diff --git a/evidence/CB-EV-0027-the-tokens-on-the-table.md b/evidence/CB-EV-0027-the-tokens-on-the-table.md new file mode 100644 index 0000000..3eacaf1 --- /dev/null +++ b/evidence/CB-EV-0027-the-tokens-on-the-table.md @@ -0,0 +1,165 @@ +# CB-EV-0027 — the tokens on the table + +CB-WP-0029 T04. Tier M (structural M — imports another edition file under +AM-4's budgets; chaos d8=4 → no override). **Declaration 12 of chaos +window 2 — the last.** Closed 2026-08-07. + +**Delivered:** [ADR-0016](../decisions/ADR-0016-the-tokens-on-the-table.md), +`Tokens.csv` vendored, `edition::tokens()`, Stress and DARVO tracks, +counted discs, Lead and Round on the table, and a supply audit that found +nothing and says so. + +--- + +## 1. The supply, measured + +750 games, 2–6 seats, greedy and random policies: + +| token | supply | max per seat | max on table | exceeded? | +|---|---:|---:|---:|---| +| Protection | 6 | 1 | 2 | no | +| Denied | 5 | — | 3 | no | +| Relation link | 12 | — | **12** | **at the limit, never over** | +| Focus / Blame | 6 | — | 0 conflicts | no | + +**The link row is the finding, and it is a negative one worth stating.** +GR-L01 gives each seat two relation slots; the box holds twelve link +tokens; six seats × two = twelve. **The rule and the component count are +the same constraint written twice**, which is what a supply looks like +when it needs no separate enforcement. Nothing was designed to make that +true — it fell out. + +**Protection is the one that could have gone wrong and did not.** +`saturating_add(1)` at `lib.rs:986` has no upper bound, so the type +permits a seventh token. Play never gets there because GROUND—OU grants +Protection and the next Attack consumes it. + +## 2. The check that was wrong, and what it cost to catch + +The Focus/Blame check reported **2 conflicts**. It compared a seat's own +placed Focus against that seat's own `blame_from` — but `blame_from` lists +**who blamed this seat**, i.e. *other players'* discs. Different tokens. +Corrected: **0**. + +**Fifth instance of the family CB-EV-0019 §1 named** — a number computed +correctly about the wrong subject: + +| # | pass | the wrong thing | +|---|---|---| +| 1 | CB-WP-0021 | `csv` cost against a budget that never sees the code | +| 2 | to ground-game | *"12 in the file"* — a sum with no deal table | +| 3 | CB-WP-0018 | SOLVE's inertness attributed to the wrong condition | +| 4 | CB-WP-0025 | a timer bracketing whole games; a win rate attributed to the game | +| 5 | **here** | a token's own disc compared against other players' discs | + +**And this is the first one caught before it left the repo** — by me, in +the same session, rather than by an adversarial reviewer or by the +maintainer. Four of the previous five reached a document or another +repository. + +**That is one data point, not a trend.** What differs is that this pass +wrote the check, read its output, and asked *what exactly did I just +compare* — a habit the previous four instances are the argument for. The +family still has **no control**; `facts-check` catches copies that +disagree and nothing catches a correct computation over the wrong subject. + +## 3. The decision not to enforce the supply + +**`quantity` does not bind**, and the reason is not that nothing exceeded +it. + +No numbered rule in `GroundRules.md` mentions a token supply. An engine +that refused a seventh Protection token would enforce a constraint nobody +ruled — **CB-WP-0023's error inverted.** That pass exists because SOLVE +was *offered* where it could not act; this would *refuse* where the rules +allow, and both are the engine deciding a rules question. + +So the check ships as a standing control. If play ever exceeds a quantity, +that is a **question for `ground-game`** — *does the box bound the game, or +do the rules?* — which is a real design question with a real answer either +way, and not ours. + +Registered as **F22, withdrawn**: a stated negative. A survey that finds +nothing and leaves no trace cannot be distinguished from one that was +never run. + +## 4. What the tracks are for + +`stress 4` is a fact you read. A marker one stop from the end of a 0–5 +track is a fact you **see coming** — and DARVO arms at Stress 5 (GR-R08), +so *"one more Attack and I trigger"* is the single most useful thing the +page can say and could not. + +Same for the DARVO pawn: OFF→DENY→ATTACK→REVERSE is a **sequence**, and a +pawn partway along it shows how much is left. `darvo Reverse` as text +tells you where you are and nothing about where that sits. + +**Unverified.** Whether this changes what a player sees coming is a claim +about play, and only playing tests it. The evidence here is that the +tracks exist and carry the right stop counts. + +## 5. Two fixture defects, and a limit corrected + +**`seat_centres` matched every ``.** Track stops and token discs +are circles, so CB-WP-0028's overlap and outside-the-table tests reported +token discs as overlapping seats. Seats now carry `class="seat"` and the +helper keys on that. **Fixture defect, not regression** — the tests were +right to fire, about the wrong objects. + +**The table height limit went 460 → 500.** That looks like lowering a +floor because the work hit it, which CB-WP-0021 T06 explicitly refused to +do (*"fix AM-7's measurement, not its floor"*). + +**It is the opposite, and the distinction is the point.** 460 was a number +I picked while fixing the unplayable table — it had **no derivation**. 500 +does: a viewport is ~800px, the header costs ~120 and the move controls +~150, leaving ~530 for the table; the version that actually broke dragging +declared 620. **An underived limit is a measurement defect**, and replacing +it with a derived one is fixing the measurement. + +If a later pass wants 560, that argument has to move the viewport budget, +not the number. + +## 6. Chaos window 2 — closed, and its verdict is due + +**This is declaration 12 of 12.** The window opened 2026-08-03 at d8. + +**Twelve declarations, zero 8s, zero overrides.** The retirement condition +— *retire if an override changes nothing twice running* — was +**untestable from the first declaration to the last**. CB-EV-0024, +CB-EV-0025 and CB-EV-0026 each said so; this is the fourth and final. + +| window | rate | declarations | overrides | changed the outcome | +|---|---|---:|---:|---:| +| 1 | d4 | 12 | 2 | **2** | +| 2 | d8 | 12 | **0** | — | + +**The verdict this supports: d8 bought rarity by spending evidence.** A +mechanism that produces no observations across a full window cannot be +evaluated by that window, which is a stronger statement than *"the rate is +too low"* — it is that the rate was chosen without asking what sample size +the retirement condition needs. + +**Recording that is a change to how the loop constrains its own operation, +which is a tier-M trigger in its own right** (InnerLoop §Loop tiers, v1.6). +It is therefore **outstanding, not done here**, and is named in the +workplan so it is not lost between passes — which is exactly how +`ground-game`'s ten rulings went uncollected for two days. + +## 7. Cost + +CB-WP-0028's cost, by re-running the instrument: `make cost`. Not inlined +(§Single source of fact). CB-EV-0019 §4's unbounded chain is still +unbounded, now across four more passes. + +## Open after this pass + +- **The window-2 verdict** (§6) — the next thing this loop owes itself. +- **The wrong-denominator family still has no control** (§2), at five + instances. +- **Whether the tracks change what a player sees coming** (§4) is untested + and only play tests it. +- **`Relations`, `DARVO`, `Player_Mats` and `Glossary` remain unvendored.** + The DARVO track now has a picture but not the edition's own words for + each stage. +- **Three of four scenarios still never dealt**, carried from ADR-0015 D5. diff --git a/workplans/CB-WP-0029-the-tokens-on-the-table.md b/workplans/CB-WP-0029-the-tokens-on-the-table.md index 024d3d8..8159503 100644 --- a/workplans/CB-WP-0029-the-tokens-on-the-table.md +++ b/workplans/CB-WP-0029-the-tokens-on-the-table.md @@ -2,7 +2,7 @@ id: CB-WP-0029 kind: product title: "The tokens on the table: components you can count, and a supply the engine may not respect" -status: active +status: done state_hub_workstream_id: "fb3d3c80-3798-4d0f-91ce-b8ea45943328" --- @@ -228,7 +228,7 @@ as a standing control. ```task id: CB-WP-0029-T04 -status: todo +status: done priority: medium state_hub_task_id: "29858777-6f8f-4d8e-90d0-cb193b7f4d29" ``` @@ -243,3 +243,22 @@ state_hub_task_id: "29858777-6f8f-4d8e-90d0-cb193b7f4d29" - **The window-2 verdict is due** (§The window closes here) — name it as outstanding if the closing pass has not run. - **Quote CB-WP-0028's cost by re-running the instrument.** + +**Done 2026-08-07.** +[CB-EV-0027](../evidence/CB-EV-0027-the-tokens-on-the-table.md). + +- **The supply is never exceeded**, and the link row explains why a supply + can need no enforcement: GR-L01's two slots per seat *are* the twelve + tokens, the same constraint written twice. +- **The Focus/Blame check was wrong and I caught it** — fifth instance of + the wrong-subject family, and **the first caught before leaving the + repo**. One data point, not a trend; the family still has no control. +- **The height limit went 460 → 500 as a correction.** 460 had no + derivation; 500 does. An underived limit is a measurement defect, and + replacing it is CB-WP-0021 T06's rule applied, not evaded. +- **Whether the tracks change what a player sees coming is untested** and + only play tests it. +- **Chaos window 2 is closed: twelve declarations, zero overrides.** Its + retirement condition was untestable from first to last. **The verdict is + the next thing this loop owes itself**, and it is a tier-M pass because + recording it changes how the loop constrains its own operation.