"""Stage an explicit allowlist of code/docs/results; never copy credentials or .git.""" import argparse import hashlib import json import shutil from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def build(reports): output = ROOT / "release" / "pcd" output.mkdir(parents=True, exist_ok=True) files = [ ROOT / name for name in ( "requirements-pcd.txt", "lfm25_pcd_modal.py", "README-PCD.md", "LICENSE-CODE", "THIRD_PARTY_NOTICES.md", "ruff.toml", ) ] files += sorted((ROOT / "pcd").glob("*.py")) files += sorted((ROOT / "tests" / "pcd").glob("*.py")) files += sorted((ROOT / "scripts").glob("*pcd*.py")) files += [ROOT / "docs" / "pcd-results.md"] files += [ROOT / name for name in reports] hashes = {} for source in files: relative = source.relative_to(ROOT) if not source.is_file() or source.is_symlink(): raise ValueError(f"expected a regular release file: {relative}") target = output / relative target.parent.mkdir(parents=True, exist_ok=True) shutil.copyfile(source, target) hashes[str(relative)] = hashlib.sha256(target.read_bytes()).hexdigest() manifest = { "files": hashes, "reports": reports, "core_files": [ "engine.py", "cache.py", "schema.py", "prompting.py", "config.py", "tasks.py", ], } for name in reports: report = json.loads((ROOT / name).read_text()) if not report.get("validation", {}).get("passed") or report.get("budget_exhausted"): raise ValueError(f"incomplete/failed release report: {name}") if report["task"] == "benchmark": for core in manifest["core_files"]: if report["source_sha256"][core] != hashes[f"pcd/{core}"]: raise ValueError(f"benchmark/code mismatch: {core}") # Fail on stale staging files rather than accidentally uploading leftovers. actual = {str(p.relative_to(output)) for p in output.rglob("*") if p.is_file()} unexpected = actual - set(hashes) - {"ARTIFACTS.json"} if unexpected: raise ValueError(f"unexpected files in release staging: {sorted(unexpected)}") (output / "ARTIFACTS.json").write_text(json.dumps(manifest, indent=2) + "\n") print(json.dumps({"directory": str(output), "files": len(hashes)}, indent=2)) if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("reports", nargs="+") build(parser.parse_args().reports)