From cf4740c8d05fb67d997f17dceb7ef67952c79a29 Mon Sep 17 00:00:00 2001 From: tegwick Date: Fri, 7 Aug 2026 20:33:19 +0200 Subject: [PATCH] CB-WP-0036: Interactive Mode, declared and specified (not started) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tier L, and it is not the animation that makes it so. Three things in the report are not presentation: a ritual is an interaction with no command behind it and must never reach the recording; hand order is not game state and must not move the state hash; and animating another player's move needs the page to see a SEQUENCE, not a state. The obstacle named up front: the page reloads after every accepted command, which destroys the DOM, and you cannot animate across it. Letting JS mutate the DOM instead is refused — that is ADR-0007 D5's line. Rust describes the movement and the reloaded page animates into place, which keeps the server authoritative and makes the animation a rendering of facts Rust wrote, exactly like the log. The journal is already the sequence needed. The invariant that protects the rest: for the same seed and the same decisions, the recording is byte-identical in both paces. Left ready, not active: tier L requires a separate-agent adversarial review before code, and it has not been done. Co-Authored-By: Claude Opus 5 --- workplans/CB-WP-0036-interactive-mode.md | 206 +++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 workplans/CB-WP-0036-interactive-mode.md diff --git a/workplans/CB-WP-0036-interactive-mode.md b/workplans/CB-WP-0036-interactive-mode.md new file mode 100644 index 0000000..a1d0f4d --- /dev/null +++ b/workplans/CB-WP-0036-interactive-mode.md @@ -0,0 +1,206 @@ +--- +id: CB-WP-0036 +kind: product +title: "Interactive Mode: the rituals and the movement" +status: ready +--- + +# Purpose + +``` +structural tier L (creates a new capability port -- a pace of play that + the driver, the server and the page all take part in, + plus a class of interaction that is NOT a game + command) +chaos d8 = 7 → no override +declared tier L +``` + +**Declaration 7 of chaos window 3.** + +> **Tier L requires a separate-agent adversarial review before code** +> (InnerLoop §Loop tiers, Step 2). **It has not been done**, and this +> workplan is `ready`, not `active`. Ask for it before T02 opens. + +## The report + +> *"Interactive-mode should include explicit rituals and visualizations +> inspired by real life physical gameplay. In Speed-mode the UI jumps to +> the result immediately skipping animations and rituals that do not have +> any decisions in them."* + +Named in the report: + +| | | +|---|---| +| **opening ritual** | who shuffles, who deals, who plays first — *"part of the ritual of focusing on the game"* | +| **closing ritual** | handing the cards on, or throwing them down after a loss — before deciding whether to play again | +| **drawing** | explicitly drawing from the stack, or being dealt by the dealer | +| **dealing to hand** | cards enter **from the right** | +| **sorting** | drag-and-drop between hand slots | +| **playing a card** | summoned **larger, on a layer above the game**, next to the player's seat — *"this signals which player is playing the card"* — then shrinking as it travels to its target | +| **discarding** | drifts to the pile **without shrinking**, or barely | +| **other players** | their actions visualized, not jumped past into a log line | + +## What makes this tier L, and it is not the animation + +**Three things in the report are not presentation at all.** + +1. **A ritual is an interaction with no command behind it.** "Who deals" + changes nothing a rule can see. It must therefore be a *driver-level* + decision point that never becomes a `GroundCommand`, never enters the + journal, and **never reaches the recording** — or two players who made + the same moves at different paces would produce different scenarios, + and `record.rs`'s round trip is the test everything else rests on. + +2. **Hand order is not game state.** Sorting your hand must not move + `state_hash`. If it does, sorting breaks every note's binding + (ADR-0019) and every replay. But it also cannot be client-only: the + page reloads after each accepted move (below), so the order would be + lost every turn. It has to be **held by the server and excluded from + the hash** — a category this project does not yet have. + +3. **Animating another player's move requires the page to see a sequence, + not a state.** The page currently renders *the position now*. Interactive + mode needs *what happened since you last looked*, in order. + +**The third is the one that decides the architecture**, and the good news +is that the data already exists: the journal is exactly that sequence +(`Applied { actor, command, events }`), and CB-WP-0032 already reads it +per game. + +## The obstacle to name before anyone starts + +**The page reloads after every accepted command** (`window.location. +reload()`), which destroys the DOM — and you cannot animate across it. + +Two ways out, and only one is allowed: + +| | | +|---|---| +| **JS mutates the DOM instead of reloading** | **Refused.** The script would have to compute what the game now looks like, which is ADR-0007 D5's line. It says the page reports raw pointer facts and constructs nothing | +| **Rust describes the movement; the new page animates into place** | Rust already knows both positions. It emits *transitions* — what moved, from where, to where — and the reloaded page plays them before settling into the state it was served | + +**The second keeps the server authoritative** and makes the animation a +rendering of facts Rust wrote, exactly like the log. + +## Tasks + +```task +id: CB-WP-0036-T01 +status: todo +priority: high +``` + +**Decide the pace, and what it may not touch.** `decisions/ADR-0020-*.md`. + +- **Name it, and not `mode`.** `--mode` is already `ScoringMode` + (shared/common/coalitions). A second "mode" on the same driver is a + collision waiting to be mis-read; propose `--pace interactive|speed`. +- **Speed stays the default** for `sim`, `trials`, benchmarks and bots. + Animation must cost those nothing — not "be fast", cost *nothing*. +- **State the invariant that protects everything else:** for the same seed + and the same decisions, **the recording is byte-identical in both + paces**. Rituals are not commands. +- **State where hand order lives** and that it is outside the state hash. +- **`prefers-reduced-motion` behaves as Speed**, and say so in the ADR + rather than leaving it to the CSS. + +```task +id: CB-WP-0036-T02 +status: todo +priority: high +``` + +**Transitions, computed in Rust.** The journal delta since the page last +rendered, expressed as movements: what moved, from where, to where, and +whether it stays. + +- **The page is told, never asked to work it out** (ADR-0007 D5). +- **A transition names an element the page can already find**, by the same + `data-*` keys the drag code uses — inventing a second addressing scheme + is how the two drift apart. +- **Control: the delta is exact.** A page that has seen commands 0..k + animates k..n and nothing else. Replaying a transition twice, or + skipping one, must fail a test. + +```task +id: CB-WP-0036-T03 +status: todo +priority: high +``` + +**The movement itself.** A layer above the game layer; card summoned +larger next to the acting seat, shrinking toward its target; discards +drifting without shrinking. + +- **A player must be able to act DURING an animation.** If animation gates + input, interactive mode is worse than speed mode and the pass has failed. +- **Skippable, always**, and skipping lands exactly where the animation + would have. +- **Control: a full game is completable with animations on.** The table + has already been made unplayable once by growing (CB-WP-0028); an + overlay layer is the same hazard wearing a different hat. + +```task +id: CB-WP-0036-T04 +status: todo +priority: medium +``` + +**The rituals.** Opening — shuffle, deal, first player. Closing — hand the +cards on, or throw them down. + +- **Never a `GroundCommand`.** A ritual is a driver-level decision point. +- **Control: the recording is byte-identical to the same game played in + Speed.** This is the falsifier for the whole task. +- **The closing ritual comes before the play-again decision**, which is + where the report puts it. + +```task +id: CB-WP-0036-T05 +status: todo +priority: medium +``` + +**The hand: dealt from the right, sortable by drag.** + +- **Control: sorting does not move `state_hash`.** Assert it directly. + Sorting that changed the hash would silently break every trial note's + binding and every replay. +- Order survives a reload, because the page reloads on every move. +- **Drawing becomes explicit** — but only where the rules have a draw to + make explicit. CB-WP-0028 established there is no standalone draw + command: INVESTIGATE's own text is *"…reveal it. **Then draw one + Solution.**"* **Do not build a draw the game does not have.** What is + explicit here is the *animation* of a draw that already happens. + +```task +id: CB-WP-0036-T06 +status: todo +priority: medium +``` + +**Evidence.** `evidence/CB-EV-*.md`. + +- **Does it make the game more legible, or only longer?** The report's own + claim is that ritual helps focus. That is testable only by playing, and + the answer may be *no* — say so if it is. +- **What Speed mode cost**, measured, since the whole point is that it + costs nothing. +- **Whether the maintainer still needs the log to follow other players** + (their 2026-08-07 note) — that is this pass's acceptance test and it has + a person attached to it. + +## Open questions the review should settle + +1. **Is a ritual with no decision still a ritual?** The report says + interactive mode skips *"animations and rituals that do not have any + decisions in them"* — but shuffling and dealing have no decisions + either, and the report wants them. The line is not where the report + puts it, and someone has to redraw it. +2. **How many transitions can queue before it stops feeling like play?** + With bots, several commands can land between two human turns. +3. **Does the recording need the pace recorded in it?** Recording it makes + scenarios pace-specific; not recording it means a replay cannot + reproduce what a player actually saw.