Skip to content

Include disabled adult care expenses in TX FPP, HI CDCC, and MT care deduction#8981

Merged
hua7450 merged 9 commits into
PolicyEngine:mainfrom
hua7450:adult-care-expenses-programs
Jul 14, 2026
Merged

Include disabled adult care expenses in TX FPP, HI CDCC, and MT care deduction#8981
hua7450 merged 9 commits into
PolicyEngine:mainfrom
hua7450:adult-care-expenses-programs

Conversation

@hua7450

@hua7450 hua7450 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds adult care expenses to the Texas Family Planning Program (FPP), Hawaii child and dependent care credit, and Montana child and dependent care deduction when the care recipient qualifies under each program's rules.

This update also resolves the review findings:

  • Texas FPP now includes disabled spouses as well as disabled tax-unit dependents.
  • Montana's former deduction is available only through tax year 2023 and is zero from 2024, when MCA § 15-30-2131 was repealed.
  • For the pre-2024 Montana simplification, care_expenses represents qualifying in-home adult care.

Part of #8811. Companion PR: #8980 (SNAP).

Programs and authority

Program Variable Adult-care rule
Texas Family Planning Program tx_fpp_dependent_care_deduction Allows up to $175 per month for a disabled adult dependent or spouse. 1 TAC §382.109
Hawaii child and dependent care credit hi_dependent_care_benefits Includes a dependent or spouse unable to provide self-care. HRS §235-55.6
Montana child and dependent care expense deduction mt_child_dependent_care_expense_deduction Before repeal, included incapacitated dependents and spouses; the full deduction was repealed beginning in 2024. MCA §15-30-2131 (2022) Montana 2021 Legislative Review

Root cause and impact

The original adult-care paths did not consistently apply each program's qualifying-person rules. Texas excluded disabled spouses, and Montana continued calculating a repealed deduction after 2023.

These changes ensure eligible adult care lowers countable income where allowed, while preventing post-repeal Montana deductions. Households without adult-care expenses are unchanged.

Validation

  • make format (Ruff format and lint)
  • Texas FPP suite: 48 passed
  • Montana child and dependent care deduction suite: 28 passed
  • Montana income-tax suite: 254 passed
  • CI passes after the latest push

…deduction

Adds the adult care_expenses input to three programs whose statutes
cover care for disabled adult dependents (and, for HI, an incapacitated
spouse) but which previously only read childcare expenses:

- TX FPP dependent care deduction: 1 TAC 382.109(2)(B) allows up to
  $175/month per dependent adult with a disability.
- HI dependent care benefits (Schedule X Part II): HRS 235-55.6(b)(1)(B)-(C)
  includes incapacitated dependents and spouses as qualifying individuals.
- MT child/dependent care expense deduction (repealed eff. 2024):
  MCA 15-30-2131(1)(c)(i) covered dependents unable to provide self-care.

Part of PolicyEngine#8811.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (3ee920d) to head (60cfccf).
⚠️ Report is 11 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #8981   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         4    +3     
  Lines           10        92   +82     
  Branches         0         1    +1     
=========================================
+ Hits            10        92   +82     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

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

☔ View full report in Codecov by Harness.
📢 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.

hua7450 and others added 4 commits July 9, 2026 19:33
…)(c)

Montana's statute qualifies dependents "unable to provide self-care
because of physical or mental illness", not disabled dependents, so the
eligible-child gate now reads is_incapable_of_self_care. Also fix the
HI dependent care benefits reference: missing commas concatenated the
three URLs into one string, and the statute anchor pointed at page 40
(rate schedules) instead of page 46 where HRS 235-55.6 begins.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hua7450 hua7450 marked this pull request as ready for review July 13, 2026 23:22
@hua7450 hua7450 requested a review from daphnehanse11 July 14, 2026 16:31
@daphnehanse11

Copy link
Copy Markdown
Collaborator

PR review

Automated review via /review-pr — four validators (regulatory accuracy, reference quality, code patterns, test coverage) run against the PR branch. No code changes made.

Overall: No critical blockers. CI is green (all 36 checks), codecov patch coverage is 100%, every parameter value and pinpoint citation was verified against primary sources, and the new formulas are correctly vectorized and parameterized. The items below are worth addressing before merge, led by two Texas regulatory questions.

🟡 Should address

  1. TX: disabled spouse deduction is not supported by the cited regulationtx_fpp_dependent_care_deduction.py. 1 TAC §382.109(2)(B) authorizes the $175/month deduction only "for each dependent adult with a disability"; spouses are not mentioned in connection with any dependent-care deduction (they appear only in §(1) as income-counted members). The code counts is_disabled & (is_tax_unit_dependent | is_spouse), so a disabled spouse now generates a deduction. Note this contrasts with MT and HI, where the statutes do include an incapacitated spouse. If there is separate TX HHS guidance supporting the spouse path, please cite it; otherwise this looks over-generous.

  2. TX: disability branch lacks the "adult" restrictiontx_fpp_dependent_care_deduction.py. §382.109(2)(B) covers "each dependent adult with a disability"; care of a disabled child is already the (2)(A) child deduction. The code applies no age floor to is_disabled_dependent_or_spouse, so a disabled dependent under 18 can stack both expense streams (pre_subsidy_childcare_expenses * is_child + care_expenses * is_disabled...) under one per-person cap. Practical impact is limited (child care_expenses inputs are normally zero), but adding an age gate — as MT does with age >= p.age_limit — would match the text.

  3. MT: eligible_children tier count now excludes disabled dependents and spousesmt_child_dependent_care_expense_deduction_eligible_children.py. MCA §15-30-2131(1)(c)(iv)(B) restricts whose out-of-household expenses qualify to under-15 children, but its dollar tier ($2,400/$3,600/$4,800) reads "one/two/three qualifying individuals" — the broad defined term, mirroring IRC §21 where the limit counts all qualifying persons for whom expenses were incurred. Counting only under-15 children can pick a lower tier in mixed households (e.g., one child with $3,000 out-of-household childcare + an incapacitated spouse with in-home care → $2,400 tier instead of $3,600, understating the deduction by $600 pre-phase-out). This is interpretive — recommend confirming against Form 2441-M instructions before finalizing; the previous broader count is arguably closer to the federal-mirroring reading.

  4. MT: naming/concept mismatch and duplicated logic in the eligible_child pair. The singular mt_child_dependent_care_expense_deduction_eligible_child now returns child OR incapacitated adult/spouse (label changed to "Qualifying person") while the name still says eligible_child, and the plural _eligible_children is no longer the sum of the singular — it re-derives dependent & (age < p.age_limit), duplicating the child branch of the singular. Two near-identically named variables now describe different populations, and the child test lives in two places. Suggested shape: rename the singular to ..._qualifying_person, keep a child-only person bool, and define the plural via adds on it.

  5. Test gaps on the new logic paths (each new behavior is pinned by a revert-safe test, but three interactions are untested):

    • MT: no case where childcare (at its per-child cap) plus adult care jointly exceed the $4,800 overall_cap — the min_(qualifying_expenses, p.overall_cap) branch never binds in the suite (case 19 totals $3,400; case 20 is adult-only).
    • MT: a disabled dependent under 15 with care_expenses (currently excluded by age >= p.age_limit) has no pinning test — worth documenting whether the 0 result is intended.
    • HI: every new adult-care case sets tax_unit_childcare_expenses: 0; nothing tests childcare + adult care together in qualified_expense_amount.

🟢 Suggestions

  1. TX: is_tax_unit_spouse & (marital_unit.nb_persons() == 2)is_tax_unit_spouse already implies a head+spouse couple, so the nb_persons() guard is redundant; the repo-standard pattern is is_tax_unit_head_or_spouse & tax_unit_married (see federal is_cdcc_eligible). Also note the SPM-unit formula keys off tax-unit relationships, which can misidentify members in multi-tax-unit households.
  2. MT: move if not p.in_effect: return 0 above the eligible_children call to skip a wasted dependency computation in repealed years. (The scalar-gate pattern itself matches repo convention, e.g. sc_sciad.py.)
  3. MT: filename typo ..._eligibile_child.py ("eligibile") — pre-existing, but since this PR edits the file it's a cheap cleanup.
  4. MT tests: mt_child_dependent_care_expense_deduction_eligible_children.yaml actually tests the singular person-level variable; the plural tax-unit count has no dedicated unit test. Consider renaming/splitting.
  5. References (all values verified correct against primary sources): in_effect.yaml could add SB 399 / Ch. 503, Laws of 2021 as primary authority alongside the legislative-review table; overall_cap.yaml's archive.legmt.gov href 301-redirects to mca.legmt.gov; age_limit.yaml's second reference title reads "Montana legal code Code §…" (duplicated word); the (1)(c) inline cite could tighten to (1)(c)(i)(B)-(C).
  6. Boundary tests: TX child at child_age_threshold (17 vs 18) and MT incapacitated dependent at exactly age 15 on the adult-care branch are untested.

Verified correct (spot-checked against primary sources)

  • MT flat $4,800 overall_cap matches MCA §15-30-2131(1)(c)(iv)(A); the $2,400/$3,600/$4,800 tier in cap.yaml matches (iv)(B)(I)–(III); applying the tier only to out-of-household childcare while in-home adult care hits only the overall cap matches the statute's structure.
  • MT repeal effective 1/1/2024 corroborated by the 2021 Legislative Review table (SB 399, Ch. 503) — in_effect dates are correct.
  • HI: §235-55.6 confirmed at #page=46 (old #page=40 was wrong — good catch); the reference tuple fix resolves a real string-concatenation bug; is_cdcc_eligible matches (b)(1)(A)–(C); no double countingcare_expenses and childcare_expenses are distinct input streams.
  • TX $200/$175 monthly caps match §382.109(2)(A).

Validation summary

Check Result
Regulatory accuracy 2 should-fix (TX spouse, TX adult gate) + 1 interpretive (MT tier count)
Reference quality 0 issues — all values corroborated; 4 minor suggestions
Code patterns 0 critical — 1 should-fix (MT naming/duplication)
Test coverage 3 should-address gaps, all new behaviors revert-pinned
CI status ✅ All 36 checks passing, 100% patch coverage

🤖 Generated with Claude Code

@daphnehanse11 daphnehanse11 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just nits, overall structure looks good

TX FPP: restrict the disability deduction to adults per 1 TAC
382.109(2)(B); keep the disabled-spouse pathway, which the FPP policy
manual supports ("$175 per adult with disabilities per month" with no
dependency qualifier); drop the redundant marital-unit size guard.

MT: follow Form 2441-M — the dollar tier counts all qualifying
individuals (including incapacitated adult dependents and spouses) and
caps combined childcare and adult care expenses, making the separate
overall cap redundant; rename the qualifying-person variable (fixing
the "eligibile" filename typo), inline the count, and add SB 399
(Sec. 65) and archived form references.

HI: pin combined childcare plus adult care expenses in
hi_dependent_care_benefits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hua7450

hua7450 commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the thorough review — everything is addressed in f9d35a3 except finding 1, which primary sources refute. Point-by-point:

🟡 Should address

1. TX disabled spouse — kept, with new supporting evidence. The FPP Policy Manual §4100 ("Income Deductions"), which is already the second reference on the variable, drops the "dependent" qualifier for the adult category:

"Allowable deductions are actual expenses up to $200 per child per month for children younger than 2, $175 per child per month for each dependent 2 years and older, and $175 per adult with disabilities per month."

This wording is stable across every Wayback snapshot from June 2022 through October 2025 (archived copy — the live page blocks automated access). Three corroborating points:

  • Within §382.109(2) itself, "dependent" reads functionally rather than as a legal status: (2)(A)'s $175 tier covers "each dependent two years of age or older," which the manual renders as "each child 2 years and older."
  • §382.109(1) counts only the applicant, spouse, and children 18 or younger, so if (2)(B) excluded spouses it would apply almost solely to disabled exactly-18-year-old children.
  • The parallel Texas Works dependent care deduction (A-1420, same $200/$175/$175 structure) says "$175 a month for each adult with disabilities" and explicitly extends beyond the certified group.

The formula comment now cites the manual language.

2. TX adult age gate — fixed. The disability branch is now is_disabled & ~is_child & (dependent | spouse), so a disabled dependent under 18 gets only the (2)(A) child stream. New Cases 8–10 pin the gate and the 17/18 boundary.

3. MT tier count — confirmed, and the form goes further than suggested. 2022 Form 2441-M (identical in 2021; the mtrevenue.gov URLs now 404, so the parameter references point at the archived copies): line 1 counts qualifying individuals defined as under-15 dependents, incapacitated dependents of any age, and incapacitated spouses; line 2 takes the lesser of total dependent care expenses paid or the $2,400/$3,600/$4,800 tier — no in-home/out-of-home split at all. The formula now follows the form: one tiered cap on combined childcare + adult care, keyed on the full qualifying-individual count. That makes the separate overall_cap redundant (the tier tops out at $4,800), so it is removed. Case 19 is now exactly the mixed-household scenario from the review ($3,600 tier, not $2,400).

4. MT naming/duplication — done, one step further. The singular is renamed to ..._qualifying_individual (also fixing the eligibile filename typo). Since the plural count became a pure single-use sum of the singular, it's computed inline via tax_unit.sum() and the ..._eligible_children variable is removed; its former test cases now build real households.

5. Test gaps — all three closed. MT Case 24 (childcare + adult care jointly exceeding the 3-QI $4,800 tier, cap binds), MT Case 23 (incapacitated under-15 dependent's care expenses count, per the form's QI definition), HI Case 13 (childcare 2,000 + adult care 3,000 → 5,000 in line 6).

🟢 Suggestions

  1. TX nb_persons() == 2 guard dropped (is_tax_unit_spouse suffices; Case 7 still pins the unrelated-adult exclusion).
  2. MT in_effect early-return now precedes all dependency computation.
  3. eligibile filename typo fixed via the rename.
  4. The mis-named test file is renamed to match the singular variable it tests, with new spouse and exactly-age-15 boundary cases.
  5. References: SB 399, Ch. 503, L. 2021, Sec. 65 added to in_effect.yaml (archived bill); the redirecting archive.legmt.gov link went away with overall_cap.yaml and remaining statute links point at mca.legmt.gov; "Montana legal code Code" title typos fixed; inline cite tightened to (1)(c)(i)(B)-(C).
  6. Boundary tests added: TX ages 17/18 (Cases 9–10), MT incapacitated dependent at exactly 15.

Not addressed (pre-existing, out of scope)

Two issues in the MT phase-out predate this PR and are left for a follow-up issue: the reduction uses each spouse's own mt_agi_indiv while the form uses combined columns A + B, and the unconditional 0.5 split also halves a single filer's deduction (the form halves only married-filing-separately-on-the-same-form returns).

🤖 Generated with Claude Code

@daphnehanse11

Copy link
Copy Markdown
Collaborator

Follow-up review (head f9d35a3)

Re-reviewed the changes addressing the previous review. The MT and HI reworks fully resolve their findings and the TX spouse pathway is now properly sourced — but the TX refactor introduced a CI-failing regression that needs one more pass.

🔴 Critical (must fix)

  1. CI failure: is_tax_unit_spouse without a marriage gate grants the deduction to unrelated adultstx_fpp_dependent_care_deduction.py. Quick Feedback fails on existing Case 7 ("disabled unrelated adult receives no deduction"): computes $2,100 instead of $0. Root cause: is_tax_unit_spouse is a rank-based heuristic — it marks the oldest non-head, non-separated adult in the tax unit as "spouse" regardless of actual marriage. Case 7's two adults are in separate marital units, but since they share the default tax unit, person2 ranks as spouse and now collects $175 × 12. The previous marital_unit.nb_persons() == 2 guard was what filtered out rank-imputed spouses, so it was load-bearing, not redundant (my earlier suggestion to drop it was half-right — the guard should be replaced, not removed). Fix with the federal CDCC pattern (see is_cdcc_eligible): gate the spouse path on tax_unit_married, e.g. is_spouse = person("is_tax_unit_spouse", period) & person.tax_unit("tax_unit_married", period), or restore the marital-unit guard. Case 6 (genuine disabled spouse) should still pass either way. The pending full-suite states shards will hit the same failure.

✅ Previous findings resolved (verified)

  • TX spouse authority: The FPP policy manual citation checks out — I pulled §4140 ("Client Eligibility Screening Process", Rev. 25-3) and the Income Deductions text reads exactly "up to $200 per child per month for children younger than 2, $175 per child per month for each dependent 2 years and older, and $175 per adult with disabilities per month" — no dependency qualifier, and the manual's household definition (legal responsibility: spouses, parents/minor children) supports covering a disabled spouse. Good call adding the manual href to the references.
  • TX adult gate: ~is_child on the disability branch resolves the child double-stacking finding; Case 8 (disabled 10-year-old gets child stream only) and Case 10 (exactly 18 → adult stream) pin both sides of the boundary.
  • MT tier count: Switching to the Form 2441-M reading — all qualifying individuals count toward the tier, applied to combined childcare + adult care — resolves the interpretive finding, and Case 19 pins the exact mixed-household scenario from the review ($4,000 → $3,600 two-person tier).
  • MT overall cap removal: Sound — with the tier now applied to all expenses and topping out at $4,800 for 3+, the flat §(1)(c)(iv)(A) cap can never bind separately, so the parameter was redundant.
  • MT naming/duplication: The rename to ..._qualifying_individual fixes the name/concept mismatch and the "eligibile" filename typo; the duplicated child-count formula is gone (count now derives from the single qualifying-individual variable).
  • MT under-15 incapacitated child: Now included (their care_expenses count via the qualifying-individual gate) and pinned by Case 23.
  • Test gaps: All three closed — MT Case 24 (combined expenses exceed the three-person tier), HI Case 13 (childcare + adult care combine on line 6), plus the TX boundary cases (9, 10).
  • References: SB 399 Sec. 65 added as primary authority for the repeal, casetext/redirecting hrefs replaced with mca.legmt.gov and archived form links, and the "code Code" title typo fixed. Cap parameter threshold_unit correctly updated to person.

🟢 Suggestion

  1. The test file mt_child_dependent_care_expense_deduction.yaml mixes legacy unnamed cases and new "Case N" naming — fine to leave, but a future cleanup could normalize.

Validation summary

Check Result
Regulatory accuracy ✅ resolved (TX manual verified, MT 2441-M reading confirmed)
Reference quality ✅ upgraded (primary authority added, dead/redirect hrefs replaced)
Code patterns 🔴 1 regression (TX spouse gate)
Test coverage ✅ all previous gaps closed
CI status 🔴 Quick Feedback failing (TX Case 7); full-suite shards pending

One small fix from green.

🤖 Generated with Claude Code

is_tax_unit_spouse flags the oldest non-head adult in a tax unit even
when unmarried, so the two-person marital unit condition is required
to exclude unrelated adults (pinned by Case 7).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hua7450

hua7450 commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Correction to suggestion 1 above: dropping the marital_unit.nb_persons() == 2 guard was wrong — is_tax_unit_spouse flags the oldest non-head adult in the tax unit even when unmarried, so without the guard a disabled unrelated adult household member was treated as a spouse (Case 7 caught it in CI). Restored in 60cfccf with a comment explaining why the guard is load-bearing. The is_tax_unit_head_or_spouse & tax_unit_married pattern from federal is_cdcc_eligible targets the taxpayer/spouse pair rather than identifying the spouse person specifically, so it doesn't fit here.

🤖 Generated with Claude Code

@hua7450 hua7450 requested a review from daphnehanse11 July 14, 2026 19:59

@daphnehanse11 daphnehanse11 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all review comments addressed, lgtm

@hua7450 hua7450 merged commit defc95d into PolicyEngine:main Jul 14, 2026
35 checks passed
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