"""Assemble the named deliverables of the mandate (§24) from the repository state.""" import os, sys, csv, shutil, subprocess, zipfile, json, datetime REPO = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")); REL = os.path.join(REPO, "release") def main(): shutil.copy(os.path.join(REPO, "paper", "main.pdf"), os.path.join(REL, "WP29_Autonomous_Research_Claude_Code_Boucher.pdf")) shutil.copy(os.path.join(REPO, "results", "analysis_data", "runs.csv"), os.path.join(REL, "WP29_Experiment_Results.csv")) # human interventions + costs rows = list(csv.DictReader(open(os.path.join(REPO, "reports", "interventions.csv")))) acc = open(os.path.join(REPO, "reports", "experiment_accounting.md")).read() with open(os.path.join(REL, "WP29_Human_Interventions_and_Costs.csv"), "w", newline="") as fh: w = csv.writer(fh); w.writerow(["record_type", "id", "timestamp_utc", "actor_or_split", "category", "description", "duration_or_cost", "measurement_basis"]) for r in rows: w.writerow(["human_intervention", r["intervention_id"], r["timestamp_utc"], r["actor"], r["category"], r["description"], r["duration_minutes"], r["measurement_basis"]]) import pandas as pd s = pd.read_csv(os.path.join(REPO, "results", "analysis_data", "sessions.csv")); rr = pd.read_csv(os.path.join(REPO, "results", "analysis_data", "runs.csv")) for sp, d in rr.groupby("split"): w.writerow(["inference_cost", sp, "", sp, "inference", f"{len(d)} runs, {int(s.run_id.isin(d.run_id).sum())} sessions", f"{s[s.run_id.isin(d.run_id)].session_cost_usd.sum():.2f} USD", "client list-price estimate (total_cost_usd)"]) be = json.load(open(os.path.join(REPO, "reports", "builder_effort.json"))) for k, v in be["subagents"].items(): w.writerow(["builder_subsession", k, "", "builder", "delegated work", k, f"{v['tokens']} tokens / {v['duration_min']:.0f} min", "client task notification"]) for k, v in be["builder"].items(): w.writerow(["builder_session", k, "", "builder", "builder work", k, v["wall"], v["basis"]]) # visual evidence appendix (standalone PDF of the gallery) tex = r"""\documentclass[11pt]{article}\usepackage[margin=0.8in]{geometry}\usepackage{graphicx}\usepackage{hyperref}\usepackage[T1]{fontenc}\usepackage[utf8]{inputenc} \DeclareUnicodeCharacter{2192}{$\rightarrow$}\DeclareUnicodeCharacter{2014}{---}\DeclareUnicodeCharacter{2013}{--} \begin{document}\title{WP29 --- Visual Evidence Appendix}\author{Simon-Pierre Boucher, UQO}\date{October 2026}\maketitle \noindent Companion to UQO Working Paper 29. All captures are authentic (native \texttt{screencapture}); modes, hashes and selection rules follow the screenshot manifest. Capture failures are listed without images. \input{appendices/gallery}\end{document}""" vt = os.path.join(REPO, "paper", "visual_appendix.tex"); open(vt, "w").write(tex) r = subprocess.run(["pdflatex", "-interaction=nonstopmode", "visual_appendix.tex"], cwd=os.path.join(REPO, "paper"), capture_output=True, text=True) vp = os.path.join(REPO, "paper", "visual_appendix.pdf") if os.path.exists(vp): shutil.copy(vp, os.path.join(REL, "WP29_Visual_Evidence_Appendix.pdf")) else: print("visual appendix failed", r.stdout[-500:]) # method + implementation zip z = zipfile.ZipFile(os.path.join(REL, "WP29_Method_and_Implementation.zip"), "w", zipfile.ZIP_DEFLATED) for d in ["src", "protocol", "configs", "evaluators", "tests", "analysis", "tasks", "README.md", "Makefile", "pyproject.toml", "CLAUDE.md", "reports"]: p = os.path.join(REPO, d) if os.path.isfile(p): z.write(p, d) else: for root, _, fs in os.walk(p): for f in fs: if "__pycache__" in root or f.endswith(".pyc"): continue q = os.path.join(root, f); z.write(q, os.path.relpath(q, REPO)) z.close() # hidden oracles for reviewers only (restricted, not committed) os.makedirs(os.path.join(REL, "restricted"), exist_ok=True) zo = zipfile.ZipFile(os.path.join(REL, "restricted", "WP29_Oracles.zip"), "w", zipfile.ZIP_DEFLATED) orc = os.path.expanduser("~/wp29-oracles") for root, _, fs in os.walk(orc): for f in fs: if "__pycache__" in root or f.endswith(".pyc"): continue q = os.path.join(root, f); zo.write(q, os.path.relpath(q, os.path.dirname(orc))) zo.close() # final review (concatenate the three sub-session reviews + builder response) parts = ["# WP29 — Final review record", "", f"Assembled {datetime.datetime.now(datetime.timezone.utc).isoformat(timespec='seconds')}. Reviewers are Claude Code sub-sessions (claude-fable-5-1) of the same client family as the builder; no human review had occurred at build time. The builder's responses are in `reports/final_review.md`.", ""] for f in ["review_systems_isolation.md", "review_statistics_evaluators.md", "review_manuscript.md", "final_review.md"]: p = os.path.join(REPO, "reports", f) if os.path.exists(p): parts += [f"\n\n---\n\n\n", open(p).read()] open(os.path.join(REL, "WP29_Final_Review.md"), "w").write("\n".join(parts)) print("release assembled:", sorted(os.listdir(REL))) if __name__ == "__main__": main()