Skip to content

Conversation

@hua7450
Copy link
Collaborator

@hua7450 hua7450 commented Nov 5, 2025

Summary

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

Closes #6790

Status

  • Parameters created (9 files)
  • Variables implemented (11 files)
  • Tests written (49 test cases across 6 files)
  • CI passing
  • Formulas verified against PAMMS regulations
  • 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 and others added 3 commits November 5, 2025 17:27
This commit adds a complete implementation of Georgia's Temporary Assistance
for Needy Families (TANF) program, including:

Parameters:
- Benefit standards (family maximum, standard of need, gross income ceiling)
- Income deductions (work expense, childcare, earned income disregard)
- Resource limits

Variables:
- Main benefit calculation (ga_tanf)
- Eligibility determination (income, resources, overall)
- Income calculations (earned, unearned, countable)
- Benefit standards calculations

Tests:
- 16 comprehensive integration test cases covering:
  - Various family sizes (1-5 members)
  - Earned and unearned income scenarios
  - Childcare deduction for different age groups
  - Earned income disregard (initial 4 months vs months 5-12)
  - Resource limit testing
  - Gross income ceiling testing
  - Two-parent households
  - SSI exclusions

Documentation:
- Complete documentation summary from official Georgia sources
- Working references for ongoing development

Integration fixes applied:
- Fixed test variable naming: ga_tanf_maximum_benefit → ga_tanf_family_maximum
- Removed Python cache files
- All variables consistently use SPMUnit entity

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Replace invalid .keys() method calls on parameter nodes with hardcoded
max_table_size value. The parameter structure has values for unit sizes
1-10, so we use 10 as the maximum table size.

This fixes ParameterNotFoundError that was preventing tests from running.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@codecov
Copy link

codecov bot commented Nov 5, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (6c8cb6a) to head (f048096).
⚠️ Report is 37 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##           master     #6791       +/-   ##
============================================
+ Coverage   72.92%   100.00%   +27.07%     
============================================
  Files        3252        11     -3241     
  Lines       46840       160    -46680     
  Branches      243         0      -243     
============================================
- Hits        34159       160    -33999     
+ Misses      12667         0    -12667     
+ Partials       14         0       -14     
Flag Coverage Δ
unittests 100.00% <100.00%> (+27.07%) ⬆️

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.

Fixes:
- Fix childcare deduction to use actual expenses capped at max per dependent
- Fix countable resources to properly access spm_unit_cash_assets
- Remove SSI from unearned income (correctly excluded from TANF)
- Remove ga_tanf_assistance_unit_size variable (use spm_unit_size directly)
- Update benefit standard variables to use spm_unit_size

Documentation:
- Document simplified implementation does not model time-based disregards
- Document simplified implementation does not exclude SSI recipients from unit size

Tests:
- Add 12 unit test files (52 test cases total)
- Update integration test expectations to match simplified implementation
- All 16 integration tests now passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@hua7450 hua7450 changed the title Add Georgia TANF (simple implementation) #6790 Add Georgia TANF (simple implementation) Nov 6, 2025
hua7450 and others added 4 commits November 10, 2025 15:02
Cleanup and standardization to align with Pennsylvania and Ohio TANF implementations.

Key changes:
- Remove unnecessary wrapper variables (ga_tanf_gross_earned_income, ga_tanf_gross_unearned_income)
- Use federal tanf_gross_earned_income and tanf_gross_unearned_income directly
- Flatten folder structure (remove income/earned and income/unearned subfolders)
- Add demographic and citizenship eligibility checks (was missing)
- Fix test files to use employment_income_before_lsr instead of employment_income
- Delete fragile unit tests that tested internal implementation details
- Keep integration tests and core functionality tests (48 tests)

Structure improvements:
- Variables: 16 → 14 files (removed 2 wrappers)
- Tests: 13 files (91 tests) → 6 files (48 tests)
- All 48 remaining tests passing

Eligibility fix:
- Added is_demographic_tanf_eligible check (minor child OR pregnant woman)
- Added is_citizen_or_legal_immigrant check (at least one citizen)
- Matches PA and OH TANF eligibility pattern

All tests passing (48/48).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…rameters

Changes:

1. Gross Income Ceiling Formula
   - Replace hardcoded table with 185% × Standard of Need formula
   - Add gross_income_ceiling_rate parameter (1.85)
   - Remove gross_income_ceiling and gross_income_ceiling_increment tables
   - Update ga_tanf_gross_income_ceiling variable to use formula
   - Per Ga. Comp. R. & Regs. 290-2-28-.02(j)

2. Earned Income Disregard Precision
   - Change percentage from 0.3333333333 to 0.33 for clarity
   - Update test expectations to match (Cases 10 & 12)

3. Parameter Folder Reorganization
   - Rename benefit_standards/ to financial_standards/
   - Create subfolders: standard_of_need/ and family_maximum/
   - Rename files: base.yaml and additional.yaml
   - Update all variable references to new parameter paths

4. Parameter Descriptions and Labels
   - Update descriptions to reflect "base" and "additional" naming
   - Change "multiplier" to "rate" for gross_income_ceiling_rate
   - Clarify "beyond size 10" for additional amounts
   - All descriptions follow parameter-architect rules

All 48 tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
After comprehensive review against PAMMS manual and Georgia regulations,
corrected multiple critical parameter errors that would have resulted in
incorrect benefit calculations.

## Critical Parameter Fixes

### 1. Work Expense Deduction ($90 → $250)
- **File**: income/deductions/work_expense.yaml
- **Regulation**: PAMMS Section 1615 and 1605
- **Impact**: $160/month difference affects ALL working families
- Correct value: $250 per employed individual

### 2. Removed Earned Income Disregard (Does Not Exist)
- **Deleted**: 4 parameter files + 1 variable file
- **Regulation**: PAMMS 1615 confirms NO $30 + 1/3 disregard in current GA policy
- **Impact**: Was overstating deductions, resulting in benefits too high
- Georgia does NOT use the traditional AFDC earned income disregard
- Only $250 work expense deduction applies

### 3. Standard of Need Values (7 out of 10 corrected)
- **File**: financial_standards/standard_of_need/base.yaml
- **Source**: PAMMS Appendix A (March 2025)
- **Corrected values**:
  - Size 2: $324 → $356 (+$32)
  - Size 4: $529 → $500 (-$29)
  - Size 5: $639 → $573 (-$66)
  - Size 6: $749 → $621 (-$128)
  - Size 7: $804 → $672 (-$132)
  - Size 8: $804 → $713 (-$91)
  - Size 9: $804 → $751 (-$53)

### 4. Family Maximum Values (7 out of 10 corrected)
- **File**: financial_standards/family_maximum/base.yaml
- **Source**: PAMMS Appendix A (March 2025)
- **Corrected values**:
  - Size 2: $188 → $235 (+$47)
  - Size 4: $364 → $330 (-$34)
  - Size 5: $447 → $378 (-$69)
  - Size 6: $530 → $410 (-$120)
  - Size 7: $530 → $444 (-$86)
  - Size 8: $530 → $470 (-$60)
  - Size 9: $530 → $496 (-$34)

## Additional Changes

### Code Cleanup
- Made `ga_tanf_countable_resources` empty variable (comment-only)
- Updated `ga_tanf_resources_eligible` to use `spm_unit_cash_assets` directly
- Deleted unused `vehicle_value_limit.yaml` parameter
- Updated `ga_tanf_countable_earned_income` to remove disregard logic

### Test Updates
- Completely rewrote integration tests with correct calculations
- Updated 16 test cases to reflect accurate policy
- Fixed resource eligibility tests to use correct input variable
- All 48 tests passing

### Documentation
- Updated working_references.md with corrected values
- Removed incorrect earned income disregard documentation
- Added critical corrections changelog entry
- Marked resolved questions about parameter sources

## Verification Sources

All corrections verified against:
- PAMMS Appendix A (March 2025 publication)
- PAMMS Section 1615 (Deductions)
- PAMMS Section 1605 (Basic Budgeting)
- PAMMS Section 1525 (Income)
- Ga. Comp. R. & Regs. 290-2-28-.02(j) (GIC formula)

## Impact Assessment

These corrections ensure:
- Working families receive accurate benefit calculations
- Income eligibility determinations match actual Georgia policy
- Formula-based GIC calculation per regulations
- Simplified resource eligibility (cash assets only)

All 48 tests passing after corrections.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Changed work expense deduction from SPM-unit level to person level per
PAMMS Section 1615: "$250 per employed individual"

## Formula Changes

### New Person-Level Variable
- Created `ga_tanf_earned_income_after_disregard.py` (Person entity)
- Applies $250 work expense at individual level
- Each employed person gets their own deduction

### Updated SPM-Unit Calculation
- Modified `ga_tanf_countable_income.py` to use correct order per PAMMS 1605:
  1. Sum person-level earned income (after work expense)
  2. Apply childcare deduction to earned income only
  3. Add unearned income (no deductions)
- Uses `add()` to sum person-level variables
- Properly implements PAMMS 1605 Step 8-9

### Deleted Obsolete Variables
- Removed `ga_tanf_countable_earned_income.py` (replaced by person-level)
- Removed `ga_tanf_countable_unearned_income.py` (now using federal variable via add())
- Removed `ga_tanf_work_expense_deduction.py` (work expense now at person level)

## Regulatory Alignment

Per PAMMS Section 1605 (13-step procedure):
- Step 8: "Apply deductions to each employed individual"
- Step 9: "Add unearned income to net earned income"
- "Deductions are not allowed to unearned income"

Per PAMMS Section 1615:
- "$250 is subtracted from the earned income of each employed individual"
- "Deductions applied in order: work expense, then childcare"

## Test Updates

### Rewrote Test Files
- `ga_tanf_countable_income.yaml`: 7 → 8 tests
  - Now tests person-level work expense
  - Tests two workers both getting $250 deduction
  - Tests childcare applies to earned only
  - Removed stubbing of deleted variables

- `ga_tanf_income_eligible.yaml`: 7 tests
  - Updated to use real inputs instead of stubbing
  - Tests complete calculation pipeline
  - Verifies both GIC and SON tests

### Updated References
- Added PAMMS 1605 and 1615 citations to all formulas
- Comments explain regulatory requirements
- Clear documentation of deduction order

## Impact

Example: Two working parents
- Parent 1: $600 earned → $600 - $250 = $350 countable
- Parent 2: $400 earned → $400 - $250 = $150 countable
- Total: $500 countable (vs $750 without proper person-level deduction)

All 49 tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@hua7450 hua7450 marked this pull request as ready for review November 11, 2025 15:53
Copy link
Collaborator

@PavelMakarchuk PavelMakarchuk left a comment

Choose a reason for hiding this comment

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

minor

description: Georgia adds this additional amount to the family maximum for each member beyond size 10 under the Temporary Assistance for Needy Families program.

values:
2025-03-01: 17
Copy link
Collaborator

Choose a reason for hiding this comment

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

need values that start on or before Jan. 1st 2025

reference:
- title: PAMMS TANF Policy Manual - Appendix A Financial Standards
href: https://pamms.dhs.ga.gov/dfcs/tanf/appendix-a/
publication_date: 2025-03-01
Copy link
Collaborator

Choose a reason for hiding this comment

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

I dont think this is valid, right?

period: month
label: GA TANF standard of need additional amount
reference:
- title: PAMMS TANF Policy Manual - Appendix A Financial Standards
Copy link
Collaborator

Choose a reason for hiding this comment

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

No legal code?

unit_size = spm_unit("spm_unit_size", period)

# Maximum amounts for units up to 10 people
max_table_size = 10
Copy link
Collaborator

Choose a reason for hiding this comment

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

same question as in other tanfs, should we hard-code this

Comment on lines +16 to +19
# For simplified implementation, use SPM unit cash assets
# In a more complete implementation, this would account for
# excluded resources (primary residence, household goods, etc.)
# and vehicle value limits
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this not be an adds of spm_unit_cash_assets for now?

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 Georgia TANF (simple implementation)

2 participants