CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 8s
CI Pipeline / rust-surface (push) Failing after 13s
CI Pipeline / go-surface (push) Failing after 18s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / type-check (push) Failing after 43s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
Auto-version and Release / release (push) Canceled after 56s
CI Pipeline / lint (push) Canceled after 56s
CI Pipeline / unit-tests (push) Canceled after 56s
CI Pipeline / canary (push) Canceled after 55s
deploy / deploy (push) Canceled after 46s
parity: every growth_delta kernel ported name-preserving into the cognition_core broker — _parse_json (fence strip, brace extraction, the _parse_error degrade), _load_deltas/_save_deltas (parse-or-default, the exact json.dump indent=2 bytes), _apply_profile (first-near-dup replace, distinct append), _apply_one (200-char evidence, now-as-argument), reflect's gate pipeline ([:3] slice, 12-char floor, behavioural-only, 0.6 gate), apply's validation (invalid-json/short/wrong-target/low-conf branches), handle_hook passthrough, _llm's exact Ollama payload, _write_store's memory_store argv, _ctx_budget's #28 arithmetic, and the dict-aware py_near_dup. fix-first: the facade's _near_dup fed DICTS into the string-only growth_near_dup kernel, which answered False for every dict pair — live core and pinned fallback DISAGREED (test_growth_delta_error_paths only ran pinned, masking it). The new cc_py_near_dup kernel takes dicts-or- strings; both pins now agree and the previously-masked assertion holds live. doc-envelope FFI via cc_free_string (never re-exported); cc_loader pins argtypes+restype for all 12 new symbols; facade delegation with the RUNE_COGNITION_CORE=python pin. Battery: 9 tests replay 24 pure + 22 state frozen-oracle cases VERBATIM (include_str!). Live parity 86/86 facade checks both pins; freeze_truth --verify byte-identical both pins. clippy --all-targets -D warnings 0 (incl. two pre-existing lints the new toolchain gates: branch_battery module inception, parse_probe format!). Audit: growth_delta 5/20 → 17/20; the 3 remaining (_store_db env-path, _cc_core loader probe, _py_growth_profile fallback oracle) stay Python by law, same calibration as drift_cache.
235 lines
8.8 KiB
Python
235 lines
8.8 KiB
Python
#!/usr/bin/env python3
|
|
"""check_growth_delta_parity.py — live parity: growth_delta facade under
|
|
BOTH core pins vs the frozen oracle truth (dichotomy wave).
|
|
|
|
Per pin (RUNE_COGNITION_CORE=python and unset → Rust via cc_loader) it
|
|
replays every frozen case through the LIVE facade. File seams are tmp
|
|
DELTAS_FILE dirs; subprocess/urlopen are stubbed at parity time (nothing
|
|
touches the machine store); the clock is frozen.
|
|
|
|
Usage: python3 scripts/check_growth_delta_parity.py
|
|
Exit 0 iff every case matches its frozen expected in BOTH pins.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import urllib.request
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
|
|
|
|
import rune.growth_delta as gd # noqa: E402
|
|
|
|
CRATE = Path(__file__).resolve().parents[1] / "src" / "rust" / "cognition_core" / "src"
|
|
EMPTY = {"applied": [], "pending": [], "last_read_back": None}
|
|
|
|
|
|
# NOTE (no-clock law): the facade's wall-clock `applied_at` is NOT logic —
|
|
# the apply_one case is normalized to the frozen `now` before comparing;
|
|
# apply_ok compares only clock-free fields. The kernel takes `now` as an
|
|
# argument, so the Rust battery is exact with zero masking.
|
|
|
|
FAILS = []
|
|
CHECKS = [0]
|
|
|
|
|
|
def call_core(core, fn, *args, **kwargs):
|
|
old = os.environ.get("RUNE_COGNITION_CORE")
|
|
os.environ["RUNE_COGNITION_CORE"] = core
|
|
try:
|
|
return getattr(gd, fn)(*args, **kwargs)
|
|
finally:
|
|
if old is None:
|
|
os.environ.pop("RUNE_COGNITION_CORE", None)
|
|
else:
|
|
os.environ["RUNE_COGNITION_CORE"] = old
|
|
|
|
|
|
def with_file(state, core, fn, *args):
|
|
with tempfile.TemporaryDirectory() as td:
|
|
path = os.path.join(td, "deltas.json")
|
|
if state is not None:
|
|
with open(path, "w") as f:
|
|
if isinstance(state, dict) and "__raw__" in state:
|
|
f.write(state["__raw__"])
|
|
else:
|
|
json.dump(state, f)
|
|
orig = gd.DELTAS_FILE
|
|
gd.DELTAS_FILE = path
|
|
try:
|
|
result = call_core(core, fn, *args)
|
|
try:
|
|
with open(path) as f:
|
|
after = f.read()
|
|
except OSError:
|
|
after = None
|
|
finally:
|
|
gd.DELTAS_FILE = orig
|
|
return result, after
|
|
|
|
|
|
def check(name, got, want):
|
|
CHECKS[0] += 1
|
|
g, w = json.dumps(got, sort_keys=True), json.dumps(want, sort_keys=True)
|
|
if g == w:
|
|
return
|
|
FAILS.append(name)
|
|
print(f"MISMATCH [{name}]\n got: {g[:240]}\n want: {w[:240]}")
|
|
|
|
|
|
def main() -> int:
|
|
for core in ("python", "auto"):
|
|
live = call_core(core, "_cc_core") is not None
|
|
tag = f"{core}:{'rust' if live else 'py'}"
|
|
print(f"== {tag} ==")
|
|
|
|
truth = json.loads((CRATE / "frozen_growth_delta_truth.json").read_text())
|
|
for c in truth:
|
|
got = call_core(core, c["fn"], *c["args"], **c["kwargs"])
|
|
check(f"{tag}:{c['fn']}", got, c["expected"])
|
|
|
|
state = json.loads((CRATE / "frozen_growth_delta_state.json").read_text())["cases"]
|
|
|
|
for c in state["load_deltas"]:
|
|
raw = c["input"]["raw"]
|
|
seed = None if raw is None else {"__raw__": raw}
|
|
got, _ = with_file(seed, core, "_load_deltas")
|
|
check(f"{tag}:load:{c['name']}", got, c["expected"])
|
|
|
|
for c in state["save_deltas"]:
|
|
st = json.loads(json.dumps(c["input"]["state"]))
|
|
_, after = with_file(None, core, "_save_deltas", st)
|
|
check(f"{tag}:save:{c['name']}", after, c["expected"])
|
|
|
|
for c in state["apply_profile"]:
|
|
prof = json.loads(json.dumps(c["input"]["profile"]))
|
|
delta = json.loads(json.dumps(c["input"]["delta"]))
|
|
action, after = with_file(
|
|
{**EMPTY, "profile": prof}, core, "_apply_profile", delta)
|
|
check(f"{tag}:profile:{c['name']}",
|
|
{"profile": json.loads(after)["profile"], "action": action},
|
|
c["expected"])
|
|
|
|
for c in state["apply_one"]:
|
|
i = c["input"]
|
|
got, _ = with_file(dict(EMPTY), core, "_apply_one",
|
|
i["change"], i["evidence"], i["conf"],
|
|
i["target"])
|
|
got = {**got, "applied_at": i["now"]} # no-clock law: the
|
|
# facade's wall-clock stamp is not logic — normalize to the
|
|
# frozen `now` before comparing
|
|
check(f"{tag}:apply_one", got, c["expected"])
|
|
|
|
for c in state["reflect"]:
|
|
orig_llm = gd._llm
|
|
gd._llm = lambda m: json.dumps({"deltas": c["input"]["deltas"]})
|
|
try:
|
|
res, _ = with_file(dict(EMPTY), core, "reflect", "material", True)
|
|
finally:
|
|
gd._llm = orig_llm
|
|
check(f"{tag}:reflect:{c['name']}", res["would_apply"],
|
|
c["expected"])
|
|
|
|
c = state["llm"][0]
|
|
captured = {}
|
|
|
|
class Resp:
|
|
def read(self):
|
|
return b"{}"
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, *exc):
|
|
return False
|
|
|
|
orig_open = urllib.request.urlopen
|
|
orig_ctx = gd._ctx_budget
|
|
gd._ctx_budget = lambda mid: c["input"]["num_ctx"]
|
|
urllib.request.urlopen = lambda req, timeout=0: (
|
|
captured.update(data=req.data.decode()), Resp())[1]
|
|
try:
|
|
call_core(core, "_llm", c["input"]["prompt"])
|
|
finally:
|
|
urllib.request.urlopen = orig_open
|
|
gd._ctx_budget = orig_ctx
|
|
check(f"{tag}:llm", captured.get("data"), c["expected"])
|
|
|
|
c = state["write_store"][0]
|
|
argv_cap = {}
|
|
orig_run = subprocess.run
|
|
subprocess.run = lambda argv, **kw: (
|
|
argv_cap.update(argv=list(argv)),
|
|
SimpleNamespace(returncode=0))[1]
|
|
try:
|
|
call_core(core, "_write_store", c["input"]["text"],
|
|
c["input"]["topic"])
|
|
finally:
|
|
subprocess.run = orig_run
|
|
check(f"{tag}:store", argv_cap.get("argv", [])[2:], c["expected"][2:])
|
|
|
|
# ctx_budget through the LIVE facade: the oracle signature only
|
|
# exposes model_id (task_kind always "default" there — the
|
|
# task-kind branches are kernel-covered by the Rust battery).
|
|
# Rows: unknown model (default), cloud, local, small, zero-window.
|
|
rows = [("unknown-model", 8192, True),
|
|
("cloud-model", 32768, False),
|
|
("local-model", 32768, True),
|
|
("small-local", 2048, True),
|
|
("zero-window", 8192, True)]
|
|
for name, window, local in rows:
|
|
want = next(c_["expected"] for c_ in state["ctx_budget"]
|
|
if c_["input"]["window"] == window
|
|
and c_["input"]["local"] == local
|
|
and c_["input"]["task_kind"] == "default")
|
|
reg = SimpleNamespace()
|
|
if window == 8192 and local:
|
|
reg.profiles = {}
|
|
else:
|
|
reg.profiles = {"t": SimpleNamespace(
|
|
id=name, context_window=window, local=local)}
|
|
import rune
|
|
from rune import model_registry as mr
|
|
import types as _t
|
|
stub = _t.ModuleType("rune.model_registry")
|
|
stub.ModelRegistry = lambda: reg
|
|
# the real resolve defaults registry=None → its OWN module's
|
|
# ModelRegistry; force the stub row explicitly
|
|
stub.resolve_context_budget = (
|
|
lambda mid, tk="default", registry=None, _r=reg:
|
|
mr.resolve_context_budget(mid, tk, registry=_r))
|
|
saved = sys.modules.get("rune.model_registry")
|
|
rune.model_registry = stub
|
|
sys.modules["rune.model_registry"] = stub
|
|
try:
|
|
got = call_core(core, "_ctx_budget", name)
|
|
finally:
|
|
if saved is not None:
|
|
rune.model_registry = saved
|
|
sys.modules["rune.model_registry"] = saved
|
|
check(f"{tag}:ctx:{name}", got, want)
|
|
|
|
res, _ = with_file(dict(EMPTY), core, "apply", json.dumps({
|
|
"change": "a valid longer change here", "confidence": 0.9,
|
|
"target": "delivery", "evidence": "ev"}))
|
|
check(f"{tag}:apply_ok",
|
|
[{"change": r["change"], "target": r["target"],
|
|
"confidence": r["confidence"]} for r in res.get("applied", [])],
|
|
[{"change": "a valid longer change here", "target": "delivery",
|
|
"confidence": 0.9}])
|
|
|
|
bad = len(FAILS)
|
|
print(f"{'PASS' if bad == 0 else 'FAIL'}: {CHECKS[0] - bad}/{CHECKS[0]}")
|
|
return 1 if bad else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|