Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/hookify.function-length.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ event: file
conditions:
- field: file_path
operator: regex_match
value: "src/ai_company/.*\\.py$"
pattern: "src/ai_company/.*\\.py$"
- field: new_text
operator: regex_match
value: "^\\s*(?:async\\s+)?def "
pattern: "^\\s*(?:async\\s+)?def "
action: warn
---

Expand Down
18 changes: 9 additions & 9 deletions .claude/hookify.missing-logger.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,31 @@ event: file
conditions:
- field: file_path
operator: regex_match
value: "src/ai_company/.*\\.py$"
pattern: "src/ai_company/.*\\.py$"
- field: file_path
operator: not_contains
value: "__init__"
pattern: "__init__"
- field: file_path
operator: not_contains
value: "enums.py"
pattern: "enums.py"
- field: file_path
operator: not_contains
value: "errors.py"
pattern: "errors.py"
- field: file_path
operator: not_contains
value: "types.py"
pattern: "types.py"
- field: file_path
operator: not_contains
value: "models.py"
pattern: "models.py"
- field: file_path
operator: not_contains
value: "protocol.py"
pattern: "protocol.py"
- field: new_text
operator: regex_match
value: "^\\s*(?:async\\s+)?(?:def |class )"
pattern: "^\\s*(?:async\\s+)?(?:def |class )"
- field: file_content
operator: not_contains
value: "get_logger"
pattern: "get_logger"
action: warn
---

Expand Down
14 changes: 14 additions & 0 deletions .claude/hookify.no-future-annotations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
name: no-future-annotations
enabled: true
event: file
pattern: from\s+__future__\s+import\s+annotations
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hookify rule uses wrong schema — conditions: block is missing

The pattern: key here is placed at the top level of the front matter, but in every other hookify rule in this project (hookify.function-length.md, hookify.missing-logger.md) the matching criteria live inside a conditions: array with explicit field:, operator:, and pattern: fields.

Without a conditions: block the hook has no predicate to evaluate: depending on how hookify handles an unknown top-level pattern: key, this rule will either fire on every file event (very noisy) or never fire at all (silently skipping the check it's supposed to enforce).

The equivalent structured form, consistent with the other rules, would be:

Suggested change
pattern: from\s+__future__\s+import\s+annotations
conditions:
- field: new_text
operator: regex_match
pattern: "from\\s+__future__\\s+import\\s+annotations"
Prompt To Fix With AI
This is a comment left during a code review.
Path: .claude/hookify.no-future-annotations.md
Line: 5

Comment:
**Hookify rule uses wrong schema — `conditions:` block is missing**

The `pattern:` key here is placed at the top level of the front matter, but in every other hookify rule in this project (`hookify.function-length.md`, `hookify.missing-logger.md`) the matching criteria live inside a `conditions:` array with explicit `field:`, `operator:`, and `pattern:` fields.

Without a `conditions:` block the hook has no predicate to evaluate: depending on how hookify handles an unknown top-level `pattern:` key, this rule will either fire on **every** file event (very noisy) or never fire at all (silently skipping the check it's supposed to enforce).

The equivalent structured form, consistent with the other rules, would be:

```suggestion
conditions:
  - field: new_text
    operator: regex_match
    pattern: "from\\s+__future__\\s+import\\s+annotations"
```

How can I resolve this? If you propose a fix, please make it concise.

action: block
---

**`from __future__ import annotations` is forbidden in this project.**

Python 3.14 has PEP 649 native lazy annotations, making this import unnecessary.
The project CLAUDE.md explicitly states: "No `from __future__ import annotations`".

Remove this import and use native type hints directly.
13 changes: 9 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
environment: ci
permissions:
contents: read
strategy:
Expand Down Expand Up @@ -106,11 +107,15 @@ jobs:
permissions: {}
steps:
- name: Check results
env:
LINT_RESULT: ${{ needs.lint.result }}
TYPE_CHECK_RESULT: ${{ needs.type-check.result }}
TEST_RESULT: ${{ needs.test.result }}
run: |
if [[ "${{ needs.lint.result }}" != "success" || \
"${{ needs.type-check.result }}" != "success" || \
"${{ needs.test.result }}" != "success" ]]; then
echo "CI failed: lint=${{ needs.lint.result }}, type-check=${{ needs.type-check.result }}, test=${{ needs.test.result }}"
if [[ "$LINT_RESULT" != "success" || \
"$TYPE_CHECK_RESULT" != "success" || \
"$TEST_RESULT" != "success" ]]; then
echo "CI failed: lint=$LINT_RESULT, type-check=$TYPE_CHECK_RESULT, test=$TEST_RESULT"
exit 1
fi
echo "All CI checks passed"
6 changes: 6 additions & 0 deletions .github/workflows/pages-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ on:
- "pyproject.toml"
- "uv.lock"
- "src/ai_company/**"
- "scripts/**"
- ".github/workflows/pages-preview.yml"

permissions: {}
Expand Down Expand Up @@ -46,6 +47,9 @@ jobs:
- name: Install docs dependencies
run: uv sync --group docs --no-dev

- name: Export OpenAPI schema
run: uv run python scripts/export_openapi.py

- name: Build MkDocs
run: uv run mkdocs build --strict

Expand Down Expand Up @@ -142,6 +146,7 @@ jobs:
needs: build
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
environment: cloudflare-preview
timeout-minutes: 5
permissions:
contents: read
Expand Down Expand Up @@ -219,6 +224,7 @@ jobs:
github.event.action == 'closed' &&
github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
environment: cloudflare-preview
timeout-minutes: 5
permissions:
contents: read
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- "pyproject.toml"
- "uv.lock"
- "src/ai_company/**"
- "scripts/**"
- ".github/workflows/pages.yml"
workflow_dispatch:

Expand Down Expand Up @@ -44,6 +45,9 @@ jobs:
- name: Install docs dependencies
run: uv sync --group docs --no-dev

- name: Export OpenAPI schema
run: uv run python scripts/export_openapi.py

- name: Build MkDocs
run: uv run mkdocs build --strict

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
release-please:
name: Release Please
runs-on: ubuntu-latest
environment: release
permissions:
contents: write
pull-requests: write
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/zizmor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ on:
branches: [main]
paths:
- ".github/workflows/**"
- ".github/dependabot.yml"
- ".zizmor.yml"
pull_request:
branches: [main]
paths:
- ".github/workflows/**"
- ".github/dependabot.yml"
- ".zizmor.yml"
workflow_dispatch:

permissions: {}
Expand All @@ -29,4 +33,5 @@ jobs:
- name: Run zizmor
uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2
with:
config: .zizmor.yml
advanced-security: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ web/dist/
# Documentation build output (MkDocs)
_site/

# Generated OpenAPI schema (built by scripts/export_openapi.py)
docs/_generated/

# Astro / Node.js (landing page)
site/node_modules/
site/dist/
Expand Down
5 changes: 5 additions & 0 deletions .zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
rules:
# Daily Dependabot updates are intentional — see CLAUDE.md and dependabot.yml.
# The project uses daily checks with grouped minor/patch to stay current.
dependabot-cooldown:
disable: true
12 changes: 8 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,25 @@ uv run pytest tests/ -m integration -n auto # integration tests only
uv run pytest tests/ -m e2e -n auto # e2e tests only
uv run pytest tests/ -n auto --cov=ai_company --cov-fail-under=80 # full suite + coverage
uv run pre-commit run --all-files # all pre-commit hooks
uv run python scripts/export_openapi.py # export OpenAPI schema (needed before mkdocs build)
uv run mkdocs build --strict # build docs (output: _site/docs/)
uv run mkdocs serve # local docs preview (http://127.0.0.1:8000)
```

## Documentation

- **Docs source**: `docs/` (MkDocs markdown + mkdocstrings auto-generated API reference)
- **Docs source**: `docs/` (MkDocs markdown)
- **Design spec**: `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations)
- **Architecture**: `docs/architecture/` (overview, tech-stack, decision log)
- **Roadmap**: `docs/roadmap/` (status, open questions, future vision)
- **Reference**: `docs/reference/` (research, standards)
- **REST API reference**: `docs/rest-api.md` — links to standalone Scalar UI page at `docs/_generated/api-reference.html` (both generated by `scripts/export_openapi.py` in CI)
- **Library reference**: `docs/api/` — auto-generated from docstrings via mkdocstrings + Griffe (AST-based, no imports)
- **Custom templates**: `docs/overrides/` (MkDocs `custom_dir` for optional theme/template overrides)
- **Scripts**: `scripts/` — CI/build utility scripts (relaxed ruff rules: `print` and deferred imports allowed)
- **Landing page**: `site/` (Astro, Concept C hybrid design)
- **Config**: `mkdocs.yml` at repo root
- **API reference**: auto-generated from docstrings via mkdocstrings + Griffe (AST-based, no imports)
- **CI**: `.github/workflows/pages.yml` — builds Astro landing + MkDocs docs, merges, deploys to GitHub Pages
- **CI**: `.github/workflows/pages.yml` — exports OpenAPI schema (`scripts/export_openapi.py`), builds Astro landing + MkDocs docs, merges, deploys to GitHub Pages
- **Architecture decisions**: `docs/architecture/decisions.md` (decision log)
- **Dependencies**: `docs` group in `pyproject.toml` (`mkdocs-material`, `mkdocstrings[python]`, `griffe-pydantic`)

Expand Down Expand Up @@ -176,7 +180,7 @@ src/ai_company/
## CI

- **Jobs**: lint (ruff) + type-check (mypy src/ tests/) + test (pytest + coverage) run in parallel → ci-pass (gate)
- **Pages**: `.github/workflows/pages.yml` — builds Astro landing + MkDocs docs, merges, deploys to GitHub Pages on push to main
- **Pages**: `.github/workflows/pages.yml` — exports OpenAPI schema (`scripts/export_openapi.py`), builds Astro landing + MkDocs docs, merges, deploys to GitHub Pages on push to main. Triggers on `docs/**`, `site/**`, `mkdocs.yml`, `pyproject.toml`, `uv.lock`, `src/ai_company/**`, `scripts/**`, workflow file changes, and `workflow_dispatch`.
- **PR Preview**: `.github/workflows/pages-preview.yml`
- Builds site on PRs (same path triggers as Pages), injects "Development Preview" banner, deploys to Cloudflare Pages (`synthorg-pr-preview` project) via wrangler CLI
- Each PR gets a unique preview URL at `pr-<number>.synthorg-pr-preview.pages.dev`
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ graph TB
|---------|-------------|
| [Design Specification](docs/design/index.md) | Vision, agents, communication, engine, memory, operations |
| [Architecture](docs/architecture/index.md) | System overview, tech stack, decision log |
| [API Reference](docs/api/index.md) | Auto-generated from docstrings |
| [API Reference](docs/rest-api.md) | REST API reference (Scalar/OpenAPI) |
| [Library Reference](docs/api/index.md) | Auto-generated from docstrings |
| [Developer Setup](docs/getting_started.md) | Clone, test, lint, contribute |
| [User Guide](docs/user_guide.md) | Install, configure, run via Docker |

Expand Down
2 changes: 1 addition & 1 deletion docs/api/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# API Reference
# Library Reference

Auto-generated reference documentation from source code docstrings.

Expand Down
3 changes: 2 additions & 1 deletion docs/architecture/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ graph TB
- [Design Specification](../design/index.md) — Full design spec split into 7 focused pages
- [Tech Stack](tech-stack.md) — Technology choices and engineering conventions
- [Decision Log](decisions.md) — All design decisions, organized by domain
- [API Reference](../api/index.md) — Auto-generated from source code
- [API Reference](../rest-api.md) — REST API reference (Scalar/OpenAPI)
- [Library Reference](../api/index.md) — Auto-generated from source code
2 changes: 1 addition & 1 deletion docs/design/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ future CLI tool are thin clients that call the API -- they contain no business l
If needed, a thin CLI utility wrapping the REST API with terminal formatting (Typer + Rich
or similar). Not a priority -- the API is fully self-sufficient. To be determined whether a
dedicated CLI is warranted or whether `curl`/`httpie` and the interactive Scalar docs at
`/docs/api` suffice.
`/docs/api` (Scalar UI) and `/docs/openapi.json` (OpenAPI schema) suffice.

### API Surface

Expand Down
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ The design spec covers the full architecture of SynthOrg — from agent identity
| [Architecture](architecture/index.md) | System overview, module map, design principles |
| [Tech Stack](architecture/tech-stack.md) | Technology choices and engineering conventions |
| [Decision Log](architecture/decisions.md) | All design decisions, organized by domain |
| [API Reference](api/index.md) | Auto-generated from docstrings |
| [API Reference](rest-api.md) | REST API reference (Scalar/OpenAPI) |
| [Library Reference](api/index.md) | Auto-generated from docstrings |
| [Roadmap](roadmap/index.md) | Status, open questions, future vision |

---
Expand Down
7 changes: 7 additions & 0 deletions docs/rest-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# REST API Reference

Interactive API documentation powered by [Scalar](https://scalar.com/) and the OpenAPI schema exported from the Litestar application.

**[Open REST API Reference :material-open-in-new:](../_generated/api-reference.html){ .md-button .md-button--primary }**

When running the server locally, live interactive docs are available at `/docs/api` (Scalar UI) and `/docs/openapi.json` (OpenAPI schema).
3 changes: 2 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ nav:
- Reference:
- reference/research.md
- reference/standards.md
- API Reference:
- API Reference: rest-api.md
- Library Reference:
- api/index.md
- Core: api/core.md
- Engine: api/engine.md
Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ convention = "google"
"PLC0415", # local imports in test functions
]
"__init__.py" = ["F401"]
"scripts/**/*.py" = [
"T20", # print allowed in CLI scripts
"E501", # long lines in embedded HTML templates
"PLC0415", # deferred imports in scripts
]

[tool.ruff.lint.isort]
known-first-party = ["ai_company"]
Expand Down
Loading
Loading