T09: close the spec->code link mechanically (M-D1-LNK)

make coverage now reports a second number: how many claimed rules are
also NAMED in the aggregate source. 58/58 tag coverage was weaker
evidence than it read as, and this says how much weaker.

Measured: 49 of 58. Nine rules are claimed by a scenario and appear
nowhere in games/ground/src/lib.rs --
GR-D07 GR-F02 GR-L03 GR-O03 GR-P01 GR-P02 GR-P03 GR-P04 GR-T01.

The gate REPORTS rather than fails, on purpose. Closing the gap by
adding those IDs to comments would satisfy the check without
establishing that any of the nine is implemented -- the overclaim
InnerLoop implementation rule 2 exists to prevent, and one CB-WP-0001
already committed once. Each needs its implementation confirmed before
it is tagged; promoting M-D1-LNK to a failing gate is correct after
that, not before.

Also added: a phantom check that fails when a rule id appears in code
that the spec does not define (currently zero).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-07-31 09:27:14 +02:00
parent 4fd6322e17
commit 9e30bbb2b3
3 changed files with 58 additions and 1 deletions

View file

@ -31,6 +31,7 @@ and add capability-specific rows only when these don't cover the claim.
| ID | Dimension | Metric | Unit | Provenance |
|---|---|---|---|---|
| M-D1-COV | D1 | numbered spec rules covered by ≥1 passing scenario | % | adapted:requirements-traceability (per-rule, not per-feature) |
| M-D1-LNK | D1 | claimed rules also **named in the aggregate source** | count | novel — closes the spec→code→scenario chain; instrument: `make coverage` (AM-1b) |
| M-D1-SPL | D1 | spec lines per numbered rule | lines | novel — proxies statement simplicity; gameable, so paired with M-D1-COV |
| M-D2-LOC | D2 | source LOC excluding tests (tokei) | lines | adopted:tokei |
| M-D2-DEP | D2 | transitive dependency count (cargo tree) | crates | adopted:cargo-deny practice |
@ -44,6 +45,32 @@ and add capability-specific rows only when these don't cover the claim.
| M-D4-LEAK | D4 | foreign types in canonical interfaces | count | novel — must be 0; enforced by grep/deny rule, the Clay-Borg hard rule |
| M-D4-SWAP | D4 | capability has null + reference impls passing the same conformance suite | bool | adapted:hexagonal-architecture port testing |
### 1b. The coverage gate's two numbers (M-D1-COV, M-D1-LNK)
M-D1-COV counts tags. It proves no rule is unclaimed and no claimed rule
is invented; it does **not** prove a scenario exercises what it names, and
that limit is printed with the number every time (InnerLoop implementation
rule 4).
**M-D1-LNK** (CB-WP-0003 T09) closes one link of that chain mechanically:
a rule a scenario claims should also appear in the aggregate source, or
the claim rests on a tag and nothing else.
Measured 2026-07-31: **49 of 58** claimed rules are named in
`games/ground/src/lib.rs`. **Unmet**, target 58. The nine unlinked:
```text
GR-D07 GR-F02 GR-L03 GR-O03 GR-P01 GR-P02 GR-P03 GR-P04 GR-T01
```
The gate **reports** this rather than failing, deliberately. Closing the
gap by adding rule IDs to comments would satisfy the check without
establishing that each rule is implemented — which is the overclaim
InnerLoop implementation rule 2 exists to prevent, and which CB-WP-0001
committed once already. Each of the nine needs its implementation
confirmed before it is tagged. Promoting M-D1-LNK to a failing gate is
correct **after** that, not before.
### 1a. Token cost accounting (M-D2-CST)
> **Superseded 2026-07-31 by [CostAccounting.md](CostAccounting.md)**, which