#!/usr/bin/env python3 """Count first whole-tile proof vetoes among full-grid uniform observations.""" from __future__ import annotations import json import re import subprocess import time from collections import Counter from pathlib import Path ROOT = Path(__file__).resolve().parents[4] OUT = ROOT / "Saved/Linux/l75/logs" DATA = ROOT / "Standalone/data/owner_world.json" BIN = ROOT / "Saved/Linux/l75/bin/VoxelForgeCoreHeadless-l75-clang" CAMERAS = { 0: (8.0, 16.0, -372.2626953125), 1: (25.8369140625, 3.19921875, -737.0), 2: (19.166015625, -14.2001953125, -753.3740234375), 3: (-20.0625, -5.068359375, -900.353515625), } ROW = re.compile(r"\[UniformGridCeiling\] (.*)") PAIR = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)") REASONS = { 0: "none_or_certified", 1: "detail_envelope", 2: "composer_candidate", 3: "passage_bounds", 4: "primitive_overlap", 5: "transition", 6: "stratum_crossing", 7: "smooth_min_slack", 8: "other", } def run(view: int) -> list[dict]: camera = ",".join(f"{value:.12f}" for value in CAMERAS[view]) + ",0,0" log = OUT / f"veto-view{view}.log" command = [ "taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--", "timeout", "1740s", str(BIN), str(DATA), "--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline", "--stream-hash-tiles", "--force-generate", "--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=8", f"--camera={camera}", ] started = time.monotonic() with log.open("w", encoding="utf-8") as output: result = subprocess.run(command, cwd=ROOT, stdout=output, stderr=subprocess.STDOUT, check=False, timeout=1740) rows = [] for line in log.read_text(encoding="utf-8", errors="replace").splitlines(): match = ROW.search(line) if not match: continue row = dict(PAIR.findall(match.group(1))) key_value = row["key"].strip("()") row["key"] = tuple(int(value) for value in key_value.split(",")) row = {key: (value if key == "key" else int(value)) for key, value in row.items()} row.update(view=view, log=str(log.relative_to(ROOT))) rows.append(row) print(json.dumps({"view": view, "exit_code": result.returncode, "wall_s": round(time.monotonic() - started, 3), "tiles": len(rows), "log": str(log.relative_to(ROOT))}, sort_keys=True), flush=True) if result.returncode != 0 or not rows: raise SystemExit(f"veto audit view {view} failed or emitted no rows; see {log}") return rows def main() -> int: if not DATA.is_file() or not BIN.is_file(): raise SystemExit("missing owner world or L75 Clang headless binary") OUT.mkdir(parents=True, exist_ok=True) all_rows = [row for view in range(4) for row in run(view)] missed = [row for row in all_rows if row["samples"] > 0 and row["uniform"] and not row["proof_safe"]] counts = Counter(row["proof_veto"] for row in missed) by_strate = [] for view in range(4): group = [row for row in missed if row["view"] == view] by_strate.append({ "strate": view, "missed_uniform_tiles": len(group), "vetoes": {REASONS.get(reason, f"unknown_{reason}"): count for reason, count in sorted(Counter( row["proof_veto"] for row in group).items())}, }) summary = { "observations": len(all_rows), "sampled_tiles": sum(row["samples"] > 0 for row in all_rows), "true_uniform_tiles": sum(row["samples"] > 0 and row["uniform"] for row in all_rows), "missed_uniform_tiles": len(missed), "vetoes": {REASONS.get(reason, f"unknown_{reason}"): count for reason, count in sorted(counts.items())}, "by_strate": by_strate, "missed_tiles": missed, } (OUT / "veto-audit.json").write_text(json.dumps(summary, indent=2) + "\n", encoding="utf-8") print("[L75VetoSummary] " + json.dumps({key: value for key, value in summary.items() if key != "missed_tiles"}, sort_keys=True), flush=True) return 0 if __name__ == "__main__": raise SystemExit(main())