#!/usr/bin/env python3 """Session-bound current-source static ABI capture; refuses output reuse.""" import hashlib import json import pathlib import struct import subprocess import sys from datetime import datetime, timezone ROOT = pathlib.Path("/home/alex/sots-re") SESSION = "run-35e59053176da458d8b46fea" OUT = ROOT / "verify/results/research-completion-abi" / (SESSION + "-repair1") ENGINE = pathlib.Path("/tmp/opencode/sots-final-research-engine") RE = pathlib.Path("/tmp/opencode/sots-final-research-re") CAMPAIGN = ROOT / "tools/campaign.py" EXE = ROOT / "dumps/sots.exe" SAVE = ROOT / "verify/results/saves/turn3-state.sav" OBJDUMP = pathlib.Path("/usr/bin/objdump") EXPECTED = { "engine": "ccd8e02083e8d2e2b3e97976ace2273c8f924dfc02a39e919004eaf3544c50fd", "re": "e5cf1c44761bebcada1aacb53f30722bdaf4784f21a9ec1023a1851c142c124f", "exe": "970b7de729956a53094c7eb98aba4270aee98e2fed5daf0d39e290013c90c841", "objdump": "1eaaef2e7f57c4c7f69115c495e2466f5a8c8e5f3bc42221d092382f30f9d4cd", "save": "978041acd168b56ed8eb3f5e42e78d5e70eae6e6517d75e659a5eb7ca3d60921", } # Names classify evidence only; these windows expose instructions but execute no branch. WINDOWS = ( ("observed-ctor", 0x8562A0, 0x856310), ("observed-append", 0x7B7320, 0x7B73A2), ("observed-copy", 0x79A150, 0x79A1DC), ("observed-growth", 0x7B34E0, 0x7B35F2), ("observed-alloc", 0x57E590, 0x57E5E7), ("player-ctor", 0x84EE30, 0x84EEF4), ("player-append", 0x86C580, 0x86C631), ("player-growth", 0x869500, 0x869620), ("player-copy", 0x7693F0, 0x7694C3), ("player-dtor", 0x61AE90, 0x61AEFC), ("string-assign", 0x4249A0, 0x424ADD), ("import-thunks", 0x924FAA, 0x924FBC), ("turn-get-create", 0x885380, 0x88544E), ("turn-append", 0x884CB0, 0x884D93), ("turn-growth", 0x8841A0, 0x884300), ("nested-copy-authority", 0x779850, 0x779930), ("nested-dtor", 0x629580, 0x6295CE), ("turn-virtual-dtor", 0x62E120, 0x62E170), ("dedup", 0x825D40, 0x825E67), ("string-not-equal", 0x46F8C0, 0x46F8F0), ("prune", 0x879EB0, 0x879FC0), ("nested-copy-stop-9913", 0x779850, 0x779913), ("nested-copy-stop-9915", 0x779850, 0x779915), ("nested-copy-stop-a20", 0x779850, 0x779A20), ("nested-copy-stop-a21", 0x779850, 0x779A21), ("nested-copy-stop-a23", 0x779850, 0x779A23), ("nested-copy-stop-a28", 0x779850, 0x779A28), ) def sha(data): return hashlib.sha256(data).hexdigest() def ident(path): target = path.resolve() data = target.read_bytes() return {"path": str(path), "resolved_path": str(target), "bytes": len(data), "sha256": sha(data)} def binding(): argv = [sys.executable, str(CAMPAIGN), "--state-root", str(ROOT), "source-binding", "research-completion-abi", "--engine-worktree", str(ENGINE), "--re-worktree", str(RE)] p = subprocess.run(argv, cwd=ROOT, capture_output=True, text=True, check=True) return {"argv": argv, "value": json.loads(p.stdout)} def rows(data): return [line.rstrip() for line in data.decode("utf-8").splitlines() if ":" in line and line.lstrip()[:1].isdigit()] def pe_reader(data): pe = struct.unpack_from(" 0 for x in records), "all_stderr_empty": all(x["stderr"]["bytes"] == 0 for x in records), "source_stable": before["value"] == after["value"], **comparisons, } manifest = { "schema": "sots-abi-static-capture/2", "session": SESSION, "actor": "research-abi-analyst", "role": "analyst", "model": "openai/gpt-5.6-sol", "timestamp": datetime.now(timezone.utc).isoformat(), "decisions": ["d-e9d6d48cd77538556d1a1c1f", "d-6e30d172051af0385f5979eb"], "scope": "Static instruction/byte capture and immutable input identity; no game/runtime execution.", "source_before": before, "source_after": after, "files": files, "image_base": f"0x{image_base:08x}", "commands": records, "direct_pe": direct, "checks": [{"name": k, "status": "pass" if v else "fail"} for k, v in checks.items()], "failed": [k for k, v in checks.items() if not v], "static_branch_exposure": ["existing-match/miss", "spare/full capacity", "empty/nonempty nested copy", "null/nonnull destruction", "short/long string", "normal/unwind", "bad/aligned boundaries"], "runtime_unexercised": ["all listed static branches", "allocator safety", "event construction and IDs", "PostEvent caller defaults/write order", "exception throw", "RNG state/draws"], "original_helpers": ["0x00924fb6 allocation thunk", "0x00924faa deallocation thunk", "0x0046f8c0 original string comparison when called"], } (OUT / "manifest.json").write_text(json.dumps(manifest, indent=2) + "\n") print(json.dumps({"output": str(OUT.relative_to(ROOT)), "commands": len(records), "failed": manifest["failed"]}, indent=2)) raise SystemExit(bool(manifest["failed"]))