Skip to content

Implement Alabama Child Care Subsidy Program (CCSP)#8322

Open
hua7450 wants to merge 17 commits into
PolicyEngine:mainfrom
hua7450:al-ccap
Open

Implement Alabama Child Care Subsidy Program (CCSP)#8322
hua7450 wants to merge 17 commits into
PolicyEngine:mainfrom
hua7450:al-ccap

Conversation

@hua7450
Copy link
Copy Markdown
Collaborator

@hua7450 hua7450 commented May 15, 2026

Summary

Implements Alabama Child Care Subsidy Program (CCSP) in PolicyEngine.

Closes #8321

Regulatory Authority

Program Overview

  • Official name: Alabama Child Care Subsidy Program (CCSP). Informally "CCAP".
  • Agency: AL DHR / Child Care Services Division / Office of Child Care Subsidy
  • Operational delivery: 4 regional Child Care Management Agencies (CMAs) covering 9 service regions
  • Funding: CCDF (federal block grant) + state matching
  • Effective dates: rates 2022-04-11; fee scale 2024-01-01

Eligibility

Requirement Source How Modeled
Child under 13 (or 19 if disabled) State Plan §2.2.1 (p. 20) al_ccsp_eligible_child
Initial income ≤ 180% FPL State Plan §2.2.4 (p. 24) al_ccsp_income_eligible with al_ccsp_enrolled = False
Continuing income ≤ 200% FPL State Plan §2.2.4 (p. 39) al_ccsp_income_eligible with al_ccsp_enrolled = True
Hard cap ≤ 85% SMI 45 CFR 98.20 + State Plan §2.5.2 (pp. 24, 35-39) al_ccsp_income_eligible (uses federal hhs_smi)
Asset limit ≤ $1,000,000 State Plan §2.2.6 (p. 27) is_ccdf_asset_eligible (federal CCDF helper, reused)
Activity ≥ 15 hrs/week State Plan §2.2.2 (pp. 21-23) al_ccsp_activity_eligible (with meets_ccdf_activity_test fallback for job training, education, etc.)
Immigration 45 CFR 98 is_ccdf_immigration_eligible_child (federal CCDF helper, reused)
Protective services waiver (income & activity) State Plan §2.2.2(f) (p. 23) al_ccsp_protective_services via is_in_foster_care, is_homeless
Alabama residency State Plan §2.2 (p. 20) defined_for = StateCode.AL

Family unit ≈ SPMUnit (PE's SPMUnit may include unrelated cohabitants that AL excludes; documented as known approximation).

Income Calculation

  • Gross monthly income — no deductions ("Regulations allow for no deductions to gross income" — Fact Sheet)
  • Counted sources: see income/countable_income/sources.yaml (employment, self-employment, farm operations, SS, pensions, unemployment, workers' comp, TANF, SSI, state supplement, interest, dividends, alimony, veterans' benefits)
  • Excluded: child support received, spousal support received, room rent
  • Weekly→monthly multiplier: WEEKS_IN_YEAR / MONTHS_IN_YEAR (52/12 ≈ 4.3333; the regulatory 4.333 is just this ratio rounded)
  • FPG year: Alabama's published income tables use the prior calendar year's HHS poverty guidelines (since HHS publishes new guidelines mid-January). The Jan-2024 Fact Sheet's family-size income thresholds match 2023 FPG values exactly (e.g., 100% FPL fam of 2 = $19,720/yr → $1,643/mo on the Fact Sheet, which is 2023 FPG, not 2024 FPG $20,440). al_ccsp_income_eligible and al_ccsp_weekly_copay_per_child therefore pull FPG for period.start.year - 1.
  • Negative countable income: al_ccsp_weekly_copay_per_child floors monthly_income at 0 before computing the FPL ratio, so self-employment / farm losses land in the $0 copay band rather than producing a negative FPL ratio.

Family Fee (Copay)

Weekly per-child fee, sliding scale by FPL band — single unified 11-band scale indexed by FPL ratio (initial applicants cap at 180% FPL, continuing recipients cap at 200% FPL):

FPL band Fee/week/child
0-100% $0
101-110% $18
111-120% $21
121-130% $24
131-140% $27
141-150% $30
151-160% $33
161-170% $36
171-180% $39
181-190% $42
191-200% $45

Copay waivers (encapsulated in al_ccsp_copay_waived):

  • ≤100% FPL (encoded in fee table $0 band, §3.3.1(i))
  • Family with a disabled child (§3.3.1(iv))
  • Family with a Head Start / EHS child (§3.3.1(v))
  • Family authorized under Protective Service — foster, kinship, or homelessness per §2.2.2(f) (§3.3.1(vi))

Copay applies per eligible child in care (is_eligible_child & childcare_hours_per_week > 0) — ineligible siblings (over age, undocumented, etc.) do not multiply the copay.

Provider Rates

486-cell rate matrix transcribed verbatim from the Provider Rate Chart "Effective April 11, 2022":

  • Provider types: Center, GFDC (Group Family Day Care), FDC (Family Day Care), INFORMAL (flat weekly cap)
  • Regions: 9 (Huntsville, Tuscaloosa, Mobile, Ft Payne, Birmingham, Talladega, Montgomery, Dothan, Opelika)
  • Age categories: Infant/Toddler (0-36mo), Preschool (37-59mo), School-Age (≥60mo) — per Rate Chart "Key to Care Level"
  • Quality tiers: Base + STAR 1-5 (transcribed cell-by-cell, not derived)
  • Part-time (≤25 hrs/wk): ½ × full-time rate — applies to INFORMAL too, so informal part-time = $25 (half of the $50 full-time cap)
  • INFORMAL cap: $50/wk full-time; $25/wk part-time
  • County → region lookup masked by state_code_str == "AL" to prevent non-AL households crashing on missing keys
  • Default region: BIRMINGHAM (used as select() fallback for AL households whose county doesn't map cleanly)

Benefit Calculation

Per-child weekly subsidy = max(0, min(provider charge, max weekly rate) − per-child copay).

Per-child monthly subsidy = weekly subsidy × (WEEKS_IN_YEAR / MONTHS_IN_YEAR) × is_paying_child.

Family-level copay split equally across eligible children in care. SPMUnit benefit = sum of per-child monthly subsidies.

Parameter Folder Structure

Parameters organized by concept rather than by lifecycle phase:

parameters/gov/states/al/dhr/ccsp/
  activity/hours_minimum.yaml
  age/{child_limit, disabled_child_limit}.yaml
  age_category/months.yaml
  copay/fee_by_fpl.yaml
  income/countable_income/sources.yaml
  income/limit/{fpl_initial, fpl_continuing, smi_cap}.yaml
  rates/{maximum_weekly_full_time, part_time_multiplier,
         full_time_hours_threshold, informal_weekly_cap}.yaml
  region/counties.yaml

Files Added

policyengine_us/parameters/gov/states/al/dhr/ccsp/   (see structure above)

policyengine_us/variables/gov/states/al/dhr/ccsp/
  al_ccsp.py
  al_ccsp_age_category.py
  al_ccsp_countable_income.py
  al_ccsp_enrolled.py
  al_ccsp_provider_type.py
  al_ccsp_quality_tier.py
  al_ccsp_region.py
  al_child_care_subsidies.py
  copay/{al_ccsp_copay_waived, al_ccsp_weekly_copay_per_child}.py
  eligibility/{al_ccsp_activity_eligible, al_ccsp_eligible, al_ccsp_eligible_child,
               al_ccsp_income_eligible, al_ccsp_protective_services}.py
  payment/al_ccsp_maximum_weekly_rate.py

policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/
  (15 YAML files, 129 test cases)

Modified:
- policyengine_us/programs.yaml (registered AL CCSP under CCDF state_implementations)
- policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml (added al_child_care_subsidies)
- changelog.d/al-ccap.added.md

Test Coverage

129 tests including multi-child mixed-eligibility scenarios (3 children with 1 eligible / 1 over-age / 1 undocumented), informal part-time, all 4 copay waiver categories, SMI hard cap, exact FPL and SMI boundaries, the 2025-01 carry-forward year, and negative countable income (self-employment loss does not inflate subsidy).

Not Modeled

  • 7% federal copay cap (45 CFR 98.45(k)) — State Plan §3.1.1.a notes Alabama has submitted a waiver request; the modeled fee table follows the State Plan's flat sliding-fee schedule and does NOT enforce the 7% ceiling
  • Protective-services sub-populations (3 of 5 per State Plan §2.2.2(f)) — child welfare engagement, EHS-CCP enrollment, kinship care / "TANF-Other Relative" are not tracked at the moment; missing categories under-count eligibility because protective services waives both income and activity tests (documented in al_ccsp_protective_services.py)
  • EHS-CCP as distinct from Head Start (proxied via is_enrolled_in_head_start)
  • In loco parentis caregiversal_ccsp_activity_eligible approximates the §2.2.2(d)(ii) caregiver set with is_tax_unit_head_or_spouse; grandparent / kinship / foster caregivers who aren't the tax-unit head won't be checked individually, but meets_ccdf_activity_test can be set as a fallback (documented in al_ccsp_activity_eligible.py)
  • Granular job-training / GED / internship enrollment status (use meets_ccdf_activity_test input as fallback)
  • Irregular / temporary income exclusion (§2.2.5)
  • McKinney-Vento homelessness flag (uses is_homeless Household variable instead)
  • CMA discretion / outreach / intake operations (§2.4, §2.5.3)
  • Job-search-alone activity
  • Priority / waitlist categories (§2.3)
  • 12-month continuity / mid-period income changes (§2.5.2)
  • Continuing-tier (200% FPL) graduation: al_ccsp_enrolled is a bare input defaulting to False, so every microdata household is treated as a new applicant unless this input is explicitly set by the caller

Test plan

  • 129 tests pass locally
  • make format clean
  • CI passes
  • Regulatory reviewer verifies: disabled-parent activity exemption (not in §2.2.2 text but standard cross-state convention per SC/VA), 7% copay cap omission, the §3.3.1(vi) Protective-Service copay waiver interpretation for homeless families, prior-year FPG lag in Fact Sheet operations

🤖 Generated with /encode-policy-v2

hua7450 and others added 3 commits May 14, 2026 22:33
Closes PolicyEngine#8321

- 16 parameter files including 486-cell rate matrix (provider × region × age × STAR tier)
- 16 variables covering eligibility (180% FPL initial / 200% FPL continuing / 85% SMI cap),
  triple-test income, dual-tier copay table, multi-dimensional rate lookup, and waiver paths
- 14 test YAML files (103 cases) covering unit + integration + edge cases
- Registered in programs.yaml and federal CCDF child_care_subsidy_programs.yaml

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hua7450 hua7450 changed the title Implement Alabama Child Care Assistance Program (CCAP) Implement Alabama Child Care Subsidy Program (CCSP) May 15, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (8cb60e7) to head (ad3e09e).
⚠️ Report is 45 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main     #8322    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            3        16    +13     
  Lines           63       271   +208     
==========================================
+ Hits            63       271   +208     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

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 11 commits May 15, 2026 00:03
- Correct §2.5.5(c)(iii) section label on income_limit_fpl_continuing.yaml
- Fix #page=26 on income_limit_fpl_initial.yaml (was 24)
- Add #page=1/2 anchors to 6 Provider Rate Chart references
- Add 4 direct unit tests for al_ccsp_weekly_copay_per_child
- Add exact-boundary tests at 180% FPL, 200% FPL, 85% SMI

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add #page= anchors to 5 variable .py files referencing Provider Rate Chart
- Fix al_ccsp_enrolled.py section label (§2.2.4 → §2.5.5(c)(iii))
- Add STAR_1/STAR_2/STAR_4 test cases to al_ccsp_maximum_weekly_rate.yaml

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parameter restructure:
- Replace eligibility/ folder with concept-based folders (age/, activity/,
  income/limit/)
- Merge initial_fee_by_fpl.yaml + continuing_fee_by_fpl.yaml into a single
  fee_by_fpl.yaml (continuing families below 180% FPL now use the same scale
  as initial applicants)
- Remove weeks_to_months.yaml; use WEEKS_IN_YEAR/MONTHS_IN_YEAR framework
  constant instead

Source-verified value corrections:
- Rate table (486 values): re-transcribed maximum_weekly_full_time.yaml from
  the dhr.alabama.gov "Effective April 11, 2022" Provider Rate Chart (prior
  values came from a different proposed/75th-percentile PDF)
- Informal weekly cap: $40 -> $50 (per same PDF)
- Age category PRESCHOOL threshold: 36 -> 37 months (per Rate Chart Key to
  Care Level)
- Verified 85% SMI income cutoffs match HHS SMI parameters exactly

New variable:
- al_ccsp_copay_waived: extracts the disabled-child / Head Start / foster
  child waiver logic shared between al_ccsp_copay and al_ccsp

Test coverage additions:
- al_ccsp_copay_waived.yaml (5 cases covering each waiver category)
- Multi-child mixed-eligibility tests for al_ccsp_copay, al_ccsp, and
  al_ccsp_eligible_child (3-children with 1 eligible / 1 over-age /
  1 undocumented; 2 eligible children with 1 in care; 3 eligible children
  in care; disabled child + young sibling)

All 126 AL CCSP tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copay waiver (al_ccsp_copay_waived):
- Replace `has_foster_child` with `al_ccsp_protective_services`. Per
  §3.3.1(vi), the parental fee is waived for any child authorized
  under the Protective Service category — which per §2.2.2(f)
  includes homelessness as well as foster care.

Activity eligibility (al_ccsp_activity_eligible):
- OR in `meets_ccdf_activity_test` as a fallback so that families
  who qualify via job training, education hours, SNAP E&T, or other
  approved-but-unmodeled activities are not incorrectly excluded.
  Matches the pattern used by DE, NJ, PA, VA, and VT CCAP variables.

Provider rate (al_ccsp_maximum_weekly_rate):
- Apply the part-time multiplier to INFORMAL providers too. The
  prior code returned the flat $50 cap regardless of hours, but
  §3.1 (Part-time Rates note) caps part-time at 1/2 of the
  applicable full-time rate, so part-time informal = $25.

Tests:
- Update the homeless-household copay test to expect waiver.
- Add multi-child mixed-eligibility coverage for the new waiver.
- Add positive/negative tests for the activity fallback.
- Add a part-time INFORMAL rate test ($25 expected).

130 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Refactor copay waiver to a single source of truth: apply §3.3.1 waiver
  inside al_ccsp_weekly_copay_per_child, remove duplicated waiver logic
  from al_ccsp.py, drop the redundant n_paying multiply/divide.
- Drop is_tax_unit_dependent gate from al_ccsp_eligible_child
  (use age + immigration + SPM co-residence).
- Reframe protective-services comment with correct §3.3.1(vi) citation
  and document the kinship-care limitation.
- Fix #page anchors (hours_minimum, smi_cap); add State Plan ref to
  fee_by_fpl; drop slash from child_limit title.
- Document the meets_ccdf_activity_test fallback semantics and the
  al_ccsp_enrolled microdata default.
- Add tests: 2025 integration, over-age-child rate masking, non-AL
  household + AL county_str regression, asset boundary, 4 untested copay
  bands (130/140/160/170 percent), 200 percent FPL top band, 4 untested
  regions, INFORMAL+STAR_5 interaction, SMI float-boundary refactor.
- Update programs.yaml: AL CCSP status partial (kinship/EHS-CCP/etc.
  not modeled).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add al_child_care_subsidies to household_state_benefits.yaml so the
  benefit flows through the household-level state-benefit aggregation.
- Drop is_tax_unit_dependent from the disabled-child copay-waiver gate
  in al_ccsp_copay_waived.py to match State Plan §3.3.1(iv) wording and
  the variable-patterns "use age, not tax dependency" rule.
- Convert (title, url) reference tuples to single-URL strings in all 16
  AL CCSP variable files; titles belong in parameter YAML, not variable
  reference fields.
- Document the federal 7% gross-income copay cap and Alabama's pending
  waiver request in al_ccsp_copay.py (State Plan §3.1.1(a) confirms AL
  charges per child and acknowledges the family total can exceed 7%).
- Remove the wrong Cornell LII citation in age_category/months.yaml
  (660-5-20-.04 is the licensing staffing-ratio rule, not the CCSP
  rate-setting categories).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Replace deprecated documentation field with inline comments on
  al_ccsp_activity_eligible.py and al_ccsp_enrolled.py
- Expand al_ccsp_protective_services.py comment to enumerate all five
  State Plan §2.2.2(f) sub-populations and which are not tracked
- Clarify in loco parentis caregiver handling via the
  meets_ccdf_activity_test fallback in al_ccsp_activity_eligible.py
- Floor monthly_income at zero in al_ccsp_weekly_copay_per_child.py so
  self-employment / farm losses land in the $0 copay band rather than
  producing a negative FPL ratio
- Add edge_cases.yaml test exercising self-employment loss
Alabama's Child Care Fact Sheet income tables track the prior calendar
year's HHS poverty guidelines (e.g., the Jan-2024 Fact Sheet uses 2023
FPG values), since HHS publishes new guidelines mid-January.

- al_ccsp_income_eligible.py and al_ccsp_weekly_copay_per_child.py now
  pull FPG for period.start.year - 1
- All FPL-relative test income values rebased to 2023 FPG for 2024-01
  tests; the 2025-01 carry-forward test still uses 38_730 because that
  is 150% of the 2024 FPG used at that period
- Remove al_ccsp_copay variable + test file. Nothing in the model
  consumed it: the benefit formula uses al_ccsp_weekly_copay_per_child
  (per-child, broadcast to Person level) because per-child clamping
  matters for households with one free-care and one paid-care child.
  Tests that asserted al_ccsp_copay now assert
  al_ccsp_weekly_copay_per_child.
- Update fee_by_fpl.yaml reference: §3.1 #page=40 -> §3.1.2(b) #page=41
  (lands on the actual fee table, not the section header)
- Update smi_cap.yaml reference: §2.5.2 #page=35 -> §2.5.5 #page=38
  (the verbatim 85% SMI rule is in §2.5.5)
- Remove trailing whitespace in sources.yaml
- Drop WHAT-only comments in al_ccsp.py and al_ccsp_age_category.py
PolicyEngine's age variable is annual, so an integer-input age of 3
maps to exactly 36 months. With the previous 37-month threshold, all
3-year-olds (whose actual age spans 36-47 months) were classified as
INFANT_TODDLER and routed to infant/toddler provider rates instead of
preschool rates.

Setting the PRESCHOOL threshold at 36 months matches how Alabama
operationally treats 3-year-olds in childcare subsidy.

Added a 2.99-year-old test case to lock the boundary.
@hua7450 hua7450 marked this pull request as ready for review May 18, 2026 03:26
@hua7450 hua7450 requested a review from PavelMakarchuk May 18, 2026 04:18
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 Alabama Child Care Assistance Program (CCAP)

1 participant