Skip to content

Implement South Carolina CCAP (Child Care Assistance Program)#7935

Open
hua7450 wants to merge 16 commits intoPolicyEngine:mainfrom
hua7450:sc-ccap
Open

Implement South Carolina CCAP (Child Care Assistance Program)#7935
hua7450 wants to merge 16 commits intoPolicyEngine:mainfrom
hua7450:sc-ccap

Conversation

@hua7450
Copy link
Copy Markdown
Collaborator

@hua7450 hua7450 commented Apr 6, 2026

Summary

Implements South Carolina's Child Care Scholarship Program (CCAP) in PolicyEngine, covering the Working Families track. Includes eligibility logic, income counting, copayment fee scale, provider rate tables, and benefit calculation.

This branch also fixes the large-family copay edge cases in the South Carolina fee scale implementation, narrows the disabled-child copay exemption to actual dependent children, and removes an unused sc_ccap_head_start_category variable and fixture.

Closes #7934

Regulatory Authority

Program Overview

  • Official name: SC Child Care Scholarship Program (formerly SC Voucher Program)
  • Administration: State-administered by SC Department of Social Services (SCDSS)
  • Federal authority: Child Care and Development Block Grant Act of 2014; 45 CFR Part 98
  • Scope: Working Families track (funding category 4 of 17)

Eligibility

Requirement Source How Modeled
SC residency Policy Manual 2.1.1 defined_for = StateCode.SC
Child age < 13 (< 19 special needs) Policy Manual 2.1.2 sc_ccap_eligible_child with parameterized age limits
Immigration: US citizen or qualified alien Policy Manual 2.1.3-2.1.4 is_ccdf_immigration_eligible_child (federal)
Child must be a dependent Policy Manual 2.1.7 is_tax_unit_dependent
Activity: work >= 15 hrs/wk or school/training Policy Manual 2.1.5 sc_ccap_activity_eligible
Income <= 85% SMI Policy Manual 2.13; CCDF Plan 2.2.4 sc_ccap_income_eligible
Assets < $1M Policy Manual 2.1.16 is_ccdf_asset_eligible (federal)
At least 1 eligible child Implicit sc_ccap_eligible checks eligible child count > 0

Income Rules

  • Countable income computed via sources.yaml — 13 included sources (employment, self-employment, farm, Social Security, pension, UI, workers comp, child support, alimony, interest, dividends, rental, veterans benefits). TANF is excluded to avoid a circular dependency (tanf -> childcare_expenses -> sc_ccap -> sc_ccap_countable_income -> tanf).
  • Key exclusions: SSI, SNAP, EITC, foster care payments, education grants (Pell, GI Bill), gifts, lump sums, capital gains, work-study
  • Single 85% SMI threshold for both entrance and exit (unlike RI/MA which use separate thresholds)
  • Source: Policy Manual sections 2.1.8, 2.1.14-2.1.15

Copayment (Fee Scale)

The copay formula covers two eras:

Pre-2024-10-01 (SMI ratio method): 5 tiers at fixed SMI ratios (45%/55%/65%/75%/85%). Family size is capped at the published 16-person row so 17+ households inherit the last published thresholds rather than receiving larger derived thresholds.

Post-2024-10-01 (FPL-to-SMI band method): Families at or below 150% FPL pay $0. Above that, positive copay bands are derived only through the last published paid-tier family size. Rows 15-16 remain $0-only per the published fee scale, and 17+ households inherit the capped published row.

This avoids two correctness issues in the original implementation:

  • large-family paid tiers no longer collapse to $0 when 150% FPL overtakes 85% SMI
  • 17+ households no longer get more generous unpublished thresholds than the size-16 row
Tier Weekly Fee/Child
0 $0 (post-2024 only, at/below 150% FPL)
1 $6
2 $11
3 $14
4 $17
5 $20
  • Max copay: 2% of family income (SC cap; federal cap is 7%)
  • $0 copay for: TANF enrolled, foster care, homeless, protective services, a disabled dependent child, Head Start
  • Head Start pathway: only the enrolled child (who must also be CCDF-eligible) is covered; non-Head-Start siblings are not charged a copay and are not covered unless the unit also meets standard/protective pathway requirements
  • Care arrangement required: children with childcare_hours_per_week = 0 get $0 rate and are excluded from copay count
  • Structural parameters:
    • smi_tier_ratios.yaml — SMI ratio per tier (pre-2024)
    • weekly_amounts.yaml — copay per tier
    • max_family_size.yaml — published fee-scale row cap
    • max_paid_family_size.yaml — last post-2024 family size with positive copay tiers

Provider Rates

Full rate tables encoded across all dimensions:

  • 6 provider categories: Center, Exempt Center, Group Home, Licensed Family Home, Registered Family Home, FFN
  • 5 quality levels: A+, A, B+, B, C (3 for Registered: B+, B, C; flat rates for FFN)
  • 7 age groups: Under 1, 1, 2, 3, 4, 5 not in K, 5-12 in school
  • 2 geographies: Urban (21 counties) / Rural (25 counties)
  • 2 schedules: Full-time (>= 25 hrs/wk) / Half-time (< 25 hrs/wk)
  • Surcharges: Special needs $20/wk, Foster care $30/wk
  • Second child discount: Provider-determined input sc_ccap_second_child_discount_rate
  • Source: Maximum Payments FFY2023

Not Modeled (by design)

What Source Why Excluded
12-month eligibility period CCDF Plan 2.1.1 Temporal; PE evaluates per-period
Dual Language Learners $0 copay CCDF Plan 3.3.1 No DLL variable in PE
4K Plus Siblings $0 copay CCDF Plan 3.3.1 No 4K Plus variable in PE
16 non-Working Families funding tracks Policy Manual / CCDF Plan Deferred to follow-up

Review Fixes Applied

  • Restricted the disabled-child copay exemption to actual dependent children under the program's disabled-child age limit, rather than any disabled person under 19 in the SPM unit.
  • Removed the unused sc_ccap_head_start_category variable and its standalone YAML fixture because the main SC CCAP formulas do not depend on it.

Files

policyengine_us/parameters/gov/states/sc/dss/ccap/
  eligibility/
  income/
  copay/
    fpg_exempt_in_effect.yaml
    fpg_exempt_rate.yaml
    income_cap_rate.yaml
    max_family_size.yaml
    max_paid_family_size.yaml
    smi_tier_ratios.yaml
    weekly_amounts.yaml
  time_category/
  age_group/
  surcharge/
  geography/
  rates/

policyengine_us/variables/gov/states/sc/dss/ccap/
  sc_ccap.py
  sc_ccap_countable_income.py
  sc_ccap_maximum_weekly_benefit.py
  sc_ccap_second_child_discount_rate.py
  sc_ccap_time_category.py
  sc_ccap_quality_level.py
  sc_ccap_registered_quality_level.py
  sc_ccap_age_group.py
  sc_ccap_geography.py
  sc_ccap_provider_type.py
  sc_child_care_subsidies.py
  copay/sc_ccap_copay.py
  eligibility/

policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap/

Validation

Local checks run:

  • uv run policyengine-core test policyengine_us/tests/policy/baseline/gov/states/sc/dss/ccap

Status at update time:

  • full local SC CCAP baseline suite passed (130 tests)
  • GitHub Actions checks are in progress

hua7450 and others added 3 commits April 6, 2026 13:52
Adds eligibility, income, copay, provider rates (~840 cells), and benefit
calculation for SC's Working Families track. Refs PolicyEngine#7934.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 6, 2026

Codecov Report

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

Additional details and impacted files
@@             Coverage Diff             @@
##             main     #7935      +/-   ##
===========================================
+ Coverage   92.72%   100.00%   +7.27%     
===========================================
  Files           3        18      +15     
  Lines          55       353     +298     
  Branches        2         4       +2     
===========================================
+ Hits           51       353     +302     
+ Misses          3         0       -3     
+ Partials        1         0       -1     
Flag Coverage Δ
unittests 100.00% <100.00%> (+7.27%) ⬆️

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 April 6, 2026 16:39
- Add 150% FPL and disabled child copay exemptions
- Fix disabled_child_age_limit off-by-one (19→20)
- Correct fee scale effective dates to 2025-10-01
- Fix 9 wrong page numbers and 2 wrong section titles
- Add historical FT hours threshold (30→25 on 10/01/2024)
- Verify second child discount direction is correct

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Revert disabled_child_age_limit from 20 back to 19 (Policy Manual: "under 19")
- Filter disabled child copay exemption to children only (not adults)
- Add fpg_exempt_in_effect boolean guard (false before 2024-10-01)
- Add defined_for on sc_ccap_second_child_discount_rate
- Remove is_tax_unit_dependent from eligible_child (use age-based check only)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The SC CCAP implementation previously hard-required income and activity
tests for all cases, which is narrower than the actual program. The
policy manual (Section 2.4, 2.15) defines protective services and Head
Start wraparound categories that bypass these requirements.

- Add sc_ccap_protective_services variable (foster care, homeless, CPS)
- Add sc_ccap_head_start_category variable (Head Start enrollment)
- Add is_enrolled_in_head_start input variable
- Refactor sc_ccap_eligible to OR across standard, protective services,
  and Head Start pathways
- Refactor sc_ccap_copay to use category-based zero-copay instead of
  ad-hoc foster/homeless checks
- Remove sources/working_references.md (agent artifact)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ity, part-time rates

- Head Start pathway now only covers the enrolled child, not siblings
  (Section 2.15: "for the Head Start child")
- Head Start children forced to half-time rates while enrolled
  (Section 2.15: "pays only part time to extend the Head Start day")
- Disabled parent satisfies activity requirement (Section 2.13)
- Copay: Head Start children excluded per-child, not family-level
- Protective services comment clarifying income test is retained
- Second-child discount comment clarifying per-facility simplification

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…esholds

Replace 16 family_size_*.yaml bracket files with structural parameters
(SMI tier ratios, weekly copay amounts, tier count). The copay formula
now computes tier boundaries dynamically from HHS SMI and FPG, covering
both eras: pre-2024 (SMI ratio thresholds) and post-2024 (150% FPL to
85% SMI equal bands).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Derive tier count from smi_tier_ratios bracket length instead of
  separate parameter file.
- Use period auto-conversion for hhs_smi (YEAR→MONTH) instead of
  manual period.this_year / MONTHS_IN_YEAR.
- Comment out tanf from CCAP countable income sources to break
  circular dependency (tanf → childcare_expenses → sc_ccap →
  sc_ccap_countable_income → tanf).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…NF cycle

- Require Head Start child itself to be CCDF-eligible (age + immigration)
  rather than allowing one child's enrollment to combine with a different
  child's eligibility (P3 fix).
- Only charge copay for non-Head-Start children when the unit qualifies
  through standard or protective pathway. Head Start-only units pay $0
  for uncovered siblings (P2 fix).
- Remove tier_count parameter (derived from bracket length).
- Simplify hhs_smi period access (auto-conversion).
- Comment out tanf from countable income sources to break circular
  dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Require is_tax_unit_dependent for child eligibility (Policy Manual
  2.1.7), matching all other CCAP implementations.
- Add age-6 threshold to age_group bracket so 6+ children always get
  AGE_5_12_IN_SCHOOL instead of AGE_5_NOT_IN_K when is_in_k12_school
  is false.
- Gate rate and copay on childcare_hours_per_week > 0 so children
  with no care arrangement get $0 rate and are not counted in copay.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ount to in-care children

- Move the 2% income cap from per-child weekly to total monthly family
  copay, so multi-child families are correctly capped.
- Compute youngest child for second-child discount only among children
  with childcare_hours_per_week > 0, so at-home siblings don't trigger
  the discount on in-care children.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Post-2024, only family sizes 1-14 have paid copay tiers; sizes 15-16
are $0-only in the published fee scale. Cap the FPL/SMI threshold
computation at max_family_size and exempt families above it. This also
prevents 17+ person units from getting extrapolated thresholds beyond
the published table.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hua7450 hua7450 marked this pull request as ready for review April 9, 2026 01:06
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 South Carolina CCAP (Child Care Assistance Program)

1 participant