#!/usr/bin/env python3 """gen_drift_cache_truth.py — freeze/replay parity truth for drift_cache (dichotomy wave, #2479 tranche). Freeze mode (default): exercises EVERY public function of the LIVE Python oracle (src/rune/drift_cache.py) across every branch and records (kernel_input, expected_kernel_output) pairs into src/rust/drift_cache/src/frozen_dc_truth.json. Replay mode (--replay): re-runs the SAME scenarios with the Rust core delegation active and asserts both kernel-level (loader direct) and facade-level (oracle methods delegate) parity against the frozen file. Poisoned-truth law: freeze pins RUNE_DC_CORE=python AND RUNE_MEMORY_CORE=python BEFORE any import (the module-level helpers carry an older _ms_core delegation chain that must never poison the truth). No-clock law: the wall clock is frozen by patching the datetime symbol in drift_cache, so every kernel payload carries its own `now` and replay is deterministic regardless of run date. Boundary law: the sqlite read (update_from_store's per-id SELECT) and the cache FILE IO (_load/_save, malformed-JSON reset) stay in the Python facade — the kernel is a pure function of their results. The `load` truth group is facade-only (no kernel symbol) and is skipped by the kernel-level replay pass. """ import copy import json import os import sqlite3 import sys import tempfile from datetime import datetime, timezone REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) TRUTH_PATH = os.path.join(REPO, "src", "rust", "drift_cache", "src", "frozen_dc_truth.json") REPLAY = "--replay" in sys.argv os.environ["RUNE_DC_CORE"] = "python" # poisoned-truth law (no-op pre-port, load-bearing post-port) os.environ["RUNE_MEMORY_CORE"] = "python" sys.path.insert(0, os.path.join(REPO, "src")) sys.path.insert(0, os.path.join(REPO, "src", "rune")) import drift_cache as oracle_mod # noqa: E402 if REPLAY: from rune import dc_loader # noqa: E402 (kernel-level replay side) FROZEN_UTC = datetime(2026, 10, 11, 12, 0, 0, 123456, tzinfo=timezone.utc) FROZEN_NOW = FROZEN_UTC.isoformat() class FrozenDatetime(datetime): @classmethod def now(cls, tz=None): return FROZEN_UTC oracle_mod.datetime = FrozenDatetime class Case: def __init__(self, name, fn): self.name = name self.fn = fn def fresh_cache(entries_pre=None): tmp = tempfile.mkdtemp(prefix="dc_truth_") oracle_mod.CACHE_DIR = tmp oracle_mod.CACHE_FILE = os.path.join(tmp, "drift_cache.json") cache = oracle_mod.DriftCache() if entries_pre is not None: cache.entries = copy.deepcopy(entries_pre) return cache def stamped(priority, wash=0, rock="washable", access_count=0): return {"priority": priority, "added_at": FROZEN_NOW, "last_accessed": FROZEN_NOW, "access_count": access_count, "wash_count": wash, "rock_status": rock} # ── compute_priority ───────────────────────────────────────────────────────── def c_prio_default(rec): rec("prio-default-empty-entry", {"entry": {}}, oracle_mod.compute_priority({}), {"priority": oracle_mod.compute_priority({})}) def c_prio_wash20_imp1(rec): e = {"wash_count": 20, "importance": 1.0} rec("prio-wash20-imp1-washfactor-1", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) def c_prio_typical(rec): e = {"wash_count": 7, "importance": 0.6} rec("prio-wash7-imp06", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) def c_prio_rock(rec): e = {"wash_count": 3, "importance": 0.7, "rock_status": "rock"} rec("prio-rock-boost", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) def c_prio_established(rec): e = {"wash_count": 3, "importance": 0.7, "rock_status": "established"} rec("prio-established-boost", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) def c_prio_none_wash(rec): e = {"wash_count": None, "importance": 0.9} rec("prio-none-wash-coerced-0", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) def c_prio_none_imp(rec): e = {"wash_count": 4, "importance": None} rec("prio-none-imp-coerced-05", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) def c_prio_zero_imp(rec): # falsy 0 → `or 0.5` coerces to 0.5 e = {"wash_count": 4, "importance": 0} rec("prio-zero-imp-coerced-05", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) def c_prio_int_importance(rec): e = {"wash_count": 2, "importance": 1} rec("prio-int-importance", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) def c_prio_wash_beyond_20(rec): # log1p scaling caps at 1.0 via min() e = {"wash_count": 1000, "importance": 0.5} rec("prio-wash1000-capped", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) def c_prio_unknown_status(rec): e = {"wash_count": 2, "importance": 0.5, "rock_status": "muddy"} rec("prio-unknown-status-no-boost", {"entry": e}, oracle_mod.compute_priority(e), {"priority": oracle_mod.compute_priority(e)}) # ── qualifies_for_cache ────────────────────────────────────────────────────── def _q_case(rec, name, entry): rec(name, {"entry": entry}, oracle_mod.qualifies_for_cache(entry), {"qualifies": oracle_mod.qualifies_for_cache(entry)}) def c_qual_below_both(rec): _q_case(rec, "qual-wash0-imp05-denied", {"wash_count": 0, "importance": 0.5}) def c_qual_imp_boundary(rec): _q_case(rec, "qual-imp-079-denied", {"wash_count": 0, "importance": 0.79}) def c_qual_imp_08_admitted(rec): _q_case(rec, "qual-imp-08-admitted", {"wash_count": 0, "importance": 0.8}) def c_qual_wash_boundary(rec): _q_case(rec, "qual-wash1-imp0-admitted", {"wash_count": 1, "importance": 0.0}) def c_qual_defaults(rec): _q_case(rec, "qual-defaults-denied", {}) def c_qual_none_fields(rec): _q_case(rec, "qual-none-fields-denied", {"wash_count": None, "importance": None}) def c_qual_proven(rec): _q_case(rec, "qual-wash5-admitted", {"wash_count": 5, "importance": 0.3}) # ── add ────────────────────────────────────────────────────────────────────── def _add_case(rec, name, entries_pre, entry_id, entry): cache = fresh_cache(entries_pre) cache.add(entry_id, entry) admitted = entry_id in cache.entries evicted = sorted(set(entries_pre) - set(cache.entries)) rec(name, {"entries": entries_pre, "entry_id": entry_id, "entry": entry, "now": FROZEN_NOW}, None, {"entries": cache.entries, "admitted": admitted, "evicted": evicted}) def c_add_denied(rec): _add_case(rec, "add-denied-unproven-unimportant", {}, 1, {"wash_count": 0, "importance": 0.5}) def c_add_denied_important_but_unwashed(rec): _add_case(rec, "add-denied-imp-below-08", {}, 2, {"wash_count": 0, "importance": 0.5, "text": "x"}) def c_add_washable(rec): _add_case(rec, "add-washable-admitted", {}, 3, {"wash_count": 2, "importance": 0.5, "rock_status": "washable"}) def c_add_high_importance_unwashed(rec): _add_case(rec, "add-important-unwashed-admitted", {}, 4, {"wash_count": 0, "importance": 0.95}) def c_add_rock(rec): _add_case(rec, "add-rock-stamped", {}, 5, {"wash_count": 3, "importance": 0.7, "rock_status": "rock"}) def c_add_overwrites(rec): pre = {7: stamped(0.9, wash=9, rock="rock", access_count=4)} _add_case(rec, "add-overwrites-existing", pre, 7, {"wash_count": 1, "importance": 0.4}) def c_add_rock_status_none(rec): # explicit None rock_status is stored verbatim (entry.get returns None) _add_case(rec, "add-rock-status-none-verbatim", {}, 8, {"wash_count": 2, "importance": 0.5, "rock_status": None}) def c_add_boundary_200_no_evict(rec): pre = {i: {"priority": (i + 1) / 200.0} for i in range(199)} _add_case(rec, "add-at-200-no-evict", pre, 199, {"wash_count": 20, "importance": 1.0}) def c_add_evict_lowest_20(rec): pre = {i: {"priority": (i + 1) / 200.0} for i in range(200)} _add_case(rec, "add-evicts-lowest-20", pre, 999, {"wash_count": 20, "importance": 1.0, "rock_status": "rock"}) def c_add_evict_tie_stable_order(rec): pre = {i: {"priority": 0.5} for i in range(196)} for i in range(196, 200): pre[i] = {"priority": 9.0} _add_case(rec, "add-evict-tie-stable-insertion-order", pre, 999, {"wash_count": 20, "importance": 1.0}) # ── access ─────────────────────────────────────────────────────────────────── def _access_case(rec, name, entries_pre, entry_id): cache = fresh_cache(entries_pre) cache.access(entry_id) changed = entry_id in entries_pre rec(name, {"entries": entries_pre, "entry_id": entry_id, "now": FROZEN_NOW}, None, {"entries": cache.entries, "changed": changed}) def c_access_hit(rec): pre = {11: stamped(0.5, access_count=3)} _access_case(rec, "access-hit-reinforces", pre, 11) def c_access_miss(rec): pre = {11: stamped(0.5)} _access_case(rec, "access-miss-noop", pre, 12) def c_access_zero_count(rec): pre = {13: stamped(0.5, access_count=0)} _access_case(rec, "access-from-zero", pre, 13) # ── contains / get_priority ────────────────────────────────────────────────── def c_contains_hit(rec): pre = {21: stamped(0.5)} cache = fresh_cache(pre) rec("contains-hit", {"entries": pre, "entry_id": 21}, cache.contains(21), {"contains": cache.contains(21)}) def c_contains_miss(rec): cache = fresh_cache({}) rec("contains-miss", {"entries": {}, "entry_id": 21}, cache.contains(21), {"contains": cache.contains(21)}) def c_getprio_hit(rec): pre = {31: stamped(0.625)} cache = fresh_cache(pre) rec("getprio-hit", {"entries": pre, "entry_id": 31}, cache.get_priority(31), {"priority": cache.get_priority(31)}) def c_getprio_miss(rec): cache = fresh_cache({}) rec("getprio-miss-zero", {"entries": {}, "entry_id": 31}, cache.get_priority(31), {"priority": cache.get_priority(31)}) # ── update_from_store ──────────────────────────────────────────────────────── def make_db(rows): db = sqlite3.connect(":memory:") db.execute("CREATE TABLE entries (id INTEGER PRIMARY KEY, wash_count INTEGER," " importance REAL, rock_status TEXT)") db.executemany("INSERT INTO entries VALUES (?,?,?,?)", rows) return db def _sync_case(rec, name, entries_pre, db_rows): db = make_db(db_rows) cache = fresh_cache(entries_pre) rows = {} for entry_id in list(cache.entries.keys()): row = db.execute( "SELECT wash_count, importance, rock_status FROM entries WHERE id = ?", (entry_id,)).fetchone() rows[str(entry_id)] = list(row) if row else None cache.update_from_store(db) rec(name, {"entries": entries_pre, "rows": rows}, None, {"entries": cache.entries}) def c_sync_updates_priority(rec): pre = {41: stamped(0.1, wash=1)} _sync_case(rec, "sync-updates-priority-wash-rock", pre, [(41, 15, 0.8, "rock")]) def c_sync_null_fields(rec): pre = {42: stamped(0.9, wash=5, rock="rock")} _sync_case(rec, "sync-null-row-fields-coerced", pre, [(42, None, None, None)]) def c_sync_deleted_row_removed(rec): pre = {43: stamped(0.5), 44: stamped(0.7)} _sync_case(rec, "sync-deleted-row-removed", pre, [(44, 2, 0.5, "washable")]) def c_sync_empty_cache(rec): _sync_case(rec, "sync-empty-cache-noop", {}, []) def c_sync_downgrade(rec): pre = {45: stamped(1.0, wash=20, rock="rock")} _sync_case(rec, "sync-downgrade-washable", pre, [(45, 0, 0.1, "washable")]) # ── get_stats ──────────────────────────────────────────────────────────────── def _stats_case(rec, name, entries_pre): cache = fresh_cache(entries_pre) stats = cache.get_stats() rec(name, {"entries": entries_pre}, stats, {"stats": stats}) def c_stats_empty(rec): _stats_case(rec, "stats-empty", {}) def c_stats_mixed(rec): pre = { 51: stamped(0.2, rock="rock"), 52: stamped(0.5, rock="established"), 53: stamped(0.9), } _stats_case(rec, "stats-mixed", pre) def c_stats_all_washable(rec): pre = {54: stamped(0.3), 55: stamped(0.4)} _stats_case(rec, "stats-all-washable", pre) def c_stats_missing_priority(rec): pre = {56: {"rock_status": "rock"}, 57: stamped(0.8)} _stats_case(rec, "stats-missing-priority-zero", pre) def c_stats_missing_rock_status(rec): pre = {58: {"priority": 0.5}} _stats_case(rec, "stats-missing-rock-status-washable", pre) # ── _load branches (facade-only: FILE IO stays in Python) ──────────────────── def c_load_missing(rec): cache = fresh_cache() rec("load-missing-file-empty", {"path": "missing"}, None, {"entries": cache.entries}) def c_load_valid(rec): tmp = tempfile.mkdtemp(prefix="dc_truth_") oracle_mod.CACHE_DIR = tmp oracle_mod.CACHE_FILE = os.path.join(tmp, "drift_cache.json") pre = {61: stamped(0.5), 62: stamped(0.9, rock="rock")} with open(oracle_mod.CACHE_FILE, "w") as f: json.dump({str(k): v for k, v in pre.items()}, f, indent=2) cache = oracle_mod.DriftCache() rec("load-valid-int-keys", {"path": "valid"}, None, {"entries": cache.entries}) def c_load_malformed(rec): tmp = tempfile.mkdtemp(prefix="dc_truth_") oracle_mod.CACHE_DIR = tmp oracle_mod.CACHE_FILE = os.path.join(tmp, "drift_cache.json") with open(oracle_mod.CACHE_FILE, "w") as f: f.write("{not json") cache = oracle_mod.DriftCache() rec("load-malformed-reset", {"path": "malformed"}, None, {"entries": cache.entries}) # ── driver ─────────────────────────────────────────────────────────────────── PRIO = [c_prio_default, c_prio_wash20_imp1, c_prio_typical, c_prio_rock, c_prio_established, c_prio_none_wash, c_prio_none_imp, c_prio_zero_imp, c_prio_int_importance, c_prio_wash_beyond_20, c_prio_unknown_status] QUAL = [c_qual_below_both, c_qual_imp_boundary, c_qual_imp_08_admitted, c_qual_wash_boundary, c_qual_defaults, c_qual_none_fields, c_qual_proven] ADD = [c_add_denied, c_add_denied_important_but_unwashed, c_add_washable, c_add_high_importance_unwashed, c_add_rock, c_add_overwrites, c_add_rock_status_none, c_add_boundary_200_no_evict, c_add_evict_lowest_20, c_add_evict_tie_stable_order] ACCESS = [c_access_hit, c_access_miss, c_access_zero_count] CONTAINS = [c_contains_hit, c_contains_miss] GETPRIO = [c_getprio_hit, c_getprio_miss] SYNC = [c_sync_updates_priority, c_sync_null_fields, c_sync_deleted_row_removed, c_sync_empty_cache, c_sync_downgrade] STATS = [c_stats_empty, c_stats_mixed, c_stats_all_washable, c_stats_missing_priority, c_stats_missing_rock_status] LOAD = [c_load_missing, c_load_valid, c_load_malformed] GROUPS = [("compute_priority", PRIO), ("qualifies_for_cache", QUAL), ("add", ADD), ("access", ACCESS), ("contains", CONTAINS), ("get_priority", GETPRIO), ("update_entries", SYNC), ("get_stats", STATS), ("load", LOAD)] # kernel symbol per group (None → facade-only group, skipped kernel-side) KERNEL = { "compute_priority": "dcc_compute_priority", "qualifies_for_cache": "dcc_qualifies_for_cache", "add": "dcc_add", "access": "dcc_access", "contains": "dcc_contains", "get_priority": "dcc_get_priority", "update_entries": "dcc_update_entries", "get_stats": "dcc_get_stats", "load": None, } # kernel-level replay: which slice of `expected` the unwrapped FFI value is UNWRAP = { "compute_priority": lambda w: w["priority"], "qualifies_for_cache": lambda w: w["qualifies"], "add": lambda w: w, "access": lambda w: w, "contains": lambda w: w["contains"], "get_priority": lambda w: w["priority"], "update_entries": lambda w: w["entries"], "get_stats": lambda w: w["stats"], } def canon(x) -> str: """Content canonicalization: int dict keys become strings through the JSON round-trip (the frozen file stores string keys), then a sorted dump makes the comparison key-order independent.""" return json.dumps(json.loads(json.dumps(x)), sort_keys=True) def main(): frozen = None if REPLAY: with open(TRUTH_PATH) as f: frozen = json.load(f)["cases"] groups = {} for group, cases in GROUPS: recs = [] def rec(name, inp, oracle_ret, expected, _r=recs): entry = {"name": name, "input": inp, "return": oracle_ret, "expected": expected} if REPLAY: old = next(c for c in frozen[group] if c["name"] == name) for key in ("input", "return", "expected"): got, want = entry[key], old[key] if canon(got) != canon(want): print(f"FACADE DIVERGE [{group}] {name} {key}") print(" got: ", json.dumps(got, sort_keys=True, default=str)[:600]) print(" want:", json.dumps(want, sort_keys=True, default=str)[:600]) recs.append({"name": name, "diverged": key}) return _r.append(entry) for c in cases: c(rec) groups[group] = recs total = sum(len(v) for v in groups.values()) if REPLAY: facade_failures = sum(1 for v in groups.values() for c in v if "diverged" in c) failures = 0 checked = 0 for group, cases in frozen.items(): sym = KERNEL[group] if sym is None: continue for case in cases: checked += 1 got = getattr(dc_loader, group)(**copy.deepcopy(case["input"])) want = UNWRAP[group](case["expected"]) if canon(got) != canon(want): failures += 1 print(f"KERNEL DIVERGE [{group}] {case['name']}") print(" got: ", json.dumps(got, sort_keys=True)[:600]) print(" want:", json.dumps(want, sort_keys=True)[:600]) print(f"replay: facade {total - facade_failures}/{total}, " f"kernel {checked - failures}/{checked}") return 1 if (failures or facade_failures) else 0 doc = { "frozen": datetime.now(timezone.utc).isoformat(), "oracle": "src/rune/drift_cache.py", "pin": "RUNE_DC_CORE=python + RUNE_MEMORY_CORE=python", "note": "Frozen via scripts/gen_drift_cache_truth.py against the live " "Python oracle; wall clock frozen at " + FROZEN_NOW + ". Battery embeds this VERBATIM. Group `load` is facade-only " "(FILE IO stays in Python).", "cases": groups, } os.makedirs(os.path.dirname(TRUTH_PATH), exist_ok=True) with open(TRUTH_PATH, "w") as f: # NO sort_keys: the entries maps are Python dicts whose INSERTION # order is load-bearing (stable eviction tie-breaks) — sorting # keys here would freeze a re-ordered kernel input. json.dump(doc, f, indent=1) f.write("\n") print(f"frozen {total} cases → {os.path.relpath(TRUTH_PATH, REPO)}") return 0 if __name__ == "__main__": sys.exit(main())