Built end-to-end by AI · directed only through prompts to Claude
A complete data-science project · World Bank panel · 1995–2024

Does growth have to cost the planet?

Every line of this project — the data pipeline, the models, the peer review, the stakeholder defense, and this page — was produced by an AI (Claude), directed only through prompts. The question below is the analysis; the project itself is the experiment: can AI carry a real, rigorous data-science study by itself?

217economies
30years of data
38indicators
5pipeline stages
63output artifacts
0lines hand-written
✦ THE EXPERIMENT

A human set the direction with plain-English prompts — "build the dataset," "review your own code as a skeptic," "defend this to stakeholders." Claude did everything else: wrote the code, fetched and audited the data, chose and built the model, caught its own bugs, and stress-tested its own conclusions.

The point isn't just the climate finding (though it's a good one). It's that a modern AI, given good direction, can produce analysis with the rigor, self-criticism, and honesty a senior data scientist would expect — including catching three of its own mistakes along the way.

TL;DR — FOR THE SKIMMERS
Plain English — for every reader Why this decision Technical note Bug caught
01 · OVERVIEW

Five stages, one honest answer

Everything below is reproducible: each stage is a runnable script that reads only the previous stage's outputs. Together they go from “nothing but an API” to a defended finding.

Build the panelFetch 38 indicators for every country from the World Bank API; clean, audit, engineer features.
build_panel.py
Explore itCoverage, distributions, relationships — learn what the data can and cannot support.
eda.py
Scan four topicsRun real panel regressions on four candidate questions; pick the strongest.
topic_models.py
Build the modelA modular econometric + ML pipeline around the chosen question.
ekc_pipeline/
Attack itStress-test every claim the way a skeptical stakeholder would — before they do.
stakeholder_stress_tests.py
Plain English

The central question is an old and famous one in economics: the Environmental Kuznets Curve (EKC) says that as countries get richer, pollution first rises, then peaks, then falls on its own — an upside-down U. If true, growth eventually cleans up after itself. This project tests whether that promise actually exists in 30 years of data for every country on Earth — and finds something more interesting instead.

02 · DATA CREATION & ENGINEERING

Building a world in a table

🧑‍💻
Prompt 1 — where it all started “I am working on creating world modeling data set for coding. Look over the two notebooks and make improvements. Focus on creating strong world data stats to model off for econometrics or other interesting facts.”

The foundation is a country-year panel: one row per country per year, one column per indicator — 38 indicators × 217 economies × 1995–2024. Everything comes from the World Bank API (the only source with genuinely global coverage), grouped into seven families: economy, governance, trade & investment, inequality, human capital, tech/AI proxies, and energy & pollution.

Why this decision

Why a panel and not a snapshot? A single year can only compare rich countries to poor ones. A panel lets you watch the same country change over time — and that distinction turns out to be the entire story of this project (see section 06).

The fetcher caches every API response and throttles between calls (firing ~35 requests back-to-back turned out to trip spurious errors from the API). Three indicator codes had silently died upstream and had to be hunted down: the governance codes were retired and re-published under a new prefix, the total-CO2 series was archived, and the clean-cooking code had changed. Data engineering is mostly this: the glamorous work of noticing what quietly broke.

Engineered features

On top of the raw indicators, the pipeline builds what models actually consume: log transforms (income and population are wildly skewed — Luxembourg vs. Burundi is a factor of 125), per-country growth rates and one-year lags (so “past” can predict “future” without cheating), a carbon-intensity ratio (CO₂ per $1,000 of GDP), and a time trend. One built-in integrity check: the growth rate computed from the data correlates 0.96 with the World Bank's own published growth series — the panel is internally consistent.

03 · THE DATA AUDIT

Trust, but verify

Before modeling anything, the data got interrogated — a dedicated quality pass that treats every suspicious number as guilty until proven innocent. Three kinds of problems surfaced — each with a fix that later analyses depend on:

🚫 Impossible values

Lithuania's fossil-fuel share reading −61%? Central African Republic's life expectancy dropping to 14.7 years for exactly one year, flanked by ~48 on both sides? Those are upstream artifacts, not history — 9 observations dropped, with a check first that other negative values (São Tomé's savings rate, Sierra Leone's 1997 investment) were real economics and must be kept.

🏝️ Micro-states

57 of 217 entities have under a million people. Micronesia reports 0.002 tonnes of CO₂ per person — implausible bookkeeping, not virtue. They stay in the dataset but carry a flag, and every model excludes them.

⚖️ The selection trap

Requiring complete data on all 38 indicators leaves just 75 countries — 40 high-income and exactly 1 low-income. Model that and you've built a rich-country model wearing a “world” costume. The honest modeling core: 120 countries, 2000–2022.

Plain English

Why the selection trap matters: imagine polling “the world” but only counting people who answer on the first ring. You'd learn a lot about people who sit near their phones — and nothing about the world. Requiring perfect data does the same thing: it silently selects rich countries, because they're the ones with complete statistics.

CO2 per capita distribution: heavy right skew with petrostate tail; log transform normalizes it
Know your target before you model it. Per-person CO₂ (left) is wildly skewed — most countries cluster near zero while a petrostate tail stretches to 45+ tonnes. The log transform (right) tames it. This one histogram drives three later decisions: log-scale modeling, petrostate robustness checks, and outlier-aware validation.
04 · EXPLORATORY ANALYSIS

What 30 years of world data actually says

Before choosing a model, you earn the right to model — by checking the data against things you already know are true.

The reality checks passed. Poorer countries grew faster than rich ones on average (the classic “convergence” pattern, slope −0.0047). Countries with better governance are richer (correlation 0.83 with government effectiveness — a textbook institutions result). And the biggest movers are exactly who history says they should be: Guyana +897% (offshore oil), China +749%, and Syria −40% (civil war).

+897%Guyana's GDP per person since 1995 — the fastest riser (offshore oil)
45.9 tQatar's CO₂ per person per year — the world's heaviest emitter
125×the income gap between the richest and poorest economies in the panel
2013the year the global internet-access divide peaked — it's been narrowing since
Beta convergence scatter: initial income vs subsequent growth, negative slope
Catch-up growth is real. Each dot is a country: horizontal = how rich it started, vertical = how fast it grew afterwards. The downward slope means poorer countries tended to grow faster — the data behaves the way economic history says it should.
GDP vs CO2, life expectancy, internet use, colored by region
Money buys emissions, lifespan, and bandwidth. Richer countries (further right) emit more CO₂, live longer, and are more online. Note pink Sub-Saharan Africa clustered lower-left in all three panels.

Just as important, the EDA mapped what the data cannot support: the governance indicators are structurally missing in 1997/1999/2001 (the survey was biennial back then — interpolating across that gap would fabricate data), and inequality (Gini) never covers more than half the world in any single year. Every later model respects these boundaries.

Bug caught

The original chart code picked its “snapshot year” by checking only 3 hardcoded indicators — and silently produced blank panels for 6 others whose data lags a year or two. The fix requires 90% of all indicators to have coverage before a year qualifies. Lesson: charts fail silently; coverage checks shouldn't.

05 · CHOOSING THE QUESTION

Four candidates, one winner

Rather than guess, all four candidates were run as real fixed-effects panel regressions first — then judged on both rigor and story:

Tech diffusion → growth

Does internet adoption (the best global AI-proxy that exists) predict growth? Answer: not significantly (p=0.46) once you control for the obvious. An honest null.

HONEST NULL

Pollution & the EKC

A quick grounding check found the famous inverted-U looks upside down in raw data — dominated by petrostates like Qatar (46 t CO₂/person). A textbook result that's fragile? That's a story.

CHOSEN ★

Conditional convergence

Poor countries grow faster even after controls (−0.051, p<0.001). Solid, but it's a well-told textbook tale.

SOLID

The digital divide

Internet access dispersion across countries widened until 2013, then began narrowing. Nice descriptive arc, limited depth.

DESCRIPTIVE
Bug caught

The first decoupling regression included both year fixed effects and a linear time trend — but year effects absorb anything that's the same for all countries in a year, which a time trend is. The leftover collinearity produced coefficients claiming emissions intensity was rising, flatly contradicting the raw data (0.30 → 0.16 t/$1000 over the sample). One line of thought — “does this number even match the data I can see?” — caught it.

06 · THE MODEL

Killing a textbook curve, carefully

Plain English

The one idea you need: there are two ways to ask “does getting richer eventually cut pollution?” You can compare different countries (Qatar vs. Ethiopia — rich ones just emit more), or you can watch the same country over 30 years as it grows. The first is called a cross-section; the second is what “fixed effects” unlock. The textbook EKC comes from the first kind of comparison. The truth requires the second.

The specification ladder

Five models, each one step stricter. Watch the curvature coefficient — the number that decides whether the inverted-U exists (a negative value means inverted-U; positive means the opposite):

Model (stricter ⭣)Comparison typeCurvatureVerdict
1 · Pooled quadratic (“textbook”)Across countries +1.324 ***U-shape — wrong direction!
2 · + country fixed effectsWithin countries −0.122 n.s.Curve vanishes
3 · + year fixed effectsWithin, minus global shocks −0.034 n.s.Still nothing
4 · + controls (energy mix, trade, urbanization…)Within, adjusted +0.478 ***Significantly convex
5 · + governance interactionWithin, adjusted +0.503 ***Same

No specification produces the inverted-U. The famous curve appears only when you compare rich countries to poor ones — it is a statement about who emits, not about what happens when a country grows.

CO2 vs income scatter colored by income group, pooled quadratic fit is U-shaped
The “textbook curve,” unmasked. Every country-year, colored by income group. The fitted curve is U-shaped (not inverted) — and the upper-right tail driving it is petrostates.
Variance decomposition: only 3.2% of CO2 variation is within-country
Why the textbook gets it wrong. Only 3.2% of the variation in per-person CO₂ is within-country change over time; 97% is differences between countries. Cross-sectional studies are almost entirely measuring “who,” not “what happens.”

Is there a turning point at all?

The EKC's promise hinges on a peak — an income level where emissions start falling. To test whether one exists, the analysis was re-run 500 times on random re-samples of countries (a “block bootstrap”). If the peak were real, it should show up again and again.

2.2%of 500 bootstrap runs found an interior turning point (0% with controls)
373 → 7.2collinearity (VIF) before → after centering the income polynomial — same coefficients, interpretable model
p = 0.001Mundlak test — the data formally demands fixed effects, not the easier random-effects shortcut
Bootstrap turning point distribution — barely any mass
500 attempts to find the peak. Only a handful of re-samples produced a turning point anywhere near real income levels, scattered from $40k to $420k. A peak that can't be pinned down isn't a peak — it's noise.
Technical note

Inference uses Driscoll-Kraay standard errors because the residual diagnostics demanded them: serial correlation (ρ = 0.76) and cross-sectional dependence (Pesaran CD = 4.78, p<0.001 — emission shocks like oil prices and recessions hit many countries at once, and error bars that ignore this are overconfident). Clustered SEs are reported side-by-side; every conclusion survives both. Robustness battery: petrostate exclusion, two alternative dependent variables, split time periods, alternative governance measure — the no-inverted-U result survives all of them.

Fitted CO2-income curves at low vs high regulatory quality
A subtle trap avoided: better-governed countries do sit on a lower emissions curve (shown here) — but that pattern lives between countries (p≈0.05) and vanishes within them (p=0.67). It's a fact about which countries are cleaner, not a lever that cleans a country. The report says exactly that, no more.
07 · THE REALITY CHECK

The day a “great” model lost to doing nothing

🧑‍💻
Prompt 5 — the peer review “Now as a senior data scientist on another team. Rigorously review the model code. Look for any potential improvements. Any errors that need to be addressed. Make sure we are testing things correctly and making the best most interesting model predictions possible.”

The pipeline validated its models on held-out years: train on 1996–2018, predict 2019–2024. First results looked spectacular — the structural model explained 97% of out-of-sample variation in emission levels, edging out a tuned gradient-boosting model. Time to celebrate?

Plain English

The weather-forecast test: predicting tomorrow's weather with “same as today” sounds dumb — and beats most forecasting systems. Emissions are like that: a country's CO₂ this year is almost exactly last year's (correlation 0.996). So the review added the dumbest possible baseline: carry each country's last known value forward, unchanged.

Task 1 — predict emission levelsRMSE
🪨 Naive “no change” baseline0.9010.977 WINNER
Structural econometric model1.0080.971
Tuned gradient boosting (ML)1.0970.966

The rock beat both models. That impressive 97% was persistence, not skill — and a validation section bragging about it would have been (unintentionally) lying. So the task was reframed around what is actually hard: predicting the change in emissions, where “no change” scores zero by construction.

Task 2 — predict emission changesRMSE
Naive “zero change” baseline0.645−0.005
Structural differenced model0.5810.184 WINNER
Gradient boosting (same features, tuned fairly)0.6060.115

On the hard task, the simple, theory-shaped model beat the flexible black box — with GDP change as the dominant driver. In a small, noisy dataset, structure is information.

Levels holdout: both models track the diagonal
Task 1 (levels): both models hug the diagonal — but so does the naive baseline. Beautiful ≠ skillful.
Changes holdout: structural model extracts more signal
Task 2 (changes): the real test. Points spread around zero; the structural model (left) captures more of the true movement than gradient boosting (right).
Bug caught — the worst one

Mid-review, the structural model briefly scored R² = −31 (catastrophically worse than guessing). Cause: a one-line data-alignment bug — reindexing the test matrix before adding the intercept column filled the intercept with zeros, silently deleting the model's baseline. Germany was being predicted at 0.25 tonnes instead of ~8. Fixed, the same model scored 0.971. Two lessons: investigate absurd numbers in both directions, and never trust a pipeline you haven't tried to break.

Technical note — fairness to the ML benchmark

The review also made the comparison fair before declaring a winner: the gradient-boosting model gets raw features (trees find curvature themselves — hand-feeding it the squared term had inflated its importance scores), hyperparameters tuned on an inner temporal fold (no peeking at test years), and importances measured by held-out permutation rather than the biased impurity method. Structure won anyway.

Permutation importance: income terms dominate, then renewables share and country effects
What actually predicts emissions? An independent cross-check from the ML side: shuffling each feature on held-out data and measuring how much predictions degrade. Income dominates, then the renewable-energy share and each country's own fixed identity — the same drivers the econometric model is built on. When two very different methods agree on what matters, that's evidence.
08 · THE RED TEAM

Attack your own work before the audience does

🧑‍💻
Prompt 6 — the stakeholder defense “Now lets do one final review as a senior data scientist. You are about to present it to stakeholders and you know that they will try to poke holes into your work. So prepare to address any concerns…”

Every claim got stress-tested with the toughest objection first. Click each one — the answers are quantified, not hand-waved:

Q1 “Your prediction win is just COVID, isn't it?”

Largely yes — and that's the finding. In calm years, annual emission changes are close to noise (R² ≈ 0.015). In 2020–21, when GDP moved violently, the model scored 0.267 while the naive baseline collapsed to −0.45. The model earns its keep exactly when growth moves — which is out-of-sample proof that the growth–emissions link is real and live. The per-year breakdown is published in the brief, including the thin post-2021 rows (n≤7), flagged before anyone else could.

Q2 “Same-year predictors aren't a real forecast.”

Correct — conceded with numbers. Using only lagged information, test R² drops to 0.01: next year's emission change is essentially unforecastable. The model is attribution (“given the growth that happened, how much did emissions move?”), and its GDP coefficient — the marginal coupling — is the quantity the final finding is built on. No crystal-ball claims anywhere.

Q3 “Petrostates create your U-shape.”

They amplify it; they don't create it. Dropping all 8 major oil-and-gas outliers (Qatar, Kuwait, UAE…), the pooled curvature stays positive and significant (+0.65, p<0.001). Still no inverted-U, with or without them.

Q4 “Intensity decoupling is a ratio trick — absolute emissions are what the atmosphere sees.”

Agreed, so absolute per-person emissions were tested directly: falling in high-income countries (−0.070 t/yr, p<0.001 — real absolute decline), but still rising in upper-middle-income countries (+0.038 t/yr, p<0.01). Absolute decoupling exists — so far as a rich-country phenomenon.

Q5 “Maybe you just lack power to detect the EKC within countries.”

Partly fair — only 3.2% of CO₂ variance is within-country, and that's flagged. But the within-country estimate isn't a shrug: with controls it's significantly convex (+0.48, p<0.001), the opposite shape — and the elasticity analysis extracts precise estimates from that same within-country variation. The data can speak; what it says is “no inverted-U.”

Q6 “Driscoll-Kraay standard errors with only ~29 years?”

Both standard-error families are published side by side. Point estimates are identical; every conclusion survives under country-clustered SEs too. The fixed-effects choice rests on the Mundlak test (p=0.001), not on the classic Hausman — which degenerates on this panel and is reported as degenerate rather than quietly swapped.

Q7 “A rising elasticity contradicts your own decoupling claim.”

No — they're the two different margins of one regression. The slope (how emissions respond to growth swings) rose; the intercept (the baseline drift when growth is zero) fell. Both moved, in opposite directions, both p<0.001. That tension isn't a contradiction; it's the headline.

Q8 “None of this is causal.”

Stated on every output. These are conditional associations with fixed effects and robust inference; no valid instrument exists here. The policy-relevant claim — that observed declines come from the drift, not from an income turning point — is about where the variation lives, and stands at the descriptive level at which it's made.

09 · THE FINDING

Two-speed decarbonization

The red team didn't just defend the work — it surfaced the best result of the project. Split every country's annual emission change into two parts: the part that moves with the economy, and the part that happens regardless of it.

Two-panel chart: coupling elasticity rising, autonomous drift falling
The star chart. Left: how tightly emissions follow growth (the “engine”) — it has not weakened; if anything it tightened, 0.32 → 0.72 (0.53 excluding COVID years). Right: what emissions do at zero growth (the “hill”) — swung from rising +0.84%/yr in the late '90s to falling −0.95%/yr today. Both shifts significant at p<0.001.
Plain English

Think of emissions as a car on a hill. The engine — economic growth — pushes emissions up as hard as it ever did (harder, actually). What changed is the hill: renewables, efficiency, and the shifting energy mix now slope the road downward, so the car drifts backwards ~1% a year whenever the engine idles — and in rich countries, ~2.7% a year. The Kuznets curve promised the engine itself would eventually go green. It hasn't. The road did.

Worked examples — what these numbers mean

−1.7%/yra rich country growing 2% today: 2 × 0.53 coupling − 2.7 drift ⇒ emissions fall ~1.7%/yr
+0.4%/yrthe same 2% growth in the late 1990s: 2 × 0.42 − 0.5 drift ⇒ emissions rose. Same growth, opposite outcome — the drift did that.
5.1% vs 1.4%“break-even” growth: rich countries can grow up to ~5%/yr with falling emissions; the world overall only ~1.4% — the global engine still outruns the global hill
PeriodCoupling (CO₂ % per 1% GDP growth)Drift at zero growth (%/yr)
1996–20050.32 ***+0.84
2006–20150.64 ***−0.18
2016–20240.72 *** (0.53 ex-COVID)−0.95 (−0.72 ex-COVID)
Carbon intensity falling by income group over time
The hill, drawn directly: CO₂ per $1,000 of GDP has fallen across every income group for two decades — fastest where incomes are highest (about −2%/yr in high and upper-middle income countries, statistically solid; not yet significant in low-income countries).

The thesis, in one paragraph

The Environmental Kuznets Curve — the promise that growth eventually cleans up after itself — is not in this data. Its inverted-U is a cross-sectional artifact that flips sign under within-country fixed effects and never yields an identifiable turning point. What is in the data is two-speed decarbonization: every 1% of GDP growth still brings ~0.5–0.7% more CO₂ — tighter coupling than in the 1990s — while the zero-growth baseline swung from +0.8%/yr to −1%/yr globally, and −2.7%/yr in rich countries. Decarbonization is happening around growth — through the energy mix — not through it. Waiting for an income turning point is not a climate strategy. The drift — technology and energy policy — is where the leverage is.

Stated limitations

Observational associations throughout — no instrument, no causal claims. Turning-point estimates are functional-form sensitive. Governance data has a structural 1997–2001 gap; post-2021 test coverage is thin. Falling carbon intensity is not sufficiency: absolute emissions still rise wherever growth outruns the drift (as it does in upper-middle-income countries). Results describe the ~150 larger economies; micro-states excluded.

10 · HOW IT WAS BUILT

100% AI-built — the human only prompted

Every artifact in this project — the data pipeline, the audit, four topic models, the EKC pipeline, the red team, the reports, and this page — was written by Claude. The human contribution was direction, not code: a handful of plain-English prompts, no manual editing of the analysis. What made the result trustworthy wasn't any single clever instruction — it was steering the AI through rotating adversarial roles, where each new role attacked the previous one's blind spots.

BuilderCreate the dataset and pipeline; optimize for coverage and features.
AuditorInterrogate your own data; assume every odd number is a bug until proven history.
Reviewer (another team)Attack the code and the methodology; found the naive-baseline embarrassment.
Red teamAttack the conclusions; found the COVID concentration — and the star result.

Three of the actual prompts, exactly as typed — one per act:

1
Act I — the kickoff “I am working on creating world modeling data set for coding. Look over the two notebooks and make improvements. Focus on creating strong world data stats to model off for econometrics or other interesting facts.”
2
Act II — the adversarial review “Now as a senior data scientist on another team. Rigorously review the model code. Look for any potential improvements. Any errors that need to be addressed. Make sure we are testing things correctly and making the best most interesting model predictions possible.”
3
Act III — the red team “Now lets do one final review as a senior data scientist. You are about to present it to stakeholders and you know that they will try to poke holes into your work. So prepare to address any concerns…”
🔒 THE SECRET SAUCE

The full prompt playbook — how the data-quality pass was framed, how the four topics were scoped and one selected, how the model build and the defense were sequenced — is deliberately not published. The method above (builder → auditor → reviewer → red team) is free to steal; the exact recipe stays in the kitchen. Adversarial process, not any single clever prompt, is what made the final answer trustworthy.

11 · REPRODUCE IT

Run the whole thing

All source code ships in this folder. Five scripts, in order — the first one rebuilds the raw panel (~17MB, not shipped) straight from the World Bank's public API, caching responses so re-runs are fast and polite to their servers:

pip install -r requirements.txt
cd notebooks
python build_panel.py                  # 1. fetch + clean + engineer  → output/panel_*.csv
python eda.py                          # 2. explore                   → output/eda/
python topic_models.py                 # 3. four topic regressions    → output/models/
python run_ekc_pipeline.py             # 4. the EKC pipeline          → output/ekc/
python stakeholder_stress_tests.py     # 5. red team + star result    → output/ekc/stress/

Key documents in this folder: FINAL_SUMMARY.md (the full technical narrative), EKC_REPORT.md (the model report), and STAKEHOLDER_BRIEF.md (the 8-question defense). Every number on this page traces to one of the 60+ published artifacts.

Home