# CB-EV-0023 — the table you can watch CB-WP-0024 T05. Tier S (structural S — renders state the projection already carries; chaos d8=6 → no override). Declaration 7 of chaos window 2. Closed 2026-08-05. **Delivered:** the ending control says what it does and the page acts on it; draw and discard drawn as stacks; each seat's play drawn as a card; a session tally across games. Five remarks from play, four addressed (remarks 2 and 3 are CB-WP-0025). --- ## 1. How many of the five remarks were already implemented **Three of five were data the projection already carried, rendered as text.** That is the finding this pass is really about, and it was established by reading the code before writing the workplan rather than by building anything. | remark | what was actually missing | |---|---| | follow the other players | nothing in the model — `selections` project as `Shown` after Reveal and were already drawn, **as sentences** | | draw and discard stacks | nothing in the model — `solution_deck_len` and `solution_discard` were one line of text | | show the scores | nothing at all — `personal`, `mastery`, `winners`, `total`/`threshold` were already drawn | | the ending button | a real defect, two of them | | a cumulative score | genuinely absent | **So the table's problem was legibility, not content.** A renderer can show every field it is given and still be unreadable, and the coverage gate — which asserts every view field appears in the parsed document — passes either way. It is a completeness gate, and completeness was never the issue. **That is worth naming as a gap in the controls**, not as a criticism of them. `every_view_field_is_classified_in_the_emitted_document` proves nothing is silently omitted. Nothing proves it is *readable*, and nothing could, cheaply. The maintainer playing the game is the instrument, which is what makes remarks like these worth more than their length suggests. ## 2. The defect that mattered was untestable, and that is why it survived The ending control was labelled *"close — I have read this"* while `hotseat.rs` read it as **stop the server**, and acknowledging it changed nothing: the tab kept a full table and a `play again` pointing at a closed port. The label was a wording bug. **The second half survived for a structural reason:** > `jsrun`'s `fetch` stub returned `{then: function () { return this; }}`, > which never invoked its callbacks. **Every line of the script that > reacts to what the server said was unreachable from every test in this > project.** The `ok` → reload branch, the status text, and the branch that did not yet exist were all equally unexercised. A page that ignores the server was indistinguishable, under test, from one that acts on it. CB-WP-0014 embedded a real JS engine specifically so the script could be executed rather than string-matched, and CB-WP-0016 found that *a stub too thin to express a failure is how the failure survives*. This is the same finding one layer deeper: the stub was thin at the **reply**, and the reply is where the session's ending lives. The stub now delivers a real then-chain and `gesture_with_reply` reports which controls survive. The seal is mutation-proven — deleting the branch turns exactly one test red — and a negative control asserts `ok: dealing` does **not** seal, because a seal that fired on every reply would pass the first test and silently break `play again`. ### One browser-versus-stub trap, avoided by writing it down The first seal used `setAttribute('data-drop', null)`. In the stub that stores a real `null` and `getAttribute` returns `null`; **in a browser it writes the literal string `"null"`, which is truthy**, so the control would have stayed live while its own test called it sealed. `removeAttribute` is correct in both. The stub gained the method rather than the script gaining a workaround. ## 3. The reshuffle question: already ruled, already implemented T02 required settling whether the deck-exhaustion shuffle happens before drawing it, and to raise a finding if it did not. **It does.** `games/ground/src/lib.rs:1419-1435` (`draw_solution`): deterministic reshuffle of the discard, seeded `seed ^ round`, carried in a `DeckReshuffled` event so replay never re-derives it; if both are empty the draw is skipped. That is the **U4 default**, which ground-game **confirmed on 2026-08-03** — a ruled rule. So nothing was raised, which is the correct outcome and the one the task was written to allow. The piles show the state in which the *next* draw triggers it, because that is derivable from the view; a claim that a reshuffle *has* happened is not, and is not made. The event already reads out in the log. **Two days earlier this question would have been raised as a finding.** CB-WP-0026 applied the U4 ruling on 2026-08-05; this pass consumed it the same day. The register paying off inside 24 hours is not proof it works, but it is the first time the answer to *"is this underdetermined?"* was one lookup instead of a message. ## 4. What the controls caught **The coverage gate caught its own probe going stale.** Replacing the `17 remaining` text broke `solution_deck_len`'s classification — the gate does not care *how* a field is rendered, only that its token appears, so changing the rendering changed the token. Fixed by putting the count in the pile's ``: a stable probe, and what a screen reader announces. The on-canvas numeral would have been a weak probe, since a bare `17` could be anything on the page. **The compiler caught a misplaced doc comment** that had silently taken `Summary`'s `#[derive(Debug)]` with it. Neither is interesting alone. Together they are the ordinary case for this project: the gates fire on rendering changes, and the cost of that is small enough that nobody is tempted to loosen them. ## 5. The cumulative-score question, and why it stayed a note The task required deciding what "cumulative" means **before** summing anything. The answer is that **GROUND defines one game and no series at all.** `personal` sums per seat; `winners` counts games won; `group_success` counts games the table cleared. They answer different questions, and a test asserts they can point at different seats — a 9/0/0 versus 0/1/1 series leads on summed score for one seat and on games won for the other. **Both are shown and both are named.** Picking one would have made it *the* score by default, which is canonising a rule nobody wrote. Registered **F15, `underdetermined`, state `note`**. It stays a note on purpose: the test demonstrates the two tallies *can differ*, which is arithmetic — not evidence that the ambiguity harms play. Under GameDesign §3.1 a note may not be reported to ground-game until an artifact exists. **This is the note tier doing exactly what ADR-0012 D6 built it for**, on the first genuinely new question since it was written. The tier was argued as the way to admit findings from *play* that the engine cannot produce; its first real use is a question from *building*, which the ADR did not anticipate and which the tier handles unchanged. ## 6. Chaos window 2 **Declaration 7 of 12.** Structural S, d8 = 6, no override. Ten declarations in, **no 8 has been rolled**. At d8 the expected count over twelve is 1.5, so this is unremarkable — but it means window 2 will likely close with **zero overrides to evaluate**, and its retirement condition (*retire if an override changes nothing twice running*) will be untestable. Window 1 closed with 2 overrides at d4 and both changed the outcome. **The rate cut to d8 may have made the mechanism unevaluable**, which is a real cost that CB-EV-0015's decision did not price, and the window's closing evidence should say so. ## 7. Cost CB-WP-0023's cost, by re-running the instrument — the pass this one is required to quote. Reported by `make cost`; **not inlined here as a literal** (§Single source of fact), and see CB-EV-0019 §4 on the chain breaking beyond ~4 passes. ## Open after this pass - **Remarks 2 and 3** — *how could we have won* and *difficulty* — are CB-WP-0025, declared and ready, tier L. - **F15** needs an artifact before the series question can go to ground-game. - **Legibility has no gate** (§1) and probably should not get one; the honest control is a person playing it.