specs/Ornamentation.md: what a game is besides its rules
Some checks failed
ci / check (push) Failing after 4s

Draws one boundary — between what the rules can see and everything else a
player experiences — and says which repository each belongs to as the
simulator grows.

"Ritual" becomes ornamentation: half the category is material rather than
ceremonial, and "decoration" is already spoken for in this repo (a control
that cannot fail). The test is not "does it have a decision in it" —
choosing who deals is a decision and is ornamental. The test is whether
the state hash moves, which reuses the instrument that already binds a
trial note to a position.

The part that earns its place in clay-borg rather than in a renderer's
stylesheet: calling something ornamentation is a CLAIM THAT IT DOES NOT
MATTER, and this project's register is a list of times that claim was
wrong — quantity in Tokens.csv, F18's four unread files, SOLVE offered
where it could not act. So a declaration carries a falsifier, and
"provisional" is a state it must say out loud.

Downstream may read, may not decide — ADR-0007 D5 restated at the
repository boundary. The port to clay-animate is deliberately NOT
designed: no consumer exists, and an interface built against an imagined
client is the same defect as a gate that cannot go red.

Five invariants, four checkable today. I3 — same seed and decisions
produce a byte-identical recording at any pace through any renderer — is
the falsifier for the whole split.

CB-WP-0036 re-declared from L to M accordingly: the animation architecture
that made it L has moved to clay-animate. No code had been written and the
tier-L review had not been run, which is the only reason it could be
re-scoped rather than unwound.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-07 21:16:34 +02:00
parent 34370d1076
commit 31ae160043
5 changed files with 353 additions and 173 deletions

View file

@ -3,6 +3,7 @@ id: CB-WP-0035
kind: product
title: "A session that answers nothing"
status: done
state_hub_workstream_id: "c4c2fcbe-064c-4c19-b851-1d8d5940a24c"
---
# Purpose
@ -41,6 +42,7 @@ thrown away.
id: CB-WP-0035-T01
status: done
priority: high
state_hub_task_id: "7be2de30-1077-439a-8e70-a20031e9ba97"
```
**Controls:**

View file

@ -1,216 +1,132 @@
---
id: CB-WP-0036
kind: product
title: "Interactive Mode: the rituals and the movement"
status: ready
title: "Pace and ornamentation"
status: active
state_hub_workstream_id: "698651ed-cccd-46f2-84cc-07b0bdb85ad0"
---
# 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)
structural tier M (a driver parameter and a declared vocabulary; the
animation architecture that made this L has moved
out of this repo)
chaos d8 = 7 → no override
declared tier L
declared tier M
```
**Declaration 7 of chaos window 3.**
**Re-declared 2026-08-07, declaration 8 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.
## Why this was rewritten, and what it used to say
## The report
Declared on 2026-08-07 as **tier L**, covering an animation layer,
Rust-computed transitions over the journal delta, and a client/server
interaction able to animate other players' moves. Chaos was d8 = 7, no
override. **No code was written**, and the tier-L adversarial review was
never run — which is the only reason this could be re-scoped rather than
unwound.
> *"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."*
**The maintainer moved the animation out of clay-borg**, and the reasoning
is now [`specs/Ornamentation.md`](../specs/Ornamentation.md):
Named in the report:
> the basic simulator should have the relevant concepts of simulation and
> interaction, feedback mechanisms etc. with very simple ui concepts and
> frontend, backend interactions to keep the focus on the game and
> simulation core
| | |
|---|---|
| **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 |
So movement, timing and layering belong to a later, separate
**`clay-animate`**; material behaviour to **`clay-physics`** beyond that.
**What stays here is the vocabulary, the boundary and the pace knob** —
and the invariants that keep the boundary real once something downstream
exists to test it.
## What makes this tier L, and it is not the animation
**Two terms changed and the change is not cosmetic.** "Ritual" became
**ornamentation**, because half the category is material rather than
ceremonial — card stock, a typeface, the drift of a discard. And the test
is no longer *"does it have a decision in it"*: choosing who deals is a
decision and is ornamental. **The test is whether the state hash moves**,
which is executable, and which settles the open question the previous
version of this workplan left for a reviewer.
**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.
## Task: decide the pace, and what it may not touch
## Task: the concept, in the spec that governs structure
```task
id: CB-WP-0036-T01
status: todo
status: done
priority: high
```
`decisions/ADR-0020-*.md`.
**Controls:**
- the boundary has a **falsifier**, not just a diagram;
- ornamentation is defined by a test something can **run**, not by taste;
- it says what is deliberately **not** built and why.
- **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.
**Done 2026-08-07.** [`specs/Ornamentation.md`](../specs/Ornamentation.md).
## Task: transitions, computed in Rust
**§1.1 makes the line executable** by reusing `state_hash` — the same
instrument that binds a trial note to a position (ADR-0019 D3).
**§2 is the part that earns its place in this repo rather than a
renderer's stylesheet.** Calling something ornamentation is a claim that
it does not matter, and this project's register is a list of times that
claim was wrong — `quantity` in `Tokens.csv`, F18's four unread files,
SOLVE offered where it could not act. So a declaration carries a
falsifier, and *provisional* is a state it must be able to say out loud.
**§3.1 restates ADR-0007 D5 one level up:** downstream may read, may not
decide. **§3.2 refuses to design the port**, because no consumer exists
and an interface built against an imagined client is the same defect as a
gate that cannot go red.
**§5 gives five invariants, four of them checkable today.** I3 — the same
seed and decisions produce a byte-identical recording at any pace, through
any renderer — is the falsifier for the whole split.
## Task: the pace parameter
```task
id: CB-WP-0036-T02
status: todo
priority: high
priority: medium
```
The journal delta since the page last
rendered, expressed as movements: what moved, from where, to where, and
whether it stays.
`--pace speed | interactive`, defaulting to **speed**, and **not**
`--mode` (taken by `ScoringMode`).
- **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.
**Controls:**
- **I4 measured, not asserted**: `sim`, `trials` and the benchmarks are
unaffected — *nothing*, not *little*;
- `prefers-reduced-motion` behaves as speed;
- **the flag exists before anything reads it**, and that is deliberate:
it is the seam `clay-animate` will attach to, and a seam is cheap while
a retrofit is not.
## Task: the movement itself
## Task: declarations, once there are any to make
```task
id: CB-WP-0036-T03
status: todo
priority: high
priority: low
```
A layer above the game layer; card summoned
larger next to the acting seat, shrinking toward its target; discards
drifting without shrinking.
Ornamentation declarations per §2.1 — what is ornamented, why it does not
bind, what would falsify it.
- **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.
**Not started deliberately.** GameDesign §2's rule applies: **no kind
exists without an instance that instantiates it.** The first real
declarations are most likely to come from F18's unvendored files —
`Player_Mats` and `Glossary` are ornamentation-bearing data this engine
has never read — so **vendoring those is the trigger**, not a schema
designed in advance.
## Task: the rituals
## No longer in this repo
```task
id: CB-WP-0036-T04
status: todo
priority: medium
```
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: the hand: dealt from the right, sortable
```task
id: CB-WP-0036-T05
status: todo
priority: medium
```
Cards enter from the right; drag to reorder.
- **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: evidence
```task
id: CB-WP-0036-T06
status: todo
priority: medium
```
`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.
- **the animation layer**, transitions over the journal delta, cards
summoned larger beside a seat and shrinking toward a target, discards
drifting — **`clay-animate`**;
- **material simulation****`clay-physics`**;
- **hand sorting**, which was T05 here: it is presentation of a hand whose
*contents* are mechanism, so it goes with the renderer. The constraint
survives the move and is now I1: sorting must not move `state_hash`,
because a hash that moved would break every trial note's binding.