sots-re/verify/results/research-completion-abi/run-16f8e9b6376b278c4870be09/capture.py

94 lines
3.1 KiB
Python

#!/usr/bin/env python3
"""Capture the four read-only windows required by decision d-b51f3f76803e852ed250846a."""
import hashlib
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path("/home/alex/sots-re")
OUT = ROOT / "verify/results/research-completion-abi/run-16f8e9b6376b278c4870be09"
BINARY = ROOT / "dumps/sots.exe"
TOOL = Path("/usr/bin/objdump")
WINDOWS = (
("turn-get-create", "0x00885380", "0x0088544a"),
("turn-append", "0x00884cb0", "0x00884d8f"),
("nested-copy", "0x00779850", "0x00779a20"),
("nested-dtor", "0x00629580", "0x006295ca"),
)
def digest(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def file_digest(path: Path) -> str:
return digest(path.read_bytes())
records = []
for name, start, stop in WINDOWS:
argv = [str(TOOL), "-D", "-Mintel", f"--start-address={start}",
f"--stop-address={stop}", str(BINARY)]
proc = subprocess.run(argv, cwd=ROOT, check=False, capture_output=True)
stdout_path = OUT / f"{name}.stdout.txt"
stderr_path = OUT / f"{name}.stderr.txt"
stdout_path.write_bytes(proc.stdout)
stderr_path.write_bytes(proc.stderr)
records.append({
"name": name,
"argv": argv,
"cwd": str(ROOT),
"start": start,
"stop": stop,
"returncode": proc.returncode,
"stdout": {
"path": str(stdout_path.relative_to(ROOT)),
"bytes": len(proc.stdout),
"sha256": digest(proc.stdout),
},
"stderr": {
"path": str(stderr_path.relative_to(ROOT)),
"bytes": len(proc.stderr),
"sha256": digest(proc.stderr),
},
})
version = subprocess.run([str(TOOL), "--version"], check=True,
capture_output=True, text=True).stdout.splitlines()[0]
manifest = {
"schema": "sots-abi-static-capture/1",
"session": "run-16f8e9b6376b278c4870be09",
"actor": "research-abi-analyst",
"role": "analyst",
"model": "openai/gpt-5.6-sol",
"timestamp": datetime.now(timezone.utc).isoformat(),
"scope": "Fresh read-only correction capture required by d-b51f3f76803e852ed250846a; no game execution or live allocator claim.",
"source_binding": {
"engine": {
"path": "/tmp/opencode/sots-final-research-engine",
"commit": "7741d42fc5e4e761e6449bdaf0e4a61d00036a23",
"sha256": "ccd8e02083e8d2e2b3e97976ace2273c8f924dfc02a39e919004eaf3544c50fd",
},
"re": {
"path": "/tmp/opencode/sots-final-research-re",
"commit": "3bfde5a70d874a723e797a695bbd847fd82c0aa7",
"sha256": "6696fd5201e144843617cbf6d78b41b5287ad5dcc9fa1e8aaa861d52b64e72e8",
},
},
"input": {
"path": "dumps/sots.exe",
"bytes": BINARY.stat().st_size,
"sha256": file_digest(BINARY),
},
"tool": {
"path": str(TOOL),
"bytes": TOOL.stat().st_size,
"sha256": file_digest(TOOL),
"version": version,
},
"windows": records,
}
(OUT / "manifest.json").write_text(json.dumps(manifest, indent=2) + "\n")