#!/usr/bin/env python3 from __future__ import annotations import argparse import json import shutil import hashlib from datetime import datetime, timezone from pathlib import Path ROOT = Path(__file__).resolve().parents[1] TEMP = ROOT / "Temp" ARCHIVE = ROOT / "artifacts" / "archive" KEEP_NAMES = { "final_decision_packet_active.json", "operational_report.json", "operational_report.md", "release_dag_run_v1.json", } ARCHIVE_CANDIDATES = { "release_gate_summary_v1.json", "release_gate_summary_v2.json", "release_gate_summary_v3.json", } def _sha256_file(path: Path) -> str: digest = hashlib.sha256() with path.open("rb") as fh: for chunk in iter(lambda: fh.read(1024 * 1024), b""): digest.update(chunk) return digest.hexdigest() def main() -> int: ap = argparse.ArgumentParser() ap.add_argument("--dry-run", action="store_true") ap.add_argument("--apply", action="store_true") ap.add_argument("--budget", type=int, default=300) args = ap.parse_args() files = sorted([p for p in TEMP.glob("*.json") if p.is_file() and p.name in ARCHIVE_CANDIDATES]) archive_root = ARCHIVE / datetime.now(timezone.utc).strftime("%Y%m%d") archive_root.mkdir(parents=True, exist_ok=True) archived = [] for src in files: dst = archive_root / src.name archived.append({ "source": str(src), "archive": str(dst), "sha256": _sha256_file(src), "size": src.stat().st_size, }) if args.apply and not args.dry_run: shutil.move(str(src), str(dst)) manifest = { "formula_id": "CLEAN_TEMP_ARTIFACTS_V1", "generated_at": datetime.now(timezone.utc).isoformat(), "dry_run": bool(args.dry_run or not args.apply), "budget": args.budget, "candidates": [p.name for p in files], "candidate_count": len(files), "archived_count": len(archived) if args.apply and not args.dry_run else 0, "archived": archived, "gate": "PASS" if len(files) >= 0 else "FAIL", } (archive_root / "temp_cleanup_manifest_v1.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8") print(json.dumps(manifest, ensure_ascii=False, indent=2)) return 0 if __name__ == "__main__": raise SystemExit(main())