Chapter 5

Proof of concept

3,229 words · 17 min · draft, July 2026


For a few years around the turn of the decade, open-source policy modeling went through a quiet boom — and I spent most of it unable to answer a simple question.

The boom was real. In October 2019, UKMOD became the first freely available tax-benefit microsimulation model of the United Kingdom ,[1] built on EUROMOD's UK component, funded by the Nuffield Foundation, open to anyone who asked. Britain had good models long before that; you just couldn't touch them. The Institute for Fiscal Studies had run TAXBEN since 1983, HM Treasury had IGOTM, and the Department for Work and Pensions had its Policy Simulation Model, all behind institutional doors. Then COVID hit, and demand for policy analysis spiked because the rules changed weekly — the CARES Act, expanded unemployment insurance, recovery rebates. NBER updated TAXSIM for the pandemic provisions. Tax-Calculator shipped a pandemic release, version 3.2.1, in August 2021 .[2] In December 2020, EUROMOD — the backbone of European tax-benefit modeling for two decades [3] — went fully open source, and the European Commission's Joint Research Centre took it over the following month. That same December, the International Microsimulation Association convened a conference devoted entirely to pandemic policy responses, and the Policy Simulation Library kept adding models to its open-source catalog.

Almost none of it was usable by anyone who could not write code. I knew, because I had spent the boom running the UBI Center — the open-source research shop I started in 2019 when no public tool could say with any specificity what a basic income would cost or whom it would help [4] — on exactly these tools: Tax-Calculator, custom Python, Census survey data. Two lessons kept arriving. The first was fragmentation. Tax-Calculator handled federal income tax but ignored benefits; TAXSIM handled state taxes but ran in batches; nothing captured the full tax-benefit interaction that decides whether a basic income is progressive, regressive, or poverty-reducing. Fund a basic income by tapering an existing benefit and you can lift some families while stranding others at a cliff — and no available tool showed both effects at once. The second lesson was the access gap. The audience for policy analysis was far larger than the audience that could run the tools. Our analyses lived in Jupyter notebooks, which meant a reader could not change a parameter, swap in their own household, or model their own group's variant. The code was public; the ability to use it was not — the wall chapter 4 ended on, met again from inside the notebook.

Putting the model in a browser

By late 2020, Nikhil Woodruff and I had a working microsimulation model of the UK tax and benefit system, built at the UBI Center. Nikhil — the college student chapter 4 introduced — had led the build; he was a University College London undergraduate reading mathematics and computer science, and the stronger engineer of the two of us. The model, OpenFisca UK, could calculate taxes, simulate benefits, and estimate what a reform would do. It could do all of that only inside Python scripts that a programmer could run, which made it one more instance of the pattern we saw everywhere we looked: TAXSIM wanted batch files, Tax-Calculator wanted Python, UKMOD was built for academics, TAXBEN was proprietary. Serious tools, locked behind technical barriers. So we set the goal that defined the next five years: put the full power of microsimulation in a web browser, so that anyone could design a reform, see what it costs and who it helps, and check what it does to their own household, without writing a line of code.

We called it PolicyEngine.

The architecture had three layers. At the bottom, the model: OpenFisca UK running in Python on cloud servers, returning exact taxes and benefits before and after any change. In the middle, an API wrapping the model in HTTP endpoints, so the interface and the rules could evolve independently. On top, a React web application that turned a user's answers — income sources, number of children, housing costs — and their reform choices — sliders, toggles — into API calls, and drew the results. The load-bearing decision was that the model had to be usable without the interface. The API was the product; the web app was merely its first consumer. At the time this looked like overengineering. It later meant that any researcher, journalist, or piece of software could call the same engine that ran the website.

Nikhil handled most of the engineering — API design, the front end, state management — while I worked the policy logic: which parameters to expose, how to present results, what comparisons mattered. Exposure was its own design problem. A tax-benefit system has thousands of parameters; show them all and a user drowns, hide too many and the tool is gutted. We exposed a curated set of the frequently debated ones — income tax rates, benefit levels, credit amounts — plus a path to reach any parameter in the model, and we staged the output: headline numbers first, net cost and poverty change, then breakdowns by income decile, household type, and region.

PolicyEngine UK went live on September 1, 2021 .[5] A user could raise income tax, increase child benefits, or introduce a carbon dividend, and read off the cost to the Treasury, the change in poverty, the shift in inequality, and the effect on their own household. Within weeks, advocacy groups were using it to design proposals. When the Chancellor's Autumn Budget changed Universal Credit that October, we published distributional analysis within a day [6] — and learned what it feels like when a website goes viral faster than two people can fix the bugs the traffic exposes. We weren't a media operation. We were two people with a model, fielding interview requests with one hand and patching the code the traffic had broken with the other.

That October we spun PolicyEngine out of the UBI Center as its own nonprofit, and the mission statement shifted from "make everyone a policymaker" to "help people understand and change public policy." Incorporating as a 501(c)(3) was a trust decision as much as a legal one. The code stayed open for anyone to inspect, and the organization had no shareholders whose interests could bend a result — which is what lets groups who agree on nothing else trust the same engine. On paper we were now an institution. In practice we remained two people plus a rotating cast of volunteers and interns.

Crossing the Atlantic

PolicyEngine US launched in March 2022 ,[7] and the United States turned out to be a different shape of problem. The UK has one national tax system — Scotland sets its own income tax rates — and Universal Credit had folded most means-tested support into a single program. The US has fifty state income tax codes layered over a complicated federal one, and benefits scattered across agencies: SNAP at the Department of Agriculture, SSI at the Social Security Administration, Medicaid at Health and Human Services, housing vouchers at HUD, childcare subsidies at the states. Each program defines income its own way, counts the household its own way, and sets eligibility its own way. Modeling the US wasn't harder than modeling the UK by some constant factor; the complexity grew multiplicatively rather than additively.

We started with what we could model — federal income and payroll taxes, SNAP, the EITC — and shipped the household calculator first. In July 2022 we added population-level impacts, computed on the Current Population Survey, the same microdata foundation behind official government estimates .[7] State coverage came one state at a time. Some states piggyback on federal adjusted gross income and fall into place almost automatically once the federal model exists. Others are miniature ecosystems — New York alone has multiple income tax schedules, city taxes, and supplemental credits — and encoding one rarely transferred to the next. By the end of 2022 we had modeled six states. Forty-four remained. The constraint was structural: we wanted comprehensive, always-current coverage, and we had a small volunteer team encoding rules on weekends — a contributor might encode Oregon's working-family credit only to find the legislature had amended the eligibility rules mid-session, with no updated documentation to encode from. Anyone could submit a pull request adding a state, and we reviewed for accuracy and code quality; the model worked wherever a local expert volunteered and failed wherever none did. That is what open cost: the map filled in where the enthusiasm was, not where the need was.

What open bought

On September 23, 2022, Chancellor Kwasi Kwarteng stood up in the Commons and announced the Truss government's mini-budget: abolish the 45p additional rate of income tax, cut the basic rate, reverse a National Insurance rise, all in the name of growth. We published household-level distributional analysis the same day .[8] The numbers said the package was overwhelmingly a high-earner event: the top income decile would gain about £2,738 a year, or 2.5 percent of net income; the bottom decile, £45, or 0.4 percent. Ours was among the only independent estimates available in those first days, and the post noted that its figures broadly resembled the IFS's and the Resolution Foundation's. Media outlets cited it. Within weeks the government reversed the 45p abolition, and within a month the prime minister had resigned. I don't claim a chart did any of that — markets and mortgage rates did the heavy lifting — but for the first time, anyone arguing about the mini-budget in public could point at an open model instead of waiting for an institution.

Quieter uses accumulated underneath the news cycle. A congressional aide could take a child tax credit proposal, discover that phasing the credit in over the first few thousand dollars of earnings missed the poorest households entirely, reshape the legislative language, and only then request a formal CBO score — arriving with a refined proposal instead of leading with "what does this cost?" That did not replace the official process; it changed the quality of the questions arriving at it. Advocacy groups and academic researchers who had relied on government estimates or expensive consultants ran their own simulations ;[7] UBI Lab Northern Ireland modeled a recovery basic income without commissioning a think tank. And developers began building on the API rather than the website — the Fund for Guaranteed Income wired PolicyEngine into a tool that showed cash-pilot participants how their other benefits would change as their income rose. We had set out to build a product and were turning into infrastructure.

Whose bug is it?

Open source means anyone can inspect the code. Inspection is not correctness. From the beginning we invested in checking outputs against official calculators and published statistics, and each model carried a test suite comparing its answers to official calculations across hundreds of household scenarios. Every discrepancy raised the same three-way question: is the bug in our code, in the official calculator, or in our reading of an ambiguous rule?

Sometimes the answer was plainly the first. An outside contributor comparing results against IRS tables caught a transposed digit in a phase-out rate — 21.60 percent entered where the EITC's two-child schedule specifies 21.06 [9] to verify. Sometimes there was no clean answer at all: when a regulation says income is figured "net of applicable deductions," different official sources sometimes disagree about which deductions apply. We kept a running log of those cases, and the log was itself a finding — the tax-benefit system is complex enough that the agencies administering it sometimes disagree about its own rules.

One limitation would not yield to more tests, because it wasn't a bug. Our aggregate revenue estimates ran below official statistics, for a reason built into the inputs: we computed on household survey data, governments compute on administrative tax records, and surveys under-sample the very rich — the CPS might hold a few hundred households above $500,000 where the IRS has vastly more. High earners generate a disproportionate share of revenue, so the sampling gap cascades into the totals. We learned to lead with relative impacts — the change a reform makes against current law — because the survey's error moves baseline and reform alike and largely cancels. The next chapter puts a number on that gap and on what it does and does not contaminate; here it enters as the first crack of light between the rules, which were exact, and the data, which was not.

From tool to infrastructure

In 2024 we finally closed the map: income tax models for all fifty states and the District of Columbia, the work of more than a hundred open-source contributors .[10] Flat-tax states with a handful of credits took days; New York, California, and Hawaii took weeks of iterative debugging each. Then the institutions arrived. On August 15, 2025, the National Science Foundation awarded PolicyEngine a Pathways to Enable Open-Source Ecosystems Phase I grant — award #2518372 to the PSL Foundation, $299,974 [11][12] — a bet that this should become permanent public plumbing rather than a project.

In September 2025 we signed a memorandum of understanding with the National Bureau of Economic Research to build an open-source emulator of TAXSIM, the calculator that had powered academic tax research since the 1970s; more than 1,200 published papers had relied on it .[13] Daniel Feenberg, TAXSIM's creator, joined our advisory board and served as external mentor under the NSF grant. The emulator's purpose was partly preservation — researchers keep TAXSIM's capabilities whatever happens to any one institution — and partly something more interesting: a framework in which several independently developed models cross-check one another.

A month later we signed a second MOU, with the Federal Reserve Bank of Atlanta, whose Policy Rules Database, built with the National Center for Children in Poverty, covers the benefit side TAXSIM never touched: SNAP, Medicaid, housing vouchers, childcare subsidies. The database powers the Atlanta Fed's CLIFF tools, which Colorado's Workforce Development Council and New Mexico's Caregivers Coalition use to help families see how earning more would affect their benefits. With three independently developed models — PolicyEngine, TAXSIM, the Policy Rules Database — agreement builds trust and divergence isolates where a discrepancy originates: it stops being "the models disagree" and becomes a specific question about a specific rule, sometimes a bug and sometimes a genuine dispute about what the policy means. PolicyEngine's role in that arrangement was the integrator's: cross-checking across Python and R, across taxes and benefits, across academic and government implementations of the same law.

And then came the UK.

On December 17, 2024, HM Treasury published an Algorithmic Transparency Record disclosing that it had piloted PolicyEngine UK as a possible supplement to IGOTM — the closed model that had produced the government's policy estimates for decades .[14] A pilot, to be precise about it: the record states the model is not currently deployed, describes an evaluation rather than an adoption, and leaves further evaluation pending. The evaluation's headline was that National Insurance calculations proved very accurate, with "almost 60% of datapoints falling within 0.5% of one another." Read that carefully, because it is easy to over-read: it measures agreement between two models, not a grade against reality. Two implementations of the same statute should agree, and where they don't, one of them has a bug or the law has an ambiguity. That is exactly what made the income tax comparison, in the record's words, less promising: the two systems had trouble even identifying which variables corresponded, with edge cases everywhere housing benefit met legacy benefits or a household crossed into Scottish provisions. The hard part of checking a model against a government model is definitional: two systems can define "income," aggregate units, and handle household composition in quietly incompatible ways. The record also singled out the machine-learning approach we had built for survey error — combining multiple years of the Family Resources Survey, filling in missing incomes with random forests, reweighting households by gradient descent — as the thing under evaluation inside government.

There is a disclosure that belongs beside this passage. From the summer of 2025, Nikhil served roughly six months as an Innovation Fellow with 10DS, the Downing Street data-science team, building a package called 10ds-microsim on top of PolicyEngine — work described, in PolicyEngine's account of the fellowship, as "intensively validated against external projections and official forecasts" .[15] As of this writing he serves in the UK government at No 10 to verify. When this chapter says British institutions evaluated tools he helped build, weigh it knowing where he now sits — and knowing the shape of the arc, which I have given up trying to improve on: the co-founder I had recruited off a subreddit, now working inside the machinery an outside tool had helped pry open.

Government microsimulation had been closed by default — proprietary code, restricted data, results no outsider could reproduce. Nothing about a pilot overturns that. But an outside model good enough for the Treasury to test against its own machinery weakens the argument that the machinery must stay closed, one evaluation at a time. In 2019 I could not find a tool to answer a basic question about a basic income. Five years later, HM Treasury was piloting one we had built.

Three clocks

By late 2025 the tool was real and unfinished. Household calculations were sharp; unusual cases still exposed gaps; revenue totals still ran below official statistics. And building it had produced the distinction that the rest of this book is organized around, one we did not design so much as keep tripping over. A policy question that looks like one question is really three, and they come apart the moment you try to compute them. What does the law say — the exact tax owed and benefit due for this household, in this place, in this year? Who are the people — how many households look like that one, and how do they sum to a country? What will happen — who changes their behavior, how the economy moves, what next year looks like?

Each is answerable, and each is checkable — but against a different kind of truth, on a different clock. An encoded rule is right or wrong against the statute, and against another calculator built from the same statute: provable to the dollar, today. A population estimate is right or wrong against surveys and administrative totals: calibrated, with the residual measured, today. A prediction is right or wrong only when the future arrives and the official number lands: committed now, graded later. We ran all three inside one engine and one organization, because that is how the tool had grown. But the seams were visible if you looked. The revenue gap was a data problem, not a rules problem. The rules stayed exact precisely where the data was uncertain. The behavioral responses belonged to neither. Three concerns, three verification loops, three different clocks.

What we had built as one thing was, underneath, three things — each buildable, checkable, and trustworthy on its own terms. Pulling them apart is a later chapter's story. First the engine has to show what it can do: for a single household, and then for a country.

Society in silico · draft in public · source