Skip to content

Leave state tax refunds and the section 68 reduction out of federal AMTI, and fix Colorado AMTI to match - #10099

Merged
MaxGhenis merged 14 commits into
mainfrom
amti-section-68-and-tax-refunds
Nov 10, 2026
Merged

MaxGhenis merged 14 commits into
mainfrom
amti-section-68-and-tax-refunds

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Federal alternative minimum taxable income (amt_income) starts from taxable income (Form 6251 line 1) and adds back the deductions the AMT doesn't allow. Main left two adjustments out, and Colorado's AMT copied the result. This PR makes both adjustments, figures the married-filing-separately increase on the corrected amount, and makes Colorado's DR 0104AMT lines 1, 2 and 4 follow the form.

What changes

1. State and local tax refunds leave AMTI. 26 U.S.C. 56(b)(1)(C) (56(b)(1)(D) before P.L. 116-94): "No recovery of any tax to which subparagraph (A)(ii) applied shall be included in gross income for purposes of determining alternative minimum taxable income." Form 6251 subtracts the refund on line 2b (2025) or line 7 (2017), whether or not the filer itemizes. The new amt_income_before_separate_addition subtracts exactly what irs_gross_income put in AGI: each head's or spouse's salt_refund_income, floored at zero. A dependent's refund is on the dependent's own return.

2. Section 68 does not apply. 56(b)(1)(E) (formerly (F)): "Section 68 shall not apply." P.L. 119-21 amended 56(a)(3), (b)(2) and (e)(1)(B) but not (b)(1). Taxable income is net of itemized_taxable_income_deductions_reduction, which is nonzero in 2013–2017 and from 2026. Section 68 raised taxable income by that reduction, so AMTI now subtracts it for itemizers, restoring the full itemized deductions the AMT allows, as 2017 Form 6251 line 6 did with a negative entry.

3. The married-filing-separately increase uses the corrected AMTI. 26 U.S.C. 55(d)(2) increases a separate filer's AMTI by the lesser of the exemption and 25% (50% from 2026, under 55(d)(4)(A)(ii)(IV)) of the excess of AMTI "determined without regard to this sentence" over the zero-exemption level. amt_separate_addition used to recompute that base as taxable income plus the excluded deductions. That base still held the refund and the section 68 reduction, and lacked the add-backs of the 2025 senior deduction and, before 2018, the personal exemptions. It now reads amt_income_before_separate_addition, and amt_income is that amount plus the increase.

4. Colorado. C.R.S. 39-22-105(2)(a) applies the 39-22-104 modifications to federal AMTI less the exemption. Against that base, the state income tax addback, "an amount equal to the deduction claimed" (39-22-104(3)(d)), is zero, because 56(b)(1)(A)(ii) allows no such deduction. The refund subtraction of 39-22-104(4)(e) exists "to avoid re-taxing" a refund that AMTI already leaves out. The 2025 DR 0104AMT follows both readings:

  • Line 2 is "the sum of lines 3 through 7 and line 9 from form DR 0104", leaving out the line 2 state income tax addback (line 8 is reserved). The model now subtracts co_state_addback from co_additions.
  • Line 4 takes the DR 0104AD subtractions "excluding the State Income Tax Refund". The model now drops salt_refund_income from line 4 and floors the line at zero.
  • Line 1 is Form 6251 line 6 or, when the exemption exceeds AMTI, line 4 less line 5 as "the resulting negative amount". The model used the floored line 6. With items 1 and 4, that floor would have created a Colorado AMT on a refund: a filer whose only income is a $15,000 refund, with $15,000 of non-Colorado bond interest, would have owed $520.50. Line 1 is now negative in that case, and the AMT is zero.

Before this PR the two refund errors offset each other: federal AMTI kept the refund and Colorado line 4 took it back out. Now the refund leaves once.

#10094, which merged on 2026-11-07, nets the DR 0104 line 4 addback of the line 2 state income tax addback, as the 2025 104 Book's line 4 instructions say. This branch has merged it, so DR 0104AMT line 2 now equals DR 0104 lines 3 through 7 and 9. The Colorado end-to-end cases below pin the two PRs together.

Examples

Case main This PR
2025 single itemizer: wages 100,000, refund 2,000, property tax 8,000, mortgage interest 20,000 (amt_income) 82,000 80,000
2026 single itemizer: wages 1,000,000, property tax 10,000, mortgage interest 30,000 (amt_income) 972,162.19 970,000
2025 separate filer: wages 1,000,000, refund 20,000, property tax 10,000 (amt_income) 1,049,912.50 1,024,912.50
2026 separate filer: wages 700,000, refund 10,000, standard deduction (amt_income) 744,900 729,900
Colorado DR 0104AMT unit case: line 1 200,000; additions 10,000 incl. 6,000 state addback; subtractions 5,000 incl. 1,500 refund 205,000 200,500
Colorado single itemizer: wages 450,000, state withholding 5,000, real estate tax 5,000, mortgage interest 20,000 (Colorado AMTI), 2025 / 2026 359,900 / 368,900 354,900 / 363,900

The main column is main at ba9bfdea75, the base this branch last merged, which includes #10094. Before #10094 merged, main gave 364,900 and 373,900 for the last row.

The 2026 itemizer: section 68 takes 2/37 × 40,000 = 2,162.16, so taxable income is 962,162.16. AMTI adds back the 10,000 SALT deduction and the 2,162.16 reduction, giving 970,000 = AGI less the non-tax itemized deductions. Main prints 972,162.19, its float32 value of 972,162.16.

The Colorado itemizer, by hand:

  • Federal: taxable income 450,000 − 30,000 = 420,000. Form 6251 line 2a adds back the 10,000 of taxes, so line 4 is 430,000. Line 6 is 430,000 − 88,100 = 341,900 in 2025 and 430,000 − 90,100 = 339,900 in 2026 (Rev. Proc. 2025-32). The 2026 section 68 reduction is zero, since 420,000 + 30,000 is below the 640,600 at which the 37% bracket starts.
  • DR 0104 line 2: min(5,000, 30,000 − the standard deduction) = 5,000. Line 4: 30,000 − 12,000 (2025, 39-22-104(3)(p.5)(I)(A)) or − 1,000 (2026, (3)(p.7)(I)(A)), less the 5,000 line 2 addback = 13,000 or 24,000.
  • DR 0104AMT: line 2 is 13,000 or 24,000, and line 4 is 0. Colorado AMTI is 341,900 + 13,000 = 354,900 (2025) and 339,900 + 24,000 = 363,900 (2026).

Sources

Source check

On 2026-11-09 the fix session fetched and read 26 U.S.C. 55 and 56, the 2025 Form 6251 instructions (pages 2 and 9), the 2017 Form 6251 and its instructions (pages 2-3), Rev. Proc. 2025-32, the 2025 DR 0104AMT (pages 1 and 3), the 2025 104 Book (pages 8-9) and C.R.S. Title 39 (pages 380-386 and 401). The quotes above match them. It couldn't fetch the 2025 DR 0104 itself; DTrim99's review of 2026-11-04 read it and confirms line 2 and the reserved line 8.

Invariants

policyengine_us/tests/core/test_amt_income_refund_and_section_68_invariants.py checks two properties with Hypothesis, for 2017 (old section 68), 2025 (none) and 2026 (P.L. 119-21 section 68), for single, joint and separate filers, itemizing or not. The households have no deduction that depends on AGI once the AMT add-backs are made, so they have no medical expenses and no charitable gifts. From 2026, the 0.5% floor of 170(b)(1)(I) ties the charitable deduction to AGI, and a refund then rightly raises AMTI by 0.5% of the refund.

  1. Refund invariance. Adding a filer's state tax refund leaves AMTI unchanged, including the separate filer's increase.
  2. Statutory identity. AMTI before the separate filer's increase equals AGI, less the refund, less the itemized deductions the AMT allows: all itemized deductions before section 68 except taxes and miscellaneous deductions, or none for a standard-deduction filer.

The derandomized draws rarely reach section 68 or the separate filer's increase. So a fixed @example adds four households to every year: single and joint itemizers above the 2017 and 2026 section 68 thresholds, and separate filers at 700,000 (inside the 2026 increase band) and 950,000 (inside the 2025 band). Dropping the section 68 subtraction now fails [2017] and [2026]. Going back to the old separate base fails [2025] and [2026] through the fixed example, and [2017] through the current draws.

Tests

  • amt_income.yaml: 13 cases, 4 of them new (2 end to end from wages, and separate filers in 2025 and 2026). amt_income_before_separate_addition.yaml (new): 6 cases, the 5 unit-input cases moved from amt_income.yaml and a negative refund input. co_alternative_minimum_taxable_income.yaml: 8 cases, 5 of them new (including the 2025 and 2026 end-to-end itemizers).
  • An existing Colorado case ("CO AMTI with no federal AMT income") supplied only Form 6251 line 6 = 0. It now also supplies line 4 = line 5, so line 1 stays zero and the expected 5,000 is unchanged.
  • At the final head, one process each: amt_income.yaml 13 passed, amt_income_before_separate_addition.yaml 6 passed, co_alternative_minimum_taxable_income.yaml 8 passed, the property test 3 passed, and test_source_conflicts.py 103 passed. co_amt.yaml, amt_separate_addition.yaml and co_federal_deduction_addback.yaml pass too.
  • Mutants this round, each run in its own process and then restored, each killed by the intended case:
    • no zero floor on the refund (the negative refund case);
    • a 25% separate rate in 2026 (the 2026 separate filer case);
    • Colorado line 2 keeping the state income tax addback (the unit case and both end-to-end cases);
    • no netting of the line 4 addback, undoing Reduce Colorado's federal deduction addback by the state income tax already added back #10094 (both end-to-end cases);
    • dropping the section 68 subtraction (property test [2017] and [2026]);
    • the old separate base (property test, all three years).
  • Earlier rounds' nine mutants covered dropping each new line, summing dependents' refunds, reversing section 68 for non-itemizers, the old separate-filer base, and the old Colorado line 1, line 2 and line 4.
  • CI: the Pull request run at 497c8168bf (42758259887) passed all 36 jobs. It tested this head merged into main at ee466893c3, which includes the 2027 AMT amounts from Update federal tax parameters to the 2027 amounts in Rev. Proc. 2026-35 #10683.
  • The property test runs in CI's Rest Python group. Locally (Python 3.14, 4 vCPU), its file took 95 s of wall time before this round and 88 s after, including the model load, with a peak of about 1.76 GB both times. That is a local measurement, not CI.

Not changed

  • DR 0104AMT bars any amount on line 2 or line 4 that "duplicates any income or adjustment made in arriving at federal alternative minimum taxable income". The model's line 4 subtractions (us_govt_interest, the pension, military retirement, CollegeInvest, ABLE and charitable subtractions, and co_other_subtractions) don't duplicate a federal AMTI adjustment. On line 2, co_federal_deduction_addback (DR 0104 line 4) can duplicate the standard deduction or the taxes that federal AMTI already adds back. In the Colorado itemizer above, if the 5,000 of real estate tax in that addback counts as a duplicate, Colorado AMTI is 5,000 lower. Main has the same gap, and is worse there because it also adds the state income tax addback. Left as a follow-up.
  • Form 6251 line 2b also subtracts refunds, reported on Schedule 1 line 8z, of state or local personal property or general sales taxes, foreign income taxes, and state, local or foreign real property taxes. The model has no input that carries those refunds into irs_gross_income: salt_refund_income is its only refund source. So AMTI subtracts only salt_refund_income.
  • Minnesota's AMT (mn_amt_taxable_income) starts from federal AGI and never subtracts the refund (Schedule M1MT line 15). Left as a follow-up.
  • The IRS draft 2026 Form 6251 (May 2026) has line 2b for tax refunds but no line for the section 68 reversal, and the 2026 instructions aren't out: the draft instructions on irs.gov are still the 2025 edition. The statute governs. When the 2026 instructions are out, cite their line or register the conflict.

Coordination

Microsimulation impact

We estimate that this PR lowers federal alternative minimum tax by $67.3m (1.3%) in 2025 and by $398.0m (4.0%) in 2026 on the default dataset. We compared main at ba9bfdea75 with this branch at 497c8168bf.

Federal AMTI falls for 7,221 sampled tax units in 2025 (15.1m weighted) and for 7,631 in 2026 (16.0m weighted). The tax falls for 8 sampled tax units in 2025 (20,661 weighted) and for 49 in 2026 (231,168 weighted), by at most $11,398 and $13,177, and household net income rises by the same totals. Colorado AMTI falls by $2.03bn in 2025 and by $3.62bn in 2026. Colorado's AMT comes to $0 on main and on this branch, so Colorado income tax doesn't change. In 2026, one sampled tax unit (3,218 weighted) pays $30 more state income tax. Household benefits don't change.

Output 2025 main 2025 change 2025 records changed (weighted) 2026 main 2026 change 2026 records changed (weighted)
amt_income $16,988.0bn −$65.22bn 7,221 (15,078,219) $17,938.6bn −$78.43bn 7,631 (16,008,436)
amt_income_less_exemptions $6,992.9bn −$58.13bn 4,340 (9,138,190) $7,644.7bn −$72.51bn 4,845 (10,245,173)
alternative_minimum_tax $5.37bn −$67.3m 8 (20,661) $10.06bn −$398.0m 49 (231,168)
co_alternative_minimum_taxable_income $143.0bn −$2.03bn 200 (410,859) $162.7bn −$3.62bn 332 (648,146)
co_amt $0 $0 0 (0) $0 $0 0 (0)
co_income_tax $10.18bn $0 0 (0) $12.71bn $0 0 (0)
state_income_tax $548.2bn $0 0 (0) $577.3bn +$95,383 1 (3,218)
income_tax $2,422.1bn −$67.3m 8 (20,661) $2,595.3bn −$398.0m 49 (231,168)
household_net_income $16,380.7bn +$67.3m 8 (20,661) $17,198.7bn +$397.9m 49 (231,168)
household_benefits $1,955.3bn $0 0 (0) $2,060.5bn $0 0 (0)

This PR adds amt_income_before_separate_addition, so main has no total to compare.

impact: federal AMT −$67.3m (−1.3%) in 2025 and −$398.0m (−4.0%) in 2026 (8 and 49 sampled tax units; 20,661 and 231,168 weighted); Colorado's AMT stays at $0; household benefits don't change
axiom: TheAxiomFoundation/rulespec-us#2033 queued (federal tax recoveries, historical section 68 reversal and separate-filer AMTI composition; historical corpus ingestion, release/re-pin and encoder approval); TheAxiomFoundation/rulespec-us#2034 queued (Colorado AMTI; dated source ingestion, release/re-pin and encoder approval).

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 11, 2026 11:51
26 U.S.C. 56(b)(1)(C): no recovery of state and local taxes is included
in AMTI (Form 6251 line 2b; 2017 line 7). 56(b)(1)(E): section 68 does not
apply (2017 Form 6251 line 6 subtracts the reduction). Main started from
taxable income, which includes the refund and is net of the section 68
reduction, without either adjustment.

Colorado AMTI (DR 0104AMT) starts from federal AMTI and adds DR 0104
lines 3-7 and 9 and subtracts DR 0104AD subtractions except the state
income tax refund. Main added the line 2 state income tax addback and
subtracted the refund, which offset the federal refund omission; both
change together here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With itemization fixed and no AGI-dependent deductions, a refund enters
AGI and is subtracted back, and the section 68 and SALT-cap changes it
causes cancel. Checked with Hypothesis for 2017, 2025 and 2026.

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

Copy link
Copy Markdown
Contributor Author

Picking this up for the US hub. I'll post a hand-off comment here when it's ready.


Generated by Claude Code

Brings the branch up to date with main before adoption; the merge has no
conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WR8LHahgdvZhtnGRY21L5Y
Drop charitable gifts from the property test's draws: from 2026 the 0.5%
floor of 26 U.S.C. 170(b)(1)(I) ties the charitable deduction to AGI, so a
refund rightly raises AMTI by 0.5% of it. Hypothesis found that on the
merged branch ( refund, +/bin/bash.02). Add a second property on the same
simulations, that AMTI is AGI less the refund less the itemized deductions
the AMT allows, and two YAML cases that compute AMTI from wages for a 2025
refund and the 2026 section 68 reduction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WR8LHahgdvZhtnGRY21L5Y
The 2017 instructions put lines 6 and 7 on PDF pages 2 and 3, and the
2025 DR 0104 numbers the Colorado additions that DR 0104AMT line 2 sums.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WR8LHahgdvZhtnGRY21L5Y
…w does

26 U.S.C. 55(d)(2) figures a married separate filer's increase on AMTI
determined without that increase, so it now uses
amt_income_before_separate_addition, which carries the refund and section
68 lines; before, the refund and the reduction still raised the increase.
DR 0104AMT line 1 enters Form 6251 line 4 less line 5 as a negative amount
when the exemption is larger, and line 4 cannot go below zero, so the PR's
line 2 and line 4 changes no longer create a Colorado AMT on a refund.
The AMTI refund line now subtracts what irs_gross_income put in AGI, each
filer's refund floored at zero. The 2017 test case now uses a zero
exemption, which a 4,155 section 68 reduction implies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WR8LHahgdvZhtnGRY21L5Y
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Picking this up for the US hub. I continue an earlier session's work on this PR: it pushed five commits (e282ae939a to 75e37bd110) and stopped before handing off. I'm checking each of those commits, merging main again, and will post a hand-off comment here when it's ready.


Generated by Claude Code

Brings in main since the November 2 merge, including #10594's state
section 68 changes, which share no file or line with this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwQq6GA1FXMB3qVPzGgvWQ
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Picking this up for the US hub. I continue the earlier sessions' work on this PR (its five commits e282ae939a to 75e37bd110). I'll post a hand-off comment here when it's ready.


Generated by Claude Code

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Ready for hub review

Head: 6cf3eb6e223ae8d338d0792a7c52de6fecdc0bfa (draft; CI skips drafts, so no Pull request run has gone at this head).

What I did

The earlier sessions' commits, checked one by one:

  • 5a6ca04e3d (refund and section 68 out of AMTI): kept. The refund subtraction in amt_income_before_separate_addition.py:52-58 removes exactly what irs_gross_income puts in AGI: each non-dependent's salt_refund_income, floored at zero, as irs_gross_income.py does. The section 68 line (:62-66) subtracts itemized_taxable_income_deductions_reduction for itemizers. That is the right sign: section 68 raised taxable income, and AMTI undoes it. The PR body said "adds that reduction back", so I reworded it.
  • b55c3ea3fe and 3a7ce22baa (property test and end-to-end YAML): kept.
  • ffc09cdc0c (reference pages): kept. The reference-URL code-health tests pass.
  • 95ce584900 (separate filer base, Colorado line 1): kept. amt_separate_addition.py now reads the corrected AMTI, as 55(d)(2)'s "determined without regard to this sentence" requires. Colorado line 1 (co_alternative_minimum_taxable_income.py:37-41) lets line 4 less line 5 go negative when line 6 is zero.
  • 75e37bd110 (changelog): kept.
  • New: 6cf3eb6e22 merges origin/main (abc67b98de) cleanly. Since the November 2 merge, main changed only amt_tax_including_cg.py among the AMT and Colorado files, and no line of this PR.

#10594

#10594 merged into main at 2026-11-03T07:16Z and is in this branch now. The two share no file or line. #10594 changes MD, ME and NM itemized deductions. Outside the federal AMT folder, only co_alternative_minimum_taxable_income reads amt_income, amt_exemption or amt_income_less_exemptions.

Hand computations (before reading the code's output)

  • 2025 single: wages 100,000, refund 2,000, property tax 8,000, mortgage interest 20,000. AGI 102,000, itemized deductions 28,000, taxable income 74,000. AMTI = 74,000 + 8,000 taxes − 2,000 refund = 80,000 (main 82,000).
  • 2026 single: wages 1,000,000, property tax 10,000, mortgage interest 30,000. The SALT cap phases down to the 10,000 floor. Section 68 = 2/37 × 40,000 = 2,162.16, so taxable income is 962,162.16. AMTI = 1,000,000 − 30,000 = 970,000, which is 962,162.16 + 10,000 − 2,162.16 (main 972,162.16).
  • 2025 separate filer: wages 1,000,000, refund 20,000, property tax 10,000. The SALT cap falls to 5,000, so the filer takes the 15,000 standard deduction and taxable income is 1,005,000. AMTI before the increase = 1,005,000 + 15,000 − 20,000 = 1,000,000. The zero-exemption level is 626,350 + 68,500 / 0.25 = 900,350. The increase is min(68,500, 25% × 99,650) = 24,912.50, so AMTI is 1,024,912.50 (main 1,049,912.50).

All three match the YAML.

Tests (merged head, one file per process)

  • amt_income.yaml: 17 passed. co_alternative_minimum_taxable_income.yaml: 6 passed.
  • tests/core/test_amt_income_refund_and_section_68_invariants.py: 3 passed (Hypothesis).
  • Code health: test_source_conflicts.py 103 passed; test_reference_urls.py 32, test_no_concatenated_reference_urls.py 48, test_known_dead_reference_urls.py 40 passed.
  • ruff format --check and ruff check on the changed Python files: clean.

Mutants (each in its own process, code restored after)

Mutant Result
Drop the section 68 subtraction caught: 3 of 17 amt_income.yaml cases fail
Count dependents' refunds (drop the filer mask) caught: 1 fails
Floor Colorado line 1 at Form 6251 line 6 caught: 1 of 6 Colorado cases fails

Judgment calls

  • Sources not refetched. This session's network policy blocked law.cornell.edu, irs.gov, web.archive.org and tax.colorado.gov, so I couldn't reread 26 U.S.C. 55 and 56, Form 6251 or DR 0104AMT. The 56(b)(1) letters (C) for refunds and (E) for section 68, after P.L. 116-94 struck the old (B), match what I know of the statute. The DR 0104AMT quotes (line 1 "as a negative amount", line 2's "lines 3 through 7 and line 9", line 4 "excluding the State Income Tax Refund") rest on the earlier session's reading. A reviewer with web access should confirm them. I added this caveat to the PR body.
  • The Colorado reading (no state tax addback and no refund subtraction against federal AMTI) follows C.R.S. 39-22-105(2)(a) and the form together, so I recorded no source conflict.
  • No microsimulation was run (impact: the hub will measure).

Proposed follow-ups

  • Subtract the state tax refund in Minnesota's AMT. mn_amt_taxable_income starts from federal AGI and never subtracts the refund (Schedule M1MT). Check the line against the M1MT instructions.
  • Bar DR 0104AMT line 2 amounts that duplicate federal AMTI adjustments. The standard deduction or taxes inside co_federal_deduction_addback may already be in federal AMTI. Read the DR 0104AMT line 2 restriction and size it.

Generated by Claude Code

@MaxGhenis

MaxGhenis commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

Hub review in progress

Superseded by the final review: #10099 (comment)


Generated by Claude Code

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Ready for hub review
VERDICT: APPROVE
6cf3eb6
METHODOLOGY_CHOICE: no

The head is unchanged since the hand-off. One thing changed on GitHub: the PR is no longer a draft (marked ready at 20:44Z). The Pull request run at this head (run 41715326437) completed with conclusion success, and every job in it passed, including Household API Partners, Microsimulation and all Baseline and Contrib shards.

I found no wrong result. All findings below are P3: test strength and body text.

Findings

P3-1. The property test does not reach section 68 or the separate filer's increase in 2026

policyengine_us/tests/core/test_amt_income_refund_and_section_68_invariants.py:84-90. derandomize=True with max_examples=4 draws a fixed set of households, and for the 2026 parameter none of them reaches the P.L. 119-21 section 68 reduction or a separate filer in the 2026 increase band. Two mutants that break 2026 pass the 2026 case:

  • Drop - section_68_reduction (amt_income_before_separate_addition.py:72): 1 failed, 2 passed, and the only failure is [2017]. Run alone, [2026] reports 1 passed ... in 10.22s.
  • Go back to the old separate base, taxable_income + amt_excluded_deductions (amt_separate_addition.py:21): 2 failed, 1 passed, with failures [2017] and [2025].

The YAML still kills both (the 2026 end-to-end case, and the separate filer case). The docstring says the test covers "2026 (the P.L. 119-21 section 68)", but in practice it doesn't. Hypothesis seeds the derandomized draws from the test's source, so any edit to the file reshuffles which years get covered. When I added a debug print, the draws changed and the 2026 case under the first mutant began to fail.

Fix: pin boundary households with @example. I ran this patch: unmutated 3 passed, the section 68 mutant [2026] 1 failed, the old-separate-base mutant [2026] 1 failed.

from hypothesis import HealthCheck, example, given, settings
...
BOUNDARY_UNITS = [
    dict(status="SINGLE", itemizes=True, employment_income=2_000_000,
         salt_refund_income=5_000, real_estate_taxes=12_000,
         home_mortgage_interest=30_000),
    dict(status="JOINT", itemizes=True, employment_income=3_000_000,
         salt_refund_income=8_000, real_estate_taxes=20_000,
         home_mortgage_interest=40_000),
    dict(status="SEPARATE", itemizes=False, employment_income=700_000,
         salt_refund_income=10_000, real_estate_taxes=0,
         home_mortgage_interest=0),
    dict(status="SEPARATE", itemizes=False, employment_income=950_000,
         salt_refund_income=20_000, real_estate_taxes=0,
         home_mortgage_interest=0),
]
...
@given(units=st.lists(tax_unit(), min_size=8, max_size=8))
# Fixed households that reach section 68 in 2017 and 2026 and the separate
# filer's increase in every year, on both sides of the 2026 cap.
@example(units=BOUNDARY_UNITS)
def test_amt_income_leaves_out_refunds_and_section_68(year, units):

(Run make format after pasting.)

P3-2. No YAML case pins the separate filer's increase at the 2026 rate

amt_income.yaml has one separate filer case (2025, 25%), and amt_separate_addition.yaml only has 2022 cases. From 2026, 55(d)(4)(A)(ii)(IV) (as the hub read it) makes the rate 50% for both the phase-out and the increase. The model gets that right: both amt_exemption.py:37 and amt_separate_addition.py:31 read the same gov.irs.income.amt.exemption.phase_out.rate (2026-01-01: 0.5), and separate_limit 2026 = 640,200 = 500,000 + 70,100 / 0.5. But no test pins it.

Here is the hand case for a 2026 separate filer with wages of 700,000, a 10,000 refund and the standard deduction:

  • AGI is 710,000.
  • AMTI before the increase is 710,000 − 10,000 = 700,000, because the standard deduction is added back.
  • The increase is min(70,100, 0.5 × (700,000 − 640,200)) = 29,900.
  • AMTI is 729,900.
  • The exemption is max(0, 70,100 − 0.5 × (729,900 − 500,000)) = 0.

At the PR head the model gives amt_income=729,900.00; amt_separate_addition=29,900.00. Main gives 744,900.00; 34,900.00, because it figures the increase on 710,000. Suggested case for amt_income.yaml:

# 26 U.S.C. 55(d)(2) and (d)(4)(A)(ii)(IV): from 2026 the separate filer's
# increase is 50% of AMTI (net of the refund) over 640,200, up to the 70,100
# exemption.
- name: Separate filer's 2026 increase is 50% and figured after the refund
  absolute_error_margin: 0.01
  period: 2026
  input:
    people:
      person1:
        age: 45
        employment_income: 700_000
        salt_refund_income: 10_000
    tax_units:
      tax_unit:
        members: [person1]
        filing_status: SEPARATE
        tax_unit_itemizes: false
    households:
      household:
        members: [person1]
        state_code: TX
  output:
    # 710,000 AGI - 16,100 standard deduction + 16,100 - 10,000 refund
    amt_income_before_separate_addition: 700_000
    # min(70,100, 0.5 x (700,000 - 640,200))
    amt_separate_addition: 29_900
    amt_income: 729_900

P3-3. Body: the source-check paragraph can go, and two "Not changed" items need correcting

The hub fetched every source on 2026-11-03 and found that the body's quotes match (see "What I couldn't check": I couldn't refetch them). So replace the "Source check" section with:

The hub fetched each source above on 2026-11-03: 26 U.S.C. 55(d)(2) and 56(b)(1)(C) and (E) with the P.L. 116-94 note, the 2025 Form 6251 instructions (lines 2b and 4), the 2017 Form 6251 (lines 6 and 7), the 2025 DR 0104AMT and its instructions (lines 1, 2 and 4), the 2025 DR 0104 (page 3), and C.R.S. 39-22-104(3)(d)(I), 104(4)(e)(II) and 105(2)(a). The quotes above match them.

Under "Not changed", replace the DR 0104AMT duplication bullet with:

DR 0104AMT bars any amount on line 2 or line 4 that duplicates an income item or adjustment already in federal AMTI. The model's line 4 subtractions (us_govt_interest, pension, military retirement, CollegeInvest, ABLE and charitable subtractions, co_other_subtractions) don't duplicate a federal AMTI adjustment. On line 2, co_federal_deduction_addback (DR 0104 line 4) can duplicate the standard deduction or the taxes that federal AMTI already adds back. Main has the same gap, and is worse there because it also adds the state income tax addback. Left as a follow-up.

Add to "Not changed":

Form 6251 line 2b also subtracts refunds of real property, personal property, sales and foreign taxes (Schedule 1 line 8z). The model has no input that carries those refunds into irs_gross_income: salt_refund_income is its only refund source. So AMTI subtracts only salt_refund_income.

Also correct item 3. Main's separate filer base didn't "still hold" the 2025 senior deduction. It lacked the senior deduction add-back, and before 2018 the personal exemptions. Neither is reachable in practice, because both phase out far below the separate filer limit. Suggested wording: "...which still held the refund and the section 68 reduction, and lacked the add-backs of the 2025 senior deduction and, before 2018, the personal exemptions."

P3-4. The hand-off's separate filer narrative misstates the deduction

The hand-off says the filer "takes the 15,000 standard deduction and taxable income is 1,005,000". But the YAML case forces tax_unit_itemizes: true, so taxable income is 1,020,000 − 5,000 SALT = 1,015,000 (model: taxable_income=1,015,000.00). Left free to choose, the filer takes the 2025 standard deduction of 15,750 and taxable income is 1,004,250 (model: 1,004,250.00). In all three versions AMTI before the increase is 1,000,000, so the expected values are right. Only the hand-off text is wrong, and the body doesn't repeat it.

Checked and sound

Defect reproduced at main (6145ad45). I copied the PR's two YAML files and ran them against a main worktree. amt_income.yaml: 7 failed, 10 passed. That is 7 of the 8 new cases; the non-itemizer guard passes, and the separate filer case fails on main's missing variable. co_alternative_minimum_taxable_income.yaml: 3 failed, 3 passed, the 3 new cases. Total: 10 of 11 new cases fail, as the body says.

Hand values, computed before reading the model's output, then run at both trees:

Case Hand Head Main
2025 single itemizer, refund 2,000 74,000 + 8,000 − 2,000 = 80,000 80,000.00 82,000.00
2026 single itemizer, 1,000,000 1,000,000 − 30,000 = 970,000 (section 68 = 2/37 × 40,000 = 2,162.16) 970,000.00 (reduction 2,162.16) 972,162.19
2025 separate filer, refund 20,000 1,000,000 + min(68,500, 0.25 × 99,650) = 1,024,912.50 1,024,912.50 1,049,912.50
2026 separate filer, wages 700,000, refund 10,000 729,900 (P3-2) 729,900.00 744,900.00
2025 joint itemizers, spouse refunds 1,000 + 700, a dependent's 300 AGI 151,700 (dependent's refund not in AGI); 117,700 + 9,000 − 1,700 = 125,000 = 150,000 − 25,000 125,000.00 126,700.00
CO 2025 itemizer: wages 400,000, refund 3,000, RE 6,000, mortgage 20,000, state withholding 15,000 line 1 291,900; line 2 44,000 − 15,000; line 4 3,000 − 3,000; CO AMTI 320,900 320,900.00 335,900.00
CO unit case (body table row 4) 200,000 + (10,000 − 6,000) − (5,000 − 1,500) = 200,500 200,500 (YAML passes) 200,000 + 10,000 − 5,000 = 205,000

The $520.50 Colorado case. The CO AMT rate parameter is 2021-01-01: 0.0347, and co_amt = max(0, tentative tax − co_income_tax_before_non_refundable_credits). The filer has a $15,000 refund and $15,000 of non-Colorado bond interest. With the old floored line 1 but this PR's federal and line 4 changes:

  • line 1 = 0, line 2 = 15,000, line 4 = max(0, 15,000 − 15,000) = 0;
  • CO AMTI = 15,000, tentative tax = 0.0347 × 15,000 = 520.50;
  • normal CO tax = 0 (the model gives co_income_tax_before_non_refundable_credits=0.00);
  • so the AMT is 520.50.

The PR's negative line 1 (0 − 88,100) gives CO AMTI 0 and co_amt=0.00. Main also gives 0, because its federal AMTI keeps the refund and line 4 takes it out.

The refund's mirror. irs_gross_income adds not_dependent * max_(0, salt_refund_income) per person. amt_income_before_separate_addition.py:55-58 subtracts tax_unit.sum(~is_tax_unit_dependent * max_(0, salt_refund_income)), which is the same mask and the same floor. Joint filers: both spouses are subtracted (125,000 above). Separate filers: the subtraction comes before amt_separate_addition (both separate rows above). Dependents: excluded on both sides (the joint row above). Colorado line 4 subtracts add(tax_unit, period, ["salt_refund_income"]), which is exactly what co_subtractions adds through its subtractions.yaml list. So line 4 removes what the DR 0104AD subtraction put in, dependents included.

Section 68. The sign is right. itemized_taxable_income_deductions = total − reduction, so taxable income is higher by the reduction, and AMTI subtracts it back, gated on tax_unit_itemizes. limitation/applies.yaml is true for 2013-2017 and from 2026, which matches the body. The taxable-income-≤-0 branch (agi - deductions) also nets the reduction, so both branches are consistent.

The 2026 rate. See P3-2. The phase-out and the increase read one parameter, so there is no mismatch.

The 105(2)(a) exceptions and the duplication bar.

  • The model has no private activity bond interest input and no 57(a)(5) preference. Federal AMTI therefore never holds state or local bond interest, and both exceptions (no add-back of state or local bond interest in AMTI; subtract Colorado government interest in AMTI) are unreachable. This is a limit, not a gap.
  • Line 4: no model subtraction duplicates a federal AMTI adjustment (list in P3-3).
  • Line 2: co_federal_deduction_addback duplicates the federal AMTI add-back of taxes or the standard deduction. In the CO itemizer row above, line 2 carries a 29,000 federal deduction addback (co_additions 44,000 less the 15,000 state addback), and federal AMTI already added back the 21,000 SALT in it. Main has the same gap and is worse there (line 2 = 44,000 rather than 29,000). This PR makes nothing reachable or worse, so it stays a follow-up.

Minnesota follow-up. mn_amt_taxable_income starts from adjusted_gross_income and its AMT_SUBTRACTIONS don't include the refund, while the regular mn/.../subtractions/sources.yaml lists salt_refund_income. This PR doesn't touch Minnesota, so the defect is the same on main and stays a follow-up. Witness: any Minnesota filer with salt_refund_income.

Mutants. Each ran in its own process; I restored the code after each and git status is clean.

Mutant Killed by
Drop the section 68 subtraction amt_income.yaml 3 failed (2017 reversal, 2026 reversal, 2026 end to end); property test [2017] only (P3-1)
Count dependents' refunds (drop the filer mask) amt_income.yaml 1 failed (the dependent case); property test passes (no dependents)
Floor Colorado line 1 at Form 6251 line 6 co_alternative_minimum_taxable_income.yaml 1 failed (the negative line 1 case); co_amt.yaml passes
Mine: keep co_state_addback in line 2 co_alternative_minimum_taxable_income.yaml 1 failed (the unit case); co_amt.yaml passes
Mine: drop the refund subtraction from federal AMTI amt_income.yaml 4 failed; property test 3 failed (all years)
Mine: old separate base (taxable_income + amt_excluded_deductions) amt_income.yaml 1 failed (the separate case); property test [2017], [2025] (P3-1)

Tests at the head, one file per process. amt_income.yaml 17 passed; co_alternative_minimum_taxable_income.yaml 6 passed; the property test 3 passed in 95 s wall time, including the model load. The property test asserts the full claim for what it draws: refund invariance on twin households, and the statutory identity against independently read AGI and itemized deductions. Its weakness is only coverage (P3-1). The edited existing CO case ("CO AMTI with no federal AMT income") now supplies line 4 = line 5, which keeps the old expected value honest under the new line 1 rule.

Readers.

  • amt_income is read by amt_exemption, amt_income_less_exemptions and co_alternative_minimum_taxable_income.
  • amt_income_less_exemptions is read by alternative_minimum_tax, amt_tax_including_cg, the two FEIE AMT variables (amt_income_less_exemptions_plus_section_911_exclusion, amt_section_911_capital_gain_excess) and Colorado.
  • amt_separate_addition and amt_income_before_separate_addition have no readers outside amt_income.
  • Iowa's amt_exemption is a local name in ia_amt_*.py, not a reader.
  • No reader is made worse. Every change lowers AMTI toward the statute's definition.

Scope. Nothing under .github/ or policyengine_us/tests/policy/baseline/partners/. Changelog fragment changelog.d/amti-section-68-and-tax-refunds.fixed.md is top-level. The impact: and axiom: lines are present.

Overlap.

Baseline movement. The diff moves baseline outputs:

  • federal AMT for filers with state or local tax refunds (every year);
  • federal AMT for itemizers subject to section 68 (2013-2017 and from 2026), where AMTI falls by the full reduction;
  • federal AMT for separate filers above the increase threshold;
  • Colorado AMT through federal AMTI and the new negative line 1;
  • downstream, every state that reads federal income tax.

Population checks for the hub: change in federal AMT revenue and AMT payer counts in 2025 and 2026, with 2026 split by section 68 itemizers; and Colorado co_amt totals and payer counts.

What I couldn't check

  • Sources. This VM's proxy refused law.cornell.edu, uscode.house.gov, govinfo.gov, irs.gov, tax.colorado.gov, olls.info, ecfr.gov and web.archive.org (CONNECT 403 or DNS refusal), so I couldn't confirm or quote any source myself. Every legal reading above rests on the hub's 2026-11-03 reading, which matches the body's quotes. That includes 56(b)(1)(C) and (E), 55(d)(2) and (d)(4)(A)(ii)(IV), Form 6251 lines 2b and 4, the 2017 Form 6251 lines 6 and 7, DR 0104AMT lines 1, 2 and 4, DR 0104 page 3, and C.R.S. 39-22-104 and 105.
  • Population impact. No microsimulation on population data here.
  • The body's "16 AMT and Colorado AMT YAML files pass (133 cases)". I ran only the two changed YAML files. CI's IRS and states baseline shards passed at this head.

Generated by Claude Code

@DTrim99

DTrim99 commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Leave state tax refunds and the section 68 reduction out of federal AMTI, and fix Colorado AMTI to match

PR #10099 (author: MaxGhenis), head 6cf3eb6e22. This is the first review. The diff covers 8 files:

  • a new variable, amt_income_before_separate_addition (Form 6251 line 4 before the 55(d)(2) increase). It subtracts each head's or spouse's salt_refund_income, floored at zero, and, for itemizers, itemized_taxable_income_deductions_reduction;
  • amt_income, which becomes adds = ["amt_income_before_separate_addition", "amt_separate_addition"];
  • amt_separate_addition, which now figures the separate filer's increase on the new variable;
  • co_alternative_minimum_taxable_income. DR 0104AMT line 1 goes negative when the exemption exceeds AMTI, line 2 drops co_state_addback, and line 4 drops the refund and is floored at zero;
  • 8 new cases in amt_income.yaml, plus 3 new cases and 1 edited case in co_alternative_minimum_taxable_income.yaml;
  • a Hypothesis property test, policyengine_us/tests/core/test_amt_income_refund_and_section_68_invariants.py;
  • a changelog fragment.

No partner test file is touched.

Summary

The law supports every change, and I found no wrong result in a claimed year. The body says the sources couldn't be refetched, so I fetched each one myself. The body's quotes match.

  • 26 U.S.C. 56(b)(1), current text:
    • (C): "No recovery of any tax to which subparagraph (A)(ii) applied shall be included in gross income for purposes of determining alternative minimum taxable income."
    • (E): "Section 68 shall not apply."
    • The amendment notes show that P.L. 116-94 struck the old (B) and "redesignated subpars. (C) to (F) as (B) to (E)". Section 103(c) applies this to "taxable years ending after December 31, 2018", so for 2017 and earlier the same text is (D) and (F). The code comments and the 2017 test comment say exactly this.
    • P.L. 119-21 amended 56(a)(3), (b)(2)(A), (b)(2)(A)(ii), (b)(2)(C) and (e)(1)(B), and left (b)(1) alone.
  • Section 68 from 2026. P.L. 119-21 sec. 70111(a) replaced section 68 with the 2/37 reduction, and the new text carves out nothing for the AMT. 56(b)(1)(E) therefore reaches the new reduction, so AMTI excludes it from 2026.
  • 55(d)(2): "alternative minimum taxable income shall be increased by the lesser of (i) 25 percent of the excess of alternative minimum taxable income (determined without regard to this sentence) over ...". From 2026, 55(d)(4)(A)(ii)(IV) substitutes 50 percent.
  • 2025 Form 6251 instructions:
    • Page 2, line 2b: "Include any refund from Schedule 1 (Form 1040), line 1, that is attributable to state or local income taxes. ... Enter the total as a negative amount." Nothing limits this to itemizers.
    • Page 9, line 4: "If your filing status is married filing separately and line 4 is more than $900,350 ... include 25% of the excess of the amount on line 4 over $900,350."
  • 2017 Form 6251:
    • Line 1 starts itemizers at Form 1040 line 41; everyone else enters line 38 "and go[es] to line 7", so the refund line applies to everyone.
    • Line 6 (instructions, PDF page 2): "enter the amount from line 9 of the Itemized Deductions Worksheet ... Enter it as a negative amount."
    • Line 7 (instructions, PDF page 3): "Include any refund from Form 1040, line 10 ... that is attributable to state or local income taxes."
  • 2025 DR 0104AMT:
    • Page 1: "Enter on line 2 of form DR 0104AMT the sum of lines 3 through 7 and line 9 from form DR 0104. Enter on line 4 ... the sum of all subtractions entered on the DR 0104AD excluding the State Income Tax Refund (line 1, DR 0104AD)."
    • Page 3, line 1: "Amount from line 6 Federal Form 6251. If line 5 on form 6251 is larger than line 4 on form 6251, subtract line 5 from line 4 and enter the resulting negative amount here."
    • The 2025 DR 0104 (page 3) has line 2 "State Income Tax Addback" and line 8 "Reserved for future use".
  • Colorado Revised Statutes 2025:
    • 39-22-105(2)(a) (page 401): "the federal alternative minimum taxable income ... minus the applicable federal exemptions allowed pursuant to such section, with the modifications provided in section 39-22-104". It sets no floor before the modifications.
    • 39-22-104(3)(d)(I) (page 380): "an amount equal to the deduction claimed".
    • 39-22-104(4)(e)(II) (page 386): "The purpose of the subtraction ... is to avoid re-taxing a taxpayer's state income tax refund".

The Colorado reading needs no source-conflict entry. Measured against federal AMTI, which allows no state tax deduction and holds no refund, the (3)(d) addback and the (4)(e) subtraction are both zero. The form says the same, so the statute and the form agree.

All 11 new cases, the edited case and the body's $520.50 figure check out by hand (below). CI is green at this head, and the merge with main is clean.

No critical findings. Three should items:

  • S1. The axiom: line is not a valid form. rulespec-us encodes only the TY2026 section 68 reversal; no issue covers the refund exclusion, the 2013-2017 reversal or Colorado AMTI.
  • S2. The property test never reaches the 2026 section 68 reduction or a 2026 separate filer's increase, though its docstring and the body say it covers 2026 section 68. I reproduced its fixed draws.
  • S3. No test pins the new zero floor on the refund (max_(0, salt_refund_income)): deleting it fails nothing.

Five suggestions: the draft 2026 Form 6251 (re-check it when the final form is out), a 2026 separate filer case at the 50% rate, a variable-named YAML file for the new variable, an issue for Colorado's DR 0104AMT duplication bar, and body corrections.

Critical

None.

Should address

S1. The axiom: line is not a valid form, and no rulespec-us issue covers most of what the PR changes.

Where. The PR body ends with axiom: (hub files pe-parity before landing). CLAUDE.md "Axiom Parity" allows only <legal id> encoded-correct | <rulespec PR> encoded | <rulespec issue> queued | n/a: <reason>. This PR changes federal AMT and Colorado AMT results, so n/a doesn't apply. #10095, #10100 and others got the same finding for the same line.

What rulespec-us has:

  • us/statutes/26/55.yaml is bounded to tax year 2026. Its amt_excluded_deductions is salt_deduction + misc_deduction - section_68_reduction for itemizers. It cites 56(b)(1), "Section 68 shall not apply", so the TY2026 section 68 reversal is encoded and matches this PR. The module's amt_separate_addition also figures the increase on AMTI with the other adjustments.
  • The refund exclusion of 56(b)(1)(C) is not encoded. The module fails closed through the input no_other_section_56_adjustment, so a filer with a refund leaves the module's domain.
  • There is no TY2013-2017 section 68 reversal and no Colorado 39-22-105 module.
  • I searched issues and PRs for "56(b)(1)", "AMTI", "alternative minimum taxable income", "section 68", "39-22-105", "Colorado AMT", "tax refund", "6251" and "10099". I found no issue for any of these provisions. The open AMT issues (rulespec-us#1487, People who are too high-income are eligible for California CARE via categorical eligibility #1857, New York SSI State Supplement #1478) cover other provisions.

Fix. File one dispatch-ready, pe-parity-labelled rulespec-us issue, modelled on rulespec-us#1467. It needs:

  • the module paths: us/statutes/26/55 (replace the fail-closed guard with the 56(b)(1)(C) refund exclusion, and extend the 56(b)(1)(E)/(F) reversal to TY2013-2017) and a Colorado 39-22-105 module;
  • the corpus citations and the verbatim law quoted above;
  • the required outputs: AMTI before and after the 55(d)(2) increase, and Colorado AMTI;
  • companion tests from an external source. Examples are the 2025 Form 6251 instructions' line 4 example ("if the amount on line 4 is $920,350, enter $925,350 instead") and the DR 0104AMT line 1 negative-amount rule.

Then write the line as axiom: TheAxiomFoundation/rulespec-us#<n> queued.

S2. The property test doesn't reach what its docstring and the body say it covers in 2026.

Where. test_amt_income_refund_and_section_68_invariants.py:12-14, and the body's "Invariants" paragraph. Both say the test covers "2026 (the P.L. 119-21 section 68)" for single, joint and separate filers. The settings at lines 83-90 are max_examples=4, derandomize=True and 8 units per example.

What's wrong. Under pytest, the derandomized draws are fixed by the test's source, the node id (the Hypothesis pytest plugin gives each parametrized id its own digest) and the Hypothesis version. I regenerated them without building a model:

  • I stubbed Simulation so no model was built.
  • I used the CI node id ...::test_amt_income_leaves_out_refunds_and_section_68[2026] and the locked Hypothesis 6.168.3.

The 2026 draws reach neither provision:

  • The largest itemizers' wages are 581,702 (single) and 543,698 (joint). Both are below the 2026 37% thresholds of 640,600 and 768,700, so the section 68 reduction is zero in every 2026 example.
  • The largest separate filer's wages are 201,682, far below the 640,200 level where the 2026 increase starts.

So in 2026 the statutory identity is checked only where section 68 is zero, and the increase is never exercised. The [2017] draws do reach both, for example a separate itemizer with wages 872,070 and real estate taxes 40,000. The author's review comment of 2026-11-03 found the same in a mutation run: dropping the section 68 subtraction fails only [2017]. The YAML still pins both terms. But the property test's distinct value, which CLAUDE.md "Justify Python coverage" asks a new Python test to state, is the 2026 identity, and the draws never produce it. Any edit to the file, or a Hypothesis upgrade, also reshuffles the draws.

Fix. Pin boundary households with @example, so every year reaches section 68 and the increase on both sides of the cap. For example:

from hypothesis import HealthCheck, example, given, settings

BOUNDARY_UNITS = [
    dict(status="SINGLE", itemizes=True, employment_income=2_000_000,
         salt_refund_income=5_000, real_estate_taxes=12_000,
         home_mortgage_interest=30_000),
    dict(status="JOINT", itemizes=True, employment_income=3_000_000,
         salt_refund_income=8_000, real_estate_taxes=20_000,
         home_mortgage_interest=40_000),
    dict(status="SEPARATE", itemizes=False, employment_income=700_000,
         salt_refund_income=10_000, real_estate_taxes=0,
         home_mortgage_interest=0),
    dict(status="SEPARATE", itemizes=False, employment_income=950_000,
         salt_refund_income=20_000, real_estate_taxes=0,
         home_mortgage_interest=0),
]

@given(units=st.lists(tax_unit(), min_size=8, max_size=8))
@example(units=BOUNDARY_UNITS)
def test_amt_income_leaves_out_refunds_and_section_68(year, units):

The 700,000 separate filer falls inside the 2026 band (AMTI 700,000 > 640,200). The 950,000 filer falls inside the 2025 band (> 900,350) and is capped in 2026. Both single and joint itemizers exceed the 2026 37% thresholds. The author's comment reports that this patch kills both 2026 mutants. If you'd rather not, drop "2026 (the P.L. 119-21 section 68)" from the docstring and the body, and the 2026 parametrization with it.

S3. The zero floor on the refund is not pinned.

Where. amt_income_before_separate_addition.py:57: filer * max_(0, person("salt_refund_income", period)).

What's wrong. The floor is right: it mirrors irs_gross_income, which adds each source as max_(0, ...), so a negative refund input never enters AGI and AMTI must not take it back out. But every test uses a positive refund (the property test draws 1-20,000), so deleting max_(0, ...) fails no case. Without the floor, a negative input would raise AMTI by its absolute value.

Fix. Add one case to amt_income.yaml:

- name: A negative refund input is not in AGI and adds nothing to AMTI, 2025
  absolute_error_margin: 0.01
  period: 2025
  input:
    tax_unit_itemizes: true
    taxable_income: 100_000
    salt_deduction: 8_000
    salt_refund_income: -2_000
    filing_status: SINGLE
  output:
    # irs_gross_income floors each source at zero: 100,000 + 8,000.
    amt_income: 108_000

Without the floor the model would give 100,000 + 8,000 + 2,000 = 110,000.

Suggestions

G1. Re-check 2026 once the final Form 6251 is out.

  • The IRS's draft 2026 Form 6251 (created 5/26/26) has no line that restores the section 68 reduction. Line 1b starts from Form 1040 line 11b less line 14 (net of Schedule 1-A line 43), and line 2a adds back only "the taxes from Schedule A, line 7".
  • The draft 2026 Schedule A (created 5/12/26) asks at line 18 whether deductions "may be limited" and sends the limited total to Form 1040 line 12e.
  • If the final form and instructions keep that layout, the PR's statute-first reading is a statute-versus-form choice. Record it in source_conflicts/candidates.yaml.
  • I don't count this as a should item yet, for two reasons. A draft is "not for filing". And the 2026 instructions, which could send the reversal through line 3 ("Other adjustments"), aren't published; the only draft instructions on irs.gov are still the 2025 edition.

G2. Pin the separate filer's increase at the 2026 rate.

  • This PR changes the base of the increase, but the only cases are 2025 (amt_income.yaml) and 2022 (amt_separate_addition.yaml).
  • Hand case for 2026: married filing separately, wages 700,000, refund 10,000, standard deduction, TX.
    • AGI is 710,000, and AMTI before the increase is 710,000 − 10,000 = 700,000.
    • The 2026 separate level is 500,000 + 70,100 / 0.5 = 640,200, which matches the draft 2026 Form 6251 line 4 note ("more than $640,200").
    • The increase is min(70,100, 0.5 × 59,800) = 29,900, so amt_income is 729,900.
  • The author's comment reports the head gives exactly this, and that main gives 744,900.

G3. Give the new variable its own YAML file. The refund and section 68 terms live in amt_income_before_separate_addition, but the five unit-input cases that test only those terms are in amt_income.yaml. CLAUDE.md asks for tests in the variable-named file, so consider moving them to amt_income_before_separate_addition.yaml and keeping the end-to-end and separate filer cases in amt_income.yaml.

G4. Open an issue for DR 0104AMT's duplication bar (pre-existing).

  • DR 0104AMT page 1 says: "do not enter any amount on line 2 or line 4 that duplicates any income or adjustment made in arriving at federal alternative minimum taxable income."
  • co_federal_deduction_addback (DR 0104 line 4) can duplicate the standard deduction or the taxes that Form 6251 line 2a already adds back.
  • The PR's own reasoning for 39-22-104(3)(d), measuring the addback against the AMTI base, applies equally to (3)(p).
  • main has the same gap, and is worse there because it also keeps the state tax addback. The body lists this as a follow-up, so an issue would track it.

G5. Body corrections.

  • Replace the "Source check" paragraph: every quote in the body matches its source (see the Summary).
  • Under "Not changed", add that line 2b also covers refunds of property, sales and foreign taxes from Schedule 1 line 8z, and that salt_refund_income is the model's only refund input.
  • In item 3, main's separate base didn't "still hold" the 2025 senior deduction. It lacked the senior deduction add-back (and, before 2018, the personal exemptions).
  • Update the "Invariants" paragraph to match S2.

Verified correct

Hand checks (the inputs are the YAML's):

Case Arithmetic Expected
2025 single itemizer (unit) line 1 100,000 + SALT 8,000 − refund 2,000 106,000
2026 single itemizer (unit) 1,000,000 + 10,000 − section 68 5,000 1,005,000
2026 non-itemizer (unit) 50,000 + standard deduction 1,000; the 5,000 reduction is gated off 51,000
2017 single itemizer (unit) 300,000 + 0 exemptions + 20,000 − 4,155. Check: 3% × (400,000 − 261,500) = 4,155; the exemption is fully phased out at 261,500 + 122,500 = 384,000 315,845
2025 head of household with a dependent's refund 100,000 + 8,000 − 1,000; the dependent's 500 is excluded 107,000
2025 single, end to end AGI 102,000; itemized 8,000 + 20,000; TI 74,000; AMTI 74,000 + 8,000 − 2,000 = 102,000 − 2,000 − 20,000 74,000 / 80,000
2026 single, end to end SALT cap 40,400 − 30% × 495,000 falls below the floor, so 10,000; section 68 = 2/37 × min(40,000, 1,000,000 − 640,600) = 2,162.16; TI 1,000,000 − 37,837.84 = 962,162.16; AMTI 962,162.16 + 10,000 − 2,162.16 970,000
2025 separate filer, refund 20,000 SALT 5,000 (the floor), TI 1,015,000; before 1,015,000 + 5,000 − 20,000 = 1,000,000; level 626,350 + 68,500 / 0.25 = 900,350; increase min(68,500, 0.25 × 99,650) 1,000,000 / 24,912.50 / 1,024,912.50
2025 separate filer on main base TI + excluded = 1,020,000; 0.25 × 119,650 = 29,912.50; 1,015,000 + 5,000 + 29,912.50 1,049,912.50 (body)
CO unit case 200,000 + (10,000 − 6,000) − (5,000 − 1,500) 200,500
CO line 4 floor 200,000 + 0 − max(0, 500 − 1,500) 200,000
CO negative line 1 federal: AGI 15,000; line 1b 15,000 − 15,750 = −750; + 15,750 − 15,000 = 0. CO: line 1 0 − 88,100; line 2 15,000; line 4 max(0, 15,000 − 15,000) = 0; max(0, −73,100) 0 / 0 / 0
CO existing case (edited) 85,700 − 85,700 = 0, so line 1 is 0; 0 + 10,000 − 5,000 (the 2024 single exemption is 85,700) 5,000
Body's $520.50 old floored line 1: 0 + 15,000 − 0 = 15,000; 3.47% × 15,000 520.50

The refund mirrors AGI exactly. irs_gross_income adds not_dependent * max_(0, salt_refund_income) per person. The new line subtracts tax_unit.sum(~is_tax_unit_dependent * max_(0, salt_refund_income)), with the same mask and the same floor. Joint filers lose both spouses' refunds, and a dependent's refund is on neither side. The refund is subtracted before the 55(d)(2) increase, as "determined without regard to this sentence" requires.

Section 68.

  • The sign is right. itemized_taxable_income_deductions = total − reduction, so taxable income is higher by the reduction, and AMTI subtracts it, gated on tax_unit_itemizes.
  • The reduction never exceeds the total (the 80% ceiling before 2018; 2/37 of at most the total from 2026), so the max_(0, ...) in itemized_taxable_income_deductions never binds.
  • The taxable-income-≤-0 branch (agi - deductions) is net of the reduction too.
  • limitation/applies.yaml is true for 2013-2017 and from 2026, which matches 68(f) as in effect before P.L. 119-21 and the new section 68.

Colorado.

  • For 2021 on, when Colorado's AMT exists, amt_income_less_exemptions = max_(0, amt_income − amt_exemption). So line_1 always equals amt_income − amt_exemption, which is what the form and 105(2)(a) both say.
  • The max_(0, ...) on line 5 is harmless: the form has no floor there, but a negative line 5 gives a negative line 6 and zero AMT.
  • co_subtractions includes salt_refund_income summed over all members, so line 4 removes exactly what the DR 0104AD line 1 entry put in.
  • The 105(2)(a) bond-interest exceptions and the line 4 Colorado-interest exclusion are unreachable, because the model has no private activity bond input.

Code and tests.

  • Readers. amt_income is read only by amt_exemption, amt_income_less_exemptions and the Colorado variable. No reform overrides it. adds keeps negative values, as Form 6251 line 4 can be negative.
  • Entities, periods and vectorization. Everything is TaxUnit/YEAR, built from where/max_/min_ and tax_unit.sum. There is no new state-gated int or enum key, so the NH Add New Hampshire state supplementation for 2026 #10156 pattern doesn't apply.
  • The other terms are pinned. The filer mask, the section 68 subtraction and its itemizer gate, the new separate base, and Colorado lines 1, 2 and 4 are each pinned by a YAML case (I traced each mutant by hand).
  • References. Each anchor shows its value: i6251--2025 page 2 (line 2b) and page 9 (line 4); f6251--2025 page 1; f6251--2017 page 1; i6251--2017 pages 2-3 (with a # PDF pages 2-3 comment); DR0104AMT_2025 pages 1 and 3; DR0104_2025 page 3; olls CRS 2025 pages 380, 386 and 401.
  • Changelog. changelog.d/amti-section-68-and-tax-refunds.fixed.md is top-level, with a fitting type.
  • Python test cost. The body reports a labelled local measurement for the core group. tests/core already holds many Hypothesis invariant tests of this kind.
  • Partner tests. No partner test file is touched, and the Household API Partners job passed.

Axiom line assessment

The line is invalid (S1). The TY2026 section 68 reversal is encoded in rulespec-us us/statutes/26/55 (amt_excluded_deductions), consistent with this PR. The 56(b)(1)(C) refund exclusion (that module fails closed on it), the TY2013-2017 reversal and C.R.S. 39-22-105(2)(a) / DR 0104AMT have no module and no queued issue. A queued line needs an OPEN, pe-parity-labelled, dispatch-ready issue that matches this head.

CI status

gh pr checks 10099: 36 pass, 3 skipping, no failures. The full run at this head, 41715326437, passed every job: Household API Partners, Microsimulation, all 11 Baseline shards, all 9 Contrib shards, Rest Python shards 1-9 (which include the core group that runs the property test), PR validation and Quick Feedback. The 3 skipping entries are the aggregate "Baseline tests", "Contrib tests" and "Python tests" jobs of run 41712887677, from before the PR left draft. That run ran after #10287, so the source-conflict ratchet was checked.

Branch status

The branch is 7 commits behind main and 8 ahead. git merge-tree --write-tree PolicyEngine/main 6cf3eb6e22 is clean. main's 7 new commits (#10307, #10600, #10554 and version bumps) touch none of this PR's files, and no AMT, Colorado or taxable income file. Sibling PRs:

Verdict: REQUEST_CHANGES

@DTrim99 DTrim99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes: 0 critical, 3 should (the axiom line isn't a valid form and rulespec-us covers only the TY2026 section 68 reversal; the property test never reaches the 2026 section 68 reduction or a 2026 separate filer's increase despite its docstring; the new zero floor on the refund is unpinned). 26 USC 56(b)(1)(C)/(E) and the Colorado reading are right. Full report in the comment above.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Picking this up for the US hub. I'll post a hand-off comment here when it's ready.


Generated by Claude Code

Bring in #10094, which nets Colorado's federal deduction addback of the
state income tax addback. Colorado AMTI reads co_additions, so the two
changes now move it together. The merge is clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N2tyHP3hjAvuftmiMnzT62
The five cases that test only the refund and section 68 lines set
taxable income directly, so they test amt_income_before_separate_addition.
They now live in that variable's file and assert it, and they keep their
amt_income checks. The end-to-end and separate filer cases stay put.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N2tyHP3hjAvuftmiMnzT62
Every case used a positive refund, so deleting max_(0, ...) failed
nothing. irs_gross_income floors each refund at zero, so a negative input
never enters AGI; a case now checks that AMTI doesn't take it back out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N2tyHP3hjAvuftmiMnzT62
This PR changes the base of the 55(d)(2) increase, but the only cases
were 2025 and 2022. A 2026 separate filer at $700,000 of wages now pins
the 50% rate and the $640,200 start, figured after the refund.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N2tyHP3hjAvuftmiMnzT62
The derandomized draws never reached the 2026 section 68 reduction or a
2026 separate filer's increase, so mutants that break both passed the
2026 case. A fixed example now adds itemizers above both section 68
thresholds and separate filers in the 2025 and 2026 increase bands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N2tyHP3hjAvuftmiMnzT62
Colorado AMTI reads co_additions, which now nets the federal deduction
addback of the state income tax addback (#10094). No case pinned the two
changes together. A 2025 and a 2026 single itemizer with $450,000 of
wages now do: 354,900 and 363,900, matching a hand computation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N2tyHP3hjAvuftmiMnzT62
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Ready for hub review
497c816

This round fixes DTrim99's two open should-address items (S2 and S3) and does four of the five suggestions. S1, the axiom: line, was already fixed: the hub replaced the line after the review. The fifth suggestion (G4) becomes a proposed issue. I also merged main with #10094 and pinned the Colorado household the brief names. The head was 6cf3eb6e22 when I started, and no one else pushed during the round. I pushed once.

Commits since 6cf3eb6e22:

  • 4fc69712c0 merges main (clean).
  • 6a42dde3e9 moves the new variable's five unit cases to its own file (G3).
  • 93f061a351 pins the refund's zero floor (S3).
  • 044d710312 pins the 2026 separate filer increase (G2).
  • 665e8fff9b pins boundary households in the property test (S2).
  • 497c8168bf adds the Colorado end-to-end cases.

1. Main

2. The Colorado end-to-end case

Cases at co_alternative_minimum_taxable_income.yaml:108 (2025) and :145 (2026): a single itemizer with $450,000 of wages, $5,000 of state withholding, $5,000 of real estate tax and $20,000 of mortgage interest. Sales taxes are zero, so the SALT deduction is the $10,000 of income and property tax.

I computed both by hand from the sources before running them:

  • Federal. Itemized deductions are $30,000, so taxable income is $420,000. Form 6251 line 2a adds back the $10,000 of taxes, so line 4 is $430,000.
    • 2025: line 6 = $430,000 − $88,100 = $341,900 (2025 Form 6251 instructions, line 5 worksheet).
    • 2026: line 6 = $430,000 − $90,100 = $339,900 (Rev. Proc. 2025-32 § .10). The section 68 reduction is zero, since $420,000 + $30,000 is below the $640,600 where the 37% bracket starts.
  • DR 0104.
    • Line 2 (C.R.S. 39-22-104(3)(d)(I)): min($5,000, $30,000 − the standard deduction) = $5,000.
    • Line 4: $30,000 − $12,000 = $18,000 (2025, (3)(p.5)(I)(A)), or $30,000 − $1,000 = $29,000 (2026, (3)(p.7)(I)(A)).
    • The 2025 104 Book (page 9) reduces line 4 "by any state income tax deduction from Schedule A of your federal return that is already added back on line 2". So line 4 is $13,000 and $24,000.
  • DR 0104AMT. Line 2 is "The sum of lines 3 through 7 and line 9, form DR 0104", so $13,000 or $24,000. Line 4 is 0.
    • Colorado AMTI 2025: $341,900 + $13,000 = $354,900.
    • Colorado AMTI 2026: $339,900 + $24,000 = $363,900.

Both match the hub's figures and the model at the final head. Each case also pins taxable income, amt_income, amt_income_less_exemptions, co_state_addback and co_federal_deduction_addback.

  • Main. Current main gives $359,900 and $368,900. The hub's $364,900 and $373,900 came from main before Reduce Colorado's federal deduction addback by the state income tax already added back #10094. The two PRs each take $5,000 out of Colorado AMTI line 2: Reduce Colorado's federal deduction addback by the state income tax already added back #10094 nets the line 4 addback, and this PR drops the line 2 state addback.
  • One difference. DR 0104AMT page 1 also says "do not enter any amount on line 2 or line 4 that duplicates any income or adjustment made in arriving at federal alternative minimum taxable income." The 104 Book nets line 4 as if the state income tax sits in the addback. On that view, the $5,000 of real estate tax in the addback duplicates Form 6251 line 2a, and Colorado AMTI is $349,900 and $358,900. The model, main and this PR keep the whole DR 0104 line 4 amount, as the line 2 instruction reads. The YAML comment above the cases says so. It is DTrim99's G4, a pre-existing gap; see proposed issue 1.
  • The 2026 addback. C.R.S. 2025 makes (3)(p.7) effective "if the ballot issue described in section 22-82.9-213 is approved". The model's $1,000 single exemption for 2026 assumes it was. I didn't verify the November 2025 result.

3. Findings

  • S1 (axiom line). When DTrim99 reviewed, the body ended with axiom: (hub files pe-parity before landing). It now reads axiom: TheAxiomFoundation/rulespec-us#2033 queued (...); TheAxiomFoundation/rulespec-us#2034 queued (...), so the hub replaced it after the review. I kept it. This session can't read rulespec-us, so I couldn't confirm that those issues are open, labelled pe-parity and match this head. Drafts to refresh them are in section 5.
  • S2 (property test 2026 coverage). I reproduced it at the original path, since the derandomized draws depend on the node id. With the section 68 subtraction dropped, the old file failed only [2017], and [2026] passed. Fix: BOUNDARY_UNITS and @example(units=BOUNDARY_UNITS) at test_amt_income_refund_and_section_68_invariants.py:59-92 and :134, with the docstring at lines 12-17. The units are DTrim99's and the hub's. With the example, dropping the section 68 subtraction fails [2017] and [2026], and the old separate base fails all three years.
  • S3 (refund floor). With max_(0, ...) deleted, the five moved unit cases pass, which reproduces the finding. The new case at amt_income_before_separate_addition.yaml:96 gives 110,000 against 108,000 under that mutant. irs_gross_income floors each source with max_(0, ...) (irs_gross_income.py:19), so the case's premise holds.
  • G1 (2026 Form 6251). I checked on 2026-11-09. The draft 2026 Form 6251 (created 5/26/26) has line 2b, "Tax refund from Schedule 1 (Form 1040), line 1 or line 8z", but no section 68 line. The only draft instructions on irs.gov, i6251--dft.pdf, are titled "2025 Instructions for Form 6251". So the 2026 instructions aren't out, and their line 3 might still carry the reversal. I recorded no candidate (see Rulings).
  • G2. The 2026 separate filer case is at amt_income.yaml:271. Hand: AGI $710,000, less the $16,100 standard deduction, gives $693,900. Add back $16,100 and subtract the $10,000 refund: $700,000. The increase is min($70,100, 0.5 × ($700,000 − $640,200)) = $29,900, so AMTI is $729,900. Main gives $744,900. § 55(d)(4)(A)(ii)(IV) substitutes "50 percent" for "25 percent", and Rev. Proc. 2025-32 gives the $640,200 complete phaseout for separate filers.
  • G3. The five unit-input cases moved to the new amt_income_before_separate_addition.yaml. Each now asserts that variable and keeps its amt_income check. A static comparison shows each moved case equals its original plus that one output line, and the 9 main cases left in amt_income.yaml are unchanged. Both files are in the same directory, so CI routes them to the same shard.
  • G4. Proposed as issue 1 below. The PR body's "Not changed" item now describes it, with the Colorado household's $5,000.
  • G5. Done in the body, which also takes the hub's P3-3 text:

The hub's P3-4 (the earlier hand-off's narrative) needs no code change. The separate filer case forces itemizing, so taxable income is $1,015,000, and AMTI before the increase is $1,000,000 in every version.

4. Rulings for the hub

  1. No new candidate. No finding this round turns on two sources that disagree in a year the PR claims. G1 isn't a conflict yet: the 2026 form is a draft and its instructions aren't out. If the final 2026 form and instructions keep the draft's layout, this candidate text is ready:
    • id: us:amti-section-68-reversal-2026-form; program: income-tax; years: {from: 2026, type: tax};
    • sources: 26 U.S.C. 56(b)(1)(E) (statute) and the 2026 Form 6251 (form);
    • readings: statute, "section 68 does not apply, so AMTI adds back the reduction"; other, "the form has no line that restores it";
    • pe_us: follows: statute, code amt_income_before_separate_addition.py.
  2. G4 may need one later. It pits the (3)(p.5)/(p.7) addback, applied to the AMTI base under § 39-22-105(2)(a), against DR 0104AMT's duplication bar. This PR takes no reading on it.
  3. Reversals. None. Every reading in the body and the earlier reviews stands.

Sources I read this round:

  • 26 U.S.C. 55 and 56, from law.cornell.edu.
  • The 2025 Form 6251 instructions, pages 2 and 9.
  • The 2017 Form 6251 and its instructions, pages 2-3.
  • The draft 2026 Form 6251.
  • Rev. Proc. 2025-32.
  • C.R.S. Title 39, 2025 compilation, pages 380-386 and 401.
  • The 2025 DR 0104AMT, pages 1 and 3, and the 2025 104 Book, pages 8-9. tax.colorado.gov serves a Cloudflare challenge to curl; the web-fetch tool saved the PDFs, and I extracted their text.

I couldn't fetch the 2025 DR 0104. Its quotes in the body rest on DTrim99's review.

5. Axiom drafts (for the hub to file)

6. Mutants

Each ran in its own process at the final head against the named file, and was then restored with git checkout. git status showed the target clean after each.

Mutant Undoes File Result Killed by
Y1: no zero floor on the refund S3 amt_income_before_separate_addition.yaml 1 of 6 fail (110,000 vs 108,000) the negative refund case
Y2: 2026 rate 0.25 G2 amt_income.yaml 1 of 13 fail (14,950 vs 29,900) the 2026 separate filer case
Y3: line 2 keeps co_state_addback this PR's line 2 co_alternative_minimum_taxable_income.yaml 3 of 8 fail (206,500 vs 200,500; 359,900 vs 354,900; 368,900 vs 363,900) the unit case and both end-to-end cases
Y4: no netting of the line 4 addback #10094, pinned with this PR co_alternative_minimum_taxable_income.yaml 2 of 8 fail (18,000 vs 13,000; 29,000 vs 24,000) both end-to-end cases
P1: drop the section 68 subtraction S2 the property test [2017] and [2026] fail BOUNDARY_UNITS in 2026
P2: old separate base (taxable_income + amt_excluded_deductions) S2 the property test all three years fail BOUNDARY_UNITS in 2026

G3 moves cases and changes no result, so no mutant applies.

7. Tests and CI

At the final head, one process each:

File Result
amt_income.yaml 13 passed
amt_income_before_separate_addition.yaml 6 passed
co_alternative_minimum_taxable_income.yaml 8 passed
co_amt.yaml 2 passed
amt_separate_addition.yaml 3 passed
co_federal_deduction_addback.yaml 42 passed
test_amt_income_refund_and_section_68_invariants.py 3 passed
test_source_conflicts.py 103 passed

ruff format left the property test unchanged, and ruff check passes.

Property test cost, measured locally (Python 3.14, 4 vCPU; not Linux CI): 95 s of wall time before and 88 s after, including the model load, with a peak of 1,760 MB before and 1,766 MB after. The pinned example adds no measurable time. It runs in CI's Rest Python group.

CI: the Pull request run at 497c8168bf, 42654756663, was in progress when I posted this. I didn't wait for it, as the brief says. One job had started and none had finished, so none was skipped or cancelled yet.

8. Body

Every section now describes 497c8168bf:

impact: the hub will measure is now impact: pending a comparison at the final head. The axiom: line is unchanged.

9. Judgment calls

10. Proposed follow-up issues

  1. Apply DR 0104AMT's duplication bar to Colorado's federal deduction addback. DR 0104AMT bars entering on line 2 any amount that duplicates a federal AMTI adjustment, but co_alternative_minimum_taxable_income carries the whole co_federal_deduction_addback. For the $450,000 itemizer, the $5,000 of real estate tax already added back on Form 6251 line 2a may be counted twice. Decide the ordering, and record the reading as a candidate.
  2. Subtract state tax refunds in Minnesota's AMT income. mn_amt_taxable_income starts from federal AGI, which includes salt_refund_income. Its AMT_SUBTRACTIONS (mn_amt_taxable_income.py:47-52) don't remove the refund, while Minnesota's regular subtractions list (mn/tax/income/subtractions/sources.yaml) does.
  3. Recheck the 2026 Form 6251 when its instructions are published. The draft form has no section 68 reversal line. If the final form and instructions don't carry the reversal, record the statute-versus-form candidate in Rulings 1.

DISMISSAL MAP

  • S1 (axiom: line invalid): ALREADY FIXED by the hub. The body names rulespec-us#2033 and South Carolina dependent exemption  #2034; refresh drafts are in section 5.
  • S2 (property test misses 2026 section 68 and the 2026 increase): FIXED at test_amt_income_refund_and_section_68_invariants.py:59-92 and :134 (@example(units=BOUNDARY_UNITS)); P1 and P2 fail [2026].
  • S3 (refund floor unpinned): FIXED at amt_income_before_separate_addition.yaml:96; Y1 killed.
  • G1 (recheck the final 2026 Form 6251): CHECKED 2026-11-09. Only the draft form exists; the 2026 instructions aren't out. No candidate yet; text in Rulings 1, follow-up 3.
  • G2 (2026 separate filer at 50%): DONE at amt_income.yaml:271; Y2 killed.
  • G3 (variable-named YAML file): DONE in amt_income_before_separate_addition.yaml (5 cases moved, verified statically).
  • G4 (issue for the duplication bar): FOLLOW-UP, proposed issue 1; the Colorado cases' comment and the body note the $5,000 effect.
  • G5 (body corrections): DONE in the body's Source check, Not changed, item 3 and Invariants sections.

Generated by Claude Code

@DTrim99

DTrim99 commented Nov 9, 2026

Copy link
Copy Markdown
Collaborator

PR Review (round 2): Leave state tax refunds and the section 68 reduction out of federal AMTI, and fix Colorado AMTI to match

PR #10099 (author: MaxGhenis), head 497c8168bf. Our first review (2026-11-04, head 6cf3eb6e22) requested changes for three should items. Since then the branch has six new commits:

The five commits of the author's own touch only test files. The formulas, references and changelog fragment are byte-identical to what we reviewed. Between the two heads, the only change to the PR's variable directories is #10308's amt_income_less_exemptions.py, which came in from main.

Summary

All three should items are fixed, and each fix is pinned. Removing any one of them now fails a test.

  • S1. The axiom: line names two open, pe-parity, dispatch-ready rulespec-us issues.
  • S2. The property test now reaches the 2026 section 68 reduction and the 2026 separate filer's increase.
  • S3. A negative-refund case pins the zero floor.

Suggestions:

  • G2, G3 and G5 are done.
  • G1 is still waiting on the IRS: the 2026 Form 6251 instructions aren't published.
  • G4 (the DR 0104AMT duplication bar) is written up in the body and the new Colorado cases' comment, but no issue has been filed.

Checks:

No critical or should items remain open. Three suggestions remain.

Prior findings

Finding Status Evidence
S1. axiom: line not a valid form; no rulespec-us issue for most of the change Fixed The body now ends axiom: TheAxiomFoundation/rulespec-us#2033 queued (...); TheAxiomFoundation/rulespec-us#2034 queued (...). Both issues are OPEN and labelled pe-parity, created 2026-11-05. Each gives target module paths, corpus citations, verbatim law, required outputs and companion tests, and records its blocker (dated corpus ingestion, release and re-pin, encoder approval). #2033 keeps the encoded TY2026 section 68 component and asks for the 56(b)(1)(C) recovery exclusion, the 2013-2017 reversal and the separate filer composition. #2034 asks for signed Colorado AMTI. See Axiom.
S2. Property test never reaches 2026 section 68 or a 2026 separate filer's increase Fixed @example(units=BOUNDARY_UNITS) (test file lines 72-105 and 147), and the docstring now says what the fixed example covers. Hand trace for 2026: (a) the single itemizer (wages 2,000,000) has SALT at the 10,000 floor and itemized deductions of 40,000, so section 68 takes 2/37 × 40,000 = 2,162.16. The joint itemizer (3,000,000) has 50,000, so 2,702.70. Dropping the subtraction moves the statutory identity by those amounts, far past the tolerance (about 0.5 at 2 million). (b) The 700,000 separate filer's base is 700,000 for both twins, so the increase is min(70,100, 0.5 × 59,800) = 29,900. Under the old base (taxable income + excluded deductions), the twin with the refund gets 710,000 and an increase of 34,900, so refund invariance fails by 5,000. (c) In 2025 the 950,000 filer's old base is 970,000, giving 17,412.50 against 12,412.50. CI ran [2017], [2025] and [2026], all PASSED.
S3. Zero floor on the refund not pinned Fixed New case "A negative refund input is not in AGI and adds nothing to AMTI, 2025": 100,000 + 8,000 − max(0, −2,000) = 108,000 for both outputs. Without max_(0, ...) the model gives 100,000 + 8,000 + 2,000 = 110,000, so the case fails.
G1. Re-check the final 2026 Form 6251 Deferred, reasonable The 2026 instructions still aren't out. The irs.gov draft instructions file is the 2025 edition, unchanged since 2025-12-04. The draft 2026 form (last modified 2026-05-28) has line 2b but no section 68 line. The author drafted the candidate text (us:amti-section-68-reversal-2026-form, follows: statute). Carried as Suggestion 3.
G2. Pin the 2026 separate filer increase Done amt_income.yaml, "Separate filer's 2026 increase is 50% and figured after the refund": 700,000 / 29,900 / 729,900 (hand check below).
G3. Variable-named YAML file Done The five cases moved verbatim to amt_income_before_separate_addition.yaml. Each gained one output line, the new variable, equal to its unchanged amt_income value. amt_income.yaml keeps main's 9 cases plus 4 new ones (13). Both files sit in the same directory, so they run in the same CI shard (irs).
G4. Open an issue for DR 0104AMT's duplication bar Open (suggestion) Only proposed: no issue is filed. The body's "Not changed" section and the new Colorado cases' comment describe the gap. Carried as Suggestion 1.
G5. Body corrections Done Changes in the body: "Source check" lists what was read. "Not changed" adds the Schedule 1 line 8z refunds and the fact that salt_refund_income is the only refund input. Item 3 now says the old base "lacked the add-backs of the 2025 senior deduction and, before 2018, the personal exemptions". "Invariants" describes the fixed example.

New findings

Critical

None.

Should address

None.

Suggestions

1. File the DR 0104AMT duplication-bar issue (G4, carried).

  • What the new cases pin. The new Colorado end-to-end cases pin the model's current reading, which carries the whole DR 0104 line 4 addback onto DR 0104AMT line 2: 354,900 (2025) and 363,900 (2026).
  • Two other readings give the same lower result.
    • DR 0104AMT page 1 says "do not enter any amount on line 2 or line 4 that duplicates any income or adjustment made in arriving at federal alternative minimum taxable income". If the 5,000 of real estate tax in the addback duplicates Form 6251 line 2a, line 2 is 8,000 (2025) or 19,000 (2026).
    • The PR measures 39-22-104(3)(d) against the AMTI base. Applied to (3)(p.5)/(p.7), the same method gives the AMT-allowed deductions (20,000 of mortgage interest) less 12,000 or 1,000: the same 8,000 and 19,000.
    • Both readings give Colorado AMTI of 349,900 and 358,900.
  • This household's tax. The difference doesn't reach tax here. The tentative minimum tax (3.47% × 354,900 = 12,315.03) is below the regular Colorado tax on about 438,000 of Colorado taxable income. Other households could owe it.
  • Fix. The gap predates this PR, and main is worse, so this stays a suggestion. Please file the author's proposed issue 1, and note that these two cases will move with it. The Minnesota follow-up (proposed issue 2: mn_amt_taxable_income never subtracts the refund) is also unfiled.

2. Bring rulespec-us#2033 and #2034 up to this head. Both issues still cite 6cf3eb6e22. The PR's behavior hasn't changed since they were filed, so they still describe this head; this is not a stale-issue finding. Posting the author's drafted comments would align the companion lists:

  • South Carolina dependent exemption  #2033:
    • It requires "dated annual tables; do not apply the 2026 rate to 2025", but it has no 2026 separate filer row. Add the 729,900 case: base 700,000, increase min(70,100, 50% × (700,000 − 640,200)) = 29,900.
    • Add the negative-refund row as a PE-adapter check: PE floors the refund at zero; the legal module takes covered recoveries.
  • South Carolina dependent exemption  #2034:
    • The issue tells the encoder to "Apply the full quoted duplication bar". So the new 354,900 and 363,900 rows should go in as PE-adapter expectations, not as law outputs (see Suggestion 1).

3. G1, carried, and two body lines.

  • When the 2026 Form 6251 instructions are published, cite the line that carries the section 68 reversal, or record the drafted candidate.
  • In the body, the "Tests" bullet says the CI run at 497c8168bf "was queued". It has since completed with success, so update that line, and the impact: line once the comparison is done.

Verified

Hand checks (every new or changed expectation):

Case Arithmetic Expected
Moved: 2025 single itemizer, refund 2,000 100,000 + 8,000 − 2,000; no separate addition 106,000 / 106,000
Moved: 2026 single itemizer, reduction 5,000 1,000,000 + 10,000 − 5,000 1,005,000 / 1,005,000
Moved: 2026 non-itemizer 50,000 + 1,000; the reduction is gated off 51,000 / 51,000
Moved: 2017 single itemizer 300,000 + 0 + 20,000 − 4,155 315,845 / 315,845
Moved: 2025 head of household with a dependent's refund 100,000 + 8,000 − 1,000; the dependent's 500 is excluded 107,000 / 107,000
New: negative refund input, 2025 100,000 + 8,000 − max(0, −2,000) 108,000 / 108,000
New: 2026 separate filer, wages 700,000, refund 10,000 AGI 710,000 − 16,100 standard deduction = 693,900; + 16,100 − 10,000 = 700,000. Zero-exemption level 500,000 + 70,100 / 0.5 = 640,200; min(70,100, 0.5 × 59,800) 700,000 / 29,900 / 729,900
Same, on main base 693,900 + 16,100 = 710,000; 0.5 × 69,800 = 34,900 744,900 (body)
New: Colorado 2025 itemizer, wages 450,000 SALT 5,000 + 5,000 (sales taxes zero; cap 40,000 with MAGI under 500,000); itemized 30,000; TI 420,000; Form 6251 line 4 430,000; line 6 430,000 − 88,100 = 341,900. DR 0104 line 2 min(5,000, 30,000 − 15,750) = 5,000; line 4 30,000 − 12,000 − 5,000 = 13,000. DR 0104AMT 341,900 + (18,000 − 5,000) − max(0, 0 − 0) 420,000 / 430,000 / 341,900 / 5,000 / 13,000 / 354,900
New: Colorado 2026 itemizer section 68: 450,000 is below 640,600, so 0; TI 420,000; line 4 430,000; line 6 430,000 − 90,100 = 339,900. DR 0104 line 2 min(5,000, 30,000 − 16,100) = 5,000; line 4 30,000 − 1,000 − 5,000 = 24,000. DR 0104AMT 339,900 + 24,000 0 / 420,000 / 430,000 / 339,900 / 5,000 / 24,000 / 363,900
Colorado itemizer on main (with #10094), and before #10094 341,900 + 5,000 + 13,000 = 359,900 and 339,900 + 5,000 + 24,000 = 368,900; before #10094: 341,900 + 5,000 + 18,000 = 364,900 and 339,900 + 5,000 + 29,000 = 373,900 body figures

Sources for the 2026 amounts:

  • The draft 2026 Form 6251 lists the line 5 exemptions as 90,100 (single, starting at 500,000), 140,200 (joint, 1,000,000) and 70,100 (separate, 500,000). Its line 4 note says "more than $640,200".
  • 26 U.S.C. 55(d)(4)(A)(ii)(IV) applies paragraph (2) "by substituting '50 percent' for '25 percent'". Paragraph (2) carries both the phase-out and the separate filer sentence, and the model reads one rate parameter for both.
  • 2025 values come from the 2025 Form 6251 line 5 table (88,100 starting at 626,350; separate 68,500) and its instructions for line 4 (900,350).
  • main's Colorado (3)(p.7) exemption of 1,000 cites HB25-1274 section 18, in effect because Proposition MM passed.

The merged changes from main fit this PR:

Code, tests and scope:

  • No new code. The fix commits change only YAML and the property test. They add no new branch or reference and leave the changelog as it was.
  • Python test cost. The body gives a labelled local measurement before and after (95 s and 88 s of wall time, peak about 1.76 GB both times). In CI the file runs in Rest Python shard 4 (the core-1 group). After the model load, [2017], [2025] and [2026] took about 5.5 s, 5.4 s and 2.8 s. The fixed example adds four households (eight with twins) to one vectorized simulation per year.
  • Tests and partners. The YAML cases are in variable-named files. No partner test file is touched.

Main-side guards:

Axiom

The line is valid. axiom: TheAxiomFoundation/rulespec-us#2033 queued (...); TheAxiomFoundation/rulespec-us#2034 queued (...). Both issues are OPEN and labelled pe-parity, and both are dispatch-ready on the rulespec-us#1467 model:

  • South Carolina dependent exemption  #2033:
    • modules us/statutes/26/56/b/1 (proposed) and us/statutes/26/55 (existing consumer);
    • 56(b)(1)(A), (C)-(E), 55(d)(2) and P.L. 119-21 sections 70107(c) and 70111 quoted verbatim;
    • five required outputs;
    • the eight original YAML rows as companion tests.
  • South Carolina dependent exemption  #2034:
    • us-co/statutes/39/39-22-105#colorado_alternative_minimum_taxable_income plus proposed DR 0104AMT and DR 0104AD modules;
    • 39-22-105(2)(a), 104(3)(d)(I) and 104(4)(e), and the 2024 and 2025 DR 0104AMT instructions, quoted verbatim;
    • signed law outputs kept separate from PE's floored comparison value.

Both record the blocker that justifies queued. They cite the earlier head, but the PR's behavior is unchanged, so they still match it; refreshing them is Suggestion 2.

CI

gh pr checks 10099: 36 pass, 0 failing, 0 pending. Run 42654756663 at 497c8168bf concluded success, with every job passing:

  • PR validation, Household API Partners, and Package and compatibility;
  • Quick Feedback and Microsimulation;
  • all 11 Baseline shards and all 9 Contrib shards;
  • Rest Python shards 1-9.

The log of Rest Python shard 4 shows test_amt_income_leaves_out_refunds_and_section_68[2017], [2025] and [2026] PASSED.

Branch

The branch is 14 commits ahead of main and 6 behind (61d9e8520c).

Verdict: APPROVE

@DTrim99 DTrim99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2: all round 1 should-address items are fixed and pinned by tests. Three suggestions remain; details in the review comment above.

@MaxGhenis MaxGhenis closed this Nov 10, 2026
@MaxGhenis MaxGhenis reopened this Nov 10, 2026
@MaxGhenis MaxGhenis closed this Nov 10, 2026
@MaxGhenis MaxGhenis reopened this Nov 10, 2026
@MaxGhenis
MaxGhenis merged commit 0093af4 into main Nov 10, 2026
75 of 79 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

US + core hub merge audit, us#10099 at 497c8168bf0bbcf81dd0bcbd530bf14b5a0a37c3 (squash): Leave state tax refunds and the section 68 reduction out of federal AMTI, and fix Colorado AMTI to match.

  • Reviews:
    • An independent review approved 6cf3eb6e22.
    • DTrim99 requested changes at 6cf3eb6e22: the form of the axiom: line, a property test that missed the 2026 section 68 reduction and the 2026 separate-filer increase, and an untested zero floor on the refund. Five test-only commits answer each, and DTrim99 approved 497c8168bf.
    • An independent review of the changes since 6cf3eb6e22 agreed at 497c8168bf. It found the four formula files unchanged and recomputed each new expected value from the parameter files.
  • Gates checked live at merge:
  • Impact (default dataset, 497c8168bf against main at ba9bfdea75): we estimate that the change lowers federal AMT by $67.3m in 2025 and by $398.0m in 2026, for 8 and 49 sampled tax units (20,661 and 231,168 weighted). Colorado's AMT comes to $0 on both sides, so Colorado income tax doesn't change.
  • Next: two follow-ups remain from the description's "Not changed" list: the DR 0104AMT duplication bar on line 2, and the refund in Minnesota's AMT.
  • Axiom: TheAxiomFoundation/rulespec-us#2033 and #2034 queued, each now with companion rows for the cases added since 6cf3eb6e22.

🤖 Generated with Claude Code

@MaxGhenis
MaxGhenis deleted the amti-section-68-and-tax-refunds branch November 10, 2026 06:06
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.

3 participants