Skip to content

Conversation

@hua7450
Copy link
Collaborator

@hua7450 hua7450 commented Nov 4, 2025

Summary

Implements Pennsylvania TANF (Temporary Assistance for Needy Families) cash assistance program with corrected income deduction formula per PA DHS policy.

Closes #6759

Status

  • Documentation collected
  • Parameters created (12 files)
  • Variables implemented (10 files)
  • Tests written (72 test cases across 9 files)
  • CI passing
  • Formula corrected to match PA DHS policy
  • Real-world validation completed
  • Ready for review (mark ready when you want review)

Key Changes

Implementation Summary

  • 10 new variables for PA TANF benefit calculation
  • 12 parameter files covering 4 county groups, FSA tables, Standard of Need, and deductions
  • 72 comprehensive test cases across 9 test files (13 integration + 59 unit tests)
  • Formula validated against real-world Just Harvest example
  • All tests passing

Correct Formula (Per PA DHS Cash Assistance Handbook Section 160.22)

For EID-eligible individuals (enrolled OR passes Standard of Need test):
  1. Apply 50% Earned Income Disregard to GROSS earned income
  2. Subtract $200 Work Expense Deduction
  
For non-EID-eligible individuals:
  Full earned income is countable (no deductions)
  
Monthly Benefit = MAX(Family Size Allowance - Countable Income, 0)

Formula Correction: Latest commit fixes deduction order to match PA DHS policy exactly. The $90 deduction is used only for EID eligibility testing, not benefit calculation.


Files Added

Parameters (12 files)

policyengine_us/parameters/gov/states/pa/dhs/tanf/
├── county_group/                                   # 4 files
│   ├── group_1.yaml
│   ├── group_2.yaml
│   ├── group_3.yaml
│   └── group_4.yaml
├── family_size_allowance/                          # 2 files
│   ├── additional_person.yaml                      # $83 increment for 7+
│   └── amount.yaml                                 # FSA by group (1-6 people)
├── income/
│   └── deductions/                                 # 3 files
│       ├── earned_income_disregard/
│       │   └── percentage.yaml                     # 50% disregard
│       └── work_expense/
│           ├── additional.yaml                     # $200 (WED)
│           └── initial.yaml                        # $90 (eligibility test only)
├── standard_of_need/                               # 2 files
│   ├── additional_person.yaml                      # $102 increment for 7+
│   └── amount.yaml                                 # Standard by group (1-6 people)
└── resource_limit.yaml                             # 1 file ($1,000)

Variables (10 files)

policyengine_us/variables/gov/states/pa/dhs/tanf/
├── eligibility/                                    # 4 files
│   ├── pa_tanf_disregard_eligible.py               # EID eligibility test
│   ├── pa_tanf_eligible.py                         # Overall eligibility
│   ├── pa_tanf_income_eligible.py                  # Income < FSA test
│   └── pa_tanf_resource_eligible.py                # Assets <= $1,000 test
├── income/                                         # 2 files
│   ├── pa_tanf_countable_income.py                 # Total countable income
│   └── pa_tanf_earned_income_after_deductions_person.py  # EID + WED per person
├── pa_tanf_county_group.py                         # Geographic group assignment
├── pa_tanf_maximum_benefit.py                      # FSA calculation
├── pa_tanf_standard_of_need.py                     # Standard of Need
└── pa_tanf.py                                      # Main benefit calculation

Tests (9 files, 72 test cases total)

policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/
├── eligibility/                                    # 4 files, 27 tests
│   ├── pa_tanf_disregard_eligible.yaml             # 8 tests
│   ├── pa_tanf_eligible.yaml                       # 6 tests
│   ├── pa_tanf_income_eligible.yaml                # 7 tests
│   └── pa_tanf_resource_eligible.yaml              # 6 tests
├── income/                                         # 2 files, 15 tests
│   ├── pa_tanf_countable_income.yaml               # 8 tests
│   └── pa_tanf_earned_income_after_deductions_person.yaml  # 7 tests
├── integration.yaml                                # 13 integration tests
├── pa_tanf_maximum_benefit.yaml                    # 11 tests (sizes 1-12)
└── pa_tanf.yaml                                    # 6 tests

Example Calculations

Real-World Verification: Just Harvest Example

Household: Family of 3 (1 parent, 2 children), enrolled in TANF
Income: $580/month employment income

Step 1: Apply 50% EID to gross income
        $580 × 50% = $290

Step 2: Subtract $200 WED
        $290 - $200 = $90 countable income

Step 3: Calculate benefit
        FSA for family of 3 = $403
        Benefit = $403 - $90 = $313/month
        
Total household income: $580 + $313 = $893/month ✓ VERIFIED

Source: Just Harvest - PA TANF Policy Analysis (Sept 2020)

Multiple Earners Example

Household: Family of 4 (2 parents, 2 children), both working
Income: Parent 1 = $1,000/month, Parent 2 = $800/month

Parent 1: $1,000 × 50% - $200 = $300 countable
Parent 2: $800 × 50% - $200 = $200 countable
Total countable: $500

FSA for family of 4 = $497
Income exceeds FSA → Benefit = $0

Testing & Verification

Test Results

✅ All 72 tests passing across 9 test files
   - 13 integration tests
   - 59 unit tests
   - 0 failures

Test Coverage Breakdown

Test File Count Purpose
integration.yaml 13 End-to-end scenarios
pa_tanf_maximum_benefit.yaml 11 FSA for sizes 1-12
pa_tanf_disregard_eligible.yaml 8 EID eligibility rules
pa_tanf_countable_income.yaml 8 Income calculations
pa_tanf_income_eligible.yaml 7 Income thresholds
pa_tanf_earned_income_after_deductions_person.yaml 7 Deduction steps
pa_tanf.yaml 6 Main benefit formula
pa_tanf_eligible.yaml 6 Overall eligibility
pa_tanf_resource_eligible.yaml 6 Resource limits
Total 72

How to Run Tests

# All PA TANF tests
policyengine-core test policyengine_us/tests/policy/baseline/gov/states/pa/dhs/tanf/ -c policyengine_us

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

Implementation Highlights

Key Features Implemented

  • ✅ Family Size Allowance (FSA) by county group (4 groups supported)
  • ✅ Earned income deductions (50% EID + $200 WED)
  • ✅ Earned Income Disregard (EID) eligibility rules
  • ✅ Standard of Need test for new applicants
  • ✅ Resource limits ($1,000)
  • ✅ Demographic eligibility (using federal TANF rules)
  • ✅ Self-employment income support
  • ✅ Multiple earner households

Geographic Variations

Pennsylvania has 4 benefit groups implemented (5 groups exist, Group 5 TBD):

  • Group 1: $421/month (family of 3) - Highest
  • Group 2: $403/month (family of 3) - Philadelphia (default)
  • Group 3: $393/month (family of 3)
  • Group 4: $365/month (family of 3)

Design Decisions

  1. Vectorization: All formulas use where(), max_(), min_() for proper array handling
  2. Per-person deductions: Each person's earned income processed individually, then summed
  3. Federal rule reuse: Uses is_demographic_tanf_eligible and is_citizen_or_legal_immigrant from federal TANF
  4. County default: GROUP_2 (Philadelphia) used if county not specified

Known Limitations & Future Enhancements

Not Yet Implemented

  1. Child care deductions (55 Pa. Code § 181.311) - Can be added as enhancement
  2. 60-month lifetime limit - Requires time-series tracking
  3. County Group 5 - Needs additional research for benefit amounts
  4. Personal expense deductions - For incapacitated adult care
  5. Sanction tracking - Sanctioned members can still receive WED if EID eligible

Simplified Assumptions

  • County defaults to GROUP_2 if not specified
  • Uses federal demographic eligibility rules
  • is_tanf_enrolled boolean (no historical tracking)
  • Monthly calculations (4.0 weekly multiplier handled at input level)

References

Official Government Sources

Real-World Validation

Research Sources


Branch Information

Branch: pa-tanf-simple
Base: master
Status: ✅ Formula corrected, all 72 tests passing, ready for review


Recent Changes (Commit f073110)

Formula Correction

Issue: Original implementation applied income deductions in wrong order
Fix: Corrected to match PA DHS Cash Assistance Handbook Section 160.22

Before (incorrect):

$1,000 - $90 = $910
$910 × 50% = $455
$455 - $200 = $255 countable

After (correct):

$1,000 × 50% = $500 (EID to gross income)
$500 - $200 = $300 countable

Impact:

  • Formula now matches PA DHS policy exactly
  • Over-estimated benefits by ~$45/month in old formula
  • All 72 test values recalculated and verified
  • Real-world Just Harvest example validates correctness

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

Starting implementation of Pennsylvania TANF.
Documentation and development will follow.

Related to PolicyEngine#6759
hua7450 and others added 2 commits November 4, 2025 03:35
- Change pa_tanf_max_benefit to pa_tanf_maximum_benefit
- This aligns test variable names with actual implementation
- All test files now reference correct variable names
Implement Pennsylvania TANF program with eligibility rules, income calculations, and benefit determination following PA DHS regulations.

Key components:
- Eligibility: demographic, income, and resource tests
- Income: earned and unearned income with PA-specific deductions
- Benefits: family size-based calculations with countable income reductions
- Parameters: benefit amounts, deductions, child care costs, time limits
- Integration tests covering various household scenarios

Updated federal TANF variable to include PA state program.

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

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

codecov bot commented Nov 4, 2025

Codecov Report

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

Additional details and impacted files
@@             Coverage Diff              @@
##           master     #6764       +/-   ##
============================================
+ Coverage   72.92%   100.00%   +27.07%     
============================================
  Files        3252        12     -3240     
  Lines       46840       189    -46651     
  Branches      243         0      -243     
============================================
- Hits        34159       189    -33970     
+ 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.

hua7450 and others added 5 commits November 4, 2025 03:51
This commit adds unit tests for all PA TANF variables with formulas, testing edge cases and boundary conditions:

- pa_tanf.yaml: Tests benefit calculation with various income levels
- pa_tanf_maximum_benefit.yaml: Tests benefit amounts for household sizes 1-12
- Income tests:
  - pa_tanf_countable_income.yaml: Tests earned/unearned income calculation
  - pa_tanf_earned_income_deductions.yaml: Tests deduction steps and edge cases
  - pa_tanf_gross_earned_income.yaml: Tests employment and self-employment income aggregation
  - pa_tanf_gross_unearned_income.yaml: Tests Social Security and unemployment income aggregation
- Eligibility tests:
  - pa_tanf_eligible.yaml: Tests combination of demographic, income, and resource requirements
  - pa_tanf_income_eligible.yaml: Tests income threshold boundaries
  - pa_tanf_resource_eligible.yaml: Tests asset limit boundaries
  - pa_tanf_demographic_eligible.yaml: Tests federal demographic eligibility passthrough

Also simplified integration.yaml to focus on realistic scenarios rather than edge cases, which are now covered in unit tests.

All 107 tests pass.

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

Co-Authored-By: Claude <[email protected]>
Major changes:
- Use federal variables directly (is_demographic_tanf_eligible, is_citizen_or_legal_immigrant, tanf_gross_earned_income, tanf_gross_unearned_income)
- Fix federal TANF parameter typo (employment_income_before_lrs → employment_income_before_lsr)
- Restructure parameters to follow DC/IL TANF pattern (one parameter per file, proper folder hierarchy)
- Change all variables to MONTH period (was incorrectly YEAR)
- Fix income eligibility 12x multiplication bug
- Remove prohibited variables for simplified TANF (demographic wrapper, gross income variables, age eligibility)
- Remove unnecessary metadata (household: false, economy: false from resource_limit)
- Delete orphaned parameters (age limits, time limits, pregnancy eligibility)
- Clean up empty folders and misplaced test files

This implements a clean, minimal PA TANF following established PolicyEngine
patterns and simplified TANF rules.

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

Co-Authored-By: Claude <[email protected]>
This comprehensive refactoring applies all rules-engineer, parameter-architect,
and test-creator guidelines systematically.

Key changes:
- Remove all documentation fields from variables (rules: label is sufficient)
- Add proper legal code URL references to all variables
- Restructure parameters following DC/IL TANF pattern (one parameter per file)
- Implement person-level earned income deductions (like DC/TX TANF)
- Add applicant vs recipient distinction for 50% disregard (uses is_tanf_enrolled)
- Add county group support (all 4 PA groups with 67 counties mapped)
- Add Standard of Need parameter (for future disregard eligibility test)
- Fix all test files to follow test-creator rules (Case N naming, person1/person2, 2024-01 period)
- Change all variables to MONTH period and fix all test values
- Use resources with period.this_year (stock variables)
- Remove household/economy metadata flags from resource_limit

Variables: 8 files (added pa_tanf_county_group, person-level deductions)
Parameters: 13 files (added county groups, standard of need, restructured)
Tests: 8 files (all 60 tests passing)

Follows simplified TANF rules:
- Uses federal demographic/immigration eligibility directly
- Uses federal tanf_gross_earned/unearned_income
- Person-level deductions aggregated to SPMUnit
- No prohibited wrapper variables

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

Co-Authored-By: Claude <[email protected]>
- Add pa_tanf_standard_of_need variable (county group-based lookup)
- Add pa_tanf_disregard_eligible variable (implements 55 Pa. Code § 183.94)
- Implement Standard of Need test for new applicants (enrolled get automatic eligibility)
- Move tests to correct location (pa/tanf → pa/dhs/tanf)
- Delete unused child_care parameter (not implemented in simplified version)
- Simplify changelog entry per guidance
- Clean up formulas (remove unnecessary intermediate variables, imports)
- Use enum values as parameter keys (following TX CCS pattern)

All 68 tests passing.

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

Co-Authored-By: Claude <[email protected]>
hua7450 added a commit to hua7450/policyengine-us that referenced this pull request Nov 4, 2025
**Structure Improvements:**
- Organize variables into eligibility/ and income/ subfolders
- Organize parameters into income/deductions/ subfolder
- Follows pattern from PA TANF implementation (PR PolicyEngine#6764)

**Simplifications:**
- Remove state-specific earned income variable
- Remove income/earned.yaml parameter list
- Directly aggregate employment_income + self_employment_income
- Use federal tanf_gross_unearned_income variable
- Update parameter path: income.deductions.earned_income_disregard

**Files Deleted:**
- oh_tanf_gross_earned_income.py (no longer needed)
- income/earned.yaml (use federal sources directly)

**Files Moved:**
Variables:
- oh_tanf_eligible.py → eligibility/
- oh_tanf_income_eligible.py → eligibility/
- oh_tanf_countable_income.py → income/

Parameters:
- earned_income_disregard.yaml → income/deductions/

All 63 tests still passing.
hua7450 and others added 5 commits November 4, 2025 18:24
Reorganizes PA TANF parameters into clearer folder structure following DC TANF pattern, and updates all parameter references to include specific legal code subsections and authoritative policy manual citations.

Changes:
- Reorganize parameters into payment_standard/ and standard_of_need/ folders
- Add specific subsection numbers to all legal code citations (e.g., 55 Pa. Code § 183.94(a)(1))
- Ensure all parameters have exactly two references (legal code + policy manual)
- Update variable formulas to use new parameter paths
- Fix parameter descriptions to accurately reflect base size (6, not 8)
- Fix test comments to show correct increment calculations

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

Co-Authored-By: Claude <[email protected]>
Reorganizes parameter structure for better clarity and updates all variable
formulas to reference the new paths.

Parameter changes:
- Rename payment_standard/ to family_size_allowance/
- Rename increment to additional_person for both family_size_allowance and standard_of_need
- Consolidate work expenses under work_expense/ folder (initial.yaml and additional.yaml)
- Update $200 additional work expense reference to correct administrative policy source
- Fix effective date from 2020-09-26 to 2020-09-28
- Update county group references and dates to 2001-01-01

Variable updates:
- Update pa_tanf_maximum_benefit.py to use family_size_allowance paths
- Update pa_tanf_standard_of_need.py to use additional_person
- Update pa_tanf_earned_income_after_deductions_person.py to use work_expense paths
- Update pa_tanf_disregard_eligible.py to use work_expense.initial

All 68 tests pass successfully.

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

Co-Authored-By: Claude <[email protected]>
Corrects the order of income deductions to match PA DHS policy:
- Apply 50% EID to GROSS earned income (not after $90 deduction)
- Then subtract $200 WED (only if EID eligible)
- $90 deduction used only for EID eligibility test, not benefit calculation

Per PA DHS Cash Assistance Handbook Section 160.22:
"If the individual is eligible for the EID, calculate and subtract the EID
and subsequently subtract the $200 WED."

Changes:
- Updated pa_tanf_earned_income_after_deductions_person.py with correct formula
- Fixed all test expected values to match corrected calculations
- Added 3 production test cases:
  * Multiple earners (two-parent household)
  * County Group 1 (geographic variation)
  * Self-employment income
- Verified against real-world Just Harvest example ($313 benefit, $893 total)

All 72 tests passing (13 integration, 59 unit tests).

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

Co-Authored-By: Claude <[email protected]>
@hua7450 hua7450 changed the title Add Pennsylvania TANF (simple implementation) Implement Pennsylvania TANF with corrected income deduction formula Nov 10, 2025
@hua7450 hua7450 marked this pull request as ready for review November 10, 2025 19:30
@hua7450 hua7450 changed the title Implement Pennsylvania TANF with corrected income deduction formula Implement Pennsylvania TANF Nov 10, 2025
hua7450 and others added 3 commits November 11, 2025 09:26
- Rename pa_tanf_resource_eligible to pa_tanf_resources_eligible (plural)
- Create pa_tanf_countable_earned_income variable (SPM unit level)
- Create pa_tanf_countable_unearned_income variable (SPM unit level)
- Update pa_tanf_countable_income to use adds pattern instead of formula
- Update all test references to use new variable names

All 72 tests passing.

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

Co-Authored-By: Claude <[email protected]>
hua7450 added a commit to hua7450/policyengine-us that referenced this pull request Nov 11, 2025
Applies code quality improvements from PA TANF (PolicyEngine#6764) and OH OWF (PolicyEngine#6788):

Code Structure:
- Delete 3 unnecessary intermediate variables with no state-specific logic
- Use federal TANF variables directly via add() helper (OH pattern)
- Add demographic and citizenship eligibility checks (PA/OH pattern)
- Change defined_for to "wa_tanf_eligible" (PA/OH pattern)

Comments & Documentation:
- Add direct WAC regulation quotes in all formulas
- Add step-by-step calculation breakdowns
- Improve variable naming (remainder_after_flat_disregard)
- Add policy context explaining WHY not just WHAT

Parameters:
- Reorder structure: description → values → metadata (OH pattern)
- Remove publication_date field (PA/OH don't use it)
- Clean up reference titles (remove quotes)

Tests:
- Add is_tax_unit_dependent: true for all children (OH pattern)
- Fix demographic eligibility tests to include all 4 requirements
- Fix single person test (must be pregnant for TANF eligibility)
- Update to use federal tanf_gross_* variables

Impact:
- Deleted 5 files (3 variables, 2 tests)
- Modified 17 files (6 variables, 6 parameters, 5 tests)
- All 59 tests passing (was 75 with redundant tests)
- Now fully aligned with PA/OH implementation patterns

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

Co-Authored-By: Claude <[email protected]>
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 Pennsylvania TANF (Temporary Assistance for Needy Families)

1 participant