Implement Florida child care subsidy (School Readiness Program)#8598
Merged
Conversation
Closes PolicyEngine#8597 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PolicyEngine#8597) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8598 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 2 17 +15
Lines 36 282 +246
Branches 0 2 +2
==========================================
+ Hits 36 282 +246
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…e anchors (PR PolicyEngine#8598) - Floor countable income at 0 in fl_sr_copay (negative self-employment income no longer inflates the benefit) - Repoint entry_smi_rate citation to enacted 2025 Fla. Stat. 1002.81(6) (55% SMI) - Correct 6M-4.400 FAQ Q6 page anchors (#page=2 -> #page=1) - Reframe 30 hr/wk full-time threshold as a documented assumption - Add negative-self-employment-income copay-floor test (integration Case 13) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n-defined (PR PolicyEngine#8598) User supplied the previously 403-blocked Fla. Admin. Code 6M-4.500. It bases reimbursement on 'a child's care level and unit of care as defined by the coalition established rate schedule' (6M-4.500(1)(b),(1)(j)) — confirming the full-time/part-time boundary is set locally per Early Learning Coalition, with no statewide hours cutoff. Updated the comment/reference accordingly; the 30 hr/wk value remains a documented modeling convention (value unchanged). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ty test (PR PolicyEngine#8598) - Read weekly_hours_worked_before_lsr (not post-LSR) so the work-activity test does not move with the policy's own labor-supply incentives (SNAP convention) - Add meets_ccdf_activity_test OR-fallback: Fla. Stat. 1002.81(14) counts 'eligible work OR education activities' toward the 20/40 hours, which cannot be derived from employment hours alone (default false, dataset/user override) - Update test input keys to weekly_hours_worked_before_lsr; add fallback test Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…8598) del is a Python reserved keyword, forcing bracket parameter access (parameters(period).gov.states.fl["del"].sr). Rename the agency folder to doe (Department of Education, the parent agency of the Division of Early Learning) — consistent with the department-level fl/dcf convention — so formulas use clean attribute access gov.states.fl.doe.sr and the dotted adds-string/parameter_prefix update accordingly. No values or logic changed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ies) (PR PolicyEngine#8598) Cap the subsidy at the statewide maximum reimbursement rate (Fla. Admin. Code 6M-4.500; 'School Readiness Reimbursement Rates FY2025-26', SPB 2502). Benefit is now max(min(expense, sum of daily_rate x attendance days) - copay, 0); an unknown county falls back to uncapped. - Rate table stored as CSV (2,814 daily rates = 67 counties x FT/PT x 7 care levels x 3 provider types), loaded via pandas (Texas CCS pattern) - New: fl_sr_provider_type (input, default Licensed/Exempt), fl_sr_care_level (from age), fl_sr_max_daily_rate (county/provider/care-level/unit CSV lookup) - Rates programmatically extracted from the source PDF text layer and spot-verified against the PDF (Miami-Dade, Alachua) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…olicyEngine#8598) The FY2026-27 schedule (HB 5001E Conference Report, May 26 2026) carries the FY2025-26 rates forward byte-identical (0 of 2,814 cells differ), so a single CSV covers both fiscal years (2025-07-01 through 2027-06-30). Source note cites both documents and explains the July-1 fiscal-year boundary for any future differing year. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…cyEngine#8598) The benefit no longer falls back to expenses when there is no published reimbursement rate: fl_sr = max(min(expense, sum daily_rate*days) - copay, 0). A county with no FL rate (an unknown / non-Florida county_str such as ORANGE_COUNTY_CA) yields a zero cap and therefore $0, even when the unit is otherwise eligible. (Real FL households are unaffected: an unset county_str defaults to the first FL county, which has a published rate.) Tests: ORANGE_COUNTY_CA -> eligible but fl_sr 0 (rate-lookup Case 9 + integration Case 14); a 2027-01 case confirms the loader reads fy2025_26.csv for FY2026-27 (HB 5001E carried the rates forward unchanged). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ntical (PR PolicyEngine#8598) Add the canonical flsenate.gov source URLs for the FY2025-26 (SPB 2502) and FY2026-27 (HB 5001E) per-county reimbursement-rate schedules to the rate-table loader, the care-level parameter, and the rate-lookup variable. Document that FY2026-27 carries the FY2025-26 rates forward byte-identical (0 of 2,814 cells differ), so a single CSV covers both fiscal years (2025-07-01 .. 2027-06-30). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…icyEngine#8598) - Activity test (Fla. Stat. 1002.81(14)): the age/disability exemption applies only to a two-parent family where the OTHER parent works >= 20 hr/wk. A single disabled non-working parent (14)(a) and a two-parent both-disabled family are no longer treated as working families (the old non_exempt_parents==0 shortcut wrongly passed them). Single >= 20; two-parent neither exempt >= 40 combined. - Countable income (Fla. Stat. 1002.81(7)): family income is the gross income (earned or unearned) of members 18 or older; income of members under 18 is now excluded via an age-filtered sum (VA CCSP pattern). Still-enrolled 18+ HS students and disabled students under 22 remain not modeled. - Tests: activity Case 6 corrected + Cases 11/12 (two-parent one-disabled vs both-disabled); countable-income Cases 4/5 (minor excluded; 18yo counted). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…olicyEngine#8598) Model the activity requirement exactly as Fla. Stat. 1002.81(14) (confirmed by the FFY2025-27 CCDF State Plan s. 2.2.2): single parent works >= 20 hr/wk; two-parent neither-exempt >= 40 combined; two-parent with one parent exempt due to age or disability (14)(c) requires the OTHER parent to work >= 20. The age/disability exemption is two-parent-only -- a single disabled non-working parent and a both-exempt couple are NOT working families; they qualify (if at all) via the protective-services / meets_ccdf_activity_test path. The exemption is proxied by is_disabled and is_senior (65+, matching MA CCFA's work-exempt age). Adds tests: single disabled + fallback -> eligible; two-parent age-exempt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…8598) Florida waives the School Readiness parent copay for families that are (i)-(ii) at or below 150% FPG, (iii) homeless, (iv) have a child with a disability, (v) enrolled in Head Start / Early Head Start, or (vi) have a child in foster care (FFY2025-27 CCDF State Plan s. 3.3.1). New fl_sr_copay_waived (SPMUnit, MONTH) models these derivable conditions; the case-by-case at-risk waiver (6M-4.400(6)(a)) and coalition 'other criteria' (s. 1002.84(9)) are not derivable and noted as not modeled. fl_sr_copay returns 0 when waived. Consequence: low-income families (<=150% FPG) now have a $0 copay, so the 4%/6% SMI scale only applies between 150% FPG and 85% SMI. Recomputed the copay-scale, benefit, and integration tests accordingly (model-verified). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…services (PR PolicyEngine#8598) Addresses the /review-program findings on the FL School Readiness PR. The changes span shared test/variable files, so they are one commit, sectioned here. Full-time/part-time care: classify by the statutory daily measure (Fla. Stat. 1002.81(9)/(11): full-time = at least 6 hours within a 24-hour period) via childcare_hours_per_day, replacing the prior 30-hr/week proxy -- so 4 days x 6 hours = 24 hr/week is now correctly full-time. fl_sr_time_category + full_time_hours_threshold (-> 6) + the 5 affected test files updated. Protective-services pathway: a child who receives or needs protective services qualifies with the income AND activity tests waived (State Plan s. 2.2.2.f-h; Fla. Stat. 1002.81(1)). New fl_sr_protective_services feeds both is_fl_sr_eligible (income) and is_fl_sr_activity_eligible (activity). Age, asset, residency, and in_effect still apply; the copay is not waived (it keys on foster care). Review fixes: statute citations 2024 -> 2025; 6M-4.500 -> flrules.elaws.us and 45 CFR -> Cornell hosts; rate-doc #page anchors -> 4; FAQ Q7/Q8 and s. 1002.87(5) comment numbering; deprecated documentation field removed; TANF-cash exclusion documented; FPG comments recomputed (size-3 monthly 2_276.67) + a 150%-FPG copay-waiver boundary test; get_reimbursement_rates now selects the CSV by FL fiscal year (year + (month >= 7)). 112 tests pass; make format clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MaxGhenis
approved these changes
Jun 14, 2026
MaxGhenis
left a comment
Contributor
There was a problem hiding this comment.
Reviewed: parameter values spot-checked against the cited state sources and match; structure follows conventions (one variable per file, defined_for state scoping, no hardcoded values, correct entities/periods); meaningful YAML integration test coverage; CI green. LGTM.
…into fl-ccap # Conflicts: # policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml # policyengine_us/programs.yaml
…into fl-ccap # Conflicts: # policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml # policyengine_us/programs.yaml
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 Florida's School Readiness Program (SR) — the state's CCDF-funded child care subsidy, administered by the Division of Early Learning (DEL) within the Florida Department of Education, and delivered through 30 local Early Learning Coalitions (ELCs).
Modeled scope (important): this PR models only the SMI-Percentage sliding fee scale (effective 2025-10-01). The pre-2025-10 rule eras — the Standard Dollar-Based scale and the Percentage-FPL scale (both keyed to enrollment cohort) — and the CCEP / SR Match / SR Plus pathways are not modeled. PolicyEngine has no enrollment-cohort state, so for any simulation period the SMI-Percentage scale applies; the program is gated off before 2025-10-01. The benefit is capped at the statewide per-county provider reimbursement schedule (all 67 counties; SPB 2502 / 6M-4.500), and there is no TANF categorical bypass (see Not Modeled).
Closes #8597
Regulatory Authority
rates/reimbursement/fy2025_26.csvfy2025_26.csvcovers both fiscal years (effective 2025-07-01 through 2027-06-30)Program Overview
gov/states/fl/doe/sr/. The agency segment isdoe(Florida Department of Education — the parent department of the Division of Early Learning, which administers SR). This was chosen to match the department-levelfl/dcfconvention already used in the repo, and becausedelis a Python reserved keyword that would force bracket parameter access (parameters(...)["del"]) instead of clean dotted access.Eligibility
is_fl_sr_income_eligiblereadsentry_smi_rate(0.55) whenfl_sr_enrolled == Falseis_fl_sr_income_eligiblereadsexit_smi_rate(0.85) whenfl_sr_enrolled == Truefl_sr_countable_incomesums the 19income/sources.yamlsources over members 18+ only (add(person, …) × ~is_child); a minor's earned and unearned income is excludedis_fl_sr_activity_eligiblereadsweekly_hours_worked_before_lsr(pre-LSR — SNAP convention) againstactivity_hours_single(20) /activity_hours_two_parent(40). The age/disability exemption (is_disabled | is_senior, 65+) is two-parent-only; a single disabled non-working parent and a both-exempt couple qualify (if at all) via the protective-services pathway (next row) ormeets_ccdf_activity_test(education/training/job-search/grace, default false)fl_sr_protective_services= any memberreceives_or_needs_protective_services.is_fl_sr_eligibleuses(income_eligible | protective_services);is_fl_sr_activity_eligibleORs it in. Age, asset, residency, andin_effectstill apply; the copay is not waived (the §3.3.1 copay waiver keys on foster care)is_fl_sr_age_eligible(age < child_age_limit= 13)is_ccdf_immigration_eligible_child— no FL copyis_ccdf_asset_eligible(verifiedgov.hhs.ccdf.asset_limit== $1M) — no FL paramdefined_for = StateCode.FLonis_fl_sr_eligible; eligibility chain inherits the scopein_effect.yaml(false → true at 2025-10-01) gatesis_fl_sr_eligible; prevents phantom pre-program benefitsCopay (sliding fee scale)
Florida's copay is a percentage of family income, not a fixed dollar table. The SMI-Percentage scale (eff. 2025-10-01) classifies the family by
monthly countable income ÷ monthly SMI(SMI by state + family size) and applies a bracket rate:fl_sr_copayappliesmax_(fl_sr_countable_income, 0)before computing the copay so a negative self-employment loss can't produce a negative copay — which would otherwise inflate the benefit above the family's actual childcare expenses.$0income — not a copay rate. The earlier July FPL scale did have a $0 row at ≤50% FPL; the SMI scale does not.)copay = min_(copay, 0.07 × monthly countable income). Implemented for fidelity but structurally slack — the scale's maximum rate is 6% FT, below the 7% ceiling, so the cap never binds for the modeled single-household copay.fl_sr_copay_waivedzeroes the copay for families that are (i)–(ii) ≤ 150% FPG, (iii) homeless, (iv) have a child with a disability, (v) enrolled in Head Start / Early Head Start, or (vi) have a child in foster care. Because most SR families are ≤ 150% FPG, the 4%/6% scale above effectively bites only between 150% FPG and the 85% SMI exit limit. The case-by-case at-risk waiver (6M-4.400(6)(a)) and coalition "other criteria" (§1002.84(9)) are not derivable and not modeled.Benefit Calculation
fl_sr_max_daily_rate(a per-county × provider-type × care-level × unit-of-care lookup against the SPB 2502 / 6M-4.500 schedule) times that child'schildcare_attending_days_per_month, across the SPMUnit. The benefit is thenmax_(min_(monthly expenses, monthly cap) − copay, 0), where monthly expenses isspm_unit_pre_subsidy_childcare_expenses(YEAR, auto-divided to a monthly value).county_strhas no published Florida rate (an unknown / non-Florida county such asORANGE_COUNTY_CA), every child's daily rate resolves to 0, the monthly cap is 0, andmin_(expenses, 0) = 0— so the subsidy is $0 even when the unit is otherwise eligible (there is no published rate to pay against). The benefit does not fall back to expenses. Real FL households are unaffected: an unsetcounty_strdefaults to the first FL county, which has a published rate.max_(., 0)guards against negative-income sign flips, andfl_sr_copayindependently floors countable income at 0 (see Copay) so a self-employment loss can't drive the copay negative and push the benefit above expenses.fl_sris MONTH-defined. The state aggregatorfl_child_care_subsidies(YEAR,adds = ["fl_sr"],defined_for = StateCode.FL) sums it into the federalchild_care_subsidiestotal via the CCDF program registry.Provider reimbursement rates
The rate cap is driven by the statewide School Readiness Reimbursement Rates, Fiscal Year 2025-2026 schedule (SPB 2502, FL Senate Committee on Appropriations, April 3, 2025), incorporated by reference under Fla. Admin. Code 6M-4.500. All 67 Florida counties are modeled.
parameters/gov/states/fl/doe/sr/rates/reimbursement/fy2025_26.csv— with 2,814 daily rates (67 counties × FT/PT × 7 care levels × 3 provider types). It is loaded via pandas throughrates/reimbursement/__init__.py(get_reimbursement_rates,lru_cached), mirroring the Texas CCS CSV-rate-table pattern. The rates were programmatically extracted from the source PDF text layer and spot-verified against the PDF (Miami-Dade, Alachua). The same file serves both FY2025-26 and FY2026-27 (the FY2026-27 schedule, HB 5001E, carried the rates forward byte-identical); if a future fiscal year publishes different rates, addfy<YYYY>.csvand select by the July 1 fiscal-year boundary inget_reimbursement_rates.fl_sr_max_daily_rate(Person, MONTH) does a vectorized left-merge on four enum-name string keys:county_str×fl_sr_provider_type×fl_sr_care_level×fl_sr_time_category(unit of care). An unmatched county (an unknown / non-FLcounty_str) yields rate 0, which zeroes the subsidy — the benefit caps at this rate with no fall-back to expenses.fl_sr_provider_type, input enum): Licensed/Exempt (center; default), Licensed Family Child Care Home, Registered Family Child Care Home.fl_sr_care_level, derived fromrates/care_level_age.yamlbracket parameter): Infant (<1), Toddler (1), 2-Year-Old (2), Preschool 3 / Preschool 4 / Preschool 5 (ages 3 / 4 / 5), School Age (6+).childcare_attending_days_per_month(YEAR-defined; read withperiod.this_year) converts the per-child daily rate to that child's monthly cap contribution.Requirements Coverage
21 / 21 in-scope items covered (100%). 19 requirements + 2 federal registrations.
eligibility/income/{entry,exit}_smi_rate.yaml;is_fl_sr_income_eligible.py(12 cases: both boundaries × sizes 1/8)income/sources.yaml(19 types);fl_sr_countable_income.py(age-filtered per §1002.81(7); minor earned/unearned excluded)eligibility/activity_hours_{single,two_parent}.yaml;is_fl_sr_activity_eligible.py(pre-LSR hours; exemption two-parent-only per §1002.81(14)(c) viais_disabled|is_senior;meets_ccdf_activity_testOR-fallback)eligibility/child_age_limit.yaml;is_fl_sr_age_eligible.py(12/13 boundary)is_ccdf_immigration_eligible_childinis_fl_sr_child_eligible.py(citizen/undocumented/refugee)is_ccdf_asset_eligibleinis_fl_sr_eligible.pydefined_for = StateCode.FL; integration out-of-FL case (GA → $0/ineligible)in_effect.yaml; gate inis_fl_sr_eligible.py; integration pre-effective-date case (2025-01 → $0)copay/smi_scale/{full,part}_time_rate.yaml;fl_sr_smi.py;fl_sr_copay.py(tiers + 0.5501 boundary; income floored at 0)fl_sr_copay; integration multi-child casefl_sr_copay.yaml(lowest bracket = 4%/2%, no $0 row); integration zero-income case (→ $0 copay)fl_sr_copay.pymin_(); test documents the cap is structurally slackcopay/fl_sr_copay_waived.py(≤150% FPG / homeless / disabled child / Head Start / foster);copay/waiver/income_fpl_limit.yaml; wired intofl_sr_copay.py;copay/fl_sr_copay_waived.yamleligibility/fl_sr_protective_services.py; wired intois_fl_sr_eligible.py(income) andis_fl_sr_activity_eligible.py(activity);eligibility/fl_sr_protective_services.yaml+ activity & integration casesfl_sr_time_category.pyfromchildcare_hours_per_day(full-time = ≥ 6 hrs within a 24-hour period, Fla. Stat. §1002.81(9)/(11); 5/6-hr boundary + 4-day×6-hr case tested)rates/care_level_age.yaml,rates/reimbursement/{fy2025_26.csv, __init__.py};fl_sr_provider_type.py,fl_sr_care_level.py,fl_sr_max_daily_rate.py; tested inrates/(18 cases) + integration cases where the cap bindsfl_sr.py; dedicatedfl_sr.yaml+ integration cases (cap binding / slack / floored)fl_child_care_subsidiesinchild_care_subsidy_programs.yamladds(line 11); integration annual + federal flow-through casestate_implementationsentry + coverage inprograms.yaml(lines 498–503)Not Modeled (by design)
fl_sr_copay_waived)fl_sr_protective_services(State Plan §2.2.2.f–h); broader at-risk/diversion concepts without that flag are not trackedmeets_ccdf_activity_test)Open items for reviewer (from validation)
No open value assumptions remain. One modeling proxy is worth noting (not blocking):
is_disabled; the age exemption is proxied byis_senior(≥ 65, matching MA CCFA's work-exempt age). A documented exemption outside these proxies remains reachable viameets_ccdf_activity_test. (The earlier 30 hr/wk full-time convention has been removed — FT/PT now follows the statutory 6-hours-within-a-24-hour-period definition, Fla. Stat. §1002.81(9)/(11).)Files
Parameters (under
parameters/gov/states/fl/doe/sr/):Variables (under
variables/gov/states/fl/doe/sr/):Tests (under
tests/policy/baseline/gov/states/fl/doe/sr/):Modified federal registration files (2):
The
meets_ccdf_activity_testfallback reuses the existing federalvariables/gov/hhs/ccdf/meets_ccdf_activity_test.pyinput (SPMUnit, YEAR, default false) — no new variable was added for it.Test plan
policyengine-core test policyengine_us/tests/policy/baseline/gov/states/fl/doe -c policyengine_us)make format(ruff format + check) cleanmainchild_care_subsidiesflow-through verified in microsim (FL family → $880/mo; non-FL control → $0)