Skip to content

Apply the Form 4952 election in Schedule D Tax Worksheet lines 3-10 - #9781

Merged
MaxGhenis merged 5 commits into
mainfrom
dwks-form-4952-election
Oct 5, 2026
Merged

MaxGhenis merged 5 commits into
mainfrom
dwks-form-4952-election

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The Schedule D Tax Worksheet lines in the model did not apply the Form 4952 line 4g investment income election the way the worksheet does, and read a different input from net_capital_gain. With a $50,000 election against a $300,000 long-term gain, net_capital_gain was $250,000 but dwks10 (worksheet line 10) $300,000. dwks10 feeds dwks13, dwks14, dwks19, regular_tax_before_credits and Form 6251 Part III (amt_tax_including_cg).

This PR makes dividend_income_reduced_by_investment_income, dwks09 and dwks10 follow worksheet lines 3 to 10, and makes net_capital_gain and adjusted_net_capital_gain apply the same election under 26 U.S.C. 1(h)(2) and 1(h)(11)(D)(i). Line 10 now equals net_capital_gain for the same inputs.

The law and the forms

2025 Schedule D Tax Worksheet (Instructions for Schedule D, page 15): line 2 qualified dividends; line 3 "the amount from Form 4952 ... line 4g"; line 4 "the amount from Form 4952, line 4e"; line 5 = line 3 − line 4, not below zero; line 6 = line 2 − line 5, not below zero; line 7 "the smaller of line 15 or line 16 of Schedule D"; line 8 "the smaller of line 3 or line 4"; line 9 = line 7 − line 8, not below zero; line 10 = lines 6 + 9.

2025 Form 4952: line 4d is "the excess, if any, of your total gains over your total losses from the disposition of property held for investment ... include capital gain distributions"; line 4e is "the smaller of line 4d or your net capital gain from the disposition of property held for investment", that is "the excess, if any, of your net long-term capital gain over your net short-term capital loss", with capital gain distributions "treated as long-term capital gains"; line 4g is "the amount from lines 4b and 4e that you elect to include in investment income". The line 4g instructions: the amount "is generally treated as being attributable first to net capital gain from property held for investment (line 4e), and then to qualified dividends (line 4b)", and "Don't reduce the amount of qualified dividends on Form 1040 ... line 3a ... by any part of the amount on line 4g."

26 U.S.C. 1(h)(2): "the net capital gain for any taxable year shall be reduced (but not below zero) by the amount which the taxpayer takes into account as investment income under section 163(d)(4)(B)(iii)."
26 U.S.C. 1(h)(11)(D)(i): "Qualified dividend income shall not include any amount which the taxpayer takes into account as investment income under section 163(d)(4)(B)."
26 U.S.C. 163(d)(4)(B): "(iii) so much of the net capital gain ... as the taxpayer elects to take into account under this clause. Such term shall include qualified dividend income (as defined in section 1(h)(11)(B)) only to the extent the taxpayer elects to treat such income as investment income".

The two inputs

  • investment_income_elected_form_4952 (Person) is Form 4952 line 4g. The default dataset (populace_us_2024.h5@populace-us-2024-spm-20260909) fills it for 135 people (135 tax units), and it is uprated in default_uprating.py. net_capital_gain already read it.
  • investment_income_form_4952 (TaxUnit) is filled by no dataset (zero for every unit in the default dataset). It is the input Tax-Calculator's e58990 port gave the worksheet; its only other reader, ca_investment_interest_deduction, uses it as FTB 3526 line 9, which is "the amount from federal Form 4952, line 8" (the deduction, not line 4g). The worksheet no longer reads it; its documentation now says so. California is unchanged.

Changes

  • New helper schedule_d_tax_worksheet_form_4952_lines (worksheet lines 3, 4 and 7), shared by lines 6 and 9.
    • Line 3: Form 4952 line 4g, summed over the tax unit (not below zero).
    • Line 4: Form 4952 line 4e, the smaller of line 4d and the net capital gain from investment property. Assumption: every capital asset is property held for investment (the model has no split), and there is no input for the "Elec." amount a filer may write beside line 4e, so the election comes from gain first, as by default.
    • Line 7: the smaller of Schedule D lines 15 and 16. Capital gain distributions (non_sch_d_capital_gains) belong on Schedule D line 13 ("Enter on Schedule D, line 13, the total capital gain distributions"), so they enter lines 15 and 16.
  • dividend_income_reduced_by_investment_income is line 6; dwks09 is line 9; dwks10 adds lines 6 and 9 (the old no-gains branch gave the same result for every valid input).
  • net_capital_gain: section 1222(11) gain (distributions netted as long-term gain), less the gain part of the election (1(h)(2)), plus qualified dividends less the rest of the election (1(h)(11)(D)(i)). Before, an election above the gain was ignored, and distributions sat outside the netting and the election.
  • adjusted_net_capital_gain adds back the qualified dividends left after 1(h)(11)(D)(i), min(max(0, QDI), net_capital_gain), not all of them. capital_gains_tax's max_(0, net_cg - qualified_dividends) already equals the gain after the election, so it is unchanged.
  • dwks09 no longer drops Schedule D gains when capital gain distributions are also positive. Before, it was where(distributions > 0, distributions, Schedule D gain).
  • Documentation and references on both inputs.

Invariants (stated and tested)

For every combination of long-term and short-term gains and losses, capital gain distributions, qualified dividends, elections, unrecaptured section 1250 gain and 28-percent rate gain:

  1. dwks10 == net_capital_gain (worksheet route = statute route).
  2. dwks13 == adjusted_net_capital_gain (worksheet line 13 = section 1(h)(3)).
  3. Lines 6, 9 and 10 equal an independent line-by-line transcription of the worksheet and Form 4952 lines 4d and 4e.
  4. Bounds: max(0, G + Q − E) <= line 10 <= G + Q, where G is the Schedule D gain before the election, Q the dividends and E the election.
  5. Monotonicity: line 10 never rises as the election rises, and falls by at most the extra amount elected.

Intended exception. With amounts in cents, 1 and 2 hold to within single-precision storage rounding: lines 6 and 9 are each stored as float32 before dwks10 adds them. On the default dataset 738 tax units differ by at most $0.25. All 738 are among the 819 units where the two differ on main, the other 81 being units this PR fixes. The tests use whole dollars up to $2,000,000, where every sum is exact, and compare exactly.

Tests: policyengine_us/tests/test_form_4952_election_worksheet.py (Hypothesis differential and property tests plus a 240-case grid), and capital_gains/schedule_d_tax_worksheet_form_4952.yaml (13 cases with worksheet line comments, including the $300,000 / $50,000 example and a 2025 tax and Form 6251 Part III case). All four Python tests fail on main and pass here. Locally, 2,699 YAML tests pass in gov/irs plus states HI, VT, ID and CA income tax.

Microsimulation (default dataset, 2026, policyengine-core 3.32.12)

Main (3c336f251d, after #9761) and this branch (ea06980c86); re-run 2026-10-04 with the same result as the first run on 6b0e773868 / 72b76cb258 (per-unit table identical), run one at a time under the shared heavy-job lock and a 24 GB watchdog (peak footprint 14.4 GB each). 135 of 79,729 tax units change: 132 that elect, and 3 with capital gain distributions alongside Schedule D gains. Every other unit is bitwise identical on all 29 measured variables.

main branch change
dwks10 (weighted) $1,816.11B $1,818.47B +$2.36B
net_capital_gain $1,819.88B $1,818.47B −$1.40B
income_tax_main_rates +$397.8M
capital_gains_tax −$230.6M
alternative_minimum_tax $11.904B $11.211B −$692.8M
income_tax $2,592.280B $2,591.755B −$525.6M
state_income_tax −$0.22 (one unit, $0.11)

By cause:

  • Electing units (132 changed): income tax +$174.3M. Elected dividends lose the capital gains rates in net_capital_gain (63 units), and Form 6251 Part III now sees the election: AMT +$7.1M across 2 units.
  • Distributions alongside Schedule D gains (3 units): income tax −$699.9M, all from one record (weight 6,610; long-term gain $1,554,762, short-term $209,132, distributions $40,164, dividends $465,786). Main's dwks09 used only the $40,164 of distributions, so Part III taxed the $1.55M long-term gain at 26/28%. That gave an AMT of $112,099 per unit, $6,210 on this branch.

Per-unit table of all 135 changed units, scripts and logs: ~/reviews/pe-us-dwks-4952-2026-10-03/microsim/ (diff_2026.txt, breakdown_2026.txt).

Interaction with #9761 (merge gate)

#9761 (section 911(f) stacking) measures the worksheet's capital gain excess from dwks10 and the section 1(h) excess from net_capital_gain, and its helper's docstring says the two "can disagree (they read different Form 4952 inputs)". After both merge they agree, apart from the storage rounding above. Its two synthetic cases (amt_section_911_capital_gain_excess.yaml, capital_gains/dwks14.yaml) set dwks10 and net_capital_gain apart by direct input and stay valid. #9761 has merged; ea06980c86 carries the follow-up: it updates that docstring and starts section_911_qualified_dividend_income from the dividends after 1(h)(11)(D)(i), min(max(0, QDI), net_capital_gain). Otherwise an excluding filer who elects dividends gets them back at the capital gains rates: all three reviews found this. Example: long-term gain 20,000, dividends 30,000, election 35,000 and capital gain excess 5,000 give 25,000 of section 911 dividends, where 10,000 is right. On the merged head, the capital gains, AMT and FEIE YAML folders pass (149 tests), as do this PR's and #9761's Python tests (14). This PR carries the same hypothesis dev dependency hunk as #9761, so either can merge first.

Reviews

Round 1, at 72b76cb258: three APPROVEs.

  • GPT-6.1 Sol, hard tier: review-r1-sol.md.
  • Opus 5.5, standard tier, two runs: review-r1-opus.md and review-r1b-opus.md.

All are in ~/reviews/pe-us-dwks-4952-2026-10-03/. Their one Medium finding is the #9761 interaction above. The Lows are fixed in 9a158d2ded:

  • the 2025 tax case now notes the Tax Table rounding;
  • the label and documentation of investment_income_form_4952 and adjusted_net_capital_gain are corrected;
  • this body is corrected.

Pre-existing gaps the reviews raised are listed below.

Not in this PR

  • The federal model deducts investment interest in full (investment_interest_expense → non_mortgage_interest → deductible_interest_expense), without the section 163(d)(1) net investment income limit. The election exists to raise that limit, so in the model it has only its capital gains side, and electing units are over-benefited on the deduction side. This is unchanged.
  • The loss limitation (loss_limited_net_capital_gains) still keeps capital gain distributions out of Schedule D netting. The default dataset has no capital losses, so there is no effect.
  • The QBID taxable income limit subtracts adjusted_net_capital_gain, where section 199A(a)(2)(B) says net capital gain. This is separate.
  • capital_gains_tax taxes 28-percent rate gain in full even when the election leaves no gain to tax at 28% (worksheet line 12 caps it). This is pre-existing and part of the 1(h) 25%/28% follow-up from Tax Form 2555 filers' income at stacked rates (26 U.S.C. 911(f)) #9761.
  • Form 6251 line 27 asks for Schedule D Tax Worksheet line 21; amt_tax_including_cg uses line 14. This is pre-existing.

axiom: us:statutes/26/1/h#net_capital_gain encoded-correct for the 1(h)(2) gain election (companion test investment_income_reduces_net_capital_gain); TheAxiomFoundation/rulespec-us#1488 queued for 1(h)(11)(D)(i), the dividend part

🤖 Generated with Claude Code

dwks09 and dividend_income_reduced_by_investment_income read
investment_income_form_4952, an input no dataset fills (California's
FTB 3526 line 9 reads it as federal Form 4952 line 8), and applied it
as min(0, election) and with line 4 assumed zero. net_capital_gain read
investment_income_elected_form_4952 (Form 4952 line 4g, populated in the
default dataset). With a $50,000 election against a $300,000 long-term
gain, net_capital_gain was $250,000 but dwks10 $300,000.

- Worksheet lines 3, 4 and 7 come from one helper: line 3 is Form 4952
  line 4g, line 4 is line 4e (all capital assets treated as held for
  investment), line 7 the smaller of Schedule D lines 15 and 16, with
  capital gain distributions on Schedule D line 13.
- dividend_income_reduced_by_investment_income is line 6, dwks09 line 9
  and dwks10 line 10 (lines 6 + 9).
- net_capital_gain takes the election from the gain first and then from
  qualified dividends (Form 4952 line 4g instructions; 26 U.S.C. 1(h)(2)
  and 1(h)(11)(D)(i)), and nets capital gain distributions with
  Schedule D gains and losses.
- adjusted_net_capital_gain adds back only the qualified dividends not
  elected.
- dwks09 no longer drops Schedule D gains when capital gain
  distributions are also present.

Tests: worksheet YAML cases with line comments, and Hypothesis
differential tests (worksheet transcription, dwks10 == net_capital_gain,
dwks13 == adjusted_net_capital_gain, monotonicity in the election).

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

codecov Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (909176a) to head (a3371b8).
⚠️ Report is 158 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #9781   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         8    +4     
  Lines           76       105   +29     
  Branches         2         0    -2     
=========================================
+ Hits            76       105   +29     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

MaxGhenis and others added 2 commits October 3, 2026 22:32
- The 2025 tax case's line 44 uses the Tax Computation Worksheet rates the
  model uses; the Tax Table gives 3,875 (review r1, GPT-6.1 Sol).
- investment_income_form_4952's label now matches its only use, federal
  Form 4952 line 8 for California FTB 3526 line 9 (review r1, Opus).
- adjusted_net_capital_gain's documentation describes section 1(h)(3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 4, 2026 21:36
With dwks10 and net_capital_gain now applying the same election, the
worksheet and section 1(h) capital gain excesses agree; update the
docstrings that said they could disagree. section_911_qualified_dividend_income
starts from qualified dividend income after 26 U.S.C. 1(h)(11)(D)(i)
(the smaller of the dividends and net_capital_gain), so elected
dividends are not added back in section_911_adjusted_net_capital_gain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis merged commit 2137342 into main Oct 5, 2026
35 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Merged by the US + core hub at head ea06980c865262a2d29450b4d2be7da780674ca0 (squash, --admin --match-head-commit). The only block was the required approving review, which no one else can give on Max's PRs.

Gates:

  • Round 1: three independent approvals at 72b76cb258 (two Opus 5.5, one GPT-6.1 Sol).
  • Delta review: a GPT-6.1 Sol review approved this exact head with no blocking findings (~/reviews/us-hub/9781/delta-review.md). It covers:
  • Impact: the review re-derived the −$699.9M AMT record by hand, as a correction. Main's dwks09 dropped that record's $1.55M long-term gain when distributions were present. The PR body's absolute income_tax totals were stale; the hub corrected them to the re-run ($2,592.280B → $2,591.755B). The −$525.6M change was already right.
  • Election allocation: the review flagged the gain-first allocation of the Form 4952 line 4g election as a modeling assumption. It follows the form's own line 4g Note ("attributable first to net capital gain"), and all three round-1 reviewers judged it the form's default. Filers may allocate otherwise, but no dataset records that choice. This is the source's stated default, not a choice between readings of the law, and the PR body documents it.
  • CI: gh pr checks exits 0, with all 35 check runs on ea06980c86 successful, including the Hypothesis tests.
  • State: MERGEABLE against current main, not a draft, no CHANGES_REQUESTED review.

Non-blocking follow-up: no end-to-end property test covers a Form 4952 election together with §911 stacking on generated inputs.

@MaxGhenis
MaxGhenis deleted the dwks-form-4952-election branch October 5, 2026 15:37
MaxGhenis added a commit that referenced this pull request Oct 5, 2026
)

* Test a Form 4952 election with section 911(f) stacking end to end

Neither the Form 4952 line 4g election test (#9781) nor the section 911(f)
stacking test (#9761) covered households with both. The new Hypothesis
tests check, on generated households with an election and an exclusion:

- closed forms for net capital gain and the section 911 amounts after the
  election (min(D, N), min(N, T), min(D, N, T));
- that the Schedule D Tax Worksheet route and the section 1(h) route give
  the same capital gain excess and reduced amounts, regular tax and AMT;
- that a zero election or exclusion matches the situation without that
  input, bit for bit;
- monotonicity in both amounts, with the intended 12%/15% overlap
  exception in the election bounded from the parameters;
- the regular tax and AMT against the transcribed 2025 Schedule D Tax
  Worksheet, Foreign Earned Income Tax Worksheet and Form 6251.

The election and the exclusion can change taxable income through the
choice to itemize (an AMT filer may itemize below the standard deduction),
so amounts that depend on taxable income are compared only where that
choice holds; income_tax, which it minimizes, is compared across it.

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

* Address review: exact gain checks, AMT excess once, docstring fixes

- Gains and worksheet lines 6-10 do not depend on taxable income, so they
  are checked exactly for every whole-dollar household, itemizers with
  fractional taxable income included (property 5 as stated).
- The AMT capital gain excess has one route; check it once against its
  closed form instead of against itself.
- Correct the wages in the 12%/15% overlap example and an inverted grid
  comment; say the zero-input test guards against leakage between
  households.

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

* Say which closed forms are exact for whole-dollar itemizers

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

* Docstring: Form 6251 line 6 can have cents without itemizing

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
… and move the distributions comment

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 6, 2026
…9788)

* 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>

* 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>

---------

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
…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>
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 7, 2026
…, in the QBI income limit (#9886)

* Keep dependents' business income off the filer's QBI deduction

qualified_business_income_deduction summed every member's qbid_amount,
and qbid_amount netted losses and the 199A(i) minimum over every
member, so a dependent's Schedule C income raised the filer's deduction
and a dependent's loss cut it. Under 26 USC 199A(a) the deduction is the
taxpayer's, from their own (and a joint spouse's) qualified business
income; a dependent takes their own deduction on their own return.

- qualified_business_income_deduction sums qbid_amount, and the 199A(i)
  minimum's eligible QBI, over the head and spouse.
- qbid_amount nets the head's and spouse's losses together; a
  dependent's businesses are netted alone for the dependent's return.
- qualified_business_income_deduction_person shares the deduction
  between the head and spouse only.
- ia_qbi_deduction takes each spouse's share of the federal deduction;
  it gave every member with a positive qbid_amount the whole tax unit's
  deduction, a dependent included.
- mo_business_income_deduction counts the head's and spouse's business
  income only (Mo. Rev. Stat. 143.022: "such individual's business
  income").

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

* Address review r1 on the QBID dependents fix

- qualified_business_income_deduction_person shares a deduction that
  comes only from the 199A(i) minimum (every per-person amount zero) in
  proportion to the spouses' positive QBI, or to the head, so the shares
  always sum to the deduction and Iowa no longer drops it.
- Tests assert the per-person shares rather than a dependent's
  qbid_amount, which is figured on the filer's taxable income.
- The Iowa case checks ia_taxable_income_joint (main: 59,500, taking the
  13,500 deduction three times; branch: 88,000).
- The property test drops its vacuous bound and the has_amounts carve-out,
  and says which checks recompute the aggregation.

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

* Subtract section 199A net capital gain in the QBI income limit

26 USC 199A(a)(2)(B) limits the deduction to 20% of taxable income over
net capital gain, which Treas. Reg. 1.199A-1(b)(3) defines as section
1222(11) net capital gain plus qualified dividends (Form 8995 line 12,
Form 8995-A line 34). The model subtracted adjusted_net_capital_gain,
which drops unrecaptured section 1250 gain and 28-percent rate gain, so
the limit was too high whenever a filer had either.

section_199a_net_capital_gain (new) is the smaller of Schedule D lines
15 and 16 (floored at zero) plus nonnegative qualified dividends, over
the head and spouse only, and is not reduced by a Form 4952 election
(unlike net_capital_gain, #9781). Replays the hub's stalled draft
(wip/hub-backup/qbid-net-capital-gain, 739df63) on top of #9866 and
masks dependents before netting, per the hub spec D1.

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

* Pin negative qualified dividend handling in the 199A gain

Review r1 (P3): a negative dividend input adds nothing, and spouses'
dividends are summed before the zero floor.

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