SPB Git forge

spb/wp20_uqo

Public
1commits 1branches 0releases
2.8 MBsize
maindefault branch
yesterdaylast push
TeX 59% Python 40.8%
2.9 KB · 61 lines python
Raw Blame History
1#!/usr/bin/env python32"""Write results/manifest.json: every result artefact with size, SHA-256, producing script and inputs."""3import hashlib4import json5import subprocess6import time7from pathlib import Path89ROOT = Path(__file__).resolve().parents[1]10R = ROOT / "results"11PRODUCERS = {12    "tables/frame_exclusions.csv": "src/ingestion/build_frame.py", "tables/robots_exclusion_balance.csv": "src/ingestion/build_frame.py",13    "raw/frame_summary.json": "src/ingestion/build_frame.py", "raw/sample_summary.json": "src/ingestion/sample.py",14    "raw/exp_agreement.json": "scripts/06_exp_agreement.py", "raw/exp_cost.json": "scripts/07_exp_cost.py",15    "raw/aggregate_summary.json": "scripts/05_aggregate.py", "raw/api_usage.jsonl": "src/extraction/client.py",16    "raw/image_hosts.json": "ad hoc host census (research_log 2026-10-20)", "raw/robots_check.txt": "curl robots.txt census (research_log)",17}181920def sha(p: Path) -> str:21    h = hashlib.sha256()22    with open(p, "rb") as fh:23        for chunk in iter(lambda: fh.read(1 << 20), b""):24            h.update(chunk)25    return h.hexdigest()262728def main():29    items = []30    for p in sorted(R.rglob("*")):31        if p.is_dir() or p.name == "manifest.json" or ".DS_Store" in p.name:32            continue33        rel = str(p.relative_to(R))34        prod = PRODUCERS.get(rel)35        if prod is None:36            if rel.startswith("tables/exp1") and rel.startswith(("tables/exp1_", "tables/exp2", "tables/exp3", "tables/exp4", "tables/exp9", "tables/exp12", "tables/exp16")):37                prod = "scripts/06_exp_agreement.py"38            elif rel.startswith("tables/exp"):39                prod = "scripts/07_exp_cost.py" if any(rel.startswith(f"tables/exp{k}") for k in ("5", "6", "7", "10", "13", "14", "15")) else "scripts/06_exp_agreement.py"40            elif rel.startswith("tables/tex/"):41                prod = "src/visualization/tables.py"42            elif rel.startswith("figures/"):43                prod = "src/visualization/figures.py"44            elif rel.startswith("raw/batches/"):45                prod = "scripts/04_run_batches.py (Anthropic Message Batches API)"46        items.append({"path": rel, "bytes": p.stat().st_size, "sha256": sha(p), "producer": prod, "modified": time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(p.stat().st_mtime))})47    try:48        commit = subprocess.run(["git", "rev-parse", "HEAD"], cwd=ROOT, capture_output=True, text=True).stdout.strip()49    except Exception:50        commit = None51    manifest = {"generated": time.strftime("%Y-%m-%dT%H:%M:%S"), "git_commit": commit or "uncommitted",52                "schema_version": json.load(open(R / "raw" / "batches" / "run_meta.json"))["schema_version"],53                "prompt_version": json.load(open(R / "raw" / "batches" / "run_meta.json"))["prompt_version"],54                "n_items": len(items), "items": items}55    json.dump(manifest, open(R / "manifest.json", "w"), indent=1)56    print(len(items), "artefacts listed")575859if __name__ == "__main__":60    main()61