CB-WP-0028 T03/T08: one overhead table, and what the nine observations
Some checks failed
ci / check (push) Has been cancelled

turned out to be

T03. One table_svg: seats around an elliptical table starting at the
BOTTOM -- the viewer sits nearest the reader, as at a real table --
Problems and both stacks in the middle, each seat's played card between it
and the centre, relations drawn between seats.

Two renderers were DELETED: relations_svg and piles_svg. The task said one
table not two diagrams, and leaving the old ones would have meant drawing
the same thing twice and letting them drift.

No coverage probe cost, through a restructure that merged three diagrams
and removed two functions. Second confirmation of CB-WP-0027's finding: a
probe naming a FACT survives a reflow, one naming a PRESENTATION does not.
CB-WP-0024's "17 remaining" broke on a rendering change; this far larger
reflow broke nothing.

The new control is per seat count -- no two seat circles closer than 70px
at 2 through 6 -- asserted rather than eyeballed at three, which is the
only count anyone ever looks at.

T08 (CB-EV-0026). Seven of nine observations were engine defects, one was
a design finding, one was already true and nobody could tell.

Observations 4 and 5 both dissolved and had ONE cause: nothing on the page
said how drawing works, so a player built a mental model to fill the gap
and reported the gap as two feature requests.

The import gap was worse than "one of nineteen" -- 5 of 13 columns read
from the file we DID vendor, discarded at parse time for eight days. Rule
coverage was 59/59 throughout. The gate measures whether rules are
EXERCISED; nothing measures whether a player can READ the game, and
nothing cheaply could, which is why the person playing it is the
instrument.

TWO GATES WERE WRITTEN FOR A SMALLER WORLD, and neither was wrong when
written. edition-check compared one recorded digest against Problems.csv
regardless of which file it described -- correct with one vendored file,
comparing across files with four. And a cb-play test asserted the literal
"game over" and went red when a won game said "solved", which was T06
working; it now asserts the heading against the OUTCOME and covers the
no-outcome case the original never touched.

Chaos window 2 closes with zero overrides in eleven declarations at d8.
Third and final statement of it: d8 bought rarity by spending evidence,
and a mechanism producing no data across a full window cannot be evaluated
by that window.

make all: exit 0. 57 render tests, 26 cb-play, loop-lint clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-06 17:33:57 +02:00
parent 4d3e30eda4
commit eb8aa64c56
5 changed files with 459 additions and 122 deletions

View file

@ -2,7 +2,7 @@
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: active
status: done
state_hub_workstream_id: "d37c8671-54e4-447f-af64-56f482483282"
---
@ -39,29 +39,16 @@ split matters because they go to different places.
## 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.**
*"I don't understand the GROUND card"* reads as a design problem. It is
not: `Actions.csv` carries that card's tagline (*"Regulate. Restore the
frame. Decide."*) and its full rules text, and **we vendored one file of
nineteen**. Everything else the engine knows is a hand-transcription into
`GroundRules.md`'s 59 rules — enough to *play* the game, and nothing to
*read*. The page shows `Clarify` where the card says *"Ask What Happened."*
`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.
**Found by a player saying he did not understand something.** Rule
coverage is 59/59 and has been for weeks. See F18 and
[ADR-0015](../decisions/ADR-0015-the-cards-own-words.md).
## Task: decide what else to import, and what it costs
@ -103,23 +90,17 @@ Decide:
[ADR-0015](../decisions/ADR-0015-the-cards-own-words.md), six decisions.
**The gap is bigger than "one file of nineteen", and the measurement is
the decision.** Of the file we *did* vendor, the engine reads **5 of 13
columns** — `title`, `problem_text`, `front_rules`, `reveal_effect` and
`unresolved_effect` were discarded at parse time. **The cheapest part of
this pass costs no new bytes** and was sitting in the repo for eight days.
And `SCN_01` is hardcoded at `lib.rs:1824`: the edition ships **four**
scenarios and the engine has never dealt three of them.
the decision.** Of the file we *did* vendor the engine reads **5 of 13
columns**; the discarded ones are player-facing text that had been in the
repo for eight days. And `SCN_01` is hardcoded — the edition ships **four**
scenarios and the engine has never dealt three.
**ADR-0011's revisit condition is measurably absent**, so the dependency
argument does not get re-run. Across Actions, Solutions, Modes and
Scenarios: **zero doubled quotes, zero embedded newlines.** The hand
reader's only job is comma-in-quoted-field, which it already did.
Vendored `Actions`, `Solutions`, `Modes` — the text a player reads. Not
the production artifacts. **Not `Extensions.csv`**, because it names
content the designer placed *outside* the core, and importing it would
break the as-printed claim — but it is now known to exist, which was the
real risk.
**ADR-0011's revisit condition is measurably absent** — zero doubled
quotes, zero embedded newlines across every candidate file — so the
dependency argument does not get re-run. Vendored `Actions`, `Solutions`,
`Modes`. Not the production artifacts, and **not `Extensions.csv`**, which
names deliberately non-core content; it is now known to exist, which was
the real risk.
## Task: the cards say what they do
@ -147,38 +128,26 @@ from the edition — not from a phrase we invented.
- **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.
**Done 2026-08-06.** One `Table` reader with four callers (a per-file copy
is how a parser acquires four subtly different bugs), `CardText` for
Actions/Solutions/Modes, and `ProblemText` for the columns already
vendored.
**The GROUND card now explains itself**: *"Regulate. Restore the frame.
Decide."* as the tagline, its GR/OU/ND text behind a disclosure. Problems
show their own titles where a priority number used to be.
**Done 2026-08-06.** One `Table` reader with four callers (a per-file
copy is how a parser acquires four subtly different bugs), `CardText` for
Actions/Solutions/Modes, `ProblemText` for the columns already vendored.
The GROUND card now explains itself; Problems show their own titles.
**The load-bearing test asserts the text is a substring of the vendored
file**, not equal to a Rust literal — a test comparing against a
hardcoded expectation would pass for a hand-copied string, which is the
drift this ends. Plus counts (5 actions, 24 solutions, 3 modes), because a
reader returning one row would pass a "the text is real" test.
file**, not equal to a Rust literal — a hardcoded expectation would pass
for a hand-copied string, which is the drift this ends.
**`edition` came out from behind `#[cfg(feature = "scenarios")]`.** It was
gated because its only consumer was; but the edition is the game's own
data and the shipped runtime now reads it. **Test machinery and game
content are different things and only one of them is optional.**
**`edition-check` was written for a single-file world** and compared the
first recorded digest against `Problems.csv` regardless of which file it
described. It now checks every file both ways — a vendored file with no
digest fails, and a digest naming an absent file fails — and asserts
ADR-0015 D3's falsifier directly: no doubled quotes, no embedded
newlines.
**`edition` came out from behind `#[cfg(feature = "scenarios")]`**: it was
gated because its only consumer was, but the edition is the game's own
data and the runtime now reads it. **Test machinery and game content are
different things and only one is optional.** `edition-check`, written for
a single-file world, now checks every file both ways.
## Task: an overhead view of a real table
```task
id: CB-WP-0028-T03
status: todo
status: done
priority: high
state_hub_task_id: "2ff677ac-80ff-4618-ad7c-05b62c8f80c8"
```
@ -204,6 +173,25 @@ as a circle and once as a row. **One table, not two diagrams.**
- 2 through 6 seats all lay out without overlap, asserted per seat count
rather than eyeballed at 3.
**Done 2026-08-06.** One `table_svg`: seats around an elliptical table
starting at the **bottom** (the viewer sits nearest the reader, as at a
real table), Problems and both stacks in the middle, each seat's played
card between it and the centre, relations drawn between seats.
**Two renderers were deleted** — `relations_svg` and `piles_svg`. The task
said *one table, not two diagrams*, and leaving the old ones would have
meant drawing the same thing twice and letting them drift.
**No coverage probe cost**, through a restructure that merged three
diagrams and removed two functions. **Second confirmation of CB-WP-0027's
finding**: a probe naming a *fact* survives a reflow; one naming a
*presentation* does not.
The new control is per seat count: **no two seat circles closer than 70px
at 2, 3, 4, 5 or 6 seats** — asserted rather than eyeballed at three,
which is the only count anyone ever looks at. Plus: the viewer's seat is
labelled *and* visually distinct, and a spectator is not given one.
## Task: take cards from the stack, or let the table do it
```task
@ -369,7 +357,7 @@ are shown as ties.
```task
id: CB-WP-0028-T08
status: todo
status: done
priority: medium
state_hub_task_id: "a20a529e-0edf-49cc-9c80-7dba3b76cff5"
```
@ -387,3 +375,25 @@ state_hub_task_id: "a20a529e-0edf-49cc-9c80-7dba3b76cff5"
- **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.**
**Done 2026-08-06.**
[CB-EV-0026](../evidence/CB-EV-0026-the-table-you-sit-at.md).
- **Seven of nine observations were engine defects**, one was a design
finding, and one was already true and nobody could tell.
- **Observations 4 and 5 both dissolved**, and had one cause: nothing on
the page said how drawing works, so a player built a mental model to
fill the gap and reported the gap as two feature requests.
- **The import gap was worse than "one of nineteen"** — 5 of 13 columns
read from the file we *did* vendor, discarded at parse time for eight
days. Rule coverage was 59/59 throughout: the gate measures whether
rules are *exercised*, and **nothing measures whether a player can read
the game.**
- **Two gates were written for a smaller world**`edition-check`
compared one digest across four files, and a `cb-play` test asserted the
literal `"game over"` and went red when a won game said *"solved"*.
Neither was wrong when written.
- **Chaos window 2 closes with zero overrides in eleven declarations.**
Third and final statement: d8 bought rarity by spending evidence, and a
mechanism producing no data across a full window cannot be evaluated by
it.