Seven claims in this project have been wrong the same way — the arithmetic right, the subject wrong. Four reached a document or another repo. ADR-0018 states the rule: a measured claim names the variable it depends on and shows the measurement moving with it. GameDesign §1.4 adds it as a fourth admissibility clause; the existing three are untouched. Honest yield is 3 clear + 1 partial of 7. It misses a count never made and a claim that is not a number, and D3 names those so nobody stops looking. The tempting fix — closing facts-check's 62 untagged literals — would have caught 1 of 7 and is deferred as separate work rather than bundled. loop-lint gains check_sensitivity_stated over arithmetic register rows, mutation-proven red on F17 and green when restored, with four self-test controls. It checks presence, never adequacy, and says so in its output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5.7 KiB
ADR-0018: a number that does not move when its subject moves is measuring something else
status: accepted date: 2026-08-07 decided by: agent, under the standing loop authorization tier: M (structural M — adds an admissibility requirement, changing how the loop constrains its own operation; ADR-0006 D5). chaos d8 = 7 → no override. Declaration 1 of chaos window 3. references: CB-WP-0030, CB-EV-0019 §1 (where the family was named), GameDesign.md §1, RetrospectiveAnalysis.md §4.1, ADR-0017 (instance 7)
Context
Seven claims in this project have been wrong in the same way: the arithmetic was right and the subject was not. Four reached a document or another repository.
D1 — what this does not do, stated first
facts-check's untagged surface is not this family's control. It
reports 62 untagged literal copies across 7 registry keys and fails on
none. That is a real gap, and closing it would have caught at most one
of the seven:
- Instance 1's denominator was a registry fact and was correct —
am4a_target= 3,798 is right; AM-4a simply does not cover the code being priced. - Instances 2, 4, 5 and 6 were fresh measurements with no registry key at all.
A tag proves a number came from somewhere. It cannot prove the somewhere was the right place.
The untagged surface is worth closing on its own merits and is named as separate work. Bundling it here would let this decision claim a victory it did not win — which is the family's own error, applied to itself.
D2 — the rule
A measured claim must name the variable it depends on, and show the measurement moving with it.
A number that does not move when its subject moves is measuring something else.
This is not new machinery. It is the generalisation of two things this project already built, each in response to one instance:
RetrospectiveAnalysis§4.1's policy panel — born from instance 5, which is why a single policy's win rate may not be reported as a difficulty;attack-value.rs's one-varying-number sweep — built for F17, which varies ATTACK's rank and holds everything else fixed.
Both were built after an instance. The rule requires them before.
D3 — the yield, instance by instance, including the misses
| # | the claim | would D2 have caught it? |
|---|---|---|
| 1 | csv against AM-4a's headroom |
yes — vary which crates are in scope and the budget moves; that is the error |
| 2 | "12 in the file" | no — but §1.2's row-level rule, born from it, does |
| 3 | SOLVE's wrong condition | no — not a number |
| 4 | 112–161 µs per node | yes — cost must rise with branching; it fell, and the tell was already printed |
| 5 | too easy at 5–6 seats | yes — vary the policy and the rate collapses to 0% |
| 6 | 2 Focus/Blame conflicts | partly — varying seat count would scale a real conflict; it is the weakest row |
| 7 | window 2 had zero overrides | no — a count that was never made has no sensitivity to state |
Three clear, one partial, three missed.
The two it catches outright are the two that travelled furthest, and
both were bound for ground-game: instance 4 sat in a survey, instance 5
was queued for a repo blocked on that exact number. A control that catches
the consequential half is worth having even at 3/7.
What it misses is stated so nobody stops looking. Instance 7 needs counting, not sensitivity. Instance 3 was not a number. No syntactic gate detects a wrong subject in general — it is a semantic error, and claiming otherwise would build a gate that cannot cash out (ADR-0006 D3, ADR-0017 D2).
D4 — where it binds
- Register findings whose claim is arithmetic — the same scope GameDesign §1.2 already uses.
- Anything leaving the repo. Four of the seven were outbound or nearly so, and the recipient caught one we did not.
Not every number in every artifact. A rule that binds everywhere is obeyed nowhere, and this project has 62 untagged literals as evidence of what a broad, unenforced requirement produces.
D5 — half of it is mechanical, and only half
loop-lint can check that a sensitivity line is present. It cannot
check that the sensitivity is the right one, because that is the same
judgement the rule exists to force.
The lint checks presence, not adequacy, and must say so in its own output — otherwise a green lint reads as "the claim was verified", and the control becomes a way of not looking.
That is the honest split: the mechanical half stops the requirement being forgotten; the judgement half stays with the author and the reviewer, who between them caught five of the seven.
Consequences
GameDesign.md§1 gains a fourth clause. The existing three are untouched — each was bought by an earlier instance.loop-lintgains a check over the register's arithmetic rows.- Existing rows are brought under it or exempted with a reason.
- The untagged-facts surface is recorded as separate, unclosed work.
What was rejected
| rejected | why |
|---|---|
| closing the untagged-facts surface as the control | 1 of 7; a tag reproduces a wrong subject faithfully |
| requiring a regenerating command on every claim | catches transcription, and six of seven were not transcription errors |
| a rule binding every number everywhere | obeyed nowhere; the 62 untagged literals are the evidence |
| a lint that claims to verify the claim | it can only see presence, and pretending otherwise trains the eye to stop at green |
| stating a yield of "the family is closed" | the family's own error, applied to itself |