phase0: add architecture guardrails, CI gates, per-language AGENTS.md
Non-negotiable structural rules that apply to every Claude Code session in
this repo and to every commit, enforced via three defense-in-depth layers:
1. PreToolUse hook in .claude/settings.json blocks any Write/Edit that
would push a file past the 500-line hard cap. Auto-loads for any
Claude session in this repo regardless of who launched it.
2. scripts/githooks/pre-commit (installed via scripts/install-hooks.sh)
enforces the LOC cap, freezes migrations/ unless [migration-approved],
and protects guardrail files unless [guardrail-change] is present.
3. .gitea/workflows/ci.yaml gets loc-budget + guardrail-integrity jobs,
plus mypy --strict on new Python packages, tsc --noEmit on Node
services, and a syft+grype SBOM scan.
Per-language conventions are documented in AGENTS.python.md / AGENTS.go.md /
AGENTS.typescript.md at the repo root — layering (router->service->repo for
Python, hexagonal for Go, colocation for Next.js), tooling baseline, and
explicit "what you may NOT do" lists.
Adds scripts/check-loc.sh (soft 300 / hard 500, reports 205 hard and 161
soft violations in the current codebase) plus .claude/rules/loc-exceptions.txt
(initially empty — the list is designed to shrink over time).
Per-service READMEs for all 10 services + PHASE1_RUNBOOK.md for the
backend-compliance refactor. Skeleton packages (compliance/{domain,
repositories,schemas}) are the landing zone for the clean-arch rewrite that
begins in Phase 1.
CLAUDE.md is prepended with the six non-negotiable rules.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
43
.claude/rules/architecture.md
Normal file
43
.claude/rules/architecture.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Architecture Rules (auto-loaded)
|
||||
|
||||
These rules apply to **every** Claude Code session in this repository, regardless of who launched it. They are non-negotiable.
|
||||
|
||||
## File-size budget
|
||||
|
||||
- **Soft target:** 300 lines per non-test, non-generated source file.
|
||||
- **Hard cap:** 500 lines. The PreToolUse hook in `.claude/settings.json` blocks Write/Edit operations that would create or push a file past 500. The git pre-commit hook re-checks. CI is the final gate.
|
||||
- Exceptions live in `.claude/rules/loc-exceptions.txt` and require a written rationale plus `[guardrail-change]` in the commit message. The exceptions list should shrink over time, not grow.
|
||||
|
||||
## Clean architecture
|
||||
|
||||
- Python (FastAPI): see `AGENTS.python.md`. Layering: `api → services → repositories → db.models`. Routers ≤30 LOC per handler. Schemas split per domain.
|
||||
- Go (Gin): see `AGENTS.go.md`. Standard Go Project Layout + hexagonal. `cmd/` thin, wiring in `internal/app`.
|
||||
- TypeScript (Next.js): see `AGENTS.typescript.md`. Server-by-default, push the client boundary deep, colocate `_components/` and `_hooks/` per route.
|
||||
|
||||
## Database is frozen
|
||||
|
||||
- No new Alembic migrations. No `ALTER TABLE`. No `__tablename__` or column renames.
|
||||
- The pre-commit hook blocks any change under `migrations/` or `alembic/versions/` unless the commit message contains `[migration-approved]`.
|
||||
|
||||
## Public endpoints are a contract
|
||||
|
||||
- Any change to a path/method/status/request schema/response schema in a backend service must update every consumer in the same change set.
|
||||
- Each backend service has an OpenAPI baseline at `tests/contracts/openapi.baseline.json`. Contract tests fail on drift.
|
||||
|
||||
## Tests
|
||||
|
||||
- New code without tests fails CI.
|
||||
- Refactors must preserve coverage. Before splitting an oversized file, add a characterization test that pins current behavior.
|
||||
- Layout: `tests/unit/`, `tests/integration/`, `tests/contracts/`, `tests/e2e/`.
|
||||
|
||||
## Guardrails are themselves protected
|
||||
|
||||
- Edits to `.claude/settings.json`, `scripts/check-loc.sh`, `scripts/githooks/pre-commit`, `.claude/rules/loc-exceptions.txt`, or any `AGENTS.*.md` require `[guardrail-change]` in the commit message. The pre-commit hook enforces this.
|
||||
- If you (Claude) think a rule is wrong, surface it to the user. Do not silently weaken it.
|
||||
|
||||
## Tooling baseline
|
||||
|
||||
- Python: `ruff`, `mypy --strict` on new modules, `pytest --cov`.
|
||||
- Go: `golangci-lint` strict config, `go vet`, table-driven tests.
|
||||
- TS: `tsc --noEmit` strict, ESLint type-aware, Vitest, Playwright.
|
||||
- All three: dependency caching in CI, license/SBOM scan via `syft`+`grype`.
|
||||
8
.claude/rules/loc-exceptions.txt
Normal file
8
.claude/rules/loc-exceptions.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
# loc-exceptions.txt — files allowed to exceed the 500-line hard cap.
|
||||
#
|
||||
# Format: one repo-relative path per line. Comments start with '#' and are ignored.
|
||||
# Each exception MUST be preceded by a comment explaining why splitting is not viable.
|
||||
#
|
||||
# Phase 0 baseline: this list is initially empty. Phases 1-4 will add grandfathered
|
||||
# entries as we encounter legitimate exceptions (e.g. large generated data tables).
|
||||
# The goal is for this list to SHRINK over time, never grow.
|
||||
Reference in New Issue
Block a user