Repository navigation
Report Montana's TAXSIM state AGI for the filing path used, and federal AGI from 2024 - #9942
Conversation
taxsim_state_agi summed mt_agi_indiv for Montana. That variable is defined only while Montana allows married couples to file separately on the same form, so Montana's state AGI was 0 from 2024; for 2021-2023 it floored each spouse's Montana AGI before adding, so a joint return was not pooled. - Generate mt_agi: the sum of mt_agi_indiv when the couple files separately on the same form, mt_agi_joint otherwise (2021-2023 Form 2, page 1, line 14), and list it in state_agis. - Move the federal-AGI state list out of taxsim_state_agi into the dated parameter gov.states.household.states_using_federal_agi, and add Montana from 2024, when Form 2 starts from federal AGI and has no Montana AGI line. TAXSIM reports federal AGI for Montana from 2024 too. Fixes #9929 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… ALD split Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9942 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 4 2 -2
Lines 76 31 -45
Branches 2 4 +2
=========================================
- Hits 76 31 -45
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Context from the original session (local_99da947a), for the US + core hub, which owns this PR now. I won't push to the branch. Evidence
My local base-versus-branch batch never ran. It was still queued for the heavy lock when the session ended. So these parts of the PR body are not yet true or still pending:
An in-session adversarial review (three lenses, two refuters per finding) upheld these findings on b04d4fb
Follow-up chips filed (not in this PR)
|
|
US + core hub merge audit, us#9942 at
|
Fixes #9929.
What was wrong
gov.states.household.state_agislistedmt_agi_indivas Montana's state AGI, andtaxsim_state_agi(with its deprecated aliasstate_agi) added that list over the tax unit.mt_agi_indivisdefined_for = "mt_married_filing_separately_on_same_return_eligible", which is false from 2024. So Montana's state AGI was 0 from 2024.mt_agi_indivfloors each spouse's Montana AGI at zero before the sum. A joint return's Montana AGI is one figure that pools the spouses first, which PE computes asmt_agi_joint. So a spouse's loss never offset the other spouse's income.Montana's income tax itself is unaffected: it already uses
mt_agi_jointand the_indivpath directly.taxsim_state_agiis TAXSIM output mapping.What the forms say
What TAXSIM's state AGI column carries from 2024: federal AGI
The issue left open whether, from 2024, the state AGI column should carry federal AGI or PE's
mt_agi_jointintermediate (federal AGI plus Montana additions minus subtractions). I ran NBER's own TAXSIM on the question. I usedtaxsimtestbuild 2025Aug23, the binary PolicyEngine/policyengine-taxsim bundles inresources/taxsimtest/, which covers years up to 2024. Its state AGI output (v32):Through 2023 TAXSIM reports Montana AGI, pooled on a joint return. From 2024 it reports federal AGI, even where Montana taxable income nets a subtraction (the 5,500 for a taxpayer aged 65 or older). It also matches how
taxsim_state_agialready treats Colorado, North Dakota and South Carolina. The repo's own parameter files describe their bases as built from federal taxable income: thestates_using_federal_standard_deductionreferences for Colorado and North Dakota, and the South Carolina comment instate_agis.yaml. For those states it reports federal AGI. So from 2024 Montana's state AGI is federal AGI, Form 2 line 1.Probe inputs and outputs:
~/reviews/mt-taxsim-state-agi-2026-10-06/probes2.csvandprobes_out_2025Aug23.csv.Changes
mt_agi(new, generated in_generate_state_mfs_variables.pyalongsidemt_taxable_income): the Montana AGI of the filing path used. It is the sum ofmt_agi_indivwhenmt_files_separately, andmt_agi_jointotherwise. From 2024,mt_files_separatelyis always false, so it ismt_agi_joint.state_agis.yamllistsmt_agiinstead ofmt_agi_indiv.gov.states.household.states_using_federal_agi(new, dated) replaces the hardcodedFEDERAL_AGI_STATESlist intaxsim_state_agi. It mirrorsstates_using_federal_standard_deduction.taxsim_state_agigets adocumentationstring stating the rule.Household effects (state MT)
Pending: local runs of
mainand this branch are queued behind the machine-wide heavy lock; this section is filled in when they finish.Tests
gov/states/tax/income/taxsim_state_agi.yaml(new): Montana cases whose expectations are TAXSIM's v32 values above, plus filing-path cases with direct inputs. (Result onmain: pending.)gov/states/mt/tax/income/mt_agi.yaml(new): both filing paths, pooling, the 2024 base, and zero outside Montana. (Result onmain: pending.)tests/core/test_mt_state_agi_invariants.py(new): a seeded grid of single filers and couples, one vectorized simulation per year for 2021–2027, plus Hypothesis-drawn batches (max_examples=5,derandomize=True). (Result onmain: pending.)test_legacy_state_umbrellas.py:gov/states/tax/income/state_agi.yamlstill passes.Every file was run on its own, in the foreground, through
~/reviews/us-hub/scripts/heavy_run.shat nice 0. The base runs used this branch's tests against upstream/main's source files. Logs are in~/reviews/mt-taxsim-state-agi-2026-10-06/runs/.Invariants (asserted in
test_mt_state_agi_invariants.pyfor every tax unit)mt_agi= the sum ofmt_agi_indivwhen the couple files separately on the same form,mt_agi_jointotherwise. From 2024 no unit files separately andmt_agi_indivis 0.taxsim_state_agi=mt_agithrough 2023 and federal AGI from 2024.state_agi=taxsim_state_agi.mainviolates. Units with negative federal AGI are excluded: PolicyEngine floors Montana AGI at zero (an inherited convention), while TAXSIM v32 returns the negative amount (a 2023 single filer aged 40 with a $20,000 self-employment loss: TAXSIM reports -$19,999.99).Test cost (hub build, macOS under heavy host load):
test_mt_state_agi_invariants.py8 passed in 369.5 s at 2.80 GB peak RSS;test_legacy_state_umbrellas.py19 passed in 484.5 s at 2.64 GB peak RSS, reusing one simulation per legacy case.4. Bounds:
mt_agi≥ 0. A unit outside Montana hasmt_agi= 0.Non-vacuity guards check that the grid reaches both filing paths through 2023, including a joint-path couple whose pooled AGI is below the floored sum. They also check that, from 2024, it holds a filer whose Montana base differs from federal AGI.
Coordination
_generate_state_mfs_variables.py,state_agis.yaml,taxsim_state_agi.py,state_agi.yamlortest_legacy_state_umbrellas.py. I checked all open PRs' file lists.mt_agi_joint, and Give each spouse their own above-the-line deductions in per-person AGI #9890/Net household members' Medicaid MAGI before the zero floor, and give each spouse their own deductions #9860 changemt_agi_indiv.mt_agireads both by name, so their fixes flow throughmt_agiandtaxsim_state_agiunchanged. There are no file conflicts. The hard-coded expectations aremt_agi,mt_agi_jointandtaxsim_state_agi, which pool the couple. They do not assert per-spousemt_agi_indiv, which depends on howloss_aldis split between spouses (Give each spouse their own above-the-line deductions in per-person AGI #9890).mt_agi_joint. It does not touch these files.Follow-ups
mt_agi_jointin every year (OUTPUT_ADAPTER_OVERRIDESinstate_output_resolver.py, from policyengine-taxsim#901), as a workaround for this bug. Once a policyengine-us release carries this fix, that override should go. Otherwise the emulator reports 94,500 for the 2024 filer aged 70 above, where TAXSIM reports 100,000.axiom: n/a: TAXSIM output mapping.
taxsim_state_agiandstate_agisonly map PE outputs to TAXSIM's state AGI column, and no Montana tax computation changes.mt_agiselects between two existing variables.🤖 Generated with Claude Code
Hub microsimulation impact (current head)
A real microsimulation on the default dataset, main at the merge base
35f3c1f92aagainst this PR's head3b249d67fc, for 2026. The runs went one at a time under the shared heavy-job lock. Sums are weighted.taxsim_state_agistate_agimt_income_taxstate_income_taxincome_taxhousehold_net_incomehousehold_benefitsVariables this PR adds (
mt_agi) have no value on the base side, so the table leaves them out..state_agiandtaxsim_state_aginow include Montana AGI, which is why they rise while Montana income tax does not change.Comparison files are in
fixes/9942-impact/on the hub host.