CB-WP-0021 T01/T02/T05: the engine plays its own data — AM-7 blocks
ADR-0011 decided it: vendor the CSV with a checked digest, read it with a ~50-line reader, and let the hashes move. The declaration's constraint was measured against the WRONG BUDGET. It said a CSV crate costs 21,613 against AM-4a's 3,798 of headroom, '5.7x over, settled by measurement'. But setup and problem_priorities are cfg(scenarios) and are not in the shipped runtime at all, so AM-4a never sees them. Against AM-4b, csv costs 17,651 against 19,742 -- it FITS, with 2,091 to spare. It is refused anyway, on proportion: 89% of the budget's remaining capacity to read 20 rows. The revisit condition is stated (nested quoting, embedded newlines, multiple dialects). GR-S01 now deals Surface + hidden 1..=k as ruled, with edition values and suits. Measured: 6/9/12 available against thresholds 5/7/9 -- the game is winnable at every seat count, which is what the maintainer could not do. gd0001 is INVERTED, not deleted, and now also asserts the 6/9/12 so a deal that is reachable for the wrong reason still fails. Blast radius was scenario expectations, exactly as the ADR predicted: no scenario pinned a hash and no bundle is committed. Six scenarios and two unit tests updated, each with a note. gr-e01-threshold-unreachable-2p is RENAMED to -reachable- and rewritten as the non-provisional import check ground-game asked for by name. gr-e03's setup was restructured, not just renumbered: with values 2,2,2 its personal-edge test would have tied three ways and asserted nothing. BLOCKING: AM-7 fails at median 0.845 against its 0.9 floor. Isolated across three runs -- 3 problems + stand-in 0.97, 3 problems + edition 0.909, 4 problems + edition 0.845. State is BOUNDED (proven: identical after 5k and 100k events), so this is not the unbounded-growth defect AM-7 exists to catch; it is a bigger working set streaming a long log. Whether AM-7's floor is still right for a larger aggregate is a spec question and lowering it requires an ADR, so it is not being tuned here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
f2281fa86c
commit
2da19a49b7
16 changed files with 593 additions and 167 deletions
118
decisions/ADR-0011-vendor-the-edition.md
Normal file
118
decisions/ADR-0011-vendor-the-edition.md
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
# ADR-0011: vendor the edition, read it by hand, and let the hashes move
|
||||
|
||||
status: accepted
|
||||
date: 2026-08-04
|
||||
decided by: agent, under the standing loop authorization
|
||||
tier: M (structural M — adds or refuses an external dependency and changes
|
||||
how a game is set up; chaos d8=7 → no override). Tier M merges survey and
|
||||
decision into one document, which this is.
|
||||
references: [CB-WP-0021](../workplans/CB-WP-0021-import-the-edition.md),
|
||||
[ADR-0007](ADR-0007-render-html-not-a-port.md) D3 (the acquisition rule),
|
||||
GROUND-WP-0002 T01 and GROUND-WP-0004 (ground-game's rulings)
|
||||
|
||||
## Context
|
||||
|
||||
`editions/ground-darvo-r0/Problems.csv` is authoritative (ground-game,
|
||||
2026-08-03) and the engine has been inventing Problem values and suits.
|
||||
GR-S01's deal was then ruled (2026-08-04): **Surface always ∪ hidden
|
||||
`1..k`**, k = 2/3/4, giving available points **6 / 9 / 12** — which holds
|
||||
*only* with the real values.
|
||||
|
||||
## Correction: the constraint was measured against the wrong budget
|
||||
|
||||
**CB-WP-0021's declaration said a CSV crate costs 21,613 lines against
|
||||
AM-4a's 3,798 of headroom — "5.7× over, settled by measurement rather
|
||||
than preference."**
|
||||
|
||||
`setup` and `problem_priorities` are `#[cfg(feature = "scenarios")]`.
|
||||
**They are not in the shipped runtime at all**, so AM-4a never sees them
|
||||
and never would have. The budget that applies is AM-4b, and measured
|
||||
against *its* graph:
|
||||
|
||||
| | lines |
|
||||
|---|---:|
|
||||
| AM-4b headroom (745,000 − 725,258) | **19,742** |
|
||||
| `csv` marginal cost (`csv` + `csv-core`; `ryu`, `itoa`, `memchr` already present via `serde_json`) | **17,651** |
|
||||
|
||||
**It fits, with 2,091 lines to spare.** The declaration's confident
|
||||
"settled by measurement" was measurement of the wrong thing — the third
|
||||
premise this pass has had to correct, and the second where a real number
|
||||
was computed against a mis-chosen denominator.
|
||||
|
||||
## Decision 1 — refuse `csv`, on proportion rather than impossibility
|
||||
|
||||
It fits and it is still refused, and the distinction matters because the
|
||||
argument has to survive someone re-running the numbers.
|
||||
|
||||
**17,651 lines is 89% of everything AM-4b has left, to read 20 rows.** The
|
||||
next dependency after it would have 2,091 lines to live in. A hand-rolled
|
||||
reader for this grammar is ~50 lines we own.
|
||||
|
||||
INTENT's rule is *"assimilate the implementation"* — but that is about
|
||||
**mature optimized libraries** for hard problems. Splitting quoted CSV
|
||||
fields is not one, and `Problems.csv` is 20 rows read once at setup.
|
||||
Taking a general parser here would spend the budget's remaining capacity
|
||||
on the easiest problem we have.
|
||||
|
||||
**If the data grows into something a hand reader should not own — nested
|
||||
quoting, embedded newlines, multiple files with differing dialects — this
|
||||
decision is wrong and `csv` is the answer.** That is the condition to
|
||||
revisit under, stated now rather than left to taste.
|
||||
|
||||
## Decision 2 — vendor the file, with a checked provenance
|
||||
|
||||
`ground-game` is a separate repository. Two options:
|
||||
|
||||
| | cost |
|
||||
|---|---|
|
||||
| **sibling checkout** | the build depends on a path that may not exist. CI runs `rust:1.97` with this repo only, so `make all` would fail or silently skip — and a silent skip is the class this project has found seven times |
|
||||
| **vendor a copy** | clay-borg carries content it does not own, and a stale copy is worse than no copy |
|
||||
|
||||
**Vendored**, at `editions/ground-darvo-r0/Problems.csv`, with a
|
||||
`PROVENANCE` note naming the upstream repo, path and revision.
|
||||
|
||||
The staleness answer is a **committed digest of the upstream file**. A
|
||||
check compares it when `../ground-game` is present, and reports
|
||||
**`upstream not checked out`** as a distinct outcome when it is not — never
|
||||
a pass. That is the shape ADR-0009 used for `node`: an absent thing is
|
||||
reported absent, not treated as satisfied.
|
||||
|
||||
**Acquisition rule (ADR-0007 D3):** this is content the build causes to be
|
||||
present, and it is ours now. It is not third-party *code* and does not
|
||||
enter AM-4, but the provenance note is what stops it becoming
|
||||
unattributed.
|
||||
|
||||
## Decision 3 — the hashes move, and nothing pins them
|
||||
|
||||
Problem values and suits enter `GroundState`, which is hashed (K7). The
|
||||
declaration called this *"the reason the ADR exists."* Measured:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| scenario files pinning a state hash | **0** |
|
||||
| replay bundles committed | **0** |
|
||||
| scenarios asserting on `problems.N.*` | **10 of 25** |
|
||||
|
||||
**So the feared blast radius is not there.** K8's double-run compares two
|
||||
runs of the same build; AM-7's probe compares segments within one run;
|
||||
`replay-test` generates its bundle at run time. All are self-consistent
|
||||
and survive a content change by construction.
|
||||
|
||||
What breaks is **scenario expectations** — which is exactly what *should*
|
||||
break when the content changes, and is why they are written as `expect`
|
||||
blocks rather than hashes.
|
||||
|
||||
**No hash is grandfathered and none is recorded as "was".** A recorded
|
||||
hash that outlives the content it describes is a lie with a timestamp.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The deal fix and the import land **together**. The ruled 6/9/12 holds
|
||||
only with real values; the same deal with the stand-in gives 6/10/15, a
|
||||
game nobody ruled on.
|
||||
- `gd0001` is **inverted, not deleted** — it is the record of why the game
|
||||
became winnable.
|
||||
- If ground-game revises `r0` in place, the digest check fails loudly.
|
||||
Per GROUND-WP-0002 T01's proposed contract, `point_value` and
|
||||
`required_solution` may not change within a revision; this is the
|
||||
mechanism that notices if they do.
|
||||
Loading…
Add table
Add a link
Reference in a new issue