Repository navigation
Net capital gain distributions inside the capital loss limit in AGI - #9788
Merged
Merged
Conversation
A filer with capital losses or other capital gains enters capital gain distributions on Schedule D line 13 (2025 Instructions for Schedule D), so they net against the losses before the 26 U.S.C. 1211(b) limit on line 21. The model added distributions (non_sch_d_capital_gains) to gross income and deducted min(3,000, losses) separately: a 5,000 long-term loss with 3,000 of distributions gave 0 in AGI instead of -2,000. - capital_losses_allowed_against_gains (new): losses allowed up to the gains in gross income, distributions included (1211(b), first part). - limited_capital_loss: the net loss up to the limit (1211(b)(1)-(2), Schedule D line 21). loss_ald deducts both. This also nets spouses' gains and losses on a joint return. - loss_limited_net_capital_gains (+ person version): Form 1040 line 7a, max(-limit, LT + ST + distributions). Net investment income no longer adds the distributions separately (Form 8960 line 5a). - has_qdiv_or_ltcg: qualified dividends, or Schedule D lines 15 and 16 both above zero (Form 1040 instructions, line 16). - dependent_taxable_ss_magi: the same netting on the dependent's return. - dc_self_employment_loss_addition: subtracts both capital parts of loss_ald. Tests: YAML cases with form line comments; grid, Hypothesis property and monotonicity tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ons-agi # Conflicts: # policyengine_us/parameters/gov/irs/investment/income/sources.yaml
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9788 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 4 11 +7
Lines 76 255 +179
Branches 2 12 +10
==========================================
+ Hits 76 255 +179
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:
|
filer_loss_limited_net_capital_gains (from #9784) now nets the head and spouse's capital gain distributions with their Schedule D gains and losses before the 1211(b) limit, and net investment income no longer adds the distributions separately. The invariant test's reference computation follows: distributions move from the person-level Form 8960 amounts to the Schedule D inputs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
capital_losses_allowed_against_gains counts only the capital gains that gov.irs.gross_income.sources includes, and dependent_taxable_ss_magi nets distributions only when both sources are listed. Cover both branches with reforms that drop non_sch_d_capital_gains or capital_gains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the independent review of #9788: - mi_household_resources subtracted all above-the-line deductions, including the capital loss already netted in the capital gains line (MI-1040CR line 30 is U.S. Schedule 1 adjustments only). It now leaves out capital_losses_allowed_against_gains and limited_capital_loss. The two existing loss-limit cases double counted the loss: 44,000 -> 47,000 and 47,000 -> 48,500. - has_qdiv_or_ltcg figures Schedule D lines 15 and 16 over the head and spouse, so a dependent's loss cannot switch off the filer's worksheet. - Distributions are floored at zero per person in every line 7a variable (box 2a is not negative), as irs_gross_income does. - Capital losses are deductible only while capital_gains is a gross income source, matching dependent_taxable_ss_magi under such a reform. - Test that the two loss-limit parameters agree; rename the #9784 invariant test that no longer compares with the pre-change formula. - loss_ald label: "Business and capital loss ALD". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI caught two tests written against the old capital loss formula: - test_dependent_losses_agi_invariants (#9647) compared limited_capital_loss with min(cap, sum of losses), which does not net one spouse's gains against the other's losses. Its reference now splits 1211(b) the same way: losses allowed up to the gains, plus the excess up to the cap. Renamed ..._match_all_member_formula. - md_capital_gains_surtax "partial offset" set capital_losses (a formula variable, max(0, -capital_gains)) to 50,000 next to 150,000 of net gains, a state no inputs can produce, and its comment applied the $3,000 cap to losses within gains. It now inputs the short-term loss directly (30,000 gains less 50,000 losses = -20,000): Schedule D line 16 and Form 502CG line 1 are 100,000, surtax 2,000 (same on main). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 5, 2026
Net Michigan business and rental losses in household resources (MI-1040CR lines 16, 17 and 30)
#9790
Merged
…ons-agi # Conflicts: # policyengine_us/tests/core/test_dependent_losses_agi_invariants.py # policyengine_us/variables/gov/states/mi/tax/income/mi_household_resources.py
… and move the distributions comment Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Hand-off to the US + core hub. Head
|
This was referenced Oct 6, 2026
Contributor
Author
|
Merged by the US + core hub on its merge gates. Audit:
|
MaxGhenis
added a commit
that referenced
this pull request
Oct 6, 2026
Brings in #9831 (amounts_in_brackets, the shared bracket walk that tax_at_main_rates and amount_taxed_below_rate use) and #9788 (capital gain distributions netted inside the capital loss limit). No textual conflicts: the additional_tax_bracket reform's tax_on_taxable_income_at_main_rates override calls tax_at_main_rates, so it takes #9831's walk. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 6, 2026
…s netting - test_additional_tax_bracket_unset_bracket.py (#9831) listed regular_tax_before_credits among the variables the reform replaces. On this branch the reform replaces tax_on_taxable_income_at_main_rates instead, and regular_tax_before_credits is income_tax_main_rates plus capital_gains_tax. The default-system leak check now covers the three replaced variables, and the finite and monotone checks cover the reform's three taxes: income_tax_main_rates, tax_on_taxable_income_at_main_rates and regular_tax_before_credits. - test_regular_tax_before_credits.py set aside households with capital gain distributions and a Schedule D net loss in the monotonicity property. #9788 nets the distributions inside the capital loss limit in AGI, so the property now holds for every household. The exclusion is gone, and the minimized counterexample (2018 single, $50,000 of distributions, a $40,273 short-term loss, $1 more long-term gain) is an explicit example; it failed before #9788 (the regular tax fell by $0.12) and passes now. Both files pass after the merge: 9 and 6 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 6, 2026
… credit fix #9788 adds capital_losses_allowed_against_gains to loss_ald: federal AGI now nets a return's capital losses against its gains, distributions included, before the $3,000 limit. Resolution and follow-through: - loss_ald adds limited_business_loss (unchanged 461(l) body, identical to main's), capital_losses_allowed_against_gains and limited_capital_loss, with main's label and 1211(b) reference. - Arizona adds back loss_ald less limited_business_loss, clipped to the two capital parts, so line D still replaces every capital amount in AGI. - Two YAML comments and one expected federal AGI follow #9788's netting (distributions case: 1,000, not 2,000); Arizona expectations unchanged. - Property test's federal coverage helper follows the new netting. Delta review r2 (Sol) fixes in the same commit: the reform test applies its Reform to an existing Simulation (sim.apply_reform) instead of rebuilding the country model (78 s call phase), and its loss_ald builds on limited_business_loss; the add-back comment states the contract for a replacement loss_ald. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 6, 2026
…40CR lines 16, 17 and 30) (#9790) * Net capital gain distributions inside the capital loss limit A filer with capital losses or other capital gains enters capital gain distributions on Schedule D line 13 (2025 Instructions for Schedule D), so they net against the losses before the 26 U.S.C. 1211(b) limit on line 21. The model added distributions (non_sch_d_capital_gains) to gross income and deducted min(3,000, losses) separately: a 5,000 long-term loss with 3,000 of distributions gave 0 in AGI instead of -2,000. - capital_losses_allowed_against_gains (new): losses allowed up to the gains in gross income, distributions included (1211(b), first part). - limited_capital_loss: the net loss up to the limit (1211(b)(1)-(2), Schedule D line 21). loss_ald deducts both. This also nets spouses' gains and losses on a joint return. - loss_limited_net_capital_gains (+ person version): Form 1040 line 7a, max(-limit, LT + ST + distributions). Net investment income no longer adds the distributions separately (Form 8960 line 5a). - has_qdiv_or_ltcg: qualified dividends, or Schedule D lines 15 and 16 both above zero (Form 1040 instructions, line 16). - dependent_taxable_ss_magi: the same netting on the dependent's return. - dc_self_employment_loss_addition: subtracts both capital parts of loss_ald. Tests: YAML cases with form line comments; grid, Hypothesis property and monotonicity tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Count distributions inside Schedule D in the NII invariant reference filer_loss_limited_net_capital_gains (from #9784) now nets the head and spouse's capital gain distributions with their Schedule D gains and losses before the 1211(b) limit, and net investment income no longer adds the distributions separately. The invariant test's reference computation follows: distributions move from the person-level Form 8960 amounts to the Schedule D inputs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test the netting when a reform drops a gross income source capital_losses_allowed_against_gains counts only the capital gains that gov.irs.gross_income.sources includes, and dependent_taxable_ss_magi nets distributions only when both sources are listed. Cover both branches with reforms that drop non_sch_d_capital_gains or capital_gains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Address review: Michigan adjustments, filer-only worksheet test, floors From the independent review of #9788: - mi_household_resources subtracted all above-the-line deductions, including the capital loss already netted in the capital gains line (MI-1040CR line 30 is U.S. Schedule 1 adjustments only). It now leaves out capital_losses_allowed_against_gains and limited_capital_loss. The two existing loss-limit cases double counted the loss: 44,000 -> 47,000 and 47,000 -> 48,500. - has_qdiv_or_ltcg figures Schedule D lines 15 and 16 over the head and spouse, so a dependent's loss cannot switch off the filer's worksheet. - Distributions are floored at zero per person in every line 7a variable (box 2a is not negative), as irs_gross_income does. - Capital losses are deductible only while capital_gains is a gross income source, matching dependent_taxable_ss_magi under such a reform. - Test that the two loss-limit parameters agree; rename the #9784 invariant test that no longer compares with the pre-change formula. - loss_ald label: "Business and capital loss ALD". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Follow 1211(b) in the #9647 invariant and a Maryland surtax test CI caught two tests written against the old capital loss formula: - test_dependent_losses_agi_invariants (#9647) compared limited_capital_loss with min(cap, sum of losses), which does not net one spouse's gains against the other's losses. Its reference now splits 1211(b) the same way: losses allowed up to the gains, plus the excess up to the cap. Renamed ..._match_all_member_formula. - md_capital_gains_surtax "partial offset" set capital_losses (a formula variable, max(0, -capital_gains)) to 50,000 next to 150,000 of net gains, a state no inputs can produce, and its comment applied the $3,000 cap to losses within gains. It now inputs the short-term loss directly (30,000 gains less 50,000 losses = -20,000): Schedule D line 16 and Form 502CG line 1 are 100,000, surtax 2,000 (same on main). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Net Michigan business and rental losses on MI-1040CR lines 16 and 17 MCL 206.508(4) adds back "any net business loss after netting all business income and loss" and "any net rental or royalty loss". The MI-1040CR nets line 16 (Schedule C, Form 4797 Part II, Schedule E Parts II and III, Schedule F) and line 17 (Schedule E Parts I and V) and floors each total at zero. Line 30 is the U.S. Schedule 1 adjustments, so loss_ald, which holds business, rental and capital losses, is no longer subtracted there. Estate and trust income and Form 4797 ordinary gains now count on line 16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep dependents' business and rental items off Michigan lines 16 and 17 MCL 206.508(3): "'Household' means a claimant and spouse." Netting every tax unit member's sources let a dependent's business or rental loss offset the claimant's income (a 15-year-old's Schedule C loss of 20,000 took the claimant's household resources from 70,000 to 50,000). Lines 16 and 17 now sum only non-dependents, as loss_ald and irs_gross_income do. Tests: three dependent YAML cases and a deterministic dependent property test. The loss_ald reform check now runs once, on the grid, instead of on every Hypothesis example; test_properties drops from 931 s in CI to about 8 s. The deterministic tests no longer need hypothesis. Small inputs are drawn at $100 or more, the tolerance docstring is corrected, and comments list Schedule E Part IV (REMIC) on line 17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add the combined #9781 regression case, a joint Maryland surtax case, and move the distributions comment Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use tax_unit_non_dep_add for lines 16 and 17; describe the dependent change in the changelog Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 6, 2026
This was referenced Oct 6, 2026
MaxGhenis
added a commit
that referenced
this pull request
Oct 6, 2026
…1)) and use it on Form 6251 line 10 (#9852) * Cap the regular tax at the tax on all taxable income and use it on Form 6251 line 10 26 U.S.C. 1(h)(1) says the tax "shall not exceed" the sum of the subparagraph (A) to (F) amounts, and Schedule D Tax Worksheet line 47 takes the smaller of line 45 and line 46 (the tax on all of line 1). capital_gains_tax now stops at tax_on_taxable_income_at_main_rates (new, line 46) less income_tax_main_rates. The cap binds where gain taxed at 15 percent falls in the 12 percent bracket: up to $3.75 single and $7.50 joint in 2025, and $28.50 and $57 in 2026. The Biden and Harris capital gains reforms apply the same limit, and the additional_tax_bracket reform figures line 46 on its own schedule. regular_tax_before_credits was a second Schedule D Tax Worksheet (2017 numbering) whose result was min(worksheet tax including the gains, income_tax_main_rates excluding them). Form 6251 line 10 then added capital_gains_tax. Whenever the worksheet path fell below the main-rates path, line 10 understated the regular tax: before #9781 that happened for 18 dataset tax units in 2025 ($328M weighted), because dwks10 ignored the Form 4952 line 4g election and because the worksheet took line 28 as min(line 21, line 22) instead of their sum. regular_tax_before_credits is now income_tax_main_rates plus capital_gains_tax, the regular tax income_tax_before_credits charges, and Form 6251 line 10 uses it alone. Tests: real-unit regression cases for tax units 1101624, 1004930, 1156248 and 1032460; line 45/46 boundary cases for 2025 and 2026 (single, joint, head of household, Form 2555); the existing worksheet property tests now compare with line 47 and Foreign Earned Income Tax Worksheet line 25 exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Cite Rev. Proc. 2025-32 section 4 for 2026 amounts Section 3 of Rev. Proc. 2025-32 modifies 2025 items (only .01, the standard deduction, and .02, section 179); the 2026 adjusted items are section 4. The 2026 AMT breakpoints are section 4.10 (PDF page 16) and the 2026 additional standard deduction for the aged or blind is section 4.14(3) (PDF page 18). Also give the dependent standard deduction citation its section number (4.14(2)). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add property and differential tests for the regular tax and the line 47 limit test_regular_tax_before_credits.py transcribes the 2025 Schedule D Tax Worksheet, lines 1 to 47, with every skip instruction, the Form 4952 election, capital gain distributions, short-term losses and Schedule D lines 18 and 19. The regular rates come from the 2025 Tax Computation Worksheet rows. 2026 runs on Rev. Proc. 2025-32's tables and capital gains amounts. The model matches lines 10, 13, 14, 21, 44, 46 and 47 for a grid, households at the 0 percent amount, and Hypothesis draws. Properties, 2018 to 2035: - 0 <= regular tax <= line 46; - 0 <= capital_gains_tax <= line 46 - income_tax_main_rates; - regular_tax_before_credits = main rates + capital gains tax; - income_tax_before_credits = regular + AMT; - the AMT is line 9 less line 10; - without net capital gain, the regular tax is line 46; - the worksheet lines (dwks10, dwks13, line 18 <= 21 <= 14); - the tax is monotone in wages, gains and dividends; - results are independent of batch order. The limit binds at the top of the 12 percent bracket in every year and filing status, with the published band widths for 2018 to 2026. The monotonicity check sets aside households with capital gain distributions and a Schedule D net loss, a known defect it found. Gross income adds non_sch_d_capital_gains outside the loss limit, while net_capital_gain nets them (a 2018 single filer's tax falls $0.12 with $1 more gain). No dataset tax unit has both. It is left for a follow-up. Also adds 2026 joint, separate and non-binding line 45/46 YAML cases, from the same Rev. Proc. 2025-32 figures as the Axiom companion tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Align the merged tests with main: #9831's reform variables and #9788's netting - test_additional_tax_bracket_unset_bracket.py (#9831) listed regular_tax_before_credits among the variables the reform replaces. On this branch the reform replaces tax_on_taxable_income_at_main_rates instead, and regular_tax_before_credits is income_tax_main_rates plus capital_gains_tax. The default-system leak check now covers the three replaced variables, and the finite and monotone checks cover the reform's three taxes: income_tax_main_rates, tax_on_taxable_income_at_main_rates and regular_tax_before_credits. - test_regular_tax_before_credits.py set aside households with capital gain distributions and a Schedule D net loss in the monotonicity property. #9788 nets the distributions inside the capital loss limit in AGI, so the property now holds for every household. The exclusion is gone, and the minimized counterexample (2018 single, $50,000 of distributions, a $40,273 short-term loss, $1 more long-term gain) is an explicit example; it failed before #9788 (the regular tax fell by $0.12) and passes now. Both files pass after the merge: 9 and 6 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Say in the changelog that regular_tax_before_credits now includes the capital gains tax PolicyEngine/salt-amt-calculator's API reads regular_tax_before_credits as its regular tax, so the meaning change belongs in the release note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Point three Rev. Proc. 2025-32 links at the pages with their 2026 amounts Three links pointed into the wrong section of Rev. Proc. 2025-32: - the capital gains rate thresholds linked page 12, which is section 4.02 (kiddie tax). Section 4.03 and its 2026 amounts (49,450, 98,900, 66,200, 545,500, 613,700, 579,600 and 306,850) are on page 13; - the child tax credit amount ($2,200) and refundable maximum ($1,700) linked page 13, which holds sections 4.03 and 4.04. Section 4.05 and its amounts are on page 14. The other parameter links to the Rev. Proc. land on the page that has the 2026 amounts or on the page where their section starts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 6, 2026
Count only the head's and spouse's income in the EITC investment income test (26 U.S.C. 32(i))
#9883
Merged
MaxGhenis
added a commit
that referenced
this pull request
Oct 7, 2026
…worksheets (#9893) * Cap the regular tax at the tax on all taxable income and use it on Form 6251 line 10 26 U.S.C. 1(h)(1) says the tax "shall not exceed" the sum of the subparagraph (A) to (F) amounts, and Schedule D Tax Worksheet line 47 takes the smaller of line 45 and line 46 (the tax on all of line 1). capital_gains_tax now stops at tax_on_taxable_income_at_main_rates (new, line 46) less income_tax_main_rates. The cap binds where gain taxed at 15 percent falls in the 12 percent bracket: up to $3.75 single and $7.50 joint in 2025, and $28.50 and $57 in 2026. The Biden and Harris capital gains reforms apply the same limit, and the additional_tax_bracket reform figures line 46 on its own schedule. regular_tax_before_credits was a second Schedule D Tax Worksheet (2017 numbering) whose result was min(worksheet tax including the gains, income_tax_main_rates excluding them). Form 6251 line 10 then added capital_gains_tax. Whenever the worksheet path fell below the main-rates path, line 10 understated the regular tax: before #9781 that happened for 18 dataset tax units in 2025 ($328M weighted), because dwks10 ignored the Form 4952 line 4g election and because the worksheet took line 28 as min(line 21, line 22) instead of their sum. regular_tax_before_credits is now income_tax_main_rates plus capital_gains_tax, the regular tax income_tax_before_credits charges, and Form 6251 line 10 uses it alone. Tests: real-unit regression cases for tax units 1101624, 1004930, 1156248 and 1032460; line 45/46 boundary cases for 2025 and 2026 (single, joint, head of household, Form 2555); the existing worksheet property tests now compare with line 47 and Foreign Earned Income Tax Worksheet line 25 exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Cite Rev. Proc. 2025-32 section 4 for 2026 amounts Section 3 of Rev. Proc. 2025-32 modifies 2025 items (only .01, the standard deduction, and .02, section 179); the 2026 adjusted items are section 4. The 2026 AMT breakpoints are section 4.10 (PDF page 16) and the 2026 additional standard deduction for the aged or blind is section 4.14(3) (PDF page 18). Also give the dependent standard deduction citation its section number (4.14(2)). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add property and differential tests for the regular tax and the line 47 limit test_regular_tax_before_credits.py transcribes the 2025 Schedule D Tax Worksheet, lines 1 to 47, with every skip instruction, the Form 4952 election, capital gain distributions, short-term losses and Schedule D lines 18 and 19. The regular rates come from the 2025 Tax Computation Worksheet rows. 2026 runs on Rev. Proc. 2025-32's tables and capital gains amounts. The model matches lines 10, 13, 14, 21, 44, 46 and 47 for a grid, households at the 0 percent amount, and Hypothesis draws. Properties, 2018 to 2035: - 0 <= regular tax <= line 46; - 0 <= capital_gains_tax <= line 46 - income_tax_main_rates; - regular_tax_before_credits = main rates + capital gains tax; - income_tax_before_credits = regular + AMT; - the AMT is line 9 less line 10; - without net capital gain, the regular tax is line 46; - the worksheet lines (dwks10, dwks13, line 18 <= 21 <= 14); - the tax is monotone in wages, gains and dividends; - results are independent of batch order. The limit binds at the top of the 12 percent bracket in every year and filing status, with the published band widths for 2018 to 2026. The monotonicity check sets aside households with capital gain distributions and a Schedule D net loss, a known defect it found. Gross income adds non_sch_d_capital_gains outside the loss limit, while net_capital_gain nets them (a 2018 single filer's tax falls $0.12 with $1 more gain). No dataset tax unit has both. It is left for a follow-up. Also adds 2026 joint, separate and non-binding line 45/46 YAML cases, from the same Rev. Proc. 2025-32 figures as the Axiom companion tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Align the merged tests with main: #9831's reform variables and #9788's netting - test_additional_tax_bracket_unset_bracket.py (#9831) listed regular_tax_before_credits among the variables the reform replaces. On this branch the reform replaces tax_on_taxable_income_at_main_rates instead, and regular_tax_before_credits is income_tax_main_rates plus capital_gains_tax. The default-system leak check now covers the three replaced variables, and the finite and monotone checks cover the reform's three taxes: income_tax_main_rates, tax_on_taxable_income_at_main_rates and regular_tax_before_credits. - test_regular_tax_before_credits.py set aside households with capital gain distributions and a Schedule D net loss in the monotonicity property. #9788 nets the distributions inside the capital loss limit in AGI, so the property now holds for every household. The exclusion is gone, and the minimized counterexample (2018 single, $50,000 of distributions, a $40,273 short-term loss, $1 more long-term gain) is an explicit example; it failed before #9788 (the regular tax fell by $0.12) and passes now. Both files pass after the merge: 9 and 6 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Say in the changelog that regular_tax_before_credits now includes the capital gains tax PolicyEngine/salt-amt-calculator's API reads regular_tax_before_credits as its regular tax, so the meaning change belongs in the release note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Point three Rev. Proc. 2025-32 links at the pages with their 2026 amounts Three links pointed into the wrong section of Rev. Proc. 2025-32: - the capital gains rate thresholds linked page 12, which is section 4.02 (kiddie tax). Section 4.03 and its 2026 amounts (49,450, 98,900, 66,200, 545,500, 613,700, 579,600 and 306,850) are on page 13; - the child tax credit amount ($2,200) and refundable maximum ($1,700) linked page 13, which holds sections 4.03 and 4.04. Section 4.05 and its amounts are on page 14. The other parameter links to the Rev. Proc. land on the page that has the 2026 amounts or on the page where their section starts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test 28-percent rate gain with a Form 4952 election against the 2025 worksheets - rate_gain_with_form_4952_election.yaml: the reproducer (no taxable income; taxable income below the gain; half and all of a collectibles gain elected; no election) and an election above the 24% bracket that leaves 28% on line 9 only, with Schedule D Tax Worksheet lines. - test_section_1h_regular_tax.py: for every household and year (2018 to 2030) with elections and both gains, the regular tax is at most line 46 figured from the rate parameters, exactly zero with no taxable income, and not negative; and electing more lowers it by at most the 12/15 rate overlap plus 3% of the smaller of the extra amount elected and the unrecaptured section 1250 gain. Pins the intended exception where an election moves gain from 28 to 25 percent (section 1(h)(1)(E)(ii) measures its excess with net capital gain, which section 1(h)(2) reduces): $68,874 to $67,374 on $50,000 elected. A 2025 differential compares Form 6251 Part III and line 11 after an election with nonzero Schedule D lines 18 and 19. - test_form_6251_part_iii.py: the Schedule D Tax Worksheet transcription takes amounts, Form 4952 lines 4g and 4e, and the Foreign Earned Income Tax Worksheet footnote's four modifications. - test_section_911_tax_stacking.py and test_form_4952_section_911_interaction.py: households with 28-percent rate and unrecaptured section 1250 gain are now compared with the forms (through the Schedule D Tax Worksheet and Form 6251 Part III with the AMT capital gain excess), including rows that reach modification 4, and kept in the monotonicity properties, with the corrected election bound in place of #9800's overlap-only bound. - Harris, Biden 2025 budget and additional tax bracket reforms: a case each where the line 47 limit binds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tighten reach assertions and fix a stale docstring (hard-tier review) - test_section_1h_regular_tax.py: the grid reaches 28% tax after an election only if some elected household has a positive Schedule D Tax Worksheet line 42; a positive capital gains tax could be all at 25%. - test_section_911_tax_stacking.py, test_form_4952_section_911_interaction.py: floor the unrecaptured section 1250 gain after modification 4 at zero, so a household whose line 9 the excess exhausts does not count as reaching it. - test_form_6251_part_iii.py: the transcription, not the model, leaves out the short-term loss netting (#9841 added it to the model). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 9, 2026
…40CR line 30) (#9795) * Net capital gain distributions inside the capital loss limit A filer with capital losses or other capital gains enters capital gain distributions on Schedule D line 13 (2025 Instructions for Schedule D), so they net against the losses before the 26 U.S.C. 1211(b) limit on line 21. The model added distributions (non_sch_d_capital_gains) to gross income and deducted min(3,000, losses) separately: a 5,000 long-term loss with 3,000 of distributions gave 0 in AGI instead of -2,000. - capital_losses_allowed_against_gains (new): losses allowed up to the gains in gross income, distributions included (1211(b), first part). - limited_capital_loss: the net loss up to the limit (1211(b)(1)-(2), Schedule D line 21). loss_ald deducts both. This also nets spouses' gains and losses on a joint return. - loss_limited_net_capital_gains (+ person version): Form 1040 line 7a, max(-limit, LT + ST + distributions). Net investment income no longer adds the distributions separately (Form 8960 line 5a). - has_qdiv_or_ltcg: qualified dividends, or Schedule D lines 15 and 16 both above zero (Form 1040 instructions, line 16). - dependent_taxable_ss_magi: the same netting on the dependent's return. - dc_self_employment_loss_addition: subtracts both capital parts of loss_ald. Tests: YAML cases with form line comments; grid, Hypothesis property and monotonicity tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Count distributions inside Schedule D in the NII invariant reference filer_loss_limited_net_capital_gains (from #9784) now nets the head and spouse's capital gain distributions with their Schedule D gains and losses before the 1211(b) limit, and net investment income no longer adds the distributions separately. The invariant test's reference computation follows: distributions move from the person-level Form 8960 amounts to the Schedule D inputs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test the netting when a reform drops a gross income source capital_losses_allowed_against_gains counts only the capital gains that gov.irs.gross_income.sources includes, and dependent_taxable_ss_magi nets distributions only when both sources are listed. Cover both branches with reforms that drop non_sch_d_capital_gains or capital_gains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Address review: Michigan adjustments, filer-only worksheet test, floors From the independent review of #9788: - mi_household_resources subtracted all above-the-line deductions, including the capital loss already netted in the capital gains line (MI-1040CR line 30 is U.S. Schedule 1 adjustments only). It now leaves out capital_losses_allowed_against_gains and limited_capital_loss. The two existing loss-limit cases double counted the loss: 44,000 -> 47,000 and 47,000 -> 48,500. - has_qdiv_or_ltcg figures Schedule D lines 15 and 16 over the head and spouse, so a dependent's loss cannot switch off the filer's worksheet. - Distributions are floored at zero per person in every line 7a variable (box 2a is not negative), as irs_gross_income does. - Capital losses are deductible only while capital_gains is a gross income source, matching dependent_taxable_ss_magi under such a reform. - Test that the two loss-limit parameters agree; rename the #9784 invariant test that no longer compares with the pre-change formula. - loss_ald label: "Business and capital loss ALD". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Follow 1211(b) in the #9647 invariant and a Maryland surtax test CI caught two tests written against the old capital loss formula: - test_dependent_losses_agi_invariants (#9647) compared limited_capital_loss with min(cap, sum of losses), which does not net one spouse's gains against the other's losses. Its reference now splits 1211(b) the same way: losses allowed up to the gains, plus the excess up to the cap. Renamed ..._match_all_member_formula. - md_capital_gains_surtax "partial offset" set capital_losses (a formula variable, max(0, -capital_gains)) to 50,000 next to 150,000 of net gains, a state no inputs can produce, and its comment applied the $3,000 cap to losses within gains. It now inputs the short-term loss directly (30,000 gains less 50,000 losses = -20,000): Schedule D line 16 and Form 502CG line 1 are 100,000, surtax 2,000 (same on main). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Net Michigan business and rental losses on MI-1040CR lines 16 and 17 MCL 206.508(4) adds back "any net business loss after netting all business income and loss" and "any net rental or royalty loss". The MI-1040CR nets line 16 (Schedule C, Form 4797 Part II, Schedule E Parts II and III, Schedule F) and line 17 (Schedule E Parts I and V) and floors each total at zero. Line 30 is the U.S. Schedule 1 adjustments, so loss_ald, which holds business, rental and capital losses, is no longer subtracted there. Estate and trust income and Form 4797 ordinary gains now count on line 16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep dependents' business and rental items off Michigan lines 16 and 17 MCL 206.508(3): "'Household' means a claimant and spouse." Netting every tax unit member's sources let a dependent's business or rental loss offset the claimant's income (a 15-year-old's Schedule C loss of 20,000 took the claimant's household resources from 70,000 to 50,000). Lines 16 and 17 now sum only non-dependents, as loss_ald and irs_gross_income do. Tests: three dependent YAML cases and a deterministic dependent property test. The loss_ald reform check now runs once, on the grid, instead of on every Hypothesis example; test_properties drops from 931 s in CI to about 8 s. The deterministic tests no longer need hypothesis. Small inputs are drawn at $100 or more, the tolerance docstring is corrected, and comments list Schedule E Part IV (REMIC) on line 17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Subtract only Schedule 1 adjustments on MI-1040CR line 30 Line 30 is "total adjustments from your U.S. Form 1040, Schedule 1". It used the federal above-the-line list without loss_ald, which still held four exclusions from gross income: us_bonds_for_higher_ed (IRC 135), qualified_adoption_assistance_expense (137), specified_possession_income (931) and puerto_rico_income (933). Total household resources include "all income exempt or excluded from AGI" (2025 MI-1040 book, page 26), and the excluded amounts already sit in the line 14 and 15 sources (line 15 is "All interest and dividend income (including nontaxable interest)"; adoption benefits are reported on Form W-2, box 12 code T), so line 30 took them back out. A new parameter, gov.states.mi.tax.income.household_resources_adjustments, lists the federal above-the-line deductions that are Schedule 1 Part II adjustments. Line 30 sums those the federal list deducts, so a federal reform that drops one drops it here too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tighten MI line 30 property tests and describe the input convention Review r1 on #9795: - The formula comment stated as model behaviour what is an input convention: because the federal list subtracts each exclusion from gross income, the excluded amount is entered in the income it comes from. - The differential reference took line 30's variables from the parameter under test. It now uses SCHEDULE_1_ADJUSTMENTS, written in the test from the 2025 Schedule 1, and the classification test asserts the parameter equals it. - Invariant 3 skipped every household with student loan interest. It now allows for the change D in that deduction (household resources = max(0, without - D); AGI lower by the exclusions plus D), and the grid adds six phase-out households so that case is exercised. - test_worked_example duplicated a YAML case and is dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Check each exclusion's effect on the student loan deduction in the MI grid Review r2 on #9795: in the phase-out households, savings bond interest and adoption benefits must change the student loan interest deduction and Puerto Rico income (added back under IRC 221(b)(2)(C)) must not; the grid now asserts each instead of "at least one". Possession income is left unchecked, since its effect depends on the federal modified AGI's treatment of section 931. The formula comment adds possession and Puerto Rico income to the input convention. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add the combined #9781 regression case, a joint Maryland surtax case, and move the distributions comment Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use tax_unit_non_dep_add for lines 16 and 17; describe the dependent change in the changelog Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sum Michigan line 30 over the head and spouse Review r5: since #9801, the federal above-the-line total leaves dependents' person-level items out, but line 30 summed educator_expense, early_withdrawal_penalty and traditional_ira_contributions over every member with add. It now uses tax_unit_non_dep_add, as above_the_line_deductions does. Regression case: a dependent's IRA 2,000, penalty 100 and educator expenses 300 gave 47,600; the form gives 50,000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Restore capped educator expenses in Michigan household resources --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 10, 2026
…I-1040CR lines 14-27, 30 and 31) (#9796) * Net capital gain distributions inside the capital loss limit A filer with capital losses or other capital gains enters capital gain distributions on Schedule D line 13 (2025 Instructions for Schedule D), so they net against the losses before the 26 U.S.C. 1211(b) limit on line 21. The model added distributions (non_sch_d_capital_gains) to gross income and deducted min(3,000, losses) separately: a 5,000 long-term loss with 3,000 of distributions gave 0 in AGI instead of -2,000. - capital_losses_allowed_against_gains (new): losses allowed up to the gains in gross income, distributions included (1211(b), first part). - limited_capital_loss: the net loss up to the limit (1211(b)(1)-(2), Schedule D line 21). loss_ald deducts both. This also nets spouses' gains and losses on a joint return. - loss_limited_net_capital_gains (+ person version): Form 1040 line 7a, max(-limit, LT + ST + distributions). Net investment income no longer adds the distributions separately (Form 8960 line 5a). - has_qdiv_or_ltcg: qualified dividends, or Schedule D lines 15 and 16 both above zero (Form 1040 instructions, line 16). - dependent_taxable_ss_magi: the same netting on the dependent's return. - dc_self_employment_loss_addition: subtracts both capital parts of loss_ald. Tests: YAML cases with form line comments; grid, Hypothesis property and monotonicity tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Count distributions inside Schedule D in the NII invariant reference filer_loss_limited_net_capital_gains (from #9784) now nets the head and spouse's capital gain distributions with their Schedule D gains and losses before the 1211(b) limit, and net investment income no longer adds the distributions separately. The invariant test's reference computation follows: distributions move from the person-level Form 8960 amounts to the Schedule D inputs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test the netting when a reform drops a gross income source capital_losses_allowed_against_gains counts only the capital gains that gov.irs.gross_income.sources includes, and dependent_taxable_ss_magi nets distributions only when both sources are listed. Cover both branches with reforms that drop non_sch_d_capital_gains or capital_gains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Address review: Michigan adjustments, filer-only worksheet test, floors From the independent review of #9788: - mi_household_resources subtracted all above-the-line deductions, including the capital loss already netted in the capital gains line (MI-1040CR line 30 is U.S. Schedule 1 adjustments only). It now leaves out capital_losses_allowed_against_gains and limited_capital_loss. The two existing loss-limit cases double counted the loss: 44,000 -> 47,000 and 47,000 -> 48,500. - has_qdiv_or_ltcg figures Schedule D lines 15 and 16 over the head and spouse, so a dependent's loss cannot switch off the filer's worksheet. - Distributions are floored at zero per person in every line 7a variable (box 2a is not negative), as irs_gross_income does. - Capital losses are deductible only while capital_gains is a gross income source, matching dependent_taxable_ss_magi under such a reform. - Test that the two loss-limit parameters agree; rename the #9784 invariant test that no longer compares with the pre-change formula. - loss_ald label: "Business and capital loss ALD". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Follow 1211(b) in the #9647 invariant and a Maryland surtax test CI caught two tests written against the old capital loss formula: - test_dependent_losses_agi_invariants (#9647) compared limited_capital_loss with min(cap, sum of losses), which does not net one spouse's gains against the other's losses. Its reference now splits 1211(b) the same way: losses allowed up to the gains, plus the excess up to the cap. Renamed ..._match_all_member_formula. - md_capital_gains_surtax "partial offset" set capital_losses (a formula variable, max(0, -capital_gains)) to 50,000 next to 150,000 of net gains, a state no inputs can produce, and its comment applied the $3,000 cap to losses within gains. It now inputs the short-term loss directly (30,000 gains less 50,000 losses = -20,000): Schedule D line 16 and Form 502CG line 1 are 100,000, surtax 2,000 (same on main). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Net Michigan business and rental losses on MI-1040CR lines 16 and 17 MCL 206.508(4) adds back "any net business loss after netting all business income and loss" and "any net rental or royalty loss". The MI-1040CR nets line 16 (Schedule C, Form 4797 Part II, Schedule E Parts II and III, Schedule F) and line 17 (Schedule E Parts I and V) and floors each total at zero. Line 30 is the U.S. Schedule 1 adjustments, so loss_ald, which holds business, rental and capital losses, is no longer subtracted there. Estate and trust income and Form 4797 ordinary gains now count on line 16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep dependents' business and rental items off Michigan lines 16 and 17 MCL 206.508(3): "'Household' means a claimant and spouse." Netting every tax unit member's sources let a dependent's business or rental loss offset the claimant's income (a 15-year-old's Schedule C loss of 20,000 took the claimant's household resources from 70,000 to 50,000). Lines 16 and 17 now sum only non-dependents, as loss_ald and irs_gross_income do. Tests: three dependent YAML cases and a deterministic dependent property test. The loss_ald reform check now runs once, on the grid, instead of on every Hypothesis example; test_properties drops from 931 s in CI to about 8 s. The deterministic tests no longer need hypothesis. Small inputs are drawn at $100 or more, the tolerance docstring is corrected, and comments list Schedule E Part IV (REMIC) on line 17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Count only the claimant and spouse in Michigan household resources MCL 206.508(3) defines the household as "a claimant and spouse", and the MI-1040CR asks for the income "you and your spouse received". Every household resources source except lines 16 and 17 was summed over all tax unit members, so a dependent's wages, interest, pensions and capital gains raised the claimant's household resources, and a dependent's Schedule 1 adjustments (such as the deduction for half of self-employment tax) lowered them. - Sources are summed over the head and spouse with tax_unit_non_dep_add. - Line 21 (Social Security, SSI and railroad retirement, including amounts received for minor children or dependent adults), line 22 (child support) and line 27 (public assistance paid to the household) still count for every member, as the form says. - Line 19 reads filer_loss_limited_net_capital_gains, the head and spouse's Schedule D. - Line 30 sums the head and spouse's Schedule 1 adjustments, with the self-employment adjustments read per person. - Line 31 premiums paid for the family are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Give the membership property tests an explicit FIP grant With no income, the model computes a Michigan FIP grant (tanf) for the test household, which counts on line 27 but was missing from the test's reference. Each SPM unit now gets a tanf input, drawn at random in the Hypothesis test and counted in full on line 27 of the reference. The Hypothesis tests also run more examples (50 and 30). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep dependents' above-the-line deductions off the filer's AGI irs_gross_income leaves tax unit dependents' income off the filer's return, but self_employment_tax_ald, self_employed_health_insurance_ald and self_employed_pension_contribution_ald summed every member's person-level amount, and above_the_line_deductions summed every member's IRA contributions, early withdrawal penalty, educator expenses, adoption assistance and education bond interest. A dependent's Schedule SE and Schedule 1 deductions belong on the dependent's own return. - The three self-employment aggregates sum their _person variables over non-dependents; alimony_expense_ald masks dependents. - above_the_line_deductions sums gov.irs.ald.deductions with tax_unit_non_dep_add. - Readers that sum the ALD list themselves do the same: taxable_ss_magi, taxable_uc_agi, student_loan_interest_ald_magi, adjusted_gross_income_person and ma_part_b_agi. - mo_adjusted_gross_income takes personal ALDs over non-dependents, so its remaining-ALD allocation never goes negative. - medicaid_adjusted_gross_income_person attributes a dependent's own person-level deductions to the dependent instead of the head. - ma_gross_income_loss_adjustment leaves out dependents' losses, as the federal gross income it adjusts does. The _person variables keep each person's own amount, which a dependent's own return (dependent_taxable_ss_magi) uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test that the ALD total stays between 0 and the all-member sum Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Read the federal Schedule 1 aggregates on Michigan line 30; reformable member lists Review r1: - Line 30 reads the tax-unit adjustments as they are, so supplied inputs and reforms of self_employment_tax_ald and the other aggregates are respected. #9801 (merged in) makes those aggregates and alimony_expense_ald leave dependents out. - The every-member sources (lines 21, 22 and 27) move to a parameter, gov.states.mi.tax.income.household_resources_all_members, and a source defined for a group larger than the tax unit (an SPM unit amount) is aggregated as a household amount, so a reform cannot hit an entity error. - gi_cash_assistance counts only for the claimant and spouse: nothing shows a pilot payment is public assistance paid to the claimant's household. - Tests: dependent alimony and guaranteed income YAML cases; property tests always have a dependent and a positive-resources household; a reform test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add the combined #9781 regression case, a joint Maryland surtax case, and move the distributions comment Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use tax_unit_non_dep_add for lines 16 and 17; describe the dependent change in the changelog Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep a supplied net_capital_gains amount on the filer's line 7a; add aggregate-input cases Review r1 finding 1: filer_loss_limited_net_capital_gains summed the head's and spouse's components, so a tax unit net_capital_gains input was ignored (wages 10,000 plus a 5,000 aggregate gain gave 10,000, not 15,000). It now takes net_capital_gains less the dependents' own gains and losses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Document supplied net_capital_gains on the filer's line 7a; add NII and SE health insurance cases Review r2 follow-ups: a supplied net_capital_gains reaches net investment income (YAML case), a supplied self-employed health insurance deduction comes off Michigan line 30 (YAML case), and the variable documents how a supplied total combines with dependents' person-level gains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Pass include_dependents on Michigan line 30; test a dependent's positive Schedule C and F income With #9801 on main: line 30 sums gov.irs.ald.filer_amounts_recorded_on_dependents over every member, as above_the_line_deductions does, and the losses test now draws positive dependent Schedule C and F income, whose self-employment tax deduction is on the dependent's own return. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use shared filer Schedule D lines without dependent rounding drift * Preserve supplied capital gains without rounded residuals * Recognize Michigan dependent pension SSI interaction (d1143) * Compute dependent SSI in Michigan retirement regression * Cite the 2025 MI-1040CR-7 book for Michigan household resources michigan.gov has removed the 2025 home heating credit book (TY2025/MI-1040CR-7-Book.pdf now returns 404), so cite the Wayback Machine capture of 2026-02-18. It is byte-identical to the NBER TAXSIM mirror (sha256 f540a3dd...). Its total household resources lines 17-33 say the same as MI-1040CR lines 14-31 about whose income counts: "you and your spouse", Social Security "for minor children or other dependent adults who live with you" (line 24), child support and foster care payments (line 25), MDHHS payments "made to your household" (line 30), and premiums "for yourself and your family" (line 33). References only; no formula or value changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 13, 2026
#9890) * Give each spouse their own above-the-line deductions in per-person AGI adjusted_gross_income_person split every above-the-line deduction other than the three self-employment ones 50/50 between head and spouse on a joint return. Each person now takes their own deductions through above_the_line_deductions_person; only tax-unit-level inputs (HSA, tuition and fees, domestic production, possession income) are divided equally. Adds alimony_expense_ald_person, loss_ald_person and limited_capital_loss_person, moves Medicaid's per-person AGI and Montana's Social Security worksheet onto the same attribution, and applies Montana's capital loss rule for spouses filing separately (MCA 15-30-2110(6)). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Split loss_ald into limited_business_loss and the capital loss deduction loss_ald_person now divides the Section 461(l)-limited business loss by each spouse's business losses and the rest of loss_ald by their capital losses, so it stays right when loss_ald gains capital components (#9788). Adds the filer_share helper used by the per-person deduction variables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Leave Medicaid AGI to a separate fix Attributing each spouse's deductions in Medicaid AGI without also netting the couple's MAGI before medicaid_magi_person's zero floor moved Medicaid eligibility in both directions; the two belong in one Medicaid change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * WIP: drop the Montana capital loss override (ARM 42.15.206(3)(a)); review r1 fixes; strengthen property test The property test's new independent 461(l) check still has a test-side indexing bug: the model gives the right limited_business_loss (256,000 for a 2026 single filer with a 1.5M loss). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Restore main's Medicaid AGI tests after the rebase * Leave filer amounts recorded on a dependent off the dependent's own deductions above_the_line_deductions_person gave a tax unit dependent every person-level deduction recorded on them, including employer adoption assistance and education savings bond interest, which gov.irs.ald.filer_amounts_recorded_on_dependents marks as the filer's. Those now count only for the head and spouse, whose parts already take them up through above_the_line_deductions. The dependent's part matters once Medicaid AGI reads it for a dependent's own return. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Divide a filer amount recorded on a dependent equally between head and spouse Education savings bond interest and employer adoption assistance recorded on a dependent are the filer's (gov.irs.ald.filer_amounts_recorded_on_dependents), but which spouse's is not recorded. They reached the head's and spouse's parts through the reconciliation to above_the_line_deductions, in proportion to each spouse's other deductions, so the spouse's IRA deduction changed the head's share. They are now divided equally, as the other amounts recorded only for the return are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fix the spouse deduction invariant test's harness and numpy references - Units that set a tax-unit deduction directly run in their own simulation. An input given for one tax unit is an input for every unit in a simulation, so one unit's loss_ald set to 0 zeroed every other unit's. - The Section 461(l) reference keeps each business source's gain and loss separate (aggregate income against aggregate deductions), as the model does, rather than netting a person's sources first. - The capital loss reference nets losses against capital gains and distributions before the 1211(b) limit, as main does since #9788. - The alimony identity skips units that set alimony_expense_ald directly: alimony_expense_ald_person stays each payer's own alimony there. - The reference gives a dependent's filer amounts to the head and spouse equally. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Give the determinism test's stand-in ALD parameters the filer amount list above_the_line_deductions_person now reads gov.irs.ald.filer_amounts_recorded_on_dependents. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Floor Michigan and Pennsylvania withholding at zero for a negative spouse AGI With each spouse's own deductions, a spouse with a business loss or an IRA deduction above their income has negative AGI, and these two withholding estimates multiplied it by the rate. Every other state's withholding formula already floors its base at zero. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Prorate Virginia additions by each spouse's positive federal AGI va_agi_person divides tax-unit additions by each spouse's share of federal AGI. A spouse with negative AGI got a negative share and the other spouse more than all of it. A spouse with negative AGI now gets none, as #9878 does for Delaware's itemized deductions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Skip only directly set alimony in the spouse identity check Directly set loss_ald still reconciles through loss_ald_person, so its identity is checked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep Montana's losses divided equally between spouses until its own rules are modeled Montana spouses who filed separately on one form through 2023 allocate capital losses by one of two elections (ARM 42.15.206(3)) and recompute the Section 461(l) limit with the single filer's threshold. Neither is modeled. Giving each spouse their own federal losses instead of half moved Montana away from both. With one spouse's $1,000 gain against the other's $3,000 loss, the loss spouse's AGI was $7,000, though separate tracking caps the loss at $1,500 ($8,500). A $600,000 business loss on one spouse used the joint limit, lowering tax by $45.65 against main. mt_loss_ald_reallocation adds back to each spouse's federal AGI the difference between their own loss_ald_person and an equal share of the return's loss_ald, so Montana divides losses as before. The IRA and other deductions still go to the spouse who has them (former MCA 15-30-2110(8); ARM 42.15.206(1)). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Base Montana's joint standard deduction and medical floor on the joint return's AGI mt_standard_deduction_joint and mt_medical_expense_deduction_joint added each spouse's mt_agi_indiv, which is floored at zero. With each spouse's own deductions, a spousal IRA above that spouse's income was lost to the floor: head wages $30,000 and a $6,000 spousal IRA gave a joint deduction of $6,000 (20% of $30,000) instead of $4,920 (the floor, 20% of the joint $24,000 being less). Both now read mt_agi_joint, the joint column's Montana AGI through 2023. Their tests take mt_agi_joint as the input. Adds the spousal IRA case, a single filer's loss and a case with student loan interest and an IRA in each spouse's own column. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use the joint Montana AGI for the medical floor only through 2023 Review r5: the medical floor had no year gate, so reading mt_agi_joint also changed 2024 and later, when mt_agi_indiv is zero for everyone and main's floor was zero. From 2024 Montana starts from federal itemized deductions, whose floor is a share of federal AGI, a separate fix. The joint AGI now applies while married filing separately on the same return is allowed (through 2023); 2024 on is unchanged from main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Note that Montana's 2024+ medical floor is zero, as on main Comment only (review r6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Limit DC separate-filing capital losses per spouse; stop Montana spouse allocation from 2024 Per Max's d1014 ruling: - DC: spouses filing separately on the same return each deduct their own capital losses up to their own capital gains plus the $1,500 married filing separately limit (D-40 instructions, line c), via dc_separate_capital_loss_adjustment. It applies only to the separate column; dc_taxable_income_joint keeps the federal joint deduction. - Montana: mt_loss_ald_reallocation and mt_applicable_ald_deductions apply only while spouses may file separately on the same form (through 2023). Adds YAML cases and DC/Montana invariants to the spouse property test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Base DC's separate-filing capital adjustment on the capital part of loss_ald Review r7: dc_separate_capital_loss_adjustment removed the computed capital loss deduction even when loss_ald was set directly, so it took out an amount federal AGI did not contain. It now removes the capital part of each spouse's loss_ald_person (loss_ald less the business loss, by own capital losses). Adds YAML cases with loss_ald set to $0 and $1,000, and the property test checks every unit against that capital part, keeping the nonnegative couple sum for computed units only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Take DC's self-employment loss add-back from the business part of loss_ald Review r8: with loss_ald set directly and both business and capital losses, dc_self_employment_loss_addition isolated the business loss by subtracting the computed capital deduction, while loss_ald_person (and so federal AGI and the DC capital adjustment) takes the business part first. Use min(limited_business_loss, loss_ald), as loss_ald_person does; the amount is unchanged when loss_ald is computed. Adds computed and direct mixed-loss YAML cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Align spouse invariants with shared IRA compensation limits * Account for IRA phaseouts in deduction invariants * Preserve hash-seed coverage without repeated country startup * Avoid reallocating owned federal losses twice for Kentucky --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Capital gain distributions reported without Schedule D (
non_sch_d_capital_gains, PUF E01100) entered gross income as their own source, and the capital loss deduction wasmin($3,000, losses)computed separately. A filer with capital losses must file Schedule D and enter the distributions on line 13, where they net against the losses before the line 21 limit. Example: long-term loss −5,000 and distributions 3,000. Schedule D line 16 is −2,000, so the deductible loss is 2,000 and AGI from capital gains is −2,000. The model gave 3,000 − 3,000 = 0.This PR makes AGI's capital gain or loss equal Form 1040 line 7a,
max(−limit, LT + ST + distributions), for the filers on the return. The path without Schedule D is unchanged: with no other capital gains or losses, the amount is the distributions, entering gross income as before.#9781 is merged, so the order below is met. #9781 does the section 1(h) side:
net_capital_gainand the Schedule D Tax Worksheet net distributions with Schedule D gains and losses. On main,net_capital_gainstill adds the distributions outside the netting. So this PR alone would take netted distributions out of taxable income whilecapital_gains_taxstill gave them the preferential rate. Example: single, 2025, wages 100,000, long-term loss −8,000, distributions 5,000. Taxable income 81,250 would then have 5,000 taxed at 15% instead of 22%, $350 too little (main is $750 too much, from AGI). The two PRs merge without conflicts. On a trial merge of this branch with #9781's head (a3371b8f1f), that household gets AGI 97,000,net_capital_gain0 andincome_tax_main_rates12,789 (2025 single brackets on 81,250), and both PRs' tests pass (283 YAML, 25 Python). #9781 is now on main. This branch merges main at6c15a622ab(head638c794a18) and adds that case as a YAML test. On the merged code it gives AGI 97,000,net_capital_gain0 andincome_tax_main_rates12,789.The law and the forms
26 U.S.C. 1211(b): "In the case of a taxpayer other than a corporation, losses from sales or exchanges of capital assets shall be allowed only to the extent of the gains from such sales or exchanges, plus (if such losses exceed such gains) the lower of— (1) $3,000 ($1,500 in the case of a married individual filing a separate return), or (2) the excess of such losses over such gains."
26 U.S.C. 852(b)(3)(B): "A capital gain dividend shall be treated by the shareholders as a gain from the sale or exchange of a capital asset held for more than 1 year."
26 U.S.C. 1222: (3) long-term capital gain is "gain from the sale or exchange of a capital asset held for more than 1 year, if and to the extent such gain is taken into account in computing gross income"; (9) "capital gain net income" is "the excess of the gains from sales or exchanges of capital assets over the losses from such sales or exchanges"; (10) "net capital loss" is "the excess of the losses from sales or exchanges of capital assets over the sum allowed under section 1211".
2025 Instructions for Schedule D, "Capital Gain Distributions" (page 2): "Enter on Schedule D, line 13, the total capital gain distributions paid to you during the year, regardless of how long you held your investment. This amount is shown in box 2a of Form 1099-DIV."
2025 Schedule D (page 2): line 16, "Combine lines 7 and 15", "If line 16 is a gain, enter the amount from line 16 on Form 1040 ... line 7a"; line 21, "If line 16 is a loss, enter here and on Form 1040 ... line 7a, the smaller of: • The loss on line 16; or • ($3,000), or if married filing separately, ($1,500)".
2025 Instructions for Form 1040, line 7a (page 31): "Exception 1. You don't have to file Form 8949 or Schedule D if you aren't deferring any capital gain by investing in a qualified opportunity fund and both of the following apply. 1. You have no capital losses, and your only capital gains are capital gain distributions from Form(s) 1099-DIV, box 2a ..." Line 16 (page 36): use the Qualified Dividends and Capital Gain Tax Worksheet if "You reported qualified dividends on Form 1040 or 1040-SR, line 3a", "You don't have to file Schedule D and you reported capital gain distributions on Form 1040 or 1040-SR, line 7a", or "You are filing Schedule D, and Schedule D, lines 15 and 16, are both more than zero."
Form 8960 line 5a (2025 instructions): the net gain or loss from "Form 1040 or 1040-SR, line 7a, and Schedule 1 (Form 1040), line 4".
Changes
The capital loss deduction (inside
loss_ald) now follows 1211(b) in two parts:capital_losses_allowed_against_gains(new, TaxUnit): losses allowed to the extent of the capital gains thatirs_gross_incomecounts (each filer's positive net gain and the distributions),min(losses, gains).limited_capital_loss: the net loss up to the limit,min(limit, losses − allowed against gains), which is Schedule D line 21 as a positive number. It keeps its meaning for its readers: Missouri's property tax credit adds back "capital loss from Federal Form 1040" (MO-PTS line 7), Wisconsin compares the "loss from line 7 of federal Form 1040" with its own limit (Schedule WD line 29e), and Maryland's surtax subtracts it.loss_alddeducts both.irs_gross_incomeis unchanged (gains, not losses). Gross gains less both parts ismax(−limit, gains − losses).Because the netting is now at the tax unit level, spouses' gains and losses also net on a joint return. Before, gross income took one spouse's 10,000 gain and only 3,000 of the other's 5,000 loss came off (7,000); now it is 5,000. Dependents stay off the return, as in
irs_gross_income.Other readers of the two variables:
loss_limited_net_capital_gainsis Form 1040 line 7a,max(−limit, net_capital_gains + distributions). Without Schedule D items it is the distributions, the same amount the filer reports directly.gov.irs.investment.income.sources) readsfiler_loss_limited_net_capital_gains(from Leave dependents' investment income out of the filer's NIIT base #9784: the head and spouse only), which now includes their distributions, so it is their Form 1040 line 7a (Form 8960 line 5a). It no longer addsnon_sch_d_capital_gainsas well, which counted the distributions next to a separately limited loss. Leave dependents' investment income out of the filer's NIIT base #9784's invariant test (tests/core/test_dependent_net_investment_income_invariants.py) computed the old way; its reference now puts distributions with the Schedule D inputs.loss_limited_net_capital_gains_personadds each person's distributions before allocating a net loss.loss_limited_net_capital_gains. The 2025 MI-1040 book, line 19: "the total of short-term and long-term gains, less short-term and long-term losses from your U.S. Schedule D (losses cannot exceed $3,000 ...)". Schedule D's long-term part includes line 13.has_qdiv_or_ltcg: qualified dividends, or the head and spouse's Schedule D lines 15 (LT + distributions) and 16 (line 15 + ST) both above zero, per the line 16 instructions. Without Schedule D items, lines 15 and 16 are the distributions, which is the second condition. Before, any positive long-term gain or distribution turned it on even when line 16 was a loss, and a short-term-only gain did too. Lines 15 and 16 leave out dependents, as AGI does, so a dependent's loss cannot switch off the filer's worksheet.mi_household_resourcesnow subtracts the deductions without the two capital parts. The two existing loss-limit cases encoded the double count: 44,000 becomes 47,000 and 47,000 becomes 48,500.irs_gross_incomedoes.capital_gainsout ofgov.irs.gross_income.sourcesalso stop the capital loss deduction (both parts), asdependent_taxable_ss_magialready did. The distributions stay in gross income.dependent_taxable_ss_magi(the dependent's own-return modified AGI, IRC 86(b)(2)): the dependent's distributions net with their gains and losses inside the limit.dc_self_employment_loss_addition, which isolates the self-employment loss inloss_ald, subtracts both capital parts.eitc_relevant_investment_incomealready usedmax(0, net_capital_gains + distributions)(Pub. 596 Worksheet 1 line 5, Form 1040 line 7a or zero if a loss), so it is unchanged.non_sch_d_capital_gainsgets documentation and a reference;loss_ald's label becomes "Business and capital loss ALD".Invariants (stated and tested)
For every combination of long-term and short-term gains and losses and distributions, filing single, separately or jointly (gains and losses split between spouses):
loss_limited_net_capital_gainsequalmax(−limit, LT + ST + D).capital_losses_allowed_against_gains=min(losses, gains);limited_capital_loss=max(0, −line 7a), between 0 and the limit; their sum = the 1211(b) allowancemin(losses, gains + limit); gains less both = line 7a.has_qdiv_or_ltcgholds exactly when lines 15 and 16 are both above zero (no qualified dividends in the test).loss_limited_net_capital_gains_personshares sum to the tax unit amount, to within $0.01 (a net loss is split in proportion, a division that single precision rounds).max(−3,000, LT + ST + D), and none of it reaches the head's return.gov.irs.ald.loss.capital.max, read by the deduction, andgov.irs.capital_gains.loss_limit, read by the line 7a variables) agree for every filing status, 2013 to 2035, which invariant 1 relies on.Tests:
policyengine_us/tests/test_capital_gain_distributions_loss_limit.py(a 432-household grid and the worked example, which run without Hypothesis; reforms that dropcapital_gainsornon_sch_d_capital_gainsfromgov.irs.gross_income.sources, where the netting follows the sources; and Hypothesis property, monotonicity and dependent tests), and.../adjusted_gross_income/schedule_d_capital_gain_distributions.yaml(16 cases with Schedule D line comments, including a dependent's loss, a negative input, and the combined case with #9781's section 1(h) netting on main: AGI 97,000,net_capital_gain0,income_tax_main_rates12,789), and two Michigan cases with MI-1040CR line comments. The original 13 YAML cases and the grid, example and dependent tests fail on main and pass here. The 205 existing YAML tests that read any of the changed variables pass, apart from the two Michigan expectations above. All 601 Michigan tests pass. In #9784's invariant test, the reference puts distributions with the Schedule D inputs, andtest_units_without_dependents_match_pre_change_formulabecomes..._match_all_member_formula, since it now compares with the all-member formula rather than main's. Two more tests were written against the old loss formula. In #9647'stest_dependent_losses_agi_invariants, the reference wasmin(cap, Σ losses)with no cross-spouse netting; it now splits 1211(b) the same way, and the test is renamed the same way. Maryland's surtax "partial offset" case setcapital_losses, a formula variable equal tomax(0, −capital_gains), to 50,000 beside 150,000 of net gains. No inputs can produce that, and its comment applied the $3,000 cap to losses within gains. It now inputs the short-term loss directly (−20,000) and expects 2,000: Form 502CG line 1 is federal line 7a, 100,000. That value is the same on main. A new joint Maryland case puts one spouse's 20,000 short-term loss within the other's 100,000 long-term gain. It expects 1,600 (Form 502CG line 1 = federal line 7a = 80,000). Main gives 1,540, because it subtracts a $3,000 capped loss again.On head
638c794a18(main merged), these all pass, run one process at a time: the three Python test files (33 passed); YAMLgov/irs/income(396),gov/states/md/tax/income(219),gov/states/mi(601) andgov/states/dc/tax/income(114). The independent delta review (r3, Opus 5.5) approves this head.The
hypothesisdev dependency hunk (pyproject and uv.lock) is identical to #9781's and #9761's, so any of them can merge first.Microsimulation (default dataset, 2026, policyengine-core 3.32.12)
Main (merge base
4de4dcb9c0) and this branch (fb5ccb25fc), run one at a time under the shared heavy-job lock and a 24 GB watchdog (peak 15.5 GB each), onpopulace_us_2024.h5@populace-us-2024-spm-20260909, 79,729 tax units.The dataset has no capital losses: no person has a negative long-term or short-term gain. So the AGI fix itself moves nothing:
adjusted_gross_income(weighted)net_investment_income/ NIITincome_tax,regular_tax_before_credits,alternative_minimum_taxloss_limited_net_capital_gainsstate_income_taxState income tax, by state. These are the readers of
loss_limited_net_capital_gains(_person), which now carry capital gain distributions:Other changes:
has_qdiv_or_ltcgturns off for 6 units: 1 with only a short-term gain, and 5 where only a dependent's gains turned it on before.dwks13,dwks14anddwks19change for them, butregular_tax_before_credits,alternative_minimum_taxandincome_taxare identical.dependent_taxable_ss_magidiffers by $0.01 for 2 dependents with distributions: single-precision addition order.dependent_taxable_social_securityis identical.capital_losses_allowed_against_gainsandlimited_capital_lossare zero everywhere, as there are no losses.Scripts, logs and per-variable tables:
~/reviews/pe-us-schd-distributions-agi-2026-10-03/microsim/(diff_2026.txt,state_breakdown_2026.txt).Not in this PR (follow-ups)
wi_capital_loss) nets only short- and long-term gains; Schedule WD line 14 is capital gain distributions, and line 28 also caps the loss at Wisconsin ordinary income.md_capital_gains_surtaxuses short- plus long-term gains lesslimited_capital_loss, which leaves out distributions.loss_limited_net_capital_gainsandnet_capital_gainssum every tax unit member, dependents included, while AGI excludes dependents. This PR keeps that membership.loss_aldafter flooring business and rental income at zero. MI-1040CR line 30 takes only U.S. Schedule 1 adjustments.axiom: us:statutes/26/1211#other_taxpayer_capital_losses_allowed encoded-correct for the 1211(b) allowance (companion tests
other_taxpayer_excess_loss_capped,other_taxpayer_losses_do_not_exceed_gains); TheAxiomFoundation/rulespec-us#1490 queued for 26 USC 852(b)(3)(B), capital gain dividends as long-term capital gains (blocked: section 852 is not in the pinned corpus, and the signed run needs approval)🤖 Generated with Claude Code