audit 4/6 PARTIAL -> 8/8 FULL (RUST). The landed FULL port (b5228ace+e41562aa) left record_trace/read_traces as facade-side IO by its strangler verdict; this close ports them name-preserving with the file IO itself in the kernel (mkdir, I1 source-guard rotation replace chain, O_APPEND write, file reads; path RESOLUTION stays the _trace_path seam the tests pin, and the facade passes module rotation knobs read at call time so the TRACE_ROTATE_BYTES monkeypatch contract survives). FFI it_record_trace / it_read_traces + it_loader wrappers + byte-identical _py_record_trace / _py_read_traces fallbacks (RUNE_IT_CORE=python pin). Fix-first (proved by frozen truth): (1) serialize/format_record ensure_ascii divergence — json.dumps escapes non-ASCII as \uXXXX (astral = surrogate pairs), serde emitted raw UTF-8; py_escape emitter added for both shapes (quirk #24, extends the context_broker pyDumpsSorted law). (2) limit=0 — Python lines[-0:] keeps ALL lines, rev().take(0) returned none; read_select + cli_tail fixed (quirk #25). (3) malformed JSONL line silently skipped by read_select where the oracle raises ValueError — now an Err through the FFI envelope so the facade fallback re-raises the AUTHENTIC exception (quirk #26; crash class pinned in truth). Frozen truth: 17-case gap corpus via the shared freeze_truth.py harness + scripts/it_freeze_seams rig (RUNE_IT_CORE=python, relative RUNE_HOME, cwd-is-the-rig, row-private it_t stores; record/read branches incl. rotation matrix + unicode line law + limit 0/2/99 + missing stores + ValueError class + round-trip). gen x2 + --verify x2 byte-identical. Battery: gap_battery.rs replays rows VERBATIM in a throwaway cwd (cargo test 9/9: old 6 + new 3). Live parity scripts/check_inference_trace_parity .py: seam 17/17 + FFI composites 17/17. Landed PARITY=1 flow preserved (byte-identical modulo the original freeze's baked worktree root). cargo build/clippy -D warnings/fmt clean. Python suite both pins 108/108 live + 108/108 RUNE_IT_CORE=python (p1_03 memory_selection failures pre-exist at pristine HEAD, outside this port's cone). Audit: FULL 65% (125/192). Evidence: verification/it-*.exit + summary-inference_trace.md (logs local, *.log gitignored).
159 lines
7.2 KiB
Python
159 lines
7.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Freeze inference_trace GAP truth (dichotomy wave #2479 gap-close,
|
|
worktree rune-wave-dk; shared harness scripts/freeze_truth.py + rig
|
|
scripts/it_freeze_seams).
|
|
|
|
The landed port (b5228ace + e41562aa) froze the kernel-shaped surface
|
|
(price_for, path resolution, serialization, rotation verdicts, read
|
|
selection counts, CLI tail) in frozen_it_truth.json. This gap truth
|
|
covers the two audit-missing IO functions — record_trace and read_traces
|
|
— through the module's JSON row runners (record_trace_json /
|
|
read_traces_json), with REAL file IO in cwd-relative row-private stores:
|
|
|
|
record_trace_json rows
|
|
fresh explicit dir (auto-created), append onto an existing store,
|
|
default <rune_home>/state resolution, rotation at row-pinned
|
|
rotate_bytes (basic shift, full chain, exact-boundary no-rotate,
|
|
under-boundary no-rotate, source-guard when a middle slot is
|
|
missing), and the v5-full record with UNICODE field values (the
|
|
json.dumps ensure_ascii line-bytes law).
|
|
read_traces_json rows
|
|
all-lines selection across blank lines, limit trims (2, 0 — the
|
|
lines[-0:] == all-lines quirk, 99), missing explicit store, missing
|
|
default-dir store, the malformed-line ValueError crash class, and a
|
|
record→read round-trip.
|
|
|
|
Layout law: every row family gets its own it_t/<name> store (or its own
|
|
rune_home hole) so rows are order-independent replays. RUNE_HOME is the
|
|
relative "it_rig_home" (rig) — no absolute paths in truth. No clock: the
|
|
oracle has no time inputs.
|
|
|
|
Output: src/rust/inference_trace/src/frozen_it_gap_truth.json
|
|
(harness array schema: [{fn, args, kwargs, expected}] — embedded VERBATIM
|
|
by src/rust/inference_trace/src/gap_battery.rs).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
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" / "rust" / "inference_trace" / "src" / "frozen_it_gap_truth.json"
|
|
|
|
|
|
def mk(**over) -> dict:
|
|
base = dict(
|
|
schema_version=5, provider="ollama", model="qwen3:14b",
|
|
task_id="T42", channel="chat", resolved_context_window=32768,
|
|
input_budget=24000, model_calls=2, prompt_tokens_estimated=5150,
|
|
prompt_tokens_served=5102, output_tokens=733, latency_ms=8123.4,
|
|
model_time_ms=6210.9,
|
|
per_block_tokens={"constitution": 412, "project": 1300},
|
|
dropped_blocks=[{"name": "human", "tokens": 88}],
|
|
tools_exposed=["read", "edit"], memories_exposed=["constitution"],
|
|
memory_tokens=1712, degraded=[], cache=None, cost_usd=None,
|
|
cost_basis="local-unpriced", success=True, error="",
|
|
)
|
|
base.update(over)
|
|
return base
|
|
|
|
|
|
def seed(path: str, content: str) -> dict:
|
|
return {"op": "seed_file", "path": path, "content": content}
|
|
|
|
|
|
cases = []
|
|
|
|
# ── record_trace_json: append + resolution ──────────────────────────────
|
|
cases += [
|
|
("record_trace_json", [mk(), "it_t/r1"], {}),
|
|
("record_trace_json", [mk(task_id="R2"), "it_t/r2"], {
|
|
"prestate": [seed("it_t/r2/inference_traces.jsonl",
|
|
json.dumps(mk(task_id="R0"), sort_keys=True,
|
|
separators=(",", ":")) + "\n")]}),
|
|
("record_trace_json", [mk(task_id="R3"), None],
|
|
{"rune_home": "it_rig_home"}),
|
|
]
|
|
|
|
# ── record_trace_json: rotation (row-pinned rotate_bytes) ───────────────
|
|
cases += [
|
|
# basic: oversized live file shifts to .1, fresh file carries the line
|
|
("record_trace_json", [mk(task_id="R4"), "it_t/r4"],
|
|
{"rotate_bytes": 200,
|
|
"prestate": [seed("it_t/r4/inference_traces.jsonl", "x" * 250)]}),
|
|
# full chain: current→.1, .1→.2, .2→.3 (every source exists)
|
|
("record_trace_json", [mk(task_id="R5"), "it_t/r5"],
|
|
{"rotate_bytes": 200,
|
|
"prestate": [seed("it_t/r5/inference_traces.jsonl", "x" * 250),
|
|
seed("it_t/r5/inference_traces.jsonl.1", "AAA\n"),
|
|
seed("it_t/r5/inference_traces.jsonl.2", "BBB\n")]}),
|
|
# exact boundary: size == rotate_bytes is NOT greater → append, no shift
|
|
("record_trace_json", [mk(task_id="R6"), "it_t/r6"],
|
|
{"rotate_bytes": 200,
|
|
"prestate": [seed("it_t/r6/inference_traces.jsonl", "z" * 199 + "\n")]}),
|
|
# under boundary
|
|
("record_trace_json", [mk(task_id="R7"), "it_t/r7"],
|
|
{"rotate_bytes": 200,
|
|
"prestate": [seed("it_t/r7/inference_traces.jsonl", "y" * 150 + "\n")]}),
|
|
# source-guard: .2 exists but .1 missing → .2→.3 fires, .1→.2 skipped
|
|
# (dest .2 survives), current→.1 fires
|
|
("record_trace_json", [mk(task_id="R9"), "it_t/r9"],
|
|
{"rotate_bytes": 200,
|
|
"prestate": [seed("it_t/r9/inference_traces.jsonl", "x" * 250),
|
|
seed("it_t/r9/inference_traces.jsonl.2", "BBB\n")]}),
|
|
]
|
|
|
|
# ── record_trace_json: v5-full + unicode (ensure_ascii line law) ────────
|
|
cases += [
|
|
("record_trace_json", [mk(
|
|
task_id="Ür-42 🚀", routing_reason="tier:heiß", routing_mode="local",
|
|
task_family="Über-möde ✗", selected_tools=["read", "größer"],
|
|
capability_reason="allowlist-✓", find_capability_calls=1,
|
|
capsule_messages=[{"role": "user", "content": "héllo wörld — ✓"}],
|
|
capsule_content_hashes={"verfassung": "a" * 64},
|
|
capsule_token_count=5150,
|
|
memory_candidates=9, memory_selected=2, memory_abstained=False,
|
|
memory_types_queried=["projekt"],
|
|
error="zeitüberschreitung — ✗", success=False,
|
|
degraded=["speicher"], model_calls=1, output_tokens=0,
|
|
), "it_t/r8"], {}),
|
|
]
|
|
|
|
# ── read_traces_json: selection, limits, missing, crash class ───────────
|
|
LINES = [json.dumps(mk(task_id=f"W{i}"), sort_keys=True,
|
|
separators=(",", ":")) for i in range(5)]
|
|
RAW = "\n".join(LINES[:3]) + "\n\n\n" + "\n".join(LINES[3:]) + "\n"
|
|
STORE = "it_t/w1/inference_traces.jsonl"
|
|
PRE_RAW = [seed(STORE, RAW)]
|
|
|
|
cases += [
|
|
("read_traces_json", ["it_t/w1"], {"limit": None, "prestate": PRE_RAW}),
|
|
("read_traces_json", ["it_t/w2"], {"limit": 2, "prestate": [
|
|
seed("it_t/w2/inference_traces.jsonl", RAW)]}),
|
|
# limit=0: Python lines[-0:] == ALL lines (quirk row)
|
|
("read_traces_json", ["it_t/w3"], {"limit": 0, "prestate": [
|
|
seed("it_t/w3/inference_traces.jsonl", RAW)]}),
|
|
("read_traces_json", ["it_t/w4"], {"limit": 99, "prestate": [
|
|
seed("it_t/w4/inference_traces.jsonl", RAW)]}),
|
|
("read_traces_json", ["it_t/nowhere"], {"limit": None}),
|
|
("read_traces_json", [None], {"rune_home": "it_rig_hole", "limit": 2}),
|
|
# malformed line → ValueError crash class (message rides the fallback)
|
|
("read_traces_json", ["it_t/w7"], {"limit": None, "prestate": [
|
|
seed("it_t/w7/inference_traces.jsonl",
|
|
LINES[0] + "\n" + "not json {" + "\n" + LINES[1] + "\n")]}),
|
|
# round-trip: seeds written as the recorder would → parsed records
|
|
("read_traces_json", ["it_t/w8"], {"limit": None, "prestate": [
|
|
seed("it_t/w8/inference_traces.jsonl",
|
|
LINES[0] + "\n" + LINES[4] + "\n")]}),
|
|
]
|
|
|
|
truth = freeze("rune.inference_trace", cases,
|
|
oracle_module="rune.inference_trace")
|
|
write(truth, OUT)
|
|
print(f"wrote {len(truth)} cases -> {OUT}")
|