CB-WP-0027: the commentary track — declare and register
Some checks are pending
ci / check (push) Waiting to run
Some checks are pending
ci / check (push) Waiting to run
The maintainer's ask: game interface left, meta and commentary right, with comments bound to game state so a test player's perception, confusion and reasoning become reviewable signal. Declared M (chaos d8=7, no override, declaration 10 of window 2). It touches two canonical interfaces: ADR-0007 D5's input contract, which currently admits only raw pointer facts, and the recorded-session format, which is deny_unknown_fields -- CB-WP-0026 just proved that bites. FRAMED AS GameDesign §5's TRIAL PROTOCOL MADE ERGONOMIC, because that is what it is. The protocol already exists and nobody would use it as written: it asks the player to reconstruct their reasoning afterwards, from memory, in a sibling file. A comment typed while the position is on screen is contemporaneous, bound to something replayable, and captures the one class of signal no gate in this project can see -- confusion and frustration. The reason it is worth more than a comment box: GameDesign §3.1 makes a note unreportable until it has a reproduction, and three findings are stuck there now (F12, F14, F15). A comment bound to a recorded state, plus the recording, is the cheapest reproduction a play-derived observation can have. So the pass closes the register's input path for findings that come from playing rather than from building. The failure it must not reproduce is named up front: a pile of prose nobody reads is this project's signature defect -- the four-day unread message, the ten uncollected rulings. Storage is not the deliverable, surfacing is, and T04 carries it. T01 (ADR-0014) must decide where comments live, what the page may send (D5's transport widens from two ids to arbitrary user text -- amended or merely scoped?), what binds a comment to a position, and the retention question this project has not faced: these are the maintainer's own words about his own game, one will eventually be unflattering, and whether they travel to ground-game needs deciding before any are written. T03 notes that esc() is about to face its first hostile input -- until now it has escaped suit names. loop-lint: no findings. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
c75ddf7697
commit
fe772eebc9
1 changed files with 229 additions and 0 deletions
229
workplans/CB-WP-0027-the-commentary-track.md
Normal file
229
workplans/CB-WP-0027-the-commentary-track.md
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
---
|
||||
id: CB-WP-0027
|
||||
kind: product
|
||||
title: "The commentary track: the meta view beside the table, and what the player says while playing"
|
||||
status: ready
|
||||
---
|
||||
|
||||
# Purpose
|
||||
|
||||
```
|
||||
structural tier M (touches two canonical interfaces — ADR-0007 D5's
|
||||
input contract, which currently admits only pointer
|
||||
facts, and the recorded-session format, which is
|
||||
`deny_unknown_fields`)
|
||||
chaos d8 = 7 → no override
|
||||
declared tier M
|
||||
```
|
||||
|
||||
Declaration 10 of chaos window 2. Tier M: survey and decision merged into
|
||||
one document; adversarial review optional.
|
||||
|
||||
## The maintainer's ask
|
||||
|
||||
> *"Extend the UI to provide the evaluation meta view to the game. Game
|
||||
> interface to the left, meta and commentary to the right. As a test
|
||||
> player I can provide comments about how I perceive the game or why I am
|
||||
> playing a move — signal about unclear situations, frustration etc. —
|
||||
> bound to the game state, reviewable for potential optimizations."*
|
||||
|
||||
## This is `GameDesign.md` §5's trial protocol, made ergonomic
|
||||
|
||||
**The protocol already exists and nobody would use it as written.** A
|
||||
trial game is a `--record`ed session plus a sibling `trials/<date>.md`
|
||||
written *afterwards*, from memory. The spec says it "must cost almost
|
||||
nothing or it will not be done" — and then asks the player to reconstruct
|
||||
their own reasoning after the fact.
|
||||
|
||||
A comment typed **while the position is on screen** is better in three
|
||||
ways that matter to this project:
|
||||
|
||||
1. **It is contemporaneous.** *"Why am I playing this"* is available for
|
||||
about ten seconds and then it is gone.
|
||||
2. **It is bound to a position**, so it points at something replayable
|
||||
rather than at a memory.
|
||||
3. **It captures the class of signal nothing else here can.** Confusion,
|
||||
frustration, and *"I don't understand what this does"* are invisible to
|
||||
every gate in the project, and they are the observations that produce
|
||||
design findings rather than engine findings.
|
||||
|
||||
## Why this is worth more than a comment box
|
||||
|
||||
**GameDesign §3.1 makes a note unreportable until it has a reproduction.**
|
||||
Three findings are stuck there right now: F12 (GR-A13 wasted SOLVE), F14
|
||||
(GR-E03/E04 never played) and F15 (the series question). Each is real and
|
||||
none can go to `ground-game`.
|
||||
|
||||
**A comment bound to a recorded state, plus the recording, is the cheapest
|
||||
reproduction a play-derived observation can have.** *"This felt pointless"*
|
||||
attached to a replayable position is a different artifact from *"this felt
|
||||
pointless"* in a file — the reader can go and look.
|
||||
|
||||
So the pass is not "add a text box". It is **closing the register's input
|
||||
path for findings that come from playing rather than from building.**
|
||||
|
||||
## The failure this must not reproduce
|
||||
|
||||
**A pile of prose nobody reads is this project's signature defect.** The
|
||||
message that sat unread for four days; the ten rulings that arrived and
|
||||
were never collected. A commentary feature that stores comments and
|
||||
surfaces them nowhere is that failure in a new medium, and it would be the
|
||||
third instance.
|
||||
|
||||
> **Storage is not the deliverable. Surfacing is.**
|
||||
|
||||
T04 carries this and no task may be called done while comments are
|
||||
write-only.
|
||||
|
||||
## Task: decide where comments live and what the page may send
|
||||
|
||||
```task
|
||||
id: CB-WP-0027-T01
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
`decisions/ADR-0014-*.md` (tier M merges survey and decision).
|
||||
|
||||
**Three questions, and the second is the one that bites.**
|
||||
|
||||
**(a) Where does a comment live?** Candidates: inside the recorded
|
||||
`ScenarioFile`; in the `trials/<date>-<slug>.md` sibling `GameDesign.md`
|
||||
§5 already specifies; or a third file keyed to the recording. Note
|
||||
CB-WP-0026 added four fields to `ScenarioFile` and the schema is
|
||||
`deny_unknown_fields` — **a scenario is a game record, and mixing a
|
||||
player's prose into it may be the wrong shape.** Say which and why.
|
||||
|
||||
**(b) What may the page send?** ADR-0007 **Decision 5** currently binds
|
||||
the browser to *raw pointer facts* — `down on id`, `up on id` — and
|
||||
forbids JavaScript from constructing commands. **A comment is not a
|
||||
command**, so D5 is arguably untouched; but the transport widens from two
|
||||
ids to arbitrary user text, and that must be *decided* rather than
|
||||
assumed. State whether D5 is amended or merely scoped, and what stops the
|
||||
new channel from becoming a command channel later.
|
||||
|
||||
**(c) What binds a comment to the game?** Round and step are readable but
|
||||
weak. **The end-state hash is the strong binding** — it is what makes a
|
||||
session comparable to its replay (`Summary::end_state_hash`), so a comment
|
||||
keyed to a hash points at a position a reader can reach. Decide whether
|
||||
the binding is the hash, the command index, or both, and what happens to a
|
||||
comment whose position no longer replays.
|
||||
|
||||
**Also decide the retention question**, because it is a boundary this
|
||||
project has not faced: these comments are **the maintainer's own words
|
||||
about his own game**, and one of them will eventually be unflattering
|
||||
about the design or about the engine. State whether they are private to
|
||||
the repo, whether they travel to `ground-game`, and who decides.
|
||||
|
||||
## Task: the table on the left, the meta on the right
|
||||
|
||||
```task
|
||||
id: CB-WP-0027-T02
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Two columns: the game as it is today on the left, a meta panel on the
|
||||
right. The log moves into the right column — it is commentary on the game,
|
||||
not part of the table.
|
||||
|
||||
**What goes in the meta panel**, beyond the log and the comment box:
|
||||
|
||||
- the **session tally** (CB-WP-0024 T04), which currently only appears at
|
||||
the end;
|
||||
- the **register's open notes** for this game, if any — the point of the
|
||||
panel is that the player can see what has already been observed;
|
||||
- whatever CB-WP-0025's witness produces, **when it is wired** — it is not
|
||||
yet, and this task does not wire it.
|
||||
|
||||
**Controls:**
|
||||
- the layout must survive a narrow viewport — a two-column desktop layout
|
||||
that unreadably overlaps on a laptop is a regression, and the existing
|
||||
page is responsive by accident rather than by design, so this is the
|
||||
moment it becomes deliberate;
|
||||
- **every existing coverage probe must still pass.** `RENDERED` in
|
||||
`lib.rs` asserts each view field appears in the *parsed* document; a
|
||||
reflow that drops one fails the build, and that is the gate working;
|
||||
- the game column must be usable with the meta column collapsed. A player
|
||||
who does not want to write anything must not be worse off.
|
||||
|
||||
## Task: capture what the player says, bound to where they said it
|
||||
|
||||
```task
|
||||
id: CB-WP-0027-T03
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
A comment box in the meta panel, posting to the existing guarded endpoint.
|
||||
|
||||
**The escaping is not incidental.** `esc()` exists and every interpolated
|
||||
value goes through it, with a comment in the source saying *"cannot
|
||||
currently carry a `<`" is how injection bugs are written*. This is the
|
||||
first user-authored free text the page has ever handled, so it is the
|
||||
first time that comment is load-bearing rather than precautionary.
|
||||
|
||||
**Controls:**
|
||||
- **a comment containing `<script>` renders as text**, asserted on the
|
||||
emitted document — the first real test of `esc()` against hostile input
|
||||
rather than against suit names;
|
||||
- a comment is bound to the position per T01's decision, and a test
|
||||
asserts the binding **resolves**: a stored comment names a state that
|
||||
the recording can reach;
|
||||
- the empty comment is not stored — a blank note is noise in the register;
|
||||
- **the game is playable with comments disabled**, and a test says so. The
|
||||
commentary track must not become a dependency of playing.
|
||||
|
||||
## Task: surface them, or this pass has failed
|
||||
|
||||
```task
|
||||
id: CB-WP-0027-T04
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
**The load-bearing task.** Comments must be readable *outside* the
|
||||
session that produced them, by a command, without opening a file by hand.
|
||||
|
||||
- `make design` (or a sibling) reports comments **with their positions**,
|
||||
because a comment without its position is prose again;
|
||||
- a comment can be **promoted to a register note** — that is the input
|
||||
path this pass exists to close, and it should cost one step;
|
||||
- **age is reported.** GameDesign §3.1 expires notes at 30 days on the
|
||||
existing `PROVISIONAL_WARN_DAYS` machinery; comments should not get a
|
||||
private mechanism.
|
||||
|
||||
**Controls:**
|
||||
- a comment written in a session is visible from a command in a *later*
|
||||
session — the whole failure mode is signal that only exists while
|
||||
someone is looking at it;
|
||||
- **the reporting path is exercised by the self-test**, not only the
|
||||
parsing. `design-baseline.py` had a self-test and a reporting path with
|
||||
no CI, and the reporting path was where it rotted (ADR-0012 D8);
|
||||
- promoting a comment to a note produces a register row that
|
||||
`tools/design.py` accepts — if the register cannot express it, the shape
|
||||
is wrong and that is a finding about ADR-0012, not a bug.
|
||||
|
||||
## Task: evidence
|
||||
|
||||
```task
|
||||
id: CB-WP-0027-T05
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
`evidence/CB-EV-0025-*.md`.
|
||||
|
||||
- **Whether a comment actually got written during play**, by the
|
||||
maintainer, unprompted. The protocol's own test is whether it costs
|
||||
little enough to use; anything else is a claim about a feature nobody
|
||||
exercised.
|
||||
- **Whether any stuck note moved.** F12, F14 and F15 are unreportable for
|
||||
want of a reproduction; if the commentary path unblocks even one, that
|
||||
is the pass's real result.
|
||||
- **What the escaping test found**, since it is the first hostile input
|
||||
this renderer has seen.
|
||||
- **Whether the two-column layout cost any coverage probe**, and what that
|
||||
says about how tightly the gate is coupled to the document's shape.
|
||||
- **Quote CB-WP-0025's cost by re-running the instrument** — and note that
|
||||
CB-EV-0019 §4's unbounded chain is still unbounded.
|
||||
Loading…
Add table
Add a link
Reference in a new issue