Skip to content

Add Hawaii Child Care Assistance Program (CCAP)#8600

Open
hua7450 wants to merge 10 commits into
PolicyEngine:mainfrom
hua7450:hi-ccap
Open

Add Hawaii Child Care Assistance Program (CCAP)#8600
hua7450 wants to merge 10 commits into
PolicyEngine:mainfrom
hua7450:hi-ccap

Conversation

@hua7450

@hua7450 hua7450 commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements Hawaii's Child Care Assistance Program (Child Care Subsidy) in PolicyEngine. This is Hawaii's CCDF-funded child care subsidy: a multi-dimensional provider max-rate lookup combined with an 85%-State-Median-Income test and a sliding-fee co-payment computed as a percentage (0–9%) of the department's maximum rate. Eligibility, income, and co-payment rules come from HAR Title 17 Chapter 798.2; the provider payment rates come from HAR Title 17 Chapter 798.3, Exhibit I. The infant/toddler vs older rate is selected from the child's actual age (under 36 months) per HAR 17-798.3-2, matching how sibling CCAPs (NH, TX, AK, RI) derive an age category rather than baking age into a provider input.

Closes #8599

Regulatory Authority

Program Overview

  • Administration: State-administered by the Hawaii Department of Human Services, Benefit, Employment & Support Services Division (DHS BESSD). Legacy brand: "Child Care Connection Hawaii (CCCH)".
  • Funding: Federal Child Care and Development Fund (CCDF), 42 USC §9858.
  • Rates: Statewide — there is no island/county variation (CCDF State Plan §3.1.2.a "set statewide ☒ Yes").
  • Directory/prefix: gov.states.hi.bessd.ccap (variables prefixed hi_ccap).

Eligibility

Requirement Source How Modeled
Child under age 13 §17-798.2-9(a)(1) age < age/child_limit (13) in hi_ccap_eligible_child
Child 13–17 with a physical/mental incapacity §17-798.2-9(a)(2) is_disabled & (age >= child_limit) & (age <= age/disabled_child_limit) (17, inclusive)
Child receiving court-ordered child protective services §17-798.2-9(a)(3) receives_or_needs_protective_services (any age in program)
Income ≤ 85% State Median Income by family size §17-798.2-9(b)(1) hi_ccap_income_eligible: smi(size, state) × income/smi_rate (0.85) / 12 vs monthly countable income
Income test waived for CPS family units §17-798.2-9(b)(1)(B) income_eligible | has_protective_services in hi_ccap_income_eligible
Caretaker(s) in an approved activity §17-798.2-9(b)(2) hi_ccap_activity_eligible: every tax-unit head/spouse must be in a real activity (employed, full-time student, or receiving CPS), with the disability pathway handled as an activity link (see below)
Child satisfies CCDF immigration eligibility §17-798.2-1 (ties to 42 USC §9858) Reuses federal is_ccdf_immigration_eligible_child (not recreated)
Resource/asset test Federal CCDF Reuses federal is_ccdf_asset_eligible (not recreated)

Disability is an activity link, not a standalone activity. Per §17-798.2-9(b)(2)(H)/(I), an incapacitated caretaker qualifies the family only when the other head/spouse is in an approved activity. A single idle disabled caretaker — or two idle disabled parents — does not qualify. hi_ccap_activity_eligible models this by disqualifying the unit if any caretaker is neither in a real activity nor disabled, and additionally requiring at least one real-activity caretaker whenever a caretaker is disabled-and-inactive.

Age group (infant/toddler vs older). hi_ccap_age_group (Person, MONTH) classifies each child as INFANT_TODDLER when the child's age is under 36 months and OLDER otherwise. The 36-month boundary comes from HAR 17-798.3-2, which defines an infant and toddler center as serving children "six weeks to thirty-six months"; the cutoff is stored in age/infant_toddler_max_months.yaml (36). The model derives the age group from the child's actual age — rather than reading an age-encoded provider input — so the correct Exhibit I rate (infant/toddler vs older) is selected automatically, matching sibling CCAPs (NH, TX, AK, RI). The school-age before/after-school and intersession/summer provider categories are care-setting based (kindergarten age and above per HAR 17-798.3-2) and so are not driven by this age group.

Income

Countable income (hi_ccap_countable_income, SPMUnit, MONTH) is monthly gross income from all counted sources (§17-798.2-10(b)). It is implemented as a formula (not a pure adds list): the formula sums the counted sources from income/countable_income/sources.yaml, then excludes the employment and self-employment income of household members who are minors and full-time students per §17-798.2-11(8). The excluded types (§17-798.2-11) are otherwise simply omitted from the source list rather than subtracted inline.

Counted sources (mapped to PolicyEngine variables): employment_income, self_employment_income, sstb_self_employment_income, social_security_retirement, social_security_disability, social_security_survivors, ssi, dividend_income, interest_income, rental_income, pension_income, veterans_benefits, military_retirement_pay, unemployment_compensation, workers_compensation, alimony_income, child_support_received. (Recurring monthly SSI is counted; §17-798.2-11(5)(B) excludes only retroactive lump-sum SSI.)

Minor-student earnings exclusion (§17-798.2-11(8)): the formula subtracts the employment_income + self_employment_income of any household member who is both a minor (age < 18) and a full-time student. The 18-year cutoff comes from age/minor_age_limit.yaml (18), backed by HAR 17-798.3-2 ("Minor means a person under eighteen years old"); is_full_time_student is the available proxy for the regulation's "at least half-time student" condition.

Counted in the regulation but with no PolicyEngine equivalent (documented in comments, not modeled): railroad retirement (captured via social_security_*), temporary disability insurance, income from estates/trust funds, royalties, free rent converted to cost compensation (we don't track in-kind rent-for-activity at the moment), strike benefits (captured via unemployment_compensation).

Excluded by §17-798.2-11 (omitted from the list): capital gains, SNAP, WIC, USDA donated foods, EITC, Title IV HEA aid, half-time-or-more student-minor earnings, non-recurring lump sums, and others.

Conversion handling: the regulation's weekly/bi-weekly conversions (§17-798.2-10(a)(3)) are handled by the framework idiom — annual income sources are auto-divided to monthly because hi_ccap_countable_income is MONTH-defined and adds annual variables. The WEEKS_IN_YEAR / MONTHS_IN_YEAR factor is used explicitly in hi_ccap_monthly_care_hours and hi_ccap_authorized_activity_hours to convert weekly hours into the monthly-hour bands.

Provider Rates (Exhibit I, effective 2020-01-02)

Rates come from HAR 17-798.3 Exhibit I (effective 2020-01-02), which supersedes the earlier 2017-08-01 standalone rate table. Rates are statewide (no island/county variation), encoded as a single multi-breakdown parameter rates/rates.yaml keyed [hi_ccap_provider_category][hi_ccap_age_group][hi_ccap_hours_tier]: 8 provider types × 2 age groups × 2 hour tiers (Full-Time / Part-Time).

hi_ccap_provider_category is a direct input enum whose 8 members are provider types with no age baked in: LICENSED_CENTER_OR_GROUP_HOME, ACCREDITED_CENTER, NAFCC_ACCREDITED_FAMILY, REGISTERED_FAMILY, LEGALLY_EXEMPT, LICENSED_SCHOOL_AGE_INTERSESSION_SUMMER, LICENSED_BEFORE_AFTER_SCHOOL, EXEMPT_BEFORE_AFTER_SCHOOL. The infant/toddler vs older row of Exhibit I is selected from the child's actual age via hi_ccap_age_group (see the Age group note above) rather than from an age-encoded provider input — matching sibling CCAPs (NH, TX, AK, RI), which all derive an age category. The two hour tiers are resolved by hi_ccap_hours_tier from one of two monthly-hour band schemes:

  • Standard care (all rows except before/after-school): Full-Time 87+ monthly hours / Part-Time 1–86.
  • Before/After-School care: Full-Time 45+ monthly hours / Part-Time 1–44.

Band lower bounds are inclusive (exactly 87 hours = Full-Time; 86 = Part-Time).

Full rate table ($/month, provider type × age group × tier, two-pass vision-verified at 1200 DPI):

Provider type (enum) Age group Full-Time Part-Time
LICENSED_CENTER_OR_GROUP_HOME — Licensed center or group child care home Infant/Toddler 1,733 1,733
Older 795 795
ACCREDITED_CENTER — NAEYC/NECPA/Hawaiian-medium accredited center-based Infant/Toddler 980 980
Older 980 980
NAFCC_ACCREDITED_FAMILY — NAFCC accredited family child care home Infant/Toddler 750 750
Older 700 700
REGISTERED_FAMILY — Registered family child care home Infant/Toddler 650 362
Older 600 334
LEGALLY_EXEMPT — Legally exempt relative, non-relative, and center-based Infant/Toddler 400 223
Older 350 195
LICENSED_SCHOOL_AGE_INTERSESSION_SUMMER — Licensed school-age intersession/summer (care-setting) 450 350
LICENSED_BEFORE_AFTER_SCHOOL — Licensed before/after school (care-setting) 155 86
EXEMPT_BEFORE_AFTER_SCHOOL — Legally exempt before/after school (care-setting) 120 61

The first 5 provider types use the standard hour bands and vary by age group (infant/toddler vs older). The last 3 are care-setting categories (kindergarten age and above per HAR 17-798.3-2): the two before/after-school types use the before/after-school hour bands, and the intersession/summer type uses the standard bands; none of the three vary by age group.

Benefit Calculation

effective_care_hours          = min(child's monthly care hours,            # HAR 17-798.2-14(b)(1)
                                     caretaker's authorized activity hours) # lesser-of
hours_tier                     = band(effective_care_hours)                # FULL_TIME / PART_TIME
age_group                      = INFANT_TODDLER if age < 36 months         # HAR 17-798.3-2
                                 else OLDER
hi_ccap_maximum_monthly_rate   = rates[provider_category][age_group][hours_tier]  # Exhibit I
                                 (= 0 if effective_care_hours < 1)         # zero-hour gate
capped_expenses                = min(spm_unit_pre_subsidy_childcare_expenses, # actual cost
                                     sum of maximum_monthly_rate)          # vs dept max rate
copay                          = sum(maximum_monthly_rate) × copay_rate    # §17-798.2-14(b)(4)
hi_ccap (MONTH)                = max(capped_expenses − copay, 0)
  • Activity-hours cap (§17-798.2-14(b)(1)): the rate tier is driven by the lesser of the child's monthly care hours (childcare_hours_per_week → monthly) and the caretaker's authorized monthly activity hours. For a two-parent unit the binding constraint is the caretaker with the fewest hours (min-of-parents, analogous to NH CCAP He-C 6910.07(p)). Employed caretakers cap the tier by their work hours; non-work activities (school, disability, protective services) have no tracked hour count and so are non-binding. Caretaker work hours read weekly_hours_worked_before_lsr to avoid a circular dependency with labor-supply responses.
  • Zero-hour gate: Exhibit I's Part-Time band starts at 1 monthly hour, so a child with less than 1 effective monthly care hour (no care need) receives $0 in hi_ccap_maximum_monthly_rate.
  • Lesser-of (§17-798.2-13(a)): the subsidy is capped at the lesser of the department's Exhibit I max rate and the family's actual childcare cost.
  • Co-payment (§17-798.2-14(b)(4)): copay = department's maximum rate allowable × copay% — the percentage multiplies the provider max rate, NOT gross income.
  • Copay % (copay/rate.yaml): a single family-size-independent bracket on the family's gross income as a share of FPG, ranging 0% (≤100% FPG) up to 9% in 1-point steps per the Exhibit II bands. The per-family-size dollar columns in Exhibit II are just FPG × band, so the percentage is a pure function of the income/FPG ratio. Band-top thresholds use X.0001 so a family at exactly a band top lands in the lower band.
  • 85% SMI cap: the income limit is computed as the federal smi() helper × 0.85 (parameterized via income/smi_rate.yaml), so the limit tracks HHS State Median Income by year (NJ CCAP pattern) rather than freezing a dollar table.

Not Modeled

What Source Why Excluded
Foster-parent income-test waiver §17-798.2-9(b)(1)(A) No licensed-foster-parent input exists at the moment (is_in_foster_care marks a child in care, not a foster-parent caretaker). The CPS-family waiver under (b)(1)(B) is modeled.
Activity pathways for short-term job offers, employment breaks, job search, first-to-work, and protective-order day care §17-798.2-9(b)(2)(B)–(J) No inputs for job-offer timing, FTW participation, POD approval, or short temporal windows we don't track at the moment. Core work/school/training and the protective-services and disability-link pathways are modeled.
Provider age 18+, licensing, background/abuse/FBI/TB checks, caretaker-relationship exclusions §17-798.2-9(c) Provider compliance attributes are not simulatable. The provider category (which drives rates) is modeled as an input enum.
One-time registration payment ≤ $125/fiscal year §17-798.2-13(b)(1) Provider-side payment, not a monthly household benefit; no fiscal-year-cumulative tracking.
12-month redetermination §17-798.2-16 Administrative process, not a benefit calculation.
Hawaii public assistance / TANF counted as income §17-798.2-10(b)(11) Counted by the regulation, but omitted from CCAP countable income to avoid the CCAP↔TANF circular dependency (CCAP income → tanf → TANF dependent-care deduction → childcare_expenseschild_care_subsidies → CCAP). TANF families fall below the lowest copay band, so the omission does not change their subsidy in practice.
Out-of-state public assistance; adoption assistance counted as income §17-798.2-10(b)(10), (12) Counted by the regulation, but no clean PolicyEngine income input exists.

Historical / Verification Notes

  • Rate era: the operative rates are the 2020-01-02 Exhibit I rates from HAR 17-798.3 (parameter effective date 2020-01-02). This supersedes the earlier 2017-08-01 standalone Exhibit I rate table and the still-earlier 2009 codified Exhibit I, which are earlier eras out of scope here. The rate table was restructured from the 2017 era's four hour tiers (Full-Time / Two-Thirds / One-Third / Casual) to the 2020 era's two tiers (Full-Time / Part-Time).
  • Age in rates is derived, not input: Exhibit I prints separate infant/toddler and older rows for each provider type. Rather than encode that age split into the provider input enum, the model keeps 8 age-free provider types and selects the infant/toddler vs older row from the child's actual age (hi_ccap_age_group, boundary 36 months per HAR 17-798.3-2). This mirrors how NH, TX, AK, and RI CCAPs derive an age category.
  • before_lsr choice: both the caretaker work-hours read (for the activity-hours cap) and the activity test use weekly_hours_worked_before_lsr rather than the post-response hours, to avoid a circular dependency with behavioral labor-supply responses.
  • 85% SMI: the income limit is computed as the federal smi() helper × 0.85 (parameterized via income/smi_rate.yaml), so values track HHS State Median Income by year rather than freezing a dollar table from Exhibit II or the CCDF plan (which report different HHS SMI years).
  • Pending policy (not enacted): a HAR 17-798.3 amendment to lower the copay cap from 9% to 7% (a federal CCDF 2024 requirement) was pending AG review as of the FFY2025-2027 plan. This is not yet enacted, so the current 9% cap is modeled.
  • Source verification: the Exhibit I rate table was two-pass vision-verified at 1200 DPI; the Exhibit II fee/income scale was transcribed from a scanned single-page chart (no text layer). Single-page scanned PDFs carry no #page= anchor; the multi-page HAR rules and HAR 798.3 payments PDFs use verified #page=XX anchors.

Files Added

changelog.d/hi-ccap.added.md

policyengine_us/parameters/gov/states/hi/bessd/ccap/
  age/child_limit.yaml                    # 13
  age/disabled_child_limit.yaml           # 17
  age/infant_toddler_max_months.yaml      # 36 (infant/toddler vs older boundary)
  age/minor_age_limit.yaml                # 18 (minor-student earnings exclusion)
  income/smi_rate.yaml                    # 0.85
  income/countable_income/sources.yaml    # positive counted-income list
  rates/rates.yaml                        # [provider_category][age_group][hours_tier], Exhibit I 2020-01-02
  hours_tier/standard.yaml                # 87+/1-86 → tier enum
  hours_tier/before_after.yaml            # 45+/1-44 → tier enum
  copay/rate.yaml                         # 0–9% copay% by FPG ratio

policyengine_us/variables/gov/states/hi/bessd/ccap/
  hi_ccap.py                              # SPMUnit MONTH subsidy
  hi_child_care_subsidies.py              # SPMUnit YEAR aggregator
  hi_ccap_countable_income.py             # SPMUnit MONTH countable income (formula: sources − minor-student earnings)
  hi_ccap_provider_category.py            # Person MONTH input enum, 8 provider types (no age)
  hi_ccap_age_group.py                    # Person MONTH enum, INFANT_TODDLER vs OLDER (age < 36 months)
  hi_ccap_hours_tier.py                   # Person MONTH tier enum from brackets
  hi_ccap_maximum_monthly_rate.py         # Person MONTH rate lookup + zero-hour gate
  hi_ccap_monthly_care_hours.py           # Person MONTH effective care hours (lesser-of)
  hi_ccap_authorized_activity_hours.py    # SPMUnit MONTH caretaker activity hours (min-of-parents)
  copay/hi_ccap_copay.py                  # SPMUnit MONTH = max rate × copay%
  copay/hi_ccap_copay_rate.py             # SPMUnit MONTH copay% from FPG ratio
  eligibility/hi_ccap_eligible.py         # SPMUnit MONTH (combine)
  eligibility/hi_ccap_eligible_child.py   # Person MONTH (age/disability/CPS/immigration)
  eligibility/hi_ccap_income_eligible.py  # SPMUnit MONTH ≤85% SMI
  eligibility/hi_ccap_activity_eligible.py# SPMUnit MONTH activity test (disability activity-link)

policyengine_us/tests/policy/baseline/gov/states/hi/bessd/ccap/
  hi_ccap.yaml
  hi_child_care_subsidies.yaml
  hi_ccap_countable_income.yaml
  hi_ccap_age_group.yaml
  hi_ccap_authorized_activity_hours.yaml
  hi_ccap_monthly_care_hours.yaml
  hi_ccap_hours_tier.yaml
  hi_ccap_maximum_monthly_rate.yaml
  integration.yaml
  copay/hi_ccap_copay.yaml
  copay/hi_ccap_copay_rate.yaml
  eligibility/hi_ccap_eligible.yaml
  eligibility/hi_ccap_eligible_child.yaml
  eligibility/hi_ccap_income_eligible.yaml
  eligibility/hi_ccap_activity_eligible.yaml

Registry edits:
  policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml  # + hi_child_care_subsidies
  policyengine_us/programs.yaml                                            # + HI state_implementation (status: complete)

Test plan

  • 130 tests pass locally (full HI CCAP suite: policyengine-core test policyengine_us/tests/policy/baseline/gov/states/hi/bessd/ccap/ -c policyengine_us)
  • Added coverage since the prior revision: the minor-student income exclusion (hi_ccap_countable_income.yaml), the two hours-helper unit tests (hi_ccap_authorized_activity_hours.yaml, hi_ccap_monthly_care_hours.yaml), the hi_ccap_age_group.yaml 36-month boundary, and a before/after-school activity-hours-cap case.
  • CI passes

hua7450 and others added 3 commits June 7, 2026 20:41
Scaffolds the branch and draft PR for implementing Hawaii's Child Care
Assistance Program (CCAP). Implementation to follow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

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

Additional details and impacted files
@@             Coverage Diff              @@
##             main     #8600       +/-   ##
============================================
+ Coverage   77.77%   100.00%   +22.22%     
============================================
  Files           1        15       +14     
  Lines           9       243      +234     
============================================
+ Hits            7       243      +236     
+ Misses          2         0        -2     
Flag Coverage Δ
unittests 100.00% <100.00%> (+22.22%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 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 5 commits June 7, 2026 22:38
Round 1 /review-program safe fixes (0 critical found):
- Tests: asset-eligibility-false, protective-services activity, income-only employment
- Annotations: Exhibit III->2020 fee scale supersession, Exhibit II label, 2017 rate-table provenance, military_retirement_pay/SSI income comments

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ity activity-link

Addresses 3 P1 findings:
- FIX A: child with <1 effective monthly care hour pays $0 (Exhibit I casual band starts at 1 hr)
- FIX B: rate tier = lesser of care hours and caretaker activity hours (HAR 17-798.2-14(b)(1)),
  via new hi_ccap_monthly_care_hours + hi_ccap_authorized_activity_hours (min-of-parents)
- FIX C: disability is not a standalone activity; qualifies only via an activity link
  per HAR 17-798.2-9(b)(2)(H)/(I)
- All caretaker work-hours reads use weekly_hours_worked_before_lsr (avoids LSR circularity)

133 tests passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 2017-08-01 4-tier/9-category rate table is superseded by the current
2020-01-02 Exhibit I in HAR 17-798.3: a 2-tier (Full-Time 87+ / Part-Time 1-86
monthly hours; before/after-school 45+/1-44) x 12-category structure. Adds
Hawaiian-medium, NAFCC-accredited family, registered family, and school-age
intersession/summer categories; values updated (e.g. center infant/toddler
$1,490 -> $1,733). Rebuilt provider-category and hours-tier enums, rate table
(24 cells, two-pass verified at 1200 DPI), hours brackets, and all tests.

115 tests passing.

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

Adds hi_ccap_age_group (infant/toddler if age < 36 months per HAR 17-798.3-2,
else older), matching the sibling-CCAP pattern (NH/TX/AK/RI age categories).
Collapses hi_ccap_provider_category from 12 age-specific members to 8 provider
types; rates re-keyed [provider_category][age_group][hours_tier]. The model now
picks the infant/toddler vs older Exhibit I rate from the child's actual age
rather than trusting an age-encoded input. 121 tests passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hua7450 hua7450 marked this pull request as ready for review June 8, 2026 19:49
hua7450 and others added 2 commits June 8, 2026 16:02
…hours-helper tests

Addresses /review-program SHOULD-ADDRESS findings:
- S1(a): hi_ccap_countable_income now excludes earnings of household minors
  (age < 18) who are full-time students, per HAR 17-798.2-11(8) (was an
  unexecuted comment). Adds minor_age_limit parameter (18, HAR 17-798.3-2).
- S1(b): documents that HAR 17-798.2-10(b)(11) Hawaii public assistance (TANF)
  is omitted from countable income to avoid the CCAP<->TANF circular dependency.
- S2/S3/S4: dedicated unit tests for hi_ccap_authorized_activity_hours
  (np.inf non-binding path + two-parent min) and hi_ccap_monthly_care_hours
  (child-hours-bind direction), plus a before/after-school activity-cap case.

130 tests passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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 Hawaii Child Care Assistance Program (CCAP)

1 participant