1# Replication23Tested on macOS 27 (Apple Silicon, 18 cores), Python 3.14.4, TeX Live 2026, on 2026-10-27.45```bash6cd finance/agi-labor-capital-asset-valuation7make setup # pip install -r requirements.txt (pinned)8make test # pytest: static block (Restrepo P1–P6, KKT, accounting), dynamics (BGP, Jacobian, Newton), saved scenarios9make benchmark # scripts/10_benchmark.py, 11_regime_map.py -> fig01, fig02, tab01, results/data/benchmark.csv10make scenarios N=12 # scripts/21_run_all_scenarios.sh: 24 scenarios × 275 years, 12 in parallel (≈ 25 min per scenario, one core each)11make ha # heterogeneous-agent GE for baseline, no_ai, citizen_fund_20 (≈ 20–40 min each)12make figures tables # results/figures/fig03–fig10, results/tables/tab02–tab08 + numbers.tex (copied into paper/)13make paper # paper/main.pdf via latexmk14make slides # slides/main.pdf15make all # everything except data download16make data # optional: re-download the raw data (key-less endpoints; see data/README.md)17```1819## What each step produces and checks2021| Step | Output | Check |22|---|---|---|23| `test` | — | 10 static tests + 3 dynamic tests + one per saved scenario; a deliberately broken accounting fails `test_income_identity_fails_when_accounting_is_broken` |24| `benchmark` | `results/data/benchmark.csv`, `regime_map.csv`; `fig01_benchmark`, `fig02_regimes`; `tab01_benchmark.tex` | P1–P6 of Restrepo (2025) hold to 1e-6 |25| `scenarios` | `results/scenarios/<name>_{paths.npz,u.npy,params.json,meta.json}`; `logs/scenario_<name>.log` | `meta.json`: `converged`, `final_res` (< 1e-9), `horizon_check` (50 extra years: max deviation of r and log K over the first 225 years) |26| `ha` | `results/ha/<name>_ha.{npz,json}` | `hist`: max log excess demand for claims per iteration (< 1e-4 at convergence) |27| `figures`, `tables` | `results/figures/*.{pdf,png}`, `results/tables/*.tex`, `results/tables/numbers.tex` | every number in the paper is a macro from `numbers.tex` or a table fragment |2829Seeds: none are needed (deterministic solvers; non-stochastic simulation of the distribution).30Tolerances: static block ftol 1e-14 + KKT polish; transition 1e-9 (max residual); HA-GE 1e-4 (log excess demand).3132## Solver notes3334* The transition is solved **directly at λ = 1** from a partial-equilibrium guess (`TwoClassModel.smart_guess`);35 if the Newton does not converge the driver falls back to a homotopy in the shock size (λ = 0, 0.25, …, 1),36 re-calibrating the base point at each λ (`solve.py`).37* Each scenario uses one core; `scripts/21_run_all_scenarios.sh N` runs N at a time.38* Cluster: the same scripts run unchanged on any MacLustr node (`rsync` the directory, `make scenarios N=30`).3940## Reproducing the paper's numbers4142`paper/tables/numbers.tex` is generated by `scripts/50_tables.py`; the paper compiles only if it exists43(`make tables` copies it). Figures are copied from `results/figures/` to `paper/figures/`.44