From fec03099bc599cfed0306fe898d8e763eec82937 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Thu, 30 Jul 2026 18:36:16 +0200 Subject: [PATCH] docs: commit trailers close the traceability chain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commits that implement, change, or withdraw a requirement carry a TRACES trailer using the same token and syntax as the code tags, so one grep pattern serves both. This is the last link. Code tags say where a requirement lives; commit trailers say when and why it changed, and `git log --grep=AR-012` then reconstructs a requirement's whole history — which no other artifact provides. A commit serving no requirement omits the trailer: absence is meaningful, and inventing a tag to satisfy the form is how orphan tags get created. Withdrawing a requirement counts as changing it, so the withdrawal stays findable. Also updates the chain diagram, which still referenced the retired @implements tag and the thematic A1..E8 IDs. Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 26 ++++++++++++++++++++++++++ SPEC.md | 14 ++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bf6c743..3beef1c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -94,6 +94,32 @@ is what creates orphan tags. When adding a requirement, give it a parent and a register row. When adding code, give it a tag. +### Commits name their requirements too + +Every commit that implements, changes, or withdraws a requirement carries a +`TRACES:` trailer — the same token and syntax as the code tags, so one grep +pattern serves both: + +``` +feat(audio): v1 content-derived audio signature + +Implements the §3 construction with the six previously-undefined +parameters pinned, plus a golden fixture the plugin can be written from. + +TRACES: IR-004, IR-005, IR-007, IR-008 | SR-003 +``` + +This closes the last link in the chain. Code tags say *where* a requirement +lives; commit trailers say *when and why it changed* — `git log --grep=AR-012` +then reconstructs a requirement's entire history, which no other artifact gives +you. + +- Trailer last, after any `Co-Authored-By`. +- A commit serving no requirement (formatting, tooling, a typo) simply omits it — + absence is meaningful, so do not invent a tag to satisfy the form. +- Withdrawing a requirement is a change to it: name it, so the withdrawal is + findable later. + - **Specs are requirements + current-state deltas.** Each requirement carries `Current:` and `Gap:` so the document doubles as a work list. Keep that shape when editing. diff --git a/SPEC.md b/SPEC.md index b7988df..60b9189 100644 --- a/SPEC.md +++ b/SPEC.md @@ -334,12 +334,18 @@ unimplemented, and both are worth knowing. ### The chain ``` -PR-n project requirement (this document, §1) — why the system exists - └─ SR-n system requirement (this document, §3) — what spans components - └─ A1…E8 / §n software requirement (component specs) — what one repo does - └─ @implements tag (source) — where it actually is +PR-nnn project requirement (this document, §1) — why the system exists + └─ SR-nnn system requirement (this document, §3) — what spans components + └─ component requirement (component registers) — what one repo does + ├─ TRACES tag (source) — where it lives + └─ TRACES trailer (commit message) — when and why it changed ``` +The commit trailer is the last link and the only one that carries *history*: +`git log --grep=AR-012` reconstructs everything that ever happened to a +requirement, which no other artifact provides. Same token and syntax as the code +tag, so one grep pattern serves both. + ### ID scheme Zero-padded three digits throughout. **IDs are permanent**: a withdrawn