#!/usr/bin/env python3 """Build frozen old/new store probes and exercise disposable rollback databases.""" import argparse import io import json import pathlib import subprocess import sqlite3 import tarfile parser = argparse.ArgumentParser() parser.add_argument("--artifacts", required=True) args = parser.parse_args() repo = pathlib.Path(__file__).resolve().parents[1] out = pathlib.Path(args.artifacts).resolve() out.mkdir(parents=True, exist_ok=False) current = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=repo, text=True).strip() versions = {"old876": "87662f5", "old8a": "8a126727", "old3ed": "3ed7665", "new": current} fixtures = repo / "internal/docs/principalstore/testdata" records = [] for name, rev in versions.items(): sha = subprocess.check_output(["git", "rev-parse", rev], cwd=repo, text=True).strip() src = out / name src.mkdir() archive = subprocess.check_output(["git", "archive", sha], cwd=repo) with tarfile.open(fileobj=io.BytesIO(archive)) as tree: tree.extractall(src, filter="data") cmd = src / "cmd/principal-compat" cmd.mkdir() (cmd / "main.go").write_bytes((fixtures / "compat_main.go.txt").read_bytes()) step = "new" if name == "new" else "old" (cmd / "step.go").write_bytes((fixtures / f"compat_{step}.go.txt").read_bytes()) with (out / f"{name}-build.log").open("wb") as log: subprocess.run(["go", "build", "-o", str(out / f"{name}-proof"), "./cmd/principal-compat"], cwd=src, stdout=log, stderr=log, check=True) records.append({"name": name, "sha": sha}) (out / "builds.json").write_text(json.dumps(records, indent=2)) results = {} for old in ["old876", "old8a", "old3ed"]: db = out / f"{old}-cycle.db" phases = [] for index, binary in enumerate([old, "new", old, "new"]): phase = f"{old}-{index}" with (out / f"{phase}.stderr").open("wb") as log: raw = subprocess.check_output([str(out / f"{binary}-proof"), "--db", str(db), "--address", f"synthetic-{index}@example.invalid", "--phase", phase], cwd=out / binary, stderr=log) (out / f"{phase}.json").write_bytes(raw) result = json.loads(raw) if result["local_id"] != index + 1: raise RuntimeError("old/new allocation or LastInsertId changed") if index and any(result[k] != phases[0][k] for k in ["owner", "grant_author", "sqid", "content_hash", "encodings", "text"]): raise RuntimeError("owner/grant/content changed across rollback") if binary == "new" and (result["home_id"] != 2**52 or result["home_owned"] != 1): raise RuntimeError("Home identity/ownership changed") if index == 2 and result["home_owned"] != 1: raise RuntimeError("old binary lost Home ownership") if index and result["principal_count"] != index + 2: raise RuntimeError("legacy insert did not mirror the canonical ledger") phases.append(result) with sqlite3.connect(db) as check: if check.execute("PRAGMA foreign_key_check").fetchall(): raise RuntimeError("foreign key damage across rollback") if check.execute("SELECT COUNT(*) FROM people WHERE email='' OR id>=4503599627370496").fetchone()[0]: raise RuntimeError("Home-only identity leaked into legacy people") results[old] = phases (out / "verified.json").write_text(json.dumps({"candidate": current, "versions": records, "cycles": results}, indent=2)) print(out / "verified.json")