Port the eleven audit-named missing fns name-preserving 1:1 from src/rune/cache.py (recordHit/_record_hit, recordMiss, flushStats, getCache, putCache, invalidateScope, invalidateAll, nowTs, parseTs, cacheStats, handleHook) with the in-memory hit/miss accumulation (threshold 50 / interval 30s), INVALIDATION_MAP, full schema (both indexes) and an oracle-byte-parity CLI (usage gates, --json indent=2, rune-aware :20 padding and [:200] truncation, compact hook line, PLUGIN manifest). Clock/monotonic/DB behind Env seams. Frozen truth: 78 cases via the shared freeze_truth.py harness (envelope, pinned clock, sandboxed RUNE_MEMORY_DIR), byte-identical regen + --verify green. Go battery replays verbatim + flush-branch seam pins + 16-case CLI live parity (100%). Python oracle battery 12 passed BOTH pins. Audit: cache 6/17 -> 17/17 FULL (GO).
90 lines
3.5 KiB
Python
90 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""gen_cache_truth.py — cache dichotomy gap-close truth battery (shared
|
|
freeze_truth.py harness, live oracle, envelope format with pinned clock).
|
|
|
|
Every ported fn and every freezable branch: _now/_now_ts/_parse_ts
|
|
(frozen clock, garbage + None inputs), _hash, _compress, flush_stats
|
|
(normalizes the flush interval), put_cache (default/explicit compressed,
|
|
scope, source_hash, upsert resurrection), get_cache (hit, pending-
|
|
visible double-hit, true miss, invalidated miss), invalidate,
|
|
invalidate_scope, invalidate_all, cache_stats (rates, scopes), the
|
|
50-event flush threshold, and handle_hook (mapped event, zero-count
|
|
event, unmapped event).
|
|
|
|
NOT freezable here (no oracle fn can idle 30s): the 30s-interval flush
|
|
branch — pinned by the Python battery (monkeypatched time.monotonic)
|
|
and the Go battery (monotonic seam) instead.
|
|
|
|
RUNE_MEMORY_DIR is sandboxed to a throwaway BEFORE the oracle import
|
|
(DB_PATH is derived at import time).
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
REPO = Path(__file__).resolve().parent.parent
|
|
|
|
_SBOX = tempfile.mkdtemp(prefix="freeze-cache-truth-")
|
|
os.environ["RUNE_MEMORY_DIR"] = _SBOX
|
|
sys.path.insert(0, str(REPO / "scripts"))
|
|
sys.path.insert(0, str(REPO / "src"))
|
|
|
|
from freeze_truth import freeze, write_envelope # noqa: E402
|
|
|
|
FROZEN_NOW = "2026-10-13T12:00:00+00:00" # microsecond 0 -> fraction-less isoformat
|
|
|
|
|
|
def main() -> int:
|
|
os.environ["RUNE_FROZEN_NOW"] = FROZEN_NOW
|
|
|
|
alpha = "Alpha full value line one\nAlpha line two"
|
|
beta = "Beta value for the retrieval scope"
|
|
gamma = "Gamma value for the warm digest scope"
|
|
uni = "Wörter value with ümlaut"
|
|
|
|
cases = [
|
|
("_now", (), {}),
|
|
("_now_ts", (), {}),
|
|
("_parse_ts", ("2026-10-13T12:00:00+00:00",), {}),
|
|
("_parse_ts", ("garbage",), {}),
|
|
("_parse_ts", (None,), {}),
|
|
("_hash", ("hello",), {}),
|
|
("_compress", ("# comment\n====\ndecorative line survives compression test\n(_source_: cite)\nab\n",), {}),
|
|
("flush_stats", (), {}),
|
|
("put_cache", ("alpha", alpha), {}),
|
|
("put_cache", ("beta", beta), {"scope": "retrieval", "source_hash": "src-1"}),
|
|
("put_cache", ("gamma", gamma), {"scope": "warm_digest"}),
|
|
("put_cache", ("uni-ü", uni), {"compressed": "MANUAL-COMPRESSED"}),
|
|
("get_cache", ("alpha",), {}),
|
|
("get_cache", ("alpha",), {}),
|
|
("get_cache", ("never-seen",), {}),
|
|
("cache_stats", (), {}),
|
|
("invalidate", ("alpha",), {"reason": "stale"}),
|
|
("get_cache", ("alpha",), {}),
|
|
("invalidate_scope", ("retrieval",), {"reason": "event test"}),
|
|
("invalidate_all", (), {"reason": "nuke"}),
|
|
("cache_stats", (), {}),
|
|
("put_cache", ("alpha", "Alpha rewritten value"), {}),
|
|
("get_cache", ("alpha",), {}),
|
|
("handle_hook", ("memory.created", {}), {}),
|
|
("handle_hook", ("persona.updated", None), {}),
|
|
("handle_hook", ("completely.unknown", None), {}),
|
|
# the 50-event flush threshold: put resets the counter, then 50
|
|
# hits — the 50th record crosses _FLUSH_THRESHOLD and flushes.
|
|
("put_cache", ("counter", "Counter value for the threshold walk"), {}),
|
|
]
|
|
cases.extend([("get_cache", ("counter",), {})] * 50)
|
|
cases.append(("cache_stats", (), {}))
|
|
|
|
truth = freeze("rune.cache", cases, oracle_module="rune.cache")
|
|
out = REPO / "src/go/cache/frozen_truth.json"
|
|
write_envelope(FROZEN_NOW, truth, out)
|
|
print(f"wrote {len(truth)} cases to {out} (sandbox {_SBOX})")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|