Skip to content

Fix federal-state tax conformity for EITC, deductions, and ALDs#8554

Open
daphnehanse11 wants to merge 23 commits into
PolicyEngine:mainfrom
daphnehanse11:codex/8243-review-fixes
Open

Fix federal-state tax conformity for EITC, deductions, and ALDs#8554
daphnehanse11 wants to merge 23 commits into
PolicyEngine:mainfrom
daphnehanse11:codex/8243-review-fixes

Conversation

@daphnehanse11
Copy link
Copy Markdown
Collaborator

Supersedes #8243 while David is away and the original fork branch cannot be updated by maintainers (maintainer edits are disabled). This branch is based on David's PR head, so it keeps David's commits and adds one follow-up commit for the remaining review issues.

Summary

  • Fix Hawaii student loan interest MAGI by adding back the federal student loan interest deduction before applying the Hawaii worksheet.
  • Restrict separated filing status logic to the tax unit head/spouse instead of any dependent or other member.
  • Tighten the affected YAML test tolerances and remove the stale dc_base_eitc comment.

Verification

  • uv run python -B -m policyengine_core.scripts.policyengine_command test policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/hi_student_loan_interest_adjustment.yaml policyengine_us/tests/policy/baseline/household/demographic/tax_unit/filing_status.yaml policyengine_us/tests/policy/baseline/gov/states/wa/tax/income/credits/wa_working_families_tax_credit.yaml policyengine_us/tests/policy/baseline/gov/states/il/tax/income/credits/il_eitc.yaml -c policyengine_us
  • uv run python -B -m policyengine_core.scripts.policyengine_command test policyengine_us/tests/policy/baseline/household/demographic/tax_unit/head_of_household_eligible.yaml policyengine_us/tests/policy/baseline/household/demographic/tax_unit/filing_status.yaml -c policyengine_us
  • uv run python -B -m compileall -q policyengine_us/variables/gov/states/hi/tax/income/subtractions/hi_student_loan_interest_adjustment.py policyengine_us/variables/household/demographic/tax_unit/filing_status.py policyengine_us/variables/gov/states/dc/tax/income/credits/eitc/dc_eitc.py
  • git diff --check

Note: ruff was not available in the temp worktree venv.

DTrim99 and others added 20 commits May 7, 2026 10:52
…ues and revert PA CDCC regression

Addresses critical review findings:
- Parameterize HI student-loan-interest deduction (cap, phase-out start/divisor by filing status) under gov.states.hi.tax.income.subtractions.student_loan_interest
- Parameterize SC federal-deduction conformity cutoff via gov.states.household.states_using_federal_{itemized_deductions,standard_deduction} (year-varying lists; SC drops out at 2026)
- Revert PA CDCC from cdcc to cdcc_potential (PA-40 Schedule DC Line 2 directs entry of Form 2441 Line 9a, the credit before federal tax-liability cap)
- Document IN/WA federal-law freeze dates as code-level constants (2023-01-01 and 2022-06-09) since policyengine-core parameters do not support string values; statutory basis is now in inline comments

Tests: 59/59 pass for affected variables (PA CDCC, IN EITC, WA WFTC, HI student-loan, shared deduction helpers).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…703(b), correct UT/IL/ID statutory references

Critical:
- Parameterize CO EITC under-25 expansion ages (18/19/24) under gov.states.co.tax.income.credits.eitc.under_25_expansion
- Parameterize HI student-loan-interest in_effect via gov.states.hi.tax.income.subtractions.student_loan_interest.in_effect (replaces period.start.year < 2025 gate)
- Parameterize IN EITC static conformity via gov.states.in.tax.income.credits.earned_income.static_conformity_in_effect (replaces period.start.year >= 2023 gate)
- Add reference blocks to gov.states.hi.tax.income.additions.additions and the two household-level federal-conformity list parameters (citing per-state statutes plus SC H.4216 / Act 110 of 2026)

IRC and state-statute fixes:
- HoH eligible: restrict is_separated test to head/spouse only per IRC 7703(b)(1) (not any tax-unit member)
- IL CTC: use is_qualifying_child_dependent (IRC 152(c)) instead of is_tax_unit_dependent (IRC 152(a)) per 35 ILCS 5/212.3
- UT EITC potential: cap at irs_employment_income (W-2 Box 1) per Utah Code 59-10-1044; correct reference URL
- ID itemized deductions: remove unconditional foreign_tax_credit addback (Idaho Form 39R only requires addback when foreign tax is claimed as itemized deduction, which is already in itemized_taxable_income_deductions)

Refactoring:
- Move policyengine_us/variables/gov/states/tax/income/credits/eitc_helpers.py to policyengine_us/tools/state_eitc_helpers.py (out of variable-discovery tree)
- Fix eitc_filing_status_eligible scalar-return bug; now returns a properly broadcast vectorized array
- Extract hi_modified_agi as a standalone variable to break the AGI / subtractions / student-loan-deduction circular reference and avoid in-formula list comprehensions
- Replace np.minimum / np.maximum with min_ / max_ in HI student loan formula

Tests:
- Update HI hi_student_loan_interest_adjustment expected hi_agi to 59,166.67 (federal AGI 100K - HI pension subtraction 40K - HI student-loan subtraction 833.33). Previous expectation of 19,166.67 double-counted the pension subtraction.
- Update ID id_itemized_deductions test to assert that the foreign tax credit is NOT added back unconditionally (Idaho Form 39R)

Verified against statutes:
- CO CRS 39-22-123.5(2)(a)(II) — three-tier 18/19/24 age rule confirmed
- IN IC 6-3-1-11 / 6-3.1-21 — 2023-01-01 IRC pin confirmed for TY 2023-2025
- WA RCW 82.08.0206(2)(d) — 2022-06-09 IRC pin confirmed verbatim
- IRC 7703(b)(1) — "considered unmarried" applies to taxpayer only, confirmed
- SC H.4216 / Act 110 of 2026 — federal-deduction decoupling effective TY 2026 confirmed
- UT Code 59-10-1044 — W-2 Box 16 wage cap excluding self-employment confirmed
- HI HRS 235-2.4 — N-11 p.35 values confirm $2,500/$50K-$65K single/$100K-$130K joint

DC EITC change reverted: D.C. Law 23-149 explicitly extends EITC to ITIN filers and ITIN qualifying children, so the PR's has_tin test is correct (a stricter meets_eitc_identification_requirements check would over-restrict).

Tests: 156/156 targeted tests pass.

Follow-up items (cannot 100% verify autonomously, documented in inline TODO/comments):
- IN SB 243 of 2026 advances IRC conformity to 2026-01-01 for TY 2026+; the static_conformity_in_effect parameter handles the gating but the hardcoded "2023-01-01" snapshot will need to advance to "2026-01-01" for TY 2026.
- DC may benefit from a separate ITIN-EITC branch (D.C. Law 23-149) rather than the current unified has_tin path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nt DC ITIN-EITC split

- IN EITC freeze date: TY 2023-2025 keeps the 2023-01-01 IRC snapshot per IC 6-3-1-11; TY 2026+ advances to 2025-07-04 per SB 243 of 2026 (signed Mar 2026, advancing conformity to include sections of H.R. 1 / Public Law 119-21)
- CO under-25 expansion YAMLs: add Colorado DOR Income Tax Topics citation (administrative interpretation of CRS 39-22-123.5)
- HI student-loan-interest YAMLs (cap, phase_out/start, phase_out/divisor): add HRS section 235-2.4 citation alongside the N-11 instructions reference
- DC EITC: add D.C. Law 23-149 to the reference tuple and add a TODO documenting the recommended branch split (federal-base SSN-required vs Law 23-149 ITIN extension)

Tests: 33/33 affected tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds 17 new tests covering the variables and behavior introduced/changed by PR 8243:

- HoH eligible (2): separated filer with qualifying child positive case; separated filer with only a qualifying relative negative case (IRC 7703(b)(1) "child within the meaning of section 152(f)(1)").
- IL CTC (2): age-11 qualifying child receives the credit; age-11 dependent who is NOT a qualifying child does not receive the credit (validates the new IRC 152(c) eligibility test).
- CO EITC (3): under-25 expansion boundary cases - age 17 below all mins, age 18 default no homeless/foster, age 20 specified-student exclusion.
- DC childless EITC (2): age 24 below federal minimum, age 65 above federal maximum.
- HI student loan interest (5): pre-2025 zeros, married-filing-separately zero, joint above phase-out end zero, subtraction = max(adjustment, 0) wrapper, addition = max(0, -adjustment) wrapper.
- GA itemized deductions adjustment (2): default-zero passthrough; explicit input flows through to ga_deductions.
- SC 2026 decoupling (2): SC adopts federal itemized deductions in TY 2025; SC decouples in TY 2026 per H. 4216 / Act 110 of 2026.
- WA WFTC (1): married-filing-separately state-only-path qualifies for credit.

All 77 affected tests pass (17 new + 60 existing).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tests

DC ITIN-EITC branch split:
- New variable dc_base_eitc implements the credit DC would grant under section
  47-1806.04 alone (federal IRC section 32 incorporation), requiring an SSN
  for the filer and each qualifying child. This dispatches between the with-
  and without-qualifying-child branches internally using
  meets_eitc_identification_requirements rather than has_tin.
- Existing dc_eitc remains the Law 23-149 ITIN-inclusive credit (behavior
  unchanged). The TODO comment is replaced with an architecture doc explaining
  that the difference dc_eitc - dc_base_eitc is the incremental Law 23-149
  benefit.
- 3 new tests in dc_base_eitc.yaml:
  - SSN filer with SSN child: dc_base_eitc == dc_eitc (no ITIN expansion)
  - ITIN filer: dc_base_eitc == 0, dc_eitc > 0 (Law 23-149 grants the credit)
  - SSN filer with ITIN child: base path falls back to childless EITC

Smaller test gaps closed:
- HI joint mid-phase-out: $115K joint MAGI -> partial $1,458 deduction
- WA WFTC extra-ITIN-children: state-only path with state child_count >
  federal_child_count
- WA WFTC age expansion: 2029+ in_effect with min_age 18; tests positive case,
  age-17 negative case, and 2028 not-yet-in-effect case
- CO age-24 qualifies via eligible_at_max_age; age-25 via standard federal EITC

58/58 affected tests pass locally (10 new + 48 existing).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Critical fixes:
- Parameterize IL childless EITC minimum age (was hardcoded 18 in il_eitc.py).
  New parameter gov.states.il.tax.income.credits.eitc.childless_min_age cites
  35 ILCS 5/212 and Public Act 102-0700.
- Fix OH educator expense reference to point at ORC 5747.01(A)(31) (was the
  unsubsectioned URL) and add #page=25 anchor on the 2025 IT-1040 booklet.
- Fix SC pre-2026 conformity citation in both states_using_federal_*.yaml
  files. The previous citation referenced 12-6-510 / 12-6-1140 (rate-bracket
  and individual-deduction sections, not the federal-conformity statute).
  The operative conformity statute is S.C. Code Ann. section 12-6-50 (which
  Act 110 of 2026 amends).

Reference polish:
- IN static_conformity_in_effect.yaml: add IC 6-3-1-11 (IRC definition that
  fixes the conformity date) plus IC 6-3.1-21 chapter URL; add page-9 anchor
  to the 2023 IT-40 booklet title.
- CO under-25 expansion YAMLs: use the post-301-redirect content.leg.colorado.gov
  URL; relabel the te19 source as "Colorado Office of the State Auditor Tax
  Expenditure Evaluation 19".
- HI student-loan-interest and additions YAMLs: standardize the HRS section
  235-2.4 title across all five files (uniformly "Hawaii operative IRC
  provisions sections 63 to 530") and drop the "page 35" wording from
  N-11 instruction titles since the page anchor lives in the href.
- ID id_itemized_deductions.py: add Idaho Code 63-3022 statute URL and Idaho
  Form 39R instructions URL to corroborate the foreign-tax-credit addback rule.

Code-style fixes:
- dc_eitc.py: slim the 9-line architecture block comment per the minimal-
  comments rule; the dc_base_eitc / dc_eitc relationship is now a one-line
  in-formula comment.
- dc_base_eitc.py: drop the forbidden `documentation` field and move the
  SSN-rule provenance into a tuple reference (IRC 32 incorporation) plus a
  short comment.
- state_eitc_helpers.py: standardize parameters access style in
  eitc_filing_status_eligible to use parameters(period).gov... rather than
  the inconsistent parameters.gov...(period) form.
- wa_working_families_tax_credit.py: rename the local `eitc_child_count`
  to `wftc_child_count` so it does not shadow the federal variable name and
  to make the EITC-vs-WFTC distinction explicit.

Additional tests:
- IL EITC childless age 17 negative, age 18 positive (validates the new
  childless_min_age parameter at the boundary).
- IN EITC TY 2026 uses the SB 243 advanced 2025-07-04 IRC snapshot.
- CO EITC under-25 expansion: age 18 homeless positive, age 18 foster
  positive (covers the homeless_or_foster_min_age branch).
- HoH eligible: surviving_spouse precedence over separated+qualifying-child.
- DC base EITC without-child branch: SSN filer age 25 qualifies; SSN filer
  age 24 does not (validates the base path's federal age gate).

DC deduction conformity verified: dc_standard_deduction.py already handles
the federal-conformity-then-decoupling-2025 via formula_2025 (per DC Act
26-214). DC is intentionally not in states_using_federal_standard_deduction.

Tests: 133/133 affected tests pass locally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CRITICAL fixes:
- HoH MFJ mask: separated_qualifies now requires filing_status != JOINT,
  so a JOINT filer with is_separated=true no longer claims HoH (IRC
  7703(b)(1) requires a separate return).
- Remove dc_base_eitc.py and its YAML test (unreferenced dead code).
- Parameterize IN EITC snapshot date as
  gov.states.in.tax.income.credits.earned_income.static_conformity_snapshot_date
  (2023-01-01 for TY 2023-2025; 2025-07-04 for TY 2026+ per SB 243).
- Parameterize WA WFTC snapshot date as
  gov.states.wa.tax.income.credits.working_families_tax_credit.federal_eitc_snapshot_date
  (2022-06-09 per RCW 82.08.0206).
- Replace `if str(period) == "2021":` hard-coded gate in in_eitc with
  a new
  gov.states.in.tax.income.credits.earned_income.childless.in_effect
  boolean parameter (true only in 2021).
- Rewrite decoupled.yaml: add period: metadata, dedupe the redundant
  2023-01-01: true entry, restructure the description, and pull
  page-number text into href #page= anchors.
- Drop `documentation =` field on ga_itemized_deductions_adjustment.py
  and oh_educator_expense_deduction_person.py (skill convention
  requires `reference =`; both already have one). Inline the previous
  explanatory text as code comments.
- Replace IL childless_min_age.yaml's two dead URLs (HTTP 404) with
  current ILGA Chapter/Act/Section deep links and the IDOR EITC page.
- Tighten SC § 12-6-50 reference titles to make clear that the
  operative amendment is in H. 4216 / Act 110 of 2026 (clicking the
  Code link today still shows the un-amended text).

SHOULD ADDRESS:
- Add a YAML test confirming a JOINT filer with is_separated=true is
  NOT HoH-eligible (regression guard for CRITICAL #1).
- Add a divisor-safety comment to hi_student_loan_interest_adjustment.py
  explaining that the SEPARATE divisor is non-zero only to keep the
  vectorized arithmetic safe; the where(separate, 0, ...) guard masks
  the result.

Changelog: expanded 8243.fixed.md with notes on the OH educator
under-implementation (federal $300 cap no longer auto-applied to the
OH deduction list; new oh_educator_expense_deduction_person is an
explicit-input stub), CT silently dropped from federal-conformity
lists, SC 2026 decoupling source, GA stub limitations, and the HI
student loan interest deduction subtree.
YAML auto-parses date-formatted strings as datetime.date objects, which
policyengine-core's parameter_at_instant rejects ('str' has no .get).
Quote the values to keep them as strings; parameters.gov.irs.credits.eitc()
accepts a string instant-spec internally.
policyengine-core's parameter system rejects string-valued parameters
('str' object has no attribute 'get'). The IN and WA snapshot-date
parameters introduced in the previous commit caused every import to
fail at startup.

Revert to statutory date literals in Python with explicit comments
citing the operative statute and noting why the date lives in code
(date-valued parameters are not supported in policyengine-core today).
This addresses Pavel's concern in spirit by making the literals
discoverable and self-documenting, but leaves the parameterization
question for a future policyengine-core enhancement.

Keep the parameterization that does work: gov.states.in.tax.income.credits.earned_income.childless.in_effect (boolean gate for the 2021-only branch).
The previous fix read filing_status to mask JOINT filers from the IRC
7703(b) treated-unmarried path, which created a CycleError:
filing_status -> head_of_household_eligible -> filing_status.

Replace the filing_status check with ~tax_unit_married, which uses
the spouse-presence signal already available. In PolicyEngine:
- JOINT filers have spouse in the same tax unit (married=true)
- MFS filers have spouse in a separate tax unit (married=false)

This still excludes the JOINT-with-is_separated=true case Pavel
flagged in CRITICAL #1, without reading filing_status.
…ty-fixes

# Conflicts:
#	policyengine_us/tests/policy/baseline/gov/states/al/tax/income/al_agi.yaml
#	policyengine_us/tests/policy/baseline/gov/states/wa/tax/income/credits/wa_working_families_tax_credit.yaml
The wa_wftc_childless_filer_with_eitc partner-analytics fixture was
authored against the pre-fix WFTC formula that used the *current*
federal EITC parameters (including ARPA's expanded childless cap).

This PR (PolicyEngine#8243) freezes the WFTC's federal EITC reference to the rules
as of 2022-06-09 per RCW 82.08.0206(2)(d), per Pavel's review. The
2022-frozen childless EITC max is materially smaller than the ARPA
expansion that was previously bleeding into WFTC, so a $15K
childless filer's WFTC drops from $342.59 to $223.25 in 2026.

Only the childless edge case is affected; the four other fixtures
(joint with child, etc.) still match because the with-child federal
EITC parameters didn't change as dramatically.
…ents

CRITICAL:
- IN EITC TY 2026+ snapshot date: change literal from 2025-07-04 to
  2026-01-01 per Indiana SEA 243 (2025), in both in_eitc.py and
  in_eitc_eligible.py. Update inline comments to cite SEA 243.
  (Parameterization was attempted in commit 16c7a00 and reverted because
  policyengine-core rejects string-valued parameters.)
- HI subtractions list: restore student_loan_interest_ald to the
  2021-01-01 entry so TY 2021-2024 retain the federal-equivalent SLI
  deduction. TY 2025+ continues to use the new HI-specific
  hi_student_loan_interest_subtraction.

SHOULD ADDRESS:
- IN static_conformity_in_effect.yaml: update description to reflect
  the two snapshot dates (2023-01-01 for TY 2023-2025, 2026-01-01 for
  TY 2026+ per SEA 243).
- OH educator deduction: strengthen inline comment citing ORC
  § 5747.01(A)(31) and explicitly noting that this stub REPLACES (not
  supplements) the federal educator_expense to avoid double-counting.
- WA WFTC age expansion: document (a) why no separate-filer guard is
  applied (state-only credit does not honor federal MFS bars) and
  (b) prior-year-age methodology approximation per ESSB 6346 Sec.
  901(2)(a)(ii)(D).
- UT EITC potential: correct misleading comment — TC-40A worksheet
  cites Box 16 (state wages); irs_employment_income (Box 1) is used
  as a proxy because PolicyEngine does not expose a state-wages
  variable.

REFERENCE CLEANUPS:
- IN earned_income parameters: restore PolicyEngine#6-3-1-11 / PolicyEngine#6-3.1-21 anchors
  on iga.in.gov links; add SEA 243 reference to static_conformity
  parameter.
- SC § 12-6-50 links in states_using_federal_*_deductions: switch from
  scstatehouse.gov table-of-contents to law.justia.com direct section
  link.
- CT exclusion: add Conn. Gen. Stat. § 12-701 reference explaining why
  CT is excluded from both federal-conformity lists.

CHANGELOG:
- Correct claim about parameterized snapshot-date parameters (those
  were reverted); document the IN 2026 snapshot correction and the
  HI 2021-2024 SLI retention explicitly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The test was authored to lock in the (incorrect) 2025-07-04 snapshot
behavior. With Pavel's corrected 2026-01-01 snapshot (per Indiana SEA
243), the computed credit shifts from 432.80 to 442.70 — this reflects
the actual difference between mid-2025 and January-2026 EITC parameter
values, not floating-point noise. Update the test name, comment, and
expected value to reflect the corrected snapshot, and tighten the
margin to 0.01 (matching the other in_eitc tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 1, 2026

Codecov Report

❌ Patch coverage is 99.64413% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 99.83%. Comparing base (c52e3d0) to head (b0d4896).
⚠️ Report is 103 commits behind head on main.

Files with missing lines Patch % Lines
...tax/income/credits/earned_income_credit/in_eitc.py 90.90% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8554      +/-   ##
==========================================
+ Coverage   97.83%   99.83%   +2.00%     
==========================================
  Files          12       25      +13     
  Lines         185      624     +439     
  Branches        3       11       +8     
==========================================
+ Hits          181      623     +442     
+ Misses          4        0       -4     
- Partials        0        1       +1     
Flag Coverage Δ
unittests 99.83% <99.64%> (+2.00%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants