--- id: CB-WP-0047 kind: product title: "All four boards and all three modes" status: done state_hub_workstream_id: "772b2646-1258-409b-8480-6dedd6c5c894" --- # Purpose ``` structural tier M (changes the state and therefore the recording, and moves a reported number -- the threshold -- from the engine to the edition) declared tier M ``` > *"lets have a look at the cards and the rules to those cards again and > implement all the scenarios and modes"* ## What was actually missing The two halves turned out to be very different sizes. **The modes were already implemented.** `ScoringMode`'s three arms all score, `--mode` reaches them, F14 fixed the driver. What was missing was that **nothing had ever compared them**, and the page never named them — see below. **The scenarios were not implemented at all.** `edition::deal` has taken a `scenario_id` since the day it was written, and the only caller passed the literal `"SCN_01"`: ```rust let dealt = crate::edition::deal("SCN_01", seats)?; ``` **The seam was the whole mechanism and it sat unused.** 15 of the 20 Problem cards had never been dealt by anything — not a gate, not a panel, not a player. Nothing was red, because nothing asked. ## Task: deal every board, name every mode ```task id: CB-WP-0047-T01 status: done priority: high state_hub_task_id: "d6298fa3-8c3d-4a47-ae52-945549b9ba95" ``` ### The scenario is state `GroundState.scenario`, `#[serde(default = "default_scenario")]` → `SCN_01`. In the state for the same reason `variant` is (CB-WP-0038): the board and the threshold follow from it, so a recording that did not carry it could not be replayed. **`standard-Np` keeps meaning `SCN_01`.** Twenty-six recorded scenarios name that preset; a grammar that redefined it would have moved every one of their boards while their hashes still claimed to pin them. `scn-03-4p` names the rest. `--scenario` accepts `3`, `scn-03`, `SCN_03` or `confidence` — ids are the edition's vocabulary, *"Broken Confidence"* is the player's — and is validated against the edition, never a pattern, so `SCN_09` is refused by name. ### The threshold now comes off the Scenario card `threshold()` was `match seats { 0..=2 => 5, 3..=4 => 7, _ => 9 }` — the engine's own copy of a number four cards already print, which is what F25 was raised about. **The first version of this control was worthless and mutation said so.** Reverting to the hardcoded bands left every test green, because all four scenarios print 5/7/9 and the two paths are observationally identical on every input the edition can supply. A control that cannot separate the thing it is about from its fallback is not a control. Fixed by splitting `threshold_from(list, scenario, seats)`, which can be handed a card that **disagrees** (4/6/8). That test goes red under the mutation; the loop over real scenarios never could. ### The page names the mode, the board, and what winning means The header read `scoring CommonProblem` — the Rust variant's name, where the Mode card is titled *"COMMON PROBLEM, PERSONAL EDGE"*. **CB-WP-0034 deleted this exact defect from the move buttons** and it was still standing on the one line that says what winning means. **And the coverage probe was holding it in place.** `("mode", "scoring BondedCoalitions")` — a probe matching `Debug` output, which went red the moment the defect was fixed. That is the **third** time this shape has been found (CB-WP-0024, CB-WP-0034, here), and it is now specific enough to state as a rule: *a probe that names a rendering pins that rendering; probes name facts.* The page now carries the Scenario's premise (*what happened*) and the Mode card's rules text (*how this game is won*) — including the **tiebreak**, which is a rule a player can play for: "lower Stress, then more Bonds" changes what a losing seat should do in round five, and it lived in a column nothing read. ### Mutations | mutation | what went red | |---|---| | `setup` deals `"SCN_01"` regardless of preset | *"the four scenarios yield 1 distinct board"* | | `threshold_from` ignores the card | *"the threshold did not come off the Scenario card"* | | header back to `{mode:?}` | *"the page shows the Rust variant's name"* | **Done 2026-08-08.** `make all` green. Verified live on `make ground SCENARIO=4 MODE=coalitions`. ## What the panel found `make panels` gained `scenario-panel`: 4 scenarios × 3 modes × 3 seat bands, greedy throughout, 100 games per cell. **1. Two of the four scenarios are the same board.** SCN_01 and SCN_02 have identical suits and values at every priority; every cell matches exactly. Not a defect — a designed reskin is a legitimate choice — but "four scenarios" buys **three** boards, and a panel that measured them as four independent boards would be measuring one of them twice. Pinned by a characterisation test so a future divergence is a decision, not a drift. **2. SCN_04 is the hard board at 2 players** — 52% group success against 67% and 73%. It is the only deck that needs **two Repair** solutions in the 2p deal, and the 2p Solution draw cannot always supply them. The seat band the thresholds treat as uniform is not uniform across boards. **3. The three modes produce identical play.** Group success is *exactly* equal across all three modes in every cell. That is correct arithmetic and a real finding: `GreedyPolicy` maximises the group outcome and never consults `state.mode`, so **the two competitive modes are scoring lenses over cooperative play**. `win/g` differs only by how the winner set is carved from the same games. Whether COMMON PROBLEM and BONDED COALITIONS change how the game is *played* is untested and cannot be tested by this panel — it needs a policy that plays for personal score. Filed as F27. **4. Every board is a formality at 6 players** — 100% group success in all twelve cells. Consistent with F17's shape and with H2's motivation; noted, not acted on. ## Not done here - **No policy plays for personal score**, so F27 stands open and the two competitive modes remain unexercised as *incentives*. This is the largest remaining gap and it is the natural next pass. - **SHARED GROUND's mastery rating counts CLAIMED CARDS, not points.** The Mode card says *"All claimed Problem cards form one shared score … subtract 1 for each Blame token still in play and 1 for each Denied Problem"* — and the shared score is the claimed **value**, while `mastery` subtracts from the claimed **count**. Underdetermined rather than plainly wrong; raised for `ground-game` rather than changed here, because scoring is theirs to rule on. - **The trial log stamps the variant (CB-WP-0046) but not the scenario or the mode.** A note from SCN_04 coalitions is indistinguishable from a baseline SHARED GROUND note, which is the same defect one pass later in two new axes. The marker already carries attributes, so this is small. - **`design.py` reported an existing reproduction as absent.** It stats `row["repro"]` directly, and the register writes **code spans** — so a backticked file path was `os.path.exists("`games/…/x.rs`")` = False. Named tests survived because `::` short-circuits before the stat, which is why it had never shown. F27's panel existed and counted as debt against a target of zero. ADR-0018's shape again: right computation, wrong string. Fixed with three checks, including that stripping the span must not turn the check off. - **`catalog.yaml` and both `VARIANT.md`s were re-vendored in this pass**: `ground-game` moved H2 from `experimental` to `measured`, `decision: keep-as-experiment`, citing our CB-EV-0032. That is their ruling on the previous pass, not work done here.