Skip to content

Count the same cash payments in household and SPM income - #10573

Merged
MaxGhenis merged 4 commits into
mainfrom
reconcile-household-spm-cash
Nov 2, 2026
Merged

MaxGhenis merged 4 commits into
mainfrom
reconcile-household-spm-cash

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

household_net_income and spm_unit_net_income keep separate lists of what they add, and the lists have drifted. A cash payment could reach one total and miss the other, and one reached neither. This PR makes the lists agree and adds a test that fails on the next drift.

Partly addresses #9919, which also covers partnership_s_corp_income, farm_rent_income and debt_relief. Those stay out of this PR and on an allow-list in the test.

What changed

Payment Household total SPM total Now
ak_permanent_fund_dividend Counted Missing from person market_income Both
nj_property_tax_relief (ANCHOR, Senior Freeze, Stay NJ) Counted Missing Both
ak_energy_relief Dropped when the 2024 block was added Counted Both
ca_capi Counted Missing Both
ma_eaedc Counted Missing Both
ca_la_expectant_parent_payment, ca_la_infant_supplement Counted Missing Both
co_denver_property_tax_relief Missing: nothing added household_local_benefits Missing Both
ny_drive_clean_rebate Missing Counted Both

household_benefits now adds household_local_benefits. The SPM list's four reform copies and the household list's two literal copies carry the same changes, and a test now guards them. That includes ak_energy_relief, which the ECPA and BOOST SPM copies lacked. #10226 tracks replacing those copies.

  • New Jersey's years: the household list now carries nj_property_tax_relief in every block, because the SPM list has no dates. The variable has no formula before 2026, so this changes earlier years only for a value someone enters.
  • Drive Clean: the rebate joins the household list because main's SPM list already counts it. It's a discount at sale, not cash, and ca_cvrp sets the precedent for counting one on both sides.
  • Left alone: the reform SPM copies count acp and ebb twice, because spm_unit_net_income adds them again, and they miss about 40 state SSI supplements plus wa_sfa and wa_rca. Both predate this PR, and Keep one spm_unit_benefits list so reforms that add a benefit stop dropping baseline programs #10226 is the place to fix them.

Child care stays out of this PR: #9503 handles the household side, and #10569 handles the SPM side.

Differences that stay, on purpose

The test names each with its reason:

  • acp and ebb: spm_unit_net_income adds them itself.
  • Head Start, health benefits and CSFP: Census section 4.3.1 doesn't list them as SPM noncash benefits.
  • ca_care, ca_fera, ca_la_ez_save and ca_riv_share_payment: bill discounts or credits, not payments.
  • Housing and energy assistance: the SPM values these with spm_unit_capped_housing_subsidy and spm_unit_energy_subsidy.

Invariants

test_household_spm_resource_parity.py states three:

  1. The two benefit lists differ only where a named reason says so, in every year from 2023 to 2026.
  2. A dollar of each listed cash payment adds a dollar to both resource totals (Hypothesis).
  3. For one person in each of 51 jurisdictions at any earnings, the two net incomes agree once you remove each measure's subtractions and the named differences (a differential test, with Hypothesis earnings).

On main, tests 1 and 2 fail, and test 3 fails for Alaska and New Jersey.

Test cost: YAML pins single payments, but these three assert a rule across every listed payment, year and jurisdiction, and test 3 compares two implementations. test_household_spm_resource_parity.py with test_aggregate_list_integrity.py took 110.98s at 2.22 GB peak on local macOS under load. I trimmed the parity file from about 233 simulations to about 140, which took it from 157.34s to 107.74s alone. These aren't Linux CI numbers, and I have no Linux peak memory figure. Both files land in the "Python tests / Full Suite - Rest" shards.

Alaska double count

Populace US carries reported dividends in miscellaneous_income: 11.05% of Alaska's person records have it, against 0.80% in Washington and 0.69% in Oregon, with spikes at past payment amounts. household_market_income already counts those people twice, and spm_unit_market_income will too after this PR. The list fix stays correct, and PolicyEngine/microcosm#1443 tracks the data fix, which lands in a data release.

Impact

These come from real 2026 microsimulations on Populace US (populace-us-2024-spm-20260909), one state's records at a time, comparing 469ad12 with this branch. No other state pays these programs.

State Household records Effective households Added to SPM resources Added to household resources SPM poverty Child SPM poverty Deep SPM poverty
Alaska 826 133 $752M $150M 10.00% to 9.06% 11.64%, no change 1.34%, no change
New Jersey 1,651 215 $1,509M $0 8.64% to 7.83% 13.86% to 11.39% 0.99%, no change
Massachusetts 1,522 255 $431M $0 19.63%, no change 22.33%, no change 4.64% to 4.24%
California 2,659 965 $205M $0 19.24%, no change 25.54%, no change 4.39%, no change
Colorado 1,164 145 $0 $0 no change no change no change
New York 2,166 431 $0 $0 no change no change no change

Across these states, SPM resources rise $2.90B and household resources rise $150M.

A national run on the same file and year, at 469ad12 and at this branch, gives the same totals and these rates:

National measure Main This branch Change
SPM poverty, all people 14.540% 14.515% -0.025 points
SPM poverty, children 18.825% 18.758% -0.067 points
SPM poverty, seniors 11.264% 11.263% -0.001 points
Deep SPM poverty 3.355% 3.347% -0.008 points
People in SPM poverty 50,263,334 50,177,331 -86,003
spm_unit_net_income $14,650.95B $14,653.85B +$2.90B
household_net_income $17,161.53B $17,161.68B +$0.15B
  • Sources of each dollar: Alaska's SPM line is the dividend and its household line is energy relief. New Jersey's is nj_property_tax_relief, Massachusetts's is ma_eaedc, and California's is ca_capi.
  • Zero on this file: co_denver_property_tax_relief, ny_drive_clean_rebate and both Los Angeles County payments are $0 in these runs. Their lists still change, so a household that receives them counts them in both totals.
  • Reading the rates: each state's file has few effective households, so a rate can move on a handful of records. These rows show what the change touches. Don't cite them as state poverty estimates.
  • Alaska overlap: miscellaneous_income totals $295M in Alaska, and some of it is the reported dividend that the section above describes.

axiom: n/a: household and SPM aggregate lists, no rule changes

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits November 1, 2026 16:53
household_net_income and spm_unit_net_income keep separate lists, and the
lists had drifted. SPM resources missed the Alaska Permanent Fund Dividend,
New Jersey property tax relief, Massachusetts EAEDC, California CAPI and two
Los Angeles County payments. Household benefits missed Alaska energy relief
from 2024, New York's Drive Clean rebate and everything in
household_local_benefits, which nothing added.

Partly addresses #9919, which covers the other market income sources.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A low-burden case keeps other benefits out of the household total, so the
expected value is the energy relief alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits November 2, 2026 02:20
Review found both reforms added it to their household lists alone, so SPM
resources fell .34 for an Alaska couple in 2024. The cash guard now covers
ak_energy_relief and ny_drive_clean_rebate on the SPM side, and the parity test
builds fewer simulations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The household list started in 2026 while the SPM list has no dates, so a value
entered for an earlier year reached one total only. Drop the exception the parity
test carried for it.

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

Copy link
Copy Markdown
Contributor Author

Merging at 0d4a7c3 under the repo's merge gates: every check passed on this head, the PR is mergeable, and no review asks for changes. The only block was the required approving review on a PR opened from Max's account.

Independent reviews, on Opus lanes because the Codex lanes are closed this week: earlier rounds asked for New Jersey's relief in every household block from 2023. 0d4a7c3 adds it, and the review of that head approved. Notes it left open all predate this PR: no household block for 2022, and the reform SPM copies (#10226).

Local runs on all five reconciliation PRs merged together: 585 YAML and 142 pytest cases passed, the parity and list-integrity tests included.

@MaxGhenis
MaxGhenis merged commit edbe17b into main Nov 2, 2026
34 checks passed
@MaxGhenis
MaxGhenis deleted the reconcile-household-spm-cash branch November 2, 2026 14:11
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