Repository navigation
Count every co-resident's income in the Arizona property tax credit - #10580
Conversation
ARS 43-1072(H)(4)-(5) defines household income as the income of everyone who lived in the claimant's homestead, and (G) allows one claimant per household. The credit summed only the claimant's tax unit and let every qualifying tax unit in a home claim. Household income now adds each tax unit's amount over the household, and only the eligible tax unit with the largest claim receives the credit. Subsection (I) excludes Arizona unemployment, so federal AGI's unemployment is taken out and other states' payments (a new input) added back; nontaxable strike benefits and alimony left out of federal gross income are added (lines H and I). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6HuSwzHSJwmgBQXw2d
…rule Hypothesis draws homes of one to three tax units and checks, in one simulation per example, that every tax unit sees the same household income, that at most one unit per home gets a credit and it is the largest claim, that Arizona unemployment never changes household income while other states' does dollar for dollar, and that a co-resident's raise never raises a shared home's credit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6HuSwzHSJwmgBQXw2d
A lookup on the tax unit's own income passed every earlier property, so the test now compares each eligible unit's claim with the schedule amount at the home's income, limited to the unit's own property taxes paid. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6HuSwzHSJwmgBQXw2d
|
Ready for hub review Head: Paths below are under Items1. Household income across tax units
2. One claimant per household
3. Arizona unemployment
4. Strike benefits and alimony
5. Above-the-line deductionsNo change, and BLOCKED on sources. I could not read R15-2C-502(A)(1) or (C), ITR 12-1, or the 2025 instructions.
6. DocumentationDocumentation is updated on 7. SurveySee the PR body. The quotes come only from PE-US's own comments, and each gap call is unverified against statute.
Hand computations (2025 tables, ARS 43-1072(B))
Tests (one file per process)
Mutants (each in its own process, code restored after)
All 9 mutants are killed. CIThe PR is a draft, so CI has not run. The workflow skips drafts. Judgment calls
Proposed follow-up issues
Generated by Claude Code |
|
Picking this up for the US hub. I'll post a hand-off comment here when it's ready. Generated by Claude Code |
Ruling us-az:ptc-above-the-line-deductions: A.A.C. R15-2C-502(A)(1) counts "the sum of all income not specifically excluded in A.R.S. § 43-1072", and neither ITR 12-1 nor Form 140PTC lines A to I subtracts an adjustment. Federal AGI took the IRA, student loan, educator, HSA, half-SE-tax and other deductions off non-dependents' income, so household income was understated. The add-back mirrors above_the_line_deductions over the same list, minus loss_ald, whose business part the rule counts. Ruling us-az:ptc-rent-and-taxes-shared-home keeps each tax unit's own rent and taxes; the comment now gives the statute and form words, and a YAML case covers a claimant whose co-resident pays the rent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6GvzSJyt6QD8rg4qb2
The half-SE-tax deduction is 211.94324 in float32, so an exact 211.94 fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6GvzSJyt6QD8rg4qb2
|
Ready for hub review Head: Ownership: the last push before mine was at 07:42Z, so within the 6-hour window. It was the head the brief names, though, and that session had posted its hand-off at 08:36Z, so I went ahead. Nobody pushed between my pick-up comment and my push. Paths are under Ruling 1,
|
| Mutant | _agi.yaml |
Property 7 |
|---|---|---|
M10 leave self_employment_tax_ald out of the add-back |
1 failed (az_property_tax_credit_agi 2,788.06 ≠ 3,000) |
failed |
M11 add loss_ald back too |
2 failed (Schedule C loss; the existing capital-loss-limit case) | pass, since it doesn't vary loss_ald |
Both are killed.
CI
The Pull request run at 57f6086f was skipped because the PR is a draft: https://github.com/PolicyEngine/policyengine-us/actions/runs/41424186160
Judgment calls
- The add-back sums the list itself, mirroring
above_the_line_deductions, rather than takingabove_the_line_deductions - loss_ald. That follows the brief's "every deduction ingov.irs.ald.deductions". The downside: if a dataset or reform suppliesabove_the_line_deductionsdirectly, or overrides its formula, the add-back won't match it. - No
# Source conflictmarker. Neither ruling sets a statute against a form; the sources agree. - Property 7 puts each person-level deduction on the dependent too. That checks the
filer_amounts_recorded_on_dependentspath, and it asserts that federal AGI drops in every variant, so the property can't pass trivially.
Proposed follow-up issue
- Arizona property tax credit: employer adoption assistance in household income. Read the ARS 43-1072(I) exclusions to decide whether §137 adoption assistance counts. If it is excluded, leave
qualified_adoption_assistance_expenseout of the add-back inaz_property_tax_credit_agi.
Generated by Claude Code
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10580 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 1 10 +9
Lines 15 173 +158
Branches 0 7 +7
==========================================
+ Hits 15 173 +158
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Ready for hub review I reviewed the whole diff from merge base The methodology choices are these. The claimant is the eligible tax unit with the largest claim, a modeling convention for the (H)(1) choice the household makes. FindingsP2-1. The
|
| Mutant | Killed by |
|---|---|
M10: self_employment_tax_ald left out of the add-back |
_agi.yaml "Half of self-employment tax…" (2,788.06 vs 3,000); property 7 |
M11: loss_ald added back too |
_agi.yaml "A Schedule C loss still reduces…" and "Federal capital loss limit is replaced…"; property 7 passes, since it doesn't vary loss_ald |
Gate removed (return potential) |
_claimant.yaml, 4 of 6 cases; test_household_income_and_one_claimant |
| Household sum switched to the unit's own income | _household_income.yaml, 3 cases (both son cases and one co-resident case); test_household_income_and_one_claimant |
Mine: include_dependents dropped from the add-back |
only test_above_the_line_deductions_do_not_change_income |
| Mine: potential counts household rent | _claimant.yaml, 3 cases; test_household_income_and_one_claimant |
-
Hypothesis properties. None can pass trivially in the sense the brief asks about:
- Property 7 asserts that AGI moves.
- Properties 1 to 3 kill the gate, household-sum and rent mutants.
- Property 4 runs on the one-tax-unit homes in each draw.
- Property 5 is the weakest: it follows from the tables never rising, which the file checks first.
- The draws are bounded, not exhaustive at the table edges. The YAML schedule files cover the band edges.
-
Readers.
az_property_tax_creditfeedsgov.states.az.tax.income.credits.refundable(2019+), and from thereaz_refundable_credits,az_income_tax,state_income_taxandhousehold_net_income. It also feedsgov.states.household.state_property_tax_credits, and from theretaxsim_state_property_tax_credit, and the 2021az_families_tax_rebate, which subtracts the other refundable credits.az_property_tax_credit_agiis read only throughincome_sources.yaml. No other Arizona credit reads it.- All of these move at baseline.
-
Scope. Nothing under
.github/ortests/policy/baseline/partners/changes, and Household API Partners passed at this head. No open PR touches these files; the search found only Apply Iowa, Kansas, Louisiana and Maryland rules for a filer who can be claimed as a dependent #10045, which changes no Arizona orgov.irs.aldfile. The changelog fragment is a top-levelchangelog.d/az-ptc-household-income.fixed.md. Theimpact:andaxiom:lines are present. -
Population check (for the hub). Beyond
az_property_tax_creditand the common set, the impact pair needs:az_property_tax_credit_household_income,az_property_tax_credit_claimant,az_property_tax_credit_potential,az_property_tax_credit_eligible,az_property_tax_credit_income,az_property_tax_credit_agi,az_property_tax_credit_unemployment,az_property_tax_credit_nontaxable_income;az_refundable_credits,az_income_tax,az_families_tax_rebate(2021),taxsim_state_property_tax_credit;- a count of tax-unit heads per Arizona household.
Expect both signs (see P2-1).
What I couldn't check
- Sources. azleg.gov, azdor.gov, law.cornell.edu and apps.azsos.gov were all refused by this VM's proxy. I confirmed no statute, rule, ITR or form text myself. Every quote in the code and body rests on the hub's 2026-11-02 reading, and I took the three standing readings as given.
- Parity. rulespec-us#1483 is outside this session's GitHub scope, so I didn't check its five companion rows against this head's YAML.
- Microdata. I couldn't count Arizona households in the default microdata that hold more than one tax unit. I also couldn't check whether any tax unit spans two households (P3-3), or whether
is_household_headis populated. - CI selection. A GitHub API rate limit stopped me reading the CI job logs, so I couldn't confirm which shard ran
test_az_property_tax_credit_household.py. Every Python shard passed.
Generated by Claude Code
get_rank orders by members_position, the order of the people in the situation, so the household's members list doesn't move a tie. The comments and a test name said household member order. No behaviour changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Hub impact pair, progress The base side has finished; the head side runs next.
Generated by Claude Code |
|
Ready for hub review The brief named head
Sums are weighted totals over all records, in dollars. Weighted rows count tax units or households. I rounded each cell on its own, so a change can differ by $1 from the rounded head sum minus the rounded base sum.
Which variables move. Seven of the ten move, all on Arizona records. No record outside Arizona changes in any variable.
What moves them. I read the PR's formula diff. Then I recomputed the ten outputs and the credit's intermediate variables on the 1,164 Arizona households alone, once per tree. That run reproduces every Arizona record of the pair exactly: the largest difference is 0 for all ten variables and the weights, on both sides.
Dropped variables: none. All ten exist in both trees on the same entity (eight on the tax unit, two on the household), and the helper accepted all ten. Resources. Each side took about 9 minutes and peaked at 3.63 GiB. That is far below the brief's reference run (eight chunks of nine outputs, about 70 minutes per side, 9.75 GiB) and the 14 GB rerun threshold, so I didn't need the 16-chunk rerun.
Commands. Setup, as in the brief except that I cloned blobless ( curl -sI https://huggingface.co/api/datasets/policyengine/populace-us | head -1
git clone --filter=blob:none https://github.com/PolicyEngine/policyengine-us.git pe && cd pe
git fetch origin pull/10580/head:pr-10580 pull/10561/head:pr-10561
HEAD_SHA=$(git rev-parse pr-10580); BASE_SHA=$(git merge-base origin/main $HEAD_SHA); echo $HEAD_SHA $BASE_SHA
git worktree add --detach ../head $HEAD_SHA
git worktree add --detach ../base $BASE_SHA
git show pr-10561:policyengine_us/tools/calculate_chunked.py > ../calculate_chunked.py
git diff $BASE_SHA $HEAD_SHA -- pyproject.toml uv.lock # empty, so the head's environment serves both sides
cd ../head && uv sync
apt-get install -y time # the VM had no /usr/bin/time
sha256sum populace_us_2024.h5 # the file in the Hugging Face cacheRuns. H=$PWD/../calculate_chunked.py; PY=$PWD/../head/.venv/bin/python
export OMP_NUM_THREADS=4 OPENBLAS_NUM_THREADS=4 MKL_NUM_THREADS=4
PYTHONPATH=$PWD/../base /usr/bin/time -v $PY ../pair_side.py $H 8 2026 ../out/base > ../out/base.log 2> ../out/base.err
PYTHONPATH=$PWD/../head /usr/bin/time -v $PY ../pair_side.py $H 8 2026 ../out/head > ../out/head.log 2> ../out/head.err
$PY ../compare.py ../out/base ../out/head ../out/compare.jsonDuring each side, nothing else ran except light shell polling loops. One ran Two extra steps ran outside the sides, one process at a time, from # before the sides: smoke test, 2 chunks on a 400-household subset
PYTHONPATH=$PWD/../base /usr/bin/time -v $PY ../smoke.py ../calculate_chunked.py 2026 300
PYTHONPATH=$PWD/../head /usr/bin/time -v $PY ../smoke.py ../calculate_chunked.py 2026 300
# after both sides: the 1,164 Arizona households alone, one Microsimulation per tree, then the cross-check
PYTHONPATH=$PWD/../base /usr/bin/time -v $PY ../explain.py ../calculate_chunked.py 2026 ../out/az_base.pkl
PYTHONPATH=$PWD/../head /usr/bin/time -v $PY ../explain.py ../calculate_chunked.py 2026 ../out/az_head.pkl
$PY -I ../explain_compare.py ..Each side's compare.json{
"household_net_income": {
"entity": "household",
"base_sum": 17161528033453.125,
"head_sum": 17161520653835.82,
"change": -7379617.3046875,
"records_changed": 4,
"weighted_changed": 14700.440122383647,
"weighted_up": 0.0,
"weighted_down": 14700.440122383647,
"largest_abs": 502.0,
"rows": [
{
"id": 1045571,
"base": 31639.705078125,
"head": 31137.705078125
},
{
"id": 101822,
"base": 91388.515625,
"head": 90886.515625
},
{
"id": 101013,
"base": 97762.9453125,
"head": 97260.9453125
},
{
"id": 1101705,
"base": 150411.28125,
"head": 150021.28125
}
]
},
"household_benefits": {
"entity": "household",
"base_sum": 2059893797415.6846,
"head_sum": 2059893797415.6846,
"change": 0.0,
"records_changed": 0,
"weighted_changed": 0.0,
"weighted_up": 0.0,
"weighted_down": 0.0,
"largest_abs": 0.0,
"rows": []
},
"az_property_tax_credit": {
"entity": "tax_unit",
"base_sum": 40957021.54327575,
"head_sum": 33577404.238127746,
"change": -7379617.3051480055,
"records_changed": 4,
"weighted_changed": 14700.440122383647,
"weighted_up": 0.0,
"weighted_down": 14700.440122383647,
"largest_abs": 502.0,
"rows": [
{
"id": 1059888,
"base": 502.0,
"head": 0.0
},
{
"id": 137293,
"base": 502.0,
"head": 0.0
},
{
"id": 136108,
"base": 502.0,
"head": 0.0
},
{
"id": 1137063,
"base": 390.0,
"head": 0.0
}
]
},
"az_property_tax_credit_income": {
"entity": "tax_unit",
"base_sum": 376421300977.306,
"head_sum": 378634015956.305,
"change": 2212714978.9989624,
"records_changed": 508,
"weighted_changed": 1284055.1684047726,
"weighted_up": 1228143.1490246812,
"weighted_down": 55912.01938009157,
"largest_abs": 57818.171875,
"rows": [
{
"id": 59724,
"base": 142317.78125,
"head": 84499.609375
},
{
"id": 1059724,
"base": 389277.21875,
"head": 331459.0625
},
{
"id": 1136701,
"base": 132928.140625,
"head": 173193.828125
},
{
"id": 1058980,
"base": 45043.76953125,
"head": 79254.0234375
},
{
"id": 59422,
"base": 33460.41015625,
"head": 0.0
}
]
},
"az_property_tax_credit_agi": {
"entity": "tax_unit",
"base_sum": 362023288935.2246,
"head_sum": 364236004125.32544,
"change": 2212715190.10083,
"records_changed": 508,
"weighted_changed": 1284055.1684047726,
"weighted_up": 1228143.1490246812,
"weighted_down": 55912.01938009157,
"largest_abs": 57818.16796875,
"rows": [
{
"id": 59724,
"base": 107672.9375,
"head": 49854.76953125
},
{
"id": 1059724,
"base": 354632.375,
"head": 296814.21875
},
{
"id": 1136701,
"base": 132928.140625,
"head": 173193.828125
},
{
"id": 1058980,
"base": 32129.96484375,
"head": 66340.21875
},
{
"id": 59422,
"base": 33460.41015625,
"head": 0.0
}
]
},
"az_property_tax_credit_dependent_income": {
"entity": "tax_unit",
"base_sum": 2189814749.006299,
"head_sum": 2189814749.006299,
"change": 0.0,
"records_changed": 0,
"weighted_changed": 0.0,
"weighted_up": 0.0,
"weighted_down": 0.0,
"largest_abs": 0.0,
"rows": []
},
"az_refundable_credits": {
"entity": "tax_unit",
"base_sum": 76636339.85728398,
"head_sum": 69256722.55213597,
"change": -7379617.3051480055,
"records_changed": 4,
"weighted_changed": 14700.440122383647,
"weighted_up": 0.0,
"weighted_down": 14700.440122383647,
"largest_abs": 502.0,
"rows": [
{
"id": 1059888,
"base": 527.0,
"head": 25.0
},
{
"id": 137293,
"base": 552.0,
"head": 50.0
},
{
"id": 136108,
"base": 527.0,
"head": 25.0
},
{
"id": 1137063,
"base": 415.0,
"head": 25.0
}
]
},
"az_income_tax": {
"entity": "tax_unit",
"base_sum": 6295095571.875141,
"head_sum": 6302475189.180289,
"change": 7379617.305148125,
"records_changed": 4,
"weighted_changed": 14700.440122383647,
"weighted_up": 14700.440122383647,
"weighted_down": 0.0,
"largest_abs": 502.0,
"rows": [
{
"id": 1059888,
"base": -527.0,
"head": -25.0
},
{
"id": 137293,
"base": -552.0,
"head": -50.0
},
{
"id": 136108,
"base": -527.0,
"head": -25.0
},
{
"id": 1137063,
"base": -415.0,
"head": -25.0
}
]
},
"income_tax": {
"entity": "tax_unit",
"base_sum": 2595105852713.508,
"head_sum": 2595105852713.508,
"change": 0.0,
"records_changed": 0,
"weighted_changed": 0.0,
"weighted_up": 0.0,
"weighted_down": 0.0,
"largest_abs": 0.0,
"rows": []
},
"state_income_tax": {
"entity": "tax_unit",
"base_sum": 578044599346.724,
"head_sum": 578051978964.029,
"change": 7379617.305053711,
"records_changed": 4,
"weighted_changed": 14700.440122383647,
"weighted_up": 14700.440122383647,
"weighted_down": 0.0,
"largest_abs": 502.0,
"rows": [
{
"id": 1059888,
"base": -527.0,
"head": -25.0
},
{
"id": 137293,
"base": -552.0,
"head": -50.0
},
{
"id": 136108,
"base": -527.0,
"head": -25.0
},
{
"id": 1137063,
"base": -415.0,
"head": -25.0
}
]
}
}Generated by Claude Code |
|
Picking this up for the US hub. I'll post a hand-off comment here when it's ready. Generated by Claude Code |
|
Picking this up for the US hub. I'll post a hand-off comment here when it's ready. Generated by Claude Code |
… dropped az_property_tax_credit_agi subtracts taxable unemployment compensation, and az_property_tax_credit_nontaxable_income nets taxable alimony, only when gov.irs.gross_income.sources lists them. No test ran the other branch, so a reform that drops either source was untested. These tests drop each source and check the amount is counted exactly once: AGI does not subtract unemployment federal AGI never held, and all alimony is added when federal gross income holds none of it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6GnePsyFdWib7Vp4kk
Each reform construction copies the parameter tree and took about 31 s. The two filers hold disjoint income, so one reform that drops both sources checks each branch on its own household at half the cost. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6GnePsyFdWib7Vp4kk
|
Ready for hub review Head: What the item asked for1. Tests: in the new file
2. Mutants. Each ran in its own process, and the code was restored after each.
After the restores, 3. No wrong value found. Both branches give the values the code comments describe, so there is no witness to report. 4. Tests run, one file per process on the build VM:
5. Body. I added one bullet under Python tests. The CI at
|
|
US + core hub merge audit, us#10580 at
|
PE-US computed the Arizona property tax credit (Form 140PTC) from the income of the claimant's own tax unit, and let every qualifying tax unit in a home claim it. Because it started that income from federal AGI, it subtracted federal above-the-line deductions and counted Arizona unemployment compensation. It also left out the strike benefits and alimony that federal gross income excludes. We now add up the income of everyone living in the home, give the credit to one claimant per home, and apply Arizona's own income rules.
Source
The Legislature defines the household and household income in ARS 43-1072. The Department of Revenue applies those definitions in A.A.C. R15-2C-502 and the 2025 Form 140PTC instructions:
Household income across tax units
az_property_tax_credit_income(TaxUnit) still adds up Form 140PTC lines A to I for the unit's members, dependents included, with the unemployment, strike benefit, alimony and deduction changes below.az_property_tax_credit_household_income(Household) adds that amount up over every tax unit in the home. It counts each unit once, through its head, ashousehold_taxdoes inpolicyengine_us/variables/household/marginal_tax_rate_helpers.py:212.az_property_tax_credit_potential(TaxUnit) holds main's credit computation and looks up the table at household income. It keeps main's zero floor and its choice between Table 1 and Table 2.One claimant per household
az_property_tax_credit_eligiblekeeps main's test: a head or spouse aged 65 or older, or receiving SSI, in a tax unit that paid rent or property tax.az_property_tax_credit_claimantpicks the household's eligible tax unit with the largest claim (az_property_tax_credit_potential). A tie goes to the tax unit holding the household head, and otherwise to the one whose head comes first in the person order (get_ranksorts stably bymembers_position).az_property_tax_creditreturns the potential for the claimant and 0 for every other unit.mt_elderly_homeowner_or_renter_credit_selected_claimantdoes.Property taxes and rent in a shared home
The claimant counts their own rent and taxes (ruling
us-az:ptc-rent-and-taxes-shared-home), so we keep main's treatment. Each candidate counts its own tax unit'sreal_estate_taxesand 15% of its ownrent.We cite these sources in the comment in
az_property_tax_credit_potential.py. In a new case inaz_property_tax_credit.yaml, a 70-year-old who pays no rent lives with a 40-year-old in another tax unit who pays $6,000. Neither gets a credit: the 70-year-old fails (A)(2) by paying no rent, and the 40-year-old fails the age test. Inaz_property_tax_credit_claimant.yaml, a parent aged 70 pays $1,000 of rent and a son aged 40 in his own tax unit pays $6,000. The parent's credit stays $150, 15% of the parent's own rent, and the son's rent never lifts it to the $502 table amount.Arizona unemployment (subsection (I), line I)
az_other_state_unemployment_compensation(Person, USD, default 0) holds the part of a person's unemployment compensation paid under another state's law. We treat the rest as Arizona's, since a claimant must have lived in Arizona for the whole year (ARS 43-1072(H)(1)).taxable_unemployment_compensation, an entry ingov.irs.gross_income.sourcesthatirs_gross_incomeadds up.az_property_tax_credit_aginow subtracts it, andaz_property_tax_credit_dependent_incomeskips that source for dependents. Each takes out only what federal gross income holds, so a reform that drops the source leaves nothing to take out.az_property_tax_credit_unemploymentadds the other-state part back in full, up to the person's total unemployment compensation.Strike benefits and alimony (lines H and I)
gov.irs.gross_income.sourcesdoesn't liststrike_benefits, so federal AGI holds none. Newaz_property_tax_credit_nontaxable_incomeadds them for every member, or adds nothing if a reform lists them as a source.taxable_alimony_income, the alimony from divorces before 2019. The new variable addsalimony_income - taxable_alimony_incomefor dependents and non-dependents alike, or all alimony if a reform drops that source, so no alimony counts twice.Above-the-line deductions
We add federal above-the-line deductions back into household income (ruling
us-az:ptc-above-the-line-deductions).Code
az_property_tax_credit_aginow adds back every deduction ingov.irs.ald.deductionsexceptloss_ald. It adds them up withtax_unit_non_dep_addandgov.irs.ald.filer_amounts_recorded_on_dependents, asabove_the_line_deductionsdoes, so the add-back equals what federal AGI subtracted. A reform that drops a deduction from the list adds nothing back.puerto_rico_income,specified_possession_income,us_bonds_for_higher_edandqualified_adoption_assistance_expense, since the department counts income "whether or not subject to Arizona income tax".az_property_tax_credit_agistill subtractsloss_ald, which carries the business losses that ITR 12-1 items (3) to (5) count. Line D still replaces its capital part.az_property_tax_credit_dependent_incomenever subtracted these deductions, so it doesn't change.Invariants
policyengine_us/tests/test_az_property_tax_credit_household.pychecks these with Hypothesis. It draws Arizona homes of one to three tax units, with wages, Arizona and other-state unemployment, strike benefits, alimony, rent and property tax.loss_aldas an input never changesaz_property_tax_credit_income, though it moves federal AGI. The test draws wages, self-employment income or loss, Social Security and a dependent, and puts each person-level deduction on the dependent too.Tests
We ran each test file in its own process.
New YAML files
az_property_tax_credit_household_income.yaml, 11 passed:az_property_tax_credit_claimant.yaml, 6 passed:Existing YAML files. No existing case changed.
az_property_tax_credit.yaml(13 passed) gains the (A)(2) case above, andaz_property_tax_credit_agi.yaml(11 passed) gains cases for student loan interest, half of self-employment tax and a Schedule C loss. The other 13 Arizona credit files pass.Python tests
test_az_property_tax_credit_household.py(new), 3 passed. The household test runs six derandomized examples, each one simulation holding 4 to 6 homes and three variants of them. The deduction test runs four, one simulation each. Locally the file took 14 s of test time and 56 s wall.test_az_property_tax_credit_source_reforms.py(new), 2 passed. Its reform dropstaxable_unemployment_compensationandtaxable_alimony_incomefromgov.irs.gross_income.sources.az_property_tax_credit_agicomes to $30,000 at baseline and under the reform, where an unguarded subtraction would give $25,000. Household income comes to $32,000 in both.az_property_tax_credit_nontaxable_incomerises from $0 to $4,000 under the reform, and household income stays $24,000.test_az_property_tax_credit_income.py(7) andtest_az_property_tax_credit_schedules.py(65) pass, and so dotest_source_conflicts,test_unemployment_compensation_readersandtest_no_group_variables_in_person_adds.Mutants for the above-the-line ruling
We ran each mutant in its own process and restored the code after each.
az_property_tax_credit_agi.yamlself_employment_tax_aldout of the add-backloss_aldback tooloss_aldimpact: we estimate that Arizona property tax credits fall $7.38 million in 2026, and no credit rises. Four tax units in the default dataset (14,700 weighted) lose their whole credit, so their Arizona income tax rises and their household net income falls by the same amount. Tax units' income for the credit rises $2.21 billion on net across 508 records (1.28 million weighted tax units). Federal income tax and household benefits don't change (pair).
axiom: us-az:statutes/43-1072 queued (TheAxiomFoundation/rulespec-us#1483)
🤖 Generated with Claude Code