--- id: CB-WP-0023 kind: product title: "SOLVE is offered only where it can do something" status: active --- # Purpose ``` structural tier S (implements a ruling inside an existing capability — no new port, no canonical interface, no dependency) chaos d8 = 6 → no override declared tier S ``` Declaration 6 of chaos window 2. ## A ruling, not a judgment call `ground-game` ruled SOLVE's legality on 2026-08-03 (GROUND-WP-0002 T02), after clay-borg raised it from play: | sub | ruling | |---|---| | **(a)** face-down Problem | **Not offered — illegal target.** *"only face-up, non-Denied. Browser no-ops were a filter bug, not a bluff mechanic."* | | **(b)** no matching Solution in hand | **Not offered.** *"the engine only offers SOLVE when a matching suit is held."* | | **(c)** already-claimed Problem | **Same-round race legal; prior-round claim not offered.** | **The bluff reading is dead.** CB-WP-0018 raised (a) as *possibly* an intended bluff in a commit/reveal game and deferred to ground-game rather than deciding. The answer is that it was a filter bug, and the engine has been offering an inert move since the day `legal_commands` was written. `legal_commands` offers Investigate and SOLVE on **every** problem key, with no reference to `face_up`, `denied`, `claimed_by` or the hand. **Only SOLVE is ruled on. Investigate is not touched** — implementing more than was ruled would be inventing rules, which is what this whole exchange exists to stop. ## Task: filter SOLVE to what the ruling allows ```task id: CB-WP-0023-T01 status: todo priority: high ``` SOLVE is offered on problem `p` for seat `s` **iff** `p.face_up`, `!p.denied`, `p.claimed_by.is_none()`, and `s`'s hand holds a card of `p.suit`. On (c): at Select time every `claimed_by` is from a prior round — claims land at Resolve — so *"prior-round claim not offered"* is exactly `claimed_by.is_none()`, and the same-round race is already legal because both seats select before either resolves. **Say this in the code**, or the next reader will add a round comparison that does nothing. **Controls:** - each of the four conditions must be independently mutation-provable — drop one filter, and a test naming *that* condition goes red; - the maintainer's reported case must be reproduced and then fixed: SOLVE on a face-down Problem is offered before, not offered after; - **`make sim` must still pass**, or the ruling has broken a scenario that encoded the old behaviour — in which case the scenario was encoding a bug and must be updated with a note, not quietly edited. ## Task: retire what the ruling settles ```task id: CB-WP-0023-T02 status: todo priority: medium ``` Update `specs/GroundRules.md` §Underdetermined for the SOLVE items, and retire the provisional flags the ruling closes. **A ruling that lands in code but not in the spec leaves the next reader with two sources.** Report to `ground-game` that the ruling is implemented — closing the loop is the part that has failed twice. ## Task: evidence ```task id: CB-WP-0023-T03 status: todo priority: high ``` `evidence/CB-EV-0020-*.md`. Short. - **How long the inert move survived**, and what it cost: a maintainer played SOLVE three rounds running with no effect and no explanation. - **Whether any scenario encoded the bug.** - **Quote CB-WP-0022's cost by re-running the instrument.**