Skip to content

Add Iowa TANF Program#7171

Open
llennemann wants to merge 34 commits intoPolicyEngine:mainfrom
llennemann:ia-tanf
Open

Add Iowa TANF Program#7171
llennemann wants to merge 34 commits intoPolicyEngine:mainfrom
llennemann:ia-tanf

Conversation

@llennemann
Copy link
Collaborator

@llennemann llennemann commented Jan 14, 2026

Summary

Implements Iowa's Family Investment Program (FIP), the state's TANF cash assistance program.

Closes #7163
Closes #6645

Regulatory Authority

Income Eligibility Tests

Iowa FIP uses a three-step income eligibility process for applicants and a two-step process for continuing recipients:

Test 1: Gross Income Test (All)

Test 2: Net Income Test (Applicants Only)

  • Net income < Standard of Need
  • Net income = Gross income - 20% earned income deduction
  • Source: IAC 441-41.27(2)(a)

Test 3: Countable Income Test (All)

  • Countable income < Payment Standard
  • Countable income applies both 20% earned income deduction AND 58% work incentive disregard
  • Source: IAC 441-41.27(2)(c)

Income Deductions & Exemptions

Deduction Rate Applies To Source
Earned Income Deduction 20% Gross earned income IAC 441-41.27(2)(a)
Work Incentive Disregard 58% Income after 20% deduction IAC 441-41.27(2)(c)

Income Standards

Family Size Standard of Need Payment Standard 185% Gross Limit
1 $365 $183 $675.25
2 $719 $361 $1,330.15
3 $849 $426 $1,570.65
4 $986 $495 $1,824.10
5 $1,092 $548 $2,020.20
6 $1,216 $610 $2,249.60
7 $1,335 $670 $2,469.75
8 $1,457 $731 $2,695.45
9 $1,576 $791 $2,915.60
10 $1,724 $865 $3,189.40
Each additional +$173 +$87 +$320.05

Source: IAC 441-41.28(2)

Resource Limits

Status Limit Source
Applicant $2,000 IAC 441-41.26(1)(e)
Recipient $5,000 IAC 441-41.26(1)(e)

Benefit Calculation

Benefit = Payment Standard - Countable Income

Where:

  • Countable Income = (Gross Earned × 0.8 × 0.42) + Gross Unearned

Source: IAC 441-41.27(2)

Historical Note

Iowa's FIP payment standards have remained unchanged since at least January 1997 (source: 1998 Green Book Table 7-8). The work incentive disregard was increased from 50% to 58% effective August 1, 2007.

llennemann and others added 12 commits January 14, 2026 17:25
Starting implementation of Iowa TANF (Family Investment Program).
Documentation and parallel development will follow.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Schedule of Living Costs for Iowa FIP (Family Investment Program):
- Main parameter with family sizes 1-10
- Additional amount for families larger than 10

Per 441 IAC 41.28(239B), effective 7/1/2025.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Schedule of Basic Needs for Iowa FIP:
- Main parameter with family sizes 1-10
- Additional amount for families larger than 10

Per 441 IAC 41.28(239B), effective 7/1/2025.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add FIP income parameters:
- 20% earned income deduction rate
- 58% work incentive disregard rate
- 185% gross income limit (percent of standard of need)

Per 441 IAC 41.27(239B), effective 7/1/2025.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add FIP resource limits:
- Applicant families: $2,000
- Recipient families: $5,000

Per 441 IAC 41.26(239B).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add FIP variables:
- ia_tanf_standard_of_need: Schedule of Living Costs by family size
- ia_tanf_payment_standard: Schedule of Basic Needs by family size
- ia_tanf_eligible: Overall eligibility combining demographic and income tests

Per 441 IAC 41.27(239B) and 41.28(239B).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add FIP income test variables:
- ia_tanf_income_eligible: Combined income eligibility
- ia_tanf_gross_income_eligible: Test 1 (185% of standard of need)
- ia_tanf_net_income_eligible: Test 2 (after 20% deduction)
- ia_tanf_payment_standard_eligible: Test 3 (after work incentive)

Per 441 IAC 41.27(239B).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add FIP income source parameters:
- Earned income sources (employment, self-employment)
- Unearned income sources (social security, SSI, unemployment, etc.)

Add FIP income variables:
- ia_tanf_gross_earned_income: Total earned income
- ia_tanf_gross_unearned_income: Total unearned income
- ia_tanf_gross_income: Combined gross income
- ia_tanf_countable_income: Net income after 20% deduction and 58% work incentive

Per 441 IAC 41.27(239B).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add main ia_tanf variable that calculates the FIP benefit amount:
- Benefit = Payment Standard - Countable Income
- Eligible households get max(payment_standard - countable_income, 0)

Per 441 IAC 41.28(239B).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add test cases for ia_tanf:
- Unit tests for benefit calculation
- Integration test based on documentation example (family of 3, $800/month)
- Integration test for gross income limit failure

Per 441 IAC 41.27(239B) and 41.28(239B).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Apply black formatting to ia_tanf_net_income_eligible.py

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

codecov bot commented Jan 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (67abb79) to head (37e9f7d).
⚠️ Report is 28 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##             main     #7171       +/-   ##
============================================
+ Coverage   72.11%   100.00%   +27.88%     
============================================
  Files        3794        12     -3782     
  Lines       54662       165    -54497     
  Branches      275         0      -275     
============================================
- Hits        39418       165    -39253     
+ Misses      15228         0    -15228     
+ Partials       16         0       -16     
Flag Coverage Δ
unittests 100.00% <100.00%> (+27.88%) ⬆️

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.

llennemann and others added 7 commits January 19, 2026 04:42
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Refactored Iowa TANF implementation to use FIP (Family Investment Program)
naming convention which is the official state program name. Added 11 tests
covering unit tests, integration tests with various income scenarios,
and edge cases including large families and non-Iowa states.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add individual test files for each Iowa FIP variable following the
Arizona TANF pattern from PR PolicyEngine#7150:

- ia_fip_eligible.yaml (8 tests)
- ia_fip_income_eligible.yaml (8 tests)
- ia_fip_payment_standard.yaml (8 tests)
- ia_fip_standard_of_need.yaml (8 tests)
- ia_fip_countable_income.yaml (8 tests)
- ia_fip_gross_income.yaml (6 tests)
- ia_fip_gross_earned_income.yaml (7 tests)
- ia_fip_gross_unearned_income.yaml (10 tests)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@llennemann llennemann marked this pull request as ready for review January 21, 2026 17:09
@llennemann llennemann requested a review from hua7450 January 21, 2026 17:17
@llennemann llennemann self-assigned this Jan 21, 2026
@llennemann
Copy link
Collaborator Author

Dates for parameters values in Iowa TANF payment values 2017, 2018, 2019 #6645.

@hua7450 Should I add Iowa TANF to the state level aggregation level? in tanf.py
Also, for the immigration check, the Iowa State TANF plan states that "Each member of the eligible group must be a citizen or qualified alien." Does the immigration eligibility look right to you?

@PavelMakarchuk
Copy link
Collaborator

PR Review - Iowa Family Investment Program (FIP/TANF) Implementation

🔴 Critical Issues (Must Fix Before Merge)

None identified. The implementation correctly follows Iowa Administrative Code regulations.


🟡 Should Address

1. Missing Dedicated Test Files

Two variables with formulas lack dedicated unit test files:

  • ia_fip_resource_eligible - Only tested indirectly via ia_fip_eligible.yaml
  • ia_fip_countable_earned_income - Only tested indirectly via ia_fip_countable_income.yaml

Action: Create dedicated test files for these variables.

2. Missing Boundary Tests at Exact Thresholds

The implementation uses <= and < comparisons that need boundary testing:

Threshold Current Tests Missing Test
Applicant resource limit ($2,000) Above limit only Exactly $2,000, exactly $2,001
Recipient resource limit ($5,000) Above limit only Exactly $5,000, exactly $5,001
185% gross income limit Above limit only Exactly at threshold
Net income = standard of need Above only Exactly equal (should fail with <)
Countable = payment standard Above only Exactly equal (should fail with <)

3. Reference Format Issues

Several parameter files have inline comments in href fields:

# Current (unconventional):
href: https://hhs.iowa.gov/media/17445/download?inline#page=7 # (3)

# Should be:
- title: Iowa TANF State Plan 2025, Section (3)
  href: https://hhs.iowa.gov/media/17445/download?inline#page=7

Files affected: work_incentive_disregard.yaml, max_unit_size.yaml, payment_standard/*.yaml, resources/*.yaml

4. Missing Page Anchors on PDF References

Files: resources/applicant_limit.yaml, resources/recipient_limit.yaml

  • IAC PDF links missing #page=XX anchors

5. Description Typo

File: need_standard/additional.yaml

  • "families larger than than the max" → "families larger than the max"

🟢 Suggestions

  1. Family size 11+ value verification: The large family integration test doesn't explicitly verify the calculated payment/need standard values. Add tests that verify $865 + $87 = $952/month for size 11.

  2. Period consistency: ia_fip_payment_standard.py and ia_fip_standard_of_need.py use period for spm_unit_size - consider period.this_year for consistency with count variables.

  3. Cliff effect test: Add an integration test showing benefit dropping to $0 at the exact payment standard threshold.


✅ What's Implemented Correctly

Component Verification
Three-step income eligibility ✓ Gross (185% SoN) → Net (< SoN) → Countable (< PS)
20% earned income deduction ✓ Applied to all earned income
58% work incentive disregard ✓ Applied after 20% deduction
Applicant vs recipient distinction ✓ Different tests and resource limits
Need standard (sizes 1-10) ✓ $365-$1,724/month + $173/additional
Payment standard (sizes 1-10) ✓ $183-$865/month + $87/additional
Resource limits ✓ $2,000 applicant, $5,000 recipient
Benefit formula max(payment_standard - countable, 0)
No hard-coded values ✓ All values from parameters
Variable naming ✓ All use ia_fip_* prefix
Pattern usage ✓ Correct adds, add(), max_(), where()
Federal eligibility reuse ✓ Uses is_demographic_tanf_eligible

Validation Summary

Check Result
Regulatory Accuracy ✅ Implementation matches IAC 441-41
Reference Quality ⚠️ Minor format issues (inline comments, missing anchors)
Code Patterns ⚠️ Missing 2 dedicated test files
Test Coverage ⚠️ Missing boundary tests at exact thresholds
CI Status ✅ All checks passing

Three-Step Income Eligibility Verified

The implementation correctly handles Iowa's unique three-step income test:

  1. Gross Income Test: gross_income ≤ 185% × standard_of_need
  2. Net Income Test (applicants only): (gross - 20%) < standard_of_need
  3. Countable Income Test: (gross × 0.80 × 0.42) + unearned < payment_standard

Recipients skip Test 2, applicants must pass all three.


Test Coverage: 68 Tests Passing

File Tests
ia_fip.yaml 11
ia_fip_countable_income.yaml 8
ia_fip_eligible.yaml 8
ia_fip_gross_income.yaml 6
ia_fip_income_eligible.yaml 11
ia_fip_payment_standard.yaml 8
ia_fip_standard_of_need.yaml 8
integration.yaml 8

Manual Calculation Verification

Scenario 2 (Family of 2, $800/month earned):

  • Standard of need: $719/month
  • Payment standard: $361/month
  • Gross income limit: $719 × 1.85 = $1,330.15

Test 1: $800 ≤ $1,330.15 ✓
Test 2: $800 × 0.80 = $640 < $719 ✓
Test 3: $640 × 0.42 = $268.80 < $361 ✓
Benefit: $361 - $268.80 = $92.20


Next Steps

To auto-fix issues: /fix-pr 7171

Or address manually:

  1. Create ia_fip_resource_eligible.yaml and ia_fip_countable_earned_income.yaml test files
  2. Add boundary tests at exact resource and income thresholds
  3. Move inline comments from href fields to title fields
  4. Fix "than than" typo in need_standard/additional.yaml

🤖 Generated with Claude Code - Complete Review Plugin

hua7450 and others added 4 commits February 2, 2026 15:15
- Update all parameter effective dates from 2017-10-27 to 2017-01-01
- Rename ia_fip_resource_eligible to ia_fip_resources_eligible
- Add #page=1 anchor to resource limit PDF references
- Fix typo in need_standard/additional.yaml description
- Create eligibility/ folder and move eligibility variables
- Break down ia_fip_income_eligible into sub-components:
  - ia_fip_gross_income_eligible (Test 1)
  - ia_fip_net_income_eligible (Test 2)
  - ia_fip_countable_income_eligible (Test 3)
- Add comprehensive test files for new variables
- Remove unnecessary test files for adds-only variables

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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.

Implement Iowa TANF Iowa TANF payment values 2017, 2018, 2019

3 participants