Some checks failed
ci / check (push) Failing after 3s
Vendored DARVO.csv, Relations.csv and Scenarios.csv — the three unread files that carry mechanism. The engine has implemented the DARVO sequence and relation formation/breaking from GroundRules.md since the beginning, and had never read the game owner's statement of them. Every checkable clause agrees, and agreement is recorded rather than noted: a survey that finds nothing and leaves no trace cannot be told from one never run. The two hardest clauses to notice were already right — Focus placed "even if the Attack was cancelled", and Focus removed when the sequence ends before REVERSE. The tests are tripwires, not derivations. The match was made by a person reading prose, and that reading goes stale in silence when the prose changes; each behaviour pins the phrase it was read from, so a reworded edition goes red and asks for a human. Mutation-proven by rewording the cancelled-Attack clause. F25 raised, and it is the real yield: Scenarios.csv carries threshold_2_players/3_4/5_6, starting_stress and round_track, and the engine hardcodes all three — a match returning 5/7/9, stress: 2 at setup, five rounds. They agree on all four scenarios. These are the most contested numbers in the project; the whole 4/6/9 vs 5/7/9 episode turned on them, and the engine has been right by maintenance coincidence rather than by reading the file that owns them. Also pinned: Problems.csv and Scenarios.csv both state the deal and the engine reads only the first. They agree; nothing was checking. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
317 lines
19 KiB
Markdown
317 lines
19 KiB
Markdown
# The finding register
|
||
|
||
Design findings about **GROUND**, with their reproductions. Governed by
|
||
[`GameDesign.md`](GameDesign.md) (admissibility, kinds, states, metrics)
|
||
and [ADR-0012](../decisions/ADR-0012-the-design-instrument.md). Reported
|
||
by `make design`.
|
||
|
||
**Split out of `GroundRules.md §Underdetermined` on 2026-08-05** when that
|
||
file crossed the ~400-line loadability limit. ADR-0012 D2 said *"no new
|
||
file"* and this is a new file — but D2's substance was **one register, not
|
||
a second mechanism competing with the first**, and that holds: this *is*
|
||
§Underdetermined's register, moved, still driving off the same
|
||
`provisional`/ruling machinery. D2 also named the awkwardness this
|
||
resolves — a finding about the engine sitting in a document about the
|
||
game.
|
||
|
||
The U-items themselves, with their defaults and rulings, stay in
|
||
[`GroundRules.md §Underdetermined`](GroundRules.md); this file tracks them
|
||
*as findings*.
|
||
|
||
**This section is the design-finding register** (ADR-0012 D2). It was the
|
||
register for dataset ambiguities already; CB-WP-0022 extended it to all
|
||
five kinds rather than building a second one beside it. Admissibility,
|
||
kinds, states and metrics: [`GameDesign.md`](GameDesign.md). Reported by
|
||
`make design`.
|
||
|
||
<!-- design-register:begin -->
|
||
|
||
| id | kind | state | reproduction | role | raised | owner |
|
||
|---|---|---|---|---|---|---|
|
||
| U1 | underdetermined | applied | — | default | 2026-07-31 | ground-game |
|
||
| U2 | underdetermined | applied | scenarios/ground/gr-d01-darvo-trigger.yaml | default | 2026-07-31 | ground-game |
|
||
| U3 | underdetermined | applied | — | default | 2026-07-31 | ground-game |
|
||
| U4 | underdetermined | applied | — | default | 2026-07-31 | ground-game |
|
||
| U5 | underdetermined | applied | — | default | 2026-07-31 | ground-game |
|
||
| U6 | underdetermined | applied | — | default | 2026-07-31 | ground-game |
|
||
| U7 | underdetermined | applied | — | default | 2026-07-31 | ground-game |
|
||
| U8 | underdetermined | applied | — | default | 2026-07-31 | ground-game |
|
||
| U9 | underdetermined | applied | — | default | 2026-07-31 | ground-game |
|
||
| U10 | underdetermined | applied | — | default | 2026-07-31 | ground-game |
|
||
| F11 | inert | applied | scenarios/ground/gr-p05-solve-legality.yaml | counterexample | 2026-08-02 | clay-borg |
|
||
| F12 | degenerate | note | — | — | 2026-08-01 | clay-borg |
|
||
| F13 | inconsistent | withdrawn | scenarios/ground/gr-e01-threshold-reachable-2p.yaml | counterexample | 2026-08-01 | clay-borg |
|
||
| F14 | unplayed | applied | games/ground/examples/attack-value.rs | counterexample | 2026-08-01 | clay-borg |
|
||
| F15 | underdetermined | note | — | — | 2026-08-05 | clay-borg |
|
||
| F16 | inconsistent | withdrawn | games/ground/examples/difficulty.rs | counterexample | 2026-08-05 | clay-borg |
|
||
| F17 | degenerate | raised | games/ground/examples/attack-value.rs | counterexample | 2026-08-06 | ground-game |
|
||
| F18 | inert | raised | `games/ground/src/edition.rs::card_text_tests::the_engine_reads_only_part_of_what_it_vendored` | counterexample | 2026-08-06 | clay-borg |
|
||
| F25 | inert | raised | `games/ground/src/edition.rs::card_text_tests::the_engine_agrees_with_the_editions_own_numbers` | default | 2026-08-08 | clay-borg |
|
||
| F24 | inert | raised | `games/ground/src/edition.rs::card_text_tests::the_hardcoded_deck_still_matches_the_edition` | default | 2026-08-07 | clay-borg |
|
||
| F19 | degenerate | applied | crates/cb-render-html/src/lib.rs::overhead_table | counterexample | 2026-08-06 | clay-borg |
|
||
| F20 | inert | applied | crates/cb-render-html/src/lib.rs::ending_page | counterexample | 2026-08-06 | clay-borg |
|
||
| F21 | degenerate | note | — | — | 2026-08-06 | clay-borg |
|
||
| F23 | inconsistent | applied | decisions/ADR-0017-chaos-window-2-verdict.md | counterexample | 2026-08-07 | clay-borg |
|
||
| F22 | underdetermined | withdrawn | games_ground::edition::supply_tests::play_never_exceeds_the_components_the_box_holds | counterexample | 2026-08-07 | clay-borg |
|
||
|
||
<!-- design-register:end -->
|
||
|
||
- **F11 — SOLVE offered where it cannot act.** Offered on a face-down
|
||
Problem, or with no matching suit in hand; inert every time. Ruled
|
||
GROUND-WP-0002 T02, implemented CB-WP-0023 as GR-P05. `applied` — the
|
||
rule changed, not just the annotation. **The case we reported was not the
|
||
case that fired**: `validate` already rejected face-down, and the
|
||
maintainer's three inert SOLVEs were the *hand* case.
|
||
- **F12 — GR-A13 "wasted SOLVE" on an already-claimed Problem.** A
|
||
scenario had to pick a default and did. `note`: no artifact isolates the
|
||
degenerate line, so under GameDesign §3.1 it may not be reported until
|
||
one exists.
|
||
- **F13 — GR-E01 vs GR-S01, withdrawn 2026-08-05.** Raised as *"4/6/9
|
||
against 5/7/9, no dataset reconciles them."* `2da19a4` measured **6/9/12
|
||
against 5/7/9** and the scenario was renamed `-unreachable-` →
|
||
`-reachable-`. **Its reproduction is green**, which under GameDesign §1.3
|
||
is the alarm that forced the resolution. Withdrawn rather than deleted,
|
||
and the withdrawal is reported (ADR-0012 D5).
|
||
- **F16 — "the game is too easy at 5–6 seats", withdrawn the day it was
|
||
raised.** Claimed from `GreedyPolicy` winning 200/200 at those seat
|
||
counts. A `FirstLegal` policy scores **0%** on the identical deals, and
|
||
at two seats it *beats* greedy — two unsophisticated agents span the
|
||
whole range, so the measurement was about the policy. Caught by the
|
||
CB-WP-0025 adversarial review (C4) **before transmission**; it would
|
||
have been the fifth wrong premise sent to ground-game and the worst,
|
||
since GROUND-WP-0005 is blocked on exactly this number. The withdrawal
|
||
was reported (ADR-0012 D5). Its reproduction is `difficulty.rs`, whose
|
||
policy panel is plural *because of this finding*.
|
||
- **F23 — a false claim propagated five times by citation instead of
|
||
measurement.** CB-EV-0024 §6 stated that chaos window 2 produced **zero
|
||
overrides** and that its retirement condition was untestable. CB-EV-0025,
|
||
CB-EV-0026, CB-EV-0027 and CB-WP-0029 each repeated it, citing the one
|
||
before.
|
||
|
||
**It was false.** Declaration 3 (CB-WP-0020) rolled d8 = 8 and overrode —
|
||
and **CB-WP-0020 recorded it correctly at the time**, in those words:
|
||
*"the first override at d8… It changed nothing… **One.**"* Counting the
|
||
workplans takes one command.
|
||
|
||
**The subject makes it worse.** Three of those four files were arguing
|
||
that this project's defect is claims asserted without their
|
||
reproduction — while carrying one. `facts-check` catches a copied number
|
||
that disagrees with its source; nothing catches a number with **no
|
||
source**, asserted once and cited thereafter.
|
||
|
||
**`applied`** — ADR-0017 corrects it, and each of the four files carries
|
||
an in-place correction rather than a silent edit (ADR-0012 D5). **The
|
||
general defect is not fixed**: it is the same family as the five
|
||
wrong-subject instances, and still has no control.
|
||
- **F22 — does the component supply bind the game? Asked, measured, and
|
||
withdrawn.** `Tokens.csv` gives every component a `quantity` — 6
|
||
Protection, 5 Denied, 12 relation links — and **no numbered rule
|
||
mentions a supply**, so the engine could in principle mint a seventh
|
||
Protection token (`saturating_add`, no bound, `lib.rs:986`). Measured
|
||
over **750 games**, 2–6 seats, greedy and random: Protection reaches 1
|
||
per seat and 2 on the table; Denied 3 of 5; links **exactly 12 of 12**,
|
||
never over, because GR-L01's two-slot rule *is* the twelve-token supply
|
||
written twice. Focus/Blame: 0 conflicts. **Withdrawn — nothing to
|
||
report.** Registered as a stated negative because a survey that finds
|
||
nothing and leaves no trace cannot be told from one that was never run.
|
||
The check ships as a standing control (ADR-0016 D3): if play ever does
|
||
exceed a quantity, that is a **finding for ground-game** — *does the box
|
||
bound the game, or do the rules?* — and **not** a bound for the engine to
|
||
invent.
|
||
- **F21 — dragging did not work until after the first note was saved.**
|
||
Reported 2026-08-06: *"I could not drag and drop at the beginning but
|
||
after I added the first comment it worked."* **`note`, and I could not
|
||
reproduce it.** The gesture logic is correct against the served page
|
||
(the JS harness posts properly), the ghost carries `pointer-events:none`
|
||
so it cannot intercept the drop, and the markup is identical before and
|
||
after the note — the 303 re-renders the same page from the same state.
|
||
**Candidates, none confirmed:** a `<details>` toggle inside an action
|
||
card shifting the layout mid-drag; a first-load timing difference; or a
|
||
browser-level pointer capture. **Reproducing it needs a browser, which
|
||
no test here has** — the same gap F19 named. Recorded rather than
|
||
guessed at.
|
||
- **F20 — a click target wearing a drag affordance made the ending
|
||
controls look dead.** `play again`, `end session`, `pass` and the move
|
||
buttons carried `.pick`, which is `cursor:grab`. A grab cursor invites a
|
||
**drag**, and a drag released over nothing posts nothing — so the button
|
||
did nothing and appeared broken. Reported as two separate observations
|
||
(*"the button shows a hand to pick up that it probably shouldn't"* and
|
||
*"I can't start another game or stop the server"*) which are one defect.
|
||
**`applied`**: click targets now carry `.tap`. **This extends CB-WP-0017's
|
||
rule** — interactive and inert must not look identical — to *click and
|
||
drag must not look identical either*.
|
||
- **F19 — the engine shipped a table nobody could play on, and every gate
|
||
was green.** CB-WP-0028's overhead view was 620px tall, so the action
|
||
cards sat a screen below the Problems; dragging between them was
|
||
physically impossible. Seats were drawn *inside* the table, and the
|
||
`table` drop target was a card among the buttons rather than the drawn
|
||
surface. **`make all` passed throughout**, because every test asserted
|
||
the DOM was correct — which it was. The JS harness even posts a correct
|
||
gesture against a page a human cannot drag on. `degenerate`: the feature
|
||
fires and collapses play. **`applied`** — fixed 2026-08-06, with height,
|
||
seat-position and single-drop-zone proxies added. **They are proxies.**
|
||
Nothing here lays out a browser, and the gap CB-EV-0026 named — that no
|
||
gate measures whether a player can play — is unclosed.
|
||
- **F17 — ATTACK cannot affect whether the table succeeds.** Reported
|
||
from play as *"there is no incentive to play attacks as long as I have
|
||
positive cards"*, and **the artifact now exists**:
|
||
`games/ground/examples/attack-value.rs`, 200 games per cell, one number
|
||
varied — ATTACK's rank in an otherwise identical policy.
|
||
|
||
| ATTACK ranked | wins (2/3/4/5/6p) | attacks | DARVO armed |
|
||
|---|---|---:|---:|
|
||
| 10 (below all) | 132 / 165 / 190 / 200 / 200 | 0 | 0 |
|
||
| 75 (above SUPPORT) | **132 / 165 / 190 / 200 / 200** | 315–923 | 13–218 |
|
||
| 95 (above SOLVE) | **0 / 0 / 0 / 0 / 0** | 1400–5170 | 400–1000 |
|
||
|
||
**The middle row is the finding: identical win counts at every seat
|
||
count**, while attacking hundreds of times and arming DARVO. Attacking
|
||
is not punished — it is **inert with respect to the goal**. Group success
|
||
is a function of SOLVE alone, and ATTACK only costs anything when it
|
||
ranks above SOLVE and displaces it.
|
||
|
||
**So the maintainer was right and the reason is sharper than the
|
||
phrasing.** There is no incentive because there is no *path*: ATTACK's
|
||
effects (Stress, Rivalry, DARVO) feed nothing that decides
|
||
`group_success`.
|
||
|
||
**Asked in all three modes 2026-08-07, and ATTACK earns its place in
|
||
none of them:**
|
||
|
||
| mode | never attack | attack sometimes |
|
||
|---|---|---|
|
||
| SHARED GROUND | 132/165/190/200 | **identical** — free but pointless |
|
||
| COMMON PROBLEM | 59/52/48/44 | 59/52/48/**34** — a cost at six seats |
|
||
| BONDED COALITIONS | 131/134/132/116 | **59/52/48/34** — roughly halved |
|
||
|
||
**The coalitions row has a mechanism the data confirms.** GR-A07 flips a
|
||
Bond to a Rivalry on Attack, and GR-E04 scores Bond *networks* — so
|
||
attacking destroys the thing that scores. And the attacking numbers in
|
||
E04 are **identical** to E03's, which is exactly what that predicts:
|
||
break every Bond and each seat becomes a coalition of one, so GR-E04
|
||
degenerates into GR-E03.
|
||
|
||
**Not a claim that the game is broken.** DARVO is the pattern the game
|
||
is *about* not falling into; a self-destructive ATTACK may be the
|
||
design. The question for `ground-game` is whether the namesake mechanic
|
||
being unreachable in competent co-op play is intended.
|
||
- **F18 — the engine imports one of nineteen edition files, so the cards
|
||
cannot say what they do.** Reported as *"I don't understand the GROUND
|
||
card"* — which is not a design gap: `Actions.csv` carries that card's
|
||
tagline (*"Regulate. Restore the frame. Decide."*) and full rules text,
|
||
and clay-borg never imported it. Every other card is the same: a player
|
||
sees `Clarify` where the card reads *"Ask What Happened — Invite a
|
||
concrete account before judging."* **`inert`**: the data exists and
|
||
cannot fire, because nothing reads it. **Ours, and CB-WP-0028 fixes it.**
|
||
- **F25 — the engine hardcodes numbers the edition states.**
|
||
`GroundState::threshold` is a `match` returning 5/7/9 while
|
||
`Scenarios.csv` carries `threshold_2_players`, `threshold_3_4_players`
|
||
and `threshold_5_6_players`; setup writes `stress: 2` against *"All
|
||
players start at Stress 2."*; the engine plays five rounds against a
|
||
printed 1–5 track. **All three agree, on all four scenarios**, and that
|
||
is the finding rather than the reassurance: these are the most contested
|
||
numbers in the project — the whole 4/6/9 versus 5/7/9 episode turned on
|
||
them — and the engine has been right by maintenance coincidence rather
|
||
than by reading the file that owns them. **`inert`**, role `default`:
|
||
green because they agree, red the moment either side moves. **Ours.**
|
||
Same shape as F24.
|
||
|
||
- **F24 — the draw pile is a Rust literal.** `solution_deck()` builds six
|
||
of each suit from an array and never opens `Solutions.csv`, whose `suit`
|
||
and `quantity` columns say the same thing. **They agree today** — 24
|
||
rows, six per suit — so nothing is wrong now, and that is the point:
|
||
the engine is right by maintenance coincidence rather than by reading.
|
||
**`inert`**: the data exists and cannot fire. Role `default`, not
|
||
`counterexample` — the reproduction is green *because* the two agree,
|
||
which is the state GameDesign §1.3 says to expect from a documented
|
||
provisional choice, and it turns red the moment either side moves.
|
||
**Ours.** CB-WP-0037 T02 deletes the literal.
|
||
|
||
- **F15 — the rules define one game, not a series.** `OutcomeView` gives
|
||
`personal` (per seat), `group_success` (per table) and `winners`. Summing
|
||
the first and counting the third answer different questions, and GROUND
|
||
says nothing about how several games combine. CB-WP-0024 T04 shows
|
||
**both, labelled**, rather than picking one and letting it become the
|
||
score by default. `note`: no artifact demonstrates that this *harms*
|
||
play — a unit test showing the two tallies point at different seats
|
||
demonstrates only that they can differ, which is arithmetic, not a design
|
||
defect. Under GameDesign §3.1 it may not be reported until one exists.
|
||
- **F14 — GR-E03/GR-E04 never played to the end. Closed 2026-08-07, and
|
||
the reason they were unplayed was ours.** `cb-play` built every game with
|
||
`ScoringMode::SharedGround` and passed an **empty patch**, so two of the
|
||
three shipped modes were unreachable from the only way anyone plays. The
|
||
mode was patchable in *scenarios* and not from the *driver*. `--mode`
|
||
added; all three now play to the end and give **different winners from
|
||
identical play**: shared → all four seats, common → P3 alone, coalitions
|
||
→ P1+P2. **`applied`** — 800 games per mode in the reproduction.
|
||
|
||
### The register's first run found ten answers nobody had collected
|
||
|
||
**U1–U10 are `ruled`, not `reported`.** GROUND-WP-0002 T05 answered all
|
||
ten on **2026-08-03** — every one **confirmed** as the default clay-borg
|
||
already simulates — and GROUND-WP-0002 T03 confirmed five of the six
|
||
provisional scenarios, voiding `gr-e01` as a rules gap. The workplan is
|
||
`finished`.
|
||
|
||
CB-RES-0007 reported *"0 of 10 ruled"* and this register was built saying
|
||
`reported`. **Both were two days stale on the day they were written.** The
|
||
answers had arrived and nothing propagated them — the same failure as the
|
||
unread inbox, in the opposite direction.
|
||
|
||
**They are `ruled`, not `applied`, and the difference is work we owe.**
|
||
Per ADR-0012 D5, `applied` means the source changed and the provisional
|
||
default was deleted. The rulings *confirmed* our defaults, so the rules did
|
||
not move — but the scenarios still carry `provisional: true` for choices
|
||
that are now settled. **Lifting those flags and recording each ruling is
|
||
what closes U1–U10**, and it is not done. `make design` shows them open
|
||
until it is.
|
||
|
||
### The U-item ↔ scenario mapping, measured twice
|
||
|
||
**One U-item has a scenario that names it: U2.** CB-RES-0007 asserted six
|
||
of ten did.
|
||
|
||
CB-WP-0026 T03 tried to write the other mappings and **produced two wrong
|
||
ones before checking them**:
|
||
|
||
| claimed | why it was withdrawn |
|
||
|---|---|
|
||
| `gr-a04-bond-support` → U1 | it asserts consent is **required**; U1 asks **when** the target accepts. Different question. |
|
||
| `gr-d05-darvo-reverse` → U5 | it exercises the **unrejected** REVERSE; U5 is the **rejected** one (GROUND—ND). Different stage. |
|
||
|
||
Both were plausible from the `covers:` list and both were wrong on
|
||
reading the description. **That is the third and fourth instance of this
|
||
exact defect** — a link that looks right, asserted without checking what
|
||
the artifact actually exercises — and the first two reached ground-game.
|
||
|
||
So a scenario now declares `encodes_u_item` explicitly or claims nothing.
|
||
**Nine U-items have no reproduction and are recorded as having none.**
|
||
They are `applied` because the ruling landed and the provisional flag came
|
||
off, not because anything demonstrates them.
|
||
|
||
### What the backfill measured, and what it contradicted
|
||
|
||
**Only U2 names its U-item in a scenario.** Measured, not estimated:
|
||
|
||
```
|
||
for u in U1 .. U10; do grep -lE "\b$u\b" scenarios/ground/*.yaml; done
|
||
```
|
||
|
||
CB-RES-0007 asserted *"six of the ten already have provisional
|
||
scenarios."* Five provisional scenarios exist and **one** cites the item
|
||
it stands for. The other four may well encode U-item defaults — the
|
||
mapping is simply **not written down**, so it is not checkable, and an
|
||
uncheckable link is the defect this register exists to fix. The register
|
||
records what is citable; the rest is debt, visible in `make design`.
|
||
|
||
**No sixth kind was needed** — the five kinds absorbed all four non-U
|
||
findings. And the survey's *"six provisional defaults"* was **not** entered
|
||
as a finding: C3 showed it double-counted GR-E01, and the provisional
|
||
scenarios are *reproductions for* underdetermined items, not a finding of
|
||
their own.
|
||
|
||
**U1–U10 are `reported` while lacking reproductions**, which GameDesign
|
||
§3.1 would now forbid. They were reported on 2026-07-30, before the rule
|
||
existed. They are grandfathered rather than rewritten, and the debt is a
|
||
reported metric with a target of zero.
|
||
|