Files
rune/scripts/check_memory_store_stats_parity.py
T
Nick 5591f3a921 feat(memory_store): close stats-family audit gaps — dichotomy wave
WORKING-SET/STATS/AUDIT lane (builder factory-heavy-ms-stats): the 5
currently-unmatched slice fns ported name-preserving into the
memory-store-deep Go corpus in a NEW family file gaps_stats.go (siblings
untouched) — reindex_entries (gap census + dry-run + full rebuild with
contentless-FTS5 DROP/recreate + vec_missing/fts_missing counting),
wake_up (CHAR-budgeted '- text' lines — rune count, never bytes),
storage_backend (R2 W2.0 read-backend seam: sqlite default,
RUNE_MEMORY_STORAGE=rust opt-in via injectable probe; loader is FFI
machinery), stats_for_path (stats through the seam; by_topic EMISSION
order preserved via parallel pair list — Go maps sort it away),
handle_hook (default envelope). The other 12 slice fns were already
landed by earlier waves (main.go/gaps_retrieval.go) — audit re-run first
per law.

Truth: 24-row truth_stats_gaps.json from the live oracle under pinned
rigs (frozen clock, _embed off/scripted, fake mems_loader sys.modules
injection, plain-table entries_vec mirror — vec0 observed only through
COUNT/JOIN/DELETE/INSERT). Battery gaps_stats_test.go replays
canonically (GAPS_TRUTH_PATH override); live parity 24/24 (fresh
capture → diff vs frozen → Go battery); gofmt/vet/build/full-test
clean; Python module suite failure sets byte-identical across both
pins (RUNE_RETRIEVAL_CORE live + python, 9 pre-existing, none this
port — no tracked Python/tests files touched); ruff clean. Documented
divergences in verification/msstats-summary.md: contentless-FTS5 NULL
text readback (both engines), json.dumps float-list format (pyJSONFloatList
mirror, integral floats keep .0), by_topic tie order engine-shaped
(distinct-count fixtures). Audit: memory_store 44/68 → 51/68; the
read_query ×2 counters (dm lane's slice) also flipped via this port's
ReadQuery interface method name — name-collision flip, NOT a dm port.
2026-10-15 02:38:09 +01:00

65 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""check_memory_store_stats_parity.py — live parity for the memory_store
STATS family gap port (builder factory-heavy-ms-stats).
Regenerates the truth corpus from the LIVE oracle (all rigs active) into a
temp file, byte-compares it against the committed frozen truth (drift gate),
then replays the FRESH corpus through the Go battery via GAPS_TRUTH_PATH.
Green = the Go kernels in src/go/memory-store-deep/gaps_stats.go agree with
the live Python oracle on every row, in both directions.
Usage: python3 scripts/check_memory_store_stats_parity.py
"""
import subprocess
import sys
import tempfile
from pathlib import Path
REPO = Path(__file__).resolve().parent.parent
GEN = REPO / "scripts/gen_memory_store_stats_truth.py"
TRUTH = REPO / "src/go/memory-store-deep/truth_stats_gaps.json"
GO_DIR = REPO / "src/go/memory-store-deep"
def run(cmd, **kw):
print("+", " ".join(str(c) for c in cmd))
return subprocess.run(cmd, capture_output=True, text=True, **kw)
def main() -> int:
tmp = Path(tempfile.mkdtemp(prefix="ms_stats_parity_")) / "truth_fresh.json"
r = run([sys.executable, str(GEN), "--out", str(tmp)])
print(r.stdout.strip() or r.stderr.strip())
if r.returncode != 0:
print("FAIL: generator crashed")
return 1
# drift gate: fresh capture must equal the committed frozen truth
r = run(["diff", str(TRUTH), str(tmp)])
if r.returncode != 0:
print("FAIL: live oracle drifted from frozen truth:")
print(r.stdout[:2000])
return 1
print("frozen truth == fresh live capture (byte-identical)")
# battery replay against the FRESH corpus
import os
env = dict(os.environ, GAPS_TRUTH_PATH=str(tmp))
r = run(["go", "test", "-run", "TestStatsGapsParity", "-v", "./..."],
cwd=GO_DIR, env=env)
out = r.stdout + r.stderr
print(out[-1500:])
if r.returncode != 0:
print("FAIL: Go battery diverges from live-oracle truth")
return 1
n = TRUTH.read_text().count('"fn"')
print(f"PARITY OK: {n} frozen rows byte-stable + Go battery green on fresh truth")
return 0
if __name__ == "__main__":
sys.exit(main())