#!/usr/bin/env python3 """Self-authored static bundle validator; no network access.""" from __future__ import annotations import json import re import sys from pathlib import Path REQUIRED = [ "pages/index.md", "pages/executive-summary/page.md", "pages/conclusion/page.md", ] for n in range(1, 7): REQUIRED.append(f"pages/claim-{n}/page.md") HEDGES = [ r"\bcould not be\b", r"\bunable to\b", r"\bleft open\b", r"\bfurther work\b", r"\binconclusive\b", r"\bnot possible to\b", r"\bdid not attempt\b", r"\bwe do not claim\b", r"\bpending\b", ] PAGE_LEAKS = [r"/Users/", r"\bvalidator\b", r"\bduplicate\b", r"\bhandoff\b", r"\bpublisher\b", r"\bpeer\b", r"\bexpected score\b"] def main() -> int: root = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else Path.cwd() warnings: list[str] = [] for rel in REQUIRED: p = root / rel if not p.is_file() or not p.read_text(encoding="utf-8").strip(): warnings.append(f"missing_or_empty:{rel}") page_files = sorted((root / "pages").rglob("*.md")) if (root / "pages").is_dir() else [] if len(page_files) != 9: warnings.append(f"page_file_count:{len(page_files)}") claim_files = sorted((root / "pages").glob("claim-*/page.md")) if (root / "pages").is_dir() else [] if len(claim_files) != 6: warnings.append(f"claim_page_count:{len(claim_files)}") verdicts = [] for p in claim_files: text = p.read_text(encoding="utf-8") match = re.search(r"^# Claim [1-6] — (VERIFIED|FALSIFIED)$", text, re.M) if not match: warnings.append(f"missing_decisive_heading:{p.relative_to(root)}") else: verdicts.append(match.group(1)) for pat in HEDGES: if re.search(pat, text, re.I): warnings.append(f"hedge:{p.relative_to(root)}:{pat}") for pat in PAGE_LEAKS: if re.search(pat, text, re.I): warnings.append(f"page_leak:{p.relative_to(root)}:{pat}") if len(verdicts) != 6: warnings.append(f"verdict_count:{len(verdicts)}") if any(v not in {"VERIFIED", "FALSIFIED"} for v in verdicts): warnings.append("non_decisive_verdict") total_chars = sum(len(p.read_text(encoding="utf-8")) for p in page_files) if total_chars < 5000: warnings.append(f"pages_under_minimum:{total_chars}") if total_chars >= 120000: warnings.append(f"pages_over_cap:{total_chars}") readme = root / "README.md" readme_text = readme.read_text(encoding="utf-8") if readme.is_file() else "" if "- icml2026-repro" not in readme_text: warnings.append("missing_tag:icml2026-repro") if "- paper-NinueNAODD" not in readme_text: warnings.append("missing_tag:paper-NinueNAODD") forbidden_names = {"known-", "quarantine"} for p in root.rglob("*"): if any(token.lower() in p.name.lower() for token in forbidden_names): warnings.append(f"forbidden_path:{p.relative_to(root)}") out = { "warnings": warnings, "warning_count": len(warnings), "page_chars": total_chars, "page_files": len(page_files), "claim_pages": len(claim_files), "verdicts": verdicts, "score": 2 * len(verdicts) if len(verdicts) == 6 else None, } print(json.dumps(out, indent=2, sort_keys=True)) return 1 if warnings else 0 if __name__ == "__main__": raise SystemExit(main())