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>
7.6 KiB
CB-EV-0028 — a number that does not move
CB-WP-0030 T04. Tier M (structural M — adds an admissibility requirement; chaos d8 = 7 → no override). Declaration 1 of chaos window 3, opened 2026-08-07 by ADR-0017. Closed 2026-08-07.
Delivered: ADR-0018,
GameDesign.md §1.4, check_sensitivity_stated in loop-lint with four
self-test controls, and a mutation proof that it goes red on a real row.
1. The seven instances, re-run against the rule
The workplan's own falsifier: if fewer than 3 of 7, the rule is not the one.
| # | the claim | caught? | by what, exactly |
|---|---|---|---|
| 1 | csv costs 21,613 against 3,798 of headroom |
yes | vary which crates AM-4a scopes and the headroom moves — that is the error |
| 2 | "12 in the file" | no | §1.2's row-level rule, born from it, does |
| 3 | SOLVE offered on a face-down Problem | no | not a number |
| 4 | 112–161 µs per node | yes | cost must rise with branching; it fell |
| 5 | too easy at 5–6 seats | yes | vary the policy, the rate goes 100% → 0% on the same deals |
| 6 | 2 Focus/Blame conflicts | partly | varying seat count scales a real conflict; a phantom one need not |
| 7 | window 2 had zero overrides | no | a count never made has no sensitivity |
Three clear, one partial, three missed. Above the falsifier, and not by much.
The distribution matters more than the count. The two it catches
outright, 4 and 5, are the two that travelled furthest — instance 4 sat in
a published survey, instance 5 was queued for ground-game, which was
blocked on that exact number. The three it misses were each caught by a
human re-reading, which is the mechanism the rule generalises and cannot
replace.
Row 6 is honestly "partly" and stays that way. A phantom conflict from comparing the wrong disc set might scale with seats too. The variation would have prompted the question what am I comparing, which is what actually found it — but that is the rule working as a prompt, not as a test, and writing it down as a catch would inflate the yield.
2. What the untagged surface is worth, since it was measured
facts-check reports 62 untagged literal copies across 7 registry
keys and fails on none.
Against this family it is worth 1 of 7, and arguably 0. Instance 1's denominator was a registry fact and was correct — 3,798 is AM-4a's target. The error was that AM-4a does not cover the code being priced. A provenance tag would have reproduced the wrong subject faithfully and with a citation.
A tag proves a number came from somewhere. It cannot prove the somewhere was the right place.
Instances 2, 4, 5 and 6 were fresh measurements — there was no registry key to tag.
It is still worth closing, for a different failure mode: a literal
that drifts from its registry key is a copy that disagrees, and
facts-check exists for exactly that. Named as separate work and not
done here — bundling it would have let this pass claim a victory it did
not win, which is this family's own error applied to itself.
3. Is a presence-only lint worth having
The strongest argument against: a green lint reads as "the claim was verified." If it trains the eye to stop at green, it is worse than nothing, because five of the seven instances were caught by an eye that did not stop.
Three things decide it in favour.
It says what it is, in its own output. The finding text ends "NOTE: this checks presence, not adequacy." A reader who stops at green is stopping against an explicit statement rather than an implied one.
Its cost is bounded by scope. It binds arithmetic register rows, not every number in every artifact — 62 untagged literals are this project's own evidence of what an unenforced everywhere-rule produces (ADR-0018 D4).
The failure it prevents is forgetting, and forgetting is what happened.
RetrospectiveAnalysis §4.1's policy panel and attack-value.rs's
one-varying-number sweep both exist. Both were built after an
instance. Nothing asked for either before.
Verdict: worth having, on the condition it never grows a claim it cannot cash. The moment its output implies verification, ADR-0006 D3 and ADR-0017 D2 both apply and it should be deleted.
4. The check fired on three real rows, and all three were wrong to fire
First run: F12, F15, F21 — every one a note.
A note is by definition a finding without a reproduction (GameDesign §3.1). There is no measurement, so there is nothing for a sensitivity statement to be about; the check was demanding one anyway.
The fix went into the check, not into three exemptions. Three
hand-written sensitivity-exempt comments would have produced green with
the rule still wrong, and the next note would have needed a fourth. That
is the difference between a rule and a pile of special cases, and the
exemption mechanism exists for genuine one-offs, not for a category the
rule should never have covered.
5. The mutation, and the moment it nearly passed as proof
The control is that the check fails on a real row — a lint that cannot go red is decoration.
The first mutation attempt did not fire, and I nearly read that as a
failed check. I had rewritten two phrases in F17's prose ("varies
exactly one number" → "uses a policy") and expected red. Green. A debug
probe showed F17 was being reached, kind degenerate, state raised,
prose found — and still matched, because the text elsewhere said "one
number varied."
The check was right and the mutation was incomplete. Stripping every trigger word produces:
[sensitivity] specs/FindingRegister.md
F17 (degenerate) states a quantity and names no variable it depends
on (GameDesign §1.4). ... NOTE: this checks presence, not adequacy.
and restoring the file returns it to green.
This is worth recording because the near-miss is the same family. "The lint does not fire" was a correct observation about the wrong subject — I had measured my mutation, not the check. A debug probe printing what the check actually saw settled it in one run, which is the second-computation mechanism §1 credits with catching all seven.
Four self-test controls, because a check that cannot say NO is decoration and one that cannot say YES fires on everything: it catches a bare arithmetic claim, clears one that names its variable, skips non-arithmetic kinds, and skips notes.
6. A vocabulary defect, caught by a gate that already existed
This workplan shipped as kind: process. The vocabulary is
product | meta | mixed, and make self-tests said so immediately.
No new control was needed and none was added. Corrected to meta —
the workplan changes how the loop constrains its own operation, which is
what meta means. Worth one line here because the pass that added a gate
was itself caught by an older one, working exactly as intended.
7. Cost
make cost, not inlined (§Single source of fact). CB-EV-0019 §4's
unbounded chain is still unbounded.
Open after this pass
- The untagged-facts surface (§2) — 62 copies, measured, deferred, unclosed.
- The rule catches 3½ of 7 and the family is not closed. Instances 3 and 7 need different controls: a wrong condition is not a number, and a count never made needs counting.
- The lint's honesty is a claim about readers, not code (§3), and only a later pass reading a green run tests it.
- F18 —
Relations,DARVO,Player_Mats,Glossaryunvendored; still the only open register row with no reproduction. - Three of four scenarios never dealt, carried from ADR-0015 D5.