Skip to content

Add a California breakdown of the labor-to-capital shift - #49

Merged
MaxGhenis merged 17 commits into
mainfrom
california-shift-current-bundle
Nov 9, 2026
Merged

MaxGhenis merged 17 commits into
mainfrom
california-shift-current-bundle

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

This adds a California breakdown of the 2026 labor-to-capital shift, a within-state variant of the shift, an accounting that counts health spending and TANF, and a rerun of all of it on the current PolicyEngine bundle: policyengine 6.16.0, policyengine-us 2.2.1 and the 2026-09-15 Microcosm national release. It leaves the site alone.

What it adds

  • analysis/california_shift.py runs the sweep's shift (labor_capital_shift._apply_shift) and fiscal accounting (fiscal.revenue_components, fiscal.state_revenue_components) on the installed bundle, with one fresh microsimulation per level. For California it records:
    • the employee SDI contribution (1.3% of wages, no cap), which sits outside the sweep's state measure (household_state_tax_before_refundable_credits holds state income tax and use tax only);
    • the change by within-state market-income group (bottom 50%, 50th to 90th percentile, 90th to 99th, top 1%), with the labor income each group gives up and the capital income it receives;
    • federal net revenue: the all-government change less every state's net change and less the state payroll and local taxes that the all-government total counts and no state's line holds. federal_net_published_definition_change_b keeps the site's definition (all governments less the states), and the drift table below uses it.
  • A second measure, the *_with_health_tanf fields, adds what the sweep's state measure leaves out. Household net income excludes health benefits (gov.simulation.include_health_benefits_in_net_income is false), so Medicaid, CHIP, the Medicare Savings Programs, ACA premium tax credits and state premium subsidies sit in no government's total, and tanf sits in household_benefits but in no state's line, so the sweep books it federal. The new fields charge each state:
    • its share of Medicaid, CHIP and Medicare Savings Program costs under federal matching rules (state_benefit_cost);
    • the whole cost of coverage it funds alone for people whose immigration status rules out federal matching, while CHIP's unborn-child coverage keeps its federal match;
    • its own health subsidies, from healthcare_benefit_value's list (for California, the Covered California premium subsidy);
    • the TANF change its line doesn't already hold, because the federal block grant is a fixed amount. The all-government total adds every program in healthcare_benefit_value and counts TANF once.
  • Medicaid at the baseline's cost per enrollee. policyengine-us spreads each state's fixed Medicaid spending over the enrollees in each simulation (medicaid_slcsp_state_denominator), so on its own a get_branch branch that adds enrollees cuts every enrollee's cost and keeps the state's total. Each shifted branch here takes the baseline's denominator, so a new enrollee adds cost.
  • A within-state variant (_apply_within_state_shift, --within-state-levels, default 10% and 50%). The sweep scales every positive capital-income dollar in the country by one factor, so a state whose share of national capital income exceeds its share of labor income gains market income from other states. The variant gives each state's freed labor income to that state's own capital holders, so each state's market income stays fixed.
  • analysis/california_summary.py prints a run against the published sweep: California with and without SDI, both measures, the federal split, groups, drift from the site, and California's gain split into income moving within the state and income moving between states.
  • analysis/california_chart.py draws California with and without SDI, against all other states unless --california-only drops that line, on either measure. A run defaults to health and TANF; the sweep holds only the study's measure.
  • analysis/outputs/california_shift_pe6.16.0.json, the rerun (state and group aggregates only).

Results (policyengine-us 2.2.1, 2026)

National allocation with health spending and TANF:

Shift California California with SDI All other states Federal All governments
10% +$2.10B −$0.15B −$16.90B −$175.0B −$194.8B
20% +$4.62B +$0.12B −$26.66B −$343.7B −$376.0B
50% +$15.36B +$4.10B −$93.33B −$863.5B −$969.9B
100% +$47.19B +$24.67B −$243.19B −$1,684.4B −$1,977.7B

California's parts at each level (the net also holds the use tax, whose change stays under $0.02B):

Shift State income tax Refundable credits Medi-Cal Premium subsidy CalWORKs SSP and other benefits Net
10% +$5.40B +$0.24B +$2.80B −$0.03B +$0.16B +$0.12B +$2.10B
20% +$11.73B +$0.58B +$5.61B +$0.04B +$0.44B +$0.44B +$4.62B
50% +$36.39B +$2.13B +$16.34B +$0.10B +$1.53B +$0.92B +$15.36B
100% +$101.29B −$0.13B +$45.69B −$0.08B +$4.94B +$3.70B +$47.19B

California comes out ahead at every level. Its top 1% hold 6.3% of the state's labor income and 39.8% of its capital income. At 10%, that group pays $7.92B more state income tax, the 90th to 99th percentile pays $2.30B more, and the 50th to 90th percentile pays $4.40B less. Medi-Cal, CalWORKs and the premium subsidy take $2.94B of the gain at 10%. SDI contributions fall $2.25B at 10%, so counting them turns the gain into −$0.15B.

This run moves $0.07B of federal Medi-Cal share to California at baseline, for people whose status rules out federal matching, and that amount changes by +$0.00B at 10% and +$0.65B at 100%. The line doesn't estimate California's actual state-only Medi-Cal cost. Microcosm treats anyone who reports Medicaid in the CPS as documented, and from 2026 policyengine-us's enrollment freeze keeps undocumented adults without existing coverage out at every income (is_ca_medicaid_immigration_status_eligible), so only the groups the freeze exempts can enter the line as incomes fall.

National allocation on the study's measure (no health or TANF):

Shift California California with SDI All other states Federal All governments
10% +$5.04B +$2.79B −$2.10B −$126.2B −$128.3B
20% +$10.71B +$6.21B +$1.39B −$243.6B −$241.7B
50% +$33.34B +$22.08B +$4.33B −$547.6B −$538.4B
100% +$97.73B +$75.21B +$86.95B −$743.0B −$655.6B

Within-state allocation:

Shift California California with SDI California with health and TANF All other states All other states with health and TANF States losing States losing with health and TANF
10% +$5.39B +$3.14B +$2.46B +$2.52B −$11.67B 18 44
50% +$35.17B +$23.91B +$17.19B +$27.83B −$69.47B 15 46

Under the national allocation, California's households give up $179.9B of labor income at 10% and receive $176.9B of capital income, so $3.1B of market income leaves the state. On the study's measure that costs California $0.35B of the $5.39B it collects when each state keeps its own income.

At every level the committed run agrees with itself: California's pipeline figure matches its household frame, the per-state sum matches the national state lines, and the within-state shift holds California's market income fixed.

Drift from the published sweep (policyengine 5.0.1, policyengine-us 1.764.6)

The study's measure, with federal on the site's definition:

Shift California, published → rerun All other states, published → rerun Federal (site's definition), published → rerun
10% +$5.00B → +$5.04B (+0.8%) −$2.10B → −$2.10B −$138.2B → −$131.3B (5.1% smaller)
20% +$10.61B → +$10.71B (+1.0%) +$1.40B → +$1.39B −$266.8B → −$253.9B (4.9% smaller)
50% +$32.39B → +$33.34B (+2.9%) +$4.30B → +$4.33B −$628.8B → −$576.0B (8.4% smaller)
100% +$96.81B → +$97.73B (+0.9%) +$86.66B → +$86.95B −$973.2B → −$840.3B (13.7% smaller)

The state figures barely move, and the federal loss shrinks by 5% to 14%. This PR neither diagnoses the federal drift nor refreshes the site's sweep.

Limits

  • The shift sets employment_income and self_employment_income on each branch, so anything that reads their *_before_lsr inputs sees pre-shift earnings. policyengine-us's default TANF earned-income list reads those inputs, as do Massachusetts's, Montana's and South Carolina's lists, so those states' TANF benefits respond to the added capital income and not to the wage cut, and can fall. The TANF, other-states and all-government lines and the study measure's federal lines miss the response to the wage cut. SNAP's gross self-employment income reads those inputs too. California's CalWORKs list reads the shifted variables, so California's line holds the response. The published sweep's shift has the same limit, and the site refresh should decide whether to move it.
  • If the state totals that medicaid_cost spreads count federally matched emergency care for people federal law otherwise excludes (42 USC 1396b(v)), moving their whole federal share overstates the state's cost by an amount this accounting can't measure.
  • or_healthier_oregon_cost has no enrollment test, and policyengine-us also enrolls Oregon's undocumented residents in Medicaid. This run drops the Healthier Oregon cost for those people, which affects Oregon only.
  • policyengine-us 2.2.1 counts Massachusetts's TAFDC in both tanf and household_state_benefits, and leaves five state premium subsidies out of household_health_benefits. This run charges TAFDC once and counts the five subsidies. On main, Count MA TAFDC once in household benefits policyengine-us#9478 and Register the remaining five state premium programs in household_health_benefits policyengine-us#9514 change both lists, and the code handles either version.

Invariants

Property-based (Hypothesis) and example tests in analysis/tests/test_california_shift.py:

  • _weighted_rank puts every household strictly inside (0, 1), and a household with a higher value always ranks higher.
  • The four groups partition California's households: for every field, the group changes add up to the state total, and the groups' labor and capital shares each add up to one.
  • Households outside California never move California's rows, and the change including SDI equals the net change plus the SDI change.
  • The within-state shift conserves every state's market income, and a state that frees labor income but holds no capital income makes the shift refuse.
  • Differential: with every record in one state, the within-state shift sets the same inputs as labor_capital_shift._apply_shift and as the closed-form national shift.
  • Differential: the summary's federal split plus the national state lines equals fiscal.net_fiscal_impact's total; the split leaves no residual, and its parts match policyengine-us's own aggregates.
  • All-government change = federal + every state + state payroll taxes + local taxes, on both measures; the state payroll and local taxes stay off the federal line.
  • Federal and state health shares add up to the costs they split; a dollar of health spending moved to a state leaves the federal line; state-only coverage never exceeds the federal share it comes from, and the unborn-child coverage keeps its federal match.
  • TANF that a state's line already holds gets charged once, and the all-government total counts it once.
  • On real policyengine-us, a get_branch branch keeps its state's Medicaid total fixed on its own, and at the baseline's denominator the total rises with enrollment while existing enrollees keep their cost.
  • The health classification check refuses any model whose health lists this accounting doesn't cover, with or without the five subsidies listed.
  • The chart's title follows the sign of California's change.

192 tests pass and 9 skip in a venv with matplotlib and Hypothesis and without PolicyEngine. With policyengine-us 2.2.1 installed, the nine tests that need it pass: test_california_shift.py runs 38 passed and 4 skipped (those four need matplotlib, which the first venv has), and all 14 tests in test_net_income_exclusions.py pass. Between the two venvs, every test runs.

🤖 Generated with Claude Code

analysis/california_shift.py runs the sweep's shift and fiscal accounting on
the installed PolicyEngine bundle, one fresh microsimulation per level, and
records what the sweep payload leaves out for California: its employee SDI
contribution, its change by within-state market-income group, and federal net
revenue (the all-government change less every state's net change).

analysis/california_chart.py draws California against all other states from
the site's sweep payload or from a run. The tests state the accounting's
invariants and check them with Hypothesis.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ai-inequality Ready Ready Preview Nov 9, 2026 9:25am UTC

Request Review

analysis/california_summary.py prints each level's California, other-state
and federal changes, the federal split into income tax, payroll, credits and
benefits, California's labor and capital flows and group rows, and the drift
from src/data/shiftSweepData.json. A differential test checks that the
federal split plus the states' lines equals fiscal.net_fiscal_impact's total.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sweep scales every positive capital-income dollar in the country by one
factor, so a state whose share of national capital income exceeds its share
of labor income gains market income from other states. The variant gives each
state's freed labor income to that state's own capital holders, so each
state's market income stays fixed and its revenue change reflects only the
movement of income within the state. california_shift runs it at 10% and 50%
by default (--within-state-levels), and california_summary splits
California's gain into the within-state part and the part from income moving
in from other states.

Tests: per-state conservation, positive-only scaling, refusal for a state
with labor but no capital, a hand-checked example, a closed-form match to the
national shift when every record sits in one state, a differential match to
labor_capital_shift._apply_shift (when policyengine_us is installed), and a
wiring test of run() with faked PolicyEngine calls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mulation year

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Output of `python -m analysis.california_shift` on policyengine 6.16.0
(policyengine-us 2.2.1, the 2026-09-15 Microcosm national release) for
2026: the national allocation at 10, 20, 50 and 100 percent and the
within-state allocation at 10 and 50 percent. Aggregates only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The all-other-states path depends on where new capital income lands, so
`--california-only` charts California with and without SDI alone. End
markers no longer clip at 0% and 100%, and the note says the shift holds
national income fixed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under the national allocation California's market income falls, so its
cross-state part comes from income leaving the state, not arriving.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review November 7, 2026 23:17
MaxGhenis and others added 2 commits November 8, 2026 14:09
…ns them

The note said the shift adds capital income "in proportion to existing
holdings"; `_apply_shift` scales the interest, dividends, capital gains
and rent people already receive. The subtitle's "state-funded benefits"
read as every state program, but California's net subtracts only its
refundable credits and the nine programs `household_state_benefits`
lists for it, none of them Medi-Cal or CalWORKs; the California-only
chart now says so. The x-axis label drops a reduced passive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e comment

"Selected" read as a reduced passive in the chart subtitle. The comment above
CALIFORNIA_MEASURE_NOTE now names fiscal.state_revenue_delta, which subtracts
the refundable credits and state benefits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sweep's state measure leaves out Medi-Cal and CalWORKs. Household net
income excludes health benefits (include_health_benefits_in_net_income is
false), so Medicaid, CHIP, the Medicare Savings Programs and ACA premium tax
credits sit in no government's total, and tanf sits in household_benefits but
in no state's line, so the sweep books CalWORKs as federal.

The new *_with_health_tanf fields charge each state its share of Medicaid,
CHIP and MSP costs under policyengine-us's federal matching rules
(state_benefit_cost), the whole cost of coverage it funds alone for people
whose immigration status rules out federal matching (policyengine-us books a
federal share for them), its own health subsidies and its whole TANF change,
since the federal TANF grant is fixed. The all-government total adds every
program in household_health_benefits, and federal is what the states leave.

The run refuses a model whose health lists differ from the ones classified
here, and checks that the federal and state shares add up to the costs.
Property tests cover conservation of health spending and the federal-plus-
states identity; differential tests check the immigration-status mirror and
the state-only move against policyengine-us 2.2.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e tax

household_state_tax_before_refundable_credits adds state income tax and use
tax, and California's income tax includes the 1% tax on taxable income above
$1 million (ca_mental_health_services_tax), whose revenue funds behavioral
health services rather than the General Fund. The California rows now report
both, so a reader can see how much of the change each fund receives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
_state_only_coverage moved every federal share policyengine-us books for
people whose immigration status rules out federal matching. That included
CHIP coverage through the From-Conception-to-End-of-Pregnancy option,
which policyengine-us gives pregnant people regardless of status
(is_chip_fcep_eligible_person) and which federal CHIP funds match, since
the unborn child is the beneficiary (42 CFR 457.10). In California every
CHIP enrollee in the model is an FCEP enrollee, as the state's separate
CHIP child limit is -inf.

_state_only_federal_share now leaves the CHIP share in place for
chip_category PREGNANT_FCEP. New tests: an example, a property test
(nothing moves for federally eligible people, never more than the booked
share, never the FCEP CHIP share), and a policyengine-us check that an
undocumented pregnant woman in Texas keeps her federal CHIP match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… off the federal line

This addresses the round-1 review of #49:

- Each shifted branch takes the baseline's medicaid_slcsp_state_denominator,
  so state Medicaid totals move with enrollment. Outside reform mode,
  policyengine-us spreads each state's spending over the branch's own
  enrollees, which holds every state's total fixed.
- Federal net revenue leaves out state payroll taxes (employee and employer)
  and local taxes, which the all-government total counts but no state line
  holds. federal_net_published_definition_change_b keeps the site's definition
  for the drift comparison. The summary's federal split adds the additional
  Medicare tax and FUTA and reports state payroll and local lines.
- A state whose line already holds its TANF program (Massachusetts's TAFDC in
  policyengine-us 2.2.1) pays it once, and the all-government total with
  health counts it once.
- Healthier Oregon's cost drops for people policyengine-us also enrolls in
  Medicaid.
- The five state premium subsidies that healthcare_benefit_value counts (CT,
  MA, NJ, VT, WA) join state health spending. The classification check reads
  healthcare_benefit_value and accepts household_health_benefits with or
  without them, as later policyengine-us releases list them there.
- CHIP's unborn-child carve-out keys on is_chip_fcep_eligible_person and
  chip_enrolled, and the docstring restates the emergency-Medicaid caveat.
- The chart's title follows the sign of California's change, its subtitle
  turns general when other states appear, and small ranges get decimal ticks.

Tests:
- On a four-household PolicyEngine dataset, a branch's Medicaid total stays
  fixed on its own and rises with enrollment at the baseline price.
- Property tests cover the federal split's completeness, the TANF charge, and
  the all-government identity with state payroll and local taxes.
- Each fix also has an example test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es TANF

- The output now holds the full rerun on policyengine 6.16.0 from c916f7f's
  code: Medicaid at the baseline price, the federal line without state payroll
  and local taxes, and the *_with_health_tanf fields. Its description field
  takes the new RUN_DESCRIPTION; no other field differs from the run.
- The module docstring, run description and summary now say that the shift sets
  employment_income and self_employment_income on each branch, so programs that
  read the *_before_lsr inputs (the default TANF earned-income list, and
  Massachusetts's, Montana's and South Carolina's) see pre-shift earnings.
  California's CalWORKs list reads the shifted variables.
- A new test ties the five unlisted state subsidies to the frame, using a
  Massachusetts adult on ConnectorCare. The Medicaid pricing test now asserts
  positive costs.
- Comments: wrap one long docstring line, and stop saying every state pays
  insurers, which Connecticut's documentation doesn't state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Those states' TANF responds to the added capital income and misses
only the wage cut, and the study measure's federal lines miss it too.
The run description in the output changes to match; no number moves.

The chart prints negatives as −$243B and moves the legend clear of the
lines when the values run further below zero than above. The state-only
Medi-Cal docstring says the line doesn't estimate California's actual
cost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The new Hypothesis test sets deadline=None like every other one in the
file, because its first example imports matplotlib when it runs alone.

The health list check now has tests for a list that also holds the five
state subsidies: a new program and a dropped program both refuse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis merged commit d32b35a into main Nov 9, 2026
4 checks passed
@MaxGhenis
MaxGhenis deleted the california-shift-current-bundle branch November 9, 2026 09:26

This branch was successfully deployed

1 active deployment
Preview — 83c83872 Deployed Nov 9, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant