Repository navigation
Net the premium tax credit and leave out unreported payroll tax in Oregon's federal tax subtraction - #10093
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…raction-worksheet
…ndable credits only ORS 316.680(1)(b) and 316.685; Publication OR-17 federal tax worksheet, Part A (2017-2025). The worksheet starts from Form 1040 line 22 plus the other income taxes on Schedule 2, lines 8, 16 and 17, and subtracts only the American Opportunity credit, the premium tax credit, and in 2020-2021 the recovery rebate credit and (2021) the refundable child tax and child care credits. Main used income_tax + eitc, so it subtracted the additional child tax credit in every year, never subtracted the premium tax credit, and kept the net investment income tax. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bounds, independence from the EITC (and the ACTC outside 2021), and 1-Lipschitz responses to listed credits and federal tax, checked with Hypothesis on batches of twin tax units in one simulation per example. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Picking this up for the US hub. I'll post a hand-off comment here when it's ready. Generated by Claude Code |
Bring the branch up to date with main before review; the merge was clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6Fmi4DmuA9GyXnRKdV
|
Picking this up for the US hub, continuing an earlier session's work on this PR (that session pushed nothing). I'll post a hand-off comment here when it's ready. Generated by Claude Code |
|
Ready for hub review Head: This continues an earlier session that pushed nothing to this PR. The four commits from 2026-10-11 are kept unchanged; this session added only a merge of Blocker: primary sources not re-readThis session's network policy refused Items
Hand computations (all under the cap)
Tests run (merged head)
Mutants (each in its own process, code restored after)
CIDraft, so Pull request CI skips it. CI has not run at this head. Judgment calls
Proposed follow-up
Generated by Claude Code |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10093 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 1 1
Lines 37 21 -16
=========================================
- Hits 37 21 -16
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:
|
|
Hub review in progress Reviewing head
Generated by Claude Code |
|
Ready for hub review The head hasn't moved past The formula follows the federal tax worksheet, Part A, as the hub read it for 2017 to 2025, and every hand value I computed matches. Three things block it: CI is red, two statements in the body are false, and the worksheet-over-statute choices aren't recorded as source conflicts. P11. CI fails: three Oregon kicker integration cases break because the subtraction now nets out the imputed premium tax credit
The Pull request run at this head concluded The hand-off's line "Draft, so Pull request CI skips it" no longer holds: the PR isn't a draft, and CI has run. Failure scenario: a single filer aged 35 with $50,000 of wages and no other inputs. The same household through
The behavior is what the PR intends, but the PR left the integration expectations stale. These cases test the kicker, so the least invasive fix keeps them on their purpose. Add one line under tax_units:
tax_unit:
members: [person1]
takes_up_aca_if_eligible: false
or_tax_before_credits_in_prior_year: ... # unchangedWith that change the file passes 9/9 at this head. I ran it on a scratch copy and pushed nothing. Alternatively, keep take-up on and recompute the expected values with the credit netted out. Either way the hub should expect household-API results for Oregon filers without employer coverage to move by up to the full credit. P22. The body's net investment income tax sentence is false for every filing status except singleThe body says: "The net investment income tax rarely matters, because the cap reaches zero ($145,000 single, $290,000 joint) at or below the tax's $200,000 and $250,000 thresholds." The cap stays positive above the NIIT threshold for head-of-household filers ($200,000 to $290,000), joint and surviving-spouse filers ($250,000 to $290,000) and separate filers ($125,000 to $145,000). I read the 2025 cap parameters, and they match the hub's reading of Table 9. It binds whenever nonrefundable credits wipe out the regular tax, because those credits are capped at
Without such credits, federal tax at these incomes exceeds the cap. A head-of-household filer with $210,000 of gains and no solar gets the full $8,500 cap either way. So the exclusion changes the result only for filers whose credits leave less tax than the cap. Replacement text for the body:
3. The body's plan for #10038 doesn't work: the two PRs disagree on the section 1341 creditBody, "Overlap": "that test moves its input to #10038 adds I trial-merged Then I aborted the merge and confirmed The lines the two PRs share in
Both PRs also append to The register's candidate Replacement text for the body's Overlap paragraph:
4. The worksheet-over-statute choices aren't recorded as source conflictsThe hub read the statute this way:
This PR follows the worksheet instead in two places:
CLAUDE.md says to record every such choice. The PR adds no entry to Fix: step 1 of CONTRIBUTING.md#source-conflicts. Extend P35. The formula comment overstates the worksheet's other-taxes line
Replacement: # Federal tax worksheet, Part A: federal tax after nonrefundable
# credits plus the other income taxes the worksheet lists for the year
# (from 2021, Schedule 2, lines 8, 16 and 17, and some line 10
# homebuyer repayments). Every year leaves out the net investment
# income tax and the Social Security and Medicare tax on unreported
# tips and wages (ORS 316.685(3)).6. Reference titles break the repo's page convention
I couldn't open any OR-17 PDF, so I haven't checked the page numbers themselves. 7. The Hypothesis file kills none of the four mutants
So dropping the premium tax credit, the NIIT netting, The file takes 47 s of wall time here, including model build, for 3 tests. The hand-off reports no time or memory as CLAUDE.md asks; it runs in the Python "Rest" shards. Follow-ups (identical on main, not this PR's defects)
Checked and sound
What I couldn't check
Generated by Claude Code |
These cases test the kicker and assume Oregon subtracts the whole federal liability. The model gives this household (no coverage inputs) a 3,264 (2024) or 3,736 (2025) premium tax credit, which the OR-17 worksheet now nets out of the subtraction, so the kicker cases broke. Setting aca_ptc to 0, as the file's elderly case already does, keeps them testing what their comments compute. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6Fmi4DmuA9GyXnRKdV
- Record the worksheet's NIIT exclusion and its unlisted refundable credits as source-conflict candidates, and list this PR on the claim-of-right item. - Reword the formula comment: the other-taxes line differs by year. - Drop single-page numbers from reference titles and open the 2020 href on the first cited page. - Tighten the Hypothesis properties: bound by T less the NIIT and unreported payroll tax and by the cap at the unit's AGI, and require a listed credit to lower an uncapped subtraction dollar for dollar. Dropping the premium tax credit, the NIIT netting, or the 2021 child tax or child care credit now fails it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6Fmi4DmuA9GyXnRKdV
|
Picking this up for the US hub. I'll post a hand-off comment here when it's ready. Generated by Claude Code |
Bring the branch up to date before the round 1 fixes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…axes ORS 316.685(1)(b) leaves out only the earned income credit, so every other federal refundable credit reduces the subtraction, and so does the premium tax credit. Read the federal refundable list without the EITC, plus assigned_aca_ptc, instead of the worksheet's closed per-year list. This restores the additional child tax credit outside 2021 and the refundable payroll tax credit, and a credit added to the federal list later reduces the subtraction with no Oregon change. Keep the net investment income tax in the base: 26 U.S.C. 1411(a)(1) imposes it under Subtitle A, and ORS 316.685(3) excludes only payroll and self-employment taxes. Keep the employee payroll tax on unreported tips and wages out, per 316.685(3)(a). Move cases 12, 14, 16 and 17 to the new rules, and add a refundable payroll tax credit case, an additional child tax credit family with an early-distribution tax, and a head-of-household witness that owes the net investment income tax after clean energy credits wipe out its regular tax. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The net investment income tax and refundable credits the OR-17 worksheet does not list are ruled for ORS 316.685, and the code now follows it. The claim-of-right item was ruled for the statute on 2026-10-20; its note said otherwise. Drop the deleted refundable_credits.yaml from the code paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bound the subtraction by the AGI cap and by federal tax before refundable credits less the unreported payroll tax, check that the EITC and the net investment income tax (with T fixed) never move it, and check that the premium tax credit, the additional child tax credit, the refundable payroll tax credit, the unreported payroll tax and, in 2021, the child care credit lower it by exactly min(d, slack) below the cap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Ready for hub review Round 1 fixes, built on Commits
Items
None survived. The 2020 Hypothesis run passes a, c and d because its four derandomized examples happen to sit where the cap binds. The run is live: it kills b and e, and a direct 2020 probe gives the expected 7,050 cap. The YAML cases cover those mutants in every year. Tests at the head
CIPull request run at
The hub should read the final conclusion at that URL. I didn't push again. Judgment calls
Proposed follow-up
|
|
Hub review in progress Reviewing head
Generated by Claude Code |
Once #10093 nets the premium tax credit in Oregon's subtraction, this household's modeled credit would zero the subtraction. Pinning it keeps the case isolating the section 1341 credit at 471.50. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JfLQkf8A2aNSw51a4
|
Ready for hub review The head hasn't moved past The round 1 fixes work at baseline. CI is green, every hand value I computed matches, and the readings PolicyEngine took are coded as stated. One problem blocks the PR. Main reaches refundable credits through P11. Refundable credits that reforms add through
|
middle_class_tax_credit |
income_tax |
Subtraction | or_income_tax |
|
|---|---|---|---|---|
main 25c4253483 |
1,718.13 | 2,153.37 | 2,153.37 | 3,014.64 |
| this head | 1,718.13 | 2,153.37 | 3,871.50 | 2,879.13 |
| this head with the fix below | 1,718.13 | 2,153.37 | 2,153.37 | 3,014.64 |
At baseline, all three give a subtraction of 3,871.50 and Oregon tax of 2,879.13.
No test catches this, because every YAML case and every Hypothesis property runs at baseline.
Replace lines 52-56 with the following, which reads the federal total and backs out the EITC:
# Read income_tax_refundable_credits, not the list, so credits that
# structural reforms add to that variable count too.
refundable = parameters(period).gov.irs.credits.refundable
eitc = tax_unit("eitc", period) if "eitc" in refundable else 0
refundable_credits = (
tax_unit("income_tax_refundable_credits", period)
- eitc
+ tax_unit("assigned_aca_ptc", period)
)I applied this on a scratch copy and ran it, then restored the code (git status clean):
or_federal_tax_liability_subtraction.yaml: 20 passed;- the witness: 2,153.37, matching main.
The "eitc" in refundable guard keeps a reform that drops the EITC from the list from subtracting it twice. A reform that neutralizes eitc (the End Child Poverty Act does) gives 0 either way.
Add one YAML case under a reform so this can't regress. A contrib test with the LIFT credit's in_effect set to true and the household above would do it: subtraction 2,153.37.
The body's sentence "A credit later added to the federal list reduces the subtraction with no Oregon change" holds only for the list. With the fix, it can read: "A refundable credit later added to the federal list, or by a reform to income_tax_refundable_credits, reduces the subtraction with no Oregon change."
P2
2. The PR title states the reading this round reversed
Title: "Reduce Oregon's federal tax subtraction by the OR-17 worksheet's refundable credits only". The code now subtracts every federal refundable credit except the EITC, plus the premium tax credit, and the body and the changelog fragment say so. A squash merge would land this title on main as the commit subject. Replacement:
Net the premium tax credit and leave out unreported payroll tax in Oregon's federal tax subtraction
P3
3. The Hypothesis properties seldom reach a positive, uncapped subtraction, so the dollar-for-dollar check is mostly 0 = 0
policyengine_us/tests/core/test_or_federal_tax_liability_subtraction_invariants.py:67-70
Property 3's exact check, r[name] == base - min(delta, base), only tests something when 0 < base < cap. I printed uncapped and base for every unit the derandomized run draws (a scratch copy with one print added):
| Year | Uncapped, base > 0 | Uncapped, base = 0 | Capped |
|---|---|---|---|
| 2020 | 4 | 18 | 2 |
| 2021 | 0 | 21 | 3 |
| 2025 | 4 | 19 | 1 |
Hypothesis draws small values first, and with seven credits of up to 3,000 against T from 0, most units floor at zero. That's why mutants (a), (c) and my (f) below pass the 2020 run. The hand-off says the 2020 examples "happen to sit where the cap binds". They don't: they sit at the zero floor.
Replacement (lines 67 and 70):
"income_tax_before_refundable_credits": draw(st.integers(3_000, 20_000)),
...
**{credit: draw(st.integers(0, 1_000)) for credit in CREDITS},On a scratch copy with these two lines:
- the file passes 3/3;
- uncapped units with a positive base rise to 16 (2020), 17 (2021) and 17 (2025) of 24;
- mutant (a) now fails all three years, where the file at head misses it in 2020.
4. Case 12's name claims the EITC doesn't reduce the subtraction, but the case can't tell
or_federal_tax_liability_subtraction.yaml:137-151. The expected value is max(0, 1,000 − 3,000) = 0. If the EITC were counted, the result would still be 0, so the case can't show the EITC is left out (mutant (d) is killed by cases 2 and 19, not 12). Set refundable_ctc: 600 and expect 400:
- here: max(0, 1,000 − 600) = 400;
- with the EITC counted: max(0, 1,000 − 600 − 500) = 0;
- under the old closed list: 1,000.
That is a hand computation; I didn't run this edit.
5. The net investment income tax register item doesn't list the source its reading rests on
source_conflicts/candidates.yaml, us-or:federal-tax-subtraction-niit. readings.statute rests on 26 U.S.C. 1411(a)(1), but sources lists only ORS 316.680/316.685 and the OR-17 worksheet. Add:
- kind: statute
citation: 26 U.S.C. 1411(a)(1)
url: https://www.law.cornell.edu/uscode/text/26/1411#a_16. Merging with #10038 conflicts in three files, and keeping this side everywhere drops #10038's case
The body says "whichever lands second keeps this formula". That holds for the .py. But git merge-tree 088177c9fc pr-10038 reports content conflicts in all three shared files:
or_federal_tax_liability_subtraction.py;or_federal_tax_liability_subtraction.yaml, where both PRs append at the end of the file;source_conflicts/candidates.yaml, where both rewriteus-or:claim-of-right-federal-tax-subtraction. Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038 also changes that item's statute URL to the archived PDF.
A trial merge with -X ours kept no #10038 case in the YAML. Whoever lands second has to keep both sides of the YAML and merge the register item's two rewrites by hand. Worth one sentence in the body's overlap section.
Mutants
I ran each mutant in its own process on the checkout, restoring the formula after each one (git status clean after each).
| Mutant | YAML: failing cases | Hypothesis file: failing years |
|---|---|---|
(a) drop assigned_aca_ptc (hand-off) |
11, 13, 17 (3 failed, 17 passed) | 2021, 2025 (2020 passes) |
| (c) subtract the net investment income tax again (hand-off) | 14, 20 (2 failed, 18 passed) | 2021, 2025 (2020 passes) |
(f) mine: count unreported_payroll_tax again (main's treatment) |
14 (1 failed, 19 passed) | 2021, 2025 (2020 passes) |
(g) mine: also leave out refundable_payroll_tax_credit |
18 (1 failed, 19 passed) | 2020, 2021, 2025 |
The results for (a) and (c) match the hand-off's table. None survives the YAML file. A seventh mutant, the reform path in finding 1, survives every test.
Checked and sound
- CI. The Pull request run at this head (41741384278) concluded
success: 36 of 36 jobssuccess, none skipped or cancelled. This includes Contrib other-shard-1, which the hand-off left running. - The defect reproduces at main. I copied this head's YAML into a main worktree (
25c4253483): 4 failed, 16 passed.- Failing cases: 11 (4,000 vs 2,500), 13 (1,000 vs 0), 14 (5,000 vs 4,600) and 17 (3,300 vs 1,300).
- These are exactly the premium tax credit and unreported payroll tax cases. Cases 12, 16, 18, 19 and 20 pass on main, so this round's credit and net investment income tax changes restore main's behavior, as the body says.
- The formula against the readings (
:40-57):- The base is
income_tax_before_refundable_credits − unreported_payroll_tax.income_tax_before_refundable_creditsaddsincome_tax_before_credits,net_investment_income_tax,recapture_of_investment_credit,unreported_payroll_taxandqualified_retirement_penalty, less the capped nonrefundable credits. So the net investment income tax stays in and the unreported payroll tax comes out. - The credits are the list without
eitc, plusassigned_aca_ptc(=aca_ptc × takes_up_aca_if_eligible). - The result is floored at 0, then the AGI cap is applied for all five filing statuses.
- The base is
- Excess advance premium tax credit repayment.
income_tax_before_refundable_creditscarries none. Neithergov/acanorgov/irshas a variable for advance payments or their repayment (grep for "repayment", "excess…advance" and "advance…premium"). So the model has nothing for worksheet line 2 to remove. gov.irs.credits.refundableby year.- 2017–2020 and 2022–2026:
eitc,refundable_american_opportunity_credit,refundable_ctc,recovery_rebate_creditandrefundable_payroll_tax_credit. - 2021: the same plus
cdcc. - None is a credit for federal tax on special fuels, special oils or a regulated investment company. The model has no such variables, so nothing in the list contradicts OR-17's exception.
refundable_payroll_tax_creditis an input with no formula.- Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038 adds
claim_of_right_creditin every year.
- 2017–2020 and 2022–2026:
- The deleted
refundable_credits.yaml. No file at the head namesfederal_tax_liability.refundable_creditsor the file path; the only grep hits are the variable, its tests,subtractions.yamland two tests that set the subtraction as an input. Its ten references, the ORS page and nine OR-17 years, are in the variable's tuple. The 2020 href now opens page 65. Page-range comments sit above the 2020, 2021 and 2025 hrefs, and the comment gives the premium tax credit line as 7, 8 from 2025 and 11 in 2021, as the old parameter did. - Hand values, computed before reading each case's arithmetic comment:
- case 12: max(0, 1,000 − 3,000) = 0;
- case 14: 5,000 − 400 = 4,600;
- case 16: 4,000 − 2,400 − 1,000 = 600;
- case 17: 6,000 − 1,000 − 2,000 − 1,700 = 1,300;
- case 18: 3,000 − 500 = 2,500;
- case 19, 2025 joint: AGI 50,000. Tax (50,000 − 31,500) × 10% = 1,850, which the nonrefundable child tax credit uses up. The refundable credit is min(4,400 − 1,850, 2 × 1,700, 15% × 17,500 = 2,625) = 2,550. Tax before refundable credits 1,850 − 1,850 + 3,000 = 3,000; subtraction 3,000 − 2,550 = 450. The hand-off reports that mutant (d) fails this case, which needs a nonzero EITC. I didn't rerun (d);
- case 20, 2025 head of household: (230,000 − 23,625 − 64,750) × 15% = 21,243.75. The 60,000 clean energy credit caps nonrefundable credits at that amount. NIIT 3.8% × 30,000 = 1,140; the cap at 230,000 is 8,500; subtraction 1,140.
- Case 16's raised input. At 3,000 the ruling gives max(0, 3,000 − 2,400 − 1,000) = 0, a floor that hides both credits. At 4,000 the result is positive, so the case still tests the recovery rebate credit dollar for dollar, as it did before, and now the additional child tax credit too.
- The properties hold for the formula as written.
- Each unit's own cap and
max(0, T − U)boundmin(max(0, T − U − C), cap). - The formula never reads
net_investment_income_taxbeyond T, and outside 2021 it never readseitcorcdcc. - Below the cap,
max(0, x − d) = x − min(d, x). At the cap, the value can only fall. - Raising T by d raises x by d, so the capped, floored value rises by between 0 and d.
- Each unit's own cap and
- Test runs at this head, one file per process:
or_federal_tax_liability_subtraction.yaml: 20 passed;or/tax/income/integration.yaml: 9 passed (four cases pinaca_ptc: 0, as the body says);test_source_conflicts.py: 103 passed;- the Hypothesis file: 3 passed, 17.4 s inside pytest and 76 s of wall time with model build, run locally on this VM. It needs the
devextra forhypothesis. ruff format --checkandruff checkare clean on both Python files.
- The register.
- All three items read
follows: statuteandstate: ruled. - Each note says what the code does, and none names a decision number.
- The claim-of-right note's "ruled for the statute on 2026-10-20" is a date, not an id.
- No marker was added, as CONTRIBUTING step 1 requires.
- All three items read
- Body.
- The quotes of ORS 316.685(1)(b), 26 U.S.C. 1411(a)(1) and 36B(a), and OR-17's PDF page 71 prose, match the hub's text word for word.
- "Main computes
max(0, income_tax + eitc)" and "already nets out every federal refundable credit … except the EITC" are true of main at baseline. - The $751.72 example reproduces at this head: 2024 tax 4,016.00,
assigned_aca_ptc3,264.28, subtraction 751.72; main gives 4,016. In 2025 the same household gives 135.82 here and 3,871.50 on main. - The net investment income tax ranges match the thresholds and the cap's zero points.
- The
impact:andaxiom:lines are present. - The only sentence that misstates the code is the one in finding 1.
- Overlap with Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038, at its head
e1e57f8dcf.- Trial merge into this head: Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038's case computes 0 without the pin (1 failed, 21 passed). With
aca_ptc: 0undertax_unit:it computes 471.50, and the file passes 22 of 22, the moved-input variant (income_tax_before_refundable_credits: 4_000,claim_of_right_credit: 1_500→ 2,500) included. - On Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038's own head with the pin: its file passes 11 of 11. Main's formula there doesn't read
aca_ptc, and the case's other outputs (claim_of_right_credit,eitc,income_tax) don't depend on it. - So pinning it in Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038 now is safe and removes the merge-order dependence.
- No other open PR changes these files or
gov/irs/credits/refundable.yaml. I searched open PRs for the variable name,refundable.yamland "Oregon federal tax subtraction", and listed the files of Date Hawaii's EITC from 2018, confine the Act 115 refund to 2021, and use each year's military pay cap #10205, Fix Montana disability exclusion repeal, elderly credit receipt timing and occupancy tests #10331, Leave dependents' income out of Wisconsin homestead credit household income #10191, Fix CalEITC child counts for ITIN holders #10322, Apply the RI, SC, UT, VT, WV and WI rules for a filer who can be claimed as a dependent #10044 and Reduce Colorado's federal deduction addback by the state income tax already added back #10094.
- Trial merge into this head: Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038's case computes 0 without the pin (1 failed, 21 passed). With
- Scope. The six changed files include nothing under
.github/ortests/policy/baseline/partners/. - Baseline impact. The diff moves baseline outputs for Oregon tax units with
assigned_aca_ptc > 0whose federal tax sits under the cap, and for units withunreported_payroll_tax. Population checks for the hub:- Oregon units with a premium tax credit and positive federal tax, which carry the main effect: a lower subtraction and higher Oregon tax;
- units with unreported payroll tax.
The credit and net investment income tax rulings restore main's treatment, so they shouldn't move baseline.
- Against the author's brief. Items 1 to 11 are done as asked. The brief didn't mention the reform path in finding 1 or the title in finding 2.
What I couldn't check
-
Sources. From this VM the proxy refused every host I tried:
- oregonlegislature.gov and oregon.gov;
- law.cornell.edu, uscode.house.gov and govinfo.gov;
- ecfr.gov, irs.gov and web.archive.org.
So I confirmed no source myself. I relied on the hub's 2026-11-03 and 2026-11-04 reading and quote no law beyond it. In particular I couldn't check the OR-17 page numbers, the worksheet's premium tax credit line for 2017–2020 and 2022–2023, or whether any year's OR-17 has a line the federal list misses.
-
Population impact. I have no microdata here.
-
Rulespec parity. That is the hub's
axiom:line.
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 |
Bring the branch up to main before the round 3 fixes; no conflicts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JQeNTyqxk53oyZpmf
…raction Six structural reforms add a refundable credit by overriding income_tax_refundable_credits and leave gov.irs.credits.refundable alone. Reading only the list dropped those credits from the subtraction, where main nets them through income_tax. Read income_tax_refundable_credits, back out eitc when the list carries it, and add assigned_aca_ptc. Baseline values don't move; a LIFT middle-class credit case pins the reform path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JQeNTyqxk53oyZpmf
With a 3,000 additional child tax credit against 1,000 of tax, the case floored at 0 whether or not the EITC counted. A 600 credit leaves 400, which counting the 500 EITC would drive to 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JQeNTyqxk53oyZpmf
With tax from 0 and seven credits up to 3,000, most drawn units floored at zero, so the dollar-for-dollar property mostly checked 0 = 0. Draw tax from 3,000 to 20,000 and each credit up to 1,000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JQeNTyqxk53oyZpmf
The item's statute reading rests on section 1411(a)(1), which its sources did not list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JQeNTyqxk53oyZpmf
|
Ready for hub review This is the fix round from the round 2 review (comment 6632521904), built on Commits
Items
Witness at this headThis is the 2025 Oregon single filer aged 35, with $50,000 of wages and
At baseline, both give Tests at this headI ran each file in its own process, after the merge and the edits:
MutantsI ran each mutant in its own processes and restored the file with
CIThe Pull request run at this head, 41895282059, was still
The run's conclusion is still open; the hub should read it before landing. Judgment calls
Proposed follow-up
Generated by Claude Code |
PR Review: Net the premium tax credit and leave out unreported payroll tax in Oregon's federal tax subtractionSummaryThe PR changes how
floored at zero, then capped as before. At baseline, two things change:
The EITC, the additional child tax credit, the other listed refundable credits and the net investment income tax are treated exactly as on main. The new contrib case confirms that credits a reform adds through I read the law before the code:
In every year the other-taxes line covers the IRA/retirement-plan tax, recapture taxes and Schedule 2 line 17 income-tax items. It leaves out the net investment income tax (Schedule 2, line 12) and the Social Security and Medicare tax on unreported tips and wages (lines 5-7). Line 2 takes out the excess advance premium tax credit repayment. How the head compares:
There are no critical findings. Two items need changes: the CriticalNone. Should address1. The
2. The new
- name: Case 21, 2025 a refundable credit list without the EITC backs out no EITC.
period: 2025
input:
gov.irs.credits.refundable:
[refundable_american_opportunity_credit, refundable_ctc, recovery_rebate_credit, refundable_payroll_tax_credit]
state_code: OR
filing_status: SINGLE
adjusted_gross_income: 40_000
income_tax_before_refundable_credits: 3_000
eitc: 1_000
assigned_aca_ptc: 0
output:
# The EITC is not in income_tax_refundable_credits, so nothing is backed
# out: 3,000 - 0 = 3,000. Without the guard: 3,000 - (0 - 1,000) = 4,000.
or_federal_tax_liability_subtraction: 3_000This adds one distinct parameter override to the Oregon tree, so the cost is one more cached system copy in that shard. Suggestions
Verified correct
Hand checks (head formula; caps from the schedules):
A filer with refundable credits, against each year's worksheet:
Axiom line assessmentInvalid. CI statusAll 38 checks pass at the head ( Branch status
Verdict: REQUEST_CHANGES |
DTrim99
left a comment
There was a problem hiding this comment.
Requesting changes: 0 critical, 2 should (the axiom line isn't a valid form; the new "eitc" in refundable guard is unpinned). The statutory reading of ORS 316.685 and the recorded departures from OR-17 are well supported. Full report in the comment above.
|
Hub review in progress Complete. The final review is #10093 (comment) (VERDICT: APPROVE at Generated by Claude Code |
|
Ready for hub review This is a delta review of
The round 2 P1 is fixed:
CI is green: the Pull request run concluded METHODOLOGY_CHOICE stays P31. "Overlap with #10038" describes #10038's old head; its current head already pins
|
| Household | eitc |
income_tax |
Subtraction | or_income_tax |
|---|---|---|---|---|
| Joint, two children (5, 8), $40,000 wages | 5,454.30 | −620.00 | 4,834.30 | 121.13 |
| Joint, two children, $50,000 | 3,348.30 | 880.00 | 4,228.30 | 1,343.99 |
| Joint, two children, $60,000 | 1,242.30 | 2,440.00 | 3,682.30 | 2,561.61 |
In each row, the subtraction equals income_tax + eitc, under the cap. One fix keys the back-out on the total rather than the list. The other six overrides use add(tax_unit, period, p.refundable), plus their own credit, plus flat_refundable_credit for the conversion reform. Each of those carries eitc exactly when the list does, so they are unaffected.
Mutants
I ran each mutant on its own scratch worktree at the head, with one process per test file. Afterwards I removed the worktrees; git status is clean in every checkout.
| Mutant | or_federal_tax_liability_subtraction.yaml |
LIFT contrib file | Hypothesis file |
|---|---|---|---|
P1: restore 088177c9fc's list-based lines (code identical to that head, comment aside) |
20 passed | 1 failed, 5 passed: "Oregon federal tax subtraction nets the reform's refundable credit", 3,871.50 vs 2,153.37 | 3 passed |
(a) drop assigned_aca_ptc |
cases 11 (4,000 vs 2,500), 13 (1,000 vs 0), 17 (3,300 vs 1,300): 3 failed, 17 passed | 6 passed | 2020, 2021, 2025 fail |
(d) drop - eitc (count the EITC) |
cases 2 (6,000 vs 7,000), 12 (0 vs 400), 19 (0 vs 450): 3 failed, 17 passed | 6 passed | 2020, 2021, 2025 fail |
(m) mine: drop the zero floor (or_federal_income_tax = federal_tax - refundable_credits) |
case 13 (−500 vs 0): 1 failed, 19 passed | 6 passed | 2020, 2021, 2025 fail |
These match the hand-off's results for P1, (a) and (d):
- Only the new contrib case kills P1.
- Case 12 now kills (d).
- The new Hypothesis ranges kill (a) in all three years.
No YAML case or property runs under a reform except the LIFT case. So the P1 mutant survives everything else, as expected.
Checked and sound
-
CI. The Pull request run at this head (41895282059) concluded
success. All 36 jobs arecompleted/success, none skipped or cancelled, including:- Contrib other-shard-1 and other-shard-3, which the hand-off left running;
- Household API Partners;
- every Baseline and Python shard;
- PR validation.
contrib/harrisruns as one batch (Makefile:194), so the new LIFT case ran in CI. -
The formula (
or_federal_tax_liability_subtraction.py:49-61) matches the round 2 replacement exactly.income_tax_refundable_creditsisadds = "gov.irs.credits.refundable"at baseline. The list carrieseitcin every period (2013, 2021 and 2022 values).- So for every path where the list carries
eitc, the floored amount is main's minusunreported_payroll_taxandassigned_aca_ptc. Algebraically, main'sincome_tax + eitc=income_tax_before_refundable_credits − income_tax_refundable_credits + eitc. That covers baseline and six of the seven reforms that override the total. - No reform overrides
income_taxitself (grep ofpolicyengine_us/reforms). - The abolish-federal-income-tax flag zeroes
income_tax_before_refundable_creditsas well asincome_tax. So the head's subtraction is 0 there, where main's is the EITC. - The one comment above the code (lines 49-54) says what the code reads: the federal total, less the EITC when the list carries it, plus the premium tax credit. It says why: credits that structural reforms add to the total count too. Both statements are true of the code.
-
The LIFT witness, run with
Simulation(situation=..., reform=(middle_class_tax_credit, in_effect=true)):middle_class_tax_creditincome_taxSubtraction or_income_taxhead 2bffdc09421,718.13 2,153.37 2,153.37 3,014.64 main 25c42534831,718.13 2,153.37 2,153.37 3,014.64 At baseline both give 3,871.50 / 3,871.50 / 2,879.13. I computed the first three values by hand before reading the case:
- 2025 parameters read from the model: LIFT cap 3,700, single phase-out start 36,850, width 24,550.
- Credit: 3,700 − 3,700 × (50,000 − 36,850) / 24,550 = 3,700 − 1,981.87 = 1,718.13.
- Federal tax: (50,000 − 15,750) = 34,250 of taxable income; 1,192.50 + 12% × 22,325 = 3,871.50; less the credit, 2,153.37.
- The Oregon single cap at 50,000 of AGI is 8,500 (read from the parameter), so it doesn't bind.
or_income_taxcomes from the runs only. The contrib case atmiddle_class_tax_credit.yaml:111-138asserts all four values, withabsolute_error_margin: 0.01, the file's reform andin_effect: true. -
Case 12 (
or_federal_tax_liability_subtraction.yaml:137-153), computed by hand:- 1,000 − 600 = 400;
- with the EITC counted, max(0, 1,000 − 600 − 500) = 0;
- with the additional child tax credit left out, 1,000.
The case asserts 400, and its comment gives the same arithmetic.
-
The Hypothesis ranges. T is drawn from
st.integers(3_000, 20_000)(:67) and each of seven credits fromst.integers(0, 1_000)(:70).- Up to 7,000 of credits plus 1,000 of unreported payroll tax can still reach the zero floor.
- AGI from 0 to 200,000 still reaches the cap.
- So both boundaries stay reachable while most units sit between them. The kills of (a) in 2020 and of (m) in every year show the dollar-for-dollar and bound checks now bite.
- Surviving-spouse filers aren't drawn, as in round 2; the YAML cases cover that status's cap through the shared
select.
-
The NIIT source.
source_conflicts/candidates.yaml:7677-7679listskind: statute,26 U.S.C. 1411(a)(1),https://www.law.cornell.edu/uscode/text/26/1411#a_1underus-or:federal-tax-subtraction-niit, as the review gave it. -
Test runs at this head, one file per process:
File Result or_federal_tax_liability_subtraction.yaml20 passed contrib/harris/lift/middle_class_tax_credit.yaml6 passed or/tax/income/integration.yaml9 passed test_reform_combo_budget.py1 passed test_source_conflicts.py103 passed test_or_federal_tax_liability_subtraction_invariants.py3 passed: 9.7 s in pytest, 46 s of wall time with model build, on a 4 vCPU VM; peak memory not measured -
Readers.
or_federal_tax_liability_subtractionis read only throughgov/states/or/tax/income/subtractions/subtractions.yaml(into Oregon taxable income andor_income_tax). The PR changes no parameter on net, andincome_tax_refundable_creditsis read, not changed. -
Title. It is exactly "Net the premium tax credit and leave out unreported payroll tax in Oregon's federal tax subtraction".
-
Body.
- The three replacements the brief gave are present word for word.
- The third "What changes" bullet now names
income_tax_refundable_credits, "which at baseline adds thegov.irs.credits.refundablelist", lesseitcwhen the list carries it, plusassigned_aca_ptc. That is what the code does. - "Tests" lists 20 cases, the new case 12 arithmetic, the LIFT case with its four values and "6 of 6", and the new Hypothesis ranges. Each matches my runs.
- The
impact:andaxiom:lines are present and unchanged. - The only stale text is the Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038 trial-merge passage (P3 1).
-
Baseline impact. Baseline moves only through the premium tax credit and the unreported payroll tax, as in round 2. The credit total equals the list at baseline, so this round's change is neutral there. Population checks for the hub are unchanged from round 2: Oregon units with a premium tax credit and positive federal tax under the cap, and units with unreported payroll tax.
-
Scope and overlap.
- No changed file is under
.github/ortests/policy/baseline/partners/. - Open-PR searches for
or_federal_tax_liability_subtraction,middle_class_tax_credit, the Hypothesis file name and "Oregon federal tax subtraction" turned up Net the premium tax credit and leave out unreported payroll tax in Oregon's federal tax subtraction #10093, Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038 and seven others. None of Fix state taxpayer-choice bugs: NJ property tax election and NE itemized deductions #10654, Add state tax comparison outputs and caller documentation #10310, Zero a separate filer's whole standard deduction and exclude dependent care benefits from wages #10579, Index IRS parameters to the 12-months-ending-August chained CPI-U, with CBO's tax-year projections #9621, Apply the RI, SC, UT, VT, WV and WI rules for a filer who can be claimed as a dependent #10044, Limit Kansas itemized deductions to the four K.S.A. 79-32,120(a) categories at each year's shares #10095 or Reduce Colorado's federal deduction addback by the state income tax already added back #10094 touches a file this PR changes,income_tax_refundable_creditsorgov/irs/credits/refundable.yaml. Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038 is the only overlap.
- No changed file is under
-
Against the author's brief. Items 1 to 8 are done as asked, and the EDAA path was left alone as item 2 said. The hand-off reports CI as still in progress; it has since concluded
success.
What I couldn't check
- Sources. From this VM, the proxy refused every source host (HTTP 403 on CONNECT): oregonlegislature.gov, oregon.gov, law.cornell.edu, uscode.house.gov, govinfo.gov and web.archive.org. So I confirmed no statute or OR-17 text myself, and I quote none. In particular, I couldn't check whether OR-17's premium tax credit line takes Form 8962 line 24 or the net credit on line 26 when advance payments exist. The model has no advance-payment input on main; Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038 adds
net_premium_tax_creditas an input. - Population impact. I have no microdata here.
- Rulespec parity. That is the hub's
axiom:line.
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 |
The "eitc" in refundable guard had no test on its else branch: every baseline refundable credit list carries the EITC, so deleting the guard failed nothing. Case 21 overrides the list without the EITC; with the guard removed it returns 4,000 instead of 3,000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6GcUUKCP2fg997bbmc
Main already nets every listed refundable credit except the EITC, so the fragment now names just the two changes: the premium tax credit and the unreported payroll tax. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6GcUUKCP2fg997bbmc
|
Ready for hub review Head: Commits
No merge of Items
Hand computation (Case 21)The list override has no
Judgment calls
Follow-upsNone beyond the reviewer's suggestions 3 to 5, which the hub is routing. Generated by Claude Code |
DTrim99's report (issue comment 6643503950) gets these answers. Should 1: rulespec-us#2027 queues Oregon's federal tax subtraction, and the axiom line names it. Should 2: Case 21 pins the eitc guard, and the mutant that drops it returns 4,000 against the expected 3,000. Suggestions 1 and 2: ebc373c6e0 adds the CI cost sentence and the fragment wording. Suggestions 3 and 4 and the EDAA follow-up go to later PRs: the 2017-2020 caps and EDAA apply to main as well, and the register's years wait for the 2026 OR-17. The independent review's third round approved 2bffdc0942, and the commit since then adds that case and text.
…41) and North Carolina's rules that depend on it (#10038) * Add North Carolina's claim of right repayment itemized deduction G.S. 105-153.5(a)(2)d, added by S.L. 2016-5 for 2014 and later, lets North Carolina itemizers deduct repayments of income included in AGI in an earlier year under a claim of right (Form D-400 Schedule A line 8). Repayments above $3,000 are deductible in full; smaller ones are reduced by 2% of federal AGI less other miscellaneous itemized deductions, which the 2016 and 2025 NCDOR worksheets both reproduce. PE had no input for these repayments, so it adds claim_of_right_repayment (person level; only the head's and spouse's count) and moves North Carolina's uncapped itemized items into a parameter list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * From 2026 limit North Carolina's claim of right deduction to income NC taxed Review r1 (subfleet 20261009-090558-nc-itemized-review): - S.L. 2026-31 section 1.8 rewrites G.S. 105-153.5(a)(2)d for taxable years beginning on or after January 1, 2026: the repaid amount must have been included in AGI "as modified in G.S. 105-153.5 and G.S. 105-153.6" in the earlier year. New person input nc_claim_of_right_repayment_excluded_from_income (the part NC deducted when received, such as repaid Social Security) and a dated parameter apply it. - Count only the head's and spouse's other miscellaneous expenses against the pre-2018 floor; a dependent's are on the dependent's return. - The property grid now varies property taxes (so the $20,000 cap binds) and adds a 2026 grid for the excluded part. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Model the section 1341 claim of right deduction and credit; wire North Carolina's 1341(a)(5) bar and G.S. 105-266.2 payment (WIP) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep the federal claim of right deduction and credit out of state rules that exclude them (AZ, KS, WI, MO, OR, VA); property tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Document the unmodeled pre-2018 small repayment deduction; changelog fragment Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fix the federal method in the North Carolina worksheet property test to keep it at two seconds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Remove a stray empty log file Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Address review: isolate the method branches, compare to the cent, return-level prior-year inputs, California and Montana flows - The branches that fix the claim of right method start from inputs only, and the itemization branches settle the method in the parent first, so a tax liability calculated before the method is known cannot leak into them. - Ties are compared to the cent, so a one-cent difference picks the credit. - The prior-year federal decrease and NC increase are return-level inputs defined on chapter 1 and Article 4 tax. - California leaves out the federal deduction (Schedule CA Part II line 16); Montana deducts it through 2023 (Form 2 itemized line 18). - Section 67(g) is now 67(h); document the Arizona and NC coverage limits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep the simulation's claim of right method in the itemizing branches Review r2 found that with itemization branching off, tax_liability_if_not_itemizing used the parent's method when calculated first but chose its own after income_tax. The itemizing branches now take the method as an input. A branch keeps its parent's cache when an override equals the value the parent already holds, so ordinary simulations still share it. Adds the review's Texas household as an order test under both itemization settings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge main into North Carolina claim of right deduction * Merge PR 10028's branch (with main) into the section 1341 branch Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Restore conservative branch invalidation; fix the method in itemizing branches only when someone qualifies Review r3 showed that keeping a parent's cache when an override equals the parent's current value can reuse tax calculated before another input changed. Branches again drop inherited values whenever the parent knows an overridden variable. The itemizing branches add the claim of right method as an override only when some tax unit repays more than $3,000, so simulations without a qualifying repayment keep sharing the parent's cache. Adds the review's stale-parent sequence as a test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge main into the section 1341 branch Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test both NC contrib credits stacked on the claim of right payment with use tax Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge main into the section 1341 branch Resolves the add/add conflicts with #10028's squash (557b539) by keeping this branch's 26 U.S.C. 1341(a)(5) bar on the North Carolina deduction, its added NC cases and the method fixture in the NC property grid, and keeps both sides' Arizona itemized deduction cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Carry the claim of right deduction into Montana itemized deductions from 2024 From 2024 Montana Form 2 line 2 takes the federal itemized deductions (2024 instructions, Worksheet A line 1: Form 1040 line 12), which include Schedule A line 16. The miscellaneous list was empty from 2024, so a Montana itemizer lost the federal claim of right deduction. Review r5b (P3-1) found it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge main into the section 1341 branch Resolves the period_branch.py conflict with #9913 (5c51e0d) by taking main's _input_keys docstring, which no longer says whether Core's clone copies or shares the input-key set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Give every itemizing branch the simulation's claim of right method From 2026 tax_unit_itemizes opens the itemizing branch for the section 68 limitation (#10136) with only tax_unit_itemizes overridden. From policyengine-core 3.33 (#560), set_input on a branch drops the values stored after the overridden variable was first stored anywhere in the simulation, so that branch lost the inherited section 1341 method and chose its own as a filer forced to itemize. Its itemized deductions then decided itemization on a liability tie, or always with itemization branching off: CI failed two 2026 grid points, and a 2026 household with branching off came out at $4,988 instead of $4,100. get_itemization_branch builds the itemizing and non-itemizing branches for all three callers, adding the method as an input whenever someone qualifies, so they share one branch and none chooses a method. A 2026 test covers that household in every calculation order under both itemization settings; it fails before this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Drop #10028's merged changelog fragment; date period_branch's set_input note main compiled the North Carolina claim of right fragment into CHANGELOG.md when #10028 merged, so the copy left on this branch would print it again. The period_branch module docstring said set_input on a branch clears nothing, which policyengine-core 3.33 changed (review r8). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Clarify federal claim of right input documentation * Keep claim of right threshold references specific to its value * Explain Wisconsin claim of right worksheet interpretation * Carry the federal claim of right deduction into California itemized deductions * Require section 1341 eligibility for North Carolina repayment relief * Merge remote-tracking branch 'gh/main' into federal-claim-of-right-1341 * Align NC refundable claim-of-right accounting with state tax invariants * Apply statute-first claim-of-right treatment in AL MO OR WI and VA * Complete Montana repayment deductions and federal taxable income base * Preserve Alabama federal deduction credit treatment before 2021 * Document Alabama credit-list verification boundary * Correct entities in Montana repayment regression fixtures * Remove duplicate household inputs from Montana fixtures * Merge remote-tracking branch 'gh/main' into federal-claim-of-right-1341 * Fix Montana state-tax adjustment before taxable-income floor * Correct tax-unit inputs in Montana property test * Merge main into federal-claim-of-right-1341 Merge upstream main at 86d3ae6. Keep California's federal section 1341 deduction carryover and $11,000 regression alongside main's mortgage insurance premium exclusion cases. Keep Wisconsin's repayment in the itemized deduction credit base under Wis. Stat. 71.07(5)(a)6-7, while excluding federally deductible mortgage insurance premiums as introduced by upstream commit 7545b2c (#10003). Preserve both sets of references and regression cases without changing either parent's expected values. * Merge main into federal-claim-of-right-1341 Preserve the 2020 above-the-line charitable deduction and 2021 non-itemizer treatment while retaining section 1341 method-aware itemization branches. Keep the single Schedule A parameter block with the claim-of-right deduction. Add six hand-calculated 2020/2021 regressions combining charitable deductions and both section 1341 methods, including comparisons with itemization branching disabled. * Merge current main into federal-claim-of-right-1341 * Merge main into federal-claim-of-right-1341 Conflicts resolved: - Wisconsin itemized deduction credit: keep main's explicit Schedule 1 component list (#10311) and add claim_of_right_deduction to it, so the section 1341 repayment stays in the credit base as this PR intends under Wis. Stat. 71.07(5)(a)6-7. - Alabama and Wisconsin YAML tests: keep both sides' cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Montana: add the state-income-tax addback after the line 3 floor from 2025 The 2024 Form 2 Worksheet A reduces the federal deduction by the capped state-income-tax addback before line 3's zero floor. The 2025 form stops adjusting line 2 and reports the addback on Schedule I line 4, a Montana addition after the floor, as MCA 15-30-2120(1) treats the (2)(j) item alongside the other additions. A new boolean parameter is true in 2024 and false from 2025 (2026 follows the 2025 form by convention), and both mt_taxable_income_joint and mt_federal_deductions read it. Adds 2025 and 2026 YAML witnesses (the review's AGI 10,000 / itemized 20,000 household gives 4,250 in 2025), keeps the 2024 pre-floor witnesses, limits the property test to 2024, and points the misc_deductions comment at mt_taxable_income_joint, which is what reads the federal base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Alabama: apply the regulation's payment-credit list from 2015 Ala. Admin. Code r. 810-3-15-.20(1)(d)2 subtracts all credits shown as payments on the federal return, and its current text dates from a 2010 amendment, so it governs every year the parameter covers, not only 2021 on. The legacy pre-2021 list (total AOC, no section 1341 credit or net PTC) is dropped, and the 2020 case that pinned it now expects 5,000 - 1,000 - 1,500 - 1,000 - 750 = 750. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Update the four source-conflict candidates this PR resolves main's backlog still described the code before this PR: AL, MO and WI as following the worksheets and OR as unknown. The head follows the statute or regulation in all four, so set pe_us.follows to statute and state to ruled, replace the notes that said a model change was still needed, start AL's years in 2015 (the corrected credit list now applies from the parameter's first year), and cite ORS 316.685(1)(b), the EITC-only disregard the OR code follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Replace two dead Montana references The 2017 Montana Form 2 with Legal References now 404s at its original address; cite the Wayback Machine copy of 2024-01-07, whose PDF p. 6 Schedule III lines 25, 26 and 28 the reviewer confirmed. Drop the "2023 HB 109" reference: its URL mixes HB0199 and HB0109, returns 404, and what it was meant to support could not be confirmed; MCA 15-30-2120 is already cited for the deduction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Rebuild the Missouri and Oregon section 1341 witnesses from a repayment Both cases set claim_of_right_credit as an input that neither formula reads, so they only checked that income_tax passes through. They now use the federal integration case 4 household (2025, $40,000 wages, $10,000 repayment, $2,200 prior-year decrease), where the credit method wins and flows through income_tax: 2,671.50 - 2,200 = 471.50. Missouri deducts 25% x 471.50 = 117.875 and Oregon subtracts 471.50. Adding the credit back in either formula fails its case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Run the section 1341 property grid in 2020 too main's #10186 made the 2020 itemization choice compare two branches with different AGI (the 2020 above-the-line charitable deduction), and no invariant in this file ran on that path. Add 2020 to YEARS (last, so the tests that read YEARS[0] and YEARS[1] keep 2025 and 2026) and run the calculation-order test in 2020 as well. Every existing assertion is kept; all 58 tests pass. Locally the file went from 182 s to 220 s and its peak RSS from 3.2 GB to 3.5 GB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Changelog: state the Montana and Alabama scope for every filer The claim-of-right fragment described the Montana work as repayment treatment, but from 2024 every Montana filer's taxable income now starts from the federal base (all six mt_taxable_income_joint cases changed), and every Alabama AOC claimant now subtracts only the refundable part. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge remote-tracking branch 'origin/main' into federal-claim-of-right-1341 * Pin Montana's QBI add-back before the zero floor with a reachable 2026 case The old 2025 case supplied a positive QBI deduction at a binding floor, which the model can't produce before 2026. From 2026 the 199A(i) $400 minimum can exceed taxable income, so a derived household now pins the order: MCA 15-30-2101(22) and 15-30-2120(2)(i) add the deduction back to federal taxable income before Form 2's line 7 floor, giving 0, not 400. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Pin aca_ptc to 0 in Oregon's section 1341 witness Once #10093 nets the premium tax credit in Oregon's subtraction, this household's modeled credit would zero the subtraction. Pinning it keeps the case isolating the section 1341 credit at 471.50. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Drop the unreachable 2025 branches from the Montana property test YEARS is (2024,), so the Schedule 1-A draw and the year >= 2025 branches never ran; YAML cases cover 2025 and 2026. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Document mt_federal_deductions as display-only mt_taxable_income_joint computes its own deduction term from taxable_income_deductions, which also holds the QBI deduction and the Schedule 1-A deductions, so the two differ (e.g. 15,750 against 21,750 in the 2025 tip case) and the formula can't read this variable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Start the Alabama credit-list item at 2018, the first worksheet compared The code applies the regulation's list from 2015, but worksheets before 2018 went unchecked, so the item can't claim a conflict for 2015-2017. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Explain Montana's QBI add-back order from Form 2, not section 63 The comment argued from federal taxable income having no floor, which would also remove the line 3 floor the code keeps for Montana's other additions. The order follows the form: line 2 leaves the QBI deduction out, and line 3 floors line 1 minus line 2 at zero. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge main Main removed gov.household.household_refundable_credits and gov.household.household_tax_before_refundable_credits, which no formula read after it dropped the abolish-tax structural reforms. This branch had added North Carolina to both. The merge keeps the removal; this branch's North Carolina entries stay in gov.household.household_refundable_state_credits and the gov.states.household lists. Main's new North Carolina use tax case under the payroll tax repeal enters nc_income_tax, which this branch's state list no longer reads: the list now counts North Carolina tax before refundable credits. The case now enters nc_income_tax_before_refundable_credits, and its totals stay at 1,020. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge main into federal-claim-of-right-1341 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge main into federal-claim-of-right-1341 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge main into federal-claim-of-right-1341 #10094 also adds an entry to source_conflicts/candidates.yaml. Git merges the two cleanly, and the merged register keeps unique ids. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolve the overlap with the section 1341 change (#10038): - or_federal_tax_liability_subtraction.py keeps this branch's formula. The federal refundable credit list includes claim_of_right_credit, so the formula's income_tax_refundable_credits already subtracts section 1341 relief. Add main's 2023 ORS reference and a comment saying so. - The YAML test keeps this branch's cases and adds main's section 1341 case (income tax 471.50, subtraction 471.50), which passes unchanged. - candidates.yaml takes main's statute reading for us-or:claim-of-right-federal-tax-subtraction, rewrites its note to describe the merged code, and keeps this branch's two new Oregon entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- or_federal_tax_liability_subtraction.py: the comment now says the federal refundable list carries the section 1341(a)(5) credit, while relief under 1341(a)(4), an itemized deduction, already lowers income_tax_before_refundable_credits. - Case 21's override list keeps claim_of_right_credit, so the list stays the 2025 list without the EITC. - candidates.yaml: the us-or:claim-of-right-federal-tax-subtraction note dates the statute ruling and names the credit. No formula or expected value changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merging at
The body gives the 2025 impact; the 2026 estimate follows. |
What changes
Oregon lets residents subtract their federal income tax liability, capped by a schedule that falls with federal AGI (ORS 316.680(1)(b), 316.685, 316.695). Main computes the liability as
max(0, income_tax + eitc). That already nets out every federal refundable credit PolicyEngine models except the EITC, but it never nets out the premium tax credit, because PolicyEngine keeps that credit out ofincome_tax. It also counts the employee Social Security and Medicare tax on unreported tips and wages.This PR computes the liability as follows:
income_tax_before_refundable_credits: federal tax after nonrefundable credits plus the other taxes PolicyEngine adds there, including the net investment income tax.unreported_payroll_tax. ORS 316.685(3)(a) says federal income tax does not include employee Social Security and Medicare taxes, and the OR-17 worksheet leaves them out too.income_tax_refundable_credits, which at baseline adds thegov.irs.credits.refundablelist), lesseitcwhen that list carries it, plus the premium tax credit (assigned_aca_ptc, the allowed credit on Form 8962, line 24).PolicyEngine follows the statute's text here, read with the publication's own prose.
Refundable credits
The subtraction now nets every federal refundable credit except the EITC, plus the premium tax credit. ORS 316.685(1)(b) says the taxpayer "shall not take into account any amount of the earned income credit provided under section 32 of the Internal Revenue Code". It leaves out no other credit. Publication OR-17 (2025, PDF page 71) says the same: "Federal income tax credits, except for the EITC, reduce your federal tax subtraction."
26 U.S.C. 36B(a) allows the premium tax credit "as a credit against the tax imposed by this subtitle", so it reduces the subtraction like any other credit. The OR-17 worksheet's Part A lists fewer credits each year than the statute and the prose allow: outside 2021 it omits the additional child tax credit, and it never lists the refundable payroll tax credit. This PR follows the statute, so both reduce the subtraction in every year. A refundable credit that PolicyEngine later adds to the federal list, or that a reform adds through
income_tax_refundable_credits, reduces the subtraction with no Oregon change.The net investment income tax
The PR keeps the net investment income tax in the subtraction, as main does, because the statute does. 26 U.S.C. 1411(a)(1) imposes the tax "in addition to any other tax imposed by this subtitle", in Subtitle A (Income Taxes), chapter 2A. ORS 316.685(3) gives a closed list of what federal income tax does not include. It names employee payroll taxes and Self-Employment Contributions Act taxes (Subtitle A, chapter 2), not chapter 2A. The OR-17 worksheet's other-taxes line leaves the net investment income tax out.
The tax can matter only where the cap stays positive above the tax's threshold: head-of-household filers with modified AGI from $200,000 to $290,000, joint and surviving-spouse filers from $250,000 to $290,000, and separate filers from $125,000 to $145,000. Even there, it changes the subtraction only when nonrefundable credits leave less federal tax than the cap. For example, a 2025 head-of-household filer with $230,000 of long-term gains, a child aged 10, and $200,000 of solar spending has their regular tax wiped out by the clean energy credit. They subtract the $1,140 net investment income tax, inside the $8,500 cap (case 20).
Sources
reference, for example 2025: https://www.oregon.gov/dor/forms/FormsPubs/publication-or-17_101-431_2025.pdf#page=71Where it matters
The premium tax credit drives the main change: for marketplace enrollees who owe federal tax, main overstated the subtraction by the credit. Household calculations also move. PolicyEngine assigns a premium tax credit by default to a filer with no coverage inputs. For example, a single 35-year-old earning $50,000 subtracts $751.72 in 2024 (federal tax of $4,016 less a $3,264.28 credit) instead of $4,016.
The unreported payroll tax lowers the subtraction for filers who owe it.
Microsimulation impact
We estimate that this branch raises Oregon income tax by $9.7m in 2025 on the default dataset. We compared main at
097b3c7f8awith this branch's merge commit,cc9d7f989d. The current head,7a0bf46dd8, changes only comments, one test's parameter override and a register note, so the estimate holds for it.The subtraction falls by $123.0m for 19 tax units (38,494 weighted), by at most $5,920 each, and Oregon income tax rises by at most $467 per unit. Household net income falls by the same $9.7m, and no household gains. Federal income tax, the premium tax credit, federal refundable credits and
household_benefitsdon't change. The default dataset carries no unreported payroll tax, so the whole change comes from netting out the premium tax credit: main's liability,income_tax + eitc, already nets every other refundable credit except the EITC.or_federal_tax_liability_subtractionor_income_taxstate_income_taxhousehold_net_incomeincome_taxassigned_aca_ptcunreported_payroll_taxIn 2026, we estimate that this branch raises Oregon income tax by $7.3m. The subtraction falls by $83.5m for 16 tax units (29,192 weighted), by at most $5,581 each, and Oregon income tax rises by at most $488 per unit. Household net income falls by the same $7.3m, and no household gains. Federal income tax, the premium tax credit, federal refundable credits and
household_benefitsdon't change. We compared the same two commits, and the default dataset again carries no unreported payroll tax.or_federal_tax_liability_subtractionor_income_taxstate_income_taxhousehold_net_incomeincome_taxassigned_aca_ptcunreported_payroll_taxOverlap with #10038
#10038 landed first. It added
claim_of_right_credittogov.irs.credits.refundable, so this PR's formula subtracts the section 1341 credit throughincome_tax_refundable_creditswith no Oregon change. Merge commitcc9d7f989dbrings main into this branch and resolves the three files the two PRs share:or_federal_tax_liability_subtraction.pykeeps this PR's formula and adds Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038's archived 2023 ORS chapter 316 PDF toreference. In place of Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038's comment above main's formula, a comment says how both section 1341 methods reach the formula: the federal list carries the section 1341(a)(5) credit, and the section 1341(a)(4) itemized deduction already lowersincome_tax_before_refundable_credits.or_federal_tax_liability_subtraction.yamlkeeps this PR's 21 cases and adds Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038's section 1341 case unchanged as Case 22. That case pinsaca_ptc: 0, so its expected 471.50 holds under this formula: 2,671.50 − 2,200 = 471.50.source_conflicts/candidates.yamltakes Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038's statute reading forus-or:claim-of-right-federal-tax-subtractionand rewrites its note to describe the merged code.A follow-up commit,
7a0bf46dd8, tightens three notes after an independent review of the merge: the comment above names both section 1341 methods, Case 21's override list keepsclaim_of_right_credit, and the register note dates the 2026-10-20 statute ruling. No formula or expected value changed. The same review ran a differential check at the merge over 960 Oregon tax units with section 1341 repayments under both methods, in 2020, 2025 and 2026. With no premium tax credit or unreported payroll tax, the merged subtraction equals main's to the cent.Tests
or_federal_tax_liability_subtraction.yaml: 22 cases, each with its arithmetic in a comment; all 22 pass at7a0bf46dd8. The 10 existing cases setincome_tax_before_refundable_creditsinstead ofincome_tax.policyengine_us/tests/policy/contrib/harris/lift/middle_class_tax_credit.yaml: a new case under the Harris LIFT middle-class credit reform, which adds its credit throughincome_tax_refundable_creditsrather than the federal list. A 2025 Oregon single filer aged 35 with $50,000 of wages andaca_ptc: 0gets a $1,718.13 credit,income_taxof $2,153.37, a subtraction of $2,153.37 andor_income_taxof $3,014.64, as on main. The file passes 6 of 6.policyengine_us/tests/core/test_or_federal_tax_liability_subtraction_invariants.py: Hypothesis properties for 2020, 2021 and 2025. The test draws federal tax before refundable credits from 3,000 to 20,000 and each credit from 0 to 1,000. So the dollar-for-dollar check in property 3 mostly runs on units with a positive subtraction below the cap, not on units floored at zero. In CI at2bffdc0942it runs in the Rest Pythoncoregroup (shard 2, chunkcore-1), where its three cases take about 0.43 s each and the chunk peaks at 9.3 GiB of memory over 25:57.gov/states/or/tax/income/integration.yaml: the four $50,000 single-filer cases setaca_ptc: 0, as the file's elderly case does. That keeps them testing the kicker arithmetic their comments compute.Pull request run 42514224872 passed all 36 jobs at the current head,
7a0bf46dd8. Locally, the Oregon YAML file (22 of 22) and the source-conflict guard (103 of 103) pass at7a0bf46dd8. At the merge, the invariants test (3 of 3), Oregon'sintegration.yaml, #10038's section 1341 state property test and three other files that compute the subtraction (47 of 47) also pass.Invariants
With
T= federal tax before refundable credits,U= the unreported payroll tax andcap= the AGI-based limit:0 ≤ subtraction ≤ min(max(0, T − U), cap(AGI)).T. Outside 2021, neither does the child and dependent care credit.Ubydlowers the subtraction bymin(d, subtraction). In 2021 the child and dependent care credit does the same. Where the cap binds, the subtraction never rises.Tbydraises the subtraction by at mostd, and never lowers it.Source conflicts
The OR-17 worksheet conflicts with the statute on two points: it leaves out the net investment income tax, and it lists fewer refundable credits than the statute allows. PolicyEngine follows the statute on both.
source_conflicts/candidates.yamlrecords them asus-or:federal-tax-subtraction-niitandus-or:federal-tax-subtraction-unlisted-refundable-credits, alongsideus-or:claim-of-right-federal-tax-subtraction.impact: Oregon income tax +$9.7m in 2025 (19 tax units, 38,494 weighted) and +$7.3m in 2026 (16 tax units, 29,192 weighted), from netting out the premium tax credit
axiom: TheAxiomFoundation/rulespec-us#2027 queued. Oregon's federal tax subtraction composition and cap integration wait on historical source ingestion and a signed corpus re-pin.
🤖 Generated with Claude Code