158 lines
6.3 KiB
Python
158 lines
6.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Freeze the dichotomy-wave truth corpus for src/rune/subconscious_pass.py.
|
|
|
|
LAW (poisoned-truth): RUNE_SP_CORE=python is pinned at the top — truth is
|
|
generated by the PYTHON ORACLE ONLY.
|
|
|
|
Every public function is exercised across ALL branches:
|
|
reflect 10 cases (topic_shift hit/same-topic/no-context/
|
|
empty-context; unresolved_question both; action
|
|
words; emotional words; short_response; combo)
|
|
_extract_topic 4 (multiword / single / empty / whitespace)
|
|
get_recent_findings 4 (default limit / limit>len / limit=0 / sparse)
|
|
save_reflection 2 (the exact json.dump(indent=2) file bytes — the
|
|
timestamped FILENAME and the write stay in the
|
|
facade; the byte law is the kernel's)
|
|
|
|
Timestamps: the report `timestamp` and the save filename clock are facade
|
|
ARGUMENTS (`now`), monkeypatched to a FIXED value so the corpus is
|
|
byte-stable.
|
|
"""
|
|
import json
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
os.environ["RUNE_SP_CORE"] = "python" # poisoned-truth law
|
|
|
|
REPO = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(REPO / "src"))
|
|
|
|
import rune.subconscious_pass as sp # noqa: E402
|
|
|
|
FIXED_NOW = "2026-10-12T00:00:01.000001+00:00"
|
|
|
|
OUT = (REPO / "src" / "rust" / "subconscious_pass" / "src"
|
|
/ "frozen_sp_truth.json")
|
|
|
|
cases = []
|
|
|
|
|
|
def case(fn, name, args, expect):
|
|
cases.append({"fn": fn, "name": name,
|
|
"args": args, "expect": expect})
|
|
|
|
|
|
class _FixedDatetime(sp.datetime):
|
|
@classmethod
|
|
def now(cls, tz=None):
|
|
return cls(2026, 10, 12, 0, 0, 1, 1, tzinfo=tz)
|
|
|
|
|
|
def main():
|
|
sp.datetime = _FixedDatetime
|
|
s = sp.SubconsciousPass()
|
|
|
|
# ── reflect ──────────────────────────────────────────────────────
|
|
for name, user, agent, ctx in [
|
|
("topic_shift_hit", "how do we deploy the cache layer",
|
|
"Sure, let's plan it.", {"previous_topic": "index tuning"}),
|
|
("topic_same", "more on index tuning please",
|
|
"The index tuning continues.", {"previous_topic": "index tuning"}),
|
|
("topic_none_extracted", " ",
|
|
"Empty message.", {"previous_topic": "old topic"}),
|
|
("no_context", "build the thing", "Building it.", None),
|
|
("empty_context", "build the thing", "Building it.", {}),
|
|
("unresolved_question", "What about the cache?",
|
|
"The cache is handled.", {"previous_topic": "cache"}),
|
|
("question_answered", "What about the cache?",
|
|
"Good question — the cache is handled.", {}),
|
|
("action_requested", "please fix and update the loader",
|
|
"On it.", {}),
|
|
("emotional_signal", "I'm frustrated and confused by the drift",
|
|
"Let's look at it.", {}),
|
|
("short_response", "x" * 201,
|
|
"ok"[:10], {}),
|
|
("combo_all", "build and fix it — I'm frustrated. What now?",
|
|
"ok", {"previous_topic": "planning"}),
|
|
]:
|
|
r = s.reflect(user, agent, ctx)
|
|
case("reflect", name,
|
|
{"user": user, "agent": agent, "context": ctx,
|
|
"now": FIXED_NOW}, r)
|
|
|
|
# ── _extract_topic ───────────────────────────────────────────────
|
|
for name, text, want in [
|
|
("multiword", "the quick brown fox jumps over the dog",
|
|
"the quick brown fox jumps"),
|
|
("single", "hello", "hello"),
|
|
("empty", "", None),
|
|
("whitespace", " \t\n ", None),
|
|
]:
|
|
got = s._extract_topic(text)
|
|
case("extract_topic", name, {"text": text}, got)
|
|
|
|
# ── get_recent_findings ──────────────────────────────────────────
|
|
s2 = sp.SubconsciousPass()
|
|
r1 = s2.reflect("build it", "ok" * 30, {})
|
|
r2 = s2.reflect("What?", "Nothing.", {})
|
|
r3 = s2.reflect("no findings here", "x" * 60, {})
|
|
r4 = s2.reflect("frustrated", "y" * 60, {})
|
|
case("recent_findings", "default_limit",
|
|
{"reports": [r1, r2, r3, r4]}, s2.get_recent_findings())
|
|
case("recent_findings", "limit_2",
|
|
{"reports": [r1, r2, r3, r4], "limit": 2}, s2.get_recent_findings(2))
|
|
case("recent_findings", "limit_0",
|
|
{"reports": [r1, r2, r3, r4], "limit": 0}, s2.get_recent_findings(0))
|
|
sparse = [{"findings": [{"type": "a", "detail": "d", "severity": "low"}]},
|
|
{"no_findings_key": True},
|
|
{"findings": []}]
|
|
s5 = sp.SubconsciousPass()
|
|
s5.findings = list(sparse)
|
|
case("recent_findings", "sparse_reports",
|
|
{"reports": sparse}, s5.get_recent_findings(10))
|
|
case("recent_findings", "empty",
|
|
{"reports": []}, _recent([], 10))
|
|
|
|
# ── save_reflection (exact file bytes; naming/write is facade) ───
|
|
for i, report in enumerate([r1, {"a": 1, "list": [1, 2.5], "s": "é"}]):
|
|
s3 = sp.SubconsciousPass()
|
|
# call the real oracle save path with a redirected dir
|
|
orig_dir = sp.REFLECTIONS_DIR
|
|
tmp = Path(__import__("tempfile").mkdtemp(prefix="sp_truth_"))
|
|
sp.REFLECTIONS_DIR = str(tmp)
|
|
try:
|
|
s3.save_reflection(report)
|
|
files = sorted(tmp.iterdir())
|
|
assert len(files) == 1
|
|
content = files[0].read_text()
|
|
finally:
|
|
sp.REFLECTIONS_DIR = orig_dir
|
|
import shutil
|
|
shutil.rmtree(tmp, ignore_errors=True)
|
|
# the frozen corpus round-trips the report sort_keys=True, so the
|
|
# replayable byte law is json.dump over THAT dict order
|
|
sorted_report = json.loads(json.dumps(report, sort_keys=True))
|
|
case("save_reflection", f"report{i}", {"report": sorted_report},
|
|
json.dumps(sorted_report, indent=2))
|
|
|
|
OUT.parent.mkdir(parents=True, exist_ok=True)
|
|
groups = {}
|
|
for c in cases:
|
|
groups.setdefault(f"{c['fn']}_cases", []).append(c)
|
|
OUT.write_text(json.dumps(
|
|
{"module": "subconscious_pass", "now": FIXED_NOW, **groups},
|
|
indent=1, sort_keys=True) + "\n")
|
|
print(f"frozen {len(cases)} cases -> {OUT}")
|
|
|
|
|
|
def _recent(reports, limit):
|
|
all_findings = []
|
|
for r in reports[-limit:]:
|
|
all_findings.extend(r.get("findings", []))
|
|
return all_findings
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|