# CB-EV-0020 — a gate moved the rule, and the report was wrong CB-WP-0023 T03. Measured 2026-08-04 at `46c2fb6`+. Pass kind `product`, tier **S** (chaos d8 = 6, no override). Declaration 6 of chaos window 2. --- ## 1. How long the inert move survived, and what it cost SOLVE has been offered where it could do nothing **since `legal_commands` was written** — nineteen passes. It cost one maintainer three consecutive rounds of a real game, playing the same move and watching nothing happen, with no explanation on the page. It was not found by a test. It was found by a person playing, and then only because they said so. ## 2. The rule ended up somewhere other than where I put it I implemented the ruling in `legal_commands` — the **offer** layer — and it worked: SOLVE stopped being offered, four conditions, four tests. Then the **AM-1 coverage gate failed the build**: 58/59, `GR-P05` uncovered. Scenarios are what cover a rule, and scenarios drive `validate`, not the offer layer. That is what showed the rule was in the wrong place. **A rule enforced only by the offer is enforced only for clients that ask what is legal.** The browser would have been filtered; a scenario file, a bot, or any future client that constructs a command directly would have walked straight past it. Once GR-P05 moved into `validate`, every condition in `legal_commands` was dead code — and the layering test I had written for a different reason said so in exactly those words: *"validate now rejects claimed — drop the filter."* The offer layer is back to one arm for Investigate and SOLVE together, and it gets the rule for free because it filters candidates through `validate` anyway. **The gate did not catch a bug. It caught a design error**, which is a better return than it was built for. ## 3. The reported case was not the one I reported CB-WP-0018, CB-EV-0016 and **the message to ground-game** all described the defect as *SOLVE offered on a face-down Problem*. Measured: **`validate` already rejected face-down.** It never was offered. Problem 1 is the Surface Problem and is face-up from the deal (GR-S01), so the maintainer's three inert SOLVEs were the **hand** case — holding no Clarify for a Clarify Problem. I inferred "face-down" from the play report without checking which condition was actually blocking, and then told the game's designer. The ruling covers both sub-cases, so nothing it says is invalidated and no re-ruling is needed. **But a ruling was requested on the strength of a description that was wrong**, and this is the second time in three passes that a premise I supplied reached ground-game unchecked — the first being the *"12 points available"* that voided GR-E01. Two of two. The pattern is not that the analysis is careless; it is that **a claim gets sent the moment it is interesting, and checked afterwards.** That is the same shape as *unexecuted verification*, one step further out: not an unverified belief acted on, but an unverified belief **published**. CB-WP-0022's *"no finding without its reproduction"* rule would have caught both. GD-0001 already carries its reproduction; this pass is the argument for making that the standard rather than the exception. ## 4. What the four conditions cost to prove Each is asserted on its own, because a single *"SOLVE is filtered"* test passes with three of four implemented and nobody learns which. | mutation | result | |---|---| | drop the claimed check | `solve_is_not_offered_on_an_already_claimed_problem` red | | drop the hand check | `solve_is_not_offered_without_a_matching_solution_in_hand` red | | invert the layering assertion | `validate_enforces_all_four_solve_conditions` red | An earlier mutation run reported **three survivors** and was wrong: the replacement strings did not match the source, so nothing was mutated. The run proved nothing and looked like a result — the harness-does-nothing class, in my own hands, caught only by checking that the file changed. **No scenario encoded the bug.** All 25 passed unchanged; the 26th covers GR-P05. ## 5. Cost | pass | kind | responses | cost | $/response | |---|---|---|---|---| | **CB-WP-0022** | product | *in flight — T01 only* | | | | **CB-WP-0021** | product | 12 | **$5.06** | 0.422 | | CB-WP-0023 | product | *provisional — not quoted* | | | CB-WP-0022 is still `active` and cannot be quoted as settled; CB-WP-0021 is `ready` with its declaration and correction committed and no implementation, which is what $5.06 buys. Read by re-running `make status` at the moment of writing. ## 6. Open - **CB-WP-0021 (the edition import) is unstarted and now partly redundant**: GR-P05's suit check makes the *stand-in's* cycled suits load-bearing, so importing real `required_solution` values changes which Problems each hand can solve. It should be re-read before it is run. - **CB-WP-0022 T02 (adversarial review) is next**, and §3 has just handed it a second data point. - **GROUND-WP-0004** — GR-E01's ruling reopened on corrected numbers, with the maintainer's unwinnable 3-player games as evidence. - **Chaos: 6 of 12 in window 2**, one override, changed nothing.