feat(warm_router): close PARTIAL gaps — dichotomy wave

Routing/activation/scoring family (builder factory-heavy-wr-route):
port the five audit-missing fns into src/go/warm-router/gaps_routing.go
(BaseLevelActivation, PrimedAssociations, AssociatedNeuronBodies,
GraphContext, RenderFired; I/O-as-args split) + gap-cli parity surface.

Fixes two latent defects the frozen battery caught:
- warm_router.py _primed_associations passed (limit,) for a statement
  with len(ids)+1 placeholders — every call raised ProgrammingError and
  returned [] (the association-neighbour priming walk was dead code).
  Now binds (*ids, limit).
- main.go baseLevelFromUses parsed nowISO with a literal-Z layout, so
  '+00:00' stamps fell back to the wall clock. Now RFC3339 first.

Frozen truth 34 rows (shared freeze_truth harness under
scripts/wr_freeze_seams rig) byte-identical on --verify; battery
truth_gap_test.go replays all rows; live parity 60/60
(check_warm_router_gap_parity.py); go build/vet/gofmt clean; Python
suite green on the delegation pin (python-pin failures pre-exist on the
stashed tree — retired-fallback -2.0 degradation, Go-only lane).

Family coverage 11/16 -> 16/16; module 17/33 -> 22/33 (remaining 11 are
other families' files).
This commit is contained in:
Nick committed 2026-10-14 23:39:00 +01:00
1 parent 7001fce0d2
commit 9102fc2be6
27 files changed
+1708 -2

No files matched your search

+252
View File
@@ -0,0 +1,252 @@
#!/usr/bin/env python3
"""check_warm_router_gap_parity.py — LIVE parity for the warm_router GO
gap port (dichotomy wave #2479, routing/activation/scoring family):
drives the Python oracle (src/rune/warm_router.py) and the GO binary's
`gap-cli` subcommand through IDENTICAL scenarios and diffs the results.
The I/O-as-args split: for every DB-backed fn the script runs the oracle
function end-to-end, then replays the oracle's OWN gather SQL (copied
verbatim — the caller-side contract) and feeds the gathered rows to the
Go binary. graph_context's gather is the subprocess payload itself: the
script runs the same graph_memory query the oracle spawns, then feeds
its stdout JSON to the Go side. render_fired args pass through verbatim.
Runs under the scripts/wr_freeze_seams rig (hermetic RUNE_MEMORY_DIR +
fixtures + pins) and EXTENDS the fixtures deterministically before the
scenarios (new entries/associations/use_history rows, a second primed
session, an extra graph entity) so the live corpus is strictly larger
than the frozen one.
Usage (build first: cd src/go/warm-router && go build -o /tmp/warm-router-gap .):
PYTHONPATH=scripts/wr_freeze_seams python3 scripts/check_warm_router_gap_parity.py /tmp/warm-router-gap
"""
from __future__ import annotations
import json
import os
import sqlite3
import subprocess
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(REPO / "src" / "rune"))
import warm_router as wr # noqa: E402 (rig pins env before this import)
NOW = "2026-10-15T00:00:00+00:00"
BINARY = sys.argv[1] if len(sys.argv) > 1 else "/tmp/warm-router-gap"
PASS = 0
FAIL = 0
def go(fn: str, *args: str):
r = subprocess.run(
[BINARY, "gap-cli", fn, *args], capture_output=True, text=True, timeout=30
)
if r.returncode != 0:
raise RuntimeError(f"go gap-cli {fn} rc={r.returncode}: {r.stderr.strip()}")
return json.loads(r.stdout)
def check(label: str, want, got) -> None:
global PASS, FAIL
ok = want == got
if isinstance(want, float) and isinstance(got, float):
ok = abs(want - got) <= 1e-12
if ok:
PASS += 1
else:
FAIL += 1
print(f"FAIL {label}:\n oracle: {want!r}\n go: {got!r}")
# ── fixture extension (deterministic, beyond the frozen set) ──
db = sqlite3.connect(wr.STORE_DB)
db.execute(
"INSERT INTO entries (id, text, slug, triggers, importance, summary, kind, status) "
"VALUES (11, 'omega bridge body', 'omega-bridge', 'omega', 0.75, 'omega bridge summary', 'neuron', 'active')"
)
db.executemany(
"INSERT INTO use_history (entry_id, used_at, session_id, outcome) VALUES (?,?,?,?)",
[
(11, "2026-10-14T22:00:00+00:00", "s2", "helpful"),
(11, "2026-10-14T10:00:00+00:00", "s2", "helpful"),
(11, "2026-10-12T10:00:00+00:00", "s2", "ignored"),
],
)
db.executemany(
"INSERT INTO associations (src_id, dst_id, strength) VALUES (?,?,?)",
[(11, 2, 0.85), (11, 9, 0.45), (11, 8, 0.3), (11, 6, 0.95)],
)
db.commit()
db.close()
state_path = Path(wr.STATE)
state = json.loads(state_path.read_text())
state["sessions"]["s2"] = {
"primed": {"omega-bridge": 0.6, "beta-lens": 0.2}, "turns": 3,
"last_active": "2026-10-14T21:00:00",
}
state_path.write_text(json.dumps(state, indent=2) + "\n")
gdb = sqlite3.connect(str(Path(wr.MEM_DIR) / "graph" / "graph.sqlite"))
gdb.execute("INSERT INTO entities (id, name, type) VALUES (5, 'Zeke', 'person')")
gdb.execute("INSERT INTO edges (subj_id, pred, obj_id, confidence, status) VALUES (5, 'knows', 1, 0.75, 'active')")
gdb.execute("INSERT INTO edges (subj_id, pred, obj_id, confidence, status) VALUES (1, 'knows', 5, 0.65, 'active')")
gdb.commit()
gdb.close()
# ── the oracle's gather SQL (caller-side contract, copied verbatim) ──
def gather_use_history(entry_id: int) -> list[str]:
db = sqlite3.connect(f"file:{wr.STORE_DB}?mode=ro", uri=True)
try:
rows = db.execute(
"SELECT used_at FROM use_history WHERE entry_id = ? ORDER BY used_at DESC LIMIT ?",
(entry_id, wr.BASE_LEVEL_MAX_USES),
).fetchall()
return [r[0] for r in rows]
finally:
db.close()
def gather_primed_links(session_id: str, limit: int):
st = wr.load_state()
sess = st.get("sessions", {}).get(session_id) or {}
primed = sess.get("primed", {})
if not primed:
return [], []
slugs = list(primed.keys())
db = sqlite3.connect(f"file:{wr.STORE_DB}?mode=ro", uri=True)
try:
ph = ",".join("?" * len(slugs))
rows = db.execute(
f"SELECT id FROM entries WHERE kind='neuron' AND slug IN ({ph})", slugs
).fetchall()
ids = [r[0] for r in rows]
if not ids:
return [], slugs
iph = ",".join("?" * len(ids))
links = db.execute(
"SELECT e.slug, a.strength FROM associations a "
"JOIN entries e ON e.id=a.dst_id "
f"WHERE a.src_id IN ({iph}) AND a.strength >= 0.3 "
"AND e.kind='neuron' AND e.status='active' "
"ORDER BY a.strength DESC LIMIT ?",
(*ids, limit),
).fetchall()
return [{"Slug": r[0], "Strength": float(r[1])} for r in links], slugs
finally:
db.close()
def gather_assoc_links(fired):
slugs = [f["slug"] for f in fired]
db = sqlite3.connect(f"file:{wr.STORE_DB}?mode=ro", uri=True)
try:
ph = ",".join("?" * len(slugs))
rows = db.execute(
f"SELECT id, slug FROM entries WHERE kind='neuron' AND slug IN ({ph})", slugs
).fetchall()
ids = [r[0] for r in rows]
if not ids:
return []
iph = ",".join("?" * len(ids))
links = db.execute(
"SELECT a.src_id AS src, a.dst_id AS dst, a.strength, "
"e.slug, e.summary, e.text "
"FROM associations a JOIN entries e ON e.id=a.dst_id "
f"WHERE a.src_id IN ({iph}) AND a.strength >= 0.3 "
"AND e.status='active' "
"ORDER BY a.strength DESC LIMIT 6",
ids,
).fetchall()
return [{"Slug": r[3], "Summary": r[4] or "", "Text": r[5] or "", "Strength": float(r[2])} for r in links]
finally:
db.close()
def gather_graph_payload(term: str, hops: int) -> str:
r = subprocess.run(
[sys.executable, str(Path(wr.__file__).parent / "graph_memory.py"),
"query", term, "--hops", str(hops), "--json"],
capture_output=True, text=True, timeout=10,
)
return r.stdout
# ── scenarios ──
# base_level_activation: entry sweep + pinned clocks (incl. a tz-offset now)
for entry_id in (1, 2, 3, 8, 10, 11, 999):
for now in (NOW, "2026-10-15T01:00:00+01:00", "2026-10-20T00:00:00+00:00"):
want = wr.base_level_activation(entry_id, now_iso=now)
got = go("base-level-activation", json.dumps(gather_use_history(entry_id)), now)["score"]
check(f"base_level_activation({entry_id}, {now})", float(want), float(got))
# _primed_associations: sessions + limit sweep
for session, limit in (
("s1", 4), ("s1", 1), ("s1", 2), ("s1", 99),
("s2", 4), ("s2", 2),
("s-missing", 4), ("s-empty", 4), ("s-ghost", 4),
):
want = wr._primed_associations(session, limit)
links, slugs = gather_primed_links(session, limit)
got = go("primed-associations", json.dumps(links), json.dumps(slugs))
want_l = [[s, float(w)] for s, w in want]
check(f"_primed_associations({session!r}, {limit})", want_l, got)
# _associated_neuron_bodies: fired combos × budgets
for fired, budget in (
([{"slug": "alpha-core"}], 6),
([{"slug": "alpha-core"}], 20),
([{"slug": "alpha-core"}], 0),
([{"slug": "alpha-core"}], 1000),
([{"slug": "alpha-core"}, {"slug": "beta-lens"}], 30),
([{"slug": "beta-lens"}], 20),
([{"slug": "alpha-shadow"}], 20),
([{"slug": "gamma-dated"}], 20),
([{"slug": "omega-bridge"}], 24),
([{"slug": "omega-bridge"}], 8),
([{"slug": "retired-one"}], 20),
([{"slug": "no-such-slug"}], 20),
):
want = wr._associated_neuron_bodies(fired, budget)
links = gather_assoc_links(fired)
fired_slugs = [f["slug"] for f in fired]
got = go("associated-neuron-bodies", json.dumps(links), json.dumps(fired_slugs), str(budget))
check(f"_associated_neuron_bodies({fired_slugs}, {budget})", want, got)
# graph_context: terms × hops × limits (gather = the subprocess payload)
for term, hops, limit in (
("Alice", 1, 4), ("Alice", 2, 4), ("Alice", 1, 1), ("Alice", 1, 0),
("Alice", 1, -1), ("Alice", 1, 99),
("Al", 1, 4), ("Rune", 1, 4), ("Zeke", 1, 4), ("Nobody", 1, 4),
("", 1, 4),
):
want = wr.graph_context(term, hops=hops, limit=limit)
payload = gather_graph_payload(term, hops)
got = go("graph-context", payload.replace("\n", " "), term, str(limit))["rendered"]
check(f"graph_context({term!r}, {hops}, {limit})", want, got)
# render_fired: pure args pass through verbatim
for fired in (
[],
[{"slug": "a", "body": "plain"}],
[{"slug": "b", "body": "x", "via_association": True}],
[{"slug": "c", "body": "y", "compressed": True}],
[{"slug": "d", "body": "z", "via_association": True, "compressed": True}],
[{"slug": "e", "body": "café — résumé ✓"}, {"slug": "f", "body": "second", "via_association": True}],
[{"slug": "g", "body": ""}],
):
want = wr.render_fired(fired)
got = go("render-fired", json.dumps(fired))["rendered"]
check(f"render_fired({len(fired)} entries)", want, got)
print(f"\nparity: {PASS}/{PASS + FAIL}" + (f" ({FAIL} FAILURES)" if FAIL else " — all green"))
sys.exit(1 if FAIL else 0)
+103
View File
@@ -0,0 +1,103 @@
#!/usr/bin/env python3
"""Freeze warm_router oracle truth for the GO gap battery (dichotomy wave
#2479, routing/activation/scoring family, builder factory-heavy-wr-route)
using the shared harness scripts/freeze_truth.py under the
scripts/wr_freeze_seams rig (hermetic RUNE_MEMORY_DIR, pinned
RUNE_GRAPH_MEMORY_CORE, live MS_RUST_LIB delegation).
Exercises the five family gap functions and every reachable branch:
base_level_activation cold start (no entry / no history), ACT-R
math (3 rows, 1 row), the db=None default,
the non-string used_at -2.0 envelope
_primed_associations full link walk (kind='neuron' filter drops
the document row), LIMIT, missing session,
empty primed, primed slug with no entry
_associated_neuron_bodies budget break mid-walk, multi-fit, seen-set
skip + empty-body slug burn, immediate
break on budget 0, the empty-slug
slug-or-assoc row, a back-link walk
graph_context dict shape (found entity — entity name from
the payload, NOT the term), unknown-entity
list shape -> '', hops=2, limit=1, empty
term, a second entry node
render_fired plain / via_association / compressed tags,
both flags (assoc outranks), unicode body,
empty list, extra keys ignored
Run from the repo root (build the memory_scoring kernel first —
cd src/rust/memory_scoring && cargo build --release):
PYTHONPATH=scripts/wr_freeze_seams python3 scripts/gen_warm_router_gap_truth.py
Verify (byte-identical law):
PYTHONPATH=src:scripts/wr_freeze_seams python3 scripts/freeze_truth.py \
--verify src/go/warm-router/truth_gap.json --module rune.warm_router
Output: src/go/warm-router/truth_gap.json
(harness schema: [{fn, args, kwargs, expected}] — replayed by
truth_gap_test.go).
"""
from __future__ import annotations
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "scripts"))
from freeze_truth import freeze, write # noqa: E402
OUT = REPO / "src" / "go" / "warm-router" / "truth_gap.json"
NOW = "2026-10-15T00:00:00+00:00"
CASES = [
# ── base_level_activation ────────────────────────────────────────
("base_level_activation", (999,), {"now_iso": NOW}), # no entry, no history
("base_level_activation", (3,), {"now_iso": NOW}), # entry, never fired
("base_level_activation", (1,), {"now_iso": NOW}), # 3 rows (1h/6h/11h)
("base_level_activation", (2,), {"db": None, "now_iso": NOW}), # single row + db default
("base_level_activation", (8,), {"now_iso": NOW}), # non-string used_at -> -2.0 envelope
("base_level_activation", (10,), {"now_iso": NOW}), # 105 rows: the 100-newest scan cap
# ── _primed_associations ─────────────────────────────────────────
("_primed_associations", ("s1",), {}), # kind filter drops plain-doc
("_primed_associations", ("s1", 2), {}), # LIMIT 2
("_primed_associations", ("s-missing",), {}), # no session -> []
("_primed_associations", ("s-empty",), {}), # nothing primed -> []
("_primed_associations", ("s-ghost",), {}), # primed slug with no entry -> []
# ── _associated_neuron_bodies ────────────────────────────────────
("_associated_neuron_bodies", ([{"slug": "alpha-core"}], 6), {}), # break mid-walk
("_associated_neuron_bodies", ([{"slug": "alpha-core"}], 20), {}), # two fit, third breaks
("_associated_neuron_bodies", ([{"slug": "alpha-core"}, {"slug": "beta-lens"}], 30), {}), # seen skip + hollow burn
("_associated_neuron_bodies", ([{"slug": "alpha-core"}], 0), {}), # immediate break
("_associated_neuron_bodies", ([{"slug": "beta-lens"}], 20), {}), # empty-slug -> assoc
("_associated_neuron_bodies", ([{"slug": "alpha-shadow"}], 20), {}), # back-link walk
("_associated_neuron_bodies", ([{"slug": "gamma-dated"}], 20), {}), # unicode body: rune-count tokens
# ── graph_context ────────────────────────────────────────────────
("graph_context", ("Alice",), {}), # dict shape; entity from payload
("graph_context", ("Al",), {}), # alias resolves; header says Alice
("graph_context", ("Nobody",), {}), # list shape ([]) -> ''
("graph_context", ("Alice", 2), {}), # 2 hops
("graph_context", ("Alice", 1, 1), {}), # limit 1
("graph_context", ("Alice", 1, 0), {}), # limit 0 -> facts[:0] -> ''
("graph_context", ("Alice", 1, -1), {}), # negative limit: facts[:-1]
("graph_context", ("",), {}), # empty term -> ''
("graph_context", ("Rune",), {}), # second entry node
# ── render_fired ─────────────────────────────────────────────────
("render_fired", ([{"slug": "alpha-core", "body": "Full body text."}],), {}),
("render_fired", ([{"slug": "via", "body": "b", "via_association": True}],), {}),
("render_fired", ([{"slug": "c", "body": "b", "compressed": True}],), {}),
("render_fired", ([{"slug": "both", "body": "b", "via_association": True, "compressed": True}],), {}),
("render_fired", ([{"slug": "u", "body": "café — résumé ✓", "via_association": False}],), {}),
("render_fired", ([],), {}),
("render_fired", ([{"slug": "no-flags", "body": "x", "extra_ignored": 1}],), {}),
]
def main() -> None:
truth = freeze("warm_router", CASES, oracle_module="rune.warm_router")
write(truth, OUT)
print(f"frozen: {OUT} ({len(truth)} rows)")
if __name__ == "__main__":
main()
+197
View File
@@ -0,0 +1,197 @@
"""sitecustomize — the warm_router routing-family freeze rig (dichotomy
wave #2479 gap-close, worktree rune-wave-ws, builder
factory-heavy-wr-route).
Auto-imported via PYTHONPATH=scripts/wr_freeze_seams by the truth
generator, `freeze_truth.py --verify`, AND the live-parity script — and,
critically, by the graph_memory SUBPROCESS graph_context spawns (env is
inherited): the rig must therefore be idempotent. The FIRST process
under the rig mints the hermetic memory root and builds the fixtures;
every child (including the subprocess) sees RUNE_MEMORY_DIR already set
and skips straight through.
Pins:
* RUNE_WARM_ROUTER_CORE=python — inert (warm_router has no loader
seam); belt-and-braces parity with _pin_oracle_cores.
* RUNE_GRAPH_MEMORY_CORE=python — graph_context's subprocess must NOT
probe a graph kernel (its query_fact would reshape the facts).
* RUNE_MEMORY_CORE — POPPED if set: the base_level rows freeze the
LIVE delegation (the retired Python fallback recurses
_py_base_level_from_uses -> base_level_from_uses and degrades to
-2.0 — the oracle's own documented outer-catch behavior, NOT the
math contract this battery pins).
* MS_RUST_LIB — the built memory_scoring kernel, repo-relative when
present (worktree build), else the shared checkout build.
Fixtures (all under <root>, byte-deterministic, no absolute paths in
any frozen output):
* store/memory.db — entries (active neurons, a retired one, a
document-kind row that only survives _associated_neuron_bodies'
status-only filter, an empty-slug neuron, a hollow-body neuron),
use_history (ACT-R rows at pinned hour offsets, one NON-STRING row
for the -2.0 envelope), associations (0.9/0.7/0.4/0.35/0.33/0.6
links + a sub-0.3 one).
* graph/graph.sqlite — Alice/Bob/Rune/Rust entities, an Al alias,
four edges (2 outbound from Alice, 1 incoming, 1 second-hop).
* index/warm_state.json — sessions s1 (primed alpha-core), s-empty
(nothing primed), s-ghost (primed a slug with no entry).
"""
import os
import sqlite3
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parents[2]
os.environ.setdefault("RUNE_WARM_ROUTER_CORE", "python")
os.environ.setdefault("RUNE_GRAPH_MEMORY_CORE", "python")
os.environ.pop("RUNE_MEMORY_CORE", None) # live delegation for the math rows
_MS = REPO / "src" / "rust" / "memory_scoring" / "target" / "release" / "libmemory_scoring.so"
if _MS.is_file():
os.environ.setdefault("MS_RUST_LIB", str(_MS))
if str(REPO / "src") not in sys.path:
sys.path.insert(0, str(REPO / "src"))
def _build_store(db_path: Path) -> None:
db_path.parent.mkdir(parents=True, exist_ok=True)
db = sqlite3.connect(str(db_path))
db.executescript("""
CREATE TABLE IF NOT EXISTS entries (
id INTEGER PRIMARY KEY, text TEXT, slug TEXT, triggers TEXT,
importance REAL, summary TEXT, wash_count INTEGER DEFAULT 0,
always_on INTEGER DEFAULT 0, priority REAL DEFAULT 0,
last_accessed TEXT, kind TEXT DEFAULT 'neuron',
status TEXT DEFAULT 'active');
CREATE TABLE IF NOT EXISTS use_history (
id INTEGER PRIMARY KEY AUTOINCREMENT, entry_id INTEGER NOT NULL,
used_at TEXT NOT NULL DEFAULT (datetime('now')),
session_id TEXT, score REAL, outcome TEXT DEFAULT 'unknown');
CREATE TABLE IF NOT EXISTS associations (
src_id INTEGER NOT NULL, dst_id INTEGER NOT NULL,
strength REAL NOT NULL);
""")
db.executemany(
"INSERT INTO entries (id, text, slug, triggers, importance, summary, kind, status) "
"VALUES (?,?,?,?,?,?,?,?)",
[
(1, "alpha core body", "alpha-core", "alpha, core", 0.9, "alpha summary", "neuron", "active"),
(2, "beta lens body", "beta-lens", "beta", 0.8, "", "neuron", "active"),
(3, "gamma dated body", "gamma-dated", "gamma", 0.7, "", "neuron", "active"),
(4, "shadow body", "alpha-shadow", "shadow", 0.6, "shadow lens notes", "neuron", "active"),
(5, "retired body", "retired-one", "retired", 0.5, "", "neuron", "retired"),
(6, "A plain document text that is fairly long for budget math", "plain-doc", "doc", 0.5, "", "document", "active"),
(7, "seven token body padding", "", "", 0.5, "", "neuron", "active"),
(8, "", "hollow-body", "hollow", 0.5, "", "neuron", "active"),
(9, "", "unicode-body", "unicode", 0.5, "çafe — naïve ✓✓ padding", "neuron", "active"),
(10, "cap body", "cap-heavy", "cap", 0.5, "", "neuron", "active"),
],
)
db.executemany(
"INSERT INTO use_history (entry_id, used_at, session_id, outcome) VALUES (?,?,?,?)",
[
(1, "2026-10-14T23:00:00+00:00", "s1", "helpful"),
(1, "2026-10-14T18:00:00+00:00", "s1", "helpful"),
(1, "2026-10-14T13:00:00+00:00", "s1", "helpful"),
(2, "2026-10-14T23:30:00+00:00", "s1", "helpful"),
],
)
# non-string used_at (INTEGER): the kernel's -2.0 envelope row
db.execute("INSERT INTO use_history (entry_id, used_at, session_id, outcome) VALUES (8, 1791234567, 's1', 'unknown')")
# 105 rows for entry 10: pins the BASE_LEVEL_MAX_USES=100 scan cap
# (the gather keeps the 100 newest, used_at DESC)
from datetime import datetime, timedelta
_t0 = datetime(2026, 10, 14, 23, 0, 0)
db.executemany(
"INSERT INTO use_history (entry_id, used_at, session_id, outcome) VALUES (10, ?, 's1', 'helpful')",
[
((_t0 - timedelta(hours=k)).strftime("%Y-%m-%dT%H:%M:%S+00:00"),)
for k in range(105)
],
)
db.executemany(
"INSERT INTO associations (src_id, dst_id, strength) VALUES (?,?,?)",
[
(1, 4, 0.9), # alpha-core -> alpha-shadow
(1, 6, 0.7), # alpha-core -> plain-doc (kind=document: only survives the status-only filter)
(1, 2, 0.4), # alpha-core -> beta-lens
(1, 3, 0.35), # alpha-core -> gamma-dated
(1, 8, 0.33), # alpha-core -> hollow-body (empty body: seen-burns-slug row)
(2, 7, 0.6), # beta-lens -> '' slug (the slug-or-assoc row)
(2, 3, 0.2), # sub-threshold: never gathered
(3, 9, 0.5), # gamma-dated -> unicode-body (rune-count token law)
(4, 1, 0.5), # back-link to alpha-core (already-fired skip row)
],
)
db.commit()
db.close()
def _build_graph(db_path: Path) -> None:
db_path.parent.mkdir(parents=True, exist_ok=True)
db = sqlite3.connect(str(db_path))
db.executescript("""
CREATE TABLE IF NOT EXISTS entities (
id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE,
type TEXT NOT NULL DEFAULT 'concept', summary TEXT DEFAULT '',
created_at TEXT NOT NULL DEFAULT '2026-10-14T00:00:00');
CREATE TABLE IF NOT EXISTS aliases (
entity_id INTEGER NOT NULL, alias TEXT NOT NULL,
UNIQUE (entity_id, alias));
CREATE TABLE IF NOT EXISTS edges (
id INTEGER PRIMARY KEY AUTOINCREMENT,
subj_id INTEGER NOT NULL, pred TEXT NOT NULL,
obj_id INTEGER NOT NULL, evidence TEXT DEFAULT '',
source TEXT DEFAULT '', confidence REAL,
strength INTEGER, valid_from TEXT DEFAULT '',
valid_until TEXT DEFAULT '', status TEXT DEFAULT 'active');
""")
db.executemany(
"INSERT INTO entities (id, name, type) VALUES (?,?,?)",
[(1, "Alice", "person"), (2, "Bob", "person"),
(3, "Rune", "project"), (4, "Rust", "tool")],
)
db.execute("INSERT INTO aliases (entity_id, alias) VALUES (1, 'Al')")
db.executemany(
"INSERT INTO edges (subj_id, pred, obj_id, confidence, status) VALUES (?,?,?,?, 'active')",
[
(1, "manages", 3, 0.9), # Alice -> Rune
(1, "knows", 2, 0.8), # Alice -> Bob
(3, "uses", 4, 0.7), # Rune -> Rust (2nd hop)
(2, "collaborates_with", 1, 0.6), # Bob -> Alice (incoming)
],
)
db.commit()
db.close()
def _build_state(root: Path) -> None:
import json
idx = root / "index"
idx.mkdir(parents=True, exist_ok=True)
state = {
"neurons": {},
"divides": [],
"sessions": {
"s1": {"primed": {"alpha-core": 0.5}, "turns": 2, "last_active": "2026-10-14T20:00:00"},
"s-empty": {"primed": {}, "turns": 1, "last_active": "2026-10-14T20:00:00"},
"s-ghost": {"primed": {"ghost-neuron": 0.9}, "turns": 1, "last_active": "2026-10-14T20:00:00"},
},
}
(idx / "warm_state.json").write_text(json.dumps(state, indent=2) + "\n", encoding="utf-8")
if not os.environ.get("RUNE_MEMORY_DIR"):
import tempfile
_root = Path(tempfile.mkdtemp(prefix="wr-freeze-"))
os.environ["RUNE_MEMORY_DIR"] = str(_root)
os.environ.setdefault("RUNE_STORE_DB", str(_root / "store" / "memory.db"))
_build_store(_root / "store" / "memory.db")
_build_graph(_root / "graph" / "graph.sqlite")
_build_state(_root)
+316
View File
@@ -0,0 +1,316 @@
package main
// gaps_routing.go — dichotomy wave #2479 gap-close, routing/activation/
// scoring family (builder factory-heavy-wr-route). PARITY ports of the
// five audit-missing warm_router.py functions:
//
// base_level_activation -> BaseLevelActivation
// _associated_neuron_bodies -> AssociatedNeuronBodies
// _primed_associations -> PrimedAssociations
// graph_context -> GraphContext
// render_fired -> RenderFired
//
// I/O-as-args law (the module's established split): the SQLite gathers,
// the graph_memory subprocess, and the state-file reads stay caller-side;
// these are the deterministic decisions over the gathered rows.
//
// Truth battery: truth_gap.json (live Python oracle via the shared
// freeze_truth harness under scripts/wr_freeze_seams — 2026-10-14).
import (
"encoding/json"
"fmt"
"math"
"os"
"strings"
"unicode/utf8"
)
// BaseLevelMaxUses — the use_history scan cap (SQL LIMIT is caller-side).
const BaseLevelMaxUses = 100
// BaseLevelActivation — the wrapper contract of warm_router.py's
// base_level_activation minus the SQLite gather: no rows → -2.0 cold
// start; otherwise the ACT-R decay math (baseLevelFromUses) over the
// caller-gathered rows (used_at DESC, capped at BaseLevelMaxUses).
// nowISO == "" mirrors the oracle's `now_iso or datetime.now()` (the
// caller passes a pinned clock for determinism).
func BaseLevelActivation(usedAtRows []string, nowISO string) float64 {
if len(usedAtRows) == 0 {
return -2.0
}
return baseLevelFromUses(usedAtRows, nowISO)
}
// PrimedLink — one gathered association row for a primed neuron's
// outbound links: dst slug + link strength (SQL already applied
// strength >= 0.3, kind/status filters, strength DESC, LIMIT).
type PrimedLink struct {
Slug string
Strength float64
}
// PrimedPair — one primed association neighbour (slug, decayed weight).
type PrimedPair struct {
Slug string
Weight float64
}
// PrimedAssociations — warm_router.py's _primed_associations decision:
// association-neighbours of the primed slugs, weighted at
// AssocPrimeWeight, excluding the primed slugs themselves. The gather
// (primed slugs → entry ids → links) is caller-side.
func PrimedAssociations(links []PrimedLink, primedSlugs []string) []PrimedPair {
inPrimed := make(map[string]bool, len(primedSlugs))
for _, s := range primedSlugs {
inPrimed[s] = true
}
out := []PrimedPair{}
for _, l := range links {
if inPrimed[l.Slug] {
continue
}
out = append(out, PrimedPair{Slug: l.Slug, Weight: l.Strength * AssocPrimeWeight})
}
return out
}
// NeuronLink — one gathered association row for _associated_neuron_bodies
// (SQL already applied strength >= 0.3, status='active', strength DESC,
// LIMIT 6): the dst entry's slug, summary, text, and link strength.
type NeuronLink struct {
Slug string
Summary string
Text string
Strength float64
}
// AssociatedBody — one association-expanded firing (summary-or-text body).
type AssociatedBody struct {
Slug string `json:"slug"`
Body string `json:"body"`
Score float64 `json:"score"`
Tokens int `json:"tokens"`
}
// AssociatedNeuronBodies — warm_router.py's _associated_neuron_bodies
// budget walk: skip already-seen slugs (the fired set grows as links are
// consumed, so an empty-body link still burns its slug), body =
// summary-or-text stripped, tokens = max(1, CHARS/4) (Python len() counts
// codepoints — rune law), BREAK (not skip) when the remaining budget
// cannot fit the next body, score = round(strength, 2) half-to-even.
func AssociatedNeuronBodies(links []NeuronLink, firedSlugs []string, budgetTokens int) []AssociatedBody {
out := []AssociatedBody{}
seen := make(map[string]bool, len(firedSlugs))
for _, s := range firedSlugs {
seen[s] = true
}
used := 0
for _, l := range links {
if seen[l.Slug] {
continue
}
seen[l.Slug] = true
body := strings.TrimSpace(l.Summary)
if body == "" {
body = strings.TrimSpace(l.Text)
}
if body == "" {
continue
}
tokens := utf8.RuneCountInString(body) / 4
if tokens < 1 {
tokens = 1
}
if used+tokens > budgetTokens {
break
}
slug := l.Slug
if slug == "" {
slug = "assoc"
}
out = append(out, AssociatedBody{
Slug: slug, Body: body, Score: roundHalfEven2(l.Strength), Tokens: tokens,
})
used += tokens
}
return out
}
// roundHalfEven2 — Python round(x, 2): banker's rounding on the exact
// binary value (math.RoundToEven; the only exact .xx5 ties are the
// dyadic rationals, where the f64 product is exact — same verdict as
// CPython's correctly-rounded decimal path).
func roundHalfEven2(f float64) float64 {
return math.RoundToEven(f*100) / 100
}
// GraphContext — warm_router.py's graph_context minus the subprocess:
// the graph_memory query JSON arrives parsed-or-raw (list of facts OR
// the {"facts", "entity"} dict shape — the audit-fix branch), the first
// `limit` facts render as "subject → predicate → object" lines under the
// entity header. No facts → "" (the caller injects nothing); a POSITIVE
// limit smaller than the list keeps the header (the oracle's empty check
// tests the FULL list, not the slice — facts[:0] renders the bare
// header). Python slice semantics: negative limits take
// facts[:limit] = len+limit.
func GraphContext(factsJSON []byte, term string, limit int) string {
var data interface{}
if err := json.Unmarshal(factsJSON, &data); err != nil {
return ""
}
var facts []interface{}
entity := term
switch v := data.(type) {
case map[string]interface{}:
if raw, ok := v["facts"].([]interface{}); ok {
facts = raw
}
if e, ok := v["entity"].(string); ok && e != "" {
entity = e
} else if e := v["entity"]; e != nil {
entity = fmt.Sprint(e)
}
case []interface{}:
facts = v
}
if len(facts) == 0 {
return ""
}
n := limit
if n < 0 {
n += len(facts)
}
if n < 0 {
n = 0
}
if n > len(facts) {
n = len(facts)
}
lines := make([]string, 0, n)
for _, f := range facts[:n] {
m, ok := f.(map[string]interface{})
if !ok {
continue
}
lines = append(lines, fmt.Sprintf("%s → %s → %s",
graphFactField(m, "subject"), graphFactField(m, "predicate"),
graphFactField(m, "object")))
}
return fmt.Sprintf("### Graph memory (connected to '%s')\n\n%s", entity, strings.Join(lines, "\n"))
}
// graphFactField — f"{f[key]}" renders via str(); JSON scalars format
// identically through Sprint (strings verbatim, numbers shortest-form).
func graphFactField(m map[string]interface{}, key string) string {
if v, ok := m[key].(string); ok {
return v
}
if v, ok := m[key]; ok && v != nil {
return fmt.Sprint(v)
}
return ""
}
// FiredRender — one fired-neuron record as render_fired sees it.
type FiredRender struct {
Slug string `json:"slug"`
Body string `json:"body"`
ViaAssociation bool `json:"via_association,omitempty"`
Compressed bool `json:"compressed,omitempty"`
}
// RenderFired — warm_router.py's render_fired: the injection block.
// via_association outranks compressed for the tag; empty input → "".
func RenderFired(fired []FiredRender) string {
parts := make([]string, 0, len(fired))
for _, f := range fired {
tag := ""
if f.ViaAssociation {
tag = " (via association)"
} else if f.Compressed {
tag = " (compressed summary — full body in store)"
}
parts = append(parts, fmt.Sprintf("### Warm neuron: %s%s\n\n%s", f.Slug, tag, f.Body))
}
return strings.Join(parts, "\n\n")
}
// gapRoutingCLI — the parity surface: runs the five gap functions on
// JSON argv payloads (the parity script feeds the same gathered rows to
// this binary that the oracle's SQL/subprocess gathered).
func gapRoutingCLI(args []string) {
if len(args) == 0 {
fmt.Fprintln(os.Stderr, "usage: warm-router gap-cli <fn> [args...]")
os.Exit(1)
}
fn, rest := args[0], args[1:]
switch fn {
case "base-level-activation":
if len(rest) != 2 {
gapUsage("base-level-activation <rows-json> <now-iso>")
}
var rows []string
mustUnmarshalJSON(rest[0], &rows)
emitJSON(map[string]float64{"score": BaseLevelActivation(rows, rest[1])})
case "primed-associations":
if len(rest) != 2 {
gapUsage("primed-associations <links-json> <primed-slugs-json>")
}
var links []PrimedLink
mustUnmarshalJSON(rest[0], &links)
var primed []string
mustUnmarshalJSON(rest[1], &primed)
pairs := PrimedAssociations(links, primed)
out := make([][2]interface{}, 0, len(pairs))
for _, p := range pairs {
out = append(out, [2]interface{}{p.Slug, p.Weight})
}
emitJSON(out)
case "associated-neuron-bodies":
if len(rest) != 3 {
gapUsage("associated-neuron-bodies <links-json> <fired-slugs-json> <budget>")
}
var links []NeuronLink
mustUnmarshalJSON(rest[0], &links)
var fired []string
mustUnmarshalJSON(rest[1], &fired)
var budget int
fmt.Sscanf(rest[2], "%d", &budget)
emitJSON(AssociatedNeuronBodies(links, fired, budget))
case "graph-context":
if len(rest) != 3 {
gapUsage("graph-context <facts-json> <term> <limit>")
}
var limit int
fmt.Sscanf(rest[2], "%d", &limit)
emitJSON(map[string]string{"rendered": GraphContext([]byte(rest[0]), rest[1], limit)})
case "render-fired":
if len(rest) != 1 {
gapUsage("render-fired <fired-json>")
}
var fired []FiredRender
mustUnmarshalJSON(rest[0], &fired)
emitJSON(map[string]string{"rendered": RenderFired(fired)})
default:
fmt.Fprintf(os.Stderr, "unknown gap-cli fn: %s\n", fn)
os.Exit(1)
}
}
func gapUsage(u string) {
fmt.Fprintln(os.Stderr, "usage: warm-router gap-cli "+u)
os.Exit(1)
}
func mustUnmarshalJSON(s string, v interface{}) {
if err := json.Unmarshal([]byte(s), v); err != nil {
fmt.Fprintf(os.Stderr, "bad JSON payload: %v\n", err)
os.Exit(1)
}
}
func emitJSON(v interface{}) {
out, _ := json.Marshal(v)
fmt.Println(string(out))
}
+7 -1
View File
@@ -28,7 +28,10 @@ func baseLevelFromUses(usedAtList []string, nowISO string) float64 {
return -2.0 // Cold start — never fired
}
now, err := time.Parse("2006-01-02T15:04:05Z", nowISO)
now, err := time.Parse(time.RFC3339, nowISO)
if err != nil {
now, err = time.Parse("2006-01-02T15:04:05", nowISO)
}
if err != nil {
now = time.Now().UTC()
}
@@ -110,6 +113,9 @@ func main() {
args := os.Args[2:]
switch cmd {
case "gap-cli":
// gap family parity surface (gaps_routing.go)
gapRoutingCLI(args)
case "base-level":
if len(args) < 2 {
fmt.Fprintln(os.Stderr, "usage: warm-router base-level <timestamps-csv> <now-iso>")
+461
View File
@@ -0,0 +1,461 @@
[
{
"fn": "base_level_activation",
"args": [
999
],
"kwargs": {
"now_iso": "2026-10-15T00:00:00+00:00"
},
"expected": -2.0
},
{
"fn": "base_level_activation",
"args": [
3
],
"kwargs": {
"now_iso": "2026-10-15T00:00:00+00:00"
},
"expected": -2.0
},
{
"fn": "base_level_activation",
"args": [
1
],
"kwargs": {
"now_iso": "2026-10-15T00:00:00+00:00"
},
"expected": 0.5363527963313388
},
{
"fn": "base_level_activation",
"args": [
2
],
"kwargs": {
"db": null,
"now_iso": "2026-10-15T00:00:00+00:00"
},
"expected": 0.3465735902799727
},
{
"fn": "base_level_activation",
"args": [
8
],
"kwargs": {
"now_iso": "2026-10-15T00:00:00+00:00"
},
"expected": -2
},
{
"fn": "base_level_activation",
"args": [
10
],
"kwargs": {
"now_iso": "2026-10-15T00:00:00+00:00"
},
"expected": 2
},
{
"fn": "_primed_associations",
"args": [
"s1"
],
"kwargs": {},
"expected": [
[
"alpha-shadow",
0.45
],
[
"beta-lens",
0.2
],
[
"gamma-dated",
0.175
],
[
"hollow-body",
0.165
]
]
},
{
"fn": "_primed_associations",
"args": [
"s1",
2
],
"kwargs": {},
"expected": [
[
"alpha-shadow",
0.45
],
[
"beta-lens",
0.2
]
]
},
{
"fn": "_primed_associations",
"args": [
"s-missing"
],
"kwargs": {},
"expected": []
},
{
"fn": "_primed_associations",
"args": [
"s-empty"
],
"kwargs": {},
"expected": []
},
{
"fn": "_primed_associations",
"args": [
"s-ghost"
],
"kwargs": {},
"expected": []
},
{
"fn": "_associated_neuron_bodies",
"args": [
[
{
"slug": "alpha-core"
}
],
6
],
"kwargs": {},
"expected": [
{
"slug": "alpha-shadow",
"body": "shadow lens notes",
"score": 0.9,
"tokens": 4
}
]
},
{
"fn": "_associated_neuron_bodies",
"args": [
[
{
"slug": "alpha-core"
}
],
20
],
"kwargs": {},
"expected": [
{
"slug": "alpha-shadow",
"body": "shadow lens notes",
"score": 0.9,
"tokens": 4
},
{
"slug": "plain-doc",
"body": "A plain document text that is fairly long for budget math",
"score": 0.7,
"tokens": 14
}
]
},
{
"fn": "_associated_neuron_bodies",
"args": [
[
{
"slug": "alpha-core"
},
{
"slug": "beta-lens"
}
],
30
],
"kwargs": {},
"expected": [
{
"slug": "alpha-shadow",
"body": "shadow lens notes",
"score": 0.9,
"tokens": 4
},
{
"slug": "plain-doc",
"body": "A plain document text that is fairly long for budget math",
"score": 0.7,
"tokens": 14
},
{
"slug": "assoc",
"body": "seven token body padding",
"score": 0.6,
"tokens": 6
},
{
"slug": "gamma-dated",
"body": "gamma dated body",
"score": 0.35,
"tokens": 4
}
]
},
{
"fn": "_associated_neuron_bodies",
"args": [
[
{
"slug": "alpha-core"
}
],
0
],
"kwargs": {},
"expected": []
},
{
"fn": "_associated_neuron_bodies",
"args": [
[
{
"slug": "beta-lens"
}
],
20
],
"kwargs": {},
"expected": [
{
"slug": "assoc",
"body": "seven token body padding",
"score": 0.6,
"tokens": 6
}
]
},
{
"fn": "_associated_neuron_bodies",
"args": [
[
{
"slug": "alpha-shadow"
}
],
20
],
"kwargs": {},
"expected": [
{
"slug": "alpha-core",
"body": "alpha summary",
"score": 0.5,
"tokens": 3
}
]
},
{
"fn": "_associated_neuron_bodies",
"args": [
[
{
"slug": "gamma-dated"
}
],
20
],
"kwargs": {},
"expected": [
{
"slug": "unicode-body",
"body": "çafe — naïve ✓✓ padding",
"score": 0.5,
"tokens": 5
}
]
},
{
"fn": "graph_context",
"args": [
"Alice"
],
"kwargs": {},
"expected": "### Graph memory (connected to 'Alice')\n\nAlice → manages → Rune\nAlice → knows → Bob\nRune → uses → Rust\nBob → collaborates_with → Alice"
},
{
"fn": "graph_context",
"args": [
"Al"
],
"kwargs": {},
"expected": "### Graph memory (connected to 'Alice')\n\nAlice → manages → Rune\nAlice → knows → Bob\nRune → uses → Rust\nBob → collaborates_with → Alice"
},
{
"fn": "graph_context",
"args": [
"Nobody"
],
"kwargs": {},
"expected": ""
},
{
"fn": "graph_context",
"args": [
"Alice",
2
],
"kwargs": {},
"expected": "### Graph memory (connected to 'Alice')\n\nAlice → manages → Rune\nAlice → knows → Bob\nRune → uses → Rust\nBob → collaborates_with → Alice"
},
{
"fn": "graph_context",
"args": [
"Alice",
1,
1
],
"kwargs": {},
"expected": "### Graph memory (connected to 'Alice')\n\nAlice → manages → Rune"
},
{
"fn": "graph_context",
"args": [
"Alice",
1,
0
],
"kwargs": {},
"expected": "### Graph memory (connected to 'Alice')\n\n"
},
{
"fn": "graph_context",
"args": [
"Alice",
1,
-1
],
"kwargs": {},
"expected": "### Graph memory (connected to 'Alice')\n\nAlice → manages → Rune\nAlice → knows → Bob\nRune → uses → Rust\nBob → collaborates_with → Alice"
},
{
"fn": "graph_context",
"args": [
""
],
"kwargs": {},
"expected": ""
},
{
"fn": "graph_context",
"args": [
"Rune"
],
"kwargs": {},
"expected": "### Graph memory (connected to 'Rune')\n\nRune → uses → Rust\nAlice → manages → Rune"
},
{
"fn": "render_fired",
"args": [
[
{
"slug": "alpha-core",
"body": "Full body text."
}
]
],
"kwargs": {},
"expected": "### Warm neuron: alpha-core\n\nFull body text."
},
{
"fn": "render_fired",
"args": [
[
{
"slug": "via",
"body": "b",
"via_association": true
}
]
],
"kwargs": {},
"expected": "### Warm neuron: via (via association)\n\nb"
},
{
"fn": "render_fired",
"args": [
[
{
"slug": "c",
"body": "b",
"compressed": true
}
]
],
"kwargs": {},
"expected": "### Warm neuron: c (compressed summary — full body in store)\n\nb"
},
{
"fn": "render_fired",
"args": [
[
{
"slug": "both",
"body": "b",
"via_association": true,
"compressed": true
}
]
],
"kwargs": {},
"expected": "### Warm neuron: both (via association)\n\nb"
},
{
"fn": "render_fired",
"args": [
[
{
"slug": "u",
"body": "café — résumé ✓",
"via_association": false
}
]
],
"kwargs": {},
"expected": "### Warm neuron: u\n\ncafé — résumé ✓"
},
{
"fn": "render_fired",
"args": [
[]
],
"kwargs": {},
"expected": ""
},
{
"fn": "render_fired",
"args": [
[
{
"slug": "no-flags",
"body": "x",
"extra_ignored": 1
}
]
],
"kwargs": {},
"expected": "### Warm neuron: no-flags\n\nx"
}
]
+253
View File
@@ -0,0 +1,253 @@
package main
// truth_gap_test.go — parity battery for the routing/activation/scoring
// family gap port (dichotomy wave #2479, builder factory-heavy-wr-route).
// Replays truth_gap.json (live Python oracle via scripts/wr_freeze_seams,
// 2026-10-14) through BaseLevelActivation, PrimedAssociations,
// AssociatedNeuronBodies, GraphContext, RenderFired.
//
// The oracle rows carry the I/O-layer arguments (entry ids, session ids,
// fired lists); the DB-backed inputs are mirrored here from the rig
// fixtures in scripts/wr_freeze_seams/sitecustomize.py — the rows the
// oracle's SQL gathered for those keys. render_fired rows are pure: the
// recorded args ARE the inputs.
import (
"encoding/json"
"math"
"os"
"testing"
"time"
)
// ── fixture mirrors (scripts/wr_freeze_seams/sitecustomize.py) ──
// useHistoryRows — the use_history rows per entry id, used_at DESC
// (the oracle's ORDER BY; the LIMIT 100 cap never binds on 3 rows —
// entry 10's 105-row case is mirrored by useHistoryRowsFor).
var useHistoryRows = map[int][]string{
1: {"2026-10-14T23:00:00+00:00", "2026-10-14T18:00:00+00:00", "2026-10-14T13:00:00+00:00"},
2: {"2026-10-14T23:30:00+00:00"},
3: {},
8: {"1791234567"}, // non-string in SQLite: the -2.0 envelope row
}
// useHistoryRowsFor — entry 10's gather: 105 rows 1h apart from
// 2026-10-14T23:00, the 100 NEWEST (used_at DESC LIMIT 100).
func useHistoryRowsFor(id int) []string {
if id != 10 {
return useHistoryRows[id]
}
rows := make([]string, 0, 100)
h, _ := time.Parse("2006-01-02T15:04:05+00:00", "2026-10-14T23:00:00+00:00")
for k := 0; k < 100; k++ {
rows = append(rows, h.Add(-time.Duration(k)*time.Hour).Format("2006-01-02T15:04:05+00:00"))
}
return rows
}
// primedFixture — session s1's primed slugs and the links its SQL
// gathered (kind='neuron' + status='active' filter, strength DESC; the
// document-kind plain-doc row is filtered GATHERER-side and absent).
var primedFixture = struct {
slugs []string
links []PrimedLink
}{
slugs: []string{"alpha-core"},
links: []PrimedLink{
{"alpha-shadow", 0.9}, {"beta-lens", 0.4},
{"gamma-dated", 0.35}, {"hollow-body", 0.33},
},
}
// assocLinks — the links the oracle's SQL gathered for fired alpha-core
// (status-only filter: plain-doc survives; strength DESC LIMIT 6; the
// sub-0.3 link is absent). Field order: slug, summary, text, strength.
var assocLinks = []NeuronLink{
{"alpha-shadow", "shadow lens notes", "", 0.9},
{"plain-doc", "", "A plain document text that is fairly long for budget math", 0.7},
{"beta-lens", "", "beta lens body", 0.4},
{"gamma-dated", "", "gamma dated body", 0.35},
{"hollow-body", "", "", 0.33},
}
// graphPayloadAlice — the graph_memory query payload for Alice (dict
// shape: found entity). The BFS facts come first, then the incoming-edge
// facts (the collaborates_with row appears TWICE — the oracle appends
// the incoming edge without dedupe; the default limit=4 masks the fifth).
// The extra oracle keys (confidence, from, ...) pin that Go ignores them.
const graphPayloadAlice = `{"entity": "Alice", "type": "person", "facts": [
{"subject": "Alice", "predicate": "manages", "object": "Rune", "confidence": 0.9, "from": "", "until": "", "status": "active", "source": ""},
{"subject": "Alice", "predicate": "knows", "object": "Bob", "confidence": 0.8, "from": "", "until": "", "status": "active", "source": ""},
{"subject": "Rune", "predicate": "uses", "object": "Rust", "confidence": 0.7, "from": "", "until": "", "status": "active", "source": ""},
{"subject": "Bob", "predicate": "collaborates_with", "object": "Alice", "confidence": 0.6, "from": "", "until": "", "status": "active", "source": ""},
{"subject": "Bob", "predicate": "collaborates_with", "object": "Alice", "confidence": 0.6, "from": "", "until": "", "status": "active", "source": ""}
]}`
const graphPayloadRune = `{"entity": "Rune", "type": "project", "facts": [
{"subject": "Rune", "predicate": "uses", "object": "Rust"},
{"subject": "Alice", "predicate": "manages", "object": "Rune"}
]}`
func TestGapTruthReplay(t *testing.T) {
b, err := os.ReadFile("truth_gap.json")
if err != nil {
t.Fatalf("truth_gap.json missing: %v", err)
}
var rows []struct {
Fn string `json:"fn"`
Args json.RawMessage `json:"args"`
Kwargs map[string]interface{} `json:"kwargs"`
Expected json.RawMessage `json:"expected"`
}
if err := json.Unmarshal(b, &rows); err != nil {
t.Fatalf("unparseable: %v", err)
}
if len(rows) != 34 {
t.Fatalf("truth_gap.json: want 34 rows, got %d", len(rows))
}
okBase, okPrimed, okAssoc, okGraph, okRender := 0, 0, 0, 0, 0
for i, r := range rows {
var args []json.RawMessage
if err := json.Unmarshal(r.Args, &args); err != nil {
t.Fatalf("row %d: bad args: %v", i, err)
}
switch r.Fn {
case "base_level_activation":
var entryID float64
json.Unmarshal(args[0], &entryID)
nowISO, _ := r.Kwargs["now_iso"].(string)
rows_ := useHistoryRowsFor(int(entryID))
got := BaseLevelActivation(rows_, nowISO)
var want float64
json.Unmarshal(r.Expected, &want)
if math.Abs(got-want) > 1e-9 {
t.Errorf("row %d base_level_activation(%d): got %v want %v", i, int(entryID), got, want)
}
okBase++
case "_primed_associations":
var session string
json.Unmarshal(args[0], &session)
limit := 4
if len(args) > 1 {
var l float64
json.Unmarshal(args[1], &l)
limit = int(l)
}
var got []PrimedPair
if session == "s1" {
links := primedFixture.links
if limit < len(links) {
links = links[:limit]
}
got = PrimedAssociations(links, primedFixture.slugs)
} else {
got = PrimedAssociations(nil, nil)
}
var wantPairs [][]interface{}
json.Unmarshal(r.Expected, &wantPairs)
if len(got) != len(wantPairs) {
t.Errorf("row %d _primed_associations(%q): got %d pairs want %d", i, session, len(got), len(wantPairs))
continue
}
for j, wp := range wantPairs {
slug, _ := wp[0].(string)
w, _ := wp[1].(float64)
if got[j].Slug != slug || math.Abs(got[j].Weight-w) > 1e-12 {
t.Errorf("row %d _primed_associations(%q)[%d]: got (%s %v) want (%s %v)",
i, session, j, got[j].Slug, got[j].Weight, slug, w)
}
}
okPrimed++
case "_associated_neuron_bodies":
var fired []map[string]interface{}
json.Unmarshal(args[0], &fired)
var budgetF float64
json.Unmarshal(args[1], &budgetF)
budget := int(budgetF)
firedSlugs := make([]string, 0, len(fired))
for _, f := range fired {
s, _ := f["slug"].(string)
firedSlugs = append(firedSlugs, s)
}
var links []NeuronLink
switch {
case len(firedSlugs) == 1 && firedSlugs[0] == "beta-lens":
links = []NeuronLink{{"", "", "seven token body padding", 0.6}}
case len(firedSlugs) == 1 && firedSlugs[0] == "alpha-shadow":
links = []NeuronLink{{"alpha-core", "alpha summary", "", 0.5}}
case len(firedSlugs) == 1 && firedSlugs[0] == "gamma-dated":
links = []NeuronLink{{"unicode-body", "çafe — naïve ✓✓ padding", "", 0.5}}
case len(firedSlugs) == 2: // ids (1,2): both srcs' links, strength DESC
links = []NeuronLink{
{"alpha-shadow", "shadow lens notes", "", 0.9},
{"plain-doc", "", "A plain document text that is fairly long for budget math", 0.7},
{"", "", "seven token body padding", 0.6},
{"beta-lens", "", "beta lens body", 0.4},
{"gamma-dated", "", "gamma dated body", 0.35},
{"hollow-body", "", "", 0.33},
}
default:
links = assocLinks
}
got := AssociatedNeuronBodies(links, firedSlugs, budget)
var want []map[string]interface{}
json.Unmarshal(r.Expected, &want)
if len(got) != len(want) {
t.Errorf("row %d _associated_neuron_bodies(%v %d): got %d want %d", i, firedSlugs, budget, len(got), len(want))
continue
}
for j, w := range want {
wslug, _ := w["slug"].(string)
wbody, _ := w["body"].(string)
wscore, _ := w["score"].(float64)
wtokens, _ := w["tokens"].(float64)
if got[j].Slug != wslug || got[j].Body != wbody ||
math.Abs(got[j].Score-wscore) > 1e-12 || got[j].Tokens != int(wtokens) {
t.Errorf("row %d _associated_neuron_bodies[%d]: got (%s %q %v %d) want (%s %q %v %d)",
i, j, got[j].Slug, got[j].Body, got[j].Score, got[j].Tokens,
wslug, wbody, wscore, int(wtokens))
}
}
okAssoc++
case "graph_context":
var term string
json.Unmarshal(args[0], &term)
limit := 4
if len(args) > 2 {
var l float64
json.Unmarshal(args[2], &l)
limit = int(l)
}
payload := "[]"
if term == "Alice" || term == "Al" {
payload = graphPayloadAlice
} else if term == "Rune" {
payload = graphPayloadRune
}
got := GraphContext([]byte(payload), term, limit)
var want string
json.Unmarshal(r.Expected, &want)
if got != want {
t.Errorf("row %d graph_context(%q %d):\n got %q\nwant %q", i, term, limit, got, want)
}
okGraph++
case "render_fired":
var fired []FiredRender
json.Unmarshal(args[0], &fired)
got := RenderFired(fired)
var want string
json.Unmarshal(r.Expected, &want)
if got != want {
t.Errorf("row %d render_fired:\n got %q\nwant %q", i, got, want)
}
okRender++
default:
t.Fatalf("row %d: unknown fn %q", i, r.Fn)
}
}
if okBase != 6 || okPrimed != 5 || okAssoc != 7 || okGraph != 9 || okRender != 7 {
t.Errorf("row counts: base=%d primed=%d assoc=%d graph=%d render=%d", okBase, okPrimed, okAssoc, okGraph, okRender)
}
}
+1 -1
View File
@@ -968,7 +968,7 @@ def _primed_associations(session_id, limit=4):
f"WHERE a.src_id IN ({iph}) AND a.strength >= 0.3 "
"AND e.kind='neuron' AND e.status='active' "
"ORDER BY a.strength DESC LIMIT ?",
(limit,),
(*ids, limit),
).fetchall()
return [(r[0], float(r[1]) * ASSOC_PRIME_WEIGHT) for r in links if r[0] not in slugs]
finally:
+52
View File
@@ -0,0 +1,52 @@
# warm_router routing-family gap-close (dichotomy wave, builder factory-heavy-wr-route)
Module: src/rune/warm_router.py (1518L, 33 fns). Family: 16 routing/
activation/scoring fns. Before: 11/16 (missing base_level_activation,
_primed_associations, _associated_neuron_bodies, graph_context,
render_fired). After: **16/16**.
## Port (src/go/warm-router/gaps_routing.go, new; + gap-cli dispatch in main.go)
Pure decision ports, I/O-as-args per the module's established split:
- BaseLevelActivation — no rows -> -2.0; else baseLevelFromUses.
- PrimedAssociations — neighbour slugs x AssocPrimeWeight, primed excluded.
- AssociatedNeuronBodies — seen-set skip (empty bodies burn slugs),
summary-or-text, tokens=max(1, RUNES/4), BREAK on budget overflow,
score=round-half-even(strength,2), empty slug -> "assoc".
- GraphContext — parsed-or-raw payload (dict/list crash-parity), facts
[:limit] with Python negative-slice semantics; bare header on
limit=0-with-facts (oracle's empty check tests the full list).
- RenderFired — injection block; via_association outranks compressed.
- main.go: RFC3339+T15:04:05 now-parse (was literal-Z-only -> wall
clock for +00:00 stamps — the base-level battery caught it).
## Oracle bug fixed (fix-first, src/rune/warm_router.py)
_primed_associations passed `(limit,)` for a statement with
len(ids)+1 placeholders -> sqlite3.ProgrammingError on EVERY call ->
[] forever (the active-priming association walk was dead code in
production). Now passes (*ids, limit). Proof: frozen rows s1/s1-limit2
freeze real pairs; parity s2 exercises the live path.
## Verification (evidence: verification/wr-family-*.{log,exit})
- freeze_truth --verify: 34/34 byte-identical (exit 0).
- family battery (truth_gap_test.go, 34-row replay): ok.
- live parity (check_warm_router_gap_parity.py, hermetic rig +
deterministic fixture extension): 60/60.
- go build / vet / gofmt: clean (exits 0/0/0).
- Python tests/test_warm_router_correctness.py: auto 5/5; python-pin
3/5 (2 failures PRE-EXIST on the stashed tree — the retired Python
fallback recurses and degrades to -2.0; my lane touches Go only).
- adjacent suites (graph_health, ffi_query_memory_smoke): 4 passed,
1 skipped.
## Divergences (documented, not bugs)
- graph_context returns the bare "### Graph memory ..." header when
limit=0 truncates a non-empty list (oracle checks the full list).
- incoming graph edges append without dedupe (collaborates_with x2 in
the Alice payload) — reproduced verbatim in the battery mirror.
- primitive budgets: budget=0 yields [] (the oracle's first body always
fires budget-free only in route()'s own loop, not in this fn).
+1
View File
@@ -0,0 +1 @@
0
View File
Whitespace-only changes.
+1
View File
@@ -0,0 +1 @@
0
View File
Whitespace-only changes.
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
OK: 34 cases byte-identical against live oracle rune.warm_router
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
ok rune/warm-router (cached)
+1
View File
@@ -0,0 +1 @@
0
+2
View File
@@ -0,0 +1,2 @@
parity: 60/60 — all green
+1
View File
@@ -0,0 +1 @@
0
+2
View File
@@ -0,0 +1,2 @@
..... [100%]
5 passed in 0.24s
+1
View File
@@ -0,0 +1 @@
1
+49
View File
@@ -0,0 +1,49 @@
.F.F. [100%]
=================================== FAILURES ===================================
__________ TestEntryIdActivation.test_fired_entry_scores_above_floor ___________
self = <tests.test_warm_router_correctness.TestEntryIdActivation object at 0x7fbe296de850>
tmp_path = PosixPath('/tmp/pytest-of-nick/pytest-744/test_fired_entry_scores_above_0')
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fbe29348c30>
def test_fired_entry_scores_above_floor(self, tmp_path, monkeypatch):
db_path = str(tmp_path / "h2.db")
db = sqlite3.connect(db_path)
db.execute("CREATE TABLE use_history (entry_id INTEGER, used_at TEXT, "
"session_id TEXT, outcome TEXT)")
db.executemany(
"INSERT INTO use_history VALUES (?,?,?,?)",
[(7, "2026-10-07T12:00:00+00:00", "s", "helpful"),
(7, "2026-10-07T18:00:00+00:00", "s", "helpful"),
(7, "2026-10-07T23:00:00+00:00", "s", "helpful")])
db.commit()
monkeypatch.setattr(wr, "STORE_DB", db_path)
score = wr.base_level_activation(7, now_iso="2026-10-08T00:00:00+00:00")
> assert score > -2.0 # three recent firings lift above the floor
^^^^^^^^^^^^^^^^^^^
E assert -2.0 > -2.0
tests/test_warm_router_correctness.py:59: AssertionError
__________ TestWashChangesRetrieval.test_use_history_changes_ranking ___________
self = <tests.test_warm_router_correctness.TestWashChangesRetrieval object at 0x7fbe296de710>
tmp_path = PosixPath('/tmp/pytest-of-nick/pytest-744/test_use_history_changes_ranki0')
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fbe29517350>
def test_use_history_changes_ranking(self, tmp_path, monkeypatch):
"""A controlled ranking demonstrably changes when use-history is
applied (#27 acceptance: reproduced, deterministic)."""
base = wr.base_level_from_uses(
["2026-10-07T23:00:00+00:00"], "2026-10-08T00:00:00+00:00")
boosted = wr.base_level_from_uses(
["2026-10-07T12:00:00+00:00", "2026-10-07T18:00:00+00:00",
"2026-10-07T23:00:00+00:00"], "2026-10-08T00:00:00+00:00")
> assert boosted > base # more history = higher activation
^^^^^^^^^^^^^^^^^^^^^
E assert -2.0 > -2.0
tests/test_warm_router_correctness.py:96: AssertionError
=========================== short test summary info ============================
FAILED tests/test_warm_router_correctness.py::TestEntryIdActivation::test_fired_entry_scores_above_floor
FAILED tests/test_warm_router_correctness.py::TestWashChangesRetrieval::test_use_history_changes_ranking
2 failed, 3 passed in 0.28s
@@ -0,0 +1 @@
0
@@ -0,0 +1,2 @@
....s [100%]
4 passed, 1 skipped in 0.41s
+1
View File
@@ -0,0 +1 @@
0
View File
Whitespace-only changes.