688 lines
27 KiB
Python
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)
|