policyengine-us icon indicating copy to clipboard operation
policyengine-us copied to clipboard

Add Georgia TANF (simple implementation)

Open hua7450 opened this issue 4 months ago • 1 comments

Summary

Implements Georgia TANF (Temporary Assistance for Needy Families) cash assistance program with formulas verified against PAMMS policy manual.

Closes #6790

Status

  • [x] Parameters created (9 files)
  • [x] Variables implemented (11 files)
  • [x] Tests written (49 test cases across 6 files)
  • [x] CI passing
  • [x] Formulas verified against PAMMS regulations
  • [x] Ready for review

Key Changes

Implementation Summary

  • 11 new variables for GA TANF benefit calculation
  • 9 parameter files covering financial standards, deductions, and resource limits
  • 49 comprehensive test cases across 6 test files (16 integration + 33 unit tests)
  • Formulas verified against PAMMS Sections 1605 and 1615
  • All tests passing

Formula (Per PAMMS Sections 1605 and 1615)

Work Expense: $250 per employed individual (person level)

# Per person (PAMMS 1615: "for each employed individual")
net_earned = max(gross_earned - $250, 0)

# Per SPM unit
total_net_earned = sum(all person.net_earned) - childcare

Childcare Deduction: Applied to earned income only

  • Up to $200/month per child under age 2
  • Up to $175/month per child age 2 or older

Unearned Income: No deductions (full amount countable)

# PAMMS 1605: "Deductions are not allowed to unearned income"
countable_income = net_earned + unearned

Benefit Calculation (PAMMS 1605 Steps 11-13):

deficit = SON - countable_income
benefit = MIN(deficit, family_maximum)
benefit = MAX(benefit, 0)  # Can't be negative

Two-Tier Income Eligibility (PAMMS 1605 Steps 6 & 11):

  • Gross income ≤ Gross Income Ceiling (185% × SON)
  • Countable income < Standard of Need

Files Added

Parameters (9 files)

policyengine_us/parameters/gov/states/ga/dfcs/tanf/
├── financial_standards/
│   ├── standard_of_need/
│   │   ├── base.yaml                       # March 2025 values (sizes 1-10)
│   │   └── additional.yaml                 # $24 increment for 11+
│   ├── family_maximum/
│   │   ├── base.yaml                       # March 2025 values (sizes 1-10)
│   │   └── additional.yaml                 # $17 increment for 11+
│   └── gross_income_ceiling_rate.yaml      # 185% (formula-based)
├── income/deductions/
│   ├── work_expense.yaml                   # $250 per employed individual
│   └── childcare.yaml                      # $200/<2, $175/≥2
└── resources/
    └── limit.yaml                          # $1,000 cash assets

Variables (11 files)

policyengine_us/variables/gov/states/ga/dfcs/tanf/
├── benefit_standards/
│   ├── ga_tanf_standard_of_need.py
│   ├── ga_tanf_family_maximum.py
│   └── ga_tanf_gross_income_ceiling.py     # Formula: SON × 1.85
├── eligibility/
│   ├── ga_tanf_eligible.py
│   ├── ga_tanf_income_eligible.py          # Two tests: GIC + SON
│   └── ga_tanf_resources_eligible.py
├── income/
│   ├── ga_tanf_countable_income.py
│   ├── ga_tanf_earned_income_after_disregard.py  # Person-level work expense
│   └── deductions/
│       └── ga_tanf_childcare_deduction.py
├── ga_tanf_countable_resources.py          # Empty (comment-only)
└── ga_tanf.py                              # Main benefit

Tests (6 files, 49 test cases)

policyengine_us/tests/policy/baseline/gov/states/ga/dfcs/tanf/
├── integration.yaml (16 tests)
├── ga_tanf.yaml (10 tests)
├── ga_tanf_countable_income.yaml (8 tests)
├── eligibility/
│   ├── ga_tanf_income_eligible.yaml (7 tests)
│   ├── ga_tanf_eligible.yaml (4 tests)
│   └── ga_tanf_resources_eligible.yaml (4 tests)

Example Calculations

Working Single Parent

Household: Single parent with 2 children
Income: $500/month employment income + $100/month child support

Step 1: Gross Income Ceiling test (PAMMS 1605 Step 6)
        GIC = $424 × 1.85 = $784.40
        Gross: $500 + $100 = $600 < $784.40 ✅

Step 2: Calculate countable income (PAMMS 1605 Step 8-9)
        Earned after work: $500 - $250 = $250
        Unearned: $100 (no deductions)
        Countable: $250 + $100 = $350

Step 3: Net Income test (PAMMS 1605 Step 11)
        SON = $424
        $350 < $424 ✅ ELIGIBLE

Step 4: Calculate benefit (PAMMS 1605 Step 13)
        Deficit: $424 - $350 = $74
        Family Max: $280
        Benefit = MIN($74, $280) = $74/month

Total household income: $600 + $74 = $674/month

Low Income (Full Benefit)

Household: Family of 2
Income: $200/month earned income

Gross: $200 < GIC ($658.60) ✅
Countable: max($200 - $250, 0) = $0
Net test: $0 < $356 ✅
Benefit: MIN($356 - $0, $235) = $235/month (maximum)

Total: $200 + $235 = $435/month

Two Working Parents (Over GIC)

Household: Family of 3 (2 parents, 1 child)
Income: Parent 1 = $600/month, Parent 2 = $400/month

Work expense (person-level):
  Parent 1: $600 - $250 = $350
  Parent 2: $400 - $250 = $150
  Total net earned: $500

Gross: $1,000
GIC: $424 × 1.85 = $784.40
Gross test: $1,000 > $784.40 ❌ FAILS
→ INELIGIBLE

Testing & Verification

Test Results

✅ All 49 tests passing across 6 test files
   - 16 integration tests
   - 33 unit tests
   - 0 failures

Coverage Highlights

  • ✅ All PAMMS 1605 calculation steps (6, 8, 9, 11, 13)
  • ✅ Person-level work expense ($250 per employed individual)
  • ✅ Childcare applies to earned only
  • ✅ Unearned income no deductions
  • ✅ Two-tier income eligibility (gross + net)
  • ✅ Formula-based GIC (185% × SON)
  • ✅ Family sizes 1-5 (parameters support 1-10+)
  • ✅ Multiple earners, mixed income, childcare scenarios

How to Run

# All tests
policyengine-core test policyengine_us/tests/policy/baseline/gov/states/ga/dfcs/tanf/ -c policyengine_us

# Integration only
policyengine-core test policyengine_us/tests/policy/baseline/gov/states/ga/dfcs/tanf/integration.yaml -c policyengine_us

Implementation Highlights

Key Features

  • ✅ Standard of Need and Family Maximum by family size (1-10+)
  • ✅ Formula-based Gross Income Ceiling (185% × SON)
  • ✅ Work expense deduction ($250 per employed individual)
  • ✅ Childcare deductions (age-based limits)
  • ✅ Resource limits ($1,000 cash assets)
  • ✅ Two-tier income eligibility tests
  • ✅ Proper vectorization throughout

Design Decisions

  1. Person-Level Work Expense

    • Applied individually: each working person gets $250
    • Matches PAMMS 1615: "for each employed individual"
    • Enables accurate multi-earner household calculations
  2. Formula-Based GIC

    • Calculates dynamically: GIC = SON × 1.85
    • Not hardcoded table (more maintainable)
    • Per Ga. Comp. R. & Regs. 290-2-28-.02(j)
  3. Simpler Than PA/OH

    • No conditional disregard eligibility (unlike PA TANF)
    • No FPL-based initial test (unlike OH OWF)
    • Straightforward: $250 work expense + childcare
  4. Order of Operations (PAMMS 1605)

    • Step 8: Work expense at person level
    • Step 8: Childcare to earned income only
    • Step 9: Add unearned (no deductions)
    • Step 11: Compare countable to SON
    • Step 13: Apply family maximum cap
  5. Federal Rule Reuse

    • Uses tanf_gross_earned_income (federal)
    • Uses tanf_gross_unearned_income (federal)
    • Uses is_demographic_tanf_eligible (federal)
    • Uses is_citizen_or_legal_immigrant (federal)
    • Maintains cross-state consistency

Known Limitations & Future Enhancements

Not Yet Implemented

  1. 48-month lifetime limit - Requires time tracking
  2. SSI recipient exclusions - Uses spm_unit_size (includes all members)
  3. Vehicle value limits - Simplified to cash assets only
  4. Work requirement tracking - Assumes compliance
  5. Income allocation rules - For non-AU members

Simplified Assumptions

  • Uses spm_unit_size directly (doesn't exclude SSI recipients)
  • Cash assets only for resource test
  • No time-based tracking
  • Assumes work compliance

References

Primary Sources


Branch Information

Branch: ga-tanf-simple
Base: master
Status: ✅ All formulas verified against PAMMS, 49 tests passing


Implementation by: @hua7450
Issue: #6790
Ready for: Code review and testing feedback

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

hua7450 avatar Nov 05 '25 22:11 hua7450

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 (5c26438). :warning: Report is 42 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##            master     #6791    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            2        10     +8     
  Lines           26       153   +127     
==========================================
+ Hits            26       153   +127     
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.

codecov[bot] avatar Nov 05 '25 23:11 codecov[bot]