Repository navigation
Conversation
PR Review: Fix the 2021 CTC split and surviving-spouse phaseout thresholdPR #10306 (author: MaxGhenis), head
The PR has no comments or reviews yet. It touches no partner test file. Path prefixes:
Sources read for this review (all fetched 2026-10-21):
SummaryWhat is right.
There are no critical findings and three should-address items:
There are also three suggestions: the Python test, references and comment housekeeping, and the stale PR body. Status.
Critical (must fix)None. Should addressS1. The Axiom line
|
| Case | F | P | ctc |
refundable_ctc |
non_refundable_ctc |
Old code (refundable / nonrefundable) |
|---|---|---|---|---|---|---|
| HoH $112,500, child 5 + dependent 19 | 0 | 0 | 4,100 | 3,600 | 500 | same |
| HoH $112,501, same family | 50 | 0 | 4,050 | 3,550 | 500 | 3,600 / 450 |
| Single $75,001, same family | 50 | 0 | 4,050 | 3,550 | 500 | 3,600 / 450 |
| Joint $150,001, children 5 and 10 + dependent 19 | 50 | 0 | 7,050 | 6,550 | 500 | 6,600 / 450 |
| Joint $400,001, same family | 2,600 | 50 | 4,450 | 3,950 | 500 | 4,450 / 0 |
| Joint $480,001, same family | 2,600 | 4,050 | 450 | 0 | 450 | 450 / 0 |
- How the joint rows work. The enhancement is 3,600 + 3,000 − 4,000 = 2,600. That is below the 5% × 250,000 = 12,500 cap, so F is capped at 2,600 at both $400,001 and $480,001. P is 50 × 1 = 50 at $400,001 and 50 × 81 = 4,050 at $480,001.
- The $112,500 row is the zero side of the boundary. The rows just above each threshold show the split moving by exactly $50.
S3. Iowa's 2021 add-back of non_refundable_ctc is now an obsolete workaround
- Where:
policyengine_us/variables/gov/states/ia/tax/income/including_married_filing_separately/deductions/ia_fedtax_deduction.py:29-37. In fully refundable years it setsus_tax = ustax + non_refundable_ctc. - History.
- Why it was added. Commit
758955bfab(2023-05-05, "Fix ia_fedtax_deduction formula to work around 2021 US CTC flaw") added the add-back. At the time, the federal split gave theia_integration.yamlfamilynon_refundable_ctc−4,000 andrefundable_ctc12,000. Adding back the negative amount cancelled the error. - It is no longer needed. At the merge base the same fixture already shows 0 and 8,000, so the flaw it worked around is gone.
- Why it was added. Commit
- What it does at this head. In 2021
non_refundable_ctcis now the ODC before the limit, min(ODC, line 12).income_tax_before_refundable_creditshas already netted out the ODC actually applied. Iowa adds the full amount back:- When the ODC is fully used, Iowa's deduction ignores the ODC.
- Below the ARPA thresholds this predates the PR: the old split also gave
non_refundable_ctc= ODC. - Above them, the PR moves the overstatement out of the federal split and into this line.
- Below the ARPA thresholds this predates the PR: the old split also gave
- When §26(a) limits the ODC, Iowa adds back more than was netted.
- Trace. Take the PR's own Oklahoma household and put it in Iowa: 2021, single, $90,000, a child aged 5, a dependent aged 19, and
income_tax_before_credits300. - At this head. CI confirmed
non_refundable_ctc500 andincome_tax_capped_non_refundable_credits300 for that household. Soincome_tax_before_refundable_creditsis 0 andus_tax= 0 + 500 = $500. That is more than the $300 of federal tax before any credit. - Before the PR,
non_refundable_ctcwas 0, sous_taxwas $300. - The PR body is wrong here. It says the PR preserves Iowa's calculation, but this result changes.
- Trace. Take the PR's own Oklahoma household and put it in Iowa: 2021, single, $90,000, a child aged 5, a dependent aged 19, and
- When the ODC is fully used, Iowa's deduction ignores the ODC.
- Iowa law.
- The instructions. The 2021 IA 1040 instructions (file page 40) say "Report on line 31 all federal tax withheld, estimated tax payments, and federal taxes paid in 2021". The listed add-backs are Schedule 2 taxes. Nothing on pages 40-41 adds a nonrefundable credit back.
- The formula's own premise. The formula approximates the payments as the liability: "With payments equal to the liability, the deduction is the federal income tax without the added-back taxes." The ODC reduces that liability, and the formula doesn't add it back in 2020 or 2022.
- The comment. The new comment ("Retain the existing addback ... including any nonrefundable credit for other dependents in 2021") presents the workaround as an Iowa rule without a source.
- Severity: should. It's a wrong Iowa result in 2021, but in a state deduction the PR doesn't claim to change, and most of its reach predates the PR. That matches the Fix CalEITC child counts for ITIN holders #10322 S2 precedent.
- Fix: delete the fully refundable branch (lines 30-37), so that
us_tax = ustaxin every year.- Existing fixture.
ia_integration.yamldoesn't move, because itsnon_refundable_ctcis 0. - New case. Add an Iowa 2021 case with an ODC (for example HoH, $170,000, a child aged 5 and a dependent aged 19). Assert
non_refundable_ctc500 and a headia_fedtax_deductionequal toincome_tax_before_refundable_creditsless the Schedule 2 add-backs. - If you'd rather leave Iowa outputs alone in this PR, add back only the ODC actually applied (
ctc_value − refundable_ctc, which is min(ODC, limiting tax)), reword the comment and file a follow-up issue.
- Existing fixture.
Suggestions
G1. The Python grid test
- The cost is fine.
policyengine_us/tests/test_ctc_2021_refundable_split.pyran in 1.42 s in CI (1.22 s setup). - CLAUDE.md's "Test design and CI cost" rules still apply:
- Duplicated formula.
test_other_years_preserve_partial_refundability(lines 137-155) restates the legacyrefundable_ctcformula and compares the code with itself. The existingrefundable_ctc.yamlcases already cover those years. - YAML can do this. The 2021 partition checks could be vectorized YAML cases over tax units, with
ctc_maximum,ctc_arpa_phase_outandctc_phase_outas array inputs. - Hard-coded amounts. Line 60 writes
3_600/3_000instead of readingamount.arpa. - No measurement note. The PR body doesn't give the measurement or the reason for using Python.
- Duplicated formula.
- Fix (optional): drop the other-years test or move its distinct cases to YAML. Otherwise, add a sentence to the PR body naming the failure only this grid detects, with the CI timing above.
G2. References and comment housekeeping
V/phase_out/arpa/ctc_arpa_addition.py:11still cites the current-yeari1040s8.pdf#page=4, which no longer has the Line 5 Worksheet. The PR moved its two siblings (ctc_arpa_max_addition.py,ctc_arpa_phase_out_cap.py) toirs-prior/i1040s8--2021.pdf#page=4. Do the same here.T/refundable/refundable_ctc.yaml:210-211has leftover scaffolding: "# Proposed additions to:" followed by the file's own path. Delete both lines.- Lines 213-214 list the govinfo PDF twice, differing only in
#page=. CLAUDE.md treats those as one source. Keep one href (#page=57) and say "PDF pages 57-58".
G3. The PR body is stale
- Draft language. It opens with "WIP: hub impact and parity are pending" although the PR is not a draft.
- Open items. Two items are still unchecked ("Finish validation" and "Hub").
- Stale test list. It lists 27 test files as "pending" or "interrupted". CI has since passed all of them (see CI status).
- Fix (optional): replace the validation section with the CI result, and remove the WIP line once S1 is settled.
Verified correct
- Hand-checks (8 cases, about 35 expectations). Unless noted, each is 2021, TX and wages only.
T/refundable/refundable_ctc.yaml:216, HoH $170,000, a child aged 5 and a dependent aged 19.- F. Uncapped 50 × ceil(57,500 / 1,000) = 2,900. The caps are $1,600 (the enhancement) and $4,375 (5% × 87,500), so F = 1,600.
- P = 0. The other expectations are
ctc2,500 (line 12),non_refundable_ctc500 (14a),refundable_ctc2,000 (14b) andctc_value2,500. - Old code: 2,500 refundable.
- Same file, line 252, HoH $240,001.
- F = 1,600 (uncapped 6,400). P = 50 × ceil(40,001 / 1,000) = 2,050.
- Line 12 = 2,500 − 2,050 = 450, so 14a is 450 and 14b is 0.
ctc_valueis 450.
- Same file, line 290, solar.
- Tax before credits. Taxable income is 170,000 − 18,800 = 151,200. On the 2021 HoH schedule the tax is 1,420 + 4,800 + 7,073 + 15,564 = 28,857.
- Solar credit. The potential is 26% × 150,000 = 39,000. The limit is 28,857 − 500 = 28,357, because Worksheet B is off in 2021 and the solar credit follows the ODC (Form 5695 Credit Limit Worksheet). The credit is 28,357.
income_tax= 28,857 − 500 − 28,357 − 2,000 = −2,000.- Recovery rebate. The 2021 HoH rebate is fully phased out by $120,000.
- AMT. It doesn't apply: (170,000 − 73,600) × 26% = 25,064, which is less than 28,857.
- Old code: −2,500, which is the PR body's $500 overstatement.
T/ctc.yaml:10, surviving spouse, $200,001, a child aged 5.- F. The ARPA threshold is $150,000. F is uncapped at 50 × 51 = 2,550, capped at $2,500 and $1,600, so F = 1,600.
- P. The threshold is $200,000, so P = 50.
ctcandrefundable_ctcare 1,950, andnon_refundable_ctcis 0. - Old code: P = 0 and
ctc2,000.
T/phase_out/arpa/ctc_arpa_phase_out_cap.yaml.- Joint with a $1,600 enhancement: min(12,500, 1,600) = 1,600.
- Surviving spouse with a $5,000 enhancement: min(5% × (200,000 − 150,000), 5,000) = 2,500, with thresholds 150,000 and 200,000. This matches Line 5 Worksheet line 6.
T/phase_out/ctc_phase_out_threshold.yaml.- 2017: [75,000, 110,000] (§24(b)(2)(B) and (A)).
- 2018 and 2021: [200,000, 400,000], with ARPA thresholds [150,000, 150,000] in 2021.
- 2026: [200,000, 400,000].
ok_federal_ctc.yaml:25, single, $90,000, a child aged 5, a dependent aged 19, tax $300.- F = 50 × 15 = 750 (the caps are $1,600 and $6,250). P = 0.
ctcis 3,350,refundable_ctc2,850 andnon_refundable_ctc500. Capped nonrefundable credits are min(300, 500) = 300.ctc_value= min(3,350, 300 + 2,850) = 3,150.ok_federal_ctc= 300 applied + 2,850 = 3,150 (Credit Limit Worksheet A, binding branch).
ia_integration.yaml(comments only), joint, $252,020, four children aged 11, 11, 11 and 16.- C = 12,000, the base is 8,000 and the enhancement 4,000.
- F. Uncapped 50 × 103 = 5,150, capped at 4,000. P = 0.
ctcandrefundable_ctcare 8,000, andnon_refundable_ctcis 0. That is unchanged.
- The Python grid. Its 2021 assertions are lines 12, 14a and 14b, plus
refundable + non_refundable == ctc. All 7 tests pass in CI. - Callers at the head:
- Solar limit.
residential_clean_energy_credit_credit_limitnow counts only the ODC as preceding in 2021. - Oklahoma.
ok_federal_ctcapplies the capped amount. - Missouri.
mo_federal_income_tax_deductionadds backrefundable_ctc(line 28) toincome_tax. With the ODC now on line 19, the base nets it, as the MO-1040 line 9 worksheet requires. - Alabama. The 2021 Part II of
al_federal_income_tax_deductionadds backctc − refundable_ctcand subtracts the recomputed 2020 amount. In the non-binding cases the result is unchanged. In the binding cases I traced, the line-6 zero floor absorbs the difference. - New York. The
ny_ctc_pre_2024branch pins every CTC parameter to 2017, so neither change reaches it. - Puerto Rico and eligibility.
pr_refundable_ctcandeligible_for_refundable_creditsread the corrected amounts. - Iowa is S3.
- Threshold readers. The other readers of
ctc_phase_out_thresholdare contrib reforms,taxsim.pyandpr_ctc_phase_out, which follow the corrected surviving-spouse value.
- Solar limit.
- References.
- The govinfo PDF. File pages 57-58 hold §24(h)-(i); page 57 prints "Page 80". File page 81 holds §25D(c).
- The forms.
f1040s8--2021.pdf#page=1shows line 9, andi1040s8--2021.pdf#page=4shows the Line 5 Worksheet. - Format. The multi-page govinfo href in
V/refundable/refundable_ctc.pycarries a "PDF pages 57-58" comment, as CLAUDE.md asks. The new threshold reference title ("2021 Schedule 8812, line 9") has no page text.
- Changelog.
changelog.d/ctc-2021-refundable-split.fixed.mdis a top-level fragment, andfixedis the right type. - Out of scope (pre-existing, not findings):
- Part I-C. The model gives every 2021 filer the fully refundable path. It doesn't model filers without a US principal place of abode (Part I-C), which Remove calculated variables from
input/income.py#1829 tracks on the rulespec side. - Advance payments. It doesn't model the §24(j)/§7527A advance payments. On the form, lines 14f-14i take advances from the refundable part first, but PolicyEngine models the annual entitlement, so the 14a/14b split is the right target.
- Part I-C. The model gives every 2021 filer the fully refundable path. It doesn't model filers without a US principal place of abode (Part I-C), which Remove calculated variables from
- Batch lessons:
- Source-conflict ratchet (Tie source-conflict markers to the register shared with Axiom #10287). The scanned roots are
variables,parametersandreforms.- The check. I ran
main'sCONFLICT_COMMENT_REover the comments of the six scanned files the PR touches (threshold.yaml,non_refundable_ctc.py,ctc_arpa_max_addition.py,ctc_arpa_phase_out_cap.py,refundable_ctc.pyandia_fedtax_deduction.py) at the merge base, the head andmain. Each has 0 matches. - The removed Iowa comment ("flaw in CTC refundable/nonrefundable split") doesn't match.
- The baseline list. None of these files is in
KNOWN_UNMARKED, and the PR adds no marker. - Result. The guard passes on the merged tree. The test YAML and the new Python file are outside the scan.
- The check. I ran
- NH Add New Hampshire state supplementation for 2026 #10156 (state-gated keys): not applicable. Both thresholds are filing-status breakdowns with all five keys, including
SURVIVING_SPOUSE. - Integrate modeled state unemployment insurance into income flows #9558, Document disjoint health premium inputs and correct consumer treatment #10046 and OK Add Oklahoma state supplementation for 2026 #10165: not applicable. No income-source list or wage definition changes.
- Partner tests: untouched. The Household API Partners check passed.
- Source-conflict ratchet (Tie source-conflict markers to the register shared with Axiom #10287). The scanned roots are
Axiom line assessment
Invalid: axiom: pending: hub files parity (S1).
- Recommended form:
axiom: us:statutes/26/24/h#ctc_phase_out_threshold_under_subsection_h encoded-correct; TheAxiomFoundation/rulespec-us#<n> queued. The queued issue is a new open,pe-parity-labelled, dispatch-ready issue for §24(i)(1)(B), (i)(3) and (i)(4). The required contents are listed under S1. Alternatively, cite an encoder PR asencoded. - Not
n/a. These are statutory provisions, and the PR changes 2021 refunds and 2018+ surviving-spouse credits. - Not
encoded-correctfor §24(i). rulespec-usmain(5796861e58) has no subsection (i) module. Remove calculated variables frominput/income.py#1829 covers only (i)(1)(A). encoded-correctis available for §24(h)(3), providedfiling_status == 1means a joint return only. Its tests lack a surviving-spouse case, so add one in the new issue.
CI status
27 pass, 3 skipping, 0 pending, 0 failed. I re-checked gh pr checks 10306 at the end of this review, and the head is still cffa308032.
- The green run. Run 39515880371 (
pull_request, created 2026-10-20 23:34 UTC) tested merge commitafedcfae. That merges the head into07eba1aeea, which ismainas of 2026-10-20 19:22 UTC. That is before Tie source-conflict markers to the register shared with Axiom #10287 (22:02 UTC) and Count the FL and SD LIHEAP comments in the source-conflict ratchet baseline #10334, so CI's tree did not contain the ratchet. I checked it statically instead (see Verified correct). - Where the changed tests ran.
- Quick Feedback selected and passed:
ctc.yaml(2),ctc_arpa_phase_out_cap.yaml(3),ctc_phase_out_threshold.yaml(6),refundable_ctc.yaml(18),ia_integration.yaml(9) andok_federal_ctc.yaml(6). It also passed the new Python file (7 tests in 1.42 s). - Rest (Python, shard-1 + variables) passed the Python file again.
- The full baseline, contrib, microsimulation and Household API Partners suites passed. That includes every file the PR body lists as unfinished.
- Quick Feedback selected and passed:
- The skipped checks are the umbrella jobs of run 39489870440 (2026-10-20 20:11 UTC), which the green run superseded.
- Locally: I ran no tests or model probes. CI is green at the current head. Every expectation and the S3 trace were checked by hand from the code, the parameters and CI-verified values.
Branch status
- Position: 4 commits ahead of
main(328d1721e2) and 26 behind. The merge base isf187dae556. - Merge: clean.
git merge-tree --write-tree PolicyEngine/main cffa308032exits 0 (tree4df778bf2e).- Since the merge base,
mainhas touched Iowa itemized deductions, Oklahoma LIHEAP, SSP and additions, and some itemized-deduction tests. It has touched no file in this PR and nothing under the federal CTC.
- CI base (note only). CI's base is 20 commits behind
main. Mergingmainand re-running would refresh CI on a tree that contains the ratchet guard. - Siblings (note only). No other open PR edits
refundable_ctc.py, the CTC phaseout parameters,non_refundable_ctc.py,ia_fedtax_deduction.pyorok_federal_ctc.py.
0 critical, 3 should and 3 suggestions are open at this head.
Verdict: REQUEST_CHANGES
DTrim99
left a comment
There was a problem hiding this comment.
The 2021 split now matches s.24(i)(1)(B) and (i)(4) and Schedule 8812 lines 12/14a/14b, the surviving-spouse $200k threshold matches s.24(h)(3), and other years are unchanged. Three should-address items: (1) the 'pending: hub files parity' axiom line is invalid, so please file a queued pe-parity issue for 24(i)(1)(B)/(i)(3)/(i)(4); (2) no new case sits on an ARPA threshold or covers both phase-outs plus the ODC (the report gives the values); (3) Iowa's 2021 non_refundable_ctc add-back is an obsolete workaround that now over-adds ($500 vs $300). Three suggestions. Full report in the comment above.
|
Evidence from Tax-Calculator's PE-TAXSIM validation (PSLmodels/Tax-Calculator
Of the 18 remaining units, 11 are new (PE-US 2.58.0 and Tax-Calculator agreed on a split that is wrong under the form) and 7 differed before. All 18 are heads of household with AGI $328,000–$406,099, where the §24(b) reduction exceeds the $2,000-per-child base. Tax-Calculator phases out its base CTC plus ODC before the ARPA increase ( The TAXSIM-35 test binary (cd2026081819) reports |
|
Picking this up for the US hub. I'll post a hand-off comment here when it's ready. Generated by Claude Code |
Conflict: refundable_ctc.yaml; keep both sides' cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No case sat on a 24(i)(4)(B) threshold, where the first reduction starts and the old split first went wrong, and none was a joint return with an other dependent. Add six TX wage-only households (a child aged 5, plus a child aged 10 on joint returns, and a dependent aged 19), each worked from Schedule 8812 lines 5-14b: head of household at $112,500 (no reduction) and $112,501, single at $75,001, joint at $150,001, $400,001 (first reduction capped at the $2,600 enhancement plus $50 of the ordinary phaseout) and $480,001 (line 12 = $450, all of it the ODC). Restoring the old split fails five of them. Also drop leftover scaffolding comments in refundable_ctc.yaml and cite the govinfo PDF once with its page range. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The add-back was a 2023 workaround for a federal split that gave a negative nonrefundable CTC. That flaw is gone, and with the corrected 2021 split non_refundable_ctc is the credit for other dependents, which reduces the federal liability that Iowa deducts (the formula takes payments as equal to that liability). Keeping the add-back made Iowa ignore the ODC, and add back more than was netted where section 26(a) limits it. Now the federal tax is income_tax_before_refundable_credits in every year. A 2021 head of household at $170,000 with a child and a dependent aged 19 deducts 28,357 (the add-back gave 28,857). ia_integration.yaml does not move. Also point ctc_arpa_addition at the 2021 Schedule 8812 instructions, as its two siblings already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The grid hard-coded 3,600 and 3,000; read them from amount.arpa so the reference follows the parameter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Ready for hub review Head: What changed
Hand computations (2021 Schedule 8812 lines 5-14b, Line 5 Worksheet; 26 U.S.C. 24(i)(4), (b), (h))Child amounts are $3,600 (under 6) and $3,000 (6-17), against a $2,000 base, with a $500 ODC. F is the first reduction: $50 per $1,000 or fraction above the (i)(4)(B) threshold, capped at the lesser of the enhancement and 5% of (the (h)(3) threshold − the (i)(4) threshold). P is the ordinary phaseout above $200,000 / $400,000.
These match the review's table. Iowa (2021 HoH, wages $170,000, a child aged 5 and a dependent aged 19):
Tests (local, one file per process)
CIPull request run 41730727280 at Judgment calls
Reply to DTrim99
Generated by Claude Code |
|
Hub review in progress This review is finished. The full review is in #10306 (comment). Generated by Claude Code |
|
Ready for hub review Independent review, round 2. The head is still Methodology choice: Iowa. The PR removes the 2021 add-back rather than adding back only the ODC actually applied. The two choices give different Iowa deductions. Removal deducts the federal tax after nonrefundable credits, which is what the formula already does in every other year. I couldn't read the Iowa sources to confirm it. The surviving-spouse threshold isn't a methodology choice. §24(h)(3) as quoted in the first review, and Schedule 8812 line 9, both give the $200,000 threshold. FindingsP2-1. A stale Iowa test comment says the removed add-back still exists
P2-2. The body has no
|
| Household | main |
Head |
|---|---|---|
| 2021 HoH, $112,501, child aged 5 and a dependent aged 19: refundable / nonrefundable CTC | 3,600 / 450 | 3,550 / 500 |
Same household: income_tax_before_refundable_credits |
14,607.24 | 14,557.24 |
| 2021 joint, $400,001, children aged 5 and 10 and a dependent aged 19: refundable / nonrefundable CTC | 4,450 / 0 | 3,950 / 500 |
2021 surviving spouse, $250,000, child aged 5: income_tax |
40,018 | 42,018 |
2021 HoH, $170,000, Iowa: ia_fedtax_deduction (head) |
28,857 | 28,357 |
- The 2021 split. Total federal tax moves only where the ODC or later nonrefundable credits meet the §26(a) limit. The solar case is one example.
- The surviving-spouse threshold. It applies every year from 2018, including current years. It cuts the CTC for surviving spouses with qualifying children and MAGI above $200,000.
- Iowa 2021. The deduction falls by
non_refundable_ctcfor every Iowa tax unit with an ODC, so Iowa tax rises.
The population check therefore needs:
- 2021 federal
income_taxandrefundable_ctc; - the CTC for surviving-spouse units in 2018 through 2026;
- 2021 Iowa income tax.
The impact run is the hub's job. I didn't run it.
P3-1 (follow-up, the same on main). The 2021 branch skips the §911 bar
refundable_ctc.py:34-43 returns inside if ctc.refundable.fully_refundable before it reads refundable_ctc_barred_by_section_911_exclusion. So a 2021 filer who elects the §911 exclusion still gets a fully refundable child amount.
Witness, on main at a61a874778. The inputs are ctc 3,600, ctc_refundable_maximum 3,600, both reductions 0, and refundable_ctc_barred_by_section_911_exclusion: true:
refundable_ctc@2021: [3600.] differs from 0.0
This PR didn't introduce it. Whether §24(d)(3) or Schedule 8812 Part I-C bars these filers in 2021 needs the 2021 text, which I couldn't reach from this VM. So it's a follow-up candidate, not a finding against this PR. The first review's "Part I-C" note covers the same gap.
Checked and sound
-
Should 2: the six boundary and joint cases (
refundable_ctc.yaml:364, 397, 431, 465, 510, 555).-
By hand first. I recomputed each case before reading the hand-off table:
- F = min(50 × ceil(excess over the §24(i)(4)(B) threshold / 1,000), the enhancement, 5% × (the §24(h)(3) threshold − the (i)(4) threshold)).
- P = 50 × ceil(excess over $200,000 or $400,000 / 1,000).
- Line 12 = C − F + O − P, 14b = max(C − F − P, 0), and 14a = line 12 − 14b.
Case F P ctcrefundable_ctcnon_refundable_ctcHoH $112,500 0 0 4,100 3,600 500 HoH $112,501 50 (caps 1,600 and 4,375) 0 4,050 3,550 500 Single $75,001 50 (caps 1,600 and 6,250) 0 4,050 3,550 500 Joint $150,001 50 (caps 2,600 and 12,500) 0 7,050 6,550 500 Joint $400,001 min(12,550, 2,600, 12,500) = 2,600 50 4,450 3,950 500 Joint $480,001 2,600 50 × 81 = 4,050 450 0 450 All match the YAML.
-
Roles. A per-person probe at the head, for HoH $112,500 and joint $400,001, shows:
- The dependent aged 19:
ctc_qualifying_childFalse,ctc_child_individual_maximum_arpa0,ctc_adult_individual_maximum500. So they count for the $500 ODC only. - The children aged 5 and 10: 3,600 and 3,000.
- The dependent aged 19:
-
Strength. Each case asserts F, P and all three CTC values, so none asserts a weaker claim. The +$1 cases sit on the boundary from above, and the $112,500 case is the zero side.
-
-
Should 3: Iowa (
ia_fedtax_deduction.py:31; case atia_fedtax_deduction.yaml:127).- The parameters. I printed the 2021 HoH brackets from the repo's parameters: 14,200 / 54,200 / 86,350 / 164,900 at 10 / 12 / 22 / 24%. The standard deduction is 18,800.
- Federal tax. (170,000 − 18,800) = 151,200 of taxable income. The tax is 1,420 + 4,800 + 7,073 + 0.24 × 64,850 (15,564) = 28,857.
- After the ODC: 28,857 − 500 = 28,357. The head's deduction is [28,357, 0, 0].
- Reach. The deleted branch only differed when
fully_refundableis true. That is 2021 at baseline. The two reforms that set it in later years (afa_other_dependent_credit,wyden_smith/ctc_expansion) replacerefundable_ctcwith their own. Iowa's §26(a)-limited case now follows automatically fromincome_tax_before_refundable_credits.
-
Suggestions.
- G1:
test_ctc_2021_refundable_split.py:60readsp.amount.arpa.calc(...). The other-years test is kept, with the reason in the body. It runs in 1.37 s locally (1.32 s of setup). - G2:
ctc_arpa_addition.py:11citesirs-prior/i1040s8--2021.pdf#page=4;- the "Proposed additions to:" scaffolding is gone;
refundable_ctc.yaml:210-213cites the govinfo PDF once, with "PDF pages 57-58".
- G3: the body has no WIP line, and every plan item is ticked except the hub's.
- G1:
-
The merge of
main(c5886d5946, parentscffa308032and6145ad4513).- Cases. I loaded
refundable_ctc.yamlat both parents and at the merge with PyYAML. All 18 branch-side cases and all 17main-side cases appear unchanged in the merge's 20 (the two sides share 15). - Other files.
git diff <main parent> <merge>carries exactly the changed lines ofgit diff <merge base> cffa308032, so the merge adds nothing else.
- Cases. I loaded
-
The code against the rule. In 2021,
refundable_ctc= min(max(0, C − F − P),ctc). Sincectc≥ that amount whenever C equals the child amounts, this is line 14b, andnon_refundable_ctc=ctc− R is min(O, line 12) = 14a. Other years keep the legacy branch, and the grid's five other-year tests pass. -
Defects reproduced on
main. These are the "Reproduce onmain" rows in P2-2: the old split refunds up to F of the ODC, and the surviving-spouse threshold is 400,000. -
Tests at the head, one file per process. All pass:
File Result refundable_ctc.yaml26 ctc.yaml2 ctc_arpa_phase_out_cap.yaml3 ctc_phase_out_threshold.yaml6 ia_fedtax_deduction.yaml5 ia_integration.yaml9 ok_federal_ctc.yaml6 test_ctc_2021_refundable_split.py7 test_source_conflicts.py103 -
Mutants. Each ran in its own process, and the tree was restored after each (
git statusclean, HEAD0a9022de26):Mutant Result Killed by M1 (hand-off): 2021 reduction = ctc_phase_outonly8 of 26 fail in refundable_ctc.yaml; 2 of 7 in the gridThe PR's three cases (refundable 2,500 vs 2,000; 450 vs 0; solar limit 28,857 vs 28,357) and five of the six new cases. All but $112,500, which is the intended no-change side. M2 (hand-off): restore Iowa's add-back 1 of 5 fails ia_fedtax_deduction.yaml:127(28,857 vs 28,357).ia_integration.yamlstill passes 9.M3 (mine): surviving-spouse threshold back to 400,000 5 fail ctc.yaml(1),ctc_phase_out_threshold.yaml(the 2018, 2021 and 2026 cases) and the surviving-spouse case inctc_arpa_phase_out_cap.yamlM4 (mine): use ctc_arpa_uncapped_phase_outin the split3 of 26 fail HoH $170,000 (700 vs 2,000), solar (27,057 vs 28,357) and joint $400,001 (0 vs 3,950) M5 (mine): ceil→floorinctc_arpa_uncapped_phase_out3 of 26 fail Exactly the three new +$1 cases (HoH $112,501, single $75,001, joint $150,001). No earlier case caught it. -
Readers of
refundable_ctc,non_refundable_ctc,ctcandctc_phase_out_threshold:- Federal readers:
ctc_value;residential_clean_energy_credit_credit_limit(tested);eligible_for_refundable_credits;- the
refundable.yamlandnon_refundable.yamllists.
- States:
ok_federal_ctc(tested; unchanged at 2,500 for HoH $170,000);al_federal_income_tax_deduction(12,557.24 and 77,172.32, the same onmainand the head);mo_federal_income_tax_deduction(0 on both for these incomes);md_ctc, which reads federalctconly within its low-AGI eligibility;ny_ctc_pre_2024, which pins 2017 parameters.
- Territories:
pr_refundable_ctcandpr_ctc_phase_out. - Reforms:
pa_ctc_match,crfb/non_refundable_ss_credit,edaa_end_child_poverty_act,fisc_act,american_worker_rebate_actandctc_minimum_refundable_amount;taxsimandctc_per_child_phase_out. Both redefine the ARPA reduction, which the new branch now subtracts consistently.
I found no reader that this PR makes reachable and worse.
- Federal readers:
-
Docs.
non_refundable_ctcdocumentation. It says "before the section 26(a) tax-liability limit" and "line 14a … before the limit on line 14d". Both matchctc − refundable_ctcin every year.- Reference format. The
refundable_ctc.pymulti-page href has its "PDF pages 57-58" comment, as CLAUDE.md asks. The new threshold reference has no page text in its title. - The changelog is one top-level
fixedfragment.
-
The body's claims checked:
- the T, R and N formulas;
- "five of the six new boundary cases" (M1);
- the Iowa mutant (M2);
- the test counts;
- the run time ("about 2 s"; 1.37 s here);
- the $500 solar overstatement (M1 shows 28,857 vs 28,357).
-
CI. Pull request run 41730727280 at
0a9022de26completed with success. All 36 jobs passed: baseline, contrib, Python, microsimulation, Household API Partners, PR validation and Quick Feedback. None was skipped or cancelled. The run's base is6145ad4513;mainis now 5 commits ahead, and none of those commits touches these files. -
Scope.
- Nothing under
.github/ortests/policy/baseline/partners/. - Open-PR searches for
refundable_ctc,non_refundable_ctc,ia_fedtax_deduction,threshold.yaml,ok_federal_ctcandctc_arpareturned Reduce Oregon's federal tax subtraction by the OR-17 worksheet's refundable credits only #10093, Ignore a dependent's separation when inferring the tax unit spouse (26 U.S.C. 7703) #9932, Apply New Jersey, North Dakota, Ohio, Oklahoma and Pennsylvania rules for a filer who can be claimed as a dependent #10043, Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038, Add Arkansas's claim of right deduction (Ark. Code § 26-51-457) #10203 and Add Indiana's, Massachusetts's and West Virginia's claim of right repayment deductions #10196. I listed their files, and none touches a file this PR changes. Apply New Jersey, North Dakota, Ohio, Oklahoma and Pennsylvania rules for a filer who can be claimed as a dependent #10043 editsnj_ctcand an Oklahoma EITC file only.
- Nothing under
What I couldn't check
- Primary sources. govinfo.gov, uscode.house.gov, irs.gov, revenue.iowa.gov and legis.iowa.gov all refused connections from this VM (proxy 403 and DNS denial). The statute and Schedule 8812 steps above rest on the first review's quotations of 26 U.S.C. 24(b), (h) and (i) and of the 2021 Schedule 8812 and Line 5 Worksheet, not on my own reading. I couldn't read the Iowa Code section or the 2021 IA 1040 instructions. The new Iowa comment ("the 2021 credit for other dependents … reduces the liability paid") rests only on the formula's existing payments-equal-liability premise.
- The 2021 AMT. I confirmed the HoH exemption ($73,600) from the repo's parameters. I didn't confirm the 26% rate, which only shows that AMT doesn't bind in the Iowa and solar cases. The model's run agrees.
- Parity. I didn't check whether 2021 child tax credit: refundable child portion after both phaseouts, nonrefundable other-dependent credit (26 USC 24(i)(1)(B), (i)(3), (i)(4)) (PE-US #10306) TheAxiomFoundation/rulespec-us#1856 exists, is open and is labelled
pe-parity. That repository is outside this session's access. - Population impact. I ran no microsimulation (P2-2).
Generated by Claude Code
The 2021 fully refundable CTC omitted the first ARPA reduction and could refund credit for other dependents (ODC). This corrects the Schedule 8812 split, including a solar-credit ordering case that previously overstated the federal refund by $500.
Using child-only credit
C, ODCO, the capped first ARPA reductionF, and ordinary phaseoutP:T = max(C − F + O − P, 0)(line 12).R = max(C − F − P, 0)(line 14b).N = min(O, T)(line 14a), retained before the §26(a) tax limit applied on line 14d.The first reduction retains its caps at the enhancement above $2,000 per qualifying child and 5% of the ordinary-minus-ARPA threshold difference. The partial-refundability branch and existing refundable-maximum guard are preserved. The ordinary phaseout threshold for surviving spouses is also corrected to $200,000 from 2018 onward; their separate 2021 ARPA threshold remains $150,000.
Sources: 2021 IRC §24(h) and (i), PDF pages 57–58, 2021 Schedule 8812, page 1, and Line 5 Worksheet, instructions page 4.
Implementation plan:
non_refundable_ctc(a 2023 workaround for a negative split) is removed, so Iowa deducts the federal tax after the credit for other dependents.Validation (after review, at
0a9022de26,mainmerged):refundable_ctc.yaml26,ctc.yaml2,ctc_arpa_phase_out_cap.yaml3,ctc_phase_out_threshold.yaml6,ia_fedtax_deduction.yaml5,ia_integration.yaml9,ok_federal_ctc.yaml6. All pass.test_ctc_2021_refundable_split.py7 andtest_source_conflicts.py103. Both pass. The grid is the one check that the 2021 branch leaves 2018, 2020, 2022, 2025 and 2026 unchanged across combinations of credits, reductions, caps and the section 911 bar. It takes about 2 s (1.42 s in CI at the reviewed head).cffa308032, including every file the earlier list called unfinished.YAML files run separately through Core's official test runner in sequential foreground processes. No microsimulation was run; the hub handles impact analysis.
axiom: TheAxiomFoundation/rulespec-us#1856 queued for §24(i)(1)(B), (i)(3) and (i)(4), with surviving-spouse companion rows for the 24(h)(3) threshold (us:statutes/26/24/h#ctc_phase_out_threshold_under_subsection_h; no test yet runs a surviving spouse), blocked on ingesting P.L. 117-2 §9611 (TheAxiomFoundation/axiom-corpus#744), a re-pin to a release with the 2021 Schedule 8812, and the derived filing-status chain (TheAxiomFoundation/rulespec-us#1399).
Generated by Claude Code