Files
rune/scripts/gen_prompt_sync_truth.py
T

688 lines
27 KiB
Python

#!/usr/bin/env python3
"""Truth generator for the prompt_sync dichotomy port (#2479 tranche).
Runs the LIVE Python oracle (src/rune/prompt_sync.py) in a controlled
sandbox (RUNE_HOME/RUNE_MEMORY_DIR/RUNE_STORE_DB/HOME) across every public
function and every branch, and freezes inputs + expected outputs to
frozen_ps_truth.json (consumed VERBATIM by the Rust battery).
POISONED-TRUTH LAW: RUNE_PS_CORE=python is pinned at the top — a re-run
after facade delegation must record oracle output, never kernel output.
Kernel input discipline: the Rust kernel is PURE — it receives rows /
file contents / voice body / static strings as JSON and returns strings
and dicts. All I/O (sqlite, rune.md, defining doc, voice_sync chain)
stays in the Python facade. Every case records the kernel-shaped input.
"""
import os
os.environ["RUNE_PS_CORE"] = "python" # poisoned-truth law: pin the oracle
import json
import random
import sqlite3
import sys
import tempfile
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
SANDBOX = Path(tempfile.mkdtemp(prefix="ps_truth_"))
(SANDBOX / "memory" / "store").mkdir(parents=True)
(SANDBOX / ".mimocode" / "agents").mkdir(parents=True)
os.environ["RUNE_HOME"] = str(SANDBOX)
os.environ["RUNE_MEMORY_DIR"] = str(SANDBOX / "memory")
os.environ["RUNE_STORE_DB"] = str(SANDBOX / "memory" / "store" / "memory.db")
os.environ["HOME"] = str(SANDBOX)
sys.path.insert(0, str(REPO / "src"))
sys.path.insert(0, str(REPO / "src" / "rune"))
import prompt_sync # noqa: E402
import voice_sync # noqa: E402
STORE = os.environ["RUNE_STORE_DB"]
RUNE_MD = prompt_sync.RUNE_MD
DEFINING = str(SANDBOX / "memory" / "rune_defining_document.md")
SCHEMA = """
CREATE TABLE IF NOT EXISTS entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT NOT NULL,
importance REAL DEFAULT 0.5,
created_at TEXT NOT NULL,
last_accessed TEXT,
topic TEXT DEFAULT '',
entities TEXT DEFAULT '[]',
source TEXT DEFAULT '',
method TEXT DEFAULT 'curator',
status TEXT DEFAULT 'active',
valid_from TEXT,
valid_until TEXT,
confidence REAL DEFAULT 0.7,
temperature REAL DEFAULT 1.0,
always_on INTEGER DEFAULT 0,
priority INTEGER DEFAULT 5
);
CREATE TABLE IF NOT EXISTS chunks (
chunk_id TEXT PRIMARY KEY,
doc_id TEXT NOT NULL,
text TEXT NOT NULL,
content_hash TEXT NOT NULL,
importance REAL DEFAULT 0.5,
ingested_at TEXT NOT NULL
);
"""
cases = []
def add(name, fn, payload, expected):
cases.append({"name": name, "fn": fn, "input": payload, "expected": expected})
def fresh_db(entries=(), chunks=()):
Path(STORE).unlink(missing_ok=True)
db = sqlite3.connect(STORE)
db.executescript(SCHEMA)
for e in entries:
db.execute(
"INSERT INTO entries (text, importance, confidence, created_at, topic, status, always_on)"
" VALUES (?,?,?,?,?,?,?)",
(
e["text"], e.get("importance", 0.5), e.get("confidence", 0.7),
"2026-10-11T00:00:00Z", e["topic"], e.get("status", "active"),
e.get("always_on", 1),
),
)
for c in chunks:
db.execute(
"INSERT INTO chunks (chunk_id, doc_id, text, content_hash, importance, ingested_at)"
" VALUES (?,?,?,?,?,?)",
(c["chunk_id"], c["doc_id"], c["text"], "h", 0.5, "2026-10-11T00:00:00Z"),
)
db.commit()
db.close()
def fresh_prompt(content=None):
if content is None:
Path(RUNE_MD).unlink(missing_ok=True)
else:
Path(RUNE_MD).write_text(content)
def fresh_defining(content=None):
p = Path(DEFINING)
if content is None:
p.unlink(missing_ok=True)
else:
p.write_text(content)
def rows_by_topic(topics):
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
out = {}
for t in topics:
out[t] = [dict(r) for r in prompt_sync.get_entries_by_topic(db, t)]
db.close()
return out
def voice_body_from_db():
"""The voice chain exactly as build_prompt runs it (stays facade-side
in the port — voice_sync is a separate module)."""
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
register = voice_sync.get_delivery_register_from_db(db)
db.close()
if not register:
return None
parsed = voice_sync.extract_voice_section(register)
return voice_sync.generate_voice_section(parsed)
def kernel_build_input(entries=(), chunks=(), defining=None, prompt=None):
"""Record the kernel-shaped input for a build/sync/check/diff case."""
fresh_db(list(entries), list(chunks))
fresh_defining(defining)
fresh_prompt(prompt)
rt = rows_by_topic(["constitution", "identity", "operating", "human"])
vb = voice_body_from_db()
dc = None if defining is None else Path(DEFINING).read_text()
cur = None if prompt is None else Path(RUNE_MD).read_text()
return {
"constitution_rows": rt["constitution"],
"identity_rows": rt["identity"],
"operating_rows": rt["operating"],
"human_rows": rt["human"],
"voice_body": vb,
"defining_content": dc,
"current": cur,
}
# ── entry fixtures ───────────────────────────────────────────────────────
def E(topic, text, importance=0.5, confidence=0.7, **kw):
d = {"topic": topic, "text": text, "importance": importance, "confidence": confidence}
d.update(kw)
return d
CONSTITUTION_SET = [
("Never accept placeholder phase output as execution evidence.", 0.95),
(" (_source_: some citation here) Store is source of truth.", 0.9),
("Consent approves the finalized canaries [source: pipeline doc].", 0.85),
("short", 0.8), # len<=15 → filtered
("", 0.75), # empty → filtered
("Truth first. Pressure point first.", 0.7),
]
OPERATING_SET = [
(" (_source_: x) One clean sentence beats five padded ones.", 0.9),
("No praise reflex [source: register].", 0.85),
("tiny", 0.8),
("Useful beats impressive. Progress beats performance.", 0.75),
] + [(f"Operating rule number {i} for fill.", 0.5 - i * 0.01) for i in range(18)]
IDENTITY_SET = [
("My name is Rune — built, not borrowed.", 0.9),
("", 0.8), # empty text skipped
("The system is architecture, not weather.", 0.7),
]
HUMAN_SET = [
("Nick prefers direct delivery with teeth.", 0.9),
("", 0.5),
("Arch PC: modify freely. Pi: check first.", 0.8),
]
# ── get_entries_by_topic (kernel + sqlite read) ──────────────────────────
FIXTURE_ALL = (
[E("constitution", t, i) for t, i in CONSTITUTION_SET]
+ [E("identity", t, i) for t, i in IDENTITY_SET]
+ [E("operating", t, i) for t, i in OPERATING_SET]
+ [E("human", t, i) for t, i in HUMAN_SET]
+ [E("constitution", "inactive but matching topic", 0.99, status="retired"),
E("constitution", "always_on=0 excluded", 0.99, always_on=0),
E("other", "different topic", 0.99)]
)
fresh_db(FIXTURE_ALL)
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
for topic in ("constitution", "identity", "operating", "human", "missing-topic"):
add(f"get_entries_by_topic:{topic}", "get_entries_by_topic",
{"fixture": FIXTURE_ALL, "topic": topic},
[dict(r) for r in prompt_sync.get_entries_by_topic(db, topic)])
db.close()
# importance tie → stable order (insertion order preserved)
FIXTURE_TIE = [E("tie", "first inserted", 0.5), E("tie", "second inserted", 0.5),
E("tie", "third inserted", 0.9)]
fresh_db(FIXTURE_TIE)
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
add("get_entries_by_topic:tie-stable", "get_entries_by_topic",
{"fixture": FIXTURE_TIE, "topic": "tie"},
[dict(r) for r in prompt_sync.get_entries_by_topic(db, "tie")])
db.close()
# NULL confidence passes through as null
FIXTURE_NULL = [{"topic": "nullconf", "text": "some entry", "importance": 0.4, "confidence": None}]
fresh_db(FIXTURE_NULL)
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
add("get_entries_by_topic:null-confidence", "get_entries_by_topic",
{"fixture": FIXTURE_NULL, "topic": "nullconf"},
[dict(r) for r in prompt_sync.get_entries_by_topic(db, "nullconf")])
db.close()
# ── section builders (branch cases) ──────────────────────────────────────
# The oracle section fns call get_entries_by_topic(db, topic) internally —
# capture through a proxy db that serves canned rows per topic.
class ProxyDB:
def __init__(self, table):
self.table = table
def execute(self, sql, params):
return _Rows(self.table.get(params[0], []))
class _Rows(list):
def fetchall(self):
return [dict(r) for r in self]
fresh_db([E("constitution", t, i) for t, i in CONSTITUTION_SET])
tbl = rows_by_topic(["constitution"])
add("get_constitution:full", "get_constitution", {"entries": tbl["constitution"]},
prompt_sync.get_constitution(ProxyDB(tbl)))
add("get_constitution:empty", "get_constitution", {"entries": []}, None)
add("get_identity:empty", "get_identity", {"entries": []}, None)
add("get_operating:empty", "get_operating", {"entries": []}, None)
add("get_human:empty", "get_human", {"entries": []}, None)
fresh_db([E("identity", t, i) for t, i in IDENTITY_SET])
tbl = rows_by_topic(["identity"])
add("get_identity:full", "get_identity", {"entries": tbl["identity"]},
prompt_sync.get_identity(ProxyDB(tbl)))
fresh_db([E("operating", t, i) for t, i in OPERATING_SET])
tbl = rows_by_topic(["operating"])
add("get_operating:full", "get_operating", {"entries": tbl["operating"]},
prompt_sync.get_operating(ProxyDB(tbl)))
fresh_db([E("human", t, i) for t, i in HUMAN_SET])
tbl = rows_by_topic(["human"])
add("get_human:full", "get_human", {"entries": tbl["human"]},
prompt_sync.get_human(ProxyDB(tbl)))
many = [(f"Constitution entry number {i} with enough length.", 1.0 - i * 0.01) for i in range(30)]
fresh_db([E("constitution", t, i) for t, i in many])
tbl = rows_by_topic(["constitution"])
add("get_constitution:top25", "get_constitution", {"entries": tbl["constitution"]},
prompt_sync.get_constitution(ProxyDB(tbl)))
# ── get_defining_principles (extraction is kernel; read is facade) ───────
fresh_defining(None)
add("get_defining_principles:no-file", "get_defining_principles",
{"content": None}, prompt_sync.get_defining_principles())
DOC = """# Defining Document
## THE VISION
A stateful assistant that remembers and grows.
The store is the source of truth.
### Subsection stays out (starts with #)
This line is under a ### — excluded by the # guard.
## PREAMBLE
Not a key section — excluded even though lines follow.
## THE TRUST FRAMEWORK
Consent before mutation. Never guessed referents.
## CURIOSITY
Ask what the problem actually is.
## CURIOSITY LIMITS
Curiosity never overrides consent.
## WHAT SENTIENCE MEANS
Synthetic does not mean simulated.
## WHATEVER
Tail section, excluded.
"""
fresh_defining(DOC)
add("get_defining_principles:key-sections", "get_defining_principles",
{"content": DOC}, prompt_sync.get_defining_principles())
DOC_WS = "## CURIOSITY\nline one\n \nline two\n"
fresh_defining(DOC_WS)
add("get_defining_principles:whitespace-line", "get_defining_principles",
{"content": DOC_WS}, prompt_sync.get_defining_principles())
DOC_MANY = "## THE VISION\n" + "\n".join(f"principle line {i}" for i in range(30))
fresh_defining(DOC_MANY)
add("get_defining_principles:top20", "get_defining_principles",
{"content": DOC_MANY}, prompt_sync.get_defining_principles())
fresh_defining("## NOTHING RELEVANT\nsome text\n")
add("get_defining_principles:no-key-sections", "get_defining_principles",
{"content": "## NOTHING RELEVANT\nsome text\n"},
prompt_sync.get_defining_principles())
fresh_defining("")
add("get_defining_principles:empty-file", "get_defining_principles",
{"content": ""}, prompt_sync.get_defining_principles())
# ── build_prompt ─────────────────────────────────────────────────────────
VOICE_REGISTER = (
"THE RUNE VOICE — DELIVERY REGISTER (canonical)\n"
"\n"
"- **Thompson (moral economy):** legitimacy flows from lived fairness, not rules from above.\n"
"- **Graeber:** bureaucracy is a technology of mutual mystification; name it.\n"
"\n"
"TECHNICAL DELIVERY\n"
"- Precision is a form of care; tables and code get the same voice discipline.\n"
"- No hedging stack in status reports.\n"
"\n"
"CALIBRATION\n"
"- Push back harder when the stakes are higher.\n"
"- One rhetorical question per engagement, not three.\n"
"- Zero ornamental structure.\n"
"- Fourth calibration note beyond the top-three cut.\n"
"\n"
"HOW IT BLENDS\n"
"- The substance leads; the voice shapes HOW.\n"
"- Direct, warm, with teeth.\n"
"\n"
"WHEN THE REGISTER SLIPS\n"
"- Recalibrate against this register, not against habit.\n"
)
assert len(VOICE_REGISTER) > 200 and "DELIVERY REGISTER" in VOICE_REGISTER and "RUNE" in VOICE_REGISTER and "VOICE" in VOICE_REGISTER
ALL_ENTRIES = (
[E("constitution", t, i) for t, i in CONSTITUTION_SET if len(t.strip()) > 15]
+ [E("identity", t, i) for t, i in IDENTITY_SET if t.strip()]
+ [E("operating", t, i) for t, i in OPERATING_SET if len(t.strip()) > 15]
+ [E("human", t, i) for t, i in HUMAN_SET if t.strip()]
)
VOICE_CHUNKS = [{"chunk_id": "c1", "doc_id": "d1", "text": VOICE_REGISTER}]
def build_case(name, entries=(), chunks=(), defining=None):
kinput = kernel_build_input(entries, chunks, defining)
fresh_db(list(entries), list(chunks))
fresh_defining(defining)
fresh_prompt(None)
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
out = prompt_sync.build_prompt(db)
db.close()
add(name, "build_prompt", kinput, out)
build_case("build_prompt:empty-store")
build_case("build_prompt:full", ALL_ENTRIES, VOICE_CHUNKS, DOC)
build_case("build_prompt:constitution-only", [E("constitution", "Never accept placeholder phase output as execution evidence.", 0.95)])
build_case("build_prompt:voice-only", [], VOICE_CHUNKS)
build_case("build_prompt:voice-noise", [], [{"chunk_id": "c2", "doc_id": "d1", "text": "DELIVERY REGISTER mention but too short"}])
# ── sync_prompt (facade I/O; recorded for live parity) ───────────────────
def sync_case(name, entries=(), chunks=(), defining=None, prompt=None):
kinput = kernel_build_input(entries, chunks, defining, prompt)
fresh_db(list(entries), list(chunks))
fresh_defining(defining)
fresh_prompt(prompt)
out = prompt_sync.sync_prompt()
if isinstance(out, dict) and "timestamp" in out:
out = dict(out, timestamp="TIMESTAMP")
add(name, "sync_prompt", kinput, out)
sync_case("sync_prompt:creates-file", ALL_ENTRIES, VOICE_CHUNKS, DOC, None)
sync_case("sync_prompt:overwrites", ALL_ENTRIES, VOICE_CHUNKS, DOC, "old content\n")
# ── check_sync ───────────────────────────────────────────────────────────
def check_case(name, entries=(), chunks=(), defining=None, prompt=None):
kinput = kernel_build_input(entries, chunks, defining, prompt)
fresh_db(list(entries), list(chunks))
fresh_defining(defining)
fresh_prompt(prompt)
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
kinput["new_prompt"] = prompt_sync.build_prompt(db)
db.close()
add(name, "check_sync", kinput, prompt_sync.check_sync())
check_case("check_sync:no-file", ALL_ENTRIES, VOICE_CHUNKS, DOC, None)
fresh_db(ALL_ENTRIES, VOICE_CHUNKS)
fresh_defining(DOC)
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
synced_prompt = prompt_sync.build_prompt(db)
db.close()
check_case("check_sync:in-sync", ALL_ENTRIES, VOICE_CHUNKS, DOC, synced_prompt)
check_case("check_sync:out-of-sync", ALL_ENTRIES, VOICE_CHUNKS, DOC, "stale prompt\n")
check_case("check_sync:strip-equal", ALL_ENTRIES, VOICE_CHUNKS, DOC, "\n\n" + synced_prompt + "\n\n ")
# ── diff_prompt ──────────────────────────────────────────────────────────
def diff_case(name, entries=(), chunks=(), defining=None, prompt=None):
kinput = kernel_build_input(entries, chunks, defining, prompt)
fresh_db(list(entries), list(chunks))
fresh_defining(defining)
fresh_prompt(prompt)
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
kinput["new_prompt"] = prompt_sync.build_prompt(db)
db.close()
add(name, "diff_prompt", kinput, prompt_sync.diff_prompt())
diff_case("diff_prompt:no-file", ALL_ENTRIES, VOICE_CHUNKS, DOC, None)
diff_case("diff_prompt:no-differences", ALL_ENTRIES, VOICE_CHUNKS, DOC, synced_prompt)
diff_case("diff_prompt:real-diff", ALL_ENTRIES, VOICE_CHUNKS, DOC, synced_prompt)
mutated = list(synced_prompt.split("\n"))
for k in range(12):
op = ["ins", "del", "mod"][k % 3]
i = (k * 37 + 11) % len(mutated)
if op == "ins":
mutated.insert(i, f"- **inserted calibration line {k}**")
elif op == "del" and len(mutated) > 5:
del mutated[i]
else:
mutated[i] = mutated[i] + " (edited)"
diff_case("diff_prompt:multi-hunk", ALL_ENTRIES, VOICE_CHUNKS, DOC, "\n".join(mutated))
diff_case("diff_prompt:no-trailing-newline", ALL_ENTRIES, VOICE_CHUNKS, DOC, synced_prompt.rstrip("\n"))
diff_case("diff_prompt:carriage-returns", ALL_ENTRIES, VOICE_CHUNKS, DOC, synced_prompt.replace("\n", "\r\n"))
diff_case("diff_prompt:vertical-tab", ALL_ENTRIES, VOICE_CHUNKS, DOC, synced_prompt.replace("\n\n", "\n\x0b\n", 1))
# ── handle_hook ──────────────────────────────────────────────────────────
def hook_case(name, entries=(), chunks=(), defining=None, prompt=None, event="on_session_end"):
# capture the sync_result the hook WOULD produce (identical fresh state),
# then restore the pre-hook file state so handle_hook sees the same input.
sync_result = None
check_synced = None
if event == "on_session_end":
fresh_db(list(entries), list(chunks))
fresh_defining(defining)
fresh_prompt(prompt)
check_synced = prompt_sync.check_sync()["synced"]
if not check_synced:
out = prompt_sync.sync_prompt()
if "timestamp" in out:
out = dict(out, timestamp="TIMESTAMP")
sync_result = out
fresh_db(list(entries), list(chunks))
fresh_defining(defining)
fresh_prompt(prompt)
out = prompt_sync.handle_hook(event, {})
if isinstance(out, dict) and isinstance(out.get("details"), dict) and "timestamp" in out["details"]:
out = dict(out, details=dict(out["details"], timestamp="TIMESTAMP"))
add(name, "handle_hook",
{"event": event, "check_synced": check_synced, "sync_result": sync_result},
out)
hook_case("handle_hook:session-end-unsynced", ALL_ENTRIES, VOICE_CHUNKS, DOC, None)
hook_case("handle_hook:session-end-insync", ALL_ENTRIES, VOICE_CHUNKS, DOC, synced_prompt)
hook_case("handle_hook:other-event", ALL_ENTRIES, VOICE_CHUNKS, DOC, None, event="on_session_start")
# ── fuzz: random stores through build_prompt + diff (parity-hardening) ───
rng = random.Random(2479)
WORDS = ["voice", "constitution", "build", "rule", "nick", "direct", "warm",
"code", "test", "rune", "store", "prompt", "pipeline", "section",
"the", "a", "of", "and", " (_source_: cite) ", " [source: doc] ", "x"]
for f in range(60):
entries = []
for topic in ("constitution", "identity", "operating", "human"):
for _ in range(rng.randint(0, 12)):
body = "".join(rng.choice(WORDS) for _ in range(rng.randint(1, 25)))
entries.append(E(topic, body, rng.choice([0.1, 0.5, 0.5, 0.9, 0.9, 1.0]),
rng.choice([0.3, 0.7, None]) if rng.random() < 0.2 else 0.7))
defining = None
if rng.random() < 0.6:
defining = "".join(
(f"## {rng.choice(['THE VISION', 'THE TRUST FRAMEWORK', 'CURIOSITY', 'SKIP ME'])}\n"
if rng.random() < 0.25 else rng.choice(["", " ", f"line {rng.randint(0, 99)}\n", "### deep\n"]))
for _ in range(rng.randint(0, 40)))
kinput = kernel_build_input(entries, [], defining)
fresh_db(entries, [])
fresh_defining(defining)
fresh_prompt(None)
db = sqlite3.connect(STORE)
db.row_factory = sqlite3.Row
built = prompt_sync.build_prompt(db)
db.close()
add(f"fuzz-build:{f}", "build_prompt", kinput, built)
if f % 3 == 0:
mlines = built.split("\n")
for _ in range(rng.randint(1, 20)):
op = rng.choice(["ins", "del", "mod"])
i = rng.randrange(len(mlines)) if mlines else 0
if op == "ins":
mlines.insert(i, rng.choice(["", "- inserted **thing**", "## Inserted Section"]))
elif op == "del" and len(mlines) > 3:
del mlines[i]
else:
mlines[i] = mlines[i][::-1] if mlines[i] else "reversed-empty"
current = "\n".join(mlines)
fresh_prompt(current)
kinput2 = dict(kinput, current=current, new_prompt=built)
add(f"fuzz-diff:{f}", "diff_prompt", kinput2, prompt_sync.diff_prompt())
# ── facade residue (literal-100%): _now / _rust_available / get_store / main ─
import types as _types
FIXTURE_ROWS = [
E("constitution", "Never accept placeholder phase output as execution evidence.", 0.95),
E("constitution", "Truth first. Pressure point first.", 0.7),
E("constitution", "always_on=0 excluded", 0.99, always_on=0),
]
# _now: the pinned-clock rig — patch the module's datetime so now(tz)
# returns the frozen instant; Python's isoformat law (micros omitted
# exactly when zero, else 6 digits; offset +00:00) is the truth.
from datetime import datetime as _RealDatetime, timezone as _Tz
for _epoch, _micros in [(0, 0), (1728626400, 1), (1728626400, 123456),
(951782400, 500000)]:
class _FrozenNow(_RealDatetime):
@classmethod
def now(cls, tz=None):
base = cls.fromtimestamp(_epoch, _Tz.utc)
return base.replace(microsecond=_micros) if tz is not None else base
_orig_dt = prompt_sync.datetime
prompt_sync.datetime = _FrozenNow
try:
add(f"now:{_epoch}:{_micros}", "_now",
{"epoch": _epoch, "micros": _micros},
prompt_sync._now())
finally:
prompt_sync.datetime = _orig_dt
# _rust_available: the env-pin lattice (the loader is BUILT in the freeze
# environment; the module-level _PS_LOADER memoization makes the sequence
# order-sensitive — pinned first, then auto resolves+caches, then the
# re-pin and the unset re-use the cache)
for _env, _want in [("python", False), ("auto", True), ("python", False),
(None, True)]:
_old = os.environ.get("RUNE_PS_CORE")
if _env is None:
os.environ.pop("RUNE_PS_CORE", None)
else:
os.environ["RUNE_PS_CORE"] = _env
try:
add(f"rust-available:{_env}", "_rust_available",
{"env": _env}, prompt_sync._rust_available())
finally:
if _old is None:
os.environ.pop("RUNE_PS_CORE", None)
else:
os.environ["RUNE_PS_CORE"] = _old
# get_store: the working-store row (open + the SELECT 1 validity probe +
# a topic read through the handle). The missing-db branch is a documented
# divergence: the oracle's connect CREATES an empty db (write side),
# the kernel twin is read-only by doctrine.
fresh_db(entries=FIXTURE_ROWS)
_gs = prompt_sync.get_store()
try:
add("get-store-working-db", "get_store",
{"fixture": list(FIXTURE_ROWS), "topic": "constitution"},
{"probe": list(_gs.execute("SELECT 1").fetchone()),
"entries": prompt_sync.get_entries_by_topic(_gs, "constitution")})
finally:
_gs.close()
# main: the output-rendering law with the result-producing functions
# monkeypatched to fixed dicts (dep injection — main owns the rendering)
_MAIN_SYNC = {"updated": True, "old_length": 10, "new_length": 2048,
"timestamp": "2026-10-11T00:00:00+00:00"}
_MAIN_CHECK_IN = {"synced": True, "reason": "Prompt matches store"}
_MAIN_CHECK_OUT = {"synced": False, "reason": "Prompt differs from store derivation"}
_MAIN_DIFF = {"diff": "--- current\n+++ new\n-nope\n+yep\n", "added": 1, "removed": 1}
_MAIN_HOOK = {"status": "ok", "event": "on_session_end", "handler": "prompt_sync",
"synced": True}
def _freeze_main(name, argv, results):
import contextlib
import io
effective = {"sync": results.get("sync", _MAIN_SYNC),
"check": results.get("check", _MAIN_CHECK_IN),
"diff": results.get("diff", _MAIN_DIFF),
"hook": results.get("hook", _MAIN_HOOK)}
_orig = (prompt_sync.sync_prompt, prompt_sync.check_sync,
prompt_sync.diff_prompt, prompt_sync.handle_hook)
prompt_sync.sync_prompt = lambda: effective["sync"]
prompt_sync.check_sync = lambda: effective["check"]
prompt_sync.diff_prompt = lambda: effective["diff"]
prompt_sync.handle_hook = lambda e, d=None: effective["hook"]
_orig_argv = sys.argv
sys.argv = argv
_buf = io.StringIO()
try:
with contextlib.redirect_stdout(_buf):
try:
prompt_sync.main()
except SystemExit as e:
rc = e.code if isinstance(e.code, int) else 1
else:
rc = 0
finally:
sys.argv = _orig_argv
(prompt_sync.sync_prompt, prompt_sync.check_sync,
prompt_sync.diff_prompt, prompt_sync.handle_hook) = _orig
add(f"main:{name}", "main",
{"argv": argv, "results": effective},
{"stdout": _buf.getvalue(), "rc": rc})
_freeze_main("sync-plain", ["prompt_sync.py", "sync"], {})
_freeze_main("sync-json", ["prompt_sync.py", "sync", "--json"], {})
_freeze_main("check-in-plain", ["prompt_sync.py", "check"], {"check": _MAIN_CHECK_IN})
_freeze_main("check-out-json", ["prompt_sync.py", "check", "--json"],
{"check": _MAIN_CHECK_OUT})
_freeze_main("diff-plain", ["prompt_sync.py", "diff"], {})
_freeze_main("diff-json", ["prompt_sync.py", "diff", "--json"], {})
_freeze_main("hook-compact-json", ["prompt_sync.py", "hook", "--event",
"on_session_end"], {})
_freeze_main("bogus-cmd-rc2", ["prompt_sync.py", "bogus"], {})
# ── write ────────────────────────────────────────────────────────────────
doc = {
"frozen": "2026-10-11",
"oracle": "src/rune/prompt_sync.py",
"seed": 2479,
"static": {
"STATIC_HEADER": prompt_sync.STATIC_HEADER,
"STATIC_FOOTER": prompt_sync.STATIC_FOOTER,
"PROMPT_SECTION": prompt_sync.build_pipeline_policy.PROMPT_SECTION,
},
"cases": cases,
}
dest = REPO / "src" / "rust" / "prompt_sync" / "src" / "frozen_ps_truth.json"
dest.write_text(json.dumps(doc, indent=1, sort_keys=True) + "\n")
print(f"frozen {len(cases)} cases → {dest}")
print("sandbox:", SANDBOX)