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
93
tools/edition-check.py
Executable file
93
tools/edition-check.py
Executable file
|
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Is the vendored edition still what ground-game published? (ADR-0011 D2)
|
||||
|
||||
`editions/ground-darvo-r0/` is a copy of content owned by another repo.
|
||||
A stale copy is worse than no copy, so the digest is committed and this
|
||||
compares it.
|
||||
|
||||
**An absent upstream is reported absent, never as a pass.** That is the
|
||||
shape ADR-0009 used for `node`: a check that cannot run says so, because
|
||||
a silent skip is the class this project has found seven times.
|
||||
"""
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from repo import ROOT, enter_root
|
||||
|
||||
VENDORED = "editions/ground-darvo-r0/Problems.csv"
|
||||
PROVENANCE = "editions/ground-darvo-r0/PROVENANCE.md"
|
||||
UPSTREAM = os.path.join(os.path.dirname(ROOT), "ground-game", VENDORED)
|
||||
|
||||
|
||||
def digest(path):
|
||||
return hashlib.sha256(open(path, "rb").read()).hexdigest()
|
||||
|
||||
|
||||
def recorded():
|
||||
text = open(os.path.join(ROOT, PROVENANCE)).read()
|
||||
m = re.search(r"sha256\s+([0-9a-f]{64})", text)
|
||||
if not m:
|
||||
raise ValueError(f"{PROVENANCE} records no sha256 digest")
|
||||
return m.group(1)
|
||||
|
||||
|
||||
def check():
|
||||
have = digest(os.path.join(ROOT, VENDORED))
|
||||
want = recorded()
|
||||
print("edition-check — vendored data against its provenance")
|
||||
if have != want:
|
||||
print(f" [FAIL] {VENDORED} does not match its recorded digest")
|
||||
print(f" recorded {want}\n actual {have}")
|
||||
return 1
|
||||
print(f" [ok ] vendored copy matches its recorded digest")
|
||||
|
||||
if not os.path.exists(UPSTREAM):
|
||||
# NOT a pass and NOT a failure: the question could not be asked.
|
||||
print(" [----] upstream not checked out — freshness UNVERIFIED")
|
||||
print(f" expected {UPSTREAM}")
|
||||
return 0
|
||||
up = digest(UPSTREAM)
|
||||
if up != have:
|
||||
print(" [FAIL] upstream has changed since this copy was vendored")
|
||||
print(f" upstream {up}\n vendored {have}")
|
||||
print(" ground-game froze point_value and required_solution")
|
||||
print(" within r0 — a change here is a new revision, or a")
|
||||
print(" contract violation worth raising.")
|
||||
return 1
|
||||
print(" [ok ] vendored copy is current with ../ground-game")
|
||||
return 0
|
||||
|
||||
|
||||
def self_test():
|
||||
"""A checker that cannot detect a mismatch is decoration."""
|
||||
results = []
|
||||
|
||||
def chk(name, ok, detail=""):
|
||||
results.append((name, ok, detail))
|
||||
|
||||
chk("the vendored file exists", os.path.exists(os.path.join(ROOT, VENDORED)))
|
||||
chk("provenance records a digest", len(recorded()) == 64)
|
||||
chk("digest of the real file matches provenance",
|
||||
digest(os.path.join(ROOT, VENDORED)) == recorded())
|
||||
# The control that matters: a changed byte must be detected.
|
||||
import tempfile
|
||||
with tempfile.NamedTemporaryFile("wb", delete=False) as fh:
|
||||
fh.write(open(os.path.join(ROOT, VENDORED), "rb").read() + b"\n#tamper\n")
|
||||
tampered = fh.name
|
||||
chk("a tampered copy has a different digest",
|
||||
digest(tampered) != recorded(), "otherwise the check is decoration")
|
||||
os.unlink(tampered)
|
||||
|
||||
print("edition-check self-test (positive control)")
|
||||
ok = True
|
||||
for name, passed, det in results:
|
||||
print(f" [{'ok ' if passed else 'FAIL'}] {name}" + (f" — {det}" if det else ""))
|
||||
ok &= passed
|
||||
return 0 if ok else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
enter_root()
|
||||
raise SystemExit(self_test() if "--self-test" in sys.argv else check())
|
||||
Loading…
Add table
Add a link
Reference in a new issue