clay-borg/workplans/CB-WP-0028-the-table-you-sit-at.md
tegwick efe9f8f1a9
Some checks failed
ci / check (push) Failing after 3s
Sync hub state for CB-WP-0028
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 15:35:47 +02:00

286 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: CB-WP-0028
kind: product
title: "The table you sit at: the cards' own words, an overhead view, and a game you solve rather than survive"
status: ready
state_hub_workstream_id: "d37c8671-54e4-447f-af64-56f482483282"
---
# Purpose
```
structural tier M (imports more of the authoritative edition, which is
an external dataset under AM-4's budgets, and touches
the rendering the coverage gate is written against)
chaos d8 = 1 → no override
declared tier M
```
Declaration 11 of chaos window 2. Tier M: survey and decision merged;
adversarial review optional.
## Nine observations from play
The maintainer played with the new meta panel and reported nine things.
**Two are findings about the game, seven are about the engine**, and the
split matters because they go to different places.
| # | observation | where it goes |
|---|---|---|
| 1 | no incentive to attack while holding positive cards | **register** — a game-design finding |
| 2 | *"I don't understand the GROUND card"* | **here** — and it is not a design gap (below) |
| 3 | overhead view: players around a table, stacks on it | T03 |
| 4 | click the draw stack to take cards | T04 |
| 5 | optional auto-draw | T04 |
| 6 | play again / stop belong in the meta column | T05 |
| 7 | so does the full log | T05 |
| 8 | *"Game over"* is wrong when you won | T06 |
| 9 | rankings — MVP, most problems solved | T07 |
## Observation 2 is a data-import gap, and it reframes the pass
*"I don't understand the GROUND card or why other cards should be played
to the table"* reads as a design problem. It is not. **The card explains
itself in the dataset and we never imported the explanation.**
`ground-game/editions/*/Actions.csv`, the GROUND row:
> **tagline:** *"Regulate. Restore the frame. Decide."*
> **rules_text:** *"After all actions are revealed, choose one mode:
> GR—Ground & Restate: 2 Stress, ready Freedom… OU—Observe & Uphold…"*
**We vendored one file of nineteen.** `editions/ground-darvo-r0/` holds
`Problems.csv` and nothing else; `Actions`, `Solutions`, `Modes`,
`Scenarios`, `Relations`, `DARVO`, `Tokens`, `Glossary` and the rest live
only in `ground-game`. Everything the engine knows about them is a
**hand-transcription into `GroundRules.md`'s 59 numbered rules** — which
is enough to *play* the game and gives a player nothing to *read*.
So the page shows `Clarify` where the card says **"Ask What Happened —
Invite a concrete account before judging."**
**This is the most valuable thing in the pass**, and it was found by a
player saying he did not understand something rather than by any gate.
Rule coverage is 59/59 and has been for weeks.
## Task: decide what else to import, and what it costs
```task
id: CB-WP-0028-T01
status: todo
priority: high
state_hub_task_id: "17e6f38c-1903-4bb2-aa20-37e76c8fc4e0"
```
`decisions/ADR-0015-*.md` (tier M merges survey and decision).
**ADR-0011 is the precedent and it constrains this.** It vendored
`Problems.csv` with a checked digest and a ~50-line hand reader, and
**refused the `csv` crate on proportion** — 17,651 lines against AM-4b's
19,742 of remaining headroom, 89% of the budget to read 20 rows.
Decide:
- **which files**, and the answer is not "all of them". `Actions`,
`Solutions` and `Modes` carry text a player reads. `BOM`, `Print_Manifest`,
`Back_Designs`, `Symbols` are production artifacts for a physical print
run and have no business here.
- **whether the hand reader survives contact.** `Solutions.csv` has
`microcopy` and `rules_text` — prose fields with commas, quotes and
possibly embedded newlines. ADR-0011 named exactly this as the revisit
condition: *"nested quoting, embedded newlines, multiple dialects."*
**If the reader cannot parse them correctly, say so and re-run the
dependency argument rather than writing a fragile parser.**
- **what happens when text and rules disagree.** `GroundRules.md` was
derived by hand from these files. If a `rules_text` contradicts a
numbered rule, that is a **finding**, and it goes to the register — not
a quiet edit of either.
- **`Extensions.csv` exists** and names content deliberately outside the
core. Decide whether it is imported at all; the answer is probably no,
but *"we did not know it existed"* must not be the reason.
## Task: the cards say what they do
```task
id: CB-WP-0028-T02
status: todo
priority: high
state_hub_task_id: "aa4453d2-a84e-4afc-8534-1feb835c4d5b"
```
Every card a player can see carries its own title, tagline and rules text,
from the edition — not from a phrase we invented.
- action cards: GROUND, SOLVE, INVESTIGATE, SUPPORT, ATTACK;
- Solution cards: the title and microcopy, not just the suit;
- the mode in play, with its own description.
**Controls:**
- **a test asserts the text comes from the dataset**, not from a Rust
literal — the whole point is that the game's own words reach the player,
and a hand-copied string drifts from the source it copies;
- the drag affordance still works: the explanation is *additional*, and
CB-WP-0020 T02 already found that replacing a label with an explanation
loses the label;
- **the page stays readable.** Five action cards with full rules text is a
wall; the tagline is the default and the rules text is on demand.
## Task: an overhead view of a real table
```task
id: CB-WP-0028-T03
status: todo
priority: high
state_hub_task_id: "2ff677ac-80ff-4618-ad7c-05b62c8f80c8"
```
> *"Players sitting around the table, the draw and discard stacks on it.
> An overhead view of a game table would instantly help with understanding
> what is going on."*
The seats become positions around a table rather than a row of cards; the
Problems, draw and discard sit in the middle; each seat's played card
appears in front of that seat.
**This subsumes `relations_svg`**, which already places seats on a circle
for the relationship graph — so the layout exists and is drawn twice, once
as a circle and once as a row. **One table, not two diagrams.**
**Controls:**
- the coverage gate still passes: every view field appears in the parsed
document. CB-WP-0027 showed a reflow costs nothing when probes name
facts; this is a bigger reflow and the same rule applies;
- **the viewer's own seat is identifiable at a glance** — a table where
you cannot find yourself is worse than a list;
- 2 through 6 seats all lay out without overlap, asserted per seat count
rather than eyeballed at 3.
## Task: take cards from the stack, or let the table do it
```task
id: CB-WP-0028-T04
status: todo
priority: medium
state_hub_task_id: "1106c60e-112b-401f-b854-eeec566ef3d1"
```
Observations 4 and 5. Clicking the draw stack to take a card is the
natural gesture; auto-draw is for when that stops being interesting.
**Both are subject to a rule the engine already has.** Drawing is not a
free action — GR-A01 draws a Solution as part of INVESTIGATE, and the deck
is not a thing a player may simply take from. **So this task must first
establish whether "click to draw" is a legal move at all**, and if it is
not, it is a **finding for `ground-game`**, not a feature: the maintainer
expected an interaction the rules do not offer, and that gap is the
signal.
**Do not implement a draw the rules do not have.** CB-WP-0023 exists
because SOLVE was offered where it could not act.
**Controls:**
- the answer to *"is clicking the deck a legal move?"* is in the task
record with the rule that settles it;
- auto-draw changes no outcome — a game played with it and without it from
the same seed produces the same end-state hash, or it is not automation
but a rules change.
## Task: the meta column takes the controls and the log
```task
id: CB-WP-0028-T05
status: todo
priority: medium
state_hub_task_id: "6c78e44e-38fc-451b-b1a0-205b1d079ca0"
```
Observations 6 and 7. `play again` and `end session` move to the meta
column, and the ending page gets the same two-column shape as the table —
it currently has none.
The full log belongs there too, which CB-WP-0027 did for the live page and
not for the ending page.
**Controls:**
- CB-WP-0024 T01's seal still works: acknowledging the end must still
remove every control, wherever they now live;
- the ending page's existing tests pass unchanged or the change is a
regression.
## Task: a game you solve
```task
id: CB-WP-0028-T06
status: todo
priority: medium
state_hub_task_id: "df0a967e-636b-4fe5-9926-4d73030a87d7"
```
> *"'Game Over' is negative and should only be used for lost games. If the
> players won, let's use 'Game solved'."*
**Right, and it is more than tone.** GROUND is a co-operative game about
repairing a situation; `group_success` means the table *solved* something.
"Game over" is arcade vocabulary for a failure state, and using it for a
win tells the player the wrong thing about what they just did.
**Controls:**
- the heading is a function of `outcome.group_success`, asserted **both
ways** — a test that only checks the win case passes for a page that
always says "solved";
- the no-outcome case (a game that ended badly) keeps its own wording and
claims neither.
## Task: who did what — rankings that are not invented
```task
id: CB-WP-0028-T07
status: todo
priority: medium
state_hub_task_id: "ad6e6f6f-e531-494c-b8a9-18dfdd14681c"
```
> *"A ranking of players in the final stats. 'Most valuable player', 'most
> problems solved' and other conditions that might apply."*
`OutcomeView` already carries `personal`, `winners`, `coalitions` and
`mastery`, and the aggregate knows who claimed each Problem.
**The risk is inventing scoring the game does not have.** *"Most problems
solved"* is countable from `claimed_by` and is a fact. *"Most valuable
player"* is a **judgement**, and any formula for it is a rule we made up.
So: **report what the game counts, and mark anything derived as ours.**
A superlative computed from real data is fine; a superlative presented as
if the rules defined it is the same defect as a provisional default
silently canonised.
**Controls:**
- every ranking names its source: a rule id, or *"clay-borg's reading"*;
- ties are handled and shown as ties, not broken arbitrarily — `Modes.csv`
has a `scoring_tiebreak` column, so the game may already say how;
- a ranking that no seat leads (nobody solved anything) renders as that,
not as an empty list.
## Task: evidence
```task
id: CB-WP-0028-T08
status: todo
priority: medium
state_hub_task_id: "a20a529e-0edf-49cc-9c80-7dba3b76cff5"
```
`evidence/CB-EV-0026-*.md`.
- **Whether importing the card text changed what the maintainer
understood** — observation 2 is the acceptance test and it has a person
attached to it.
- **Whether any `rules_text` contradicted `GroundRules.md`.** Nineteen
files were hand-transcribed into 59 rules; if the import surfaces a
disagreement, that is the most valuable output of this pass.
- **Whether "click the deck to draw" was legal**, and if not, what went to
`ground-game`.
- **What the overhead view cost the coverage gate**, against CB-WP-0027's
finding that a probe naming a fact survives a reflow.
- **Quote CB-WP-0027's cost by re-running the instrument.**