Implement Alabama Child Care Subsidy Program (CCSP)#8322
Open
hua7450 wants to merge 17 commits into
Open
Conversation
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>
Codecov Report✅ All modified and coverable lines are covered by tests. 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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements Alabama Child Care Subsidy Program (CCSP) in PolicyEngine.
Closes #8321
Regulatory Authority
Program Overview
Eligibility
al_ccsp_eligible_childal_ccsp_income_eligiblewithal_ccsp_enrolled = Falseal_ccsp_income_eligiblewithal_ccsp_enrolled = Trueal_ccsp_income_eligible(uses federalhhs_smi)is_ccdf_asset_eligible(federal CCDF helper, reused)al_ccsp_activity_eligible(withmeets_ccdf_activity_testfallback for job training, education, etc.)is_ccdf_immigration_eligible_child(federal CCDF helper, reused)al_ccsp_protective_servicesviais_in_foster_care,is_homelessdefined_for = StateCode.ALFamily unit ≈ SPMUnit (PE's SPMUnit may include unrelated cohabitants that AL excludes; documented as known approximation).
Income Calculation
income/countable_income/sources.yaml(employment, self-employment, farm operations, SS, pensions, unemployment, workers' comp, TANF, SSI, state supplement, interest, dividends, alimony, veterans' benefits)WEEKS_IN_YEAR / MONTHS_IN_YEAR(52/12 ≈ 4.3333; the regulatory 4.333 is just this ratio rounded)al_ccsp_income_eligibleandal_ccsp_weekly_copay_per_childtherefore pull FPG forperiod.start.year - 1.al_ccsp_weekly_copay_per_childfloorsmonthly_incomeat 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):
Copay waivers (encapsulated in
al_ccsp_copay_waived):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":
state_code_str == "AL"to prevent non-AL households crashing on missing keysselect()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:
Files Added
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
al_ccsp_protective_services.py)is_enrolled_in_head_start)al_ccsp_activity_eligibleapproximates the §2.2.2(d)(ii) caregiver set withis_tax_unit_head_or_spouse; grandparent / kinship / foster caregivers who aren't the tax-unit head won't be checked individually, butmeets_ccdf_activity_testcan be set as a fallback (documented inal_ccsp_activity_eligible.py)meets_ccdf_activity_testinput as fallback)is_homelessHousehold variable instead)al_ccsp_enrolledis a bare input defaulting to False, so every microdata household is treated as a new applicant unless this input is explicitly set by the callerTest plan
make formatclean🤖 Generated with /encode-policy-v2