#!/usr/bin/env python3 """Offline release gate for the RL4RLA static candidate.""" from __future__ import annotations import hashlib import json import os import stat import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] EXPECTED_PATHS = { "README.md", "index.html", "evidence/claims.json", "evidence/claims_anchored.json", "evidence/provenance.json", "pages/01-claim-matrix.md", "pages/02-evidence-boundaries.md", "scripts/verify_release.py", "manifest.sha256", "release-allowlist.txt", } REQUIRED_TAGS = ("icml2026-repro", "paper-Oj2I1xdKpv") BOUNDARY = ( "Evidence limit: this package contains a released-source and paper-table audit plus one " "runner dry-run; it is not an independent reproduction and does not validate the reported " "numerical results." ) EXPECTED_CLAIMS = ( "RL4RLA rediscovers state-of-the-art randomized linear algebra methods including sketch-and-precondition, Randomized Kaczmarz, and Newton Sketch", "Numerical curriculum with Monte Carlo Graph Search enables discovery of interpretable, symbolic RLA algorithms", "On Newton Sketch, MCGS with the UCD criterion reaches 100% success using only 1,416 playouts, compared to 10,721 playouts for Preconditioned Weighted SGD and 25,158 for Block Randomized Kaczmarz (Table 2).", "MCGS reduces the number of playouts needed versus standard MCTS by roughly 2-3x by merging equivalent states in a DAG rather than a tree (Section 4.3, Table 2).", "The five-stage curriculum (Landweber iteration, Gradient Descent, Preconditioned GD, Sketched Preconditioned GD, Leverage-Score Subsampling) progressively increases problem difficulty, each stage introducing exactly one new failure mode resolved by one algorithmic component (Section 4.2, Table 1).", "Ablating the staged curriculum causes discovery of the Newton Sketch algorithm to fail completely (0% success across all partial curricula), while the full four-stage curriculum achieves 100% success (Table 7).", "MCGS sustains 50-58% state revisit rates during search, versus near-zero revisit rates for standard MCTS, demonstrating effective exploitation of shared subproblem structure (Figure 4).", "The discovered framework generalizes to eigenvalue problems (power iteration and sketched power iteration) with only one added normalization primitive, achieving 100% success on all three curriculum stages (Section 5.4, Table 3).", ) def fail(message: str) -> None: print(f"FAIL: {message}", file=sys.stderr) raise SystemExit(1) def sha256(path: Path) -> str: return hashlib.sha256(path.read_bytes()).hexdigest() def public_files() -> set[str]: files: set[str] = set() for directory, dirnames, filenames in os.walk(ROOT, followlinks=False): relative_dir = Path(directory).relative_to(ROOT) if ".git" in dirnames: dirnames.remove(".git") for name in filenames: path = Path(directory, name) if path.is_symlink(): fail(f"symlink is forbidden: {path.relative_to(ROOT)}") files.add(str(relative_dir / name)) return files def load_manifest() -> dict[str, str]: entries: dict[str, str] = {} for line in (ROOT / "manifest.sha256").read_text(encoding="utf-8").splitlines(): digest, separator, path = line.partition(" ") if not separator or len(digest) != 64 or path in entries: fail("malformed manifest") entries[path] = digest return entries def main() -> None: actual_paths = public_files() if actual_paths != EXPECTED_PATHS: fail(f"release inventory mismatch: {sorted(actual_paths ^ EXPECTED_PATHS)}") allowlist = set((ROOT / "release-allowlist.txt").read_text(encoding="utf-8").splitlines()) if allowlist != EXPECTED_PATHS: fail("release allowlist is not the exact expected inventory") for relative in EXPECTED_PATHS: path = ROOT / relative if stat.S_IMODE(path.stat().st_mode) != 0o644: fail(f"unexpected file mode: {relative}") manifest = load_manifest() expected_manifest_paths = EXPECTED_PATHS - {"manifest.sha256"} if set(manifest) != expected_manifest_paths: fail("manifest inventory is incomplete or has undeclared paths") for relative, digest in manifest.items(): if sha256(ROOT / relative) != digest: fail(f"hash mismatch: {relative}") readme = (ROOT / "README.md").read_text(encoding="utf-8") if not all(tag in readme for tag in REQUIRED_TAGS): fail("required discovery tags are missing") if "sdk: static" not in readme or "app_file: index.html" not in readme: fail("static Space metadata is missing") default_claims = json.loads((ROOT / "evidence/claims.json").read_text(encoding="utf-8"))["claims"] anchored_claims = json.loads((ROOT / "evidence/claims_anchored.json").read_text(encoding="utf-8"))["claims"] observed_claims = tuple(entry["text"] for entry in default_claims + anchored_claims) if observed_claims != EXPECTED_CLAIMS: fail("official claim text differs from the immutable expected target set") page_text = "\n".join(path.read_text(encoding="utf-8") for path in sorted((ROOT / "pages").glob("*.md"))) if len("".join(page_text.split())) < 200: fail("combined stripped page text is under 200 characters") if BOUNDARY not in page_text or BOUNDARY not in (ROOT / "index.html").read_text(encoding="utf-8"): fail("immutable evidence boundary is missing") html = (ROOT / "index.html").read_text(encoding="utf-8").lower() if any(token in html for token in ("