Band faces now use signed distance to the displaced solid intervals, continuous across bands, so MC interpolates the interface instead of terracing at density levels. The Gradient amplitude is restored to width/8 (about 4 m peak-to-peak at 16 m). Ring/terrace audit at LOD0-8 on the FI floor and SW ceiling passes; negative controls: L30 (rings) and L31 (flat) both fail. Hole/interface audits, 16 passage rows and 24/24 determinism pass. Evaluator 20. Cost vs L31 SW +1.9%, FI +1.5%. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
82 lines
3.6 KiB
Python
82 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Run L31 route/proof and transition invariants with recipe-stamped logs."""
|
|
import re
|
|
import subprocess
|
|
import time
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[4]
|
|
OUT = ROOT / "Saved/Linux/l32"
|
|
BINARIES = {
|
|
"clang": OUT / "bin/VoxelForgeCoreHeadless-l32-clang-v20",
|
|
"gcc": OUT / "bin/VoxelForgeCoreHeadless-l32-gcc-v20",
|
|
}
|
|
rows = []
|
|
failed = False
|
|
|
|
|
|
def run(name, binary, data, recipe, extra, checks):
|
|
global failed
|
|
logfile = OUT / f"{name}.log"
|
|
command = [
|
|
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--", str(binary), str(data), "--workers=12", "--world-assembler-prototype",
|
|
"--stream-benchmark", "--stream-pipeline", "--force-generate",
|
|
"--clip-radius=3", "--max-clip-level=8", "--max-level=-1",
|
|
f"--recipe={recipe}", *extra,
|
|
]
|
|
started = time.monotonic()
|
|
try:
|
|
with logfile.open("w", encoding="utf-8") as stream:
|
|
result = subprocess.run(command, stdout=stream, stderr=subprocess.STDOUT,
|
|
timeout=900, check=False)
|
|
except subprocess.TimeoutExpired:
|
|
result = None
|
|
elapsed = time.monotonic() - started
|
|
text = logfile.read_text(encoding="utf-8", errors="replace")
|
|
stamps = re.findall(
|
|
r"^\[WorldAssemblerRecipeAudit\] requested=([^ ]+) actual=([^ ]+).*status=([^ ]+)$",
|
|
text, re.M)
|
|
stamp_ok = stamps == [(recipe, recipe, "PASS")]
|
|
checks_ok = all(check(text) for check in checks)
|
|
ok = result is not None and result.returncode == 0 and stamp_ok and checks_ok
|
|
rows.append((name, recipe, elapsed, result.returncode if result else "TIMEOUT", ok))
|
|
print(f"{name} elapsed={elapsed:.1f}s recipe={stamps[0][1] if stamps else 'MISSING'} "
|
|
f"stamp={'PASS' if stamp_ok else 'FAIL'} checks={'PASS' if checks_ok else 'FAIL'} "
|
|
f"{'PASS' if ok else 'FAIL'}", flush=True)
|
|
failed |= not ok
|
|
|
|
|
|
owner = ROOT / "Standalone/data/owner_world.json"
|
|
for recipe in ("surface-world", "floating-islands"):
|
|
for compiler, binary in BINARIES.items():
|
|
name = f"invariant-route-proof-{recipe}-{compiler}"
|
|
run(name, binary, owner, recipe,
|
|
["--stream-hash", "--audit-uniform-block-proofs", "--audit-route-parity"],
|
|
[lambda text: bool(re.search(
|
|
r"^\[RouteParityAudit\].*status=PASS$", text, re.M)),
|
|
lambda text: bool(re.search(
|
|
r"^\[UniformBlockProofAudit\].*violations=0(?:\s|$)", text, re.M))])
|
|
|
|
for recipe in ("surface-world", "floating-islands"):
|
|
for compiler, binary in BINARIES.items():
|
|
for mode in ("hard", "gradient", "interleaved"):
|
|
name = f"invariant-transition-{recipe}-{mode}-{compiler}"
|
|
run(name, binary, owner, recipe,
|
|
[f"--transition-mode={mode}", "--audit-strate-transitions"],
|
|
[lambda text: bool(re.search(
|
|
r"^\[StrateTransitionAuditSummary\].*hole_columns=0 air_samples=0 .*status=PASS$",
|
|
text, re.M)),
|
|
lambda text: bool(re.search(
|
|
r"^\[StrateTransitionNegativeControls\].*status=PASS$", text, re.M))])
|
|
|
|
summary = OUT / "invariant-audits.csv"
|
|
summary.write_text(
|
|
"run,recipe,elapsed_seconds,exit_code,status\n" +
|
|
"".join(f"{name},{recipe},{elapsed:.3f},{code},{'PASS' if ok else 'FAIL'}\n"
|
|
for name, recipe, elapsed, code, ok in rows),
|
|
encoding="utf-8")
|
|
print(f"[L32InvariantAudits] runs={len(rows)} pass={sum(row[-1] for row in rows)} "
|
|
f"fail={sum(not row[-1] for row in rows)} summary={summary}", flush=True)
|
|
raise SystemExit(1 if failed or len(rows) != 16 else 0)
|