This is the authoritative control surface for all coding agents. Read this first.
apps/web/ Next.js 16 frontend (App Router, Tailwind v4, shadcn/ui)
services/api/ FastAPI backend (layered: types/config/repo/service/runtime)
packages/shared/ Shared TypeScript types
docs/ System of record (features, workflows, security, reliability)
docs/exec-plans/ Execution plans and tech debt tracker
infra/railway/ Deployment config
Backend layering: types -> config -> repo -> service -> runtime
- No backward imports across layers
- No
boto3outsiderepo/ - No business logic in route handlers (
runtime/) - All external APIs wrapped in
repo/adapters - All request/response data validated at boundary (Pydantic models)
- No shared mutable state across layers
Frontend: shadcn/ui components in src/components/ui/ are generated — never modify them.
- DRY — do not duplicate logic, types, or constants. Extract shared code only when used in 2+ places.
- Structured JSON logging only — no
print()statements - No raw SDK calls outside
repo/layer - Files stay under 300 lines
- Tests added or updated for every behavior change
- Docs updated in same PR as code changes
- Lint clean before merge
- Prefer boring, composable libraries over clever abstractions
- No implicit type assumptions — use typed models
| Rule | Enforced by |
|---|---|
| No backward imports | tests/test_structure.py::test_no_backward_imports |
| No boto3 outside repo/ | tests/test_structure.py::test_boto3_only_in_repo |
| File size < 300 lines | tests/test_structure.py::test_file_size_limits |
| All layers exist | tests/test_structure.py::test_all_layers_exist |
| No bare print() | ruff rule T20 |
| Import ordering | ruff rule I001 |
| Frontend strict equality | eslint rule eqeqeq |
| No unused vars | eslint + ruff rules |
# Run
pnpm dev # start both frontend and backend
pnpm dev:web # frontend only
pnpm dev:api # backend only
# Test & Lint
pnpm lint # frontend lint (eslint)
pnpm build # frontend type check + build
pnpm lint:api # backend lint (ruff)
pnpm test:api # backend tests (pytest)
pnpm check:structure # structural boundary tests
pnpm test:e2e # Playwright e2e tests- Read this file first.
- Review ARCHITECTURE.md before structural changes.
- For non-trivial changes, create a plan in
docs/exec-plans/active/. - Implement the smallest coherent change.
- Run:
pnpm lint && pnpm lint:api && pnpm test:api && pnpm check:structure - Update docs in the same PR (see §8).
- Move completed plans to
docs/exec-plans/completed/. - Only change files relevant to the task. No drive-by improvements.
See docs/dev-workflows.md for full details.
| Change Type | Update Location |
|---|---|
| Feature logic, inputs, outputs, tests | docs/features/<feature>.md |
| User journeys | docs/app-workflows.md |
| System layout, deployments | ARCHITECTURE.md |
| Dev or testing process | docs/dev-workflows.md |
| Setup or scope changes | README.md |
| Security changes | docs/SECURITY.md |
| Reliability changes | docs/RELIABILITY.md |
| Active work plans | docs/exec-plans/active/ |
| Known tech debt | docs/exec-plans/tech-debt-tracker.md |
If documentation and implementation conflict, update docs in the same PR. Documentation rot destroys agent reliability.
| Topic | Location |
|---|---|
| System layout, data flows, boundaries | ARCHITECTURE.md |
| Feature docs | docs/features/ |
| User journeys | docs/app-workflows.md |
| Engineering workflows and testing | docs/dev-workflows.md |
| Security principles | docs/SECURITY.md |
| Reliability expectations | docs/RELIABILITY.md |
| Execution plans | docs/exec-plans/ |
| Tech debt | docs/exec-plans/tech-debt-tracker.md |
- Prefer boring, stable libraries
- Prefer small PRs over large changes
- Add tests with every change
- Never bypass lint rules without explicit instruction
- Ask before making destructive or irreversible changes