From 6d8dc00b99478076286584f505a837d96ffb24b1 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 26 Mar 2026 11:09:16 -0400 Subject: [PATCH 1/6] Initial commit for Maryland CCAP implementation Co-Authored-By: Claude Opus 4.6 (1M context) --- changelog.d/md-ccap.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/md-ccap.added.md diff --git a/changelog.d/md-ccap.added.md b/changelog.d/md-ccap.added.md new file mode 100644 index 00000000000..e58dd10c19d --- /dev/null +++ b/changelog.d/md-ccap.added.md @@ -0,0 +1 @@ +Implement Maryland CCAP (Child Care Assistance Program). From 59fef63d1d2746d7f4fb2bbdf75ff4725f2bf192 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 26 Mar 2026 12:48:02 -0400 Subject: [PATCH 2/6] Implement Maryland Child Care Scholarship (CCS) program Adds eligibility, income calculation, copayment, and provider reimbursement rate parameters for Maryland's CCS program (COMAR 13A.14.06). Includes formal rates (7 regions) and informal rates (24 counties), enum-keyed parameter lookups, and 78 test cases. Closes #7888 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../hhs/ccdf/child_care_subsidy_programs.yaml | 1 + .../md/msde/ccs/age_threshold/child.yaml | 11 + .../ccs/age_threshold/disabled_child.yaml | 11 + .../md/msde/ccs/copay/federal_cap_rate.yaml | 11 + .../ccs/copay/max_children_with_copay.yaml | 11 + .../states/md/msde/ccs/copay/unit_hours.yaml | 25 + .../md/msde/ccs/copay/weekly_amount.yaml | 20 + .../ccs/income/countable_income/sources.yaml | 31 + .../self_employment_deduction_rate.yaml | 11 + .../ccs/income/smi_rate/continuation.yaml | 13 + .../md/msde/ccs/income/smi_rate/initial.yaml | 15 + .../ccs/payment/baltimore_city_counties.yaml | 12 + .../ccs/payment/formal/licensed_center.yaml | 119 ++ .../ccs/payment/formal/licensed_family.yaml | 119 ++ .../ccs/payment/infant_age_threshold.yaml | 13 + .../md/msde/ccs/payment/informal/rates.yaml | 370 +++++ .../msde/ccs/payment/region_u_counties.yaml | 16 + .../msde/ccs/payment/region_v_counties.yaml | 16 + .../msde/ccs/payment/region_x_counties.yaml | 13 + .../msde/ccs/payment/region_y_counties.yaml | 14 + .../msde/ccs/payment/region_z_counties.yaml | 14 + .../gov/states/md/msde/ccs/edge_cases.yaml | 1236 +++++++++++++++++ .../gov/states/md/msde/ccs/integration.yaml | 424 ++++++ .../gov/states/md/msde/ccs/md_ccs.yaml | 176 +++ .../md/msde/ccs/md_ccs_countable_income.yaml | 98 ++ .../states/md/msde/ccs/md_ccs_eligible.yaml | 114 ++ .../md/msde/ccs/md_ccs_eligible_child.yaml | 132 ++ .../md/msde/ccs/md_ccs_income_eligible.yaml | 115 ++ .../md/msde/ccs/md_ccs_payment_rate.yaml | 122 ++ .../md/msde/ccs/md_ccs_weekly_copay.yaml | 242 ++++ .../msde/ccs/eligibility/md_ccs_eligible.py | 20 + .../ccs/eligibility/md_ccs_eligible_child.py | 22 + .../gov/states/md/msde/ccs/md_ccs.py | 33 + .../md/msde/ccs/md_ccs_countable_income.py | 26 + .../gov/states/md/msde/ccs/md_ccs_enrolled.py | 9 + .../md/msde/ccs/md_ccs_income_eligible.py | 25 + .../md/msde/ccs/md_ccs_provider_type.py | 18 + .../md/msde/ccs/md_ccs_receives_snap.py | 9 + .../states/md/msde/ccs/md_ccs_receives_wic.py | 9 + .../states/md/msde/ccs/md_ccs_weekly_copay.py | 54 + .../md/msde/ccs/md_child_care_subsidies.py | 11 + .../md/msde/ccs/payment/md_ccs_age_group.py | 26 + .../msde/ccs/payment/md_ccs_payment_rate.py | 41 + .../md/msde/ccs/payment/md_ccs_region.py | 51 + .../msde/ccs/payment/md_ccs_service_unit.py | 28 + sources/working_references.md | 271 ++++ 46 files changed, 4178 insertions(+) create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/child.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/disabled_child.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/copay/federal_cap_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/copay/max_children_with_copay.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/income/self_employment_deduction_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/baltimore_city_counties.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_center.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_family.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/infant_age_threshold.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/informal/rates.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_u_counties.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_v_counties.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_x_counties.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_y_counties.yaml create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_z_counties.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/edge_cases.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_eligible_child.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_payment_rate.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_weekly_copay.yaml create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible_child.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/md_ccs.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_countable_income.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_enrolled.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_provider_type.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_receives_snap.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_receives_wic.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_weekly_copay.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/md_child_care_subsidies.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_age_group.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_payment_rate.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_region.py create mode 100644 policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_service_unit.py create mode 100644 sources/working_references.md diff --git a/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml b/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml index 7a253af1f86..1d8237aacd3 100644 --- a/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml +++ b/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml @@ -4,6 +4,7 @@ values: - ca_child_care_subsidies # California Child Care - co_child_care_subsidies # Colorado Child Care Assistance Program - ma_child_care_subsidies # Massachusetts Child Care Financial Assistance + - md_child_care_subsidies # Maryland Child Care Scholarship - me_child_care_subsidies # Maine Child Care Affordability Program - ne_child_care_subsidies # Nebraska Child Care Subsidy - nh_child_care_subsidies # New Hampshire Child Care Scholarship Program diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/child.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/child.yaml new file mode 100644 index 00000000000..3d81b4a1ef6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/child.yaml @@ -0,0 +1,11 @@ +description: Maryland limits the Child Care Scholarship program to children under this age. +values: + 2018-01-01: 13 + +metadata: + unit: year + period: year + label: Maryland CCS child age threshold + reference: + - title: COMAR 13A.14.06.02 - Definitions, "Child" + href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.02.aspx diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/disabled_child.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/disabled_child.yaml new file mode 100644 index 00000000000..55a67bc8011 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/disabled_child.yaml @@ -0,0 +1,11 @@ +description: Maryland limits the Child Care Scholarship program to disabled children under this age. +values: + 2018-01-01: 19 + +metadata: + unit: year + period: year + label: Maryland CCS disabled child age threshold + reference: + - title: COMAR 13A.14.06.02 - Definitions, "Child" + href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.02.aspx diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/federal_cap_rate.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/federal_cap_rate.yaml new file mode 100644 index 00000000000..972e835c739 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/federal_cap_rate.yaml @@ -0,0 +1,11 @@ +description: Maryland limits copayments to this share of family gross income under the Child Care Scholarship program per federal requirements. +values: + 2022-05-01: 0.07 + +metadata: + unit: /1 + period: year + label: Maryland CCS federal copayment cap rate + reference: + - title: 45 CFR 98.45(k) + href: https://www.ecfr.gov/current/title-45/section-98.45#p-98.45(k) diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/max_children_with_copay.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/max_children_with_copay.yaml new file mode 100644 index 00000000000..6dc26b33386 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/max_children_with_copay.yaml @@ -0,0 +1,11 @@ +description: Maryland assesses copayments for up to this many children under the Child Care Scholarship program. +values: + 2022-05-01: 3 + +metadata: + unit: person + period: year + label: Maryland CCS maximum children with copayment + reference: + - title: COMAR 13A.14.06.12 + href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.12.aspx diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml new file mode 100644 index 00000000000..c4c292d7ec6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml @@ -0,0 +1,25 @@ +description: Maryland determines the number of service units based on daily hours of care under the Child Care Scholarship program. + +metadata: + type: single_amount + threshold_unit: hour + amount_unit: /1 + period: year + label: Maryland CCS service units by daily hours + reference: + - title: COMAR 13A.14.06.11 + href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.11.aspx + +brackets: + - threshold: + 2022-05-01: 0 + amount: + 2022-05-01: 1 + - threshold: + 2022-05-01: 3.0001 + amount: + 2022-05-01: 2 + - threshold: + 2022-05-01: 6 + amount: + 2022-05-01: 3 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml new file mode 100644 index 00000000000..a9e17012e35 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml @@ -0,0 +1,20 @@ +description: Maryland sets this amount as the weekly copayment by service unit under the Child Care Scholarship program. + +metadata: + unit: currency-USD + period: week + label: Maryland CCS weekly copayment by service unit + breakdown: + - md_ccs_service_unit + reference: + - title: Chapter 717 of 2024 + href: https://mgaleg.maryland.gov/2024RS/Chapters_noln/CH_717_sb0482e.pdf + - title: COMAR 13A.14.06.12 + href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.12.aspx + +UNIT_3: + 2022-05-01: 3 +UNIT_2: + 2022-05-01: 2 +UNIT_1: + 2022-05-01: 1 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml new file mode 100644 index 00000000000..df29e6820ff --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml @@ -0,0 +1,31 @@ +description: Maryland counts these income sources under the Child Care Scholarship program. +values: + 2022-05-01: + - employment_income + # Note: self_employment_income is handled separately in the formula + # with a 30% deduction per COMAR 13A.14.06.03(F)(6) + - social_security + - pension_income + - interest_income + - dividend_income + - rental_income + - alimony_income + - unemployment_compensation + - workers_compensation + - veterans_benefits + - disability_benefits + - capital_gains + - farm_income + - military_retirement_pay + # NOT included: + # - child_support_received (excluded per Chapters 525/526 of 2022) + +metadata: + unit: list + period: year + label: Maryland CCS countable income sources + reference: + - title: COMAR 13A.14.06.03(F)(3)-(8) + href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx + - title: Chapters 525/526 of 2022 + href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/self_employment_deduction_rate.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/self_employment_deduction_rate.yaml new file mode 100644 index 00000000000..54034c673ee --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/self_employment_deduction_rate.yaml @@ -0,0 +1,11 @@ +description: Maryland deducts this share of self-employment income for business expenses under the Child Care Scholarship program. +values: + 2018-01-01: 0.3 + +metadata: + unit: /1 + period: year + label: Maryland CCS self-employment deduction rate + reference: + - title: COMAR 13A.14.06.03(F)(6) + href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml new file mode 100644 index 00000000000..1f1bd6a90a3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml @@ -0,0 +1,13 @@ +description: Maryland limits continuation eligibility for the Child Care Scholarship program to families with income at or below this share of State Median Income. +values: + 2018-01-01: 0.85 + +metadata: + unit: /1 + period: year + label: Maryland CCS continuation eligibility SMI rate + reference: + - title: 45 CFR 98.21(b) - Eligibility requirements + href: https://www.ecfr.gov/current/title-45/section-98.21#p-98.21(b) + - title: Chapters 525/526 of 2022 + href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml new file mode 100644 index 00000000000..a66bbc91975 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml @@ -0,0 +1,15 @@ +description: Maryland limits initial eligibility for the Child Care Scholarship program to families with income at or below this share of State Median Income. +values: + 2018-01-01: 0.5 + 2019-01-01: 0.65 + 2022-05-01: 0.75 + +metadata: + unit: /1 + period: year + label: Maryland CCS initial eligibility SMI rate + reference: + - title: Chapters 595/596 of 2018 + href: https://mgaleg.maryland.gov/2018RS/Chapters_noln/CH_595_hb0377e.pdf + - title: Chapters 525/526 of 2022 + href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/baltimore_city_counties.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/baltimore_city_counties.yaml new file mode 100644 index 00000000000..cb09fb47d74 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/baltimore_city_counties.yaml @@ -0,0 +1,12 @@ +description: Maryland sets Baltimore City as its own region for Child Care Scholarship rate purposes. +values: + 2020-11-23: + - BALTIMORE_CITY_MD + +metadata: + unit: list + period: year + label: Maryland CCS Baltimore City region + reference: + - title: Maryland CCS Scholarship Rates + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_center.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_center.yaml new file mode 100644 index 00000000000..aa6b3aeadbd --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_center.yaml @@ -0,0 +1,119 @@ +description: Maryland provides these weekly reimbursement rates for licensed child care centers under the Child Care Scholarship program. + +metadata: + period: week + unit: currency-USD + label: Maryland CCS licensed center weekly rates + breakdown: + - md_ccs_region + - md_ccs_age_group + - md_ccs_service_unit + reference: + - title: Maryland CCS Scholarship Rates (Formal Rates, 60th Percentile, 2024 Market Rate Survey) + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + +REGION_U: + REGULAR: + UNIT_3: + 2026-03-01: 244 + UNIT_2: + 2026-03-01: 163 + UNIT_1: + 2026-03-01: 82 + INFANT: + UNIT_3: + 2026-03-01: 325 + UNIT_2: + 2026-03-01: 217 + UNIT_1: + 2026-03-01: 109 +REGION_V: + REGULAR: + UNIT_3: + 2026-03-01: 200 + UNIT_2: + 2026-03-01: 133 + UNIT_1: + 2026-03-01: 67 + INFANT: + UNIT_3: + 2026-03-01: 264 + UNIT_2: + 2026-03-01: 176 + UNIT_1: + 2026-03-01: 88 +REGION_W: + REGULAR: + UNIT_3: + 2026-03-01: 305 + UNIT_2: + 2026-03-01: 204 + UNIT_1: + 2026-03-01: 102 + INFANT: + UNIT_3: + 2026-03-01: 420 + UNIT_2: + 2026-03-01: 280 + UNIT_1: + 2026-03-01: 140 +REGION_X: + REGULAR: + UNIT_3: + 2026-03-01: 424 + UNIT_2: + 2026-03-01: 283 + UNIT_1: + 2026-03-01: 142 + INFANT: + UNIT_3: + 2026-03-01: 554 + UNIT_2: + 2026-03-01: 369 + UNIT_1: + 2026-03-01: 185 +REGION_Y: + REGULAR: + UNIT_3: + 2026-03-01: 278 + UNIT_2: + 2026-03-01: 185 + UNIT_1: + 2026-03-01: 93 + INFANT: + UNIT_3: + 2026-03-01: 378 + UNIT_2: + 2026-03-01: 252 + UNIT_1: + 2026-03-01: 126 +REGION_Z: + REGULAR: + UNIT_3: + 2026-03-01: 207 + UNIT_2: + 2026-03-01: 138 + UNIT_1: + 2026-03-01: 69 + INFANT: + UNIT_3: + 2026-03-01: 297 + UNIT_2: + 2026-03-01: 198 + UNIT_1: + 2026-03-01: 99 +BALTIMORE_CITY: + REGULAR: + UNIT_3: + 2026-03-01: 282 + UNIT_2: + 2026-03-01: 188 + UNIT_1: + 2026-03-01: 94 + INFANT: + UNIT_3: + 2026-03-01: 376 + UNIT_2: + 2026-03-01: 251 + UNIT_1: + 2026-03-01: 126 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_family.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_family.yaml new file mode 100644 index 00000000000..e0ea886e198 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_family.yaml @@ -0,0 +1,119 @@ +description: Maryland provides these weekly reimbursement rates for licensed family child care homes under the Child Care Scholarship program. + +metadata: + period: week + unit: currency-USD + label: Maryland CCS licensed family weekly rates + breakdown: + - md_ccs_region + - md_ccs_age_group + - md_ccs_service_unit + reference: + - title: Maryland CCS Scholarship Rates (Formal Rates, 60th Percentile, 2024 Market Rate Survey) + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + +REGION_U: + REGULAR: + UNIT_3: + 2026-03-01: 200 + UNIT_2: + 2026-03-01: 134 + UNIT_1: + 2026-03-01: 67 + INFANT: + UNIT_3: + 2026-03-01: 225 + UNIT_2: + 2026-03-01: 150 + UNIT_1: + 2026-03-01: 75 +REGION_V: + REGULAR: + UNIT_3: + 2026-03-01: 175 + UNIT_2: + 2026-03-01: 117 + UNIT_1: + 2026-03-01: 59 + INFANT: + UNIT_3: + 2026-03-01: 200 + UNIT_2: + 2026-03-01: 134 + UNIT_1: + 2026-03-01: 67 +REGION_W: + REGULAR: + UNIT_3: + 2026-03-01: 265 + UNIT_2: + 2026-03-01: 177 + UNIT_1: + 2026-03-01: 89 + INFANT: + UNIT_3: + 2026-03-01: 300 + UNIT_2: + 2026-03-01: 200 + UNIT_1: + 2026-03-01: 100 +REGION_X: + REGULAR: + UNIT_3: + 2026-03-01: 325 + UNIT_2: + 2026-03-01: 217 + UNIT_1: + 2026-03-01: 109 + INFANT: + UNIT_3: + 2026-03-01: 350 + UNIT_2: + 2026-03-01: 234 + UNIT_1: + 2026-03-01: 117 +REGION_Y: + REGULAR: + UNIT_3: + 2026-03-01: 220 + UNIT_2: + 2026-03-01: 147 + UNIT_1: + 2026-03-01: 73 + INFANT: + UNIT_3: + 2026-03-01: 250 + UNIT_2: + 2026-03-01: 167 + UNIT_1: + 2026-03-01: 83 +REGION_Z: + REGULAR: + UNIT_3: + 2026-03-01: 170 + UNIT_2: + 2026-03-01: 114 + UNIT_1: + 2026-03-01: 57 + INFANT: + UNIT_3: + 2026-03-01: 185 + UNIT_2: + 2026-03-01: 124 + UNIT_1: + 2026-03-01: 62 +BALTIMORE_CITY: + REGULAR: + UNIT_3: + 2026-03-01: 225 + UNIT_2: + 2026-03-01: 150 + UNIT_1: + 2026-03-01: 75 + INFANT: + UNIT_3: + 2026-03-01: 252 + UNIT_2: + 2026-03-01: 168 + UNIT_1: + 2026-03-01: 84 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/infant_age_threshold.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/infant_age_threshold.yaml new file mode 100644 index 00000000000..4810dd8cdcc --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/infant_age_threshold.yaml @@ -0,0 +1,13 @@ +description: Maryland defines infants as children under this age in months for Child Care Scholarship rate purposes. +values: + 2020-11-23: 24 + +metadata: + unit: month + period: year + label: Maryland CCS infant age threshold in months + reference: + - title: Maryland CCS Scholarship Rates + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + - title: COMAR 13A.14.06.02 - Definitions + href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.02.aspx diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/informal/rates.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/informal/rates.yaml new file mode 100644 index 00000000000..e0bc3b53a0d --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/informal/rates.yaml @@ -0,0 +1,370 @@ +description: Maryland provides these weekly reimbursement rates for informal child care providers under the Child Care Scholarship program. + +metadata: + period: week + unit: currency-USD + label: Maryland CCS informal provider weekly rates + reference: + - title: Maryland CCS Scholarship Rates (Informal Rates, 70th Percentile, March 2021 Market Rate Survey) + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + +ALLEGANY_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 83 + UNIT_2: + 2020-11-23: 55 + UNIT_1: + 2020-11-23: 28 + INFANT: + UNIT_3: + 2020-11-23: 90 + UNIT_2: + 2020-11-23: 60 + UNIT_1: + 2020-11-23: 30 +ANNE_ARUNDEL_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 135 + UNIT_2: + 2020-11-23: 90 + UNIT_1: + 2020-11-23: 45 + INFANT: + UNIT_3: + 2020-11-23: 150 + UNIT_2: + 2020-11-23: 100 + UNIT_1: + 2020-11-23: 50 +BALTIMORE_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 125 + UNIT_2: + 2020-11-23: 83 + UNIT_1: + 2020-11-23: 42 + INFANT: + UNIT_3: + 2020-11-23: 150 + UNIT_2: + 2020-11-23: 100 + UNIT_1: + 2020-11-23: 50 +CALVERT_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 135 + UNIT_2: + 2020-11-23: 90 + UNIT_1: + 2020-11-23: 45 + INFANT: + UNIT_3: + 2020-11-23: 150 + UNIT_2: + 2020-11-23: 100 + UNIT_1: + 2020-11-23: 50 +CAROLINE_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 84 + UNIT_2: + 2020-11-23: 56 + UNIT_1: + 2020-11-23: 28 + INFANT: + UNIT_3: + 2020-11-23: 100 + UNIT_2: + 2020-11-23: 67 + UNIT_1: + 2020-11-23: 33 +CARROLL_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 135 + UNIT_2: + 2020-11-23: 90 + UNIT_1: + 2020-11-23: 45 + INFANT: + UNIT_3: + 2020-11-23: 150 + UNIT_2: + 2020-11-23: 100 + UNIT_1: + 2020-11-23: 50 +CECIL_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 105 + UNIT_2: + 2020-11-23: 70 + UNIT_1: + 2020-11-23: 35 + INFANT: + UNIT_3: + 2020-11-23: 120 + UNIT_2: + 2020-11-23: 80 + UNIT_1: + 2020-11-23: 40 +CHARLES_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 135 + UNIT_2: + 2020-11-23: 90 + UNIT_1: + 2020-11-23: 45 + INFANT: + UNIT_3: + 2020-11-23: 150 + UNIT_2: + 2020-11-23: 100 + UNIT_1: + 2020-11-23: 50 +DORCHESTER_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 84 + UNIT_2: + 2020-11-23: 56 + UNIT_1: + 2020-11-23: 28 + INFANT: + UNIT_3: + 2020-11-23: 100 + UNIT_2: + 2020-11-23: 67 + UNIT_1: + 2020-11-23: 33 +FREDERICK_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 125 + UNIT_2: + 2020-11-23: 83 + UNIT_1: + 2020-11-23: 42 + INFANT: + UNIT_3: + 2020-11-23: 150 + UNIT_2: + 2020-11-23: 100 + UNIT_1: + 2020-11-23: 50 +GARRETT_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 83 + UNIT_2: + 2020-11-23: 55 + UNIT_1: + 2020-11-23: 28 + INFANT: + UNIT_3: + 2020-11-23: 90 + UNIT_2: + 2020-11-23: 60 + UNIT_1: + 2020-11-23: 30 +HARFORD_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 125 + UNIT_2: + 2020-11-23: 83 + UNIT_1: + 2020-11-23: 42 + INFANT: + UNIT_3: + 2020-11-23: 150 + UNIT_2: + 2020-11-23: 100 + UNIT_1: + 2020-11-23: 50 +HOWARD_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 177 + UNIT_2: + 2020-11-23: 118 + UNIT_1: + 2020-11-23: 59 + INFANT: + UNIT_3: + 2020-11-23: 195 + UNIT_2: + 2020-11-23: 130 + UNIT_1: + 2020-11-23: 65 +KENT_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 84 + UNIT_2: + 2020-11-23: 56 + UNIT_1: + 2020-11-23: 28 + INFANT: + UNIT_3: + 2020-11-23: 100 + UNIT_2: + 2020-11-23: 67 + UNIT_1: + 2020-11-23: 33 +MONTGOMERY_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 177 + UNIT_2: + 2020-11-23: 118 + UNIT_1: + 2020-11-23: 59 + INFANT: + UNIT_3: + 2020-11-23: 195 + UNIT_2: + 2020-11-23: 130 + UNIT_1: + 2020-11-23: 65 +PRINCE_GEORGE_S_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 135 + UNIT_2: + 2020-11-23: 90 + UNIT_1: + 2020-11-23: 45 + INFANT: + UNIT_3: + 2020-11-23: 150 + UNIT_2: + 2020-11-23: 100 + UNIT_1: + 2020-11-23: 50 +QUEEN_ANNE_S_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 105 + UNIT_2: + 2020-11-23: 70 + UNIT_1: + 2020-11-23: 35 + INFANT: + UNIT_3: + 2020-11-23: 120 + UNIT_2: + 2020-11-23: 80 + UNIT_1: + 2020-11-23: 40 +ST_MARY_S_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 105 + UNIT_2: + 2020-11-23: 70 + UNIT_1: + 2020-11-23: 35 + INFANT: + UNIT_3: + 2020-11-23: 120 + UNIT_2: + 2020-11-23: 80 + UNIT_1: + 2020-11-23: 40 +SOMERSET_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 84 + UNIT_2: + 2020-11-23: 56 + UNIT_1: + 2020-11-23: 28 + INFANT: + UNIT_3: + 2020-11-23: 100 + UNIT_2: + 2020-11-23: 67 + UNIT_1: + 2020-11-23: 33 +TALBOT_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 105 + UNIT_2: + 2020-11-23: 70 + UNIT_1: + 2020-11-23: 35 + INFANT: + UNIT_3: + 2020-11-23: 120 + UNIT_2: + 2020-11-23: 80 + UNIT_1: + 2020-11-23: 40 +WASHINGTON_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 105 + UNIT_2: + 2020-11-23: 70 + UNIT_1: + 2020-11-23: 35 + INFANT: + UNIT_3: + 2020-11-23: 120 + UNIT_2: + 2020-11-23: 80 + UNIT_1: + 2020-11-23: 40 +WICOMICO_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 84 + UNIT_2: + 2020-11-23: 56 + UNIT_1: + 2020-11-23: 28 + INFANT: + UNIT_3: + 2020-11-23: 100 + UNIT_2: + 2020-11-23: 67 + UNIT_1: + 2020-11-23: 33 +WORCESTER_COUNTY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 83 + UNIT_2: + 2020-11-23: 55 + UNIT_1: + 2020-11-23: 28 + INFANT: + UNIT_3: + 2020-11-23: 90 + UNIT_2: + 2020-11-23: 60 + UNIT_1: + 2020-11-23: 30 +BALTIMORE_CITY_MD: + REGULAR: + UNIT_3: + 2020-11-23: 106 + UNIT_2: + 2020-11-23: 71 + UNIT_1: + 2020-11-23: 35 + INFANT: + UNIT_3: + 2020-11-23: 120 + UNIT_2: + 2020-11-23: 80 + UNIT_1: + 2020-11-23: 40 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_u_counties.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_u_counties.yaml new file mode 100644 index 00000000000..6aaca3f2c63 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_u_counties.yaml @@ -0,0 +1,16 @@ +description: Maryland sets these counties as Region U for Child Care Scholarship rate purposes. +values: + 2020-11-23: + - CECIL_COUNTY_MD + - QUEEN_ANNE_S_COUNTY_MD + - ST_MARY_S_COUNTY_MD + - TALBOT_COUNTY_MD + - WASHINGTON_COUNTY_MD + +metadata: + unit: list + period: year + label: Maryland CCS Region U counties + reference: + - title: Maryland CCS Scholarship Rates + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_v_counties.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_v_counties.yaml new file mode 100644 index 00000000000..5cf99beec1e --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_v_counties.yaml @@ -0,0 +1,16 @@ +description: Maryland sets these counties as Region V for Child Care Scholarship rate purposes. +values: + 2020-11-23: + - CAROLINE_COUNTY_MD + - DORCHESTER_COUNTY_MD + - KENT_COUNTY_MD + - SOMERSET_COUNTY_MD + - WICOMICO_COUNTY_MD + +metadata: + unit: list + period: year + label: Maryland CCS Region V counties + reference: + - title: Maryland CCS Scholarship Rates + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_x_counties.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_x_counties.yaml new file mode 100644 index 00000000000..0cc357c3df6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_x_counties.yaml @@ -0,0 +1,13 @@ +description: Maryland sets these counties as Region X for Child Care Scholarship rate purposes. +values: + 2020-11-23: + - HOWARD_COUNTY_MD + - MONTGOMERY_COUNTY_MD + +metadata: + unit: list + period: year + label: Maryland CCS Region X counties + reference: + - title: Maryland CCS Scholarship Rates + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_y_counties.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_y_counties.yaml new file mode 100644 index 00000000000..1ae3f1de0af --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_y_counties.yaml @@ -0,0 +1,14 @@ +description: Maryland sets these counties as Region Y for Child Care Scholarship rate purposes. +values: + 2020-11-23: + - BALTIMORE_COUNTY_MD + - FREDERICK_COUNTY_MD + - HARFORD_COUNTY_MD + +metadata: + unit: list + period: year + label: Maryland CCS Region Y counties + reference: + - title: Maryland CCS Scholarship Rates + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_z_counties.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_z_counties.yaml new file mode 100644 index 00000000000..99055a52bac --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_z_counties.yaml @@ -0,0 +1,14 @@ +description: Maryland sets these counties as Region Z for Child Care Scholarship rate purposes. +values: + 2020-11-23: + - ALLEGANY_COUNTY_MD + - GARRETT_COUNTY_MD + - WORCESTER_COUNTY_MD + +metadata: + unit: list + period: year + label: Maryland CCS Region Z counties + reference: + - title: Maryland CCS Scholarship Rates + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/edge_cases.yaml new file mode 100644 index 00000000000..d3ef27886d3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/edge_cases.yaml @@ -0,0 +1,1236 @@ +# Maryland CCS Edge Case Tests +# Tests boundary conditions for eligibility, copayment, and benefit calculations. +# FY2025 MD SMI base: $149,249 +# +# SMI by family size: +# Fam 1: 149,249 * 0.52 = 77,609.48 +# Fam 2: 149,249 * 0.68 = 101,489.32 +# Fam 7: 149,249 * (0.52 + 0.16*5 + 0.03) = 149,249 * 1.35 = 201,486.15 +# Fam 8: 149,249 * (0.52 + 0.16*5 + 0.03*2) = 149,249 * 1.38 = 205,963.62 +# +# 75% SMI (initial): Fam 1 = 58,207.11, Fam 2 = 76,116.99 +# 85% SMI (continuation): Fam 2 = 86,265.92 + +# === Income threshold boundary: 75% SMI === + +- name: Case 1, income just below 75 percent SMI threshold for family of 2. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 75% SMI for fam 2 ~ 76,116.99 annually + # Use 76,116 to stay just below threshold (avoids float precision) + employment_income: 76_116 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # monthly countable: 76,116 / 12 = 6,343.00 + # monthly 75% SMI: ~6,343.08 + # 6,343.00 <= 6,343.08 -> eligible + md_ccs_income_eligible: true + +- name: Case 2, income one dollar above 75 percent SMI threshold for family of 2. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 76_118 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # monthly countable: 76,118 / 12 = 6,343.17 + # monthly 75% SMI: 6,343.08 + # 6,343.17 > 6,343.08 -> not eligible + md_ccs_income_eligible: false + +# === Income threshold boundary: 85% SMI (continuation) === + +- name: Case 3, enrolled family income just below 85 percent SMI threshold. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 85% SMI for fam 2 ~ 86,265.92 annually + # Use 86,265 to stay just below threshold (avoids float precision) + employment_income: 86_265 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + md_ccs_enrolled: true + households: + household: + members: [person1, person2] + state_code: MD + output: + # monthly countable: 86,265 / 12 = 7,188.75 + # monthly 85% SMI: ~7,188.83 + # 7,188.75 <= 7,188.83 -> eligible + md_ccs_income_eligible: true + +- name: Case 4, enrolled family income one dollar above 85 percent SMI threshold. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 86_267 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + md_ccs_enrolled: true + households: + household: + members: [person1, person2] + state_code: MD + output: + # monthly countable: 86,267 / 12 = 7,188.92 + # monthly 85% SMI: 7,188.83 + # 7,188.92 > 7,188.83 -> not eligible + md_ccs_income_eligible: false + +# === Enrolled between 75-85% SMI: initial vs continuation === + +- name: Case 5, not enrolled with income between 75 and 85 percent SMI is not eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + # 80,000 is between 75% SMI (76,117) and 85% SMI (86,266) for fam 2 + employment_income: 80_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + md_ccs_enrolled: false + households: + household: + members: [person1, person2] + state_code: MD + output: + # Not enrolled -> initial threshold (75% SMI) + # monthly countable: 80,000 / 12 = 6,666.67 + # monthly 75% SMI: 6,343.08 + # 6,666.67 > 6,343.08 -> not eligible + md_ccs_income_eligible: false + +- name: Case 6, enrolled with income between 75 and 85 percent SMI is eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 80_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + md_ccs_enrolled: true + households: + household: + members: [person1, person2] + state_code: MD + output: + # Enrolled -> continuation threshold (85% SMI) + # monthly countable: 80,000 / 12 = 6,666.67 + # monthly 85% SMI: 7,188.83 + # 6,666.67 <= 7,188.83 -> eligible + md_ccs_income_eligible: true + +# === Zero income === + +- name: Case 7, zero income family is income eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 0 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # 0 <= 75% SMI -> eligible + md_ccs_income_eligible: true + +# === Very high income === + +- name: Case 8, very high income family is not income eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 500_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # 500,000/12 = 41,666.67 >> 75% SMI -> not eligible + md_ccs_income_eligible: false + +# === Family size: minimum (1 person, adult only) === + +- name: Case 9, single adult with no children has no eligible child. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_eligible_child: [false] + md_ccs_eligible: false + +# === Family size: large (8 people, 6 children) === + +- name: Case 10, large family of 8 with 6 children. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 120_000 + is_tax_unit_head_or_spouse: true + person2: + age: 38 + is_tax_unit_head_or_spouse: true + person3: + age: 12 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person4: + age: 10 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person5: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person6: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person7: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 4 + person8: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: MD + output: + # All 6 children under 13 -> all eligible + md_ccs_eligible_child: [false, false, true, true, true, true, true, true] + + # hhs_smi for fam 8 = 149,249 * (0.52 + 0.16*5 + 0.03*2) = 149,249 * 1.38 = 205,963.62 + # monthly 75% SMI = 205,963.62 * 0.75 / 12 = 12,872.73 + # monthly countable: 120,000 / 12 = 10,000 + # 10,000 <= 12,872.73 -> eligible + md_ccs_income_eligible: true + +# === Self-employment income edge cases === + +- name: Case 11, family with 100 percent self-employment income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + self_employment_income: 60_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # self_employment_income: 60,000 * (1 - 0.30) = 42,000 + # monthly: 42,000 / 12 = 3,500 + md_ccs_countable_income: 3_500 + +- name: Case 12, family with zero self-employment income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + self_employment_income: 0 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # employment: 50,000, self_employment: 0 * 0.70 = 0 + # monthly: 50,000 / 12 = 4,166.67 + md_ccs_countable_income: 4_166.67 + +# === Age boundary: child exactly age 13 (non-disabled) === + +- name: Case 13, child exactly age 13 not disabled is not eligible. + period: 2025-01 + input: + people: + person1: + age: 40 + is_tax_unit_head_or_spouse: true + person2: + age: 13 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # age 13, threshold is < 13 -> not eligible + md_ccs_eligible_child: [false, false] + +# === Age boundary: disabled child exactly age 18 === + +- name: Case 14, disabled child exactly age 18 is eligible. + period: 2025-01 + input: + people: + person1: + age: 45 + is_tax_unit_head_or_spouse: true + person2: + age: 18 + is_disabled: true + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # age 18 < 19 (disabled threshold) -> eligible + md_ccs_eligible_child: [false, true] + +# === Age boundary: disabled child exactly age 19 === + +- name: Case 15, disabled child exactly age 19 is not eligible. + period: 2025-01 + input: + people: + person1: + age: 45 + is_tax_unit_head_or_spouse: true + person2: + age: 19 + is_disabled: true + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # age 19, threshold is < 19 -> not eligible + md_ccs_eligible_child: [false, false] + +# === Multiple children copay scaling === + +- name: Case 16, one child copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # 1 child, full-time -> $3/week + # capped_count = min(1, 3) = 1 + # scale = 1/1 = 1 + # total = $3 * 1 = $3/week + md_ccs_weekly_copay: 3 + +- name: Case 17, two children copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person3: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MD + output: + # 2 children, each full-time -> $3 + $3 = $6/week + # capped_count = min(2, 3) = 2, scale = 2/2 = 1 + # total = $6/week + md_ccs_weekly_copay: 6 + +- name: Case 18, three children copay at max. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 10 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person3: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person4: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # 3 children, each full-time -> $3*3 = $9/week + # capped_count = min(3, 3) = 3, scale = 3/3 = 1 + # total = $9/week + md_ccs_weekly_copay: 9 + +- name: Case 19, four children copay capped at 3 children. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 10 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person3: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person4: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person5: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MD + output: + # 4 eligible children, each full-time -> raw total = $3*4 = $12/week + # capped_count = min(4, 3) = 3, scale = 3/4 = 0.75 + # scaled total = $12 * 0.75 = $9/week + md_ccs_weekly_copay: 9 + +- name: Case 20, five children copay capped at 3 children. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 11 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person3: + age: 9 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person4: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person5: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person6: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: MD + output: + # 5 eligible children, each full-time -> raw total = $3*5 = $15/week + # capped_count = min(5, 3) = 3, scale = 3/5 = 0.6 + # scaled total = $15 * 0.6 = $9/week + md_ccs_weekly_copay: 9 + +# === Copay federal cap edge cases === + +- name: Case 21, copay exactly at 7 percent federal cap. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # Target: 7% of weekly income = $3/week (full-time copay) + # weekly income = $3 / 0.07 = $42.86/week + # annual = $42.86 * 52 = $2,228.57 + # Need income where 7% cap = $3/week exactly + employment_income: 2_229 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # monthly countable = 2,229 / 12 = 185.75 + # weekly income = 185.75 * 12 / 52 = 42.87 + # 7% cap = 42.87 * 0.07 = 3.00 + # raw copay = $3/week (full-time) + # min($3, $3.00) = $3 -> cap does not reduce copay + md_ccs_weekly_copay: 3 + +- name: Case 22, copay below 7 percent federal cap with very low income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 1_200 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # monthly countable = 1,200 / 12 = 100 + # weekly income = 100 * 12 / 52 = 23.08 + # 7% cap = 23.08 * 0.07 = 1.62 + # raw copay = $3/week (full-time, 8 hrs) + # min($3, $1.62) = $1.62 -> cap applies + md_ccs_weekly_copay: 1.62 + +- name: Case 23, zero income results in zero copay via federal cap. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 0 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # weekly income = 0 + # 7% cap = 0 * 0.07 = 0 + # min($3, $0) = $0 + md_ccs_weekly_copay: 0 + +# === Zero childcare expenses === + +- name: Case 24, zero childcare expenses results in zero benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 0 + households: + household: + members: [person1, person2] + state_code: MD + output: + # expenses = 0, copay = $3 * 52 / 12 = $13/month + # benefit = max(0 - 13, 0) = 0 + md_ccs: 0 + +# === Expenses less than copay === + +- name: Case 25, expenses less than copay results in zero benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 100 + households: + household: + members: [person1, person2] + state_code: MD + output: + # annual copay = $3 * 52 = $156 + # annual expenses = $100 + # benefit = max(100 - 156, 0) = 0 (floored at 0) + md_ccs: 0 + +# === Service unit boundary: hours per day === + +- name: Case 26, childcare exactly 3 hours per day gets hourly rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # 3 hrs/day: bracket threshold 0->1 unit, next at 3.0001 + # 3 < 3.0001 -> 1 unit (hourly) -> $1/week + md_ccs_weekly_copay: 1 + +- name: Case 27, childcare 3.5 hours per day gets part-time rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 3.5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # 3.5 hrs/day >= 3.0001 -> 2 units (part-time) -> $2/week + md_ccs_weekly_copay: 2 + +- name: Case 28, childcare exactly 6 hours per day gets full-time rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 6 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # 6 hrs/day >= 6 -> 3 units (full-time) -> $3/week + md_ccs_weekly_copay: 3 + +- name: Case 29, childcare 5.99 hours per day gets part-time rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 5.99 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # 5.99 hrs/day < 6 -> 2 units (part-time) -> $2/week + md_ccs_weekly_copay: 2 + +# === Mixed service units across children === + +- name: Case 30, two children with different service levels. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 8 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person3: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 2 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MD + output: + # person2: 8 hrs -> 3 units -> $3/week + # person3: 2 hrs -> 1 unit -> $1/week + # total: $3 + $1 = $4/week + md_ccs_weekly_copay: 4 + +# === Immigration ineligible child === + +- name: Case 31, undocumented child is not eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # CCDF immigration check fails for undocumented children + md_ccs_eligible_child: [false, false] + md_ccs_eligible: false + +# === Non-dependent child === + +- name: Case 32, non-dependent child under 13 is not eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: false + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # Not a dependent -> not eligible child + md_ccs_eligible_child: [false, false] + +# === TCA exemption with very high income === + +- name: Case 33, TCA recipient eligible despite income far above 85 percent SMI. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 300_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: MD + output: + # TCA -> income test waived regardless of how high income is + md_ccs_eligible: true + +# === SSI exemption with very high income === + +- name: Case 34, SSI recipient eligible despite income far above 85 percent SMI. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 300_000 + ssi: 9_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # SSI recipient (ssi > 0) -> income test waived + md_ccs_eligible: true + +# === Federal cap with multiple children === + +- name: Case 35, federal 7 percent cap applies with three children. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 3_600 + is_tax_unit_head_or_spouse: true + person2: + age: 10 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person3: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person4: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # 3 children, each full-time -> raw = $3 * 3 = $9/week + # capped_count = min(3, 3) = 3, scale = 1 + # monthly countable = 3,600 / 12 = 300 + # weekly income = 300 * 12 / 52 = 69.23 + # 7% cap = 69.23 * 0.07 = 4.85 + # min($9, $4.85) = $4.85 -> cap applies + md_ccs_weekly_copay: 4.85 + +# === Zero childcare hours === + +- name: Case 36, zero childcare hours per day gets hourly rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 0 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # 0 hrs/day -> 1 unit (hourly) -> $1/week + md_ccs_weekly_copay: 1 + +# === Benefit floor at zero: copay exceeds expenses === + +- name: Case 37, negative countable income from self-employment does not inflate benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + self_employment_income: -60_000_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: MD + output: + # TCA -> copay exempt -> $0 copay + # benefit = max(10,000 - 0, 0) = 10,000 + # monthly: 10,000 / 12 = 833.33 + # Negative self-employment income does not inflate benefit (benefit formula + # uses expenses - copay, not income-based formula) + md_ccs: 833.33 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/integration.yaml new file mode 100644 index 00000000000..d8f0050bf2b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/integration.yaml @@ -0,0 +1,424 @@ +# Maryland CCS Integration Tests +# FY2025 SMI base for MD (from 2024-10-01): $149,249 +# Family of 2: hhs_smi = 149,249 * 0.68 = 101,489.32 +# Family of 3: hhs_smi = 149,249 * 0.84 = 125,369.16 +# Family of 4: hhs_smi = 149,249 * 1.00 = 149,249 +# +# 75% SMI (initial): fam 2 = 76,116.99, fam 4 = 111,936.75 +# 85% SMI (continuation): fam 2 = 86,265.92, fam 4 = 126,861.65 + +- name: Case 1, single parent with one child age 3 and full-time care. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 28 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: MD + output: + # === Child eligibility === + # person1: adult, not dependent -> false + # person2: age 3 < 13, dependent, citizen -> true + md_ccs_eligible_child: [false, true] + + # === Income === + # employment_income: 50,000 + # monthly countable: 50,000 / 12 = 4,166.67 + md_ccs_countable_income: 4_166.67 + + # === Income eligibility === + # hhs_smi for fam 2 = 101,489.32 annual + # monthly 75% SMI = 101,489.32 * 0.75 / 12 = 6,343.08 + # 4,166.67 <= 6,343.08 -> eligible + md_ccs_income_eligible: true + + # === Overall eligibility === + md_ccs_eligible: true + + # === Copay === + # 8 hrs/day >= 6 -> 3 units (full-time) -> $3/week + # Not TCA/SSI/SNAP/WIC -> standard copay + md_ccs_weekly_copay: 3 + + # === Benefit === + # Default county: Allegany = Region Z, REGULAR, UNIT_3 -> $207/week + # annual max reimbursement: $207 * 52 = $10,764 + # annual copay: $3 * 52 = $156 + # uncapped: max(12,000 - 156, 0) = 11,844 + # capped: min(11,844, 10,764) = 10,764 + # monthly: 10,764 / 12 = 897 + md_ccs: 897 + +- name: Case 2, two-parent family with two children and mixed income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 60_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person2: + age: 33 + self_employment_income: 20_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person3: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person4: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 4 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_pre_subsidy_childcare_expenses: 18_000 + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # === Child eligibility === + # person1: adult -> false + # person2: adult -> false + # person3: age 7 < 13, dependent, citizen -> true + # person4: age 3 < 13, dependent, citizen -> true + md_ccs_eligible_child: [false, false, true, true] + + # === Income === + # employment: 60,000 + # self_employment: 20,000 * (1 - 0.30) = 14,000 + # total annual: 60,000 + 14,000 = 74,000 + # monthly countable: 74,000 / 12 = 6,166.67 + md_ccs_countable_income: 6_166.67 + + # === Income eligibility === + # hhs_smi for fam 4 = 149,249 + # monthly 75% SMI = 149,249 * 0.75 / 12 = 9,328.06 + # 6,166.67 <= 9,328.06 -> eligible + md_ccs_income_eligible: true + + md_ccs_eligible: true + + # === Copay === + # person3: 8 hrs/day >= 6 -> 3 units -> $3/week + # person4: 4 hrs/day, >3 and <6 -> 2 units -> $2/week + # total weekly copay: $3 + $2 = $5 + md_ccs_weekly_copay: 5 + + # === Benefit === + # annual copay: $5 * 52 = $260 + # annual benefit: max(18,000 - 260, 0) = 17,740 + # monthly: 17,740 / 12 = 1_478.33 + md_ccs: 1_478.33 + +- name: Case 3, TCA recipient family with zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 25 + employment_income: 15_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: MD + output: + # === Child eligibility === + md_ccs_eligible_child: [false, true] + + # === Income === + # monthly: 15,000 / 12 = 1,250 + md_ccs_countable_income: 1_250 + + # === Eligibility === + # TCA -> income test waived + md_ccs_income_eligible: true + md_ccs_eligible: true + + # === Copay === + # TCA recipient -> $0 + md_ccs_weekly_copay: 0 + + # === Benefit === + # annual: max(8,000 - 0, 0) = 8,000 + # monthly: 8,000 / 12 = 666.67 + md_ccs: 666.67 + +- name: Case 4, family at income boundary just below 75 percent SMI. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 100_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person2: + age: 33 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person4: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_pre_subsidy_childcare_expenses: 20_000 + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # === Child eligibility === + md_ccs_eligible_child: [false, false, true, true] + + # === Income === + # monthly countable: 100,000 / 12 = 8,333.33 + md_ccs_countable_income: 8_333.33 + + # === Income eligibility === + # hhs_smi fam 4 = 149,249 + # monthly 75% SMI = 149,249 * 0.75 / 12 = 9,328.06 + # 8,333.33 <= 9,328.06 -> eligible + md_ccs_income_eligible: true + + md_ccs_eligible: true + + # === Copay === + # 2 children, each full-time (8 hrs >= 6) -> $3 + $3 = $6/week + md_ccs_weekly_copay: 6 + + # === Benefit === + # annual copay: $6 * 52 = $312 + # annual benefit: max(20,000 - 312, 0) = 19,688 + # monthly: 19,688 / 12 = 1_640.67 + md_ccs: 1_640.67 + +- name: Case 5, enrolled family between 75 and 85 percent SMI with continuation eligibility. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 120_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person2: + age: 33 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person3: + age: 6 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person4: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + md_ccs_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 22_000 + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # === Child eligibility === + md_ccs_eligible_child: [false, false, true, true] + + # === Income === + # monthly: 120,000 / 12 = 10,000 + md_ccs_countable_income: 10_000 + + # === Income eligibility === + # monthly 75% SMI = 9,328.06 -> 10,000 > 9,328.06 (would fail initial) + # enrolled -> use 85% SMI = 149,249 * 0.85 / 12 = 10,571.81 + # 10,000 <= 10,571.81 -> eligible (continuation) + md_ccs_income_eligible: true + + md_ccs_eligible: true + + # === Copay === + # 2 children, each full-time -> $3 + $3 = $6/week + md_ccs_weekly_copay: 6 + + # === Benefit === + # Default county: Allegany = Region Z + # person3 (age 6): REGULAR, UNIT_3 -> $207/week + # person4 (age 2 = 24 months, not < 24): REGULAR, UNIT_3 -> $207/week + # annual max reimbursement: ($207 + $207) * 52 = $21,528 + # annual copay: $6 * 52 = $312 + # uncapped: max(22,000 - 312, 0) = 21,688 + # capped: min(21,688, 21,528) = 21,528 + # monthly: 21,528 / 12 = 1,794 + md_ccs: 1_794 + +- name: Case 6, SSI recipient with disabled teenager. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + employment_income: 200_000 + ssi: 9_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person2: + age: 16 + is_disabled: true + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 6 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 15_000 + households: + household: + members: [person1, person2] + state_code: MD + output: + # === Child eligibility === + # person2: age 16 < 19 (disabled threshold), disabled, dependent -> true + md_ccs_eligible_child: [false, true] + + # === Income === + # sources list does NOT include ssi (only employment_income counts here) + # employment_income: 200,000 / 12 = 16,666.67 + md_ccs_countable_income: 16_666.67 + + # === Eligibility === + # income $16,666.67/month > 75% SMI for fam 2 ($6,343.08) -> income test fails + md_ccs_income_eligible: false + # BUT SSI recipient (ssi > 0) -> overall eligibility via SSI bypass + md_ccs_eligible: true + + # === Copay === + # SSI recipient -> $0 + md_ccs_weekly_copay: 0 + + # === Benefit === + # Default county: Allegany = Region Z, REGULAR, UNIT_3 -> $207/week + # annual max reimbursement: $207 * 52 = $10,764 + # uncapped: max(15,000 - 0, 0) = 15,000 + # capped: min(15,000, 10,764) = 10,764 + # monthly: 10,764 / 12 = 897 + md_ccs: 897 + +- name: Case 7, family with income above 85 percent SMI is not eligible even when enrolled. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 140_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person2: + age: 33 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + person4: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + md_ccs_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 20_000 + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # === Child eligibility === + md_ccs_eligible_child: [false, false, true, true] + + # === Income === + # monthly: 140,000 / 12 = 11,666.67 + md_ccs_countable_income: 11_666.67 + + # === Income eligibility === + # enrolled -> use 85% SMI = 149,249 * 0.85 / 12 = 10,571.81 + # 11,666.67 > 10,571.81 -> not eligible + md_ccs_income_eligible: false + + md_ccs_eligible: false + md_ccs: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs.yaml new file mode 100644 index 00000000000..fcf5b997754 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs.yaml @@ -0,0 +1,176 @@ +# Tests for md_ccs (main benefit variable) +# Benefit = min(max(expenses - annual_copay, 0), max_reimbursement) / 12 +# COMAR 13A.14.06.11 + +- name: Case 1, eligible family with expenses under rate cap. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: MD + output: + # Default provider: LICENSED_CENTER, default county: Allegany = Region Z + # age 5 = REGULAR, 8hrs = UNIT_3 + # weekly rate: $207, annual max reimbursement: $207 * 52 = $10,764 + # weekly copay: $3, annual copay: $3 * 52 = $156 + # uncapped: max(12,000 - 156, 0) = 11,844 + # capped: min(11,844, 10,764) = 10,764 + # monthly: 10,764 / 12 = 897 + md_ccs: 897 + +- name: Case 2, ineligible family gets zero benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 15 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: MD + output: + # child age 15 >= 13, not disabled -> no eligible child -> not eligible + md_ccs: 0 + +- name: Case 3, TCA family with zero copay gets full benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: MD + output: + # TCA: copay $0 + # weekly rate: $207 (default center, Allegany = Region Z, regular, unit 3) + # annual max reimbursement: $207 * 52 = $10,764 + # uncapped: max(10,000 - 0, 0) = 10,000 + # capped: min(10,000, 10,764) = 10,000 + # monthly: 10,000 / 12 = 833.33 + md_ccs: 833.33 + +- name: Case 4, benefit capped at max reimbursement rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 4 + md_ccs_provider_type: LICENSED_FAMILY + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 20_000 + households: + household: + members: [person1, person2] + state_code: MD + county: ALLEGANY_COUNTY_MD + output: + # Provider: LICENSED_FAMILY, Region Z (Allegany), REGULAR (age 5), UNIT_2 (4hrs) + # weekly rate: $114 + # annual max reimbursement: $114 * 52 = $5,928 + # weekly copay: $3 (part-time), annual copay: $3 * 52 = $156 + # uncapped: max(20,000 - 156, 0) = 19,844 + # capped: min(19,844, 5,928) = 5,928 + # monthly: 5,928 / 12 = 494 + md_ccs: 494 + +- name: Case 5, informal provider rate by county. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: INFORMAL + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 20_000 + households: + household: + members: [person1, person2] + state_code: MD + county: HOWARD_COUNTY_MD + output: + # Provider: INFORMAL, Howard County, INFANT (age 1 = 12 months < 24), UNIT_3 (8hrs) + # weekly rate: $195 + # annual max reimbursement: $195 * 52 = $10,140 + # weekly copay: $3, annual copay: $3 * 52 = $156 + # uncapped: max(20,000 - 156, 0) = 19,844 + # capped: min(19,844, 10,140) = 10,140 + # monthly: 10,140 / 12 = 845 + md_ccs: 845 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_countable_income.yaml new file mode 100644 index 00000000000..f17d9b842fb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_countable_income.yaml @@ -0,0 +1,98 @@ +# Tests for md_ccs_countable_income +# Countable income = adds sources + self_employment_income * (1 - 0.30) +# Child support received is excluded since 2022. +# COMAR 13A.14.06.03(F)(3)-(8) + +- name: Case 1, employment income only. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # employment_income is in sources list + # 30,000 / 12 = 2,500 + md_ccs_countable_income: 2_500 + +- name: Case 2, self-employment income with 30 percent deduction. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + self_employment_income: 20_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # self_employment_income 20,000 * (1 - 0.30) = 14,000 + # 14,000 / 12 = 1,166.67 + md_ccs_countable_income: 1_166.67 + +- name: Case 3, mixed employment and self-employment income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + self_employment_income: 20_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # employment_income: 30,000 + # self_employment_income: 20,000 * (1 - 0.30) = 14,000 + # total annual: 30,000 + 14,000 = 44,000 + # monthly: 44,000 / 12 = 3,666.67 + md_ccs_countable_income: 3_666.67 + +- name: Case 4, child support received is excluded from income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + child_support_received: 6_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # employment_income: 30,000 (counted) + # child_support_received: 6,000 (EXCLUDED per Ch 525/526 of 2022) + # total annual: 30,000 + # monthly: 30,000 / 12 = 2,500 + md_ccs_countable_income: 2_500 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_eligible.yaml new file mode 100644 index 00000000000..cda4399c201 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_eligible.yaml @@ -0,0 +1,114 @@ +# Tests for md_ccs_eligible +# Eligible when: has at least one eligible child + income eligible +# OR TCA/SSI recipient (income test waived) + +- name: Case 1, basic eligible family with eligible child and income eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # child age 5 < 13, dependent, citizen -> eligible child + # income 50,000 well below 75% SMI for family of 2 + # (75% SMI for fam 2 = 101,489.32 * 0.75 = 76,116.99) + md_ccs_eligible: true + +- name: Case 2, TCA recipient is eligible regardless of income. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 200_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: MD + output: + # TCA recipient -> income test waived + # Has eligible child -> eligible + md_ccs_eligible: true + +- name: Case 3, SSI recipient is eligible regardless of income. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 200_000 + ssi: 9_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # SSI recipient (ssi > 0) -> income test waived + # Has eligible child -> eligible + md_ccs_eligible: true + +- name: Case 4, no eligible children means not eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 15 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # child age 15 >= 13, not disabled -> not eligible child + # no eligible children -> not eligible + md_ccs_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_eligible_child.yaml new file mode 100644 index 00000000000..12ce3947a4a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_eligible_child.yaml @@ -0,0 +1,132 @@ +# Tests for md_ccs_eligible_child +# Child must be: under 13 (or under 19 if disabled), a tax unit dependent, +# and CCDF immigration eligible. +# COMAR 13A.14.06.02 (definition of "Child") + +- name: Case 1, child age 5 not disabled is eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # person1: adult, not dependent -> false + # person2: age 5 < 13, dependent, citizen -> true + md_ccs_eligible_child: [false, true] + +- name: Case 2, child age 14 not disabled is not eligible. + period: 2025-01 + input: + people: + person1: + age: 40 + is_tax_unit_head_or_spouse: true + person2: + age: 14 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # person2: age 14 >= 13 (non-disabled threshold) -> false + md_ccs_eligible_child: [false, false] + +- name: Case 3, disabled child age 14 is eligible. + period: 2025-01 + input: + people: + person1: + age: 40 + is_tax_unit_head_or_spouse: true + person2: + age: 14 + is_disabled: true + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # person2: age 14 < 19 (disabled threshold), disabled -> true + md_ccs_eligible_child: [false, true] + +- name: Case 4, disabled child age 19 is not eligible. + period: 2025-01 + input: + people: + person1: + age: 45 + is_tax_unit_head_or_spouse: true + person2: + age: 19 + is_disabled: true + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # person2: age 19 >= 19 (disabled threshold) -> false + md_ccs_eligible_child: [false, false] + +- name: Case 5, child age 12 at boundary is eligible. + period: 2025-01 + input: + people: + person1: + age: 35 + is_tax_unit_head_or_spouse: true + person2: + age: 12 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # person2: age 12 < 13 -> true + md_ccs_eligible_child: [false, true] diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_income_eligible.yaml new file mode 100644 index 00000000000..1fa9a6355f2 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_income_eligible.yaml @@ -0,0 +1,115 @@ +# Tests for md_ccs_income_eligible +# Initial applicants: income <= 75% SMI +# Continuing families (md_ccs_enrolled): income <= 85% SMI +# TCA/SSI recipients: income test waived +# +# For MD family of 4 in 2025 (FY2025 SMI base = $149,249): +# hhs_smi = 149,249 * (0.52 + 0.16 * 3) = 149,249 +# 75% SMI = 149,249 * 0.75 = 111,936.75 annual +# 85% SMI = 149,249 * 0.85 = 126,861.65 annual + +- name: Case 1, family of 4 with income below 75 percent SMI is eligible. + period: 2025-01 + input: + people: + person1: + age: 35 + employment_income: 100_000 + person2: + age: 33 + person3: + age: 8 + person4: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # Monthly countable income: 100,000 / 12 = 8,333.33 + # Monthly 75% SMI threshold: 149,249 * 0.75 / 12 = 9,328.06 + # 8,333.33 <= 9,328.06 -> eligible + md_ccs_income_eligible: true + +- name: Case 2, family of 4 with income above 75 percent SMI is not eligible. + period: 2025-01 + input: + people: + person1: + age: 35 + employment_income: 120_000 + person2: + age: 33 + person3: + age: 8 + person4: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # Monthly countable income: 120,000 / 12 = 10,000 + # Monthly 75% SMI threshold: 149,249 * 0.75 / 12 = 9,328.06 + # 10,000 > 9,328.06 -> not eligible (new applicant) + md_ccs_income_eligible: false + +- name: Case 3, enrolled family of 4 with income between 75 and 85 percent SMI is eligible. + period: 2025-01 + input: + people: + person1: + age: 35 + employment_income: 120_000 + person2: + age: 33 + person3: + age: 8 + person4: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + md_ccs_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # Monthly countable income: 120,000 / 12 = 10,000 + # Monthly 85% SMI threshold: 149,249 * 0.85 / 12 = 10,571.81 + # 10,000 <= 10,571.81 -> eligible (continuation) + md_ccs_income_eligible: true + +- name: Case 4, enrolled family of 4 with income above 85 percent SMI is not eligible. + period: 2025-01 + input: + people: + person1: + age: 35 + employment_income: 130_000 + person2: + age: 33 + person3: + age: 8 + person4: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + md_ccs_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: MD + output: + # Monthly countable income: 130,000 / 12 = 10,833.33 + # Monthly 85% SMI threshold: 149,249 * 0.85 / 12 = 10,571.81 + # 10,833.33 > 10,571.81 -> not eligible + md_ccs_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_payment_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_payment_rate.yaml new file mode 100644 index 00000000000..1cb4c1ec973 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_payment_rate.yaml @@ -0,0 +1,122 @@ +# Tests for md_ccs_payment_rate (weekly rate lookup) +# Formal rates by region/age/unit, informal rates by county/age/unit + +- name: Licensed center, Region X (Howard), regular age, full-time. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + county: HOWARD_COUNTY_MD + output: + # Region X, REGULAR (age 5), UNIT_3 (8hrs): $424/week + md_ccs_payment_rate: [0, 424] + +- name: Licensed family, Region Y (Baltimore Co), infant, part-time. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 4 + md_ccs_provider_type: LICENSED_FAMILY + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + county: BALTIMORE_COUNTY_MD + output: + # Region Y, INFANT (age 1 = 12 months < 24), UNIT_2 (4hrs): $167/week + md_ccs_payment_rate: [0, 167] + +- name: Informal provider, Montgomery County, regular, hourly. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 2 + md_ccs_provider_type: INFORMAL + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + county: MONTGOMERY_COUNTY_MD + output: + # Informal, Montgomery Co, REGULAR (age 3 = 36 months >= 24), UNIT_1 (2hrs): $59/week + md_ccs_payment_rate: [0, 59] + +- name: Licensed center, Baltimore City, infant, full-time. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + county: BALTIMORE_CITY_MD + output: + # Baltimore City, INFANT (age 1 = 12 months), UNIT_3 (8hrs): $376/week + md_ccs_payment_rate: [0, 376] diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_weekly_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_weekly_copay.yaml new file mode 100644 index 00000000000..3d0058ea60e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_weekly_copay.yaml @@ -0,0 +1,242 @@ +# Tests for md_ccs_weekly_copay +# Weekly copay by service units: +# Full-time (>=6 hrs/day, 3 units): $3/week +# Part-time (>3 to <6 hrs/day, 2 units): $2/week +# Hourly (<=3 hrs/day, 1 unit): $1/week +# Exempt: TCA, SSI, SNAP, WIC recipients pay $0 +# Federal 7% cap: annual copay cannot exceed 7% of countable income +# Copay assessed for up to 3 children +# COMAR 13A.14.06.12; Chapter 717 of 2024; 45 CFR 98.45(k) + +- name: Case 1, standard family with full-time care. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # child hours/day = 8 >= 6 -> 3 units (full-time) -> $3/week + # annual copay: $3 * 52 = $156 -> well below 7% of $50,000 ($3,500) + md_ccs_weekly_copay: 3 + +- name: Case 2, standard family with part-time care. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # child hours/day = 5, >3 and <6 -> 2 units (part-time) -> $2/week + md_ccs_weekly_copay: 2 + +- name: Case 3, standard family with hourly care. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 2 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # child hours/day = 2, <=3 -> 1 unit (hourly) -> $1/week + md_ccs_weekly_copay: 1 + +- name: Case 4, TCA recipient pays zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: MD + output: + # TCA recipient -> copay exempt + md_ccs_weekly_copay: 0 + +- name: Case 5, SSI recipient pays zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + ssi: 9_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # SSI recipient (ssi > 0) -> copay exempt + md_ccs_weekly_copay: 0 + +- name: Case 6, SNAP eligible family pays zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + md_ccs_receives_snap: true + households: + household: + members: [person1, person2] + state_code: MD + output: + # SNAP recipient -> copay waived per Ch 525/526 of 2022 (bare input) + md_ccs_weekly_copay: 0 + +- name: Case 7, WIC eligible parent pays zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + md_ccs_receives_wic: true + households: + household: + members: [person1, person2] + state_code: MD + output: + # WIC recipient -> copay waived per Ch 525/526 of 2022 + md_ccs_weekly_copay: 0 + +- name: Case 8, federal 7 percent cap on very low income family. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 2_000 + is_tax_unit_head_or_spouse: true + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # Full-time -> $3/week raw copay + # Annual raw copay: $3 * 52 = $156 + # 7% of annual income: $2,000 * 0.07 = $140 + # $156 > $140 -> 7% cap applies + # Capped weekly: $140 / 52 = $2.69 + md_ccs_weekly_copay: 2.69 diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible.py b/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible.py new file mode 100644 index 00000000000..dbca8e755fc --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class md_ccs_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Maryland Child Care Scholarship (CCS)" + definition_period = MONTH + defined_for = StateCode.MD + reference = ( + "https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx", + "https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf", + ) + + def formula(spm_unit, period, parameters): + has_eligible_child = add(spm_unit, period, ["md_ccs_eligible_child"]) > 0 + income_eligible = spm_unit("md_ccs_income_eligible", period) + is_tca = spm_unit("is_tanf_enrolled", period) + receives_ssi = add(spm_unit, period, ["ssi"]) > 0 + return has_eligible_child & (income_eligible | is_tca | receives_ssi) diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible_child.py b/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible_child.py new file mode 100644 index 00000000000..de54e423f9c --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible_child.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class md_ccs_eligible_child(Variable): + value_type = bool + entity = Person + label = "Eligible child for Maryland Child Care Scholarship (CCS)" + definition_period = MONTH + defined_for = StateCode.MD + reference = "https://dsd.maryland.gov/regulations/Pages/13A.14.06.02.aspx" + + def formula(person, period, parameters): + p = parameters(period).gov.states.md.msde.ccs.age_threshold + age = person("age", period.this_year) + is_disabled = person("is_disabled", period.this_year) + age_limit = where(is_disabled, p.disabled_child, p.child) + age_eligible = age < age_limit + is_dependent = person("is_tax_unit_dependent", period.this_year) + immigration_eligible = person( + "is_ccdf_immigration_eligible_child", period.this_year + ) + return age_eligible & is_dependent & immigration_eligible diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs.py new file mode 100644 index 00000000000..8f35d2b6a95 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs.py @@ -0,0 +1,33 @@ +from policyengine_us.model_api import * + + +class md_ccs(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Maryland Child Care Scholarship (CCS) benefit amount" + definition_period = MONTH + defined_for = "md_ccs_eligible" + reference = ( + "https://dsd.maryland.gov/regulations/Pages/13A.14.06.11.aspx", + "https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates", + ) + + def formula(spm_unit, period, parameters): + weekly_copay = spm_unit("md_ccs_weekly_copay", period) + annual_copay = weekly_copay * WEEKS_IN_YEAR + + actual_expenses = spm_unit( + "spm_unit_pre_subsidy_childcare_expenses", period.this_year + ) + + person = spm_unit.members + is_eligible_child = person("md_ccs_eligible_child", period) + weekly_rate = person("md_ccs_payment_rate", period) + weekly_to_annual = WEEKS_IN_YEAR + max_reimbursement = ( + spm_unit.sum(weekly_rate * is_eligible_child) * weekly_to_annual + ) + + uncapped_benefit = max_(actual_expenses - annual_copay, 0) + return min_(uncapped_benefit, max_reimbursement) / MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_countable_income.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_countable_income.py new file mode 100644 index 00000000000..4dcaa4e2bfb --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_countable_income.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class md_ccs_countable_income(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Maryland Child Care Scholarship (CCS) countable income" + definition_period = MONTH + defined_for = StateCode.MD + reference = ( + "https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx", + "https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.md.msde.ccs.income + sources_income = add( + spm_unit, + period, + p.countable_income.sources, + ) + self_employment_income = add(spm_unit, period, ["self_employment_income"]) + return sources_income + self_employment_income * ( + 1 - p.self_employment_deduction_rate + ) diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_enrolled.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_enrolled.py new file mode 100644 index 00000000000..79dca26a13c --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_enrolled.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class md_ccs_enrolled(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Whether the family is currently enrolled in Maryland Child Care Scholarship (CCS)" + defined_for = StateCode.MD diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py new file mode 100644 index 00000000000..f37a0b63bee --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class md_ccs_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Maryland Child Care Scholarship (CCS) income eligible" + definition_period = MONTH + defined_for = StateCode.MD + reference = ( + "https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx", + "https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.md.msde.ccs.income.smi_rate + countable_income = spm_unit("md_ccs_countable_income", period) + smi = spm_unit("hhs_smi", period) + enrolled = spm_unit("md_ccs_enrolled", period) + income_limit = where( + enrolled, + smi * p.continuation, + smi * p.initial, + ) + return countable_income <= income_limit diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_provider_type.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_provider_type.py new file mode 100644 index 00000000000..ffe391bad0a --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_provider_type.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class MDCCSProviderType(Enum): + LICENSED_CENTER = "Licensed Child Care Center" + LICENSED_FAMILY = "Licensed Family Child Care Home" + INFORMAL = "Informal/License-Exempt" + + +class md_ccs_provider_type(Variable): + value_type = Enum + entity = Person + possible_values = MDCCSProviderType + default_value = MDCCSProviderType.LICENSED_CENTER + definition_period = MONTH + label = "Maryland CCS child care provider type" + defined_for = StateCode.MD + reference = "https://dsd.maryland.gov/regulations/Pages/13A.14.06.11.aspx" diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_receives_snap.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_receives_snap.py new file mode 100644 index 00000000000..b7d9d39a840 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_receives_snap.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class md_ccs_receives_snap(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Whether the family receives SNAP (used for Maryland CCS copay waiver)" + defined_for = StateCode.MD diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_receives_wic.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_receives_wic.py new file mode 100644 index 00000000000..7b85d732492 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_receives_wic.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class md_ccs_receives_wic(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Whether the family receives WIC (used for Maryland CCS copay waiver)" + defined_for = StateCode.MD diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_weekly_copay.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_weekly_copay.py new file mode 100644 index 00000000000..84148219da6 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_weekly_copay.py @@ -0,0 +1,54 @@ +from policyengine_us.model_api import * + + +class md_ccs_weekly_copay(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Maryland Child Care Scholarship (CCS) weekly copayment" + definition_period = MONTH + defined_for = StateCode.MD + reference = ( + "https://dsd.maryland.gov/regulations/Pages/13A.14.06.12.aspx", + "https://mgaleg.maryland.gov/2024RS/Chapters_noln/CH_717_sb0482e.pdf", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.md.msde.ccs.copay + + # TCA/SSI recipients pay $0 copayment per COMAR 13A.14.06.12(A)(1) + is_tca = spm_unit("is_tanf_enrolled", period) + receives_ssi = add(spm_unit, period, ["ssi"]) > 0 + + # SNAP/WIC recipients have copayments waived per Chapters 525/526 of 2022 + # Use bare inputs to avoid circular dependency through SNAP/TANF/childcare chain + is_snap = spm_unit("md_ccs_receives_snap", period) + receives_wic = spm_unit("md_ccs_receives_wic", period) + exempt = is_tca | receives_ssi | is_snap | receives_wic + + # Weekly copay per child based on service unit (enum-keyed lookup) + person = spm_unit.members + service_unit = person("md_ccs_service_unit", period) + weekly_per_child = p.weekly_amount[service_unit] + + # Only charge copay for eligible children + is_eligible_child = person("md_ccs_eligible_child", period) + weekly_per_child = where(is_eligible_child, weekly_per_child, 0) + + # Copay assessed for up to max_children_with_copay children + eligible_child_count = add(spm_unit, period, ["md_ccs_eligible_child"]) + capped_count = min_(eligible_child_count, p.max_children_with_copay) + total_weekly = spm_unit.sum(weekly_per_child) + scale = where( + eligible_child_count > 0, + capped_count / eligible_child_count, + 0, + ) + scaled_weekly = total_weekly * scale + + # Federal cap: copay cannot exceed 7% of gross income per 45 CFR 98.45(k) + countable_income = spm_unit("md_ccs_countable_income", period) + weekly_income = countable_income * MONTHS_IN_YEAR / WEEKS_IN_YEAR + federal_cap = weekly_income * p.federal_cap_rate + + return where(exempt, 0, min_(scaled_weekly, federal_cap)) diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_child_care_subsidies.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_child_care_subsidies.py new file mode 100644 index 00000000000..7c31208d248 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_child_care_subsidies.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class md_child_care_subsidies(Variable): + value_type = float + entity = SPMUnit + label = "Maryland child care subsidies" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + adds = ["md_ccs"] diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_age_group.py b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_age_group.py new file mode 100644 index 00000000000..7d4bcadfe87 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_age_group.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class MDCCSAgeGroup(Enum): + REGULAR = "Regular" + INFANT = "Infant" + + +class md_ccs_age_group(Variable): + value_type = Enum + entity = Person + possible_values = MDCCSAgeGroup + default_value = MDCCSAgeGroup.REGULAR + definition_period = MONTH + defined_for = StateCode.MD + label = "Maryland CCS child age group for rate purposes" + reference = "https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates" + + def formula(person, period, parameters): + p = parameters(period).gov.states.md.msde.ccs.payment + age_months = person("age", period.this_year) * MONTHS_IN_YEAR + return where( + age_months < p.infant_age_threshold, + MDCCSAgeGroup.INFANT, + MDCCSAgeGroup.REGULAR, + ) diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_payment_rate.py b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_payment_rate.py new file mode 100644 index 00000000000..9dd663258c1 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_payment_rate.py @@ -0,0 +1,41 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.md.msde.ccs.md_ccs_provider_type import ( + MDCCSProviderType, +) + + +class md_ccs_payment_rate(Variable): + value_type = float + entity = Person + unit = USD + label = "Maryland Child Care Scholarship (CCS) weekly payment rate" + definition_period = MONTH + defined_for = "md_ccs_eligible_child" + reference = "https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates" + + def formula(person, period, parameters): + p = parameters(period).gov.states.md.msde.ccs.payment + provider_type = person("md_ccs_provider_type", period) + age_group = person("md_ccs_age_group", period) + service_unit = person("md_ccs_service_unit", period) + region = person.household("md_ccs_region", period) + + # Formal rates: by region, age group, and service unit + center_rate = p.formal.licensed_center[region][age_group][service_unit] + family_rate = p.formal.licensed_family[region][age_group][service_unit] + + # Informal rates: by county, age group, and service unit + county = person.household("county_str", period) + in_md = person.household("state_code_str", period) == "MD" + safe_county = where(in_md, county, "ALLEGANY_COUNTY_MD") + informal_rate = p.informal.rates[safe_county][age_group][service_unit] + + return select( + [ + provider_type == MDCCSProviderType.LICENSED_CENTER, + provider_type == MDCCSProviderType.LICENSED_FAMILY, + provider_type == MDCCSProviderType.INFORMAL, + ], + [center_rate, family_rate, informal_rate], + default=center_rate, + ) diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_region.py b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_region.py new file mode 100644 index 00000000000..0b144b1ee94 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_region.py @@ -0,0 +1,51 @@ +from policyengine_us.model_api import * + + +class MDCCSRegion(Enum): + REGION_U = "Region U" + REGION_V = "Region V" + REGION_W = "Region W" + REGION_X = "Region X" + REGION_Y = "Region Y" + REGION_Z = "Region Z" + BALTIMORE_CITY = "Baltimore City" + + +class md_ccs_region(Variable): + value_type = Enum + entity = Household + possible_values = MDCCSRegion + default_value = MDCCSRegion.REGION_W + definition_period = MONTH + defined_for = StateCode.MD + label = "Maryland CCS rate region" + reference = "https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates" + + def formula(household, period, parameters): + county = household("county_str", period) + p = parameters(period).gov.states.md.msde.ccs.payment + is_region_u = np.isin(county, p.region_u_counties) + is_region_v = np.isin(county, p.region_v_counties) + is_region_x = np.isin(county, p.region_x_counties) + is_region_y = np.isin(county, p.region_y_counties) + is_region_z = np.isin(county, p.region_z_counties) + is_baltimore_city = np.isin(county, p.baltimore_city_counties) + return select( + [ + is_region_u, + is_region_v, + is_region_x, + is_region_y, + is_region_z, + is_baltimore_city, + ], + [ + MDCCSRegion.REGION_U, + MDCCSRegion.REGION_V, + MDCCSRegion.REGION_X, + MDCCSRegion.REGION_Y, + MDCCSRegion.REGION_Z, + MDCCSRegion.BALTIMORE_CITY, + ], + default=MDCCSRegion.REGION_W, + ) diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_service_unit.py b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_service_unit.py new file mode 100644 index 00000000000..0d4b6cf4ab3 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_service_unit.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class MDCCSServiceUnit(Enum): + UNIT_1 = "1 Unit (3 hours or less per day)" + UNIT_2 = "2 Units (more than 3 to less than 6 hours per day)" + UNIT_3 = "3 Units (6 or more hours per day)" + + +class md_ccs_service_unit(Variable): + value_type = Enum + entity = Person + possible_values = MDCCSServiceUnit + default_value = MDCCSServiceUnit.UNIT_3 + definition_period = MONTH + defined_for = StateCode.MD + label = "Maryland CCS service unit category" + reference = "https://dsd.maryland.gov/regulations/Pages/13A.14.06.11.aspx" + + def formula(person, period, parameters): + hours_per_day = person("childcare_hours_per_day", period.this_year) + p = parameters(period).gov.states.md.msde.ccs.copay + units = p.unit_hours.calc(hours_per_day) + return select( + [units == 3, units == 2], + [MDCCSServiceUnit.UNIT_3, MDCCSServiceUnit.UNIT_2], + default=MDCCSServiceUnit.UNIT_1, + ) diff --git a/sources/working_references.md b/sources/working_references.md new file mode 100644 index 00000000000..02cadffe599 --- /dev/null +++ b/sources/working_references.md @@ -0,0 +1,271 @@ +# Maryland Child Care Scholarship (CCS) Program - Working References + +## Official Program Name +**Child Care Scholarship (CCS) Program** (formerly "Child Care Subsidy Program") + +## Administering Agency +Maryland State Department of Education (MSDE), Division of Early Childhood, Office of Child Care + +## Primary Regulations + +### COMAR 13A.14.06 - Child Care Subsidy Program (Full Chapter) +- **URL**: http://mdrules.elaws.us/comar/13a.14.06 +- **PDF (Jan 2023 version with income tables)**: https://marylandpublicschools.org/stateboard/Documents/2023/0124/COMAR13A.14.06.pdf +- **Local copy**: `/tmp/md-comar-13a1406.pdf` +- **Sections**: + - .01 Purpose + - .02 Definitions + - .03 Eligibility (income scales, need requirements, categorical exemptions) + - .04 Pursuit of Child Support Obligations + - .05 Application Process + - .06 Provider Requirements + - .07 Child Care Vouchers + - .08 Service Groups (priority levels) + - .09 Redetermination + - .10 Termination + - .11 Payments for Child Care Services + - .12 Copayments (regional copayment tables, income levels A-J) + - .13 Confidentiality + - .14 Intentional Program Violations + - .15 Hearings and Appeals + +### Individual COMAR Sections Online +- **Definitions**: http://mdrules.elaws.us/comar/13a.14.06.02 +- **Eligibility**: http://mdrules.elaws.us/comar/13a.14.06.03 +- **Service Groups**: http://mdrules.elaws.us/comar/13a.14.06.08 +- **Copayments**: http://mdrules.elaws.us/comar/13a.14.06.12 +- **Cornell LII (full chapter)**: https://www.law.cornell.edu/regulations/maryland/title-13A/subtitle-14/chapter-13A.14.06 + +## Income Eligibility + +### Current Income Eligibility Scale (updated Dec 15, 2024) +- **Source**: CCS Scholarship Brochure (most current) +- **URL**: https://earlychildhood.marylandpublicschools.org/system/files/filedepot/2/scholarship-brochure-4.pdf +- **Local copy**: `/tmp/md-ccs-brochure.pdf` +- **Standard**: 75% of State Median Income (SMI) for initial eligibility; 85% SMI for continuation +- **Initial Income Scale (annual)**: + - Family of 2: $76,117 + - Family of 3: $94,026 + - Family of 4: $111,936 + - Family of 5: $129,846 + - Family of 6: $147,756 + - Family of 7: $151,114 + - Family of 8: $154,472 + - Family of 9: $157,830 + - Family of 10: $161,188 + - Family of 11: $164,546 + - Family of 12: $167,904 +- **Continuation Income Scale (annual)**: + - Family of 2: $86,266 + - Family of 3: $106,563 + - Family of 4: $126,861 + - Family of 5: $147,159 + - Family of 6: $167,457 + - Family of 7: $171,262 + - Family of 8: $175,068 + - Family of 9: $178,874 + - Family of 10: $182,680 + - Family of 11: $186,486 + - Family of 12: $190,292 + +### Previous Income Eligibility Scale (pre-Dec 2024) +- **Source**: CCS Income Eligibility Scale PDF +- **URL**: https://earlychildhood.marylandpublicschools.org/system/files/filedepot/2/income_eligibility_scale.pdf +- **Local copy**: `/tmp/md-ccs-income-scale.pdf` +- **Initial thresholds**: Family of 2: $61,222; Family of 4: $90,033 +- **Continuation thresholds**: Family of 2: $73,899; Family of 4: $108,675 + +### Historical Income Eligibility Thresholds (from Feb 2026 briefing) +| Fiscal Year | % of SMI | SMI Vintage | Family of 4 Threshold | +|---|---|---|---| +| 2016 | 50% | current | $54,631 | +| 2017 | 50% | current | $55,019 | +| 2018 | 50% | current | $55,839 | +| 2019 | 65% | 2018 SMI | $75,590 | +| 2020 | 65% | 2018 SMI | $75,590 | +| 2021 | 65% | 2018 SMI | $75,590 | +| 2022 | 65% | 2018 SMI | $75,590 | +| 2023 | 75% | 2021 SMI | $93,605 | +| 2024 | 75% | 2021 SMI | $93,605 | +| 2025 | 75% | 2025 SMI | $115,588 | +| 2026 | 75% | 2025 SMI | $115,588 | + +### State Median Income (SMI) Data +- **LIHEAP FY2026 SMI for Maryland**: $154,117 (4-person family) +- **Source**: https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf +- **60% SMI by household size (FY26)**: + - 1 person: $48,084 + - 2 persons: $62,879 + - 3 persons: $77,674 + - 4 persons: $92,470 + - 5 persons: $107,265 + - 6 persons: $122,060 +- **CCS uses ACF SMI estimates for FY2025** (per Feb 2026 briefing, slide 20): + - SMI for household of 2: $101,489 + - SMI for household of 4: $149,249 + +### CCDF Family Income Eligibility Levels by State (Jan 2025) +- **URL**: https://acf.gov/sites/default/files/documents/occ/CCDF-Family-Income-Eligibility-Levels-by-State.pdf +- **Local copy**: `/tmp/md-ccdf-income-levels.pdf` +- **Maryland entry**: 60% SMI (based on CCDF methodology), $6,302/month for family of 3, $7,503/month for family of 4 +- **Note**: CCDF and state report different % because they use different SMI bases + +## COMAR Income Eligibility Scale (Regulation .03H) - Older Values +- **Source**: COMAR 13A.14.06 PDF (Jan 2023 version) +- **Note**: These are the 2018 SMI-based values codified in regulation, superseded by Dec 2024 update +- Family of 1: $0-$37,193 (Level J max) +- Family of 2: $0-$48,637 (Level J max) +- Family of 3: $0-$60,081 (Level J max) +- Family of 4: $0-$71,525 (Level J max) +- Family of 5: $0-$82,969 +- Family of 6: $0-$94,413 +- Family of 7: $0-$96,558 +- Family of 8: $0-$98,704 +- Family of 9: $0-$100,850 +- Family of 10: $0-$102,996 + +## Copayments + +### Current Copayment Policy +- **TCA recipients**: $0 copayment (exempt) +- **SSI recipients**: $0 copayment (exempt) +- **SNAP, WIC, Section 8 recipients**: Copayments waived since May 23, 2022 (Chapters 525/526 of 2022) +- **All other families**: Maximum $3/week per 3-unit scholarship, $2/week per 2-unit, $1/week per 1-unit +- **Chapter 717 of 2024**: Prohibits MSDE from increasing copayment levels in effect as of Jan 1, 2024 +- **Federal CCDF 2024 Final Rule**: Caps copayments at 7% of family gross income + +### COMAR Copayment Tables (Regulation .12) +- **Regional copayment tables** by income level (A-J), region (U, V, W, X, Y, Z, BC), child age (<24 months vs >=24 months) +- **Copayment assessed for up to 3 children**: youngest gets highest, 2nd and 3rd get lower, 4th+ free +- **Units of service**: 1 unit (<=3 hrs), 2 units (>3 to <6 hrs), 3 units (>=6 hrs) +- **2-unit and 1-unit copayments**: multiply 3-unit figures by 2/3 and 1/3 respectively +- **Informal care copayments**: percentage of informal care weekly rate (5%-50% for first child by level A-J) +- **Note**: The COMAR regulation copayment tables appear to be from the pre-2022 era; current copayments are minimal ($1-$3/week) per legislative changes + +## Market Regions +- **Source**: RESI of Towson University, "Maryland Child Care Scholarship Program Reimbursement Rate Adjustments" (Sep 2023) +- **URL**: https://dlslibrary.state.md.us/publications/Exec/MSDE/ED9.5-111(c)_2022.pdf +- **Local copy**: `/tmp/md-ccs-reimbursement-2022.pdf` + +| Region | Counties | +|---|---| +| Region U | Cecil, Queen Anne's, St. Mary's, Talbot, Washington | +| Region V | Caroline, Dorchester, Kent, Somerset, Wicomico | +| Region W | Anne Arundel, Calvert, Carroll, Charles, Prince George's | +| Region X | Howard, Montgomery | +| Region Y | Baltimore, Frederick, Harford | +| Region Z | Allegany, Garrett, Worcester | +| Region B/BC | Baltimore City | + +## Eligibility Requirements Summary + +### Child Age +- Under 13 years (non-disabled) +- Under 19 years (disabled) +- **Source**: COMAR 13A.14.06.02 (definition of "Child") + +### Residency +- Must be a resident of the State of Maryland +- **Source**: COMAR 13A.14.06.03(A)(1) + +### Citizenship +- Children must be U.S. citizens or qualified aliens +- Parents do NOT have to be U.S. citizens +- **Source**: COMAR 13A.14.06.03(B); CCS Brochure + +### Activity Requirement (Need) +- Parent/caretaker must be working/employed, in an approved training program, or attending school +- For two-parent households, both parents must meet requirements +- **Source**: COMAR 13A.14.06.03(E); CCS Brochure + +### Categorical Eligibility +- TCA recipients: exempt from income limits and copayments +- SSI recipients: exempt from income limits and copayments +- **Source**: COMAR 13A.14.06.03(F)(1), .12(A)(1) + +### Income Calculation +- Annual gross income used +- Self-employment: flat 30% deducted for business expenses +- Military housing: paid rental/mortgage fees deducted from allowance +- Child support: averaged over 3 most recent consecutive months (excluded from income per 2022 legislation) +- **Source**: COMAR 13A.14.06.03(F)(3)-(8) + +### Immunizations +- Required for children before receiving services +- Exemptions for medical contraindications or religious objections +- **Source**: COMAR 13A.14.06.03(D) + +### Child Support Cooperation +- Must pursue child support obligations unless good cause exists +- **Source**: COMAR 13A.14.06.04 + +### Eligibility Period +- 12-month minimum (per federal mandate); Maryland uses 24-month eligibility periods +- **Source**: Jan 2025 briefing slide 7 + +## Legislative History + +| Year | Legislation | Key Changes | +|---|---|---| +| 2017 | Ch 209/210 | Required periodic reimbursement rate analysis | +| 2018 | Ch 555/556 | Supplemental Head Start funding | +| 2018 | (MSDE action) | Reimbursement 9th -> 20th percentile; eligibility 32% -> 50% SMI | +| 2019 | Ch 595/596 | Required 60th percentile market rate adjustment; eligibility -> 65% SMI | +| 2020 | (COVID) | All copays waived Mar-Sep 2020; reimbursement -> 60th percentile | +| 2021 | Ch 36/55 | Annual funding for Judy Centers, EXCELS, Blueprint capacity | +| 2022 | Ch 525/526 | Copay waivers for SNAP/WIC/TCA/Section 8/SSI; removed child support from income; created presumptive eligibility; eligibility -> 75% SMI; reimbursement -> 70th percentile | +| 2022 | Ch 498/499 | Therapeutic Child Care Grant Program | +| 2023 | Ch 731/732 | Restrict MSDE from changing key CCS policies as of Jan 1, 2023 | +| 2024 | Ch 717 | Prohibit MSDE from increasing copayment levels as of Jan 1, 2024 | +| 2025 | Ch 369 | Expanded CCS to parenting foster youth | + +## Briefings and Presentations + +### Feb 2026 Ways and Means Committee Briefing +- **URL**: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf +- **Local copy**: `/tmp/md-ccs-briefing-2026.pdf` +- **Key data**: 41,148 children / 27,235 families (Jan 2026); waitlist ~4,929 children; current SMI threshold table; demographic breakdowns + +### Jan 2025 Early Childhood Subcommittee Briefing +- **URL**: https://mgaleg.maryland.gov/meeting_material/2025/app%20-%20133815104940229083%20-%20MSDE-Child%20Care%20Scholarship%20Program%20Update%20to%20Subcommittee%20(1).pdf +- **Local copy**: `/tmp/md-ccs-briefing-2025.pdf` +- **Key data**: $568M proposed investment; enrollment freeze May 2025; copayment policy details + +### Jan 2025 CCS Info Session +- **URL**: https://earlychildhood.marylandpublicschools.org/system/files/filedepot/3/january_2025_occ_info_session.pdf +- **Local copy**: `/tmp/md-ccs-info-session-jan2025.pdf` +- **Key data**: Income eligibility increased effective Dec 15, 2024 (family of 2: $76,117; family of 4: $111,936) + +### Jan 2024 Early Childhood Subcommittee Briefing +- **URL**: https://mgaleg.maryland.gov/cmte_testimony/2024/ecm/1qQzLR-gr9jXICeb4E76YUf3vjAwJekVU.pdf +- **Local copy**: `/tmp/md-ccs-briefing-2024.pdf` +- **Key data**: Historical timeline of policy changes; copayment sliding scale proposal (3% for ~$43K-$65K, 7% for >$66K) + +### Oct 2025 Child Care in Maryland (DLS) +- **URL**: https://mgaleg.maryland.gov/meeting_material/2025/app%20-%20134063072915355066%20-%20ChildCarePresentation.pdf +- **Local copy**: `/tmp/md-ccs-childcare-in-md-2025.pdf` +- **Key data**: Comprehensive program overview; freeze status; market rate timeline; federal rule changes + +## Market Rate Survey +- **2024 Market Rate Survey**: https://earlychildhood.marylandpublicschools.org/system/files/filedepot/3/md-market-rate-survey-2024-2.pdf +- **Reimbursement Rate Analysis (2022 data, Sep 2023 report)**: https://dlslibrary.state.md.us/publications/Exec/MSDE/ED9.5-111(c)_2022.pdf +- **Local copy**: `/tmp/md-ccs-reimbursement-2022.pdf` + +## Program Websites +- **Official CCS Program**: https://earlychildhood.marylandpublicschools.org/child-care-providers/child-care-scholarship-program +- **Family Portal**: https://family.childcareportals.org/s/?language=en_US +- **money4childcare.com**: www.money4childcare.com (main family-facing site) +- **CCS Rates**: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates +- **CCDF State Plan**: https://earlychildhood.marylandpublicschools.org/about/ccdf-state-plan +- **Enrollment Data**: https://earlychildhood.marylandpublicschools.org/data + +## Failed Fetches +| URL | Status | Likely Content | +|---|---|---| +| https://earlychildhood.marylandpublicschools.org/child-care-providers/child-care-scholarship-program | 403 | Main program page with eligibility details and links | +| https://earlychildhood.marylandpublicschools.org/changes-subsidy-eligibility | 403 | Details of eligibility changes over time | +| https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates | Not fetched | Current provider reimbursement rate tables by region/age/quality | +| https://earlychildhood.marylandpublicschools.org/about/ccdf-state-plan | 403 | CCDF state plan documents with full eligibility and copayment details | +| https://earlychildhood.marylandpublicschools.org/system/files/filedepot/2/income_eligibility_scale.pdf | 403 | Older income eligibility scale PDF (data obtained from text version) | +| https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM202502_SMIStateTable_Att4.pdf | 404 | FY26 SMI table (obtained via alternate URL) | +| https://regulations.justia.com/states/maryland/title-13a/subtitle-14/chapter-13a-14-06/section-13a-14-06-02/ | 403 | COMAR definitions (obtained from mdrules.elaws.us) | From 2363974809e1ab3960c289cfd87bf606e7f6b9ed Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 26 Mar 2026 12:50:57 -0400 Subject: [PATCH 3/6] Update changelog fragment with correct program name Co-Authored-By: Claude Opus 4.6 (1M context) --- changelog.d/md-ccap.added.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/md-ccap.added.md b/changelog.d/md-ccap.added.md index e58dd10c19d..379dc3540da 100644 --- a/changelog.d/md-ccap.added.md +++ b/changelog.d/md-ccap.added.md @@ -1 +1 @@ -Implement Maryland CCAP (Child Care Assistance Program). +Implement Maryland Child Care Scholarship (CCS) program. From 4fd8acb8445ea364c4abe46f0371b2449b360181 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 26 Mar 2026 13:18:32 -0400 Subject: [PATCH 4/6] Review-fix round 1: address critical issues from /review-program - Add region_w_counties.yaml and update md_ccs_region.py - Add MD CCS to programs.yaml registry - Add #page=XX to 5 session law PDF references - Fix continuation.yaml to cite state source as primary - Document frozen SMI limitation with TODO Co-Authored-By: Claude Opus 4.6 (1M context) --- .../states/md/msde/ccs/copay/weekly_amount.yaml | 2 +- .../ccs/income/countable_income/sources.yaml | 2 +- .../msde/ccs/income/smi_rate/continuation.yaml | 8 +++++--- .../md/msde/ccs/income/smi_rate/initial.yaml | 4 ++-- .../md/msde/ccs/payment/region_w_counties.yaml | 16 ++++++++++++++++ policyengine_us/programs.yaml | 7 ++++++- .../states/md/msde/ccs/md_ccs_income_eligible.py | 5 +++++ .../states/md/msde/ccs/payment/md_ccs_region.py | 3 +++ 8 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_w_counties.yaml diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml index a9e17012e35..f4a060e7cd0 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml @@ -8,7 +8,7 @@ metadata: - md_ccs_service_unit reference: - title: Chapter 717 of 2024 - href: https://mgaleg.maryland.gov/2024RS/Chapters_noln/CH_717_sb0482e.pdf + href: https://mgaleg.maryland.gov/2024RS/Chapters_noln/CH_717_sb0482e.pdf#page=1 - title: COMAR 13A.14.06.12 href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.12.aspx diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml index df29e6820ff..5ca5e4e5549 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml @@ -28,4 +28,4 @@ metadata: - title: COMAR 13A.14.06.03(F)(3)-(8) href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx - title: Chapters 525/526 of 2022 - href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf + href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml index 1f1bd6a90a3..e2417c31d6f 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml @@ -7,7 +7,9 @@ metadata: period: year label: Maryland CCS continuation eligibility SMI rate reference: - - title: 45 CFR 98.21(b) - Eligibility requirements - href: https://www.ecfr.gov/current/title-45/section-98.21#p-98.21(b) + - title: COMAR 13A.14.06.03(B) + href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx - title: Chapters 525/526 of 2022 - href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf + href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf#page=1 + - title: 45 CFR 98.21(b) - Federal ceiling + href: https://www.ecfr.gov/current/title-45/section-98.21#p-98.21(b) diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml index a66bbc91975..6f36e46c586 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml @@ -10,6 +10,6 @@ metadata: label: Maryland CCS initial eligibility SMI rate reference: - title: Chapters 595/596 of 2018 - href: https://mgaleg.maryland.gov/2018RS/Chapters_noln/CH_595_hb0377e.pdf + href: https://mgaleg.maryland.gov/2018RS/Chapters_noln/CH_595_hb0377e.pdf#page=1 - title: Chapters 525/526 of 2022 - href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf + href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_w_counties.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_w_counties.yaml new file mode 100644 index 00000000000..4d1b9a0d9c7 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_w_counties.yaml @@ -0,0 +1,16 @@ +description: Maryland sets these counties as Region W for Child Care Scholarship rate purposes. +values: + 2020-11-23: + - ANNE_ARUNDEL_COUNTY_MD + - CALVERT_COUNTY_MD + - CARROLL_COUNTY_MD + - CHARLES_COUNTY_MD + - PRINCE_GEORGE_S_COUNTY_MD + +metadata: + unit: list + period: year + label: Maryland CCS Region W counties + reference: + - title: Maryland CCS Scholarship Rates + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 32409746ae5..1e4f6a435dd 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -421,7 +421,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: CA, CO, IL, MA, DC, NC, TX + coverage: CA, CO, DC, IL, MA, MD, NC, TX state_implementations: - state: CA status: complete @@ -444,6 +444,11 @@ programs: status: complete name: Massachusetts CCFA full_name: Massachusetts Child Care Financial Assistance + - state: MD + status: complete + name: Maryland CCS + full_name: Maryland Child Care Scholarship + variable: md_child_care_subsidies - state: DC status: complete name: DC CCSP diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py index f37a0b63bee..0cded2ffe0b 100644 --- a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py @@ -15,6 +15,11 @@ class md_ccs_income_eligible(Variable): def formula(spm_unit, period, parameters): p = parameters(period).gov.states.md.msde.ccs.income.smi_rate countable_income = spm_unit("md_ccs_countable_income", period) + # TODO: Maryland froze SMI base years for historical periods + # (FY2019-2022 used 2018 SMI, FY2023-2024 used 2021 SMI). + # This formula uses the current-year SMI, which is correct for + # 2025+ but overstates historical thresholds. Follow-up PR + # should parameterize the SMI base year. smi = spm_unit("hhs_smi", period) enrolled = spm_unit("md_ccs_enrolled", period) income_limit = where( diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_region.py b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_region.py index 0b144b1ee94..3d066d60349 100644 --- a/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_region.py +++ b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_region.py @@ -26,6 +26,7 @@ def formula(household, period, parameters): p = parameters(period).gov.states.md.msde.ccs.payment is_region_u = np.isin(county, p.region_u_counties) is_region_v = np.isin(county, p.region_v_counties) + is_region_w = np.isin(county, p.region_w_counties) is_region_x = np.isin(county, p.region_x_counties) is_region_y = np.isin(county, p.region_y_counties) is_region_z = np.isin(county, p.region_z_counties) @@ -34,6 +35,7 @@ def formula(household, period, parameters): [ is_region_u, is_region_v, + is_region_w, is_region_x, is_region_y, is_region_z, @@ -42,6 +44,7 @@ def formula(household, period, parameters): [ MDCCSRegion.REGION_U, MDCCSRegion.REGION_V, + MDCCSRegion.REGION_W, MDCCSRegion.REGION_X, MDCCSRegion.REGION_Y, MDCCSRegion.REGION_Z, From 5b5479854f670c53da3dad8b044467f69bd171e6 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 26 Mar 2026 13:53:25 -0400 Subject: [PATCH 5/6] Review-fix round 2: fix COMAR URLs and subsection citations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace all broken dsd.maryland.gov URLs with regs.maryland.gov - Fix continuation.yaml: .03(B) → .03(H) (Income Eligibility Scale) - Fix self_employment_deduction_rate.yaml: (F)(6) → (F)(8)(a)(i) - Fix sources.yaml: (F)(3)-(8) → .02 (Gross income definition) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../gov/states/md/msde/ccs/age_threshold/child.yaml | 2 +- .../states/md/msde/ccs/age_threshold/disabled_child.yaml | 2 +- .../states/md/msde/ccs/copay/max_children_with_copay.yaml | 2 +- .../parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml | 2 +- .../gov/states/md/msde/ccs/copay/weekly_amount.yaml | 2 +- .../states/md/msde/ccs/income/countable_income/sources.yaml | 6 +++--- .../md/msde/ccs/income/self_employment_deduction_rate.yaml | 4 ++-- .../states/md/msde/ccs/income/smi_rate/continuation.yaml | 4 ++-- .../states/md/msde/ccs/payment/infant_age_threshold.yaml | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/child.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/child.yaml index 3d81b4a1ef6..f69a9aff0c5 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/child.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/child.yaml @@ -8,4 +8,4 @@ metadata: label: Maryland CCS child age threshold reference: - title: COMAR 13A.14.06.02 - Definitions, "Child" - href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.02.aspx + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.02 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/disabled_child.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/disabled_child.yaml index 55a67bc8011..a7337cb6fdd 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/disabled_child.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/age_threshold/disabled_child.yaml @@ -8,4 +8,4 @@ metadata: label: Maryland CCS disabled child age threshold reference: - title: COMAR 13A.14.06.02 - Definitions, "Child" - href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.02.aspx + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.02 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/max_children_with_copay.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/max_children_with_copay.yaml index 6dc26b33386..6c8e59955c2 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/max_children_with_copay.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/max_children_with_copay.yaml @@ -8,4 +8,4 @@ metadata: label: Maryland CCS maximum children with copayment reference: - title: COMAR 13A.14.06.12 - href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.12.aspx + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.12 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml index c4c292d7ec6..d445e101fc4 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml @@ -8,7 +8,7 @@ metadata: label: Maryland CCS service units by daily hours reference: - title: COMAR 13A.14.06.11 - href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.11.aspx + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.11 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml index f4a060e7cd0..b351e54da59 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml @@ -10,7 +10,7 @@ metadata: - title: Chapter 717 of 2024 href: https://mgaleg.maryland.gov/2024RS/Chapters_noln/CH_717_sb0482e.pdf#page=1 - title: COMAR 13A.14.06.12 - href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.12.aspx + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.12 UNIT_3: 2022-05-01: 3 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml index 5ca5e4e5549..587f31f087d 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml @@ -3,7 +3,7 @@ values: 2022-05-01: - employment_income # Note: self_employment_income is handled separately in the formula - # with a 30% deduction per COMAR 13A.14.06.03(F)(6) + # with a 30% deduction per COMAR 13A.14.06.03(F)(8)(a)(i) - social_security - pension_income - interest_income @@ -25,7 +25,7 @@ metadata: period: year label: Maryland CCS countable income sources reference: - - title: COMAR 13A.14.06.03(F)(3)-(8) - href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx + - title: COMAR 13A.14.06.02 - Definition of "Gross income" + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.02 - title: Chapters 525/526 of 2022 href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/self_employment_deduction_rate.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/self_employment_deduction_rate.yaml index 54034c673ee..1204f6afe01 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/income/self_employment_deduction_rate.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/self_employment_deduction_rate.yaml @@ -7,5 +7,5 @@ metadata: period: year label: Maryland CCS self-employment deduction rate reference: - - title: COMAR 13A.14.06.03(F)(6) - href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx + - title: COMAR 13A.14.06.03(F)(8)(a)(i) - Self-Employment Deduction + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.03 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml index e2417c31d6f..97ceccfd3e8 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/continuation.yaml @@ -7,8 +7,8 @@ metadata: period: year label: Maryland CCS continuation eligibility SMI rate reference: - - title: COMAR 13A.14.06.03(B) - href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.03.aspx + - title: COMAR 13A.14.06.03(H) - Income Eligibility Scale + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.03 - title: Chapters 525/526 of 2022 href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0275e.pdf#page=1 - title: 45 CFR 98.21(b) - Federal ceiling diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/infant_age_threshold.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/infant_age_threshold.yaml index 4810dd8cdcc..cd45ea9efe8 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/infant_age_threshold.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/infant_age_threshold.yaml @@ -10,4 +10,4 @@ metadata: - title: Maryland CCS Scholarship Rates href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates - title: COMAR 13A.14.06.02 - Definitions - href: https://dsd.maryland.gov/regulations/Pages/13A.14.06.02.aspx + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.02 From 66641c5e59f6cbd2de8e66f8b294b5218cca8dd9 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 26 Mar 2026 13:54:59 -0400 Subject: [PATCH 6/6] Add lessons from Maryland CCS implementation Co-Authored-By: Claude Opus 4.6 (1M context) --- lessons/agent-lessons.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 lessons/agent-lessons.md diff --git a/lessons/agent-lessons.md b/lessons/agent-lessons.md new file mode 100644 index 00000000000..b2bcee7c7df --- /dev/null +++ b/lessons/agent-lessons.md @@ -0,0 +1,18 @@ +# Agent Lessons Learned + +Accumulated from /encode-policy-v2 and /backdate-program runs across all contributors. +Loaded by implementation agents on future runs. + +## New Lessons from Maryland CCS (2026-03-26) + +### VARIABLE +- When a formula uses `select()` with a default/fallback for one category, replace it with explicit matching for ALL categories including the default; implicit defaults silently swallow new or misspelled values and make the "default" category untestable in isolation. + +### REFERENCE +- When a state regulation portal migrates domains (e.g., `dsd.maryland.gov` to `regs.maryland.gov`), ALL parameter files referencing the old domain must be updated in one pass; broken redirects (301 to 404) are systematic, not isolated, so always search-and-replace across the entire state directory rather than fixing one file at a time. +- When a parameter encodes a state policy choice (e.g., state sets 85% SMI threshold), cite the state regulation as the primary reference, not the federal CFR that merely sets the ceiling; federal authority is context, not the source of the state's specific value. +- When correcting a wrong COMAR/regulation subsection citation, verify the replacement subsection's content in the same review round; three of four citation corrections in this session initially pointed to the wrong subsection because adjacent subsections cover different provisions with similar-sounding names (e.g., .03(B) = citizenship vs .03(H) = income eligibility). + +### WORKFLOW +- When implementing a new state program, add it to `programs.yaml` as part of the initial implementation, not as an afterthought; missing registry entries block the program from appearing in the metadata API and coverage page. +- When a `select()` or similar lookup relies on a parameter file for each category, verify that ALL categories have corresponding parameter files before the first review round; a missing file for one category (e.g., Region W counties) forces the formula to use an implicit default, hiding a data gap.