Files
rune/scripts/gen_tool_executor_fsops_truth.py
T
Nick af6c56c003 feat(rebase): J1 complete — five conversational subsystems as libraries behind thin shells
event-bus, model-routing, tool-executor, work-manager, rune-entry: core
code in internal/*, 15-26 line main.go shells preserving exact CLI
behavior. Batteries green through the shells; byte-identical CLI
matrices pre/post (24-case event-bus, 16-case tool-executor, 6-case
work-manager replay, 7-case routing parity, 8-case entry).

Fixes riding the wave: tool-executor duplicate pyListRepr symbol (broken
on HEAD since 07c08c34), work-manager repoRoot depth, CI run-pattern +
fuzz + generator path repointing.

Main-session verification: all five build + test green by own run;
-race clean on event-bus. model-routing has no Go test files — its
battery IS the binary's replay mode, verified through the shell.
2026-10-16 20:03:22 +01:00

147 lines
7.9 KiB
Python

#!/usr/bin/env python3
"""gen_tool_executor_fsops_truth.py — freeze the FILESYSTEM/REPO/MEMORY
family truth for the tool-executor Go port (dichotomy wave #2479, shared
harness scripts/freeze_truth.py, contract factory-heavy-te-fs).
Exercises the 10 family fns of src/rune/tool_executor.py under the
scripts/tefs_freeze_seams rig (fixed /tmp/tefs-freeze-rig root, pinned
HOME, rigged tree-sitter, real echo/sh/grep subprocesses):
_resolve_execution_cwd explicit / precedence over project / process
cwd / registry-resolved project
_run_command echo + shlex quote split / argv stderr merge /
exit-code suffix / pipe refusal / shell mode /
empty + bad argv / 10000-CHAR truncation /
workdir explicit / project refusal (caught) /
no-output / timeout branch (battery-only: 30s
wall cost)
_edit_file exactly-once preview / not-found / multi-match /
identical / empty search / outside-write-dirs
_glob_files pathlib glob semantics (hidden files matched,
** crosses hidden dirs, a/** zero-dir) with
FIXED mtimes / no-match / empty pattern / dir
suffix
_repo_map tree-sitter rc-0 (rigged payload → 5000-CHAR
cap) / fallback via real grep / no symbols /
denied path
_read_persona full block (5100-char persona → 5000-CHAR cap)
_query_memory .2f scores + 200-CHAR text cap / limit 2 / 0 /
single / miss / empty query
_check_growth last-10 default / last-3 / limit-0 ALL (quirk
pin) / negative limit / 100-CHAR detail cap
_diagnose_behavior issue order / clean text / empty text / unicode
char length
Missing-file / malformed-JSON / unterminated-shlex branches cannot ride
freeze truth (fixture-swap or raise-at-freeze hazards; messages are
interpreter-shaped) — the Go battery covers them hermetically.
Run from the repo root:
PYTHONPATH=scripts/tefs_freeze_seams python3 scripts/gen_tool_executor_fsops_truth.py
Verify (byte-identical law):
PYTHONPATH=src:scripts/tefs_freeze_seams python3 scripts/freeze_truth.py \
--verify src/go/tool-executor/internal/toolexec/truth_fsops.json \
--module rune.tool_executor
Output: src/go/tool-executor/internal/toolexec/truth_fsops.json
(harness list schema: [{fn, args, kwargs, expected}] — replayed VERBATIM
by src/go/tool-executor/internal/toolexec/truth_fsops_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" / "tool-executor" / "internal" / "toolexec" / "truth_fsops.json"
RIG = "/tmp/tefs-freeze-rig"
cases = [
# ── _resolve_execution_cwd ──────────────────────────────────────────
("_resolve_execution_cwd", ({"workdir": f"{RIG}/work/proj"},), {}),
("_resolve_execution_cwd",
({"workdir": f"{RIG}/work/proj", "project": "proj-alpha"},), {}),
("_resolve_execution_cwd", ({},), {}),
("_resolve_execution_cwd", ({"project": "proj-alpha"},), {}),
# ── _run_command ────────────────────────────────────────────────────
("_run_command", ({"command": "echo hello"},), {}),
("_run_command", ({"command": "echo 'a b'"},), {}),
("_run_command", ({"argv": ["sh", "-c", "echo out; echo err 1>&2"]},), {}),
("_run_command", ({"argv": ["sh", "-c", "exit 3"]},), {}),
("_run_command", ({"command": "ls -la | head"},), {}),
("_run_command", ({"command": "echo shell-ok", "shell": True},), {}),
("_run_command", ({"shell": True},), {}),
("_run_command", ({},), {}),
("_run_command", ({"argv": ["ok", ""]},), {}),
("_run_command",
({"argv": ["sh", "-c", "printf 'x%.0s' $(seq 1 12000)"]},), {}),
("_run_command", ({"command": "pwd", "workdir": f"{RIG}/work/proj"},), {}),
("_run_command", ({"command": "echo x", "project": "ghost"},), {}),
("_run_command", ({"argv": ["true"]},), {}),
# ── _edit_file (targets under the rig HOME — write-allowed) ────────
("_edit_file",
({"path": f"{RIG}/home/fix/edit.txt", "search": "line 2",
"replace": "CHANGED"},), {}),
("_edit_file",
({"path": f"{RIG}/home/fix/edit.txt", "search": "absent-token",
"replace": "x"},), {}),
("_edit_file",
({"path": f"{RIG}/home/fix/edit.txt", "search": "line",
"replace": "x"},), {}),
("_edit_file",
({"path": f"{RIG}/home/fix/edit.txt", "search": "line 2",
"replace": "line 2"},), {}),
("_edit_file", ({"path": f"{RIG}/home/fix/edit.txt"},), {}),
("_edit_file",
({"path": "/usr/share/x.txt", "search": "a", "replace": "b"},), {}),
# ── _glob_files ─────────────────────────────────────────────────────
("_glob_files", ({"pattern": "**/*.py", "path": f"{RIG}/work/globtree"},), {}),
("_glob_files", ({"pattern": "*.py", "path": f"{RIG}/work/globtree"},), {}),
("_glob_files", ({"pattern": "*.zzz", "path": f"{RIG}/work/globtree"},), {}),
("_glob_files", ({"pattern": "", "path": f"{RIG}/work/globtree"},), {}),
("_glob_files", ({"pattern": "a/**/*.py", "path": f"{RIG}/work/globtree"},), {}),
("_glob_files", ({"pattern": "a*", "path": f"{RIG}/work/globtree"},), {}),
# ── _repo_map ───────────────────────────────────────────────────────
("_repo_map", ({"path": f"{RIG}/work/code"},), {}),
("_repo_map", ({"path": f"{RIG}/work/code2"},), {}),
("_repo_map", ({"path": f"{RIG}/work/empty"},), {}),
("_repo_map", ({"path": "/etc"},), {}),
# ── _read_persona ───────────────────────────────────────────────────
("_read_persona", ({},), {}),
# ── _query_memory ───────────────────────────────────────────────────
("_query_memory", ({"query": "alpha"},), {}),
("_query_memory", ({"query": "alpha", "limit": 2},), {}),
("_query_memory", ({"query": "alpha", "limit": 0},), {}),
("_query_memory", ({"query": "single"},), {}),
("_query_memory", ({"query": "nope"},), {}),
("_query_memory", ({},), {}),
# ── _check_growth ───────────────────────────────────────────────────
("_check_growth", ({},), {}),
("_check_growth", ({"limit": 3},), {}),
("_check_growth", ({"limit": 0},), {}),
("_check_growth", ({"limit": -2},), {}),
# ── _diagnose_behavior ──────────────────────────────────────────────
("_diagnose_behavior",
({"text": "Great question! I think Rune would maybe agree."},), {}),
("_diagnose_behavior",
({"text": "I am direct and honest; evidence filed. Nick asked, warm reply."},), {}),
("_diagnose_behavior", ({},), {}),
("_diagnose_behavior", ({"text": "héllo wörld"},), {}),
]
def main() -> int:
truth = freeze("tool_executor", cases, oracle_module="rune.tool_executor")
write(truth, OUT)
print(f"wrote {OUT} ({len(truth)} cases)")
return 0
if __name__ == "__main__":
raise SystemExit(main())