Skip to content

Conversation

@hua7450
Copy link
Collaborator

@hua7450 hua7450 commented Nov 11, 2025

Summary

Implements Washington State Temporary Assistance for Needy Families (TANF) program with complete parameterization and comprehensive testing following PA TANF and OH OWF quality standards.

Closes #6819

Status

  • Documentation collected
  • Parameters created (7 files)
  • Variables implemented (8 files)
  • Tests written (59 test cases across 7 files)
  • All tests passing
  • Formulas verified against Washington Administrative Code
  • Code refactored to match PA/OH patterns
  • All references verified to show actual values
  • Ready for review

Key Changes

Implementation Summary

  • 8 variables for WA TANF benefit calculation
  • 7 parameter files with clean PA/OH-style structure
  • 59 comprehensive test cases across 7 test files (19 integration + 40 unit tests)
  • All formulas verified against Washington Administrative Code (WAC)
  • All references verified to actually show the parameter values
  • Zero unnecessary intermediate variables (OH pattern)
  • Complete eligibility checks (PA pattern)
  • Historical data preserved with proper legislative citations

Formula (Per WAC 388-450-0170 and WAC 388-450-0162)

Earned Income Disregard: "$500 + 50% of Remainder"

# Step 1: Deduct flat $500 family earnings disregard
remainder = max(gross_earned - $500, 0)

# Step 2: Disregard 50% of remaining income
amount_disregarded = remainder × 0.5

# Step 3: Calculate countable earned income
countable_earned = remainder - amount_disregarded

Income Eligibility Limit: Derived from break-even point

Income Limit = (Payment Standard × 2) + $500
# Where countable income = payment standard, resulting in $0 benefit

Unearned Income: No disregards (full amount countable)

Benefit Calculation:

benefit = MIN(
    MAX(payment_standard - countable_income, 0),
    $1,338  # maximum grant cap
)

Files Added

Parameters (7 files) - Clean PA/OH structure

policyengine_us/parameters/gov/states/wa/dshs/tanf/
├── income/
│   ├── deductions/
│   │   └── earned_income_disregard/
│   │       ├── amount.yaml                         # $500 flat disregard
│   │       └── percentage_disregarded.yaml         # 50% of remainder
│   └── limit.yaml                                  # Income limits (formula-derived)
├── payment_standard/
│   ├── amount.yaml                                 # By size: $450-$1,662
│   └── maximum_amount.yaml                         # $1,338 cap
├── resource_limit.yaml                             # $6,000 → $12,000 (HB 1447)
└── maximum_family_size.yaml                        # 10

Variables (8 files) - Following PA/OH patterns

policyengine_us/variables/gov/states/wa/dshs/tanf/
├── benefit/
│   └── wa_tanf_payment_standard.py                 # Payment standards by size
├── eligibility/
│   ├── wa_tanf_eligible.py                         # All 4 requirements
│   └── wa_tanf_income_eligible.py                  # Income < limit test
├── income/
│   ├── wa_tanf_countable_earned_income.py          # $500 + 50% disregard
│   └── wa_tanf_countable_income.py                 # Total countable (uses adds)
├── wa_tanf_countable_resources.py                  # Resource calculation
├── wa_tanf_resources_eligible.py                   # Assets <= $12,000 test
└── wa_tanf.py                                      # Main benefit calculation

Tests (7 files, 59 test cases total)

policyengine_us/tests/policy/baseline/gov/states/wa/dshs/tanf/
├── benefit/
│   └── wa_tanf_payment_standard.yaml               # 6 tests
├── eligibility/
│   ├── wa_tanf_eligible.yaml                       # 6 tests
│   └── wa_tanf_income_eligible.yaml                # 9 tests
├── income/
│   └── wa_tanf_countable_earned_income.yaml        # 8 tests
├── integration.yaml                                # 19 integration tests
├── wa_tanf.yaml                                    # 9 benefit tests
└── wa_tanf_resources_eligible.yaml                 # 2 resource tests

Example Calculations

Basic Example: Family of 3 with Earned Income

Household: Single parent with 2 children
Income: $1,000/month employment income

Payment Standard: $706/month

Earned Income Disregard:
  $1,000 - $500 = $500 (remainder)
  $500 × 50% = $250 (disregarded)
  Countable: $500 - $250 = $250/month

Benefit: $706 - $250 = $456/month
Total household income: $1,000 + $456 = $1,456/month

Low Income Example: Under $500/month

Household: Family of 2
Income: $400/month earned

Payment Standard: $570/month

Earned Income Disregard:
  $400 - $500 = -$100 (clipped to $0)
  Countable: $0 (all income disregarded)

Benefit: $570 - $0 = $570/month (maximum)
Total household income: $400 + $570 = $970/month

Key Insight: All earned income under $500/month is fully disregarded!

Maximum Grant Cap: Large Family

Household: Family of 10
Income: $800/month earned

Payment Standard: $1,662/month
Maximum Grant Cap: $1,338/month

Earned Income Disregard:
  $800 - $500 = $300
  $300 × 50% = $150 (disregarded)
  Countable: $150

Benefit before cap: $1,662 - $150 = $1,512
Benefit after cap: MIN($1,512, $1,338) = $1,338/month

Testing & Verification

Test Results

✅ All 59 tests passing across 7 test files
   - 19 integration tests
   - 40 unit tests
   - 0 failures

============================== 59 passed in 5.90s ==============================

Test Coverage Breakdown

Test File Count Purpose
integration.yaml 19 End-to-end realistic scenarios
wa_tanf.yaml 9 Main benefit formula
wa_tanf_income_eligible.yaml 9 Income limit thresholds
wa_tanf_countable_earned_income.yaml 8 Earned income disregard
wa_tanf_payment_standard.yaml 6 Payment standards by size
wa_tanf_eligible.yaml 6 Overall eligibility (all 4 requirements)
wa_tanf_resources_eligible.yaml 2 Resource limits ($6K/$12K)
Total 59

How to Run Tests

# All WA TANF tests
policyengine-core test policyengine_us/tests/policy/baseline/gov/states/wa/dshs/tanf/ -c policyengine_us

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

Implementation Highlights

Key Features

  • ✅ Payment standards for all family sizes (1-10)
  • Maximum grant cap ($1,338) - Unique to Washington
  • ✅ Earned income disregard ($500 + 50% of remainder)
  • Income limit formula: Break-even point at (Payment Std × 2) + $500
  • ✅ Resource limits with historical tracking ($6,000 → $12,000 via HB 1447)
  • ✅ Demographic eligibility (federal TANF rules)
  • ✅ Citizenship requirements (at least one citizen/qualified immigrant)
  • ✅ Uses federal TANF variables directly (OH pattern)

Design Decisions

  1. Follows OH Pattern: Uses federal variables directly

    • add(spm_unit, period, ["tanf_gross_earned_income"])
    • No unnecessary intermediate aggregation variables
    • Cleaner code, fewer files
  2. Follows PA Pattern: Comprehensive eligibility checks

    • Checks is_demographic_tanf_eligible
    • Checks is_citizen_or_legal_immigrant
    • Uses defined_for = "wa_tanf_eligible"
  3. Parameter Structure: Clean, flat organization

    • Removed "eligibility" folder nesting
    • Renamed "benefit" → "payment_standard" (OH pattern)
    • Grouped deductions under income/deductions/ (PA/OH pattern)
    • Resource limit at root level (PA pattern)
  4. Verified References: All parameter references actually show values

    • Followed Parameter Architect agent rules
    • Two references per parameter (where available)
    • Removed references that don't contain values
    • Added legislative citations (HB 1447 for $12,000 increase)
  5. Formula Documentation: Income limits explained as break-even points

    • Mathematical relationship to payment standards documented
    • Preserves table structure per WAC (not calculated dynamically)

Known Limitations & Future Enhancements

Not Yet Implemented

  1. Dependent care deductions (WAC 388-450-0170(4)) - Variable amounts by hours worked
  2. Child support pass-through (currently $50-$100, changing to 100% in 2026)
  3. 60-month lifetime limit - Requires time-series tracking
  4. Work requirements - WorkFirst participation tracking
  5. Sanction tracking - Benefit reductions for non-compliance

Simplified Assumptions

  • Uses federal demographic eligibility rules
  • Resources calculated but not fully implemented (variable is empty)
  • Monthly calculations only
  • No historical tracking of benefit receipt

References

Official Government Sources

Legislative Sources

DSHS Policy Manuals

State Plans


Branch Information

Branch: wa-tanf-simple
Remote: origin/integration/wa-tanf-2025-11-11
Base: master
Status: ✅ All 59 tests passing, ready for review


Implementation by: @hua7450
Issue: #6819

🤖 Generated with Claude Code

Starting implementation of Washington State TANF program.
Documentation and parallel development will follow.

Related issues: PolicyEngine#2858, PolicyEngine#1359, PolicyEngine#2205, PolicyEngine#2206, PolicyEngine#2207

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

Co-Authored-By: Claude <[email protected]>
@hua7450 hua7450 mentioned this pull request Nov 11, 2025
hua7450 and others added 4 commits November 11, 2025 12:09
Created 20 integration test scenarios for WA TANF covering:
- Single parent families with varying income levels
- Two-parent families (one and two earners)
- Various family sizes (1-10 people)
- Earned income with $500 disregard and 50% work incentive
- Unearned income (no disregards)
- Mixed earned and unearned income
- Maximum grant cap testing ($1,338 for 8+ members)
- Income threshold boundary testing
- Self-employment income scenarios

Tests validate:
- wa_tanf_payment_standard (by family size)
- wa_tanf_countable_income (with disregards)
- wa_tanf_eligible (eligibility determination)
- wa_tanf (final benefit amount)

All calculations documented with comments showing:
- Payment standards from WAC 388-478-0020
- Income calculation: (Gross - $500) × 0.5
- Benefit formula: Payment Standard - Countable Income
- Maximum grant cap application

Related to issue PolicyEngine#6819 and PR PolicyEngine#6818

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

Co-Authored-By: Claude <[email protected]>
This implementation adds Washington State TANF (Temporary Assistance for Needy Families) benefit calculation with ZERO hard-coded values, following issue PolicyEngine#6819.

Variables implemented:
- wa_tanf.py - Main benefit amount with maximum grant cap
- wa_tanf_eligible.py - Overall eligibility combining income and resources
- wa_tanf_income_eligible.py - Income eligibility test against gross earned income limits
- wa_tanf_payment_standard.py - Payment standard by family size (1-10+)
- wa_tanf_countable_income.py - Total countable income combining earned and unearned
- wa_tanf_countable_earned_income.py - Earned income with $500 disregard and 50% work incentive
- wa_tanf_countable_unearned_income.py - Unearned income without disregards
- wa_tanf_gross_earned_income.py - Household gross earned income
- wa_tanf_gross_unearned_income.py - Household gross unearned income

Parameters created:
- Payment standards by family size (WAC 388-478-0020, effective Jan 1, 2024)
- Maximum grant cap of $1,338 for units with 8+ members
- Gross earned income limits by family size (WAC 388-478-0035, effective Aug 1, 2024)
- Earned income disregard of $500 (WAC 388-450-0170)
- Work incentive percentage of 50% (WAC 388-450-0170)
- Resource limit updated to $12,000 (WAC 388-470-0045, effective Feb 1, 2024)

Benefit calculation formula:
1. Countable Earned Income = (Gross Earned Income - $500) × 0.5
2. Total Countable Income = Countable Earned Income + Unearned Income
3. Grant Amount = Payment Standard - Total Countable Income (capped at $1,338)

All values are fully parameterized with proper references to Washington Administrative Code (WAC).

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

Co-Authored-By: Claude <[email protected]>
Washington TANF implementation includes:
- Complete parameterization of benefit amounts and income limits
- Income calculation variables (earned/unearned, countable income)
- Eligibility determination logic
- Comprehensive integration tests
All WA TANF variables are defined at SPMUnit level (family-based benefit),
but tests were expecting person-level array outputs. Fixed all test outputs
to use SPMUnit-level scalar values instead of person-level arrays.

Changes:
- Updated all test outputs from arrays (e.g., [706, 0, 0]) to scalars (e.g., 706)
- Affected variables: wa_tanf, wa_tanf_eligible, wa_tanf_payment_standard, wa_tanf_countable_income
- All 18 test cases corrected

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

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

codecov bot commented Nov 11, 2025

Codecov Report

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

Additional details and impacted files
@@             Coverage Diff              @@
##           master     #6818       +/-   ##
============================================
+ Coverage   72.92%   100.00%   +27.07%     
============================================
  Files        3252         7     -3245     
  Lines       46840        95    -46745     
  Branches      243         0      -243     
============================================
- Hits        34159        95    -34064     
+ 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 3 commits November 11, 2025 12:20
- Restructure gross_earned_income_limit.yaml to use top-level breakdown keys
- Restructure payment_standard.yaml to use top-level breakdown keys
- Update breakdown metadata to use range(1, 11) format
- Fixes parameter validation errors preventing system initialization

This change aligns with the standard parameter structure used in other
states (e.g., Missouri TANF) for scale parameters with family size breakdowns.

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

Co-Authored-By: Claude <[email protected]>
- Create unit test files for 8 variables with formulas
- Organized tests in benefit/, eligibility/, and income/ subdirectories
- Each test file follows DC TANF pattern with edge cases
- Tests cover boundary conditions, zero values, and state filtering
- All 56 unit tests pass successfully

Test files created:
- wa_tanf.yaml - Main benefit with grant cap (9 tests)
- wa_tanf_payment_standard.yaml - Payment standards by size (6 tests)
- wa_tanf_eligible.yaml - Overall eligibility logic (5 tests)
- wa_tanf_income_eligible.yaml - Income eligibility (9 tests)
- wa_tanf_countable_earned_income.yaml - Earned income disregards (8 tests)
- wa_tanf_countable_unearned_income.yaml - Unearned income (5 tests)
- wa_tanf_gross_earned_income.yaml - Earned aggregation (6 tests)
- wa_tanf_gross_unearned_income.yaml - Unearned aggregation (6 tests)

Edge cases covered:
- Zero income scenarios
- Exactly at threshold values
- One dollar over/under thresholds
- Family size caps (size 15 capped at 10)
- Grant cap application
- State code filtering (WA vs other states)
- Multiple earners in household

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

Co-Authored-By: Claude <[email protected]>
- Fix parameter date alignment: Update gross_earned_income_limit to start 2024-01-01
- Parameterize hard-coded family size cap (10) with maximum_family_size parameter
- Fix income aggregation: Use federal tanf_gross_earned_income/tanf_gross_unearned_income
- Update integration tests to use employment_income_before_lsr instead of employment_income
- Fix test expectation: Family of 4 with $2,300 income is ineligible (over $2,166 limit)

All 75 tests now pass.

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

Co-Authored-By: Claude <[email protected]>
@hua7450 hua7450 closed this Nov 11, 2025
@hua7450 hua7450 deleted the integration/wa-tanf-2025-11-11 branch November 11, 2025 23:07
@hua7450 hua7450 restored the integration/wa-tanf-2025-11-11 branch November 11, 2025 23:14
@hua7450 hua7450 reopened this Nov 11, 2025
@hua7450 hua7450 closed this Nov 11, 2025
@hua7450 hua7450 deleted the integration/wa-tanf-2025-11-11 branch November 11, 2025 23:15
@hua7450 hua7450 restored the integration/wa-tanf-2025-11-11 branch November 11, 2025 23:16
@hua7450 hua7450 reopened this Nov 11, 2025
hua7450 and others added 5 commits November 11, 2025 18:59
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]>
Changes parameter semantics to be clearer and match regulation language:

Before (confusing):
- Parameter: work_incentive_percentage = 0.5 (what we COUNT)
- Formula: remainder × 0.5
- Issue: If regulation changes to "subtract 40%", need to set parameter to 0.6

After (clear):
- Parameter: percentage_of_remainder_disregarded = 0.5 (what we DISREGARD)
- Formula: remainder - (remainder × 0.5)
- Benefit: Parameter value directly matches regulation ("subtract 50%" → 0.5)

Additional improvements:
- Inline single-use variables in payment_standard, income_eligible, and main benefit
- Use "share" instead of "percentage" in description (OH/PA pattern)
- Reference title includes subsection detail (OH pattern)

All 59 tests passing.

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

Co-Authored-By: Claude <[email protected]>
Parameter Structure Reorganization:
- Rename benefit/ → payment_standard/ (OH pattern)
- Flatten structure: remove eligibility/ folder (PA pattern)
- Group deductions: income/deductions/earned_income_disregard/
- Rename files for clarity: amount.yaml, maximum_amount.yaml
- Move resource_limit.yaml to root level (PA pattern)

Parameter Content Improvements:
- Spell out "Temporary Assistance for Needy Families program" in all descriptions
- Use agent-approved placeholders: "this amount", "this share"
- Add dual references where values exist, remove non-showing references
- Verify all references actually show the parameter values
- Remove unverifiable historical $6,000 resource limit (keep only $12,000)
- Fix $1,338 cap reference to DSHS manual (WAC doesn't show it)
- Remove publication_date fields from all parameters

Formula Improvements:
- Consistent use of p = parameters(...) pattern
- Remove single-use intermediate variables
- Remove parentheses from single-reference variables
- Add reference to wa_tanf_resources_eligible
- Remove unverified 33% FPL comment

Test Improvements:
- Convert member lists to inline bracket format [member1, member2]
- Update resource tests to use current $12,000 limit

All 59 tests passing.

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

Co-Authored-By: Claude <[email protected]>
Resource Limit Updates:
- Restore historical $6,000 value (2022-01-01) verified in 2022 State Plan
- Keep current $12,000 value (2024-01-01) from HB 1447 (2023 c 418)
- Reference 2022 State Plan with page anchor (#page=13)
- Reference HB 1447 legislation that increased the limit

Income Limit Documentation:
- Add comment explaining mathematical relationship to payment standards
- Formula: Income Limit = (Payment Standard × 2) + $500
- Represents break-even point where countable income = payment standard
- Note that WAC publishes as table, not formula (preserve structure)

All 59 tests passing.

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

Co-Authored-By: Claude <[email protected]>
Add explanatory comment in income/limit.yaml showing that these values
follow the formula: Income Limit = (Payment Standard × 2) +

This represents the break-even point where countable income equals the
payment standard, resulting in $0 benefit. While mathematically derived,
WAC 388-478-0035 publishes these as a table rather than a formula, so
we preserve the table structure here for regulatory accuracy.

🤖 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 12, 2025 20:52
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.

Nit, but LGTM! Really clean PR

Copy link
Collaborator

Choose a reason for hiding this comment

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

We are not modeling child support reception or SSN as eligibility reqs right? If so, can we file an issue

Image

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.

Washington TANF (simple implement)

2 participants