Skip to content

Split household income inputs 50/50 between spouses in Microsim runner#842

Merged
PavelMakarchuk merged 4 commits into
mainfrom
fix-microsim-income-splitting
Apr 20, 2026
Merged

Split household income inputs 50/50 between spouses in Microsim runner#842
PavelMakarchuk merged 4 commits into
mainfrom
fix-microsim-income-splitting

Conversation

@PavelMakarchuk
Copy link
Copy Markdown
Collaborator

@PavelMakarchuk PavelMakarchuk commented Apr 19, 2026

Summary

Fixes #665. Fixes #838.

Splits household-aggregate TAXSIM income inputs between spouses in the PolicyEngineRunner Microsimulation path, matching the existing convention in input_mapper.py.

Allocation rules

Split 50/50 for MFJ, primary otherwise (6 types):

  • intrectaxable_interest_income
  • dividendsqualified_dividend_income
  • ltcglong_term_capital_gains
  • stcgshort_term_capital_gains
  • gssisocial_security_retirement
  • scorppartnership_s_corp_income

Age-aware split for pensions (pensionstaxable_private_pension_income):

  • Both spouses age 60+: split 50/50 (both qualify for per-person state pension exclusions)
  • Mixed-age or both under 60: all to primary (avoids losing per-person exclusion in states like GA, MD, NJ)

The 60 threshold is the lowest common age across state pension rules (DE starts at 60; GA 62; MD 65).

Validation

612 records across all 51 states × 12 scenarios:

Metric Result
Federal changed 0/612 (as expected)
Single filers changed 0/51 (no regression)
State improvements 22 records, +$5,853
State regressions vs TAXSIM 6 records, −$570 (all understood)
Net +$5,282

Remaining small regressions (all understood)

All 6 regressions share a pattern: PE gives a lower state tax than TAXSIM, because PE applies per-person exclusions more aggressively — i.e. more legally accurate, but further from the TAXSIM benchmark.

id state ages income Direction
41, 42 AR 45/45 ltcg/stcg PE further below TAXSIM; AR joint bracket behavior
44, 46 AR 70/70 pension PE exclusion uses both spouses; TAXSIM less aggressive
70 CO 70/70 pension PE larger refund
560 VA 70/70 pension PE further below TAXSIM

All regressions push PE to lower tax (favorable to taxpayer) and are small individually (max −$237). These aren't new bugs — they're PE correctly applying per-person state exclusions that TAXSIM applies less completely.

Example (#838 — DE elderly couple, $44k pension, 2 deps)

TaxAct confirms 50/50 split: $22,249 per spouse, each with $12,500 exclusion (total $25,000).

Before fix After fix TAXSIM TaxAct
State taxable income $40,000 $25,500 $27,500
State tax (siitax) $848 $276 $386 $0

Tests added

tests/test_spouse_income_splitting.py — 13 focused tests:

  • Each of the 6 non-pension income types: verify 50/50 split for MFJ
  • Single filers with household income: verify full amount stays on primary
  • Pension with both 60+: verify 50/50 split
  • Pension with mixed-age or both under 60: verify stays on primary
  • End-to-end DE elderly 20Kswages 44Kpensions 2depx #838 scenario: guards against regression of the DE pension bug

🤖 Generated with Claude Code

The PolicyEngineRunner Microsimulation path was assigning seven
household-level aggregate TAXSIM inputs (intrec, dividends, ltcg, stcg,
pensions, gssi, scorp) entirely to the primary filer. The single-record
input_mapper.py path already split these 50/50 between spouses for MFJ
returns.

The misallocation was invisible for federal calculations (combined AGI
is unchanged) and for most states (joint filing consolidates), but
produced incorrect results for states with per-person rules — e.g.
Delaware's age 60+ exclusion and pension exclusion are per-spouse caps.

Verified against TAXSIM and TaxAct for the DE elderly pension case
(#838): PE Microsim siitax went from $848 to $276 (TAXSIM: $386,
TaxAct: $0), bringing PE substantially closer to both reference tools.

Closes #665. Closes #838.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 19, 2026

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

Project Deployment Actions Updated (UTC)
policyengine-taxsim Ready Ready Preview, Comment Apr 20, 2026 1:27pm

Request Review

Pensions now split 50/50 only when both spouses are at least 60 (the
lowest common threshold across state pension exclusions such as DE).
For mixed-age couples (one spouse 60+, one under 60), pensions stay
with the primary filer so state per-person elderly exclusions still
apply to the qualifying spouse.

Validated against TAXSIM over 612 records (51 states × 12 scenarios).
Net improvement versus before-fix: +$5,282 across 22 improvements
vs -$570 across 6 small residual regressions. Mixed-age pension
regressions eliminated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tests cover:
- MFJ: six household-aggregate income types split 50/50 between spouses
- Single: full amount stays on primary (no spouse entity)
- Pension: split 50/50 when both spouses 60+, on primary otherwise
- Pension: stays on primary for mixed-age couples (mentions #838)
- End-to-end: DE elderly pension case from #838 stays under $500 siitax

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@PavelMakarchuk PavelMakarchuk marked this pull request as ready for review April 20, 2026 14:24
@PavelMakarchuk PavelMakarchuk merged commit 2381e9b into main Apr 20, 2026
12 checks passed
@PavelMakarchuk PavelMakarchuk deleted the fix-microsim-income-splitting branch April 20, 2026 14:24
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.

DE elderly 20Kswages 44Kpensions 2depx Microsimulation runner doesn't split investment income between spouses

1 participant