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

@ -42,6 +42,8 @@
| workplan | CB-WP-0032 | done | — | workplans/CB-WP-0032-the-comments-in-the-account.md |
| workplan | CB-WP-0033 | done | — | workplans/CB-WP-0033-a-game-is-the-unit.md |
| workplan | CB-WP-0034 | done | — | workplans/CB-WP-0034-who-you-are-bonding-with.md |
| workplan | CB-WP-0035 | done | — | workplans/CB-WP-0035-a-session-that-answers-nothing.md |
| workplan | CB-WP-0036 | ready | — | workplans/CB-WP-0036-interactive-mode.md |
| task | CB-WP-0001-T01 | done | — | workplans/CB-WP-0001-inner-loop.md |
| task | CB-WP-0001-T02 | done | — | workplans/CB-WP-0001-inner-loop.md |
| task | CB-WP-0001-T03 | done | — | workplans/CB-WP-0001-inner-loop.md |
@ -207,3 +209,10 @@
| task | CB-WP-0032-T01 | done | — | workplans/CB-WP-0032-the-comments-in-the-account.md |
| task | CB-WP-0033-T01 | done | — | workplans/CB-WP-0033-a-game-is-the-unit.md |
| task | CB-WP-0034-T01 | done | — | workplans/CB-WP-0034-who-you-are-bonding-with.md |
| task | CB-WP-0035-T01 | done | — | workplans/CB-WP-0035-a-session-that-answers-nothing.md |
| task | CB-WP-0036-T01 | todo | — | workplans/CB-WP-0036-interactive-mode.md |
| task | CB-WP-0036-T02 | todo | — | workplans/CB-WP-0036-interactive-mode.md |
| task | CB-WP-0036-T03 | todo | — | workplans/CB-WP-0036-interactive-mode.md |
| task | CB-WP-0036-T04 | todo | — | workplans/CB-WP-0036-interactive-mode.md |
| task | CB-WP-0036-T05 | todo | — | workplans/CB-WP-0036-interactive-mode.md |
| task | CB-WP-0036-T06 | todo | — | workplans/CB-WP-0036-interactive-mode.md |

View file

@ -5,6 +5,9 @@ the stable structural decisions: layers, component planes, capability ports,
data flows, and repository layout. For motivation and product intent see
[`../INTENT.md`](../INTENT.md); for the full originating exploration see
[`../history/260730-InitialExploration.md`](../history/260730-InitialExploration.md).
For the boundary between what the rules can see and everything else a
player experiences — and which repository each belongs to as the simulator
grows — see [`Ornamentation.md`](Ornamentation.md).
Status: **draft** — this blueprint is normative for new work but still
malleable (Clay). Changes go through a decision record in `decisions/`.

250
specs/Ornamentation.md Normal file
View file

@ -0,0 +1,250 @@
# Ornamentation — what a game is besides its rules
Status: **draft**, normative for new work. Changes go through a decision
record in `decisions/`.
Companion to [`ArchitectureBlueprint.md`](ArchitectureBlueprint.md)
(layers and ports) and [`GameDesign.md`](GameDesign.md) (findings about
the game). This document draws **one boundary**: between what the rules
can see and everything else a player experiences — and says which repo
each belongs to as the simulator grows.
> **A good game is not only its rules.** It is materials, flow, timing,
> relatability, illustration, typography, and the ceremony around play.
> A simulator that models only the rules models a *part* of the game, and
> should say which part rather than implying it is the whole.
---
## 1. Two categories, and the test between them
**Mechanism** is anything that can change the state the rules can see.
**Ornamentation** is everything else the player nonetheless experiences.
### 1.1 The test
> **Does it move the state hash?**
>
> If yes, it is mechanism. If no, it is ornamentation.
This reuses an instrument the project already has and already trusts:
`state_hash` is what makes a session comparable to its replay, and what a
trial note binds to (ADR-0019 D3). **The line is therefore executable, not
editorial** — which matters here more than elsewhere, because everything
downstream depends on the classification being right.
### 1.2 Ornamentation usually decorates a mechanism rather than replacing it
The clearest case, and the one that named this document:
| the fact | category | why |
|---|---|---|
| the deck's permutation | **mechanism** | it decides the deal; in clay-borg it comes from the seed |
| **who shuffles**, and the shuffling | **ornamentation** | no rule can see it |
| the hands after dealing | **mechanism** | the state contains them |
| **who deals**, cards arriving one at a time, entering from the right | **ornamentation** | the same hands either way |
So ornamentation is typically **a ceremony around, or a presentation of, a
mechanism** — and occasionally a thing with no mechanism under it at all.
**"Has a decision in it" is NOT the test.** Choosing who deals is a
decision, and it is ornamentation. This was the open question in
CB-WP-0036 and the maintainer settled it: these are ornamental *because
they are not necessary*, not because nobody chooses.
### 1.3 Why not "ritual"
`ritual` reads as ceremony only, and half of this category is not
ceremonial — card stock, a typeface, the drift of a discard, how legible a
player mat is. **`ornamentation` covers the material and the ceremonial
together**, and carries the right implication: it is *applied to* the
thing, and it is not structural.
Ornamentation is **not decoration in the pejorative sense**. This project
uses "decoration" for a control that cannot fail (ADR-0006 D3), and that
word is spoken for.
---
## 2. Why clay-borg names what it will never render
The rendering belongs downstream (§3). The **classification does not**,
for one reason:
> **Calling something ornamentation is a claim that it does not matter to
> the game — and claims that something does not matter are exactly the
> claims this project has been wrong about.**
The register is the evidence. `quantity` in `Tokens.csv` was measured
across 750 games before being declared non-binding (CB-EV-0027 §3), and
the argument that settled it was *not* "nothing exceeded it" — it was that
no numbered rule mentions a supply, so enforcing one would have been the
engine deciding a rules question. F18 stands open because four edition
files were assumed not to matter. CB-WP-0023 exists because SOLVE was
offered where it could not act.
**A classification is a claim about the game.** It therefore belongs where
this project keeps claims about the game — with a reproduction and a
falsifier (GameDesign §1) — and not in a renderer's stylesheet, where
nothing can contradict it.
### 2.1 What a declaration carries
1. **What it ornaments** — the mechanism it accompanies, or `none`.
2. **Why it does not bind** — by rule text where the edition has one, or
by measurement, or explicitly *"provisional, nobody has ruled"*.
3. **What would falsify it** — the rule or observation that would make it
mechanism. A declaration that cannot be wrong is not a claim.
**Provisional is a legitimate state and must be said out loud.** The
failure mode this project has already committed once is canonising a
provisional default by implementing it quietly.
### 2.2 Ornamentation is sourced, not invented
ADR-0015's discipline applies unchanged: **the game's own words, where the
game has words.** Card text, mat layout, the vocabulary in `Glossary` and
the stage names in `DARVO` are ornamentation-bearing data that exists
upstream and is currently **unvendored** (F18).
Where the edition says nothing, clay-borg may choose — and must **label
the choice as ours**, exactly as the rankings panel labels its one derived
superlative *"clay-borg's reading, not a rule"* (CB-EV-0026 §5).
---
## 3. The module boundary
```mermaid
flowchart LR
CB["clay-borg
state - rules - admissibility
trials - findings
ornamentation DECLARED
one simple built-in view"]
CA["clay-animate
movement - timing - layering
the interactive pace's presentation"]
CP["clay-physics
material simulation
cards - table - gravity"]
CB -->|"facts + declarations"| CA
CA --> CP
```
**clay-borg is the simulation core and stays that way.** Its built-in view
is deliberately plain: simple frontend/backend interaction, simple UI
concepts, so attention stays on the game and the simulation rather than on
a rendering pipeline. **Its native pace is Speed** (§4), and it is tuned
for that.
**clay-animate** is where movement lives: a card summoned larger beside
the acting seat, shrinking toward its target, a discard drifting without
resizing. It is a *later, separate repository* and needs a client/server
interaction materially more complex than the core should carry.
**clay-physics** is further out still: real material behaviour.
### 3.1 The rule that makes the boundary hold
> **Downstream may read. Downstream may not decide.**
This is [ADR-0007](../decisions/ADR-0007-hot-seat-in-a-browser.md) D5 —
*the page reports raw pointer facts and constructs no commands* — restated
one level up, at the repository boundary rather than the script boundary.
A game played through `clay-animate` must be **indistinguishable, in the
record, from the same game played through clay-borg's own view.** If a
renderer can change an outcome it is not a renderer.
### 3.2 Why the port is not being built yet
**No consumer exists.** This project's own rules say a kind with no
instance was invented rather than observed (GameDesign §2) and a gate that
cannot go red is decoration (ADR-0006 D3). An interface designed against
an imagined client would be both.
**What is being fixed now is the vocabulary and the boundary.** The port
gets designed when `clay-animate` exists to pull on it, and the first
version of it should be *the data clay-borg already emits* — the journal
is already the sequence of what happened, and CB-WP-0032 already reads it.
---
## 4. Pace
`--pace speed | interactive` (proposed; **not** `--mode`, which is
already `ScoringMode`).
| pace | what it means |
|---|---|
| **speed** | ornamentation is skipped; the view jumps to the result. **The default**, and what `sim`, `trials`, benchmarks and bot play always use |
| **interactive** | ornamentation is performed |
Pace selects **how much ornamentation is performed**. It can never select
*different mechanism*, which §5 states as an invariant rather than an
intention.
`prefers-reduced-motion` behaves as **speed**.
---
## 5. Invariants
These are the document's teeth. **I1I4 are checkable today, cheaply**,
which is the point — this project has 62 untagged literals as evidence of
what a broad unenforced requirement produces (ADR-0018 D4).
| | invariant |
|---|---|
| **I1** | Ornamentation never moves `state_hash`. |
| **I2** | Ornamentation never enters the journal or the recording. |
| **I3** | The same seed and the same decisions produce a **byte-identical recording** at any pace, through any renderer. |
| **I4** | Speed pace costs the core **nothing** — not "little": `sim`, `trials` and the benchmarks are unaffected. |
| **I5** | Every ornamentation declaration states what would falsify it (§2.1). |
**I3 is the falsifier for the whole boundary.** If it ever fails,
something downstream has become mechanism and the split has stopped being
real.
### 5.1 What to do when ornamentation must be preserved
I2 keeps the recording canonical, which raises a fair objection: a replay
then cannot reproduce **what a player actually saw**.
The answer already exists in this repo. A trial keeps *two* files — the
recording and a sibling log of what the player said (GameDesign §5). **A
session's ornamentation goes in a sibling too**, never in the scenario.
One artifact stays replayable; the other stays human.
---
## 6. Where a new capability goes
In order. The first match wins.
1. **Can it change a legal move, an outcome, or the state hash?**
→ clay-borg, as mechanism, under the existing rule budgets.
2. **Is it a claim that something does *not* matter?**
→ clay-borg, as a declared ornamentation with a falsifier (§2.1).
**This is the step that gets skipped**, and skipping it is how a
provisional default becomes canon without anyone deciding.
3. **Is it the presentation, timing or movement of either?**
→ clay-animate.
4. **Does it need materials to behave like materials?**
→ clay-physics.
5. **None of these?** Then it is not yet understood well enough to place,
and the honest move is a finding, not a module.
---
## 7. Falsifier for this document
If an ornamentation declaration is ever found to have changed an outcome,
§1.1's test is not the right test and this document is wrong at the root —
not patchable at the edges.
If, after `clay-animate` exists, **§3.2's deferred port turns out to have
needed designing here all along**, then the "no consumer, no interface"
rule cost more than it saved, and that should be recorded against it.

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.