Files
rune/scripts/check_tool_executor_fsops_parity.py
T
Nick df088fbe30 feat: THE CONVERGENCE LANDING — six waves, one tree
- GO CORE TURN ENGINE (src/go/rune-core): per-channel single-flight,
  channel-keyed context, K25 tail+snapshot store (D40 seam), live
  Ollama with the thinking split, PTY parity proven with Python
  stopped + the owner's 27B live with thinking surfaced
- FULL-WIDTH SHARED BOX (D36): spans both panes, focus-signage
  placeholder, drafts survive focus round-trips, PTY-proven 110+140
- MODEL SPLIT (D37): pane-aware /model, per-pane record fields,
  status line; letter-stealing round 2 fixed (j/k type)
- APPROVAL CARD (T5): gold y/n through /v1/approvals/resolve, stale
  revalidation, chained asks, PTY-proven both legs
- PROVIDERS P1: 18 providers both languages, three-artifact drift
  gate, provider step in first-run (real names, no 'local' hardcode)
- SCROLLBACK: /history depth persisted, ctrl+up/down + pgup/pgdn,
  dim ↑N indicator, deeper-page fetch, PTY-proven on real history
- RETIREMENT rows 4+10 advanced: tool-executor dispatch wired
  (49/49+48/48), Go mode-gate door built, work-manager CLI parity
2026-10-19 00:02:18 +01:00

129 lines
4.9 KiB
Python

#!/usr/bin/env python3
"""check_tool_executor_fsops_parity.py — LIVE parity for the fsops family
(tool-executor Go port, dichotomy wave #2479, contract factory-heavy-te-fs).
Runs the live Python oracle AND the Go port against the SAME
scripts/tefs_freeze_seams rig tree (fixed /tmp/tefs-freeze-rig): every
generator case is executed by rune.tool_executor directly, then replayed
by `go test -run TestFsopsParityLive` (FSOPS_PARITY_LIVE=1) with the
rig-mirroring seams pinned, and the envelopes are byte-compared.
Comparison discipline:
* full-envelope exact for every fn;
* _edit_file success rows: the diff field is compared by MARKERS
(-search/+replace present) — difflib and the native unified diff
render hunk headers differently (established truth_fileops law);
* _resolve_execution_cwd: (cwd, source) tuple compared, refusal "".
Run from the repo root (the rig is rebuilt by sitecustomize):
PYTHONPATH=scripts/tefs_freeze_seams python3 \\
scripts/check_tool_executor_fsops_parity.py
"""
from __future__ import annotations
import copy
import importlib
import json
import os
import subprocess
import sys
import tempfile
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "scripts"))
from gen_tool_executor_fsops_truth import cases # noqa: E402
RIG = "/tmp/tefs-freeze-rig"
def oracle_call(fn_name: str, args: dict):
te = importlib.import_module("rune.tool_executor")
fn = getattr(te, fn_name)
return fn(copy.deepcopy(args))
def main() -> int:
os.environ.setdefault("RUNE_TOOL_EXECUTOR_CORE", "python")
te = importlib.import_module("rune.tool_executor")
oracle_rows = []
case_rows = []
for fn_name, argtuple, _kwargs in cases:
args = argtuple[0]
expected = oracle_call(fn_name, args)
oracle_rows.append({"fn": fn_name, "expected": expected})
case_rows.append({"fn": fn_name, "args": args})
with tempfile.TemporaryDirectory(prefix="tefs-parity-") as td:
case_path = str(Path(td) / "cases.json")
out_path = str(Path(td) / "outcomes.json")
Path(case_path).write_text(json.dumps(case_rows), encoding="utf-8")
env = dict(os.environ)
env.update({
"FSOPS_PARITY_LIVE": "1",
"FSOPS_PARITY_CASES": case_path,
"FSOPS_PARITY_OUT": out_path,
"FSOPS_PARITY_ROOT": RIG,
})
proc = subprocess.run(
["go", "test", "-run", "TestFsopsParityLive", "-count=1", "./internal/toolexec"],
cwd=str(REPO / "src" / "go" / "tool-executor"),
env=env, capture_output=True, text=True, timeout=600,
)
if proc.returncode != 0:
print("go test failed:\n", proc.stdout, proc.stderr)
return 1
outcomes = json.loads(Path(out_path).read_text(encoding="utf-8"))
passed = 0
fails = []
for oracle_row, outcome in zip(oracle_rows, outcomes):
name = oracle_row["fn"]
got = outcome["got"]
want = oracle_row["expected"]
if name == "_resolve_execution_cwd":
ok = (got.get("cwd"), got.get("source")) == (want[0], want[1]) and got.get("refusal") == ""
elif name == "_edit_file" and want.get("needs_confirm"):
diff = want.get("diff", "")
ok = (
got.get("success") == want.get("success")
and got.get("needs_confirm") == want.get("needs_confirm")
and got.get("result") == want.get("result")
and got.get("path") == want.get("path")
and got.get("content") == want.get("content")
and got.get("has_diff") is True
and "-line 2" in diff
and "+CHANGED" in diff
)
elif name == "_glob_files":
channel = "result" if want.get("success") else "error"
ok = got.get("success") == want.get("success") and got.get(channel) == want.get(channel)
else:
if got.get("success") is True and want.get("success") is True:
ok = got.get("result") == want.get("result")
else:
ok = got.get("success") == want.get("success") and got.get("error") == want.get("error")
for extra in ("cwd_source", "needs_confirm", "path", "content"):
if extra in want or extra in got:
ok = ok and got.get(extra) == want.get(extra)
if ok:
passed += 1
else:
fails.append((name, want, got))
total = len(oracle_rows)
print(f"live parity: {passed}/{total}")
for name, want, got in fails:
print(f"FAIL {name}:\n oracle: {json.dumps(want, ensure_ascii=False)[:300]}\n go: {json.dumps(got, ensure_ascii=False)[:300]}")
if fails:
return 1
# silence unused-import lint (te pinned the oracle import for clarity)
assert te is not None
return 0
if __name__ == "__main__":
raise SystemExit(main())