Repository navigation
Fix Vermont student loan interest, Utah's at-home parent credit and Wisconsin's homestead claimant - #10104
Fix Vermont student loan interest, Utah's at-home parent credit and Wisconsin's homestead claimant#10104MaxGhenis wants to merge 14 commits into
Conversation
32 V.S.A. 5811(21)(B)(vi) (2022 Act 138, from 2022) subtracts the interest a qualified resident taxpayer paid on a qualified education loan, for AGI up to $200,000 joint or $120,000 otherwise (5811(29)(B)). Schedule IN-112 line 16 subtracts the interest paid (16a) less the amount "already deducted on federal Form 1040, Schedule 1" (16b). The model subtracted the raw interest from 2021, deducting it a second time for anyone who took the federal deduction, with no income limit; the 2021 IN-112 has no such line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 V.S.A. 5830f(b) reduces "the amount of the credit per child" by $20 for each $1,000 of AGI over $125,000; the model reduced the total once, so two young children at $150,000 got $1,500 instead of $1,000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Utah Code 59-10-1005(2) allows $100 "for each qualifying child if ... the claimant or another claimant filing a joint individual income tax return with the claimant is an at-home parent". The model multiplied the credit by the number of spouses earning $3,000 or less; the existing two-parent case asserted $400 for two children and now expects $200. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Schedule H instructions put each condition on the claimant: 18 or older;
62 or older, disabled or with earned income ("The spouse that meets this
definition must be the claimant"); and not claimed as a dependent on another
person's federal return unless 62 or older (Wis. Stat. 71.53(2)(d); Step 2a).
Spouses choose the claimant. The model tested age and earnings across the
household and never read the dependency bar. The existing cases now use
person inputs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…split The Vermont student loan subtraction, the Vermont child tax credit per-child phase-out, Utah's at-home parent credit once per return and Wisconsin's homestead claimant tests change results for households where nobody is claimed, so they now go to main in #10104; this branch keeps the base formulas there. New cases: a filer who can be claimed but is not claimed (no Wisconsin $250 exemption; still a Rhode Island relief and Vermont renter credit claimant), and a would-be claimant who meets the filing exception (South Carolina, Utah, Vermont and West Virginia dependents survive). The property test now draws claimability, actual claims and the filing exception per spouse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The subtraction list already omits the variable in 2021, but the variable itself returned a positive amount when computed for 2021. An in_effect parameter (false before 2022) makes it zero there. The Act 138 references now cite Sec. 5 (the subtraction, pages 4-5) and Sec. 13 (effective retroactively on January 1, 2022, page 15); the earlier reference named Sec. 4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@MaxGhenis — this draft contains the fix for #9996: 32 V.S.A. § 5830f(b) reduces "the amount of the credit per child", and the 2025 Vermont booklet's table reaches $0 per child at $174,001, but The draft does not link #9996 and bundles three other state fixes. Could you split the Vermont CTC change into its own PR that says "Fixes #9996", or add the link here? We will not open a parallel PR. 🤖 Posted 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 |
A maintainer asked for the per-child phase-out under 32 V.S.A. 5830f(b) as a separate PR that fixes #9996; #10644 now carries it with its own tests. This reverts 2f79c67 and drops the matching property and changelog text, so this PR holds only the Vermont student loan, Utah and Wisconsin fixes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Picking this up for the US hub, continuing an earlier session's work. I'll post a hand-off comment here when it's ready. Generated by Claude Code |
|
Ready for hub review Head: I continue an earlier session's work. That session pushed nothing here, so the starting point was the author's head, 7ae084b. What the items asked for, and how it's resolved
Fixes kept (unchanged by me)
Hand checks of the YAML cases, done from the rules as the PR states them:
Tests (this session, at the merged head)
Mutants (each in its own process, then restored)
CIThe PR is a draft, so CI skips it. The Pull request run at 99ae1e5 concluded Overlap with open PRs
Judgment calls and limits
Proposed follow-upNone. Generated by Claude Code |
|
Hub review in progress Superseded by the final review: #10104 (comment) (VERDICT: REQUEST_CHANGES at Generated by Claude Code |
|
Ready for hub review The head hasn't moved since the hand-off: All three fixes are right on the hub's reading of the sources, and each defect reproduces at main. CI is green at the head. I'm asking for changes for three reasons:
Each fix below is small, and I ran the full set on a scratch copy: the guard passes 103, the VT file 11 and the WI file 16. Sources. This VM's network policy refused every source with a proxy 403 on CONNECT: legislature.vermont.gov, taxsim.nber.org, le.utah.gov, docs.legis.wisconsin.gov, revenue.wi.gov, govinfo.gov, uscode.house.gov, ecfr.gov and web.archive.org. Every legal reading below rests on the hub's reading of 2026-11-03, quoted in the review brief. I quote nothing from memory. FindingsP2-1. Vermont's surviving-spouse limit follows the form over the statute, and the PR doesn't record the conflict
On the hub's reading, § 5811(29)(B) defines a "qualified resident taxpayer" by two limits: (i) "$120,000.00 if the individual's filing status is single, head of household, or married filing separately", and (ii) "$200,000.00 if ... married filing jointly". The definition lists those statuses and no others. Read literally, a qualifying surviving spouse never meets it and gets no subtraction at any income. Line 16c gives the surviving spouse $120,000. The two texts give different answers, the canon that definitions control favours the statute, and the PR follows the form. That's a source conflict under Failure scenario: a 2025 surviving spouse with $110,000 of federal AGI and $3,000 of interest (none deducted federally, since MAGI is above the $100,000 single end) gets a $3,000 subtraction. A literal reading of (29)(B) gives $0. I ran this case (W5) at the head: The brief asked for a - id: us-vt:student-loan-interest-surviving-spouse-limit
program: income-tax
years:
from: 2022
type: tax
question: Does a qualifying surviving spouse get Vermont's student loan interest subtraction, when 32 V.S.A. §
5811(29)(B) sets an income limit only for single, head of household, married filing separately and joint filers?
sources:
- kind: statute
citation: 32 V.S.A. § 5811(21)(B)(vi), (29)(B)
url: https://legislature.vermont.gov/statutes/section/32/151/05811
- kind: form
citation: 2025 Vermont Schedule IN-112, line 16c
url: https://taxsim.nber.org/historical_state_tax_forms/VT/2025/Income-Booklet-2025.pdf#page=23
readings:
statute: (29)(B) defines a qualified resident taxpayer by a $120,000 limit for single, head of household and
married filing separately filers and a $200,000 limit for joint filers. It names no amount for a qualifying
surviving spouse, so a surviving spouse doesn't meet the definition and gets no subtraction.
other: Line 16c applies $120,000 to "All other filers", a qualifying surviving spouse included.
example: A 2025 surviving spouse with $110,000 of federal AGI and $3,000 of student loan interest, none deducted
federally, subtracts $3,000 under line 16c and nothing under a literal reading of (29)(B).
pe_us:
follows: conflicting-source
code:
- policyengine_us/parameters/gov/states/vt/tax/income/agi/student_loan_interest/income_limit.yaml
prs:
- https://github.com/PolicyEngine/policyengine-us/pull/10104
state: open
note: The PR keeps the form's $120,000 until the hub rules. Code not yet on main.Step 1 also asks for the YAML case that pins the reading: that's the surviving-spouse case in P2-2. I checked the item with The federal offset is not a second conflict. (21)(B)'s "to the extent such income is included in federal adjusted gross income" qualifies "items of income". Interest paid isn't an item of income, so that clause has nothing to act on and doesn't produce the offset. Read alone, (vi) subtracts "the amount of interest paid". But P2-2. Four mutants survive: Vermont's
|
| Mutant | Changed YAML file | Property test | Result |
|---|---|---|---|
| VT: subtract the whole interest | 3 of 7 fail | fails | killed |
| VT: no income limit | 2 of 7 fail | fails | killed |
| UT: one credit per qualifying spouse | 2 of 5 fail | fails | killed |
| WI: no dependency bar | 4 of 15 fail | passes | killed |
| WI: any household member's earnings | 2 of 15 fail | passes | killed |
| WI: earnings summed across both spouses (hub) | 2 of 15 fail | passes | killed by the two "only the claimed spouse has earned income" cases |
VT: < instead of <= (hub) |
7 of 7 pass | passes | survives |
VT: SURVIVING_SPOUSE $200,000 (hub) |
7 of 7 pass | passes | survives |
| WI: 18-or-older tested across the couple, not the claimant (mine) | 15 of 15 pass | passes | survives |
| VT: dependents' interest counted (mine) | 7 of 7 pass | passes | survives |
The command per mutant was uv run python -m policyengine_core.scripts.policyengine_command test <changed yaml> -c policyengine_us, then uv run pytest -q -p no:cacheprovider policyengine_us/tests/core/test_vt_ut_wi_statutory_invariants.py -k <state>.
Failure scenarios that no test catches:
<: a single filer at exactly $120,000 of AGI loses the subtraction, against "equal to or less than".- $200,000: a surviving spouse at $150,000 keeps it.
- Age across the couple: an 18-year-old with no earnings, married to a 17-year-old earner, counts as eligible. Main gives this couple eligible (W8 below), so this PR fixes it, but nothing pins the fix.
- Dependents' interest: a dependent's interest flows into the parent's subtraction.
The property test can't catch the first two. It hard-codes the limit as np.where(joint, 200_000, 120_000), never draws a surviving spouse, and with integer wage draws and max_examples=3 it doesn't land on exactly $120,000.
Add these four cases at the end of policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_student_loan_interest_subtraction.yaml:
- name: 2025 single filer at exactly $120,000 of adjusted gross income keeps the Vermont student loan interest subtraction
period: 2025
input:
people:
filer:
age: 30
employment_income: 120_000
student_loan_interest: 3_000
tax_units:
tax_unit:
members: [filer]
households:
household:
members: [filer]
state_code: VT
output:
# 32 V.S.A. 5811(29)(B)(i): AGI "equal to or less than" $120,000. The
# federal deduction is fully phased out above $100,000 of MAGI, so 16a $3,000
# - 16b $0 = $3,000.
adjusted_gross_income: 120_000
student_loan_interest_ald: 0
vt_student_loan_interest_subtraction: 3_000
- name: 2022 joint return at exactly $200,000 of adjusted gross income keeps the Vermont student loan interest subtraction
period: 2022
input:
people:
head:
age: 30
employment_income: 200_000
student_loan_interest: 3_000
spouse:
age: 30
is_tax_unit_spouse: true
tax_units:
tax_unit:
members: [head, spouse]
filing_status: JOINT
households:
household:
members: [head, spouse]
state_code: VT
output:
# 5811(29)(B)(ii): AGI "equal to or less than" $200,000 if married filing
# jointly. The 2022 federal deduction ends at $175,000 of joint MAGI.
adjusted_gross_income: 200_000
student_loan_interest_ald: [0, 0]
vt_student_loan_interest_subtraction: 3_000
- name: 2025 surviving spouse with $150,000 of adjusted gross income gets no Vermont student loan interest subtraction
period: 2025
input:
people:
head:
age: 40
employment_income: 150_000
student_loan_interest: 3_000
child:
age: 10
tax_units:
tax_unit:
members: [head, child]
filing_status: SURVIVING_SPOUSE
households:
household:
members: [head, child]
state_code: VT
output:
# Schedule IN-112 line 16c: "All other filers, if AGI is greater than
# $120,000, enter -0-." 5811(29)(B) names no amount for this status.
vt_student_loan_interest_subtraction: 0
- name: 2025 interest paid by a dependent is not part of the filer's Vermont student loan interest subtraction
period: 2025
input:
people:
head:
age: 50
employment_income: 60_000
student:
age: 22
is_full_time_student: true
is_tax_unit_dependent: true
student_loan_interest: 1_000
tax_units:
tax_unit:
members: [head, student]
households:
household:
members: [head, student]
state_code: VT
output:
# 5811(21)(B)(vi): interest "paid by a qualified resident taxpayer"; the
# dependent is not the taxpayer on this return.
student_loan_interest_ald: [0, 0]
vt_student_loan_interest_subtraction: 0Add this case at the end of policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_homestead_eligible.yaml:
- name: "2025 joint return where the only earner is 17 and the 18-year-old spouse has no earned income: no Wisconsin homestead claimant"
period: 2025
input:
people:
head:
age: 18
spouse:
age: 17
employment_income: 5_000
is_tax_unit_spouse: true
tax_units:
tax_unit:
members: [head, spouse]
filing_status: JOINT
wi_homestead_income: 9_000
households:
household:
members: [head, spouse]
state_code: WI
output:
# Wis. Stat. 71.53(2)(c) bars a claimant under 18, and 71.54(1)(gm) bars a
# claimant under 62 who is not disabled and has no earned income. Neither
# spouse meets both alone.
wi_homestead_eligible: falseAll five pass at the head: 4 passed (VT) and 1 passed (WI). They kill the four survivors:
<: 2 of 4 VT cases fail ([0.] differs from 3000.0at 2025 and 2022).- $200,000: 1 of 4 fails (
[3000.] differs from 0.0). - Dependents' interest: 1 of 4 fails (
[1000.] differs from 0.0). - Age across the couple: the WI case fails (
[1.] differs from 0.0).
Merged into the files, VT passes 11 and WI 16.
P2-3. A code comment misstates § 5811(29)(B)
policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/vt_student_loan_interest_subtraction.py:35-36 says AGI is "at most $200,000 if married filing jointly and $120,000 otherwise". The statute gives $120,000 only to single, head of household and married filing separately filers. "Otherwise" hides the surviving-spouse gap that P2-1 records. Replace the two lines with:
# 5811(29)(B): a qualified resident taxpayer's adjusted gross income is
# at most $120,000 if single, head of household or married filing
# separately, and $200,000 if married filing jointly. It names no
# amount for a qualifying surviving spouse; income_limit.yaml applies
# IN-112 line 16c's $120,000 for "All other filers".This wording avoids the guard's conflict phrases, so KNOWN_UNMARKED doesn't change. With it in place, test_source_conflicts.py passes 103 and ruff format --check reports the file already formatted.
P2-4. The body states several rules the sources don't support
Each item gives the text to replace and its replacement.
- VT row, "Rule now": "when AGI is at most $200,000 (joint) or $120,000 (other filers)". Replace with: "when federal AGI is at most $200,000 (joint) or $120,000 (single, head of household, married filing separately). § 5811(29)(B) names no amount for a qualifying surviving spouse. The code follows IN-112 line 16c's $120,000 for "All other filers", a source conflict recorded in
source_conflicts/candidates.yamlasus-vt:student-loan-interest-surviving-spouse-limit." - VT offset. Add: "§ 5811(21)(B)(vi) subtracts "the amount of interest paid by a qualified resident taxpayer during the taxable year on a qualified education loan". Read with the no-double-deduction canon in
CONTRIBUTING.md, that is the interest left after the federal deduction, which is what IN-112 lines 16a to 16c compute ("Enter any student loan interest already deducted on federal Form 1040, Schedule 1, Line 21")." - VT effective date. The body cites "2022 Act 138, Sec. 5 (Sec. 13, p. 15, makes it effective January 1, 2022)". On the hub's reading, the § 5811 history note lists "2021, No. 138 (Adj. Sess.), §§ 5, 6, eff. Jan. 1, 2022". I couldn't open the act to check Sec. 13. Replace with: "2021, No. 138 (Adj. Sess.), §§ 5, 6, eff. Jan. 1, 2022 (the history note to § 5811)". The same applies to the
in_effect.yamlandincome_limit.yamlreference titles and the code comment at line 40. - WI row, source column. It cites only "Wis. Stat. § 71.53(2)(d)". Cite § 71.53(2)(c) ("under 18 years of age at the close of the year"), § 71.53(2)(d) (claimed as a dependent unless 62 or older), § 71.54(1)(gm) (no earned income, "For claims filed in 2018 and thereafter"), and § 71.52(1) and (1g), with links. The brief asked for a page link for each source.
- WI "Was" column. "Age and earnings were tested across the household" is incomplete. Main tested age 18+ and 62+ across head and spouse, and earnings across every tax unit member, dependents included. Replace with: "Age, disability and age 62 were tested across the head and spouse, and earned income across every member of the tax unit, dependents included. The dependency bar was never read."
- Readings, item 1. "This PR follows page 10, which matches the claimant-based conditions in Wis. Stat. § 71.53." The earned income condition sits in § 71.54(1)(gm), not § 71.53. Replace with: "This PR follows page 10 ("The spouse that meets this definition must be the claimant"). That matches the statute: § 71.53(2)(c) and (d) and § 71.54(1)(gm) each test "the claimant", § 71.52(1g) defines earned income as the claimant's own wages and net self-employment earnings, and § 71.52(1) lets a couple choose which of them is the claimant."
- Readings, item 2. It can quote the statute: § 71.53(2)(d) bars a claimant who "was claimed as a dependent for federal income tax purposes by another person", which supports
claimed_as_dependent_on_another_returnover the claimable variable. - Utah row. It can quote (2): "$100 for each qualifying child if: (a) the claimant or another claimant filing a joint individual income tax return with the claimant is an at-home parent".
- The hand-off's CI line is stale. It says CI skipped the draft. The PR is no longer a draft, and the Pull request run at this head (41722397999) concluded
success: all 38 jobs succeeded, none were skipped or cancelled.
The impact: and axiom: lines are present. I left them as they are.
P3-1. The WI reference tuple cites no statute
policyengine_us/variables/gov/states/wi/tax/income/credits/homestead/wi_homestead_eligible.py:9-14 cites the 2021 LFB paper and the Schedule H instructions. The comments at lines 23-26 cite only the instructions for the age and earned income tests. #10191's version of this file cites https://docs.legis.wisconsin.gov/statutes/statutes/71/viii/53/2/c and https://docs.legis.wisconsin.gov/statutes/statutes/71/viii/54. Carry those into the tuple, and cite "Wis. Stat. 71.53(2)(c), 71.54(1)(gm)" in the comment at lines 23-24. I couldn't reach either URL to confirm the subchapter path.
Answers to the brief's questions
- Vermont's AGI. The formula compares federal
adjusted_gross_incomewith the limit, using<=for "equal to or less than". Line 16c's test decides a subtraction that produces Vermont AGI, so reading its "AGI" as Vermont AGI would be circular. Federal AGI is the only reading that works without circularity, and (21)(B) is itself framed as a decrease of "federal adjusted gross income". I couldn't open IN-111 to confirm that line 1 is federal AGI. - Utah.
- (2) has the same wording in every version the hub read. The parameters start in 2021, so the per-return count
p.amount * count_qualifying_children * has_at_home_parentis right in every year the model covers. - The $50,000 AGI test in (2)(b) is applied through
defined_for = "ut_at_home_parent_credit_agi_eligible", on bothut_at_home_parent_credit_potentialandut_at_home_parent_credit. That variable checks federaladjusted_gross_income <= 50_000. - (1)(a)(iii) is measured by
earned_income: employment income plus net self-employment income. That's net profit, not Schedule C gross income, so a Schedule C loss can offset wages. Main has the same gap (follow-up F1).
- (2) has the same wording in every version the hub read. The parameters start in 2021, so the per-return count
- Wisconsin's earned income start.
min_age,min_elderly_age,max_incomeandearnings_sourcesall start on 2021-01-01, so the model never reaches a tax year before 2017. No follow-up. - Wisconsin's claimant choice.
tax_unit.any(filer & qualifies & (~claimed | elderly))asks whether either spouse alone meets every condition, which matches § 71.52(1). I checked both of the brief's couples:- One spouse meets every condition: eligible whichever spouse is the head. The PR's paired "claimed spouse is the head/spouse" cases cover this, and so does the property test.
- No one spouse meets them all: ineligible. W10 below, where the only earner is claimed and the other spouse has no earnings, is false at the head and true at main. W8 is false at the head and true at main.
- The overlap with Leave dependents' income out of Wisconsin homestead credit household income #10191 is covered below.
Overlap with #10191 (head a953caf419)
git merge-tree --write-tree --name-only pr-10104 pr-10191 conflicts in exactly the two files the hand-off names, wi_homestead_eligible.py and wi_homestead_eligible.yaml.
This PR's formula is a superset of #10191's. #10191's eight new eligibility cases (Cases 8 to 15, the 208 lines it appends after line 95 of the YAML) all pass on this PR's head: 8 passed.
I ran a trial merge on a scratch copy, keeping this PR's side of both files and appending #10191's Cases 8 to 15:
wi_homestead_eligible.yaml: 23 passed.wi_homestead_credit.yaml: 5 passed.wi_homestead_property_tax.yaml: 3 passed.wi_homestead_disqualified_losses.yaml: 9 passed.wi_homestead_income.yaml: 11 passed, 5 failed, all withValueError: Reported Social Security benefits must be finite and nonnegative. The same 5 fail when Leave dependents' income out of Wisconsin homestead credit household income #10191 is merged with this PR's main base (abc67b98) alone, and all 16 pass at Leave dependents' income out of Wisconsin homestead credit household income #10191's own head. So the failures come from Leave dependents' income out of Wisconsin homestead credit household income #10191 meeting current main, not from this PR. Leave dependents' income out of Wisconsin homestead credit household income #10191 needs that fixed before it lands, whatever the order.
Simpler order: this PR first. The build on #10191 may not edit either eligibility file. If this PR lands first and carries #10191's Cases 8 to 15 and its two statute URLs, #10191's merge of main resolves by taking main's side of both files whole. That needs no authored edit to either file, so it fits that build's orders.
If #10191 lands first instead, this PR's merge must keep:
- in
.py: this PR's formula whole (lines 17-39, including the dependency bar at lines 30-34), plus Leave dependents' income out of Wisconsin homestead credit household income #10191's statute URLs in the reference tuple; - in
.yaml: this PR's person-input rewrite of cases 1 to 7 (Leave dependents' income out of Wisconsin homestead credit household income #10191 keeps main's tax-unit inputs for them), this PR's eight added cases, and Leave dependents' income out of Wisconsin homestead credit household income #10191's Cases 8 to 15.
Other open work. #10044 (draft) auto-merges in ut_at_home_parent_credit_potential.py. Its UT cases each have only one spouse at $3,000 or less, so the per-return change doesn't move them. #10595 is the only other open PR the overlap search returns. It touches only Vermont 2017 taxable income files, none of this PR's.
Checked and sound
- Each defect reproduces at main (
abc67b98) and is fixed at the head. I ran witness YAMLs at both heads:- VT single, $10,000 wages, $1,000 interest:
vt_agiis 8,000 at main and 9,000 at the head. - UT, both spouses earning $3,000 or less, one newborn:
ut_at_home_parent_credit_potentialis 200 at main and 100 at the head. - WI W7, a 40-year-old with no earnings and a dependent 16-year-old earning $5,000: eligible at main, ineligible at the head.
- WI W8, an 18-year-old with no earnings and a 17-year-old earning spouse: eligible at main, ineligible at the head.
- WI W10, a claimed 30-year-old only earner with a spouse who has no earnings: eligible at main, ineligible at the head.
- A self-employed WI claimant with no wages is eligible at both heads.
earnings_sourcesincludesself_employment_income, which matches § 71.52(1g).
- VT single, $10,000 wages, $1,000 interest:
- Hand values, computed before reading the code that produces them:
- VT $4,000 interest at $50,000 wages: federal cap $2,500, so $4,000 - $2,500 = $1,500.
- VT joint at $195,000: $2,500 × (1 - 25,000/30,000) = $416.67 federal, AGI $194,583 ≤ $200,000, so $3,000 - $416.67 = $2,583.33.
- VT single at $125,000 and joint at $205,000: over the limit, so $0. 2021: $0. The § 5811 history note dates the subtraction to Jan. 1, 2022.
- UT: one at-home parent with two children gives $200, and two at-home parents give $200 as well. The rename of the old "2 eligible parents with 1 child" case to "1 eligible parent with 2 children" matches its inputs.
- WI: each case's expected value follows § 71.53(2)(c) and (d) and § 71.54(1)(gm) on the hub's reading.
- The changed test files pass at the head, one per process: VT 7, UT 5, WI 15,
test_vt_ut_wi_statutory_invariants.py3,test_source_conflicts.py103. - Cost of the new Python file. Locally, alone: 75 s wall time including import and model build, of which about 12 s is test calls (WI 9.6 s, VT 2.1 s, UT 0.6 s), and 1.5 GB peak RSS for its process. The file runs in the
coregroup of the rest-Python shards, which the Makefile records at 13.3 GB / 11:51 in CI run 38141803955. I didn't measure the file's marginal memory inside that group. The PR's CI run passed every Rest Python shard. - Properties. Each property asserts what the body claims. They're weak:
max_examples=3withderandomize=Truemakes each one a fixed sample, and the VT property hard-codes the limits (see P2-2). - Readers.
vt_student_loan_interest_subtractionis read only throughgov.states.vt.tax.income.agi.subtractions, thenvt_subtractionsandvt_agi.ut_at_home_parent_credit_potentialis read only byut_at_home_parent_credit, whichgov.states.ut.tax.income.credits.non_refundablelists.wi_homestead_eligibleis read only asdefined_forofwi_homestead_credit, which feedsgov.states.wi.tax.income.credits.refundable,retirement_income_exclusion_refundableandgov.states.household.state_property_tax_credits.- No reader gets worse. The old list item, the raw
student_loan_interest, has no other Vermont reader.
- Baseline. The diff can move baseline outputs:
- Vermont AGI and tax rise for every Vermont filer with student loan interest that was deducted federally, for filers over the limits, and for every 2021 filer with interest.
- Utah credits halve for couples where both spouses earn $3,000 or less.
- Wisconsin eligibility falls for units where only a dependent or an under-18 spouse earns.
claimed_as_dependent_on_another_returnis an input that defaults to false, so the dependency bar moves little unless the microdata sets it. - The hub's population check should report the Vermont revenue change and the Utah and Wisconsin counts.
- The CTC removal.
git diff abc67b98 pr-10104 -- '*vt_ctc*'is empty, and Phase out Vermont's child tax credit per child #10644 carries the CTC fix with its own hand-off. - Reviews. There are no reviews or inline comments to answer.
- Scope. Nothing under
.github/orpolicyengine_us/tests/policy/baseline/partners/, and a changelog fragment exists atchangelog.d/vt-ut-wi-statutory-fixes.fixed.md. - What the author's brief asked for that the PR doesn't do: cite each source with a page link (the WI statute has none, P2-4), and record the source conflict (P2-1). Everything else it asked for is done.
Proposed follow-ups (main shares these)
- F1. Utah's at-home parent test uses net earnings, not W-2 wages plus Schedule C gross income.
ut_at_home_parent_credit_earned_income_eligible_personcomparesearned_income(wages plus net self-employment income) with $3,000, while (1)(a)(iii) counts W-2 wages plus Schedule C gross income. Witness, 2025: a head with $5,000 of wages and a $3,000 Schedule C loss, plus a newborn. The person comes out eligible ([1. 0.]) at both main and this head; the statute's test gives $5,000 > $3,000. The model also doesn't test (1)(a)(i) and (ii), full-time care of and a dependency claim for the parent's own child. - F2. Wisconsin earned income includes
partnership_s_corp_income. § 71.52(1g) counts wages and "net earnings from self-employment". S corporation income isn't self-employment earnings, so an S-corp shareholder with no wages can qualify. Main has the same list. Check the list against the statute's definition.
What I couldn't check
- None of the primary sources: every host was blocked (see the top). I relied on the hub's reading for all of them.
- Act 138's Sec. 13 and its page numbers.
- IN-111 line 1, the Schedule H page numbers, and the
71/viiipath of the WI statute URLs. - IRC § 221's text: the code comment at lines 27-29 cites § 221(c) for the dependent bar on the federal deduction.
- Population impact: I had no access to the microdata.
- This file's marginal memory inside the
coreCI group.
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 |
32 V.S.A. § 5811(29)(B) sets limits only for single, head of household, married filing separately and joint filers, and the chapter names surviving spouses wherever it includes them, so a surviving spouse is not a qualified resident taxpayer. IN-112 line 16c's "All other filers" $120,000 has no gap to fill. The limit for that status becomes -inf; the conflict is recorded as the candidate us-vt:student-loan-interest-surviving-spouse-limit, and the parameter's comment is counted in KNOWN_UNMARKED until the marker lands. Also cite the effective date as the § 5811 history note gives it (2021, No. 138 (Adj. Sess.), §§ 5, 6, eff. Jan. 1, 2022) and state (29)(B)'s filing statuses exactly in the variable's comment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JwDtRRMHxwVAQMx6f
The age, earned income and earned income definition tests come from Wis. Stat. 71.53(2)(c), 71.54(1)(gm) and 71.52(1g); the reference tuple and the comment cited only the LFB paper and the Schedule H instructions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JwDtRRMHxwVAQMx6f
Adds the cases no test covered: AGI exactly at the $120,000 and $200,000
limits ("equal to or less than"), two surviving spouses who get no
subtraction under 32 V.S.A. § 5811(29)(B) (the form would give $3,000 and
$1,500), a dependent's interest, and a Wisconsin couple where neither
spouse alone is both 18 or older and an earner.
Also carries #10191's eligibility Cases 8 to 15 unchanged, so that PR's
merge of main can take main's side of the eligibility file whole, and cites
the effective date as the § 5811 history note gives it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwQq6JwDtRRMHxwVAQMx6f
The test hard-coded the limit as $200,000 joint and $120,000 otherwise and never drew a surviving spouse, so a surviving-spouse limit of $120,000 or $200,000 passed it. It now draws single, joint and surviving spouse returns and asserts a zero subtraction for every surviving spouse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JwDtRRMHxwVAQMx6f
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JwDtRRMHxwVAQMx6f
|
Ready for hub review Head: This round answers the r1 review at Ownership check. The PR's last commit (20:15Z) was inside the 6-hour window, but it is the previous round's own merge commit. That round posted its hand-off at 21:19Z, and the review was made at that head, so I treated no writer as active and picked up at 23:47Z. Judgment call. Items
None survives. The brief's own "$200,000" mutant is the same as the review's R8, so I ran it once and added O2 (no 2022 effective-date gate) as a 12th.
CICI: the Pull request run at Judgment calls
Proposed follow-ups
Generated by Claude Code |
|
Hub review in progress Superseded by the final review: #10104 (comment) Generated by Claude Code |
|
Ready for hub review The head hasn't moved since the round 2 hand-off. This is a delta review of the five commits from The round 2 changes are right on the hub's reading. A qualifying surviving spouse now gets no Vermont subtraction at any AGI, including 0 and negative AGI. The register item passes the guard. Every new case matches my hand values. The carried #10191 block is byte-identical to #10191's current head. CI is green: 36 of 36 jobs. I'm approving because no finding changes a result. Two things should still land before or with the merge:
Sources. I couldn't reach any primary source from this VM. curl got a proxy 403 on CONNECT from legislature.vermont.gov, docs.legis.wisconsin.gov, le.utah.gov, taxsim.nber.org, revenue.wi.gov, tax.vermont.gov, govinfo.gov, uscode.house.gov and ecfr.gov. A second fetch route was refused for legislature.vermont.gov as outside the session's allowed domains. Every legal statement below rests on the hub's 2026-11-03 reading, quoted in the review brief. I quote nothing from memory. FindingsP2-1. No test pins Vermont's head of household or married filing separately limit; two mutants survive
Failure scenarios:
Both scenarios give $3,000 at the head; I ran them as witnesses. Add these three cases at the end of - name: 2025 head of household at exactly $120,000 of adjusted gross income keeps the Vermont student loan interest subtraction
period: 2025
input:
people:
head:
age: 40
employment_income: 120_000
student_loan_interest: 3_000
child:
age: 10
tax_units:
tax_unit:
members: [head, child]
filing_status: HEAD_OF_HOUSEHOLD
households:
household:
members: [head, child]
state_code: VT
output:
# 5811(29)(B)(i): $120,000 if head of household. The federal deduction is
# fully phased out above $100,000 of MAGI, so 16a $3,000 - 16b $0 = $3,000.
adjusted_gross_income: 120_000
student_loan_interest_ald: [0, 0]
vt_student_loan_interest_subtraction: 3_000
- name: 2025 head of household above $120,000 of adjusted gross income gets no Vermont student loan interest subtraction
period: 2025
input:
people:
head:
age: 40
employment_income: 125_000
student_loan_interest: 3_000
child:
age: 10
tax_units:
tax_unit:
members: [head, child]
filing_status: HEAD_OF_HOUSEHOLD
households:
household:
members: [head, child]
state_code: VT
output:
# 5811(29)(B)(i): $125,000 is above the $120,000 head of household limit.
vt_student_loan_interest_subtraction: 0
- name: 2025 married filing separately at exactly $120,000 of adjusted gross income keeps the Vermont student loan interest subtraction
period: 2025
input:
people:
head:
age: 40
employment_income: 120_000
student_loan_interest: 3_000
tax_units:
tax_unit:
members: [head]
filing_status: SEPARATE
households:
household:
members: [head]
state_code: VT
output:
# 5811(29)(B)(i): $120,000 if married filing separately. No federal
# deduction, so 16a $3,000 - 16b $0 = $3,000.
adjusted_gross_income: 120_000
student_loan_interest_ald: 0
vt_student_loan_interest_subtraction: 3_000I ran the three cases alone, once at the head and once under each mutant, one process per run, on a scratch worktree:
Appended to the VT file, the cases give P2-2. The PR body: a stale CI line, and quotes it can carryThe
Every other statement in the body matches what I ran or read:
P3-1. The VT property test's 2021 branch tests nothing
The surviving-spouse draw does reach the statute's assertion:
That's enough to kill R8 and O1, but thin. No change is required. If the file changes again, drop 2021 from the property's The property also repeats the parameter's P3-2. Follow-up, not this PR's defect: § 71.54(1)(gm)'s exemption, read literally
The hub's quote has an ellipsis, and I couldn't open the statute. Before the comment's citation stands, the hub should read the full text of (gm). If the literal reading holds, it's a statute-versus-instructions conflict to record as a candidate. Main has the same formula. The checks the brief asked for
Checked and sound
What I couldn't check
Follow-ups (main shares these)
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 |
…mits No test pinned the $120,000 HEAD_OF_HOUSEHOLD or SEPARATE limit, so the round 2 review's mutants setting either to -inf, or head of household to $200,000, passed. Three 2025 cases at and above the limit now kill each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6FqQp8Bf92tRiedzTm
|
Ready for hub review Head: One commit on top of What the round 2 review asked for, and what I did
CIPull request run 41947821257 at The body's CI line still describes run 41745174793 at Judgment calls
Proposed follow-up
Generated by Claude Code |
PR Review: Fix Vermont student loan interest, Utah's at-home parent credit and Wisconsin's homestead claimantSummaryI read each provision's law first and then compared the code. All three fixes match the law:
The surviving-spouse reading for Vermont is well supported and recorded as a candidate. Four things block approval:
CI is green: 36 of 36 checks at Critical (must fix)C1. Vermont 2021 no longer subtracts
Should addressS1. No test pins the new
S2. No test pins the Wisconsin
S3. The PR follows Schedule H over the literal text of § 71.54(1)(gm) for the 62-or-older / disabled / earned income routes. That reading isn't recorded, and the comment cites (gm) alone for it. The comment says "Wis. Stat. 71.53(2)(c), 71.54(1)(gm): the claimant must be 18 or older and must be 62 or older, disabled or have earned income." The statute (§ 71.54(1)) says:
How the readings differ:
Fix:
S4. The Act 138 references name the wrong section and use a page that doesn't show the values.
Suggestions
Verified correct
Hand-checks (each matches the file):
Axiom line assessment
CI statusAll 36 checks pass at Branch status
Verdict: REQUEST_CHANGES |
DTrim99
left a comment
There was a problem hiding this comment.
Requesting changes: 1 critical (the merge with main rebuilt Vermont's 2021 subtraction list without vt_other_subtractions, which main has had since #10302; a 2021 filer's subtractions drop from $1,300 to $0; re-add it and pin a 2021 case), 4 should (the new VT student loan entry and the WI filer guard are unpinned; WI follows Schedule H's three routes over 71.54(1)(gm) without a record; the Act 138 page references are off). All three fixes otherwise match the law. Full report in the comment above.
What changes
This PR fixes three statutory errors in Vermont, Utah and Wisconsin formulas, found while applying those states' rules to a filer who can be claimed as a dependent (#10044). They change results for households where nobody is claimed, so they go to main on their own rather than waiting on that stack.
The Vermont child tax credit fix that this PR used to carry now lives in #10644 (
Fixes #9996), as a maintainer asked on 2026-10-27. Commit e553dc0 reverts it here.vt_student_loan_interest_subtraction(new);gov.states.vt.tax.income.agi.subtractions;...agi.student_loan_interest.income_limitand.in_effect(new)source_conflicts/candidates.yamlasus-vt:student-loan-interest-surviving-spouse-limit. There's no subtraction in 2021.ut_at_home_parent_credit_potentialwi_homestead_eligibleVermont's federal offset. Under § 5811(21)(B)(vi), Vermont subtracts "the amount of interest paid by a qualified resident taxpayer during the taxable year on a qualified education loan" for attendance at an eligible educational institution. Read with the no-double-deduction canon in
CONTRIBUTING.md, the subtraction covers only the interest left after the federal deduction. The filer computes that amount on IN-112 lines 16a to 16c (16b: "Enter any student loan interest already deducted on federal Form 1040, Schedule 1, Line 21").Examples (2025 unless noted)
Readings
claimed_as_dependent_on_another_return.income_limit.yamlgivesSURVIVING_SPOUSE-.inf;vt_student_loan_interest_subtractionis its only reader, and itsagi <= limittest is false for every surviving spouse. The conflict is candidateus-vt:student-loan-interest-surviving-spouse-limit(follows: statute,state: ruled); the parameter's comment is counted inKNOWN_UNMARKEDuntil the marker lands in the follow-up PR.Invariants
policyengine_us/tests/core/test_vt_ut_wi_statutory_invariants.pychecks each one over Hypothesis-drawn households:Tests
vt_student_loan_interest_subtraction.yaml: 15 passed.ut_at_home_parent_credit.yaml: 5 passed.wi_homestead_eligible.yaml: 24 passed.test_vt_ut_wi_statutory_invariants.py: 3 passed.test_source_conflicts.py: 103 passed.6f203e8ba3against the 15-case Vermont file; the other rows ran against the earlier 12-case file:<instead of<=SURVIVING_SPOUSE$200,000SURVIVING_SPOUSE$120,000 (the form's reading)HEAD_OF_HOUSEHOLD-.infSEPARATE-.infHEAD_OF_HOUSEHOLD$200,000None survives.
6f203e8ba3.Overlap with open PRs
wi_homestead_eligible, adding the per-claimant age and earned income test but not the dependency bar. This PR's formula applies the same per-claimant tests to the head and the spouse and adds the § 71.53(2)(d) dependency bar. This PR carries Leave dependents' income out of Wisconsin homestead credit household income #10191's eligibility Cases 8 to 15 (the cases it appends after line 95 ofwi_homestead_eligible.yaml), unchanged at the end of that file, and the statute URLs Leave dependents' income out of Wisconsin homestead credit household income #10191 cites. If this PR lands first, Leave dependents' income out of Wisconsin homestead credit household income #10191's merge of main can take main's side ofwi_homestead_eligible.pyandwi_homestead_eligible.yamlwhole.ut_at_home_parent_credit_potential.pyat line 22 (qualifying_child). This PR edits lines 24–38.git merge-treeof the two heads is clean.impact: the hub will measure
axiom: TheAxiomFoundation/rulespec-us#2029 queued (Vermont student loan interest; corpus re-pin and source review); TheAxiomFoundation/rulespec-us#2030 queued (Utah at-home parent credit; historical corpus ingestion and re-pin); TheAxiomFoundation/rulespec-us#2031 queued (Wisconsin homestead claimant; statutory-source verification and corpus re-pin). All await encoder approval.
https://claude.ai/code/session_01LwQq6JwDtRRMHxwVAQMx6f
Generated by Claude Code