diff --git a/changelog.d/md-ccap.added.md b/changelog.d/md-ccap.added.md new file mode 100644 index 00000000000..379dc3540da --- /dev/null +++ b/changelog.d/md-ccap.added.md @@ -0,0 +1 @@ +Implement Maryland Child Care Scholarship (CCS) program. 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 ed0f0a42c7d..1766eb70f13 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 @@ -7,6 +7,7 @@ values: - ct_child_care_subsidies # Connecticut Care 4 Kids - de_child_care_subsidies # Delaware Purchase of Care - 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 - vt_child_care_subsidies # Vermont Child Care Financial Assistance 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..f69a9aff0c5 --- /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://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 new file mode 100644 index 00000000000..a7337cb6fdd --- /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://regs.maryland.gov/us/md/exec/comar/13A.14.06.02 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..6c8e59955c2 --- /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://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 new file mode 100644 index 00000000000..0a9cc708554 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/unit_hours.yaml @@ -0,0 +1,27 @@ +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: Maryland CCS Provider Resources - Units of Service + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + - title: COMAR 13A.14.06.11 - Units of Service (general framework) + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.11 + +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..ef8cf4b9172 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/copay/weekly_amount.yaml @@ -0,0 +1,22 @@ +description: Maryland sets this amount as the weekly copayment by service unit under the Child Care Scholarship program. The flat $1/$2/$3 schedule replaced the historical COMAR 13A.14.06.12 regional matrix via MSDE policy in May 2022 and was frozen at January 1, 2024 levels by Chapter 717 of 2024 (SB 362). + +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 (SB 362) - Budget Reconciliation and Financing Act - freeze at January 1, 2024 levels + href: https://mgaleg.maryland.gov/2024RS/Chapters_noln/CH_717_sb0362E.pdf#page=19 + - title: MSDE Tuesday Tidbits bulletin (May 23, 2022) - introduction of $1/$2/$3 flat schedule + href: https://content.govdelivery.com/accounts/MDMSDE/bulletins/31a37f2 + - title: COMAR 13A.14.06.12 - codifies the historical regional matrix (superseded operationally) + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.12 + +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..3c7f45b6e50 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/countable_income/sources.yaml @@ -0,0 +1,35 @@ +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.03F(8)(a)(i) + - 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 Chapter 525 of 2022 / HB 995) + # COMAR-listed sources we don't model at the moment: commissions, tips, + # bonuses, annuities, estate income, military entitlements. + +metadata: + unit: list + period: year + label: Maryland CCS countable income sources + reference: + - title: COMAR 13A.14.06.02B(28) - Definition of "Gross income" + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.02 + - title: Chapter 525 of 2022 (HB 995) - child support excluded + href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0995E.pdf#page=1 + - title: Chapter 526 of 2022 (SB 920) + href: https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_526_sb0920E.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 new file mode 100644 index 00000000000..1204f6afe01 --- /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)(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_freeze_in_effect.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_freeze_in_effect.yaml new file mode 100644 index 00000000000..c4b71b22b07 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_freeze_in_effect.yaml @@ -0,0 +1,15 @@ +description: Maryland freezes the State Median Income (SMI) base year for Child Care Scholarship income eligibility during certain fiscal-year windows. When the freeze is in effect, the formula uses smi_frozen_year; otherwise it uses the current-year SMI. Maryland's fiscal year starts July 1. +values: + 2016-01-01: false + 2018-07-01: true + 2024-12-15: false + +metadata: + unit: bool + period: year + label: Maryland CCS SMI freeze in effect + reference: + - title: MSDE Child Care Scholarship Program Briefing (Feb 4, 2026), slide 21 - fiscal-year freeze schedule + href: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf#page=21 + - title: MSDE Jan 23, 2025 OCC Info Session - Dec 15, 2024 SMI unfreeze + href: https://earlychildhood.marylandpublicschools.org/system/files/filedepot/3/january_2025_occ_info_session.pdf#page=7 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_frozen_year.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_frozen_year.yaml new file mode 100644 index 00000000000..c3c1ab7017a --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_frozen_year.yaml @@ -0,0 +1,12 @@ +description: Maryland pins the State Median Income (SMI) base year used for Child Care Scholarship income eligibility when smi_freeze_in_effect is true. Maryland's fiscal year starts July 1. +values: + 2018-07-01: 2018 + 2022-07-01: 2021 + +metadata: + unit: year + period: year + label: Maryland CCS SMI frozen year + reference: + - title: MSDE Child Care Scholarship Program Briefing (Feb 4, 2026), slide 21 - fiscal-year base years + href: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf#page=21 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..103a08c30eb --- /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) - Federal CCDF continuation eligibility floor (85% SMI) + href: https://www.ecfr.gov/current/title-45/section-98.21#p-98.21(b) + - title: COMAR 13A.14.06.03H - Income Eligibility Scale + 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/initial.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml new file mode 100644 index 00000000000..c0b2879300f --- /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 + 2018-07-01: 0.65 + 2022-07-01: 0.75 + +metadata: + unit: /1 + period: year + label: Maryland CCS initial eligibility SMI rate + reference: + - title: COMAR 13A.14.06.03H - Income Eligibility Scale + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.03 + - title: MSDE Child Care Scholarship Program Briefing (Feb 4, 2026), slide 21 - historical thresholds + href: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf#page=21 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..2fa4997c641 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_center.yaml @@ -0,0 +1,64 @@ +description: Maryland provides these weekly UNIT_3 (full-time) reimbursement rates for licensed child care centers under the Child Care Scholarship program. UNIT_2 and UNIT_1 rates are derived in the formula by multiplying by unit_count / 3 per COMAR 13A.14.06.11. + +metadata: + period: week + unit: currency-USD + label: Maryland CCS licensed center weekly UNIT_3 rates + breakdown: + - md_ccs_region + - md_ccs_age_group + reference: + - title: Maryland CCS Scholarship Rates as of 3/1/26 + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + - title: Maryland CCS Scholarship Rates as of 5/23/22 (Wayback Machine snapshot) + href: https://web.archive.org/web/20220616202551/https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + +REGION_U: + REGULAR: + 2022-05-23: 205 + 2026-03-01: 244 + INFANT: + 2022-05-23: 296 + 2026-03-01: 325 +REGION_V: + REGULAR: + 2022-05-23: 175 + 2026-03-01: 200 + INFANT: + 2022-05-23: 242 + 2026-03-01: 264 +REGION_W: + REGULAR: + 2022-05-23: 262 + 2026-03-01: 305 + INFANT: + 2022-05-23: 370 + 2026-03-01: 420 +REGION_X: + REGULAR: + 2022-05-23: 381 + 2026-03-01: 424 + INFANT: + 2022-05-23: 481 + 2026-03-01: 554 +REGION_Y: + REGULAR: + 2022-05-23: 278 + 2026-03-01: 312 + INFANT: + 2022-05-23: 378 + 2026-03-01: 427 +REGION_Z: + REGULAR: + 2022-05-23: 183 + 2026-03-01: 207 + INFANT: + 2022-05-23: 262 + 2026-03-01: 297 +REGION_BC: + REGULAR: + 2022-05-23: 250 + 2026-03-01: 282 + INFANT: + 2022-05-23: 303 + 2026-03-01: 376 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..51127de43c2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/formal/licensed_family.yaml @@ -0,0 +1,64 @@ +description: Maryland provides these weekly UNIT_3 (full-time) reimbursement rates for licensed family child care homes under the Child Care Scholarship program. UNIT_2 and UNIT_1 rates are derived in the formula by multiplying by unit_count / 3 per COMAR 13A.14.06.11. + +metadata: + period: week + unit: currency-USD + label: Maryland CCS licensed family weekly UNIT_3 rates + breakdown: + - md_ccs_region + - md_ccs_age_group + reference: + - title: Maryland CCS Scholarship Rates as of 3/1/26 + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + - title: Maryland CCS Scholarship Rates as of 5/23/22 (Wayback Machine snapshot) + href: https://web.archive.org/web/20220616202551/https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + +REGION_U: + REGULAR: + 2022-05-23: 176 + 2026-03-01: 200 + INFANT: + 2022-05-23: 200 + 2026-03-01: 225 +REGION_V: + REGULAR: + 2022-05-23: 142 + 2026-03-01: 175 + INFANT: + 2022-05-23: 175 + 2026-03-01: 200 +REGION_W: + REGULAR: + 2022-05-23: 230 + 2026-03-01: 262 + INFANT: + 2022-05-23: 270 + 2026-03-01: 300 +REGION_X: + REGULAR: + 2022-05-23: 300 + 2026-03-01: 325 + INFANT: + 2022-05-23: 325 + 2026-03-01: 350 +REGION_Y: + REGULAR: + 2022-05-23: 220 + 2026-03-01: 250 + INFANT: + 2022-05-23: 250 + 2026-03-01: 288 +REGION_Z: + REGULAR: + 2022-05-23: 150 + 2026-03-01: 170 + INFANT: + 2022-05-23: 168 + 2026-03-01: 185 +REGION_BC: + REGULAR: + 2022-05-23: 182 + 2026-03-01: 225 + INFANT: + 2022-05-23: 210 + 2026-03-01: 252 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..b9e6d902567 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/infant_age_threshold.yaml @@ -0,0 +1,11 @@ +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 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..7b2366d95a6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/informal/rates.yaml @@ -0,0 +1,130 @@ +description: Maryland provides these weekly reimbursement rates for informal child care providers under the Child Care Scholarship program. Rates originate from the 70th percentile of the March 2021 Market Rate Survey and have remained operational at MSDE since November 2020. + +metadata: + period: week + unit: currency-USD + label: Maryland CCS informal provider weekly rates + reference: + - title: Maryland CCS Scholarship Rates (Informal Rates) + href: https://earlychildhood.marylandpublicschools.org/families/child-care-scholarship-program/child-care-scholarship-rates + +ALLEGANY_COUNTY_MD: + REGULAR: + 2020-11-23: 83 + INFANT: + 2020-11-23: 90 +ANNE_ARUNDEL_COUNTY_MD: + REGULAR: + 2020-11-23: 135 + INFANT: + 2020-11-23: 150 +BALTIMORE_COUNTY_MD: + REGULAR: + 2020-11-23: 125 + INFANT: + 2020-11-23: 150 +CALVERT_COUNTY_MD: + REGULAR: + 2020-11-23: 135 + INFANT: + 2020-11-23: 150 +CAROLINE_COUNTY_MD: + REGULAR: + 2020-11-23: 84 + INFANT: + 2020-11-23: 100 +CARROLL_COUNTY_MD: + REGULAR: + 2020-11-23: 135 + INFANT: + 2020-11-23: 150 +CECIL_COUNTY_MD: + REGULAR: + 2020-11-23: 105 + INFANT: + 2020-11-23: 120 +CHARLES_COUNTY_MD: + REGULAR: + 2020-11-23: 135 + INFANT: + 2020-11-23: 150 +DORCHESTER_COUNTY_MD: + REGULAR: + 2020-11-23: 84 + INFANT: + 2020-11-23: 100 +FREDERICK_COUNTY_MD: + REGULAR: + 2020-11-23: 125 + INFANT: + 2020-11-23: 150 +GARRETT_COUNTY_MD: + REGULAR: + 2020-11-23: 83 + INFANT: + 2020-11-23: 90 +HARFORD_COUNTY_MD: + REGULAR: + 2020-11-23: 125 + INFANT: + 2020-11-23: 150 +HOWARD_COUNTY_MD: + REGULAR: + 2020-11-23: 177 + INFANT: + 2020-11-23: 195 +KENT_COUNTY_MD: + REGULAR: + 2020-11-23: 84 + INFANT: + 2020-11-23: 100 +MONTGOMERY_COUNTY_MD: + REGULAR: + 2020-11-23: 177 + INFANT: + 2020-11-23: 195 +PRINCE_GEORGE_S_COUNTY_MD: + REGULAR: + 2020-11-23: 135 + INFANT: + 2020-11-23: 150 +QUEEN_ANNE_S_COUNTY_MD: + REGULAR: + 2020-11-23: 105 + INFANT: + 2020-11-23: 120 +ST_MARY_S_COUNTY_MD: + REGULAR: + 2020-11-23: 105 + INFANT: + 2020-11-23: 120 +SOMERSET_COUNTY_MD: + REGULAR: + 2020-11-23: 84 + INFANT: + 2020-11-23: 100 +TALBOT_COUNTY_MD: + REGULAR: + 2020-11-23: 105 + INFANT: + 2020-11-23: 120 +WASHINGTON_COUNTY_MD: + REGULAR: + 2020-11-23: 105 + INFANT: + 2020-11-23: 120 +WICOMICO_COUNTY_MD: + REGULAR: + 2020-11-23: 84 + INFANT: + 2020-11-23: 100 +WORCESTER_COUNTY_MD: + REGULAR: + 2020-11-23: 83 + INFANT: + 2020-11-23: 90 +BALTIMORE_CITY_MD: + REGULAR: + 2020-11-23: 106 + INFANT: + 2020-11-23: 120 diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_bc_counties.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_bc_counties.yaml new file mode 100644 index 00000000000..b9da883a771 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/region_bc_counties.yaml @@ -0,0 +1,12 @@ +description: Maryland assigns Baltimore City to Region BC for Child Care Scholarship rate purposes. +values: + 2020-11-23: + - BALTIMORE_CITY_MD + +metadata: + unit: list + period: year + label: Maryland CCS Region BC 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_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_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/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/parameters/gov/states/md/msde/ccs/payment/unit_count.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/unit_count.yaml new file mode 100644 index 00000000000..3dd57452c9c --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/payment/unit_count.yaml @@ -0,0 +1,18 @@ +description: Maryland's UNIT_3 (full-time) rate corresponds to three units of service per day per COMAR 13A.14.06.11. UNIT_2 and UNIT_1 rates are derived by multiplying the UNIT_3 rate by unit_count / 3 (i.e., 2/3 and 1/3 respectively). + +metadata: + unit: /1 + period: year + label: Maryland CCS service unit count + breakdown: + - md_ccs_service_unit + reference: + - title: COMAR 13A.14.06.11.B(3), .11.C(2), .11.D + href: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.11 + +UNIT_3: + 2022-05-01: 3 +UNIT_2: + 2022-05-01: 2 +UNIT_1: + 2022-05-01: 1 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 7d6212eec9a..671c7dd84fe 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -495,9 +495,10 @@ programs: full_name: Massachusetts Child Care Financial Assistance variable: ma_ccfa - state: MD - status: in_progress + status: complete name: Maryland CCS full_name: Maryland Child Care Scholarship + variable: md_child_care_subsidies - state: ME status: complete name: Maine CCAP 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..002a49eee69 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/edge_cases.yaml @@ -0,0 +1,461 @@ +# Maryland CCS Edge Case Tests +# Edge cases not covered by md_ccs_eligible.yaml, md_ccs_eligible_child.yaml, +# md_ccs_income_eligible.yaml, md_ccs_countable_income.yaml, md_ccs_weekly_copay.yaml, +# md_ccs.yaml, integration.yaml. + +- 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 + weekly_hours_worked: 40 + 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 + weekly_hours_worked: 40 + 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 10, large family of 8 with 6 children. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + employment_income: 120_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + person2: + age: 38 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + person3: + age: 12 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person4: + age: 10 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person5: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person6: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person7: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 4 + md_ccs_provider_type: LICENSED_CENTER + person8: + 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, 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.1 + input: + people: + person1: + age: 30 + self_employment_income: 60_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + 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.1 + input: + people: + person1: + age: 30 + employment_income: 50_000 + self_employment_income: 0 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + 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 19, four children copay capped at 3 children. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + person2: + age: 10 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person3: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person4: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person5: + age: 3 + 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, 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 24, zero childcare expenses results in zero benefit. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + 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] + 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.1 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + 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] + 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 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 + weekly_hours_worked: 40 + 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 35, federal 7 percent cap applies with three children. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 3_600 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + person2: + age: 10 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person3: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person4: + age: 3 + 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, 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.1 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 0 + 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 + 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.1 + input: + people: + person1: + age: 30 + self_employment_income: -60_000_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + 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] + 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: 793 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..b5bc97f4a5f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/integration.yaml @@ -0,0 +1,458 @@ +# 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.1 + input: + people: + person1: + age: 28 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 3 + 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] + 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 === + # 2025-01 uses 5/23/22 historical schedule (current schedule effective 2026-03-01). + # Default county: Allegany = Region Z, Center, REGULAR, UNIT_3 -> $183/week + # annual max reimbursement: $183 * 52 = $9,516 + # annual copay: $3 * 52 = $156 + # uncapped: max(12,000 - 156, 0) = 11,844 + # capped: min(11,844, 9,516) = 9,516 + # monthly: 9,516 / 12 = 793.00 + md_ccs: 793 + +- name: Case 2, two-parent family with two children and mixed income. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + employment_income: 60_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 33 + self_employment_income: 20_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person3: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person4: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 4 + md_ccs_provider_type: LICENSED_CENTER + 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 === + # 2025-01 uses 5/23/22 historical schedule. + # Default county: Allegany = Region Z, Center. + # person3 (age 7, REGULAR, UNIT_3): $183 * 1 = $183/week + # person4 (age 3, REGULAR, UNIT_2): $183 * (2/3) = $122/week + # weekly max: $183 + $122 = $305 -> annual max reimbursement: $305 * 52 = $15,860 + # annual copay: $5 * 52 = $260 + # uncapped: max(18,000 - 260, 0) = 17,740 + # capped: min(17,740, 15,860) = 15,860 + # monthly: 15,860 / 12 = 1,321.67 + md_ccs: 1_321.67 + +- name: Case 3, TCA recipient family with zero copay. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 25 + employment_income: 15_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 4 + 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] + 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.1 + input: + people: + person1: + age: 35 + employment_income: 100_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 33 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person4: + age: 3 + 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, 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 === + # 2025-01 uses 5/23/22 historical schedule. Default county: Allegany = Region Z, Center. + # person3 (age 5, REGULAR, UNIT_3): $183; person4 (age 3, REGULAR, UNIT_3): $183 + # annual max reimbursement: ($183 + $183) * 52 = $19,032 + # annual copay: $6 * 52 = $312 + # uncapped: max(20,000 - 312, 0) = 19,688 + # capped: min(19,688, 19,032) = 19,032 + # monthly: 19,032 / 12 = 1,586.00 + md_ccs: 1_586 + +- name: Case 5, enrolled family between 75 and 85 percent SMI with continuation eligibility. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + employment_income: 120_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 33 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person3: + age: 6 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person4: + age: 2 + 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, 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 === + # 2025-01 uses 5/23/22 historical schedule. Default county: Allegany = Region Z, Center. + # person3 (age 6): REGULAR, UNIT_3 -> $183/week + # person4 (age 2 = 24 months, not < 24): REGULAR, UNIT_3 -> $183/week + # annual max reimbursement: ($183 + $183) * 52 = $19,032 + # annual copay: $6 * 52 = $312 + # uncapped: max(22,000 - 312, 0) = 21,688 + # capped: min(21,688, 19,032) = 19,032 + # monthly: 19,032 / 12 = 1,586.00 + md_ccs: 1_586 + +- name: Case 6, SSI recipient with disabled teenager. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 45 + employment_income: 200_000 + ssi: 9_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 16 + is_disabled: true + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 6 + md_ccs_provider_type: LICENSED_CENTER + 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 === + # 2025-01 uses 5/23/22 historical schedule. + # Default county: Allegany = Region Z, Center, REGULAR, UNIT_3 -> $183/week + # annual max reimbursement: $183 * 52 = $9,516 + # uncapped: max(15,000 - 0, 0) = 15,000 + # capped: min(15,000, 9,516) = 9,516 + # monthly: 9,516 / 12 = 793.00 + md_ccs: 793 + +- name: Case 7, family with income above 85 percent SMI is not eligible even when enrolled. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + employment_income: 140_000 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 33 + is_tax_unit_head_or_spouse: true + immigration_status: CITIZEN + weekly_hours_worked: 40 + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + md_ccs_provider_type: LICENSED_CENTER + person4: + age: 3 + 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, 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..f167d01549b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs.yaml @@ -0,0 +1,187 @@ +# 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.1 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + 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] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: MD + output: + # Provider: LICENSED_CENTER (set), default county: Allegany = Region Z + # age 5 = REGULAR, 8hrs = UNIT_3 + # 2025-01 uses 5/23/22 historical schedule (current schedule effective 2026-03-01). + # weekly rate: $183, annual max reimbursement: $183 * 52 = $9,516 + # weekly copay: $3, annual copay: $3 * 52 = $156 + # uncapped: max(12,000 - 156, 0) = 11,844 + # capped: min(11,844, 9,516) = 9,516 + # monthly: 9,516 / 12 = 793.00 + md_ccs: 793 + +- name: Case 2, ineligible family gets zero benefit. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + person2: + age: 15 + 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] + 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.1 + input: + people: + person1: + age: 30 + employment_income: 20_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + 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] + is_tanf_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: MD + output: + # TCA: copay $0 + # 2025-01 uses 5/23/22 historical schedule. + # weekly rate: $183 (default center, Allegany = Region Z, regular, unit 3) + # annual max reimbursement: $183 * 52 = $9,516 + # uncapped: max(10,000 - 0, 0) = 10,000 + # capped: min(10,000, 9,516) = 9,516 + # monthly: 9,516 / 12 = 793.00 + md_ccs: 793 + +- name: Case 4, benefit capped at max reimbursement rate. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + 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) + # 2026-01 still uses 5/23/22 historical schedule (current schedule effective 2026-03-01). + # UNIT_3 base $150 * (2/3) = $100/week for UNIT_2 + # annual max reimbursement: $100 * 52 = $5,200 + # weekly copay: $2 (part-time), annual copay: $2 * 52 = $104 + # uncapped: max(20,000 - 104, 0) = 19,896 + # capped: min(19,896, 5,200) = 5,200 + # monthly: 5,200 / 12 = 433.33 + md_ccs: 433.33 + +- name: Case 5, informal provider rate by county. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + 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_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_activity_eligible.yaml new file mode 100644 index 00000000000..1f6fcbbb220 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_activity_eligible.yaml @@ -0,0 +1,140 @@ +# Tests for md_ccs_activity_eligible +# All parents (tax-unit head/spouse) must be working OR a full-time student. + +- name: Single working parent passes activity test. + period: 2025-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_activity_eligible: true + +- name: Single full-time student parent passes activity test. + period: 2025-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + is_full_time_student: true + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_activity_eligible: true + +- name: Single non-working non-student parent fails activity test. + period: 2025-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 0 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_activity_eligible: false + +- name: Two-parent household — both working passes. + period: 2025-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + person2: + age: 30 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 30 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + md_ccs_activity_eligible: true + +- name: Two-parent household — only one parent working fails (both must qualify). + period: 2025-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + person2: + age: 30 + is_tax_unit_head_or_spouse: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + md_ccs_activity_eligible: false + +- name: Two-parent household — one working, one full-time student passes. + period: 2025-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 40 + person2: + age: 28 + is_tax_unit_head_or_spouse: true + is_full_time_student: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + md_ccs_activity_eligible: true + +- name: Non-working non-student parent passes via meets_ccdf_activity_test fallback. + period: 2025-01 + input: + people: + person1: + age: 30 + is_tax_unit_head_or_spouse: true + weekly_hours_worked: 0 + spm_units: + spm_unit: + members: [person1] + meets_ccdf_activity_test: true + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_activity_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_age_group.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_age_group.yaml new file mode 100644 index 00000000000..138477aa18c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_age_group.yaml @@ -0,0 +1,54 @@ +# Tests for md_ccs_age_group (Person-level, Enum) +# Boundary: age_months < 24 → INFANT, else REGULAR + +- name: Newborn (age 0) is INFANT. + period: 2025-01 + input: + people: + person1: + age: 0 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_age_group: [INFANT] + +- name: Age 1 (12 months) is INFANT. + period: 2025-01 + input: + people: + person1: + age: 1 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_age_group: [INFANT] + +- name: Age exactly 2 (24 months) is REGULAR — boundary uses strict `<`. + period: 2025-01 + input: + people: + person1: + age: 2 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_age_group: [REGULAR] + +- name: Age 5 is REGULAR. + period: 2025-01 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_age_group: [REGULAR] 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..0104dfd4eb9 --- /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.1 + 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.1 + 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.1 + 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.1 + 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..5e7921dae5f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_eligible.yaml @@ -0,0 +1,118 @@ +# 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 + weekly_hours_worked: 40 + 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 + weekly_hours_worked: 40 + 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 + weekly_hours_worked: 40 + 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 + weekly_hours_worked: 40 + 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..ef692523db0 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_income_eligible.yaml @@ -0,0 +1,142 @@ +# 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 + +- name: Case 5, frozen SMI is converted to monthly before comparing income. + period: 2024-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 + # Frozen FY2024 four-person SMI uses 2021 MD SMI: 124,807 + # Monthly 75% SMI threshold: 124,807 * 0.75 / 12 = 7,800.44 + # 8,333.33 > 7,800.44 -> 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..db483251a5e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_payment_rate.yaml @@ -0,0 +1,218 @@ +# 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.1 + 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: + # 2026-01 uses 5/23/22 historical schedule (current schedule effective 2026-03-01). + # Region X, Center, REGULAR (age 5), UNIT_3 (8hrs): $381/week + md_ccs_payment_rate: [0, 381] + +- name: Licensed family, Region Y (Baltimore Co), infant, part-time. + period: 2026-01 + absolute_error_margin: 0.1 + 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: + # 2026-01 uses 5/23/22 historical schedule. + # Region Y, Family, INFANT (age 1 = 12 months < 24), UNIT_2 (4hrs): + # UNIT_3 base $250 * (2/3) = $166.67/week + md_ccs_payment_rate: [0, 166.67] + +- name: Informal provider, Montgomery County, regular, hourly. + period: 2026-01 + absolute_error_margin: 0.1 + 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.1 + 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: + # 2026-01 uses 5/23/22 historical schedule. + # Baltimore City (REGION_BC), Center, INFANT (age 1 = 12 months), UNIT_3 (8hrs): $303/week + md_ccs_payment_rate: [0, 303] + +- name: Licensed family, Region U (Cecil), regular, full-time. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + 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: CECIL_COUNTY_MD + output: + # 2026-01 uses 5/23/22 historical schedule. + # Region U, Family, REGULAR (age 4), UNIT_3 (8hrs): $176/week + md_ccs_payment_rate: [0, 176] + +- name: Informal provider, Anne Arundel, infant, full-time. + period: 2026-01 + absolute_error_margin: 0.1 + 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] + households: + household: + members: [person1, person2] + state_code: MD + county: ANNE_ARUNDEL_COUNTY_MD + output: + # Informal, Anne Arundel, INFANT (age 1 = 12 months < 24), UNIT_3 (8hrs): $150/week + md_ccs_payment_rate: [0, 150] + +- name: Licensed family, Region W (Anne Arundel), regular, full-time — post-2026-03-01 schedule. + period: 2027-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 40_000 + is_tax_unit_head_or_spouse: true + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_day: 8 + 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: ANNE_ARUNDEL_COUNTY_MD + output: + # 2027-01 uses post-2026-03-01 schedule (60th percentile of 2024 MRS). + # Region W, Family, REGULAR (age 4), UNIT_3 (8hrs): $262/week + md_ccs_payment_rate: [0, 262] diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_region.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_region.yaml new file mode 100644 index 00000000000..ca07fccf5ac --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_region.yaml @@ -0,0 +1,100 @@ +# Tests for md_ccs_region (Household-level, Enum) +# Verifies the 23-county-plus-Baltimore-City mapping into 7 rate regions. + +- name: Cecil County maps to Region U. + period: 2025-01 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: MD + county: CECIL_COUNTY_MD + output: + md_ccs_region: REGION_U + +- name: Caroline County maps to Region V. + period: 2025-01 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: MD + county: CAROLINE_COUNTY_MD + output: + md_ccs_region: REGION_V + +- name: Anne Arundel County maps to Region W. + period: 2025-01 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: MD + county: ANNE_ARUNDEL_COUNTY_MD + output: + md_ccs_region: REGION_W + +- name: Howard County maps to Region X. + period: 2025-01 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: MD + county: HOWARD_COUNTY_MD + output: + md_ccs_region: REGION_X + +- name: Baltimore County maps to Region Y. + period: 2025-01 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: MD + county: BALTIMORE_COUNTY_MD + output: + md_ccs_region: REGION_Y + +- name: Allegany County maps to Region Z. + period: 2025-01 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: MD + county: ALLEGANY_COUNTY_MD + output: + md_ccs_region: REGION_Z + +- name: Baltimore City maps to Region BC. + period: 2025-01 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: MD + county: BALTIMORE_CITY_MD + output: + md_ccs_region: REGION_BC diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_service_unit.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_service_unit.yaml new file mode 100644 index 00000000000..162a9228a84 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_service_unit.yaml @@ -0,0 +1,87 @@ +# Tests for md_ccs_service_unit (Person-level, Enum) +# Boundary thresholds: 0 → UNIT_1, 3.0001 → UNIT_2, 6 → UNIT_3 +# Hours = exactly 3 stays in UNIT_1; hours = exactly 6 lands in UNIT_3. + +- name: Zero hours is UNIT_1. + period: 2025-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 0 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_service_unit: [UNIT_1] + +- name: Exactly 3 hours is UNIT_1 (≤3 hours per day). + period: 2025-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 3 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_service_unit: [UNIT_1] + +- name: 3.5 hours is UNIT_2. + period: 2025-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 3.5 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_service_unit: [UNIT_2] + +- name: 5.999 hours is UNIT_2 (just below 6-hour boundary). + period: 2025-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 5.999 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_service_unit: [UNIT_2] + +- name: Exactly 6 hours is UNIT_3 (≥6 hours per day). + period: 2025-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 6 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_service_unit: [UNIT_3] + +- name: 12 hours is UNIT_3. + period: 2025-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 12 + households: + household: + members: [person1] + state_code: MD + output: + md_ccs_service_unit: [UNIT_3] 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..ca087994c5c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_weekly_copay.yaml @@ -0,0 +1,243 @@ +# 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.1 + 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.1 + 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.1 + 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.1 + 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.1 + 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.1 + 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] + receives_snap: true + households: + household: + members: [person1, person2] + state_code: MD + output: + # SNAP recipient -> copay waived per Ch 525/526 of 2022 + md_ccs_weekly_copay: 0 + +- name: Case 7, WIC eligible parent pays zero copay. + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 50_000 + is_tax_unit_head_or_spouse: true + receives_wic: true + wic: 100 + 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: + # 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.1 + 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_activity_eligible.py b/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_activity_eligible.py new file mode 100644 index 00000000000..0f28507bc48 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_activity_eligible.py @@ -0,0 +1,29 @@ +from policyengine_us.model_api import * + + +class md_ccs_activity_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Maryland Child Care Scholarship (CCS) based on activity requirements" + definition_period = MONTH + defined_for = StateCode.MD + reference = "https://earlychildhood.marylandpublicschools.org/system/files/filedepot/2/scholarship-brochure-4.pdf" + + def formula(spm_unit, period, parameters): + # CCS Brochure (Eligibility Requirements): each parent in the household + # must be working/employed, in an approved training program, or + # attending school. We approximate per-parent with employment + student; + # for activities we don't individually model (job training, job search, + # SNAP E&T, temporary leave, etc.), users can override at the SPMUnit + # level via the federal CCDF bare input meets_ccdf_activity_test. + person = spm_unit.members + is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) + hours_worked = person("weekly_hours_worked", period.this_year) + is_employed = hours_worked > 0 + is_student = person("is_full_time_student", period.this_year) + individually_eligible = is_employed | is_student + per_parent_check_passes = ( + spm_unit.sum(is_head_or_spouse & ~individually_eligible) == 0 + ) + fallback = spm_unit("meets_ccdf_activity_test", period.this_year) + return per_parent_check_passes | fallback 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..4238b826160 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible.py @@ -0,0 +1,28 @@ +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://regs.maryland.gov/us/md/exec/comar/13A.14.06.03", + "https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0995E.pdf#page=4", + ) + + 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) + activity_eligible = spm_unit("md_ccs_activity_eligible", period) + # COMAR 13A.14.06.03F(1) waives the income test for TCA applicants or + # recipients. We don't track TANF applicants separately from recipients + # at the moment; the regulation covers both. + is_tca = spm_unit("is_tanf_enrolled", period) + receives_ssi = add(spm_unit, period, ["ssi"]) > 0 + return ( + has_eligible_child + & activity_eligible + & (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..ed99d9db528 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/eligibility/md_ccs_eligible_child.py @@ -0,0 +1,21 @@ +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://regs.maryland.gov/us/md/exec/comar/13A.14.06.02" + + 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 + immigration_eligible = person( + "is_ccdf_immigration_eligible_child", period.this_year + ) + return age_eligible & 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..d1aa5728752 --- /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://regs.maryland.gov/us/md/exec/comar/13A.14.06.11", + "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..7481f8ff982 --- /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://regs.maryland.gov/us/md/exec/comar/13A.14.06.03", + "https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0995E.pdf#page=1", + ) + + 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..f24aa0123fc --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py @@ -0,0 +1,37 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import smi + + +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://regs.maryland.gov/us/md/exec/comar/13A.14.06.03", + "https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0995E.pdf#page=1", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.md.msde.ccs.income + countable_income = spm_unit("md_ccs_countable_income", period) + # Maryland freezes the SMI base year on a fiscal-year schedule (MSDE + # Feb 4, 2026 W&M briefing slide 21): FY2019-2022 used 2018 SMI, + # FY2023-2024 used 2021 SMI, FY2025+ uses current SMI. + if p.smi_freeze_in_effect: + size = spm_unit("spm_unit_size", period.this_year) + state = spm_unit.household("state_code_str", period.this_year) + smi_value = ( + smi(size, state, f"{p.smi_frozen_year}-10-01", parameters) + / MONTHS_IN_YEAR + ) + else: + smi_value = spm_unit("hhs_smi", period) + enrolled = spm_unit("md_ccs_enrolled", period) + income_limit = where( + enrolled, + smi_value * p.smi_rate.continuation, + smi_value * p.smi_rate.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..ca155470da3 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_provider_type.py @@ -0,0 +1,19 @@ +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" + NONE = "None" + + +class md_ccs_provider_type(Variable): + value_type = Enum + entity = Person + possible_values = MDCCSProviderType + default_value = MDCCSProviderType.NONE + definition_period = MONTH + label = "Maryland CCS child care provider type" + defined_for = StateCode.MD + reference = "https://regs.maryland.gov/us/md/exec/comar/13A.14.06.11" 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..49d3745d5d0 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_weekly_copay.py @@ -0,0 +1,62 @@ +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://regs.maryland.gov/us/md/exec/comar/13A.14.06.12", + "https://mgaleg.maryland.gov/2024RS/Chapters_noln/CH_717_sb0362E.pdf#page=19", + "https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0995E.pdf#page=3", + ) + + 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.12A(1). + # We don't track TANF applicants separately from recipients at the + # moment; the regulation covers both. + is_tca = spm_unit("is_tanf_enrolled", period) + receives_ssi = add(spm_unit, period, ["ssi"]) > 0 + + # SNAP/WIC recipients have copayments waived per Chapter 525 of 2022 + # (HB 995). Uses bare-input receives_snap (SPMUnit) and receives_wic + # (Person, summed) rather than the computed snap/wic benefits to + # avoid the cycle through snap_dependent_care_deduction → childcare_expenses → md_ccs. + is_snap = spm_unit("receives_snap", period) + is_wic = add(spm_unit, period, ["receives_wic"]) > 0 + exempt = is_tca | receives_ssi | is_snap | is_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. + # We don't track the COMAR youngest/2nd/3rd-child rank distinction at + # the moment — moot under the flat $1/$2/$3 schedule, where every child + # at the same service unit pays the same amount. + 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..678a79d25c6 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_payment_rate.py @@ -0,0 +1,43 @@ +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) + + # Rate tables store UNIT_3 base rates (three units of service per day). + # COMAR 13A.14.06.11.B(3), .11.C(2), .11.D direct: multiply by + # unit_count / 3 to derive UNIT_2 (2/3) and UNIT_1 (1/3) rates. + unit_share = p.unit_count[service_unit] / 3 + center_rate = p.formal.licensed_center[region][age_group] * unit_share + family_rate = p.formal.licensed_family[region][age_group] * unit_share + + 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] * unit_share + + return select( + [ + provider_type == MDCCSProviderType.LICENSED_CENTER, + provider_type == MDCCSProviderType.LICENSED_FAMILY, + provider_type == MDCCSProviderType.INFORMAL, + provider_type == MDCCSProviderType.NONE, + ], + [center_rate, family_rate, informal_rate, 0], + ) 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..4c458762a03 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_region.py @@ -0,0 +1,57 @@ +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" + REGION_BC = "Region BC" + + +class md_ccs_region(Variable): + value_type = Enum + entity = Household + # Non-MD households fall through to REGION_W; masked by defined_for on + # consumers, but the load-bearing default is needed because vectorized + # formula execution does not short-circuit on defined_for. + 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_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) + is_region_bc = np.isin(county, p.region_bc_counties) + return select( + [ + is_region_u, + is_region_v, + is_region_w, + is_region_x, + is_region_y, + is_region_z, + is_region_bc, + ], + [ + MDCCSRegion.REGION_U, + MDCCSRegion.REGION_V, + MDCCSRegion.REGION_W, + MDCCSRegion.REGION_X, + MDCCSRegion.REGION_Y, + MDCCSRegion.REGION_Z, + MDCCSRegion.REGION_BC, + ], + 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..73a0a7860dd --- /dev/null +++ b/policyengine_us/variables/gov/states/md/msde/ccs/payment/md_ccs_service_unit.py @@ -0,0 +1,31 @@ +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://regs.maryland.gov/us/md/exec/comar/13A.14.06.11" + + 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, units == 1], + [ + MDCCSServiceUnit.UNIT_3, + MDCCSServiceUnit.UNIT_2, + MDCCSServiceUnit.UNIT_1, + ], + ) diff --git a/policyengine_us/variables/gov/usda/snap/receives_snap.py b/policyengine_us/variables/gov/usda/snap/receives_snap.py new file mode 100644 index 00000000000..c1310239d75 --- /dev/null +++ b/policyengine_us/variables/gov/usda/snap/receives_snap.py @@ -0,0 +1,8 @@ +from policyengine_us.model_api import * + + +class receives_snap(Variable): + value_type = bool + entity = SPMUnit + label = "Reported to receive SNAP" + definition_period = MONTH