1#!/usr/bin/env python32"""artifacts/manifest.json: sha256 and size of every raw log, processed result, figure and table, plus the git commit and the3model revisions — the reproducibility package index (Gate G)."""4import hashlib, json, os, subprocess, time5ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))6def sha(p):7 h = hashlib.sha256()8 with open(p, "rb") as f:9 for b in iter(lambda: f.read(1 << 20), b""): h.update(b)10 return h.hexdigest()11files = []12for sub in ("benchmarks/raw", "benchmarks/processed", "figures", "paper/tables", "paper/main.pdf", "artifacts/environment.json", "research/prior_art.csv"):13 p = os.path.join(ROOT, sub)14 if os.path.isfile(p): files.append(p)15 else:16 for d, _, fs in os.walk(p):17 files += [os.path.join(d, f) for f in fs if not f.startswith(".")]18man = {"generated": time.strftime("%Y-%m-%dT%H:%M:%S"), "git": subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True, text=True, cwd=ROOT).stdout.strip(),19 "models": {"olmoe-1b-7b-0125-4bit": "mlx-community/OLMoE-1B-7B-0125-Instruct-4bit@e23844197887b031e7ddddbb0b8959c5a6853a7b",20 "qwen3-30b-a3b-2507-4bit": "mlx-community/Qwen3-30B-A3B-Instruct-2507-4bit@e9675aa3ca5f900ccef55267914466d55ab325fa"},21 "files": [{"path": os.path.relpath(p, ROOT), "bytes": os.path.getsize(p), "sha256": sha(p)} for p in sorted(files)]}22json.dump(man, open(os.path.join(ROOT, "artifacts", "manifest.json"), "w"), indent=1)23print(len(man["files"]), "files,", sum(f["bytes"] for f in man["files"]) / 1e6, "MB")24