Declaration 1 of chaos window 3 (opened by ADR-0017), tier M, chaos d8=7, no override. Seven claims in this project have been wrong the same way, and the workplan tabulates all seven with what caught each. MEASURED BEFORE PROPOSING: facts-check reports 62 untagged literal copies and fails on none, which is a real drift surface it names and does not close. CLOSING IT WOULD HAVE CAUGHT AT MOST ONE OF THE SEVEN. Instance 1's denominator WAS a registry fact and WAS correct -- the error was that AM-4a does not cover the code. Four others were fresh measurements with no registry key. A tag proves a number came from somewhere; it cannot prove the somewhere was the right place. Named as separate work rather than bundled, because bundling would let this pass claim a victory it did not win. What did work: every instance was caught when the number was computed a SECOND TIME by something with a different purpose. Two of them share a sharper property -- the claim was tested against a variation. #4's cost FELL as branching ROSE, which no per-node cost can do, and the tell was in the published output. #5's win rate was attributed to the game, and a second policy on the same deals gave 0% where the first gave 100%. So the rule generalises what this project already builds after each instance (the policy panel, the attack-value sweep) and requires it before: 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. HONEST YIELD: 3 or 4 of 7, and it catches the two that travelled furthest. It does not catch a count never made, or a claim that is not a number. Claiming it closes the family would be the family's own error applied to itself. T03 requires the lint to fail on a real row by mutation, and to say in its own output that it checks PRESENCE and not ADEQUACY -- so nobody reads a green lint as 'the claim was verified'. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5.8 KiB
| id | kind | title | status |
|---|---|---|---|
| CB-WP-0030 | process | A number that does not move: a control for the wrong-subject family | ready |
Purpose
structural tier M (changes how the loop constrains its own operation —
it adds an admissibility requirement, ADR-0006 D5)
chaos d8 = 7 → no override
declared tier M
Declaration 1 of chaos window 3, opened 2026-08-07 at d8 by ADR-0017.
The family, with every instance
Seven claims in this project have been wrong in the same way. CB-EV-0019 §1 named it: this project's arithmetic errors are not in the arithmetic.
| # | pass | the claim | what was wrong | caught by |
|---|---|---|---|---|
| 1 | CB-WP-0021 | csv costs 21,613 against 3,798 of headroom |
AM-4a never sees that code | re-deriving in ADR-0011 |
| 2 | → ground-game | "12 in the file" | a sum with no deal table | the recipient |
| 3 | CB-WP-0018 | SOLVE offered on a face-down Problem | the wrong condition named | implementing the ruling |
| 4 | CB-WP-0025 | 112–161 µs per node | the timer bracketed whole games | adversarial review |
| 5 | CB-WP-0025 | the game is too easy at 5–6 seats | a win rate attributed to the game | adversarial review |
| 6 | CB-WP-0029 | 2 Focus/Blame conflicts | compared other players' discs | re-reading the check |
| 7 | ADR-0017 | window 2 had zero overrides | never counted; cited 4× | writing the verdict |
What will not work, measured before proposing anything
facts-check has a real gap and it is not this one. It reports 62
untagged literal copies across 7 registry keys and fails on none of
them — a drift surface it names and does not close.
Closing it would have caught at most one of the seven. Instance 1's denominator was a registry fact and was correct; the error was that AM-4a does not cover the code. Instances 2, 4, 5, 6 were fresh measurements — no registry key existed, and a provenance tag reproduces a wrong subject faithfully.
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 bundling it here would let this pass claim a victory it did not win. Named as separate work, not done here.
What did work, and it is one thing
Read the caught by column. Every instance was caught when the number was computed a second time by something with a different purpose — a later pass, a reviewer, the recipient, or the author re-reading.
Two of them, 4 and 5, share a sharper property: the claim was tested against a variation.
- #4's cost fell as branching rose. A per-node cost cannot do that. The tell was in the published output.
- #5's win rate was attributed to the game; a second policy on the same deals gave 0% where the first gave 100%.
And #1 has it too: vary which crates are in scope and the budget changes, which is the whole error.
So the control is to generalise the thing this project already builds after each instance — RetrospectiveAnalysis §4.1's policy panel, CB-WP-0029's attack-value sweep — and require it before:
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.
Honest yield: 3 or 4 of 7, and it catches the two that travelled furthest. It does not catch #7 (a count never made) or #3 (not a number). Claiming it closes the family would be the family's own error applied to itself.
Task: decide the rule and its limits
id: CB-WP-0030-T01
status: todo
priority: high
decisions/ADR-0018-*.md.
- State the rule and where it binds: register findings that carry arithmetic, and anything leaving the repo.
- State the yield honestly, instance by instance, including what it misses. A control whose reach is overstated is worse than none, because it stops people looking.
- Decide whether it is a gate or a discipline. A sensitivity claim is
prose;
loop-lintcan check presence, never adequacy. Say which half is mechanical. - Do not bundle the untagged-facts surface. Name it as separate.
Task: the rule, in the spec that governs findings
id: CB-WP-0030-T02
status: todo
priority: high
specs/GameDesign.md §1 already requires a reproduction that exists,
has the ruled shape, and can fail. This adds the fourth clause,
because §1.2's row-level rule was itself born from instance 2 and covers
only sums.
Controls:
- the clause names the variable and the expected direction, or it is a sentence with no content;
- the existing three clauses are unchanged — this is an addition, and a rewrite would silently drop what earlier instances bought.
Task: make the mechanical half mechanical
id: CB-WP-0030-T03
status: todo
priority: high
loop-lint fails when a register row of an arithmetic kind lacks a
sensitivity line.
Controls:
- the check must fail on a real row, demonstrated by mutation — a lint that cannot go red is decoration (ADR-0006 D3, ADR-0017 D2);
- it checks presence, not adequacy, and its output says so, so nobody reads a green lint as "the claim was verified";
- existing register rows are brought under it or explicitly exempted with a reason — a rule that only binds future rows leaves the six instances unprotected.
Task: evidence
id: CB-WP-0030-T04
status: todo
priority: medium
evidence/CB-EV-0028-*.md.
- Re-run the seven instances against the rule and report how many it would have caught. If the answer is below 3, the rule is not the one.
- What the untagged surface is worth, since it was measured here and deferred.
- Whether a lint that checks presence is worth having at all, or whether it trains the eye to stop at green.