# CB-EV-0022 — collect the rulings CB-WP-0026 T05. Tier S (structural S — applies rulings inside an existing capability; chaos d8=6 → no override). Declaration 9 of chaos window 2. Closed 2026-08-05. **Delivered:** ten rulings recorded in `§Underdetermined`, five `provisional: true` flags lifted, four scenario schema fields, the `encodes_u_item` declaration, and an empty finding queue. --- ## 1. How long the answers sat, and what noticed them **Two days**, and the thing that noticed was **the register's first run** — not a human, not the adversarial review. `ground-game` ruled all ten U-items on **2026-08-03** (GROUND-WP-0002 T05), every one confirmed. On the same day CB-RES-0007 reported *"0 of 10 ruled."* Two days later CB-WP-0022 built the register recording them as `reported`, and the adversarial review — which found four other things — did not catch it either. `make design` did, on its first execution. **This is the symmetric failure nobody designed for.** CB-WP-0022 was shaped end to end around *we send findings and nobody reads them*: the four-day unread inbox is quoted in the declaration, the survey, the ADR and the spec. The mirror case — *they answer and we do not collect it* — appears in none of them. It is arguably the worse of the two. An unread message is visible as silence; a collected-but-unapplied ruling looks exactly like work in progress. ## 2. Did any confirmed default fail to match the kernel? No. This was the control that mattered. Every ruling was a *confirmation* of what we told `ground-game` we simulate — so a red scenario would have meant **we described our own behaviour incorrectly to them**, a defect in our report rather than in their ruling, and the most serious class available since it would be about our own code. ``` make sim → 26 passed, 59 rules covered ``` **No scenario went red.** The five confirmed defaults are the behaviour implemented. That is the strongest single result here and it is a negative: nothing was wrong. ## 3. The mapping gap was not what the survey said, and I reproduced the defect writing it CB-RES-0007: *"six of the ten already have provisional scenarios."* **Measured: one.** And the interesting part is how the other nine were lost. I wrote two mappings from the `covers:` lists and **both were wrong**: | claimed | why it was withdrawn | |---|---| | `gr-a04-bond-support` → U1 | asserts consent is **required**; U1 asks **when** the target accepts | | `gr-d05-darvo-reverse` → U5 | exercises the **unrejected** REVERSE; U5 is the **rejected** one (GROUND—ND) | Both were plausible from `covers:`. Neither survived reading the description. **These are the third and fourth instances of this exact defect** — a link that looks right from metadata, asserted without checking what the artifact exercises — and the first two reached `ground-game`. So the answer to *"do the four unlinked scenarios encode U-item defaults at all?"* is: **at least two of the four do not**, and the survey's "six of ten" was not an under-documented truth. It was wrong. `encodes_u_item` is now a declaration a scenario makes or omits, and `design.py` asserts the file names what it claims. ### The check's own first version was the same looseness Written as `grep -lE "\bU\b"`, it went red the moment two scenarios recorded *why they do not* encode U1 and U5 — reporting `['U1','U2','U5']`. **A mention is not a claim.** That is precisely the imprecision that let *"six of the ten have provisional scenarios"* stand unchallenged for five days: someone grepped for U-item strings and counted hits. The check now asserts on the declaration. ## 4. The queue reached 0 ``` QUEUE (open findings) (none) open, lacking a reproduction 0 target 0 closed (log) 12 [U1..U10, F11, F13] with a resolving reproduction 3/12 = 25% notes 2 F12, F14 ``` **`9 → 0`**, the number CB-WP-0026 T04 named. First evidence that ADR-0012 D5's lifecycle is real rather than drawn: findings entered a state, moved through it, and left the queue. **25% reproduced must not be read as a failure.** Nine U-items closed by a **ruling**, and a ruling is not an artifact. The metric is now honest about something the survey's 33% concealed: most of our findings close because someone answered them, not because anything demonstrates them. **What the lifecycle could not express** — the honest gap: `applied` is defined as *the source changed and the provisional default was deleted*. Here the rulings **confirmed** our defaults, so nothing in the rules moved; what changed is that the flags came off. The state fits, but the definition had to be read generously. If a future ruling *overturns* a default, `applied` will mean something materially different from what it meant today, and D5 does not distinguish them. ## 5. Two things the schema caught **`ScenarioFile` is `deny_unknown_fields`**, so five scenarios failed to parse until `ruled`, `ruled_by`, `ruled_note` and `encodes_u_item` were declared in the Rust struct. A corpus that accepted unknown metadata would let a typo'd `encodes_u_iem` sit forever claiming nothing — and this pass's whole subject is claims nobody checks. **`record.rs` had to set them explicitly.** A recorded game is evidence of what happened, not a claim about an undetermined rule. Filling the fields via `..Default::default()` would have been shorter and would let a recording silently inherit a U-item claim, pointing a reproduction at a finding it has nothing to do with. ## 5b. Two gates went red for the best possible reason Lifting the last five provisional flags broke two positive controls, and **both were broken in the same way**: they asserted against live repo data instead of constructing the condition they test. **`rule-coverage.py`** required `bool(prov)` — *at least one provisional item must exist*. That guard was the right instinct (a control that passes vacuously is worthless) wired the wrong way. With nothing provisional, it went red. It now builds a fixture, asserts the missing-owner case is **caught**, and reports the live count as a diagnostic — because **there is no number of provisional items this project should have.** **`design-baseline.py`** pinned *"the measured baseline is 2 of 6"* and reported `1/6`. Its "six provisional defaults" row **globbed `provisional: true` at run time**, so the dated snapshot was never a snapshot — it drifted with the repo. C2 dismantled this tool four hours earlier and missed this: a hand-maintained dict with one dynamically computed row is worse than a fully hand-maintained one, because the recomputed row silently disagrees with the date in the header. Frozen to the literal list it measured on 2026-08-03, and **removed from `make self-tests`** — that target is *"a positive control for every reporting tool"*, and per ADR-0012 D8 this is no longer a reporting tool. Leaving it wired in meant a superseded instrument could fail the build. **The pattern across both**: a control that reads the world it is meant to audit will eventually audit a world that has moved. Neither was caught by review; both were caught by the world moving. ## 6. The register moved, and ADR-0012 D2 gave way to loadability `specs/GroundRules.md` crossed the ~400-line limit and `loop-lint` required a split. ADR-0012 D2 said **"no new file"**, so this is a deviation and is recorded as one. **D2's substance holds.** Its argument was *one register, not a second mechanism competing with the first* — and `specs/FindingRegister.md` is that same register, moved, still driving off the `provisional`/ruling machinery, still the only one. What was traded away is the literal "no new file", which was D2's *implementation*, not its reason. It also resolves an awkwardness D2 named itself: *"a finding about the engine's behaviour sits in a document about the game."* Now it does not. ## 7. Chaos window 2 **Declaration 9 of 12.** Structural S, d8 = 6, no override. Recorded per §Loop tiers even though it changed nothing. **Window 2 still has no override to evaluate** — nine declarations, zero 8s. The retirement condition (*retire if an override changes nothing twice running*) cannot be assessed, and at d8 the expected count over twelve declarations is 1.5, so this is unremarkable rather than evidence of anything. ## 8. Cost CB-WP-0022's cost, by re-running the instrument: ``` CB-WP-0022-T05 $ 6.43 CB-WP-0022-T01 $ 4.17 CB-WP-0022-T02 $ 3.56 (the separate reviewer's own spend is in the subagent tree) CB-WP-0022-T04 $ 1.92 CB-WP-0022-T03 $ 1.01 ``` **The chain did not snap this time** — CB-EV-0019 §4 predicted it might, having found `cb-cost.py --slug CB-WP-0020` aborts for want of retained transcripts. CB-WP-0022 is recent enough to still be in the window. **The bound CB-EV-0019 asked for is still owed**; this pass is evidence that the rule works for a pass one step back, not that it works generally. ## Open after this pass - **Nine U-items are `applied` with no reproduction.** That is recorded, not hidden, but it means nine rules rest on a ruling nobody can re-run. Cheap to fix incrementally: each needs one scenario naming its item. - **`applied` conflates *confirmed* with *overturned*** (§4). It will matter the first time a ruling goes against us. - **The cost-chain bound** (CB-EV-0019 §4) is still unwritten.