AI vs Human Capital: an ROI counterfactual simulation.
The world is pouring record capital into AI. This tool asks the counterfactual nobody actually models: what would the same money have returned if directed at human capital (education, health, and skills) instead? Built with public-grade sourcing discipline from day one, so every projected dollar traces to a citation.
This page is the build record for the AI vs Human Capital simulation. It covers the counterfactual question the tool models, the sourcing discipline behind every coefficient, the split Python/Next.js architecture, and the dense single-screen interface that renders it.
Project overview
OverviewA personal research tool, live at gauravg.dev/builds/ai-vs-humancap-sim. Built with the sourcing discipline of a public-facing product because the entire premise collapses the moment a single number is hand-waved.
A comparison everyone asserts
and almost no one models.
01 · The Question
“Imagine if we’d spent the AI buildout on schools instead” is a rhetorical move, not an argument, nobody attaches numbers, sources, or a confidence level to it. This tool turns the rhetorical into the falsifiable: a dual-track simulation that runs global AI investment against a counterfactual where the same resources are reallocated to education, health, and workforce skills, then resolves both to cumulative GDP contribution.
It is a personal research tool first. But it was built from day one with the discipline of something public-facing, because the entire point collapses the moment a single number is hand-waved.
Track A: AI investment
Global AI capex modeled forward from historical base year to 2035, resolved to cumulative GDP contribution.
Track B: Human capital
The same dollars reallocated to education, health, and skills, each with its own cited return coefficient.
Where they meet
Both tracks resolve to the same unit, cumulative GDP, so the counterfactual is a real comparison, not two incommensurate numbers.
Every number has a source,
or it doesn’t ship.
02 · Methodology
The projection engine is a deliberate blend of three input types, kept honest by a single ledger format:
Published research coefficients
Returns-to-schooling literature, WHO / World Bank health-ROI ratios. Every value traces to a citable source (e.g. Psacharopoulos & Patrinos, 2018).
Historical ROI multipliers
Coarser “dollar in → outcome out” ratios for broader coverage where rigorous published coefficients don’t exist.
Tunable hybrid sliders
User-adjustable assumptions for the sandbox’s “play with it” mode.
The non-negotiable rules
Provenance on every coefficient
Each carries confidence, source_citation, and
tier_applicability. Nothing without a real source can be marked
confidence: high, enforced by a test that fails CI on any empty
provenance field.
Confidence is a floor, not an average
The confidence of any result is the minimum across every coefficient in its effect chain. A chain is only as defensible as its weakest link, and the UI shows that floor, always.
Speculative numbers are segregated
Arbitrary-sector and speculative coefficients live in separate
speculative_*.yaml files, never silently mixed into the
defensible core ledger.
Python owns the truth.
The browser just renders it.
03 · Architecture
The system is split so each layer sits in the tool best suited to it. The
simulation engine is pure Python, zero I/O, fully
pytest-covered, with one core contract:
run_scenario(inputs, ledger) → ScenarioResult. Every projected point
carries the value, the coefficients that fed it, and an aggregate confidence (the floor
of its inputs), making the full effect chain auditable end to end.
A build step exports the ledger and contract fixtures to JSON. The frontend is a static Next.js export, no backend at runtime, with a client-side TypeScript port of the engine’s closed-form math. Python stays the single source of truth; the TS port is contract-tested against the Python fixtures, so the two can never silently drift.
Why a static site for a simulation? The engine’s pure-function core means a thin FastAPI wrapper can be added later for live, open-ended input without a rewrite. Until that’s actually needed, precomputing to static JSON removes an entire class of deployment and uptime concerns, the dividing line for every deferral is the same: defer enrichment and interactivity, never rigor.
A dense command center,
not a slideshow.
04 · The Interface
One screen, high information density by design, the user should learn a lot without navigating away.
Control rail + stat strip
Income-tier toggle (Global / Low / Lower-middle / Upper-middle / High), a year scrubber, and six compact cards: cumulative GDP per track, net delta @2035, confidence floor, reallocation %, return multiple.
Dual-track hero chart
AI-investment track (ochre) vs. human-capital counterfactual (sage), both resolving to cumulative GDP. Historical segment solid; projection hatched; a hard-anchored “you are here” marker separates actuals from projection.
Data-bound narrative
A templated sentence reads the live scenario: “Under a 20% reallocation from AI capex to education, the human-capital track overtakes the AI track in 2031; by 2035 it contributes an additional $1.4T, a 2.3× return at a ‘medium’ confidence floor.”
Impact Translator
The projected $ delta runs through a cited impact_equivalents.yaml
ledger to produce human-scale cards (“= 14,000 new primary schools,”
“= 38M children fully vaccinated”). A confidence-floor banner caps the
grid, a “medium”-floor scenario can never render
“high”-confidence equivalents.
Full tech stack.
05 · Stack| Layer | Technology | Details |
|---|---|---|
| Engine | Python 3.11 · PyYAML | Coefficient ledger · pure functions · pytest. |
| Contract | JSON export | Ledger + fixtures · schema-validated engine→frontend contract. |
| Frontend | Next.js 16 | App Router, static export · Tailwind CSS · visx charts. |
| Engine TS Port | TypeScript · Vitest | Client-side re-implementation, contract-tested against Python. |
| Quality Gate | 35 pytest + 119 Vitest | Ledger-validation test fails CI on empty provenance. |
| Deployment | Netlify | Static hosting · light-only by design. |