--- id: CB-WP-0021 kind: product title: "Import the edition: the game plays its own data" status: ready --- # Purpose ``` structural tier M (adds or refuses an external dependency, and changes how a game is set up — a canonical interface) chaos d8 = 7 → no override declared tier M ``` Declaration 4 of chaos window 2. ## The engine has been playing a stand-in `games/ground/src/lib.rs` builds Problems with `value: priority` and suits cycled by index. `editions/ground-darvo-r0/Problems.csv` has carried the real thing since 2026-07-31, and **GROUND-WP-0002 T01 ruled it authoritative on 2026-08-03**: | | problems/scenario | values | total | suits | |---|---:|---|---:|---| | `Problems.csv` | **5** | 2, 2, 2, 3, 3 | **12** | `required_solution` per problem | | the stand-in | 3 | 1, 2, 3 | **6** | cycled by index | GR-E01's thresholds are 2p → 5, 3–4p → 7, 5–6p → 9. **Ordinary against 12, unreachable against 6** — which is why the maintainer's last game ended `0` scores and `winners nobody`, and why clay-borg has been carrying `GR-E01 unreachable below 5 seats` as a rules gap for ground-game to rule on. It was never a rules gap. ## The constraint, measured before declaring **AM-4a has 3,798 lines of headroom.** A CSV crate costs, marginally against the shipped graph: | crate | lines | |---|---:| | `csv` | 14,291 | | `csv-core` | 3,360 | | `ryu` | 3,962 | | **marginal total** | **21,613** | **5.7× the available headroom.** `itoa`, `memchr`, `serde` and `serde_core` are already present and cost nothing; the parser itself is what does not fit. So the shipped runtime cannot gain a CSV parser, and that is settled by measurement rather than by preference. What remains is *which* of the alternatives to take, and that is the ADR. ## Task: decide how the data reaches the game ```task id: CB-WP-0021-T01 status: todo priority: high ``` Write `decisions/ADR-0011-*.md` (tier M: survey and decision in one). **Three questions, and the third is the one that bites.** **(a) Where does the data live?** `ground-game` is a separate repository. Depending on a sibling checkout makes the build depend on a path that may not exist; vendoring a copy makes clay-borg carry content it does not own. Whichever is chosen must say how a copy is known to be current, because a silently stale copy is worse than no copy. **(b) How is it parsed, given a CSV parser does not fit?** Candidates, and each needs its marginal cost stated rather than assumed: - hand-rolled reader in `games/ground` — small, but it is a parser we then own, and `problem_text` contains commas; - **bake it**: a dev-time step converts the CSV into a generated Rust module or compact literal, so the shipped runtime parses **nothing**. Then the generated artifact must be proven to match its source, which is the DFD class this repo already has machinery for; - load nothing at runtime and treat the data as scenario input. **(c) What does this do to determinism?** Problem values and required suits become part of `GroundState`, which is hashed (K7). **Every recorded state hash changes.** Before writing code, establish what actually pins a hash today — `make sim` runs 25 scenarios, `replay-test` re-executes bundles, and AM-7's probe asserts per-segment hashes. Say which of those break, and whether any of them are *supposed* to be stable across a content change. **This is the reason the ADR exists.** A content import that quietly invalidates every recorded hash, in a project whose central invariant is replay determinism, is not a data-loading change. ## Task: import it, and let the thresholds mean something ```task id: CB-WP-0021-T02 status: todo priority: high ``` Replace the stand-in. `setup` must build Problems from the edition data: `point_value`, `required_solution`, `visibility` (Surface → face up, Hidden → face down) and `hidden_priority`. **Controls:** - **The stand-in must become unreachable.** A test that the fixture constants no longer appear — a `value: priority` that survives beside real data is a fallback nobody will notice until the numbers look odd again. - **A scenario must be able to reach GR-E01's threshold at 2 players**, which is the specific thing that was impossible. Assert the arithmetic, not just that a game runs. - The 5-problem shape must survive: the stand-in dealt 3, and code that assumed 3 will not announce itself. ## Task: retire the rules gap that was never one ```task id: CB-WP-0021-T03 status: todo priority: medium ``` `gr-e01-threshold-unreachable-2p` is tagged `provisional: true` with `provisional_owner: ground-game`, and its description says group success *"is unreachable at 2, 3 and 4 players"*. If T02 lands, that scenario is asserting a property of the **stand-in**, not of the game. Retire or rewrite it, and **say which of the six provisional items this resolves**, so GROUND-WP-0002 T03 shrinks rather than being left to rediscover it. Message `ground-game` with the outcome — the last such message sat unread for four days because nothing pointed at it. Do **not** quietly delete a failing-in-fact scenario. CB-EV-0005: *a score improved by deleting the question is not an improvement.* ## Task: evidence ```task id: CB-WP-0021-T04 status: todo priority: high ``` `evidence/CB-EV-0019-*.md`. - **What the import cost**, against the 3,798 lines that were available. - **What broke**, especially hashes, and whether the blast radius was predicted in T01 or discovered in T02. If it was discovered, say so — that is the ADR having missed something. - **Whether the endings now mean anything**: play one and report the score against the threshold. - **Quote CB-WP-0020's cost by re-running the instrument.** - **Chaos: 4 of 12 in window 2.**