diff --git a/CLAUDE.md b/CLAUDE.md index be343f61..1312d5ed 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -227,6 +227,34 @@ Before accepting a spec, run it past a spec around "no Rust changes required" — correct layer placement is the goal, not minimal backend churn. +### 🔴 A spec becomes an architecture doc when it ships + +`docs/specs/` holds **only work that has not shipped**. There is no "Implemented" +resting state for a spec file: when the last acceptance criterion is met, fold +the design into [docs/architecture/](docs/architecture/README.md) and **delete +the spec in the same commit**. + +This is not tidying. A directory that mixes promises with descriptions makes both +unreliable — you cannot tell from a file whether it describes the build or +proposes a change to it, and stale specs then quietly disagree with the code +while reading as authority. + +- **Every spec names its destination up front** — the template's "Destination on + completion" line. Deciding at spec time which architecture doc will absorb it + is a design check in itself: a feature that fits no existing doc is usually a + feature whose layer assignment is unclear. +- **Carry the reasoning, not the plan.** The architecture doc gets the *why* a + future change still needs — invariants, rejected alternatives that would be + re-attempted, the defect a piece of code exists to prevent. Acceptance + criteria, phase breakdowns and migration steps die with the spec; git history + keeps them. +- **Deferred work outlives its spec.** Anything the spec listed as out-of-scope + and still worth doing goes beside the code it concerns, not into the void. +- **Rewrite inbound references before deleting** — source comments and CI + scripts cite spec paths, and `check-doc-links` only sees markdown. +- **Partially implemented is a real status.** A spec stays until *all* of it + ships, with the header naming what is left. + ## Conventions ### Rust Backend diff --git a/docs/specs/SPEC-REVIEW-CHECKLIST.md b/docs/specs/SPEC-REVIEW-CHECKLIST.md index f6114b35..9f287814 100644 --- a/docs/specs/SPEC-REVIEW-CHECKLIST.md +++ b/docs/specs/SPEC-REVIEW-CHECKLIST.md @@ -53,6 +53,18 @@ Copy the boxes into the review comment (or the PR) and tick them. - [ ] Traceability coverage stays ≥ 88% (the CI gate — a ratchet, so check `bun run traces:coverage` rather than trusting this number). +## Lifecycle + +- [ ] **"Destination on completion" names a real architecture doc and section.** + This spec file is deleted when it ships; something has to absorb the + design. If nothing fits, the layer assignment is probably unclear — go back + to that table. +- [ ] The spec separates the **durable half** (invariants, rejected alternatives, + the defect a decision exists to prevent) from the **disposable half** + (phases, migration steps, acceptance criteria). Only the first is folded in. +- [ ] Anything listed as out of scope but still worth doing is written where it + will be found after this file is gone — beside the code it concerns. + ## Conflicts & hygiene - [ ] If this spec revises/supersedes another, the older spec gets a banner diff --git a/docs/specs/SPEC-TEMPLATE.md b/docs/specs/SPEC-TEMPLATE.md index e27df44b..61e28a5e 100644 --- a/docs/specs/SPEC-TEMPLATE.md +++ b/docs/specs/SPEC-TEMPLATE.md @@ -6,12 +6,27 @@ "Layer assignment" — read its comment before writing it. Before merging a spec, run it past docs/specs/SPEC-REVIEW-CHECKLIST.md. + + LIFECYCLE: this file is temporary. docs/specs/ holds only unshipped work — when + the last acceptance criterion is met, the design is folded into + docs/architecture/ and this file is deleted in the same commit. Write it + knowing that: the durable half is the reasoning (invariants, rejected + alternatives, the defect a decision prevents), and the disposable half is the + plan (phases, migration steps, acceptance criteria). --> -**Status:** Proposed +**Status:** Proposed **Requirements:** **UX spec:** **Supersedes / revises:** +**Destination on completion:** ## Summary