Skip to content

Wire up all 51 state TANF programs, fix childcare cycle artifact, add takeup#7401

Open
MaxGhenis wants to merge 15 commits intomainfrom
add-tanf-takeup
Open

Wire up all 51 state TANF programs, fix childcare cycle artifact, add takeup#7401
MaxGhenis wants to merge 15 commits intomainfrom
add-tanf-takeup

Conversation

@MaxGhenis
Copy link
Contributor

@MaxGhenis MaxGhenis commented Feb 14, 2026

Summary

Wires up all 51 state TANF programs into the tanf variable, adds takeup support, removes the tanf_reported short-circuit, and fixes two CO CCAP issues that created circular dependencies.

Closes #7400

Changes

TANF wiring and takeup

  • tanf.py: Removed tanf_reported short-circuit; added all 51 state programs; applied takeup multiplier
  • takes_up_tanf_if_eligible.py: New bool variable (default True; set by microdata for microsim)
  • Added KS, KY, MT, NH, TN, AR, ID, IA, LA, MA, NE, OH, UT, WV, WY to state list

Childcare cycle fix (false cycle removed)

An audit revealed that the pre-subsidy childcare workaround across 24 state TANF programs was unnecessary. The suspected cycle ran: TANF → state programs → childcare deduction → childcare_expenses → childcare subsidies (CO CCAP) → SNAP → TANF.

Root cause: CO CCAP's co_ccap_countable_income used SNAP income as a placeholder instead of its actual statutory income sources. No childcare subsidy program (CA, CO, NE, MA) includes SNAP in its income definition, so no cycle existed through this path.

Fix: Replaced the placeholder with the actual income sources from 8 CCR 1403-1 §7.105, extracted to a YAML parameter at gov.states.co.ccap.income.countable_income.sources.

Result: All 24 state TANF programs and SNAP's dependent care deduction now use childcare_expenses (post-subsidy) instead of the pre-subsidy workaround, which is more accurate.

CO CCAP FPG cycle fix (real cycle fixed)

A separate real cycle existed through CO CCAP's FPG eligibility check: TANF → childcare_expensesco_ccap_subsidyco_ccap_fpg_eligiblesnap_fpgsnap_unit_sizeis_snap_ineligible_studenttanf_person → TANF.

CO CCAP was borrowing SNAP's FPG variable, which depends on SNAP unit size (which excludes ineligible students based on TANF receipt).

Fix: Replaced snap_fpg with spm_unit_fpg / MONTHS_IN_YEAR in all three CO CCAP variables that used it (co_ccap_fpg_eligible, co_ccap_base_parent_fee, co_ccap_add_on_parent_fee). spm_unit_fpg uses spm_unit_size (just nb_persons()) with no SNAP or TANF dependency.

Files changed

  • 1 new parameter: parameters/gov/states/co/ccap/income/countable_income/sources.yaml
  • 1 new variable: takes_up_tanf_if_eligible.py
  • ~30 modified variables: tanf.py, co_ccap_countable_income.py, snap_dependent_care_deduction.py, co_ccap_fpg_eligible.py, co_ccap_base_parent_fee.py, co_ccap_add_on_parent_fee.py, 24 state childcare deduction variables
  • ~65 modified test files: removed spm_unit_pre_subsidy_childcare_expenses inputs, updated FPG mocks

Companion PR

policyengine-us-data#536 adds state-level TANF takeup rates to microdata construction.

Test plan

  • All 58 CO CCAP tests pass
  • All 205 SNAP tests pass
  • All state TANF integration tests pass
  • Full Suite - States (incl microsim) passes
  • All 9 CI checks pass

🤖 Generated with Claude Code

@codecov
Copy link

codecov bot commented Feb 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (56f72a9) to head (ea20939).
⚠️ Report is 94 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #7401   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           31        19   -12     
  Lines          408       342   -66     
  Branches         1         5    +4     
=========================================
- Hits           408       342   -66     
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 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.

@hua7450
Copy link
Collaborator

hua7450 commented Feb 16, 2026

11 additional state TANF programs exist in the codebase but are not included in STATE_TANF_VARIABLES:

State Variable Name Program Name
AR ar_tea Transitional Employment Assistance
ID id_tafi Temporary Assistance for Families in Idaho
KY ky_ktap Kentucky Transitional Assistance Program
LA la_fitap Family Independence Temporary Assistance Program
MA ma_tafdc Transitional Aid to Families with Dependent Children
NE ne_adc Aid to Dependent Children
NH nh_fanf Financial Assistance to Needy Families
OH oh_owf Ohio Works First
TN tn_ff Families First
UT ut_fep Family Employment Program
WY wy_power Personal Opportunities With Employment Responsibilities

This would bring the total from 39 to 50 (all states + DC except Montana, which is still in PR).

MaxGhenis and others added 14 commits February 16, 2026 07:11
…-circuit

- Add `takes_up_tanf_if_eligible` variable (bool, SPMUnit, default True)
- Wire all 39 implemented state TANF programs into tanf.py:
  26 with standard naming ({st}_tanf) and 13 with program-specific
  names (ak_atap, ct_tfa, fl_tca, ia_fip, md_tca, mi_fip, mn_mfip,
  nj_wfnj, nm_works, ri_works, vt_reach_up, wi_works, wv_works)
- Apply takeup in TANF formula: value * takes_up
- Remove tanf_reported short-circuit that blocked reform microsimulations
- Update tests for new behavior

Companion to PolicyEngine/policyengine-us-data#536 which adds
state-level TANF takeup rates to microdata construction.

Closes #7400

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FL TCA's payment standard depends on housing_cost, which cycles back
through rent → housing_assistance → hud_annual_income → tanf.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FL TCA payment standard now uses pre_subsidy_rent instead of
housing_cost, avoiding the cycle: tanf -> fl_tca -> housing_cost ->
rent -> housing_assistance -> hud_annual_income -> tanf.

This is more accurate: TANF agencies assess shelter obligation based
on what applicants owe, not the net amount after housing subsidies
from a separate agency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All FL TCA tests now use pre_subsidy_rent instead of rent/housing_cost,
matching the formula change in fl_tca_payment_standard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Same pattern as FL TCA fix: use pre_subsidy_rent + other housing
components instead of housing_cost to break the cycle
tanf -> az_tanf -> housing_cost -> rent -> housing_assistance
-> hud_annual_income -> tanf.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The baseline test used FL because it had no TANF implementation,
but now that fl_tca is wired up, this household receives TANF.
Set takes_up_tanf_if_eligible to false since this test is about
ECPA, not TANF.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MI household resources includes tanf. Now that mi_fip is wired up,
this family receives TANF which increases their household resources
and changes the home heating credit. Suppress TANF since this test
is about the home heating credit, not TANF.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rams

Changed 22 state TANF childcare deduction formulas to use
spm_unit_pre_subsidy_childcare_expenses instead of childcare_expenses,
breaking the cycle: TANF → childcare_expenses → childcare subsidies →
SNAP → tanf. Also fixed VT Reach Up housing allowance to use
pre_subsidy_rent instead of housing_cost, breaking the same type of
cycle as FL TCA and AZ TANF.

States affected (childcare): AL, AK, AZ, DC, DE, GA, HI, IL, KY, MD,
ME, MN, MO, NH, NM, OK, RI, TN, TX, VA, VT, WV
States affected (housing): VT

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…NH broadcast

- Add ky_ktap, mt_tanf, nh_fanf, tn_ff to STATE_TANF_VARIABLES (39 → 43)
- Fix MT TANF childcare deduction to use spm_unit_pre_subsidy_childcare_expenses
- Fix NH FANF childcare deduction entity broadcast (any_full_time SPMUnit→Person)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…43 → 51)

All 51 US jurisdictions now have TANF programs wired up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The childcare "cycle" (TANF → childcare_expenses → childcare subsidies →
SNAP → TANF) was an implementation artifact, not a real policy interaction.

Root cause: CO CCAP's co_ccap_countable_income used SNAP income variables
as a placeholder (with a TODO comment), creating a false dependency chain.
California, Nebraska, and Massachusetts childcare subsidies never included
SNAP in their income definitions.

Changes:
- Replace CO CCAP placeholder with actual income sources per 8 CCR 1403-1
- Switch 24 state TANF programs from spm_unit_pre_subsidy_childcare_expenses
  to childcare_expenses (the accurate post-subsidy amount)
- Switch SNAP dependent care deduction from pre_subsidy_childcare_expenses
  to childcare_expenses (workaround no longer needed)
- Update 65+ test files to match

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract hardcoded income source list from co_ccap_countable_income.py
into a YAML parameter at gov.states.co.ccap.income.countable_income.sources,
following the same pattern as MA CCFA and federal TANF income definitions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@MaxGhenis MaxGhenis changed the title Wire up all 39 state TANF programs with takeup support Wire up all 51 state TANF programs, fix childcare cycle artifact, add takeup Feb 17, 2026
@MaxGhenis MaxGhenis requested review from hua7450 and nikhilwoodruff and removed request for nikhilwoodruff February 17, 2026 01:48
CO CCAP used snap_fpg for its FPG calculation, creating a cycle:
tanf → childcare_expenses → co_ccap_subsidy → co_ccap_fpg_eligible
→ snap_fpg → snap_unit_size → is_snap_ineligible_student
→ tanf_person → tanf

Replaced with spm_unit_fpg (existing HHS FPG variable using
spm_unit_size) divided by 12 for monthly values. No new variable
needed — reuses the existing annual FPG with time-based indexing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Collaborator

@hua7450 hua7450 left a comment

Choose a reason for hiding this comment

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

Minor changes, others looks good.

@@ -36,8 +36,7 @@ def formula(spm_unit, period, parameters):
)
if mask.any():
fpg_rate[mask] = p.entry.fpg_rate[county[mask]]
# SNAP FPG is monthly.
fpg = spm_unit("snap_fpg", period)
fpg = spm_unit("spm_unit_fpg", period.this_year) / MONTHS_IN_YEAR
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
fpg = spm_unit("spm_unit_fpg", period.this_year) / MONTHS_IN_YEAR
fpg = spm_unit("spm_unit_fpg", period)

And all others

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.

Move TANF reported value logic from policy model to data package

2 participants