Implement Michigan Family Independence Program (FIP)
Summary
Implements Michigan Family Independence Program (FIP), the state's TANF cash assistance program, with dual-test system and per-person deductions verified against BEM policy manuals.
Closes #6813
Status
- [x] Documentation collected
- [x] Parameters created (6 files)
- [x] Variables implemented (11 files)
- [x] Tests written (66 test cases across 8 files)
- [x] CI passing
- [x] Dual-test system implemented (20% initial, 50% benefit)
- [x] Per-person deduction logic verified
- [x] Formulas verified against BEM 518, 520, 503
- [x] Ready for review
Key Changes
Implementation Summary
- ✅ 11 new variables for Michigan FIP benefit calculation
- ✅ 6 parameter files with dual deduction rates and historical values
- ✅ 66 comprehensive test cases across 8 test files (17 integration + 49 unit)
- ✅ Dual-test system correctly separates eligibility from benefit calculation
- ✅ All tests passing
Correct Formula (Per BEM 518 and BEM 520)
Earned Income Deduction (per person):
Flat: $200 per working person
Percentage: 20% OR 50% depending on purpose
Initial Eligibility (new applicants - BEM 520 Section C):
- Uses 20% deduction rate (Qualifying Deficit Test)
- Determines IF household qualifies
Benefit Calculation (everyone - BEM 520 Section D):
- Uses 50% deduction rate (Issuance Deficit Test)
- Determines HOW MUCH benefit
- Applies to both new applicants and enrolled recipients
Countable Income = Sum(per-person countable earned) + gross unearned
Monthly Benefit = MAX(Payment Standard - Countable Income, 0)
Critical Implementation Details:
- Deductions apply per person (each worker gets their own $200)
- Initial eligibility test (20%) is separate from benefit calculation (50%)
- Once qualified, everyone gets benefits calculated with 50% rate
Files Added
Parameters (6 files)
policyengine_us/parameters/gov/states/mi/mdhhs/fip/
├── resource_limit.yaml
├── income/deductions/earned_income_disregard/
│ ├── flat_amount.yaml # $200
│ ├── initial_percent.yaml # 20% (eligibility only)
│ └── ongoing_percent.yaml # 50% (benefit calc, since 2011)
└── payment_standard/
├── amounts.yaml # Historical 2017 & 2025
└── additional_person_increment.yaml # $80→$95
Variables (11 files)
policyengine_us/variables/gov/states/mi/mdhhs/fip/
├── eligibility/
│ ├── mi_fip_eligible.py
│ ├── mi_fip_income_eligible.py # Dual-test logic!
│ └── mi_fip_resources_eligible.py
├── income/
│ ├── mi_fip_earned_income_after_deductions_person.py # 50% (benefit)
│ ├── mi_fip_earned_income_after_deductions_initial_person.py # 20% (eligibility)
│ ├── mi_fip_countable_earned_income.py # Uses adds pattern (50%)
│ ├── mi_fip_countable_earned_income_initial.py # Uses adds pattern (20%)
│ ├── mi_fip_countable_income.py # Uses adds (50% version)
│ └── mi_fip_countable_income_initial.py # Uses adds (20% version)
├── mi_fip.py
└── mi_fip_payment_standard.py
Tests (8 files, 66 test cases)
policyengine_us/tests/policy/baseline/gov/states/mi/mdhhs/fip/
├── eligibility/
│ ├── mi_fip_eligible.yaml # 5 tests
│ ├── mi_fip_income_eligible.yaml # 7 tests (tests both 20% & 50%)
│ └── mi_fip_resources_eligible.yaml # 6 tests
├── income/
│ ├── mi_fip_countable_earned_income.yaml # 8 tests (50% benefit calc)
│ └── mi_fip_countable_income.yaml # 6 tests
├── integration.yaml # 17 integration tests
├── mi_fip.yaml # 7 benefit tests
└── mi_fip_payment_standard.yaml # 10 payment tests
Example Calculations
New Applicant: Two-Step Process
Household: Family of 3, NEW applicant, $600/month earned
STEP 1: Initial Eligibility Test (20% deduction)
Countable = $600 - [$200 + 20%×$400] = $600 - $280 = $320
Payment Standard = $583
$320 < $583 → PASSES (eligible for FIP)
STEP 2: Benefit Calculation (50% deduction)
Countable = $600 - [$200 + 50%×$400] = $600 - $400 = $200
Benefit = $583 - $200 = $383/month
Enrolled Recipient: One-Step Process
Household: Family of 3, ENROLLED, $1,000/month earned
Initial eligibility: Already passed (enrolled)
Benefit Calculation (50% deduction):
Countable = $1,000 - [$200 + 50%×$800] = $1,000 - $600 = $400
Payment Standard = $583
Benefit = $583 - $400 = $183/month
Multiple Earners - Per-Person Deductions
Household: 2 parents + 2 children, ENROLLED
Income: $800 + $400 = $1,200 total
BEM 518: "Apply separately to each program group member"
Parent 1: $800 - [$200 + 50%×$600] = $300 countable
Parent 2: $400 - [$200 + 50%×$200] = $100 countable
Total countable = $400
Payment Standard (size 4) = $707
Benefit = $707 - $400 = $307/month
Testing & Verification
Test Results
✅ All 66 tests passing
- 17 integration tests
- 49 unit tests
- 0 failures
Legal Verification
All formulas verified against:
- ✅ BEM 518 (BPB 2023-013, effective 7-1-2023)
- ✅ BEM 520 (BPB 2023-002, effective 1-1-2023)
- ✅ BEM 503 (BPB 2025-022, effective 10-1-2025)
- ✅ Michigan TANF State Plan 2017 (2008 frozen amounts)
- ✅ Michigan TANF State Plan 2025 (2024 increased amounts)
Recent Formula Corrections
Commit History
- ✅ Per-person deduction logic (each worker gets own $200)
- ✅ Dual-test system (20% eligibility, 50% benefit)
- ✅ Historical payment standards (2008 & 2025)
- ✅ Proper use of
addspattern - ✅ Verified against BEM manuals
🤖 Generated with Claude Code
Co-Authored-By: Claude [email protected]
Codecov Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 100.00%. Comparing base (ba52386) to head (a40f9bd).
:warning: Report is 42 commits behind head on master.
Additional details and impacted files
@@ Coverage Diff @@
## master #6812 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 2 11 +9
Lines 26 147 +121
==========================================
+ Hits 26 147 +121
| Flag | Coverage Δ | |
|---|---|---|
| unittests | 100.00% <100.00%> (ø) |
Flags with carried forward coverage won't be shown. Click here to find out more.
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.