Skip to content

Implement Washington ECEAP (Early Childhood Education and Assistance Program)#8154

Open
hua7450 wants to merge 9 commits intoPolicyEngine:mainfrom
hua7450:wa-eceap
Open

Implement Washington ECEAP (Early Childhood Education and Assistance Program)#8154
hua7450 wants to merge 9 commits intoPolicyEngine:mainfrom
hua7450:wa-eceap

Conversation

@hua7450
Copy link
Copy Markdown
Collaborator

@hua7450 hua7450 commented Apr 24, 2026

Summary

Implements Washington's Early Childhood Education and Assistance Program (ECEAP), including both standard ECEAP (ages 3-5, RCW 43.216.505/512) and Birth to Three ECEAP (under age 3, RCW 43.216.578). Service eligibility only — ECEAP provides preschool slots, not a cash benefit. Analogous to federal Head Start.

Closes #8153

Regulatory Authority

  • RCW 43.216.505 — standard ECEAP definition, age/income/categorical eligibility. Effective-date note: Sections 204-206 of 2021 c 199 take effect July 1, 2025; the 50% SMI threshold takes effect August 1, 2030.
  • RCW 43.216.512 — expanded enrollment: 110-130% FPL allowed (no risk factor required) and 130-200% FPL allowed (risk factor required), expires 2030-08-01
  • RCW 43.216.578 — Birth to Three ECEAP (separate statute): 130% FPL → 50% SMI on 2026-07-01; SNAP/Basic Food categorical
  • WAC 110-425 — DCYF ECEAP rules
  • DCYF 05-006 ECEAP Application, Section 9 — official list of countable income sources
  • DCYF ECEAP/Head Start program page

Program Overview

ECEAP is Washington's state-funded preschool program administered by DCYF. It provides preschool slots plus wraparound family-support services. Standard ECEAP (RCW 43.216.505) and Birth to Three ECEAP (RCW 43.216.578) are governed by separate statutes with different rules and different transition dates. Per the Fair Start for Kids Act (2021 c 199), Sections 204-206 took effect July 1, 2025, replacing FPL-based thresholds with state median income for standard ECEAP; the threshold rises to 50% SMI on August 1, 2030. Birth to Three transitions on a different date (2026-07-01).

Income Eligibility (Standard ECEAP)

The standard pathway uses a single FPG-or-SMI rate gated by the standard uses_fpg toggle:

Effective date Rate Basis Source
2021-07-25 130% FPL ceiling FPL RCW 43.216.512 (allowed enrollment, no risk factor required)
2025-07-01 36% SMI SMI RCW 43.216.505, 2021 c 199 §§ 204-206 effective date
2030-08-01 50% SMI SMI RCW 43.216.505

Why 130% FPL, not 110%: per RCW 43.216.505, families ≤ 110% FPL have priority enrollment; per RCW 43.216.512, families 110-130% FPL are allowed enrollment without a risk factor (space-available). PolicyEngine does not simulate space allocation, so both pathways are treated as eligible. The 130-200% FPL with-risk-factor band lives in wa_eceap_risk_factor_eligible. Documented in a code comment.

Risk-factor pathway (RCW 43.216.512): applies in the 130-200% FPL band (FPL era) or 36-50% SMI band (SMI era) for children with at least one modeled risk factor; expires 2030-08-01. The lower bound reuses the parent fpg_rate / smi_rate, since the risk-factor band starts where the standard pathway ends.

Birth to Three ECEAP (RCW 43.216.578)

Quoted directly from the statute: a child must be under 36 months old AND either (i) household income at or below the income threshold, OR (ii) eligible for / receiving SNAP or state FAP. No homelessness or IEP categorical pathway exists in RCW 43.216.578, unlike standard ECEAP.

Birth to Three has its own FPG↔SMI toggle (birth_to_three_eceap/uses_fpg.yaml):

Effective date Rate Basis Source
2021-07-25 130% FPL FPL RCW 43.216.578(5)(a)(i)
2026-07-01 50% SMI SMI RCW 43.216.578(4)(a)(i) (post-2026 version)

The categorical SNAP path uses the existing is_snap_eligible (SPMUnit) projected to Person, inlined directly in wa_birth_to_three_eceap_eligible. State FAP (for SNAP-ineligible legal immigrants) is documented as not modeled — small edge case, no PolicyEngine variable available.

Age Eligibility (Standard ECEAP)

Per RCW 43.216.505(4) and WAC 110-425-0080, an ECEAP-eligible child is at least 3 by August 31 of the school year and not yet kindergarten-age, with mid-year carry-over for a child who turns 5 during enrollment. PolicyEngine evaluates age annually without an Aug-31 anchor, so we take the generous reading and treat ages 3-5 as eligible to capture the carry-over case. Documented in a code comment.

Family Income Definition (wa_eceap_family_income)

The income aggregator counts the sources DCYF lists in Form 05-006, Section 9 (page 6) of the official ECEAP application. The list is a unit: list parameter (income_sources.yaml), pulled in via parameter-driven adds:

adds = "gov.states.wa.dcyf.eceap.income_sources"

Source list (income_sources.yaml):

  • market_income (covers W-2, self-employment, military pay)
  • tanf_reported
  • ssi_reported
  • social_security
  • child_support_received
  • unemployment_compensation
  • veterans_benefits
  • workers_compensation

alimony_income is excluded — it is not listed in DCYF Form 05-006 Section 9. Tribal income, emergency assistance cash, regular insurance payments, training stipends, and scholarships listed in Section 9 have no PolicyEngine equivalent at the moment.

Categorical Eligibility (Standard ECEAP, wa_eceap_categorically_eligible)

Per RCW 43.216.505(4), only two categorical paths are modelable with existing inputs:

Criterion Existing variable
Homelessness is_homeless (Household)
IEP / special education has_individualized_education_program (Person)

The other two statutory pathways — prior early-intervention services (Early Head Start / ESIT / class C developmental services / Birth-to-Three ECEAP / ECLIPSE) and Native-American + 100% SMI — are not modeled because we do not track those prior-program indicators or tribal enrollment at the moment. These categorical paths apply ONLY to standard ECEAP, not Birth to Three — RCW 43.216.578 has its own (different, narrower) categorical rules.

Risk Factors Modeled (Standard ECEAP only)

Modelable subset of RCW 43.216.512 risk factors using existing PolicyEngine inputs:

  • is_non_english_speaking_home (Household)
  • is_migratory_child (Person)
  • has_developmental_delay (Person)
  • has_individualized_education_program (Person)
  • is_single_parent_household (Person, projected via person.spm_unit.any(...))

Not modeled (no input variables): domestic violence, incarcerated parent, teen parent, parent education level, substance abuse, premature/LBW birth, chronic health, deployed military, loss of caregiver, Indian Boarding School family history, per-person ELL status.

Variables Created

Variable Entity Purpose
wa_eceap_eligible Person Standard top-level: age AND (income OR categorical OR risk-factor)
wa_eceap_age_eligible Person Generous age 3-5 (statute is 3 by Aug 31, not yet K-age)
wa_eceap_income_eligible Person Standard income test (130% FPL → 36% SMI → 50% SMI)
wa_eceap_categorically_eligible Person Homeless OR IEP
wa_eceap_risk_factor_eligible Person 130-200% FPL or 36-50% SMI band + ≥1 risk factor (expires 2030-08-01)
wa_eceap_family_income SPMUnit DCYF Form 05-006 Section 9 income aggregator (parameter-driven adds)
wa_birth_to_three_eceap_eligible Person BT3 top-level: age AND (income OR is_snap_eligible)
wa_birth_to_three_eceap_age_eligible Person Under age 3
wa_birth_to_three_eceap_income_eligible Person BT3 income test (130% FPL → 50% SMI on 2026-07-01)

All variables have defined_for = StateCode.WA and definition_period = YEAR. Following Washington convention, no is_ prefix; the wa_ state prefix is retained.

Parameter Structure

Parameters use a flat-by-rate convention (fpg_rate, smi_rate) with separate FPG↔SMI toggles for the two programs:

parameters/gov/states/wa/dcyf/eceap/
├── uses_fpg.yaml                          # standard toggle (2021-07-25: true → 2025-07-01: false)
├── income_sources.yaml                    # unit: list, parameter-driven adds for wa_eceap_family_income
├── age_range.yaml                         # 3-5 bracket (generous reading)
├── income/
│   ├── fpg_rate.yaml                      # 130% FPL ceiling
│   ├── smi_rate.yaml                      # 36% → 50% on 2030-08-01
│   └── risk_factor_pathway/
│       ├── in_effect.yaml                 # expires 2030-08-01
│       ├── fpg_rate.yaml                  # 200% FPL upper bound
│       └── smi_rate.yaml                  # 50% SMI upper bound (lower bound reuses parent)
└── birth_to_three_eceap/
    ├── uses_fpg.yaml                      # BT3 toggle (2021-07-25: true → 2026-07-01: false)
    ├── age_limit.yaml                     # 3
    └── income/
        ├── fpg_rate.yaml                  # 130% FPL
        └── smi_rate.yaml                  # 50% SMI (effective 2026-07-01)

The standard toggle and the risk-factor pathway share eceap.uses_fpg because they transition on the same date (2025-07-01). Birth to Three has its own toggle because RCW 43.216.578 transitions one year later (2026-07-01).

Existing Variables Reused

  • age, is_homeless, has_individualized_education_program, is_snap_eligible
  • is_migratory_child, is_non_english_speaking_home, has_developmental_delay, is_single_parent_household
  • spm_unit_fpg, hhs_smi
  • For income aggregator: market_income, tanf_reported, ssi_reported, social_security, child_support_received, unemployment_compensation, veterans_benefits, workers_compensation

Scope Excluded (documented reasons)

  • Indian-child categorical/income path (RCW 43.216.505) — no tribal-membership variable in PolicyEngine
  • Prior early-intervention participation (Early Head Start, ESIT, class C, Birth-to-Three ECEAP, ECLIPSE) — no per-program prior-participation indicators
  • State Food Assistance Program (FAP) — Washington's program for SNAP-ineligible legal immigrants. No standalone variable in PolicyEngine; is_snap_eligible is used as the proxy.
  • Risk factors without existing inputs (see Risk Factors Modeled section)
  • 25% statewide cap on risk-factor pathway — supply-side enrollment constraint, not individual eligibility
  • Priority points scoring — slot allocation, not eligibility
  • Foster care / TANF as automatic categorical for standard ECEAP — per RCW 43.216.505(4) none of these are categorical pathways. Foster care MAY warrant separate review — see open question below.

Open Questions / Known Gaps

  • Foster care categorical: worth verifying against the statute and considering whether to add is_in_foster_care / was_in_foster_care to wa_eceap_categorically_eligible in a follow-up.
  • State FAP: a small population of SNAP-ineligible legal immigrants who would be BT3-eligible under RCW 43.216.578(5)(a)(ii) are missed because we model only federal SNAP eligibility.

Files Added/Updated

  • policyengine_us/parameters/gov/states/wa/dcyf/eceap/ — 12 parameter YAMLs
  • policyengine_us/variables/gov/states/wa/dcyf/eceap/ — 9 variable .py files
  • policyengine_us/tests/policy/baseline/gov/states/wa/dcyf/eceap/ — 8 test YAMLs (98 test cases)
  • policyengine_us/programs.yaml — ECEAP added as state implementation under federal Head Start entry, variable: wa_eceap_eligible
  • changelog.d/wa-eceap.added.md

Test plan

  • 98 unit + edge-case + integration tests pass
  • make format clean
  • CI passes

hua7450 and others added 2 commits April 24, 2026 11:56
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (20705b0) to head (60635cd).
⚠️ Report is 29 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##             main     #8154       +/-   ##
============================================
+ Coverage   85.36%   100.00%   +14.63%     
============================================
  Files           3         9        +6     
  Lines          41       134       +93     
  Branches        2         4        +2     
============================================
+ Hits           35       134       +99     
+ Misses          6         0        -6     
Flag Coverage Δ
unittests 100.00% <100.00%> (+14.63%) ⬆️

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 7 commits April 24, 2026 19:52
- Fix FSKA Sec. 403 page anchor: #page=7 → #page=9 in 5 files
- Replace ccdf_income (excludes govt transfers) with new wa_eceap_family_income aggregator
  (market_income + TANF + SSI + Social Security + child support) per RCW 43.216.505
- Fix is_single_parent_household projection: child-level access was always False;
  now projects via add(spm_unit, ...) > 0 so parent's flag reaches the child

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Round 2 fixes (from /review-program round 2):
- wa_eceap_family_income: add 4 missing income types per WAC 110-425-0080
  (unemployment_compensation, alimony_income, veterans_benefits, workers_compensation)
- wa_eceap_risk_factor_eligible: switch single-parent projection from
  add(spm_unit, ...) > 0 to person.spm_unit.any(...) (idiomatic pattern)
- in_effect.yaml: add specific subsection citation for 2030-08-01 sunset
- early_eceap_age_limit.yaml: drop FSKA Sec. 403 (income), add WAC 110-425
- wa_eceap_categorically_eligible: clarify "prior Head Start" proxy scope in docstring
- wa_eceap_eligible: document why is_on_tribal_land is not an Indian-child proxy

Historical fidelity (per HB 1945 Feb 2024 House Bill Report):
- Add FPL-era parameters for Early ECEAP and risk-factor pathway
  - early_eceap_fraction_of_fpg.yaml (130% FPL)
  - early_eceap_uses_fpg.yaml (basis toggle)
  - risk_factor_pathway/lower_fraction_of_fpg.yaml (130% FPL lower bound)
  - risk_factor_pathway/fraction_of_fpg.yaml (200% FPL upper bound)
  - risk_factor_pathway/uses_fpg.yaml (basis toggle)
- Update wa_early_eceap_income_eligible and wa_eceap_risk_factor_eligible
  formulas with FPL/SMI branching
- Backfill all parameters to FSKA enactment (2021-07-25): 110% FPL standard,
  130% FPL Early ECEAP, 130-200% FPL risk-factor; SMI rollover 2025-10-01

Reorganization:
- Drop wa_ prefix from parameter file names (path already has wa_)
- Drop is_ prefix from variable class names (matches wa_tanf, wa_apple_health convention)
- Hierarchical variable folders: eceap/{eligibility/{age,income,categorical,risk_factor},income/}
- Top-level outputs (wa_eceap_eligible, wa_early_eceap_eligible) at eceap/ root
- Update programs.yaml: variable: wa_eceap_eligible

100/100 ECEAP tests pass; make format clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Variables: drop eligibility/, age/, income/ subfolders; flat layout under
  eceap/ with early_eceap/ subfolder for the birth-to-three variant
- Parameters: drop age/ subfolder (age_range and age_limit move up one level)
- Parameter filenames under early_eceap/ drop the early_eceap_ prefix since
  the folder already disambiguates
- Add income_sources.yaml at top of eceap/ and convert wa_eceap_family_income
  to YAML-driven adds (gov.states.wa.dcyf.eceap.income_sources)
- Update parameter paths in 3 formulas (wa_eceap_age_eligible,
  wa_early_eceap_age_eligible, wa_early_eceap_income_eligible)

100/100 ECEAP tests pass; make format clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add separate birth_to_three_eceap/uses_fpg toggle (flips 2026-07-01,
  not 2025-07-01 like standard ECEAP)
- Move BT3 SMI rate effective date 2025-10-01 to 2026-07-01
- Replace shared wa_eceap_categorically_eligible (homeless | IEP) with
  inline is_snap_eligible: BT3 statute has no homeless/IEP path, only
  income or Basic Food/SNAP/FAP
- Update BT3 income variable to use local toggle
- Rewrite BT3 tests for FPL era (2025-2026) and SMI era (2027+),
  including regression tests confirming the 2026-07-01 transition

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hua7450 hua7450 marked this pull request as ready for review April 26, 2026 20:31
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 Washington ECEAP (Early Childhood Education and Assistance Program)

1 participant