Repository navigation
Conversation
26 U.S.C. 163(h)(4)(B)(i) counts interest on indebtedness incurred by the taxpayer, and 26 CFR 1.163-16(h)(1) applies the $10,000 limit per return. The household-level input was split across a household's tax units by head count (core's group-to-group add()), so roommates and adult children each deducted a share of one loan's interest. Add a person-level input for each filer's own loans (head and spouse count; a dependent's loans do not), and give a household-level amount in full to the household head's tax unit (oldest member when no head is designated). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Multi-tax-unit households, each filer's own loans, a dependent's loan, the per-return limit, several or no flagged heads, and 26 CFR 1.163-16(h)(3) Examples 1 and 2; Indiana follows the federal deduction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conservation of the household total, one holder per household amount, locality across tax units, and a differential against the statute's limit and phase-out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ions Test an adult dependent's own loan and the oldest-member fallback when the oldest member is a dependent, and draw adult dependents in the property tests. Document the several-heads and dependent-head rules on the household input, cite the payor statement legend (91 FR 57243) and point Cornell at 163(h)(4)(B)(i). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
October 23, 2026 14:51
Keeps auto_loan_interest_deduction.yaml as on main, so this PR no longer conflicts with #10395, which appends cases to that file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status: the round-1 Opus 5.5 review (APPROVE-WITH-NITS) is addressed in
04cbbdef, and the impact is in (below). Still waiting on the GPT-6.1 Sol review, which is queued until the Codex lanes reopen around 19:15Z, and on the affected-test batch.Problem
qualified_passenger_vehicle_loan_interestis a Household input, andauto_loan_interest_deductionread it withadd(tax_unit, period, [...]). For a group-to-group add, policyengine-core (commons/formulas.py,for_each_variable, 3.33.12) does three things:So a household's car loan interest was split across its tax units by member count. On main:
This only arises in households with more than one tax unit. On the default dataset those hold 31.3% of the $12.16bn of weighted 2024 input, and $1.64bn of it was split to tax units other than the household head's.
The law ties the interest to the borrower:
Splitting one loan over several returns also multiplied the per-return limit.
Fix
qualified_passenger_vehicle_loan_interest_person: interest on loans the person incurred. It counts on the return of the tax unit the person heads or is the spouse in. A tax-unit dependent's own loans don't reach the filer's return.tax_unit_qualified_passenger_vehicle_loan_interest: the head's and spouse's own interest, plus the household-level amount in full for the one tax unit holding the household head. When no head is designated (API, YAML), that is the oldest member; with several flagged heads, the oldest flagged one; ties go to the first listed (get_rank, as inis_hud_dependent).auto_loan_interest_deductionreads the new variable. The limit and the phase-out are unchanged.Why the household head
The data can't say who took out the loan. Microcosm draws the household amount from the 2022 SCF, whose debts belong to the "primary economic unit": "an economically dominant single individual or couple ... and all other individuals in the household who are financially interdependent with that individual or couple" (2022 SCF codebook, "Unit of analysis"). It then scales by Treasury's six million qualifying loans a year.
The household head is the CPS householder, "the person (or one of the people) in whose name the housing unit is owned or rented". It is the model's closest observed stand-in for that economic unit. The default build sets exactly one head per household, and 98.9% are CPS line 1. The same Microcosm SCF stage also names it as the carrier of its household asset draws:
head_carry, conditionis_household_head, inus/source_stages.json.Microcosm picks the person whose traits drive the imputation by its own rule: the one adult, the man of a married couple, otherwise the oldest adult. In multi-tax-unit households with this interest, that person is in the head's tax unit in 70.5% of records; aligning the two is a data follow-up, noted on PolicyEngine/microcosm#1215. The ruling is logged in
us-hub/source-conflicts/RULINGS.md(us:car-loan-interest-household-attribution).Invariants
These hold for every household. They are tested with Hypothesis plus seeded mixed batches in
tests/core/test_auto_loan_interest_attribution_invariants.py:max(min(interest, 10,000) − 200 × ceil(max(MAGI − threshold, 0) / 1,000), 0), with a $200,000 threshold for a joint return and $100,000 otherwise. It is computed in the test from the statute's numbers.0 ≤ deduction ≤ min(tax unit interest, 10,000).The tests mix households with and without flagged heads (the fallback runs beside flagged ones), include ties and adult dependents, and list people out of household order. Seven mutants are killed, each by the property tests and at least one YAML case:
The round-1 review found that the oldest-filer and every-adult mutants survived; they are now caught.
Tests
tax_unit_qualified_passenger_vehicle_loan_interest.yaml(14 cases):The examples live here, not in
auto_loan_interest_deduction.yaml, so this PR doesn't conflict with Use the $100,000 car loan interest phase-out threshold for surviving spouses #10395, which appends to that file (git merge-treeis clean).in_auto_loan_interest_deduction.yaml: Indiana follows the federal deduction to the head's return.Revert check: with main's
add()formula, 12 of the new cases fail (11 of the 14 here, plus Indiana's). The 3 that still pass read only the new tax-unit variable, or are the one-tax-unit case, which doesn't change.Consumers
in_auto_loan_interest_deduction), South Carolina (sc_obbba_addback), Montana (mt_federal_obbba_subtraction), and the Idaho and Arizona subtraction lists read the federalauto_loan_interest_deductionper tax unit, so they follow the fix unchanged.Impact
This is a real microsimulation on the default dataset (
populace_us_2024, sha6496cc43…). It compares main at the merge basec5837fb00bwith this PR ate5c1b8d16e, for 2025 and 2026. The runs went one at a time under the hub heavy lock. Later commits change only tests, documentation and references: the variables' formulas and attributes are AST-identical toe5c1b8d16e(formula_ast_check.txtin the evidence folder~/reviews/auto-loan-attribution-2026-10-23/impact/). Sums are weighted.auto_loan_interest_deduction(baseline $10.72bn; $10.85bn)taxable_incomeincome_taxstate_income_taxhousehold_net_incomehousehold_benefitsWhy the total deduction falls. The interest is conserved: every household amount still lands on exactly one return. The largest household amount in the data is $2,456, so the $10,000 limit never binds. The whole net fall therefore comes from the phase-out: more of the moved interest now sits on returns whose MAGI is above the $100,000 or $200,000 threshold.
Why federal income tax falls even though the deduction falls.
taxable_incomeis floored at zero. So the $1,566M of deduction taken off other returns raises taxable income by only $1,104M in all, and the $1,448M added to the holders lowers it by $1,101M.States. State income tax moves mostly in Colorado (+$647K in 2025, +$648K in 2026), which starts from federal taxable income. Arizona is +$152K in 2025, when it subtracts the deduction. Indiana is −$108K in 2026, the year its conformity deduction is in
in_deductions. Idaho is −$87K/−$89K. Every other state's change is under $70K. South Carolina's add-back falls $1.5M, but SC tax barely moves. Montana's subtraction is unchanged in total; it moves between people.Comparison files are in
fixes/10406-impact/on the hub host (compare.<year>.json,by_state.<year>.json).Axiom
axiom: us:statutes/26/163/h/4/B encoded-correct
main(fa888658),interest_is_qualified_passenger_vehicle_loan_interest(Payment) conjoinsindebtedness_incurred_by_taxpayer_after_statutory_start_datewith the other conditions.us/statutes/26/163/h/4/C.yamlapplies the $10,000 limit to the per-return amount (TaxUnit).axiom-encode teston the pinned engine (89571cc2):not_holds(8 of 8 cases pass inB.test.yaml);C.test.yaml).pe-parity).🤖 Generated with Claude Code