Skip to content

Make state income taxes independent of which spouse is labelled head - #9981

Open
MaxGhenis wants to merge 5 commits into
mainfrom
fix-state-head-spouse-swap
Open

MaxGhenis wants to merge 5 commits into
mainfrom
fix-state-head-spouse-swap

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Which spouse a married couple lists first is a convention of the form, but swapping is_tax_unit_head and is_tax_unit_spouse (with every other input kept) changed state income tax in Arkansas, Iowa, Mississippi, Montana and Oklahoma. The review of #9617 found this for 12,944 dataset units that only exchange head and spouse: federal outcomes unchanged, state tax −$8.931M (2025) and −$8.551M (2026).

This PR makes those taxes independent of the label:

State Formula on main Change
Arkansas ar_agi_indiv put dependents' net income on the head's column (Filing Status 4) Spouse with the greater own net income takes it; an exact tie splits it
Delaware de_agi_indiv, same pattern (Filing Status 4) Same rule. No observed effect on main (see below)
Iowa (≤2022) ia_net_income, same pattern (status 3) Same rule
Mississippi ms_agi put dependents' positive income on the head's column (combined return; the "joint" path is per column too) Same rule
Montana mt_agi_indiv, same pattern (Filing Status 2a, ≤2023); and both joint itemized deduction variables counted only the head's mortgage and investment interest (all years) Same rule for mt_agi_indiv; joint itemized deductions add every member's interest, as the federal interest_deduction does
Oklahoma ok_ptc accepted a disabled head but not a disabled spouse (either spouse's age already counted) Either spouse's total disability qualifies

A shared helper, move_dependent_amounts_to_filer in model_api.py, holds the dependent rule.

How the swap asymmetry was found

  • Random scan on main (f33a4b3): 6 seeds × 40 random married couples per state (with and without dependents, 27 income and deduction inputs per adult), every state, 2019–2027, each couple simulated twice with the labels exchanged. Only AR (all years), IA (2019–2022), MS (all years) and MT (all years; some couples without dependents) changed by more than $0.005. No other state did.
  • Edge-case scan on main: 25 crafted couple types (offsetting incomes, zero incomes, one disabled or elderly spouse, one earner, equal spouses, interest paid by one spouse) in every state, 2021–2026. Only Oklahoma changed: $200 of ok_ptc for a low-income couple with a disabled non-head spouse.
  • Delaware never changed. I ran the review's DE case ($100,000/$30,000 adults, $20,000 dependent wages) on main: the dependent's irs_gross_income, adjusted_gross_income_person and de_pre_exclusions_agi are all 0, and de_income_tax is $6,137.12 under either labelling. de_pre_exclusions_agi is adjusted_gross_income_person + de_additions (an input with no formula) − de_subtractions (floored at 0), so a dependent reaches de_agi_indiv only through a de_additions input. The DE change keeps the same rule as the other states for that case.
  • Montana without dependents traced to the itemized interest: in a 2023 couple, mt_itemized_deductions_for_federal_itemization_joint was $12,018.81 with one spouse as head and $22,023.81 with the other.

The law, and the methodology choice (for the hub to queue for Max)

What each state says about a dependent's income on a separate-column return. None of the five states has a rule. Each tells spouses to report their own income in their own column:

  • Arkansas, 2025 AR1000F instructions, p. 12: "If your filing status is Married Filing Separately on the Same Return, columns A and B must be used. Write the primary's income in column A and the spouse's income in column B."
  • Delaware, 2025 PIT-RES instructions, p. 5: "For Filing Status 3 or 4, you must each report your own income, personal credits, deductions, and one-half of the income derived from securities, bank accounts, real estate, etc., which are titled or registered in joint names." Filing Status 4 is "two separate returns which have been combined on the same form for convenience."
  • Iowa, 2021 IA 1040 instructions, p. 7: status 3 is "married filing separately on a combined return"; dependents follow federal law ("The Iowa tax law follows federal guidelines"), and a dependent with $5,000 or more of net income files their own Iowa return.
  • Mississippi, Form 80-100 instructions, p. 5: "A combined return is completed when both spouses have income. Place one spouse's income in Column A (Taxpayer) and the other spouse's income in Column B (Spouse)." Minors with income over their exemption and standard deduction file their own return.
  • Montana, 2023 Form 2 instructions, p. 12: "When filing separately on the same form this allocation is done between Columns A and B, with each column constituting its own return. ... If you filed your federal tax return separately, report the items of income the same way you reported them on your federal Form 1040."

So under the law a dependent's income belongs on neither column: it is on the dependent's own return. PolicyEngine-US nonetheless counts dependents' income on the filers' return in these states, on both the joint and the separate path (the model does not compute dependents' own returns, #9618). This PR keeps that and changes only which column gets it.

Rule chosen: the spouse with the greater income takes it; an exact tie splits it equally. The one federal rule that puts a child's income on a parent's return addresses parents filing separately: the child's income goes on "the return of the parent with the greater taxable income" (IRS Form 8814 instructions; 26 U.S.C. 1(g)(5)(B)). Montana says separate-column filers report income as on a separate federal return, and the others treat each column as a separate return. The comparison uses each spouse's own state net income before the move (per-spouse taxable income is not computed, and AR prorates itemized deductions by this income). The tie split keeps the rule independent of the label.

Alternatives Max may prefer:

  1. Split by each spouse's share of their combined income. This is smooth where the chosen rule jumps when the spouses' incomes cross, but has no legal source, and shares are undefined when one column is negative (MS, IA).
  2. Drop dependents' income from these states' returns on every path. This is the law, but without dependents' own returns (Compute a tax-unit dependent's own income tax return #9618) it removes the tax entirely. It belongs with that work.

Oklahoma interpretation. 68 O.S. 2906 allows a claim by "any totally disabled person, who is the head of a household", and Form 538-H defines head of household as "a person who as owner or joint owner maintained a home". A totally disabled spouse who jointly owns the home is such a person, and the form asks about "you or your spouse" for age. main already counted either spouse's age. This PR counts either spouse's disability too.

Invariants

These hold for every input:

  1. Swap invariance. Exchanging the two adults' head and spouse labels leaves state_income_tax and state_income_tax_before_refundable_credits unchanged, in every state and year.
  2. Label-independent columns. Each person's ar_agi_indiv, de_agi_indiv, ia_net_income, ms_agi and mt_agi_indiv is the same under either labelling.
  3. Conservation. The move changes no tax unit's total: dependents get 0, and the filers' columns gain exactly the dependents' total.
  4. Unchanged for units without a spouse. Single and head-of-household filers keep the dependents' amount on the head, as before.

Tests

  • YAML: new swap and tie cases in ar_agi_indiv, de_agi_indiv, ia_net_income, ms_agi, mt_agi_indiv, both Montana joint itemized deduction files and ok_ptc. Two existing expectations change because they encoded the asymmetry: ms_agi (the spouse's $10,000 exceeds the head's $9,000, so the spouse now takes the $3,000) and ia_net_income "unit test 2" (equal $8,000 spouses now split the $600).
  • Property test policyengine_us/tests/core/test_state_tax_head_spouse_swap_invariance.py checks invariants 1–3:
    • Hypothesis draws batches of 10–40 married couples (0–3 dependents, who may have income) in AR, DE, IA, MS, MT and OK, 2021–2026.
    • A seeded population of those states, with crafted edge couples and the two cases from the Honor dataset-supplied tax-unit roles #9617 review, runs in every year.
    • Three seeded couples in every state check 2026.
    • Differential: AR, DE, IA and MS columns equal an independent numpy statement of the rule.
  • Fails on main: all 8 tests fail (log: ~/reviews/us-hub/state-swap-invariance/logs/property-test-main.log). For example: "state_income_tax in 2021 changes when the head and spouse labels are exchanged: AR 277.84 -> 271.62, ... IA 7328.70 -> 6964.60". Hypothesis also reports MS 1972.15 -> 2135.20 and MT 10562.37 -> 10564.16.
  • Passes on this branch: 8 passed (property-test-branch.log).
  • Cost (local, macOS arm64, not CI): 25 s of test time; 45 s wall including imports; 2.9 GB peak RSS for the file alone. It runs in the Rest "core" group. That group took 8:20 and peaked at 6.1 GB RSS in run 37616582113. Covering all 51 states in every year was the costly option (2021 alone: 3.7 GB, 15 s), so the all-state guard runs in 2026 only.

Microsimulation impact

A real microsimulation, main (f33a4b3) against this branch (cd24bdd), on the default dataset populace_us_2024.h5@populace-us-2024-spm-20260909, run through lockrun.sh (arrays in ~/reviews/pe-us-merge-backlog-2026-10-02/impact/out/ssw-{b,p}.*). These are weighted changes in state income tax, branch minus main, in $ millions:

State 2025 change 2025 units changed (records / weighted) 2026 change 2026 units changed (records / weighted)
AR +1.104 9 / 19,249 +2.000 7 / 17,166
DE +0.000 0 / 0 +0.000 0 / 0
IA +0.000 0 / 0 +0.000 0 / 0
MS -1.955 3 / 4,443 -1.790 3 / 4,474
MT -6.207 25 / 11,786 -6.205 25 / 11,870
OK +0.000 0 / 0 +0.000 0 / 0
Every other state 0.000 0 / 0 0.000 0 / 0
All states -7.057 37 / 35,477 -5.995 35 / 33,510
  • Arkansas moves both ways, as dependents' income changes column: +3.294 / -2.190 in 2025 and +3.924 / -1.923 in 2026.
  • Mississippi falls in both years (3 records each).
  • Montana falls (25 records each year). All of it comes from counting both spouses' interest in joint itemized deductions: mt_agi_indiv, the only other Montana change, applies only through 2023, when filing separately on one form ended.
  • Delaware, Iowa and Oklahoma do not change on this dataset. Delaware's dependents carry no income into de_agi_indiv (see above), Iowa's separate filing ended after 2022, and no Oklahoma unit has ok_ptc in either run.
  • State income tax before refundable credits changes by the same amounts. Household net income rises by $7.057M (2025) and $5.995M (2026), matching the state tax change to within $4 and $37.

A 2025 cross-check, #9617 on current main with and without this fix, is running and will be added here.

Overlaps

Follow-ups (not in this PR)

Label-dependent fallbacks with no observed tax effect in either scan: ia_prorate_fraction and va_agi_share give 100% to the head when the couple's total is 0; mo_adjusted_gross_income gives the head all the remaining ALDs when the couple's gross income is not positive; and md_two_income_subtraction gives the head the couple's whole federal AGI when their gross income is not positive. Separately, Montana's itemized deductions use mortgage_interest, which includes non_deductible_mortgage_interest.

axiom: 68 O.S. §2906 TheAxiomFoundation/rulespec-us#1555 queued | Minn. Stat. 290.067 / 26 USC 21(b)(1)(C) TheAxiomFoundation/rulespec-us#1603 queued | RSMo 135.010(1) TheAxiomFoundation/rulespec-us#1604 queued | ORS 315.264 / 26 USC 21 TheAxiomFoundation/rulespec-us#1605 queued | 30 Del. C. §1110 / PIT-RES line27 TheAxiomFoundation/rulespec-us#1606 queued | 30 Del. C. §1114 TheAxiomFoundation/rulespec-us#1607 queued | 30 Del. C. §1117 TheAxiomFoundation/rulespec-us#1608 queued | MCA 15-30-2131(1)(a), (1)(c)(i)(C) TheAxiomFoundation/rulespec-us#1512 queued | MCA 15-30-2131 (Montana itemized deductions, 2021–2023) queued, blocked: the corpus has only the repeal notice | n/a for the dependent-income column rule: it places income the law keeps on dependents' own returns (#9618), so there is no provision to mirror | n/a for unknown-account ownership and first-listed output storage conventions

🤖 Generated with Claude Code

MaxGhenis and others added 3 commits October 7, 2026 09:45
Swapping a married couple's is_tax_unit_head and is_tax_unit_spouse labels
changed state income tax in Arkansas, Iowa, Mississippi, Montana and
Oklahoma (Delaware's code had the same pattern without an observed effect).

- Arkansas, Delaware, Iowa, Mississippi and Montana put dependents' income
  on the head's column of a separate-column return. A shared helper,
  move_dependent_amounts_to_filer, now puts it on the column of the spouse
  with the greater income of their own and splits an exact tie, following
  the rule for parents filing separately (26 U.S.C. 1(g)(5)(B), Form 8814).
- Montana's joint itemized deductions counted only the head's mortgage and
  investment interest; they now count every member's.
- Oklahoma's property tax credit accepted a disabled head but not a
  disabled spouse; either spouse now qualifies, as for age.

Adds YAML cases for each formula and a Hypothesis property test that
swapping the labels leaves state income tax unchanged to the cent.

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

The independent review of #9981 found four more state formulas that change
when a couple's head and spouse labels are exchanged:

- Minnesota's dependent care credit and Montana's dependent care deduction
  counted an incapacitated spouse but not an incapacitated head.
- Delaware's combined separate return sent the EITC (and the dependent care
  credit) to the head's column on equal taxable incomes, and split the
  dependent personal credits with a floor/ceil heuristic that was not
  symmetric. Ties now go to the column where they cut tax most, and the
  split searches every allocation.
- Missouri's property tax credit tested the surviving-spouse pathway on the
  head only; either spouse can be the claimant.

Also:
- Montana's joint itemized deductions count the spouses' interest, not a
  dependent's own.
- The helper's docstring and the state comments call the dependent
  allocation a modelling convention, and state its one-spouse precondition.
- The property test covers MN and MO, incapacity, adult care expenses,
  survivor benefits, veterans and dependents' DE/MT additions, adds the
  review's counterexamples, and asserts finite values with rtol=0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 8, 2026 09:34
- Delaware: the dependent personal-credit split, and on equal Line 23
  incomes the dependent care credit and EITC columns, are now chosen
  together to minimise the columns' tax after the EITC
  (de_combined_separate_credit_choices). Maximising credits used first, or
  sending the dependent care credit to the roomier column, could leave
  more tax than main's labelling did.
- Oregon: either married filer with a disability is the other's qualifying
  spouse for the working family household and dependent care credit, and
  either filer's earnings, or a disabled spouse's imputed earnings, meet
  the employment test ("you" also means your spouse on a joint return).
- The property test covers Oregon and a disabled, incapacitated spouse,
  and states that couples with a spouse claimed elsewhere are out of scope.

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

The #9617 cross-check found one Mississippi pure head/spouse swap that still
changed state tax: the microdata supply the health savings account deduction
at the tax-unit level, and person_share_of_tax_unit_amount gave a deduction
with no per-person amounts to the head's column. It now takes an opt-in
split_between_spouses flag, which the Mississippi health savings account,
self-employed health insurance and self-employed retirement adjustments use:
the head and spouse each take half. Medicaid AGI keeps the head fallback.

The property test now draws tax-unit deductions with no per-person split,
and fails on the previous head for this case.

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

This branch has not been deployed

No deployments
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