#!/usr/bin/env python3 """Negative tamper tests for the offline release verifier.""" from __future__ import annotations import shutil import subprocess import sys import tempfile from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def verify(path: Path, expected: int) -> None: result = subprocess.run( [sys.executable, "scripts/verify_release.py"], cwd=path, text=True, capture_output=True, check=False, ) if result.returncode != expected: raise AssertionError( f"expected verifier exit {expected}, got {result.returncode}: {result.stdout}{result.stderr}" ) def copied_candidate(temp_root: Path) -> Path: target = temp_root / "candidate" shutil.copytree(ROOT, target, ignore=shutil.ignore_patterns(".git", "__pycache__")) return target def main() -> int: with tempfile.TemporaryDirectory(prefix="l35-verifier-") as directory: temp_root = Path(directory) clean = copied_candidate(temp_root / "clean") verify(clean, 0) claim_tamper = copied_candidate(temp_root / "claim-tamper") claims = claim_tamper / "evidence/active_claims.json" claims.write_text(claims.read_text(encoding="utf-8").replace("Theorem 1", "Tampered theorem", 1), encoding="utf-8") verify(claim_tamper, 1) pin_tamper = copied_candidate(temp_root / "pin-tamper") pins = pin_tamper / "evidence/pins.json" pins.write_text(pins.read_text(encoding="utf-8").replace("af5ab2d6", "bf5ab2d6", 1), encoding="utf-8") verify(pin_tamper, 1) inventory_tamper = copied_candidate(temp_root / "inventory-tamper") inventory = inventory_tamper / "evidence/repository_tree.json" inventory.write_text(inventory.read_text(encoding="utf-8").replace("README.md", "README-tampered.md", 1), encoding="utf-8") verify(inventory_tamper, 1) extra_file = copied_candidate(temp_root / "extra-file") (extra_file / "unexpected.txt").write_text("tamper\n", encoding="utf-8") verify(extra_file, 1) short_page = copied_candidate(temp_root / "short-page") (short_page / "pages/01-overview.md").write_text("too short\n", encoding="utf-8") verify(short_page, 1) event_handler = copied_candidate(temp_root / "event-handler") index = event_handler / "index.html" index.write_text(index.read_text(encoding="utf-8").replace("
", '
', 1), encoding="utf-8") verify(event_handler, 1) external_link = copied_candidate(temp_root / "external-link") index = external_link / "index.html" index.write_text(index.read_text(encoding="utf-8").replace("pages/01-overview.md", "https://example.invalid", 1), encoding="utf-8") verify(external_link, 1) metadata_tamper = copied_candidate(temp_root / "metadata-tamper") readme = metadata_tamper / "README.md" readme.write_text(readme.read_text(encoding="utf-8").replace("paper-l35QweVxgn", "paper-tampered", 1), encoding="utf-8") verify(metadata_tamper, 1) print("PASS: clean candidate accepted; eight negative tamper tests rejected") return 0 if __name__ == "__main__": try: raise SystemExit(main()) except AssertionError as error: print(f"FAIL: {error}", file=sys.stderr) raise SystemExit(1)