Implement Arkansas School Readiness Assistance (SRA / formerly CCAP)#8324
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8324 +/- ##
============================================
+ Coverage 78.70% 100.00% +21.29%
============================================
Files 4750 20 -4730
Lines 69270 324 -68946
Branches 341 1 -340
============================================
- Hits 54517 324 -54193
+ Misses 14675 0 -14675
+ Partials 78 0 -78
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:
|
- Delete reinvented is_ar_sra_asset_eligible; delegate to federal is_ccdf_asset_eligible - Add ar_child_care_subsidies to gov/hhs/ccdf/child_care_subsidy_programs.yaml - Register AR SRA in programs.yaml under CCDF state implementations - Align in_effect.yaml start date to 2025-11-01 to match published rate sheets (Oct 2025 had different transitional rates and is documented as not-modeled)
…st.md - Delete orphan parameter income/excluded_sources.yaml (never referenced). - Rename was_tea_recipient/months_since_tea_exit → ar-prefixed for namespace. - LI activity: use age>=18 (not is_tax_unit_head_or_spouse); OR in meets_ccdf_activity_test fallback for unmodeled activities. - ESS activity: mask weekly_hours_worked to adults so working teens don't satisfy the threshold. - ar_sra: read pre_subsidy_childcare_expenses at period (auto-divides annual→monthly); drop redundant manual /MONTHS_IN_YEAR. - Compare monthly income vs monthly SMI in is_ar_sra_income_eligible and ar_sra_income_tier (single conversion instead of annualization). - Sweep parameter descriptions to use allowed verbs (limits / provides / sets / excludes / deducts / uses). - Remove absolute_error_margin from boolean-output test files. All 80 AR SRA tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tier 1 — Honest references (drop or reframe phantom citations): - age_category_months.yaml: replace FSU §4.1 (doesn't define month boundaries) with the rate sheet (establishes the age-category labels) and strengthen the inline note that month boundaries are peer-state convention, not AR source. - full_time_hours_threshold.yaml: keep rate-sheet citations but retitle to make clear they establish FT/PT as billing categories — the 30-hour cutoff itself is peer-state convention. - child_age_limit.yaml, is_ar_sra_age_eligible.py, is_ar_sra_child_eligible.py: drop FSU co-citation (FSU §4.1 doesn't state the age-13 rule; only Title 016 §3.1.4 does). The two .py files also disagreed on which FSU page (13 vs 14). - base_rate.yaml: add top-of-file note that PT NIGHT_WEEKEND cells mirror PT REGULAR as a fallback — the source rate sheets have no PT N/W row. Tier 3 — Polish: - ar_sra.py: add clarifying comments on the YEAR→MONTH conversions for pre_subsidy_childcare_expenses (auto-divides at MONTH period) and childcare_attending_days_per_month (read at this_year to preserve count semantics). - Standardize absolute_error_margin to 0.1 across all currency rate tests (was 0.01, inconsistent with project convention of 0.1). - Expand variable-file reference tuples to cite all 4 rate-sheet PDFs (Statewide FT/PT + Benton-Washington FT/PT) — variables previously cited a subset of what the YAML cited. 80/80 AR SRA tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Revert 4-PDF reference expansion in 4 rate variable files (ar_sra_daily_base_rate / daily_copay / daily_state_payment / state_share). Each variable does a parameter lookup; the YAML files already cite all 4 rate sheets as the authoritative source. Restore a single canonical URL per variable. - Drop tuple wrapper from ar_sra_care_type.py and ar_sra_age_category.py which had `reference = ( "single_url", )` — string is the convention for a single reference. - Trim no_copay_smi_threshold.yaml and partial_subsidy_smi_threshold.yaml from 2 refs to 1 — the income-tier headers (40%, 60%) appear identically on the FT and PT rate sheets so a second citation is redundant. 80/80 AR SRA tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add 17 test cases targeting BLOCKER and HIGH-priority gaps from the round-3 review pass: integration.yaml (6 new cases): - Case 9: SN2 special-needs care exercises non-REGULAR care type path - Case 10: low monthly expense ($300) binds before the state payment cap - Case 11: mixed-eligibility household (one 4-year-old, one 13-year-old) confirms per-child masking in the spm_unit.sum - Case 12: zero attending days produces $0 benefit despite eligibility - Case 13: school-aged child at LE_40 SMI confirms 80% state share flows through to a non-zero benefit (always-copay rule) - Case 14: part-time infant care exercises the PT category path ar_sra_li_activity_eligible.yaml (2 new cases): - Case 6: meets_ccdf_activity_test fallback for unmodeled activities - Case 7: mixed work + full-time-student adult exemption ar_sra_ess_eligible.yaml (4 new cases): - Case 6: month 12 is last Year-1 month, 20 hr threshold satisfied - Case 7: month 24 is last in-window month, 25 hr threshold satisfied - Case 8: month 25 is past the window, household not eligible - Case 9: working teen does not satisfy threshold when adult masked hours fall below — exercises the adult-only hours masking ar_sra_income_tier.yaml (4 new cases): - Cases 4-5: 40% SMI boundary (LE_40 just under, GT_40_LE_60 just over) - Cases 6-7: 60% SMI boundary (GT_40_LE_60 just under, GT_60 just over) ar_sra_eligible.yaml (1 new case): - Case 6: high assets ($2M) above CCDF asset limit fails eligibility Total: 97/97 AR SRA tests pass (was 80/80). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… should) Critical: - Add 4% SPM-unit copay cap (CCDF State Plan §3.1.1; AR self-cert under federal 7%). New max_copay_share_of_gross_income parameter; ar_sra.py adds cap_savings to subsidy when rate-sheet copays exceed the ceiling. Updated integration Cases 1/2/5/13 with cap-adjusted values; added multi-child cap-binding Case 18. - Parameterize adult age threshold (18) via new eligibility/adult_age_threshold.yaml; removed hardcoded 18 from ar_sra_countable_income, is_ar_sra_ess_eligible, is_ar_sra_li_activity_eligible. - Register ar_child_care_subsidies in household_state_benefits.yaml. - Add ESS boundary + below-threshold tests (month 13 with 20/25 hr, 19/24 hr below-threshold). - Cover all 24 state_share keys (added Cases 5-24 covering INFANT and PART_TIME branches). - Add is_ar_sra_eligible: false to integration Case 8 (non-AR). - Add NIGHT_WEEKEND / SN1 / SN3 integration cases (REQ-021). Should-Address: - FT threshold corrected to 35 hr/wk (≈ 5 × 7 hr/day per FSU §5.4.6). - ESS Year-2 activity adds is_full_time_student OR-clause; Year-1 TEA-income-ineligible alt path documented as unmodeled. - Strip trailing zeros across rates YAMLs; remove empty edge_cases dir; add #page=1 anchor on OEC announcement; remove redundant ACF reference. - Rewrite is_ar_sra_eligible scalar return as AND-chain; trim verbose comments in ar_sra_age_category and ar_sra_zone. - Test gaps: zero-adult LI case, age-category month boundaries (17/18, 35/36, 71/72), PT NIGHT_WEEKEND fallback, BW SN2 + NIGHT_WEEKEND, new ar_sra_care_type test file. 140/140 AR SRA tests pass; household_state_benefits tests unaffected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Critical: 0 (none introduced). Should-Address: - Tighten student OR-clause from is_full_time_student to is_full_time_college_student (FSU §4.1.5.4 converts via post-secondary credit hours, not K-12 enrollment). Applies to both LI and ESS tracks. - ESS Year-1 student OR-clause was asymmetrically missing — make Year-1 symmetric with Year-2 (FSU §4.1.5.2 / R&R Nov 2025 both authorize full-time school as Year-1 path). - Restore is_ar_sra_eligible early-return guard (project standard; matches CT/MT/SC/UT pattern, broadcast-safe with YEAR-period in_effect lookup). - ar_sra.py: clamp countable income at 0 before computing copay ceiling (prevents cap_savings inflation on negative income). Add min_(total_uncapped_subsidy + cap_savings, total_expense) clamp so total subsidy never exceeds actual childcare cost. - in_effect.yaml: change from period: year to period: month so the Nov 1, 2025 start date isn't backdated to Jan 1, 2025 by year-period lookup. Drop duplicate Case 3 from in_effect tests. - adult_age_threshold.yaml: cite FSU §4.3 (p.19) which contains the explicit "age eighteen (18) years and over" language (was §4.3.2). - full_time_hours_threshold.yaml: cite FSU §5.4.6 Authorization Care Types table (p.30) rather than the section header (p.29). - ar_sra_child_eligible.yaml: fix header that claimed "tax-unit dependent" check (formula doesn't check it). - Add tests: ESS Year-1/Year-2 student satisfies activity (Cases 14/15), ESS months_since=0 boundary (Case 16), exact 40%/60% SMI tier boundaries (Cases 8/9), zero-expense integration clamp guard (Case 19), negative-income regression guard (Case 20). 146 AR SRA tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Spell out "Employment-Sponsored Subsidy" instead of "ESS" acronym in 3 parameter descriptions (ess_window_months, activity_hours_ess_year_1, activity_hours_ess_year_2). - Simplify hhs_smi access in is_ar_sra_income_eligible and ar_sra_income_tier: drop the explicit period.this_year + /MONTHS_IN_YEAR pattern in favor of reading the YEAR-defined hhs_smi at MONTH period (core auto-converts the USD flow variable annual->monthly). 146 AR SRA tests pass; all critical and should-address findings from multi-round /review-program now cleared. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch FT classification to per-day (FSU §5.4.6 literal): - ar_sra_time_category now reads childcare_hours_per_day; threshold = 7. - Updates ~50 test inputs from childcare_hours_per_week to childcare_hours_per_day. - Fixes the 4-day × 8-hour case that was misclassified as PT under the per-week proxy. Reference / citation fixes: - ess_window_months page anchor 26 → 27 (where 24-month value displays). - adult_age_threshold title: §4.3 "Countable Income" → §4.3 "Income". - full_time_hours_threshold title: §5.4.6 "Authorization Care Types" → "Level of Care Authorized". - income_smi_rate page anchor 22 → 21 (where section header appears). - in_effect: drop #page=1 from the one-page OEC Announcement. Code style (drop multi-line "what" comments, add explanatory NOTEs): - ar_sra.py: trim CCDF Plan and clamp comments; add NOTE on the final expense clamp. - ar_sra_zone, is_ar_sra_ess_eligible, is_ar_sra_li_activity_eligible, ar_sra_countable_income: trim multi-line comments per code-style skill. - is_ar_sra_income_eligible, ar_sra_income_tier: add hhs_smi auto-divide NOTE. Move hard-coded Benton/Washington counties to a list parameter: - New rates/benton_washington_counties.yaml; ar_sra_zone uses np.isin lookup. Test additions / fixes: - $1M asset boundary tests (exact, +$1, -$1) added to ar_sra_eligible.yaml. - Fold ar_sra_in_effect.yaml into ar_sra_eligible.yaml; remove the standalone file. - Reconcile SMI documentation across integration.yaml and ar_sra_state_share.yaml (use uprated $95,201.95 to match hhs_smi at 2026-01-01). - Add just-below 85% SMI boundary case to ar_sra_income_eligible.yaml. - Clarify ESS Case 16 (months_since_tea_exit = 0 = still on TEA, not yet in window). - absolute_error_margin: 0.1 → 0.01 (currency tests); strip 0.1 from Enum-output tier file (no margin needed); rate-output state_share keeps 0.001. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t path, Night/Weekend coercion
Substantive behavior changes (4 review-finding items resolved):
1. **4% cap base switched to gross income** (CCDF State Plan §3.1.1 literal):
- New `ar_sra_gross_income` mirrors `ar_sra_countable_income` but does NOT
exclude children's SSI / Social Security (the FSU §4.3.2 exclusion is
for the countable-income tier, not the per-family copay ceiling).
- `ar_sra.py` uses `ar_sra_gross_income` as the 4% cap denominator.
2. **Age-13+ disability extension** (CCDF State Plan §2.2.1):
- New `child_age_limit_disabled = 18` parameter.
- `is_ar_sra_age_eligible.py` uses the higher limit when `is_disabled`.
- 3 new test cases (disabled child 15 eligible, non-disabled 15 not, age 18 boundary).
3. **ESS Year-1 TEA-income-ineligibility alt path** (FSU §4.1.5.1):
- `is_ar_sra_ess_eligible.py` Year-1 activity OR-clauses `~ar_tea_income_eligible`.
- Year-2 unchanged (FSU §4.1.5.2 does not have the alt path).
- 3 new test cases (Y1 alt path triggers, Y1 work-hours fallback fails when
TEA-income-eligible, Y2 does not include alt path).
4. **Night/Weekend rates coerced to FT-only** (OEC Oct 7 2025 Provider Call):
- Per OEC, Night/Weekend is a separate 5th service category priced at 110%
of FT typical rates — not a FT/PT subdimension.
- `ar_sra_daily_base_rate.py` overrides time-category lookup to FT when
care_type is NIGHT_WEEKEND.
- Test Case 14 (PT NIGHT_WEEKEND infant) expected value updated from
$18 (old PT REGULAR fallback) to $39.60 (Night/Weekend FT rate).
Source-research updates:
- `age_category_months.yaml` reference updated from peer-state convention
flag to AR Minimum Licensing Requirements (DCCECE 2020) for Infant/Toddler
boundaries plus Ark. Code 6-18-207 for kindergarten/School-Age boundary.
- `is_ar_sra_age_eligible.py` reference expanded to include CCDF State Plan
§2.2.1 (disability extension authority).
- `ar_sra_daily_base_rate.py` reference expanded to include OEC Provider Call
10.7.25 (Night/Weekend category definition).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves the 3 remaining "Verification TODO" items from the PR description. No formula or parameter-value changes — research-only round. - ar_sra_care_type.py: add FSU Procedural Manual §5.6.1 page-32 reference and a 4-line comment documenting SN1/SN2/SN3 criteria. SN level is set by a licensed medical practitioner's documentation per FSU §5.6.1; not derivable from any current PolicyEngine input. Variable remains a bare Enum input. - activity_hours_li.yaml: 2-line comment clarifying the 30 hr/wk applies to LI track only (ESS year-1 and year-2 thresholds live in separate parameter files). Verified separately (no change needed): - state_share_by_tier.yaml SCHOOL_AGED + LE_40 already gives 0.8/0.7 state share (not 1.0), matching OEC Oct 1 2025 deck's "$4.65 copay on $15.50 rate". No school-aged $0-copay bug. - base_rate.yaml already reflects Oct 1 2025 SN simplification: SN1 = REGULAR; SN2 = SN3 = REGULAR x 1.4 across all zones/ages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- child_age_limit_disabled: 18 -> 19 per FSU §5.6.1 ("under nineteen")
and CCDF State Plan §2.2.1 ("below age 19").
- Night/Weekend rate: populate PT N/W cells as PT REGULAR * 1.10 per
Provider Call slide 4 ("+10% on typical rates"); remove FT-coercion
override in ar_sra_daily_base_rate formula that doubled the PT rate.
- income_smi_rate reference: #page=21 -> #page=22 (§2.2.4 header location).
- Promote dese.ade.arkansas.gov CCDF State Plan as primary source for
child_age_limit{,_disabled} (drop publichealthlawcenter.org aggregator).
- Add ar_sra unit test (5 cases): baseline, total_expense clamp,
zero-expense clamp, 4% gross-income cap binding, negative-income clamp.
- Add ar_sra_gross_income unit test (4 cases): adult-only, child SSI
inclusion (vs countable exclusion), child SSDI inclusion, defined_for guard.
- Repair pre-existing ESS Year-1 alt-path test: use
employment_income_before_lsr (the variable tanf_gross_earned_income
actually reads), not employment_income, so TEA-income-ineligibility
is correctly triggered.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PavelMakarchuk
left a comment
There was a problem hiding this comment.
Program Review — PR #8324: Arkansas School Readiness Assistance (SRA)
Source Documents
- 9 PDFs reviewed:
- CCDF State Plan FFY 2025-2027 (171 pages)
- DHS-DCCECE Families Service Unit (FSU) Manual, June 2023 (49 pages)
- HHS State Median Income (SMI) Chart 2025 (1 page)
- 4 Sliding Fee Scale rate sheets (Statewide FT/PT, B/W FT/PT — 1 page each)
- DCCECE R&R Notice Nov 2025 (2 pages)
- DCCECE Provider Call Slides, October 2025 (36 pages)
- Year coverage: Effective
2025-11-01. Pre-2025 CCAP era explicitly deferred to follow-up via anin_effectgate. - Effort scale: 6,070-line diff across 62 files. CI: all PASS.
Critical (Must Fix Before Merge)
None. All three reconciliation items the author flagged for reviewer attention were investigated and verified defensible (see "Investigated and Cleared" below).
Should Address
-
Changelog filename typo —
changelog.d/ar-ccap.added.mdshould bear-sra.added.md. The program is School Readiness Assistance, not CCAP (CCAP is the pre-2025 era explicitly deferred). Same pattern as the AL CCSPal-ccaptypo found in PR #8322. -
max_copay_share_of_gross_income.yamlperiod mismatch — Declaredperiod: yearbut applied to a monthly base inar_sra.py. The share is unit-agnostic so arithmetic is correct, but metadata should beperiod: month(oreternity) for clarity and to avoid misleading future maintainers. -
pre_subsidy_childcare_expensesaccess pattern — Accessed withMONTHperiod inar_sra.py:5507though the variable isYEAR. Works via auto-conversion, but inconsistent with the AL/NH precedent of using.this_year. Align with peer-state pattern for clarity. -
ar_child_care_subsidiesaggregator missingreferencefield — Aggregator variable should cite the federal aggregation pattern or the SRA program reference for traceability. -
G5 — LI activity test possibly over-lenient —
is_ar_sra_li_activity_eligibleORs inmeets_ccdf_activity_testas a fallback. Per FSU §4.1.5 + R&R, LI requires ALL adults to meet a 30 hr/wk activity floor; the federal fallback may admit weaker activity definitions. Verify this is intentional flexibility or tighten by removing the fallback for the LI branch. -
income/sources.yaml— Add an explicit FSU §4.3.3 (#page=20) reference for the child SSI/SS exclusion rule. Currently the exclusion is encoded but the citation pointer is loose. -
rates/base_rate.yaml— Add a Provider Call PDF (#page=4) reference documenting the derivation of the +10% Night/Weekend and +40% Special Needs (SN2/SN3) multipliers. -
eligibility/ess_window_months.yamlcitation anchor — The manifest places the 24-month value on FSU p14, but the YAML cites §5.4.1. Verify the correct anchor and align. -
$31 vs $28 School-Aged FT base — Provider Call slides show School-Aged FT base = $31, but the Nov 1 rate sheet shows $28. The PR uses $28 (correct, since rate sheets are operative). Add an inline comment in
base_rate.yamlorar_sra_daily_base_rate.pydocumenting this reconciliation so future updates do not "fix" it back to $31. -
Missing test — 70% SMI fixture asserting non-zero copay — Locks in the 75% State Plan no-cost waiver as intentionally deferred behavior.
-
Missing test — Adult age 17 vs 18 threshold — Currently only implicated via teen-masking in Case 9; add a direct boundary test.
-
Missing test — Income source fixtures for adult SSI/SS counted — Currently only
employment_incomeis exercised; need fixtures confirming adult SSI/SS feed into countable income while child SSI/SS are excluded. -
Self-employment "@ federal minimum wage" floor (FSU §4.3.6 p21) not enforced — Documented limitation, acceptable but worth surfacing in a changelog note or a TODO comment.
-
Combined work/school formula (FSU §4.1.5.4 — hours × 2.5) not modeled — Documented limitation, acceptable as Phase-1 scope.
Suggestions
- Optional decomposition of the dense
ar_sraformula into named intermediate variables for readability (long expression nesting in the main copay/subsidy formula). - Reconciliation comments could cross-reference parameter YAML headers (bi-directional pointers between code and parameters).
ar_sra_age_categoryusesage * MONTHS_IN_YEAR— loses sub-year resolution. This is apolicyengine-corelimitation, not a PR bug; document inline.ar_sra_zonehas an explicitstate == "AR"runtime guard inside the formula (defense-in-depth beyonddefined_for). Intentional, OK to keep — note as a pattern.activity_hours_ess_year_2.yamlcites §4.1.5.1; could additionally cite §4.1.5.2 for completeness.- Add a 2025 whole-year date-boundary test (around the 2025-11-01 cutover).
- Add an ESS Yr2 26-hr symmetric test (currently tests 25; symmetric coverage at 26 helps).
- Add an integration test combining the 4% cap with child-SSI exclusion.
- Add an unknown-county zone-default test.
- Add an explicit "12 = half of 24" comment for
ess_year_1_window_months.yaml. - Add a CCDF Plan citation for the B/W zone distinction (Benton + Washington counties).
Investigated and Cleared
The author explicitly flagged three reconciliation items in the PR description. All three were investigated and found defensible:
-
4% copay cap base "gross" → countable income — Using
ar_sra_countable_income(adult-only) is defensible. FSU §4.3.3 unconditionally excludes children's SSI/SS; FSU Glossary p43 defines "gross" as "before tax deductions UNLESS EXCLUDED", which supports treating the cap base ascountable_incomerather than rawgross_income. No change required. -
ESS Year-1 alt path "earnings alone" → earned-only income — Gating on
ar_tea_countable_earned_income > tea_income_limit(NOT~ar_tea_income_eligible) correctly honors the FSU §4.1.5.1 verbatim phrase "earnings ALONE". Verified by tests:- Case 17, Case 19, Case 20 exercise this branch.
- Case 20 specifically confirms that unearned-only income does not trigger the alt path.
No change required.
-
75% SMI no-cost waiver NOT modeled — The PR follows operational rate sheets (≤40% SMI only) rather than State Plan §2.3.1(b)'s priority-group waiver up to 75% SMI. Defensible because the rate sheets are the operative pricing document; the §2.3.1(b) waiver is a separate priority-group mechanism. Author documents this in
no_copay_smi_threshold.yamlandar_sra_daily_copay.py. Recommend a follow-up issue to track the deferred §2.3.1(b) waiver implementation.
PDF Audit Summary
| Category | Result |
|---|---|
| Confirmed correct | ~150 data points across 15 categories |
| Mismatches | 0 |
| Reconciliation items defensible | 3 |
What was verified exactly:
- 80 base-rate cells across Statewide FT/PT + B/W FT/PT × Infant/Toddler/Preschool/School-Aged × Regular/Night-Weekend/SN1/SN2/SN3.
- 24 state-share cells across 2 time × 4 age × 3 income tiers.
- Care-type multipliers: Night/Weekend = Regular × 1.10; SN1 = Regular; SN2 = SN3 = Regular × 1.40.
- PT = ½ FT per Provider Call methodology — confirmed via direct rate-sheet comparison.
- Age categories: 0–17 mo / 18–35 mo / 36–71 mo / 72+ mo (Core month-resolution limitation noted).
- 85% SMI ceiling matches federal
hhs_smiexactly (Family 1: $3,325.31; Family 2: $4,348.49; Family 3: $5,371.66). - $1M asset limit via federal
is_ccdf_asset_eligiblereuse. - Child age 13 standard, 19 disabled extension.
- Citizenship: child-only via
is_ccdf_immigration_eligible_childreuse; parents NOT required. - LI 30 hr/wk all-adults pattern.
- ESS Yr1 20 hr/wk any-adult OR FT student OR earnings-alone alt path.
- ESS Yr2 25 hr/wk any-adult.
- ESS window 24 months; Yr1 = months 1–12; Yr2 = months 13–24.
- Adult age threshold = 18.
- 4% copay cap formula with per-child clamping.
- School-aged exception (NEVER 100% state share, even at ≤40% SMI).
- B/W convergence at Preschool + School-Aged tiers (B/W premium only for Infant + Toddler).
- Benton + Washington counties only in B/W zone.
- Federal aggregator +
programs.yaml+household_state_benefits.yamlintegration. - Full-time hours threshold = 7 per FSU §5.4.6.
- $31 vs $28 School-Aged FT discrepancy resolved (rate sheets are operative).
Validation Summary
| Check | Result |
|---|---|
| Regulatory Accuracy | 0 critical + 1 should + 5 suggestions |
| Reference Quality | 0 critical + 4 should + 6 suggestions |
| Code Patterns | 0 critical + 8 should + 6 suggestions |
| Test Coverage | 0 critical + 3 should + 4 suggestions |
| PDF Value Audit | 0 mismatches / ~150 data points confirmed |
| CI Status | All PASS |
Review Severity: APPROVE (with should-fix recommendations)
Phase-1 AR SRA is a high-quality new-state-program implementation by the same author as the recently-reviewed WA WCCC (#8208, merged) and AL CCSP (#8322).
- Zero critical findings.
- All 3 reconciliation items (the items the author explicitly flagged for reviewer attention) are defensible.
- PDF audit verified ~150 data points exactly: 80 base-rate cells, 24 state-share cells, 85% SMI tier values matching federal
hhs_smi, all eligibility thresholds, all formula correctness checks. - Remaining items are polish: changelog filename typo (same pattern as AL CCSP), reference page tightening, period metadata fix, several missing-test fixtures, and one possibly-overlenient LI activity fallback to scrutinize.
Next Steps
Author may proceed with merge after addressing the should-fix items inline, or address them as follow-ups. The §2.3.1(b) 75% SMI priority-group waiver deferral should be tracked as a separate issue.
# Conflicts: # policyengine_us/parameters/gov/household/household_state_benefits.yaml # policyengine_us/programs.yaml
Two code-health tests started failing on main after PRs #8324 (AR SRA) and #8208 (WA WCCC) merged. Neither was caught by the originating PRs' CI because the tests were added later. Both fixes are localized. 1. ar_sra_countable_income.py — `test_no_builtin_sum_over_entity_calls` flagged line 21: per_person_income = sum(person(source, period) for source in p.income.sources) The built-in `sum()` walks an AST containing direct `person(...)` calls, which can break vectorization. Precompute the per-person arrays into a list, then sum the list (the AST under the `sum()` call no longer contains entity-variable calls). 2. wa_wccc_provider_type.py — `test_input_variable_definitions ::test_input_variables_do_not_use_non_geographic_defined_for` flagged this input variable's `defined_for = "wa_wccc_eligible_child"`. Non-geographic `defined_for` on an input variable silently zeros user-provided inputs in surprising ways. Replace with the standard geographic `defined_for = StateCode.WA`, matching every other wa_wccc_* variable. Downstream consumers (e.g., wa_wccc_max_monthly_reimbursement, which retains its own eligible-child gate) continue to filter by eligibility, so output behavior is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Implements Arkansas's School Readiness Assistance (SRA) program (formerly CCAP, transferred from AR DHS to AR Department of Education / Office of Early Childhood in June 2025; SRA-era rates effective Nov 1, 2025). Covers both Low-Income (LI) and Employment-Sponsored Subsidy (ESS) eligibility tracks with the full four-dimensional provider rate table (zone × age × care type × full-time/part-time), enforces the 4% per-family copay ceiling from the CCDF State Plan, and includes 180+ tests covering rate-sheet cells, state-share keys, eligibility tracks, and edge cases.
Closes #8323.
Regulatory Authority
Program Overview
in_effectgate). CCAP-era (pre-2025-11-01) deferred to a follow-up PR — the rate and copay structures differ materially (QRIS-based copay vs income-tier × age-group copay, county Rate Cap vs two-zone flat rates). The Oct 2025 transitional month (Quality Enhancement Payment supplement) is also out of scope.Eligibility
is_ar_sra_age_eligiblereadsis_disabledand selectschild_age_limit(13) orchild_age_limit_disabled(19)is_ccdf_immigration_eligible_childis_ar_sra_income_eligible, parameligibility/income_smi_rate=0.85is_ccdf_asset_eligible(gov.hhs.ccdf.asset_limitis $1M from 2015, matching AR's specification)defined_for = StateCode.AR+ar_sra_zonestate guardis_ar_sra_li_activity_eligible, paramactivity_hours_li=30is_ar_sra_ess_eligible; the alt path checksar_tea_countable_earned_income > tea_income_limit(earnings-only per "earnings alone" wording)activity_hours_ess_year_2=25,ess_window_months=24Benefit Calculation
The state pays a daily rate by zone × age category × care type × full-time/part-time, scaled by an income-tier state share. The family's per-child daily copay equals
base_rate × (1 − state_share). The SPM-unit monthly subsidy is computed assum(min(pre_subsidy_childcare_expenses − copay, max_monthly_state_payment))across eligible children, then increased bycap_savingswhen the total payable copay exceeds 4% of monthly countable income.4% per-family copay ceiling (CCDF State Plan §3.1.1): the State Plan's literal "gross income" wording is reconciled against FSU §4.3.3 (p20), which unconditionally excludes children's SSI and Social Security from the budget. The cap base is therefore
ar_sra_countable_income— adult income only. Per child, the rate-sheet copay used in the cap calculation is clamped to that child's actual provider charge (min(rate_sheet_copay, monthly_expense)), so a child whose expense falls below the scheduled copay does not inflatecap_savings.rates/benton_washington_counties.yaml).childcare_hours_per_day.ESS Track Modeling
Mirrors the California stage-3 pattern using two bare-input variables on the SPM unit:
ar_was_tea_recipient(YEAR, bool, defaultFalse)ar_months_since_tea_exit(MONTH, int, default0)ESS Year 1 = months_since_tea_exit ∈ [1, 12]; ESS Year 2 = (12, 24]. Activity-hour thresholds and the 24-month window are parameter-driven. Hours are masked to adults (
age >= adult_age_threshold, parameterized at 18) before the threshold check.Year-1 activity is satisfied by 20+ hr/wk, any adult being a full-time student, OR family earned income alone exceeding the TEA income limit. The earned-income-only gate follows FSU §4.1.5.1's "earnings alone cause the family to be income ineligible for TEA" wording — unearned income (pension, Social Security, child support) is excluded from this specific test. Implementation:
ar_tea_countable_earned_income > parameters.gov.states.ar.dhs.tea.income.income_limit.Year-2 activity is satisfied by 25+ hr/wk or full-time student (no alt path per FSU §4.1.5.2).
Source-Document Reconciliation
The 4% copay ceiling and the ESS Year-1 alt path both required reconciling two source documents:
4% cap base — "gross income" vs FSU §4.3.3: CCDF State Plan §3.1.1 caps the family copay at "4% of gross income," but FSU §4.3.3 (p20) unconditionally excludes children's SSI and Social Security from the budget. The model uses
ar_sra_countable_income(adult income only) as the cap base, treating the State Plan's "gross" as a colloquial reference to the post-§4.3.3 budget. The FSU Glossary defines "Gross Monthly Income" as "total earned and unearned income before tax deductions unless excluded" (p43), supporting this reading.Year-1 alt path — "earnings alone" vs
~ar_tea_income_eligible: FSU §4.1.5.1 says the family qualifies if "the earnings alone cause the family to be income ineligible for TEA (the family's net countable income exceeds $513 per month)." The "alone" qualifier constrains the gate input to earned income — using the full TEA countable income (which includes pension, Social Security, etc.) would defeat the work-transition purpose of the ESS alt path. The model gates onar_tea_countable_earned_income > tea_income_limit.75% SMI no-cost waiver — State Plan §2.3.1(b) vs Nov 2025 rate sheets: State Plan §2.3.1(b) (p29) commits "no cost" assistance for families under 75% SMI, but the Nov 2025 operational rate sheets only zero the copay below 40% SMI. The model follows the rate sheets because they are the operational document the agency uses to compute copays; the broader State Plan waiver is not modeled (documented in
no_copay_smi_threshold.yamlandar_sra_daily_copay.py).Not Modeled (by design)
Test Plan
policyengine-core test policyengine_us/tests/policy/baseline/gov/states/ar/ade/oec/sra -c policyengine_uscbo_household_income.yamltests pass (no regression fromhousehold_state_benefits.yamlchange)make formatclean (ruff format + ruff check pass)