Skip to content

Count capital gains once in Arizona property tax credit income - #9762

Draft
MaxGhenis wants to merge 3 commits into
mainfrom
fix-az-ptc-capital-gains
Draft

MaxGhenis wants to merge 3 commits into
mainfrom
fix-az-ptc-capital-gains

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

az_property_tax_credit_income adds the list gov.states.az.tax.income.credits.property_tax.income_sources. That list had capital_gains_excluded_from_taxable_income under the comment "Item (7): Capital gains - excluded gains not in Federal AGI", next to az_property_tax_credit_agi (federal AGI less taxable Social Security).

capital_gains_excluded_from_taxable_income is the federal 26 U.S.C. 1(h)(1)(A) step: the part of taxable income taxed at the capital gains rates, which income_tax_main_rates subtracts before applying the ordinary rates. Its formula is not capped at taxable income. When taxable income is zero, reduced_taxable_income is negative and the variable returns min(net_capital_gain, adjusted_net_capital_gain). That is the adjusted net capital gain: long-term gains and qualified dividends, less 28%-rate and unrecaptured section 1250 gain. Federal consumers clamp it (max_(0, taxable_income - exclusion)), so federal tax is unaffected. The Arizona list instead read it as an amount of gains, so gains and qualified dividends that federal AGI already holds counted twice. This mostly hit the low-income seniors the credit is for, whose federal taxable income is zero.

2025, single Arizona renter aged 70, $5,000 rent:

Income main: household income main: credit this PR: household income this PR: credit
$3,000 long-term capital gain $6,000 $0 $3,000 $212
$3,000 qualified dividends $6,000 $0 $3,000 $212
$3,000 wages (unchanged) $3,000 $212 $3,000 $212

The PR also counts dependents' income. irs_gross_income, and so federal AGI, leaves out every tax-unit dependent's income. The removed amount summed all members' gains and qualified dividends, so it had happened to count a dependent's gains. Arizona counts every household member's income whether or not the member is a dependent. The new az_property_tax_credit_dependent_income adds dependents' income from the same federal gross income sources, without Social Security.

Federal AGI deducts every member's losses, dependents' included. So az_property_tax_credit_agi is no longer floored at zero before the other items are added; the Schedule 1 and 2 lookup uses zero for a negative total, as the Form 140PTC line J note says.

This PR also takes the Arizona credit off capital_gains_excluded_from_taxable_income. #9761 (section 911(f) stacking) recomputes that variable on taxable income plus the section 911 exclusion, using the section 911 gain amounts, so it would have moved Arizona household income for Form 2555 filers too. After this PR, Arizona household income does not read it, and #9761 touches no Arizona file.

What Arizona counts

  • ARS 43-1072(H)(6) (azleg.gov, read 2026-10-02): "Income" means the sum of "(a) Adjusted gross income as defined by the department. (b) The amount of capital gains excluded from adjusted gross income." plus (c)-(g). (H)(5): "'Household income' means all income received by all persons of a household". Subsection (I) excludes Social Security.
  • A.A.C. R15-2C-502, the department's definition:
    • (A)(1): "'Adjusted gross income' means the sum of all income not specifically excluded in A.R.S. § 43-1072 whether or not subject to Arizona income tax, except those items that A.R.S. § 43-1072 specifically includes in income."
    • (A)(2): a member of the household is any person residing with the claimant "whether or not the person is related to, or a dependent of, the claimant."
    • (B): "A claimant shall arrive at household income by combining the separately determined income of each member of the household."
    • (C)(3): "Income from capital gains is the net capital gains and losses for each member of the household. Net losses are limited to $1,500 for each household member."
  • ITR 12-1, item (7): "Capital gains and losses from the sale or exchange of property." It nets the year's losses against the year's gains, limits a net loss to $1,500 for each member, and allows no prior-year carryover.
  • Form 140PTC instructions, Part 1 line D, worded the same for 2021 through 2025 (page 4 each year): "For each member of the household, combine gains and losses from the sale or exchange of property. If the result is a gain, enter the gain. If the result is a loss, enter the amount of the loss up to a maximum of ($1,500)." Form line D is "Gain or loss from sale or exchange of property".

None of these sources lists anything under "capital gains excluded from adjusted gross income": no section 1202 exclusion, no home-sale exclusion and no Arizona item, and Form 140PTC has no separate line for it. Read literally, (b) reaches gains that federal AGI leaves out, such as a section 121 home-sale or section 1202 small business stock exclusion. PolicyEngine-US has no variable for either, so the entry is removed rather than replaced. long_term_capital_gains_on_small_business_stock is the taxable 28%-rate part of section 1202 gain, not the excluded part. Arizona's own long-term capital gain subtraction (ARS 43-1022(22), 25% of net long-term gain "included in federal adjusted gross income") reduces Arizona gross income, not federal AGI. Those gains therefore stay in az_property_tax_credit_agi and count once.

Changes

  • income_sources.yaml: drop capital_gains_excluded_from_taxable_income and add az_property_tax_credit_dependent_income. Rewrite the comments to say where line D gains are counted (federal AGI, once), why the preferential-rate amount must not be added, and why dependents' income is added. Add references: R15-2C-502, ITR 12-1 page 2, the 2021-2025 Form 140PTC instructions (page 4) and the 2025 form (page 2).
  • New az_property_tax_credit_dependent_income: for is_tax_unit_dependent members, the gov.irs.gross_income.sources amounts (positive parts, as in irs_gross_income), without taxable_social_security (ARS 43-1072(I)). It is the exact complement of the members irs_gross_income counts.
  • az_property_tax_credit_agi: drop the floor at zero. az_property_tax_credit: look the schedules up at max_(income, 0). These are the same lines as in Apply Arizona's $1,500 member capital loss limit and allow negative household income in the property tax credit #9770, so that PR rebases cleanly.
  • az_property_tax_credit_income: fix the label ("property tax the credit") and add references.
  • New YAML tests, az_property_tax_credit_income.yaml, with Form 140PTC line comments: 16 cases. They cover long-term gains (counted once), qualified dividends, gains large enough to make federal taxable income positive, gains on both spouses' columns, short-term loss netting, a net loss within $1,500, every line together with Social Security excluded, 2021, a dependent's gains, dividends and wages, a capital loss on the dependent and on the claimant, a dependent's rental loss, and a negative line J. Eight of the first eleven fail on main.
  • New property tests, test_az_property_tax_credit_income.py (see Invariants).

Invariants

These are checked on a seeded sample of 60 Arizona tax units: 26 couples, 22 with a child dependent who has income (2 of them with a net capital loss), 6 with positive federal taxable income, 7 with taxable Social Security, and 6 whose credit falls when gains rise. The sample stays where the federal and Arizona capital loss rules agree: each member's net gain is at least -$1,500, and a tax unit's net losses total at most $3,000.

  1. Differential: az_property_tax_credit_income equals an independent Form 140PTC Part 1 line A + B + D + E sum over every member, with Social Security excluded.
  2. Counted once: raising one member's long-term gains by d (the dependent's where there is one, else the head's) raises household income by exactly d.
  3. Independence: setting capital_gains_excluded_from_taxable_income to arbitrary values leaves household income unchanged.
  4. Monotone: az_property_tax_credit never rises when gains rise.

On main, 1, 2 and 3 fail for all 60 units. On this branch all four pass.

Microsimulation

Real runs of the default dataset (populace_us_2024.h5@populace-us-2024-spm-20260909), main (7bc185b) against this branch (7491794), one process per year, policyengine-core 3.32.12, compared tax unit by tax unit:

2025 2026
Tax units whose az_property_tax_credit changes 0 of 79,729 0 of 79,729
Weighted credit total, main and this PR $40,666,618 $40,957,022
Tax units with a nonzero credit, both sides 11 11
Tax units whose household income changes 410 (334 down, 76 up) 410 (334 down, 76 up)
Weighted household income change -$32.4bn -$33.6bn
Eligible tax units (age or SSI, rent or property tax) 141 141
Eligible tax units whose household income changes 59 59

No credit changes. Every eligible tax unit whose household income moved is above the $5,501 Schedule 2 ceiling on both sides, except one already in the $502 top band on both sides. The fix matters for households the dataset doesn't hold, such as low-income seniors with capital gains or dividends, and for any reform that raises the income limits.

Runs on policyengine-core 3.32.8 reached 28-31 GB while computing federal taxable income and were stopped by a 24 GB memory guard. On 3.32.12, the first release with core#556 (branches share cached arrays), every run peaked at 8.6-9.2 GB.

Not changed here

These existing departures from the Arizona rules are left for separate changes:

  • Capital loss limit: federal AGI limits a net capital loss to $3,000 per return. R15-2C-502(C)(3) and line D limit it to $1,500 for each household member. Apply Arizona's $1,500 member capital loss limit and allow negative household income in the property tax credit #9770, stacked on this branch, replaces the federal amounts with each member's line D amount.
  • Income sources: federal AGI and the dependent loop follow the federal source list, not Arizona's. They count unemployment whichever state paid it (ARS 43-1072(I) excludes Arizona's; the model has no paying-state field), and leave out estate income, strike benefits and alimony that is not federally taxable.
  • Schedule 2 thresholds: amount/cohabitating.yaml starts each band one dollar early (2,500 instead of 2,501, and so on), so a household at exactly $2,500 gets $479 instead of $502. The tests here stay off those boundaries.

Review

  • Round 1 (GPT-6.1 Sol, head 628ef23): request changes. Blocking: dependents' gains and dividends dropped out once the preferential-rate amount was removed. Nit: the zero-taxable-income wording. Both fixed in 7b5013b.
  • Round 2 (GPT-6.1 Sol, head 7b5013b): request changes. Blocking: AGI was floored before dependents' income was added, so losses were lost. Should-fix: the property sample's domain, and the source-list limits. Fixed or documented in 7491794.
  • Round 3 (delta 7b5013b..7491794): see the comment below.

axiom: us-az:statutes/43-1072 household income (H)(4)-(6), (I) TheAxiomFoundation/rulespec-us#1483 queued

🤖 Generated with Claude Code

az_property_tax_credit_income added capital_gains_excluded_from_taxable_income
on top of federal AGI. That variable is the part of federal taxable income
taxed at the capital gains rates; when taxable income is zero it is the whole
net capital gain plus qualified dividends. Federal AGI already holds those
amounts, so they counted twice, mostly for the low-income seniors the credit
is for.

ARS 43-1072(H)(6)(b) adds "the amount of capital gains excluded from adjusted
gross income". A.A.C. R15-2C-502(C)(3), ITR 12-1 item (7) and the 2021-2025
Form 140PTC instructions (Part 1 line D) count each member's net gains and
losses from sales or exchanges of property, which federal AGI holds. The model
has no gain excluded from federal AGI, so the entry is removed.

Adds Form 140PTC line-by-line YAML tests and seeded property tests
(differential against a line A-J reference, counted once, independence from
the preferential-rate amount, credit monotone in gains).

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 (7491794).
⚠️ Report is 151 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #9762   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         4           
  Lines           76        64   -12     
  Branches         2         2           
=========================================
- Hits            76        64   -12     
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.

Review r1b: federal AGI (irs_gross_income) leaves out every tax-unit
dependent's income. The removed preferential-rate amount summed all members'
gains and qualified dividends, so it had been counting a dependent's gains;
without it a claimant whose child had $3,000 of gains got $502 instead of $412.
A.A.C. R15-2C-502(A)(2) and (B) count every household member's income whether
or not the member is a dependent, so az_property_tax_credit_dependent_income
adds dependents' income from the same federal gross income sources, without
Social Security (ARS 43-1072(I)).

Also corrects the zero-taxable-income description: the preferential-rate
amount is then the adjusted net capital gain. Adds dependent YAML cases and
dependents to the sampled property tests.

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

Review r2: federal AGI deducts every member's losses, dependents' included,
but az_property_tax_credit_agi floored at zero before dependents' income was
added, so a loss counted only against the claimant's or spouse's own income.
A claimant with no income whose dependent had $3,000 of wages and a $1,000
capital loss got household income of $3,000 instead of $2,000.

az_property_tax_credit_agi is no longer floored. Form 140PTC line J can be
negative, and az_property_tax_credit uses zero for the Schedule 1 and 2
lookup (the same change as in #9770, so that PR rebases cleanly).

Adds regressions for a loss on the dependent, on the claimant, a rental loss
and a negative line J; the property sample now includes dependents' losses,
raises a dependent's gains, and states its actual domain. Notes that the
federal source list is not Arizona's (unemployment by paying state, estate
income, strike benefits, nontaxable alimony).

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

Copy link
Copy Markdown
Contributor Author

#9762 fails tests when merged with current main. While checking #9779 (Schedule 2 thresholds) against this PR, I found that this head (7491794) merged with current main (6b0e773) fails:

  • 3 YAML cases in az_property_tax_credit_income.yaml:
    • "A dependent's capital loss offsets the dependent's wages"
    • "A dependent's capital loss with a claimant's pension"
    • "A dependent's rental loss offsets the dependent's wages"
  • all 3 tests in test_az_property_tax_credit_income.py. In test_household_income_matches_form_140ptc_lines, 2 of 60 sampled units are off, for example 7,921.55 vs 7,065.14 desired.

I bisected this to #9647 ("Keep dependents' losses off the filer's AGI", 4e78791). This head merged with 4e78791^ passes 16/16 and 3/3; merged with 4e78791 it fails as above.

#9779 itself doesn't touch these files. #9770's head (0450a28) merged with #9779 passes all 651 Arizona YAML tests and both property test files.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant