clay-borg/workplans/CB-WP-0023-solve-legality.md

98 lines
3.3 KiB
Markdown
Raw Normal View History

---
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.**