From 919d820ada02589be47a1c16813e9cc4b2a2e4f7 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Jun 2026 09:30:21 -0400 Subject: [PATCH 1/9] Initialize Mississippi CCPP (CCAP) branch Placeholder changelog fragment to start the ms-ccap branch. Co-Authored-By: Claude Opus 4.8 (1M context) --- changelog.d/ms-ccap.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/ms-ccap.added.md diff --git a/changelog.d/ms-ccap.added.md b/changelog.d/ms-ccap.added.md new file mode 100644 index 00000000000..87b9b43ca48 --- /dev/null +++ b/changelog.d/ms-ccap.added.md @@ -0,0 +1 @@ +Initialize Mississippi Child Care Payment Program (CCPP/CCAP) implementation. From 35d1e53d1e2e7874be45edb8f8c44077dd377bd9 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Jun 2026 12:41:24 -0400 Subject: [PATCH 2/9] Implement Mississippi Child Care Payment Program (ref #8647) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../hhs/ccdf/child_care_subsidy_programs.yaml | 1 + .../gov/states/ms/dhs/ccpp/age_group/age.yaml | 35 + .../ms/dhs/ccpp/copay/fpg_exempt_rate.yaml | 13 + .../ms/dhs/ccpp/copay/max_family_size.yaml | 13 + .../copay/minimum_fee_categories_cap.yaml | 16 + .../ms/dhs/ccpp/copay/rate/low_income.yaml | 34 + .../dhs/ccpp/copay/rate/very_low_income.yaml | 34 + .../dhs/ccpp/eligibility/activity_hours.yaml | 13 + .../dhs/ccpp/eligibility/child_age_limit.yaml | 11 + .../special_needs_child_age_limit.yaml | 11 + .../ms/dhs/ccpp/geography/metro_counties.yaml | 33 + .../ccpp/income/countable_income/sources.yaml | 29 + .../states/ms/dhs/ccpp/income/smi_rate.yaml | 11 + .../ccpp/income/very_low_income_smi_rate.yaml | 13 + .../gov/states/ms/dhs/ccpp/rates/center.yaml | 59 ++ .../states/ms/dhs/ccpp/rates/family_home.yaml | 59 ++ .../dhs/ccpp/rates/special_needs_center.yaml | 25 + .../ms/dhs/ccpp/rates/special_needs_home.yaml | 26 + .../ms/dhs/ccpp/time_category/hours.yaml | 25 + policyengine_us/programs.yaml | 8 +- .../ms/dhs/ccpp/copay/ms_ccpp_copay.yaml | 341 ++++++++++ .../ms_ccpp_activity_eligible.yaml | 171 +++++ .../ms_ccpp_categorically_eligible.yaml | 81 +++ .../ccpp/eligibility/ms_ccpp_eligible.yaml | 139 ++++ .../eligibility/ms_ccpp_eligible_child.yaml | 127 ++++ .../eligibility/ms_ccpp_income_eligible.yaml | 112 ++++ .../gov/states/ms/dhs/ccpp/integration.yaml | 273 ++++++++ .../gov/states/ms/dhs/ccpp/ms_ccpp.yaml | 192 ++++++ .../states/ms/dhs/ccpp/ms_ccpp_age_group.yaml | 96 +++ .../ms/dhs/ccpp/ms_ccpp_countable_income.yaml | 72 +++ .../dhs/ccpp/ms_ccpp_facility_location.yaml | 74 +++ .../dhs/ccpp/ms_ccpp_maximum_weekly_rate.yaml | 598 ++++++++++++++++++ .../ms/dhs/ccpp/ms_ccpp_time_category.yaml | 75 +++ .../states/ms/dhs/ccpp/copay/ms_ccpp_copay.py | 67 ++ .../eligibility/ms_ccpp_activity_eligible.py | 30 + .../ms_ccpp_categorically_eligible.py | 27 + .../dhs/ccpp/eligibility/ms_ccpp_eligible.py | 33 + .../eligibility/ms_ccpp_eligible_child.py | 26 + .../eligibility/ms_ccpp_income_eligible.py | 17 + .../gov/states/ms/dhs/ccpp/ms_ccpp.py | 24 + .../states/ms/dhs/ccpp/ms_ccpp_age_group.py | 26 + .../ms/dhs/ccpp/ms_ccpp_countable_income.py | 13 + .../ms/dhs/ccpp/ms_ccpp_facility_location.py | 30 + .../dhs/ccpp/ms_ccpp_maximum_weekly_rate.py | 46 ++ .../ms/dhs/ccpp/ms_ccpp_provider_type.py | 21 + .../ms/dhs/ccpp/ms_ccpp_time_category.py | 25 + .../ms/dhs/ccpp/ms_child_care_subsidies.py | 11 + 47 files changed, 3215 insertions(+), 1 deletion(-) create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/max_family_size.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/minimum_fee_categories_cap.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/low_income.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/activity_hours.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/geography/metro_counties.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/very_low_income_smi_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/center.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/family_home.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_center.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_home.yaml create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.yaml create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py 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 748e5f5bffc..28f19090689 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 @@ -17,6 +17,7 @@ values: - ky_child_care_subsidies # Kentucky Child Care Assistance Program - ma_child_care_subsidies # Massachusetts Child Care Financial Assistance - me_child_care_subsidies # Maine Child Care Affordability Program + - ms_child_care_subsidies # Mississippi Child Care Payment Program (CCPP) - ne_child_care_subsidies # Nebraska Child Care Subsidy - vt_child_care_subsidies # Vermont Child Care Financial Assistance Program - nh_child_care_subsidies # New Hampshire Child Care Scholarship Program diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml new file mode 100644 index 00000000000..2c58f159940 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml @@ -0,0 +1,35 @@ +description: Mississippi determines a child's age group for payment rates under the Child Care Payment Program. +# Maps age in years to the 4-band age-group index used by the rate tables: +# 0 = INFANT (birth through 12 months, i.e. under 1 year) +# 1 = TODDLER (12 months up to 36 months, i.e. 1 to under 3 years) +# 2 = PRESCHOOL (3 years up to kindergarten, i.e. 3 to under 5 years) +# 3 = SCHOOL_AGE (5 years and older) +# Boundaries from the CCPP Policy Manual definitions of Infant (#49), Toddler +# (#87), Preschool (#66), and School Age (#74). +metadata: + type: single_amount + threshold_unit: year + amount_unit: /1 + period: year + label: Mississippi CCPP child age group by age + reference: + - title: Mississippi CCPP Policy Manual, Definitions (Infant, Toddler, Preschool, School Age) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=14 + +brackets: + - threshold: + 2023-07-01: 0 + amount: + 2023-07-01: 0 + - threshold: + 2023-07-01: 1 + amount: + 2023-07-01: 1 + - threshold: + 2023-07-01: 3 + amount: + 2023-07-01: 2 + - threshold: + 2023-07-01: 5 + amount: + 2023-07-01: 3 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml new file mode 100644 index 00000000000..e5ce4029431 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml @@ -0,0 +1,13 @@ +description: Mississippi waives the co-payment for families at or below this share of the federal poverty line under the Child Care Payment Program. +# Families with gross income at or below the federal poverty line pay no +# co-payment. +values: + 2021-11-01: 1 + +metadata: + unit: /1 + period: year + label: Mississippi CCPP co-payment poverty line exemption rate + reference: + - title: Mississippi CCPP Policy Manual, Rule 6.2 (Co-payment Fees) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=39 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/max_family_size.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/max_family_size.yaml new file mode 100644 index 00000000000..b902528f7af --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/max_family_size.yaml @@ -0,0 +1,13 @@ +description: Mississippi caps family size at this number when determining the co-payment rate under the Child Care Payment Program. +# The published fee scale's largest family-size row is "6 or more", so families +# of 6+ all use the size-6 co-payment percentage. +values: + 2021-11-01: 6 + +metadata: + unit: person + period: year + label: Mississippi CCPP co-payment maximum family size + reference: + - title: Mississippi CCPP Family Co-Payment Fee Scale (effective November 1, 2021) + href: https://www.mdhs.ms.gov/wp-content/uploads/2021/11/Copay-Table-Update-11_01_21.pdf diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/minimum_fee_categories_cap.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/minimum_fee_categories_cap.yaml new file mode 100644 index 00000000000..1de32557494 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/minimum_fee_categories_cap.yaml @@ -0,0 +1,16 @@ +description: Mississippi caps the monthly co-payment at this amount for minimum-fee categories under the Child Care Payment Program. +# Minimum-fee categories (income above the federal poverty line) include +# protective-services children, parents with a disability receiving SSI, and +# special-needs children. The categories that cannot be tracked at the moment +# (transitional child care, teen parents, Healthy Families Mississippi) are +# handled on the variable side. +values: + 2021-11-01: 10 + +metadata: + unit: currency-USD + period: month + label: Mississippi CCPP minimum-fee co-payment cap + reference: + - title: Mississippi CCPP Policy Manual, Rule 6.2 (Co-payment Fees) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=39 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/low_income.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/low_income.yaml new file mode 100644 index 00000000000..25681e58e7c --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/low_income.yaml @@ -0,0 +1,34 @@ +description: Mississippi sets the co-payment as this share of gross income for families above 50% and up to 85% of state median income under the Child Care Payment Program. +# Co-payment percentage by family size for the "50% to 85% SMI" band. Family size +# is capped at 6 (the published table's "6 or more" row) before lookup. +metadata: + type: single_amount + threshold_unit: person + amount_unit: /1 + period: year + label: Mississippi CCPP co-payment rate above 50% SMI + reference: + - title: Mississippi CCPP Family Co-Payment Fee Scale (effective November 1, 2021) + href: https://www.mdhs.ms.gov/wp-content/uploads/2021/11/Copay-Table-Update-11_01_21.pdf + +brackets: + - threshold: + 2021-11-01: 2 + amount: + 2021-11-01: 0.065 + - threshold: + 2021-11-01: 3 + amount: + 2021-11-01: 0.06 + - threshold: + 2021-11-01: 4 + amount: + 2021-11-01: 0.055 + - threshold: + 2021-11-01: 5 + amount: + 2021-11-01: 0.05 + - threshold: + 2021-11-01: 6 + amount: + 2021-11-01: 0.045 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml new file mode 100644 index 00000000000..29310141ee6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml @@ -0,0 +1,34 @@ +description: Mississippi sets the co-payment as this share of gross income for families at or below 50% of state median income under the Child Care Payment Program. +# Co-payment percentage by family size for the "up to 50% SMI" band. Family size +# is capped at 6 (the published table's "6 or more" row) before lookup. +metadata: + type: single_amount + threshold_unit: person + amount_unit: /1 + period: year + label: Mississippi CCPP co-payment rate at or below 50% SMI + reference: + - title: Mississippi CCPP Family Co-Payment Fee Scale (effective November 1, 2021) + href: https://www.mdhs.ms.gov/wp-content/uploads/2021/11/Copay-Table-Update-11_01_21.pdf + +brackets: + - threshold: + 2021-11-01: 2 + amount: + 2021-11-01: 0.055 + - threshold: + 2021-11-01: 3 + amount: + 2021-11-01: 0.05 + - threshold: + 2021-11-01: 4 + amount: + 2021-11-01: 0.045 + - threshold: + 2021-11-01: 5 + amount: + 2021-11-01: 0.04 + - threshold: + 2021-11-01: 6 + amount: + 2021-11-01: 0.035 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/activity_hours.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/activity_hours.yaml new file mode 100644 index 00000000000..54f773a5704 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/activity_hours.yaml @@ -0,0 +1,13 @@ +description: Mississippi sets this minimum weekly activity hours requirement under the Child Care Payment Program. +# Parents or caretakers must work at least this many hours per week, or be +# enrolled full-time in education or approved job training (or a combination). +values: + 2021-11-01: 25 + +metadata: + unit: hour + period: week + label: Mississippi CCPP minimum weekly activity hours + reference: + - title: Mississippi CCPP Policy Manual, Rule 5.9 (Activity Requirement) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=24 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml new file mode 100644 index 00000000000..841f8484ab0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml @@ -0,0 +1,11 @@ +description: Mississippi limits the Child Care Payment Program to children younger than this age. +values: + 2021-11-01: 13 + +metadata: + unit: year + period: year + label: Mississippi CCPP child age limit + reference: + - title: Mississippi CCPP Policy Manual, Rule 5.2 (Eligibility) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml new file mode 100644 index 00000000000..c61acc90bbc --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml @@ -0,0 +1,11 @@ +description: Mississippi limits the Child Care Payment Program to special-needs children younger than this age. +values: + 2021-11-01: 19 + +metadata: + unit: year + period: year + label: Mississippi CCPP special-needs child age limit + reference: + - title: Mississippi CCPP Policy Manual, Rule 5.2 (Eligibility) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/geography/metro_counties.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/geography/metro_counties.yaml new file mode 100644 index 00000000000..3144507001f --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/geography/metro_counties.yaml @@ -0,0 +1,33 @@ +description: Mississippi designates these counties as metropolitan for payment rates under the Child Care Payment Program. +# The 17 Mississippi counties in a Metropolitan Statistical Area under the OMB +# February 2013 delineation (the basis for the 2013 NCHS Urban-Rural scheme the +# Market Rate Survey uses). Every other Mississippi county is treated as +# non-metro. Grouped by MSA: Jackson, Gulfport-Biloxi-Pascagoula, Hattiesburg, +# and the Mississippi portion of Memphis. +values: + 2023-07-01: + - COPIAH_COUNTY_MS + - HINDS_COUNTY_MS + - MADISON_COUNTY_MS + - RANKIN_COUNTY_MS + - SIMPSON_COUNTY_MS + - YAZOO_COUNTY_MS + - HANCOCK_COUNTY_MS + - HARRISON_COUNTY_MS + - JACKSON_COUNTY_MS + - FORREST_COUNTY_MS + - LAMAR_COUNTY_MS + - PERRY_COUNTY_MS + - BENTON_COUNTY_MS + - DESOTO_COUNTY_MS + - MARSHALL_COUNTY_MS + - TATE_COUNTY_MS + - TUNICA_COUNTY_MS + +metadata: + unit: list + period: year + label: Mississippi CCPP metropolitan counties + reference: + - title: OMB Bulletin No. 13-01, Metropolitan and Micropolitan Statistical Area delineations (February 2013) + href: https://www2.census.gov/programs-surveys/metro-micro/geographies/reference-files/2013/delineation-files/list1.xls diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml new file mode 100644 index 00000000000..c31d5e0b9a0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml @@ -0,0 +1,29 @@ +description: Mississippi counts these gross income sources for eligibility and the co-payment under the Child Care Payment Program. +values: + 2021-11-01: + - employment_income # wages, salary, military base pay, commissions, bonuses, tips + - self_employment_income # gross self-employment income (can be negative; floored at 0 downstream) + - sstb_self_employment_income + - farm_operations_income + - social_security # SSA benefits for parent and child (umbrella; do not also add social_security_disability) + - ssi # SSI for parent and child (separate from the social_security umbrella) + - unemployment_compensation # counted at redetermination only; simplified to always countable + - workers_compensation + - alimony_income + - veterans_benefits + - pension_income # retirement and pension + - rental_income + - dividend_income + - interest_income + - capital_gains + # Countable items in the manual with no matching variable at the moment: + # military allotments, lump sums. + # Tips, commissions, and bonuses are captured by employment_income. + +metadata: + unit: list + period: year + label: Mississippi CCPP countable income sources + reference: + - title: Mississippi CCPP Policy Manual, Rule 5.9 (Income) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=24 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml new file mode 100644 index 00000000000..255532bed4d --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml @@ -0,0 +1,11 @@ +description: Mississippi limits income to this share of state median income for eligibility under the Child Care Payment Program. +values: + 2021-11-01: 0.85 + +metadata: + unit: /1 + period: year + label: Mississippi CCPP SMI income limit rate + reference: + - title: Mississippi CCPP Policy Manual, Rule 5.2 (Eligibility) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/very_low_income_smi_rate.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/very_low_income_smi_rate.yaml new file mode 100644 index 00000000000..2dd42695df2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/very_low_income_smi_rate.yaml @@ -0,0 +1,13 @@ +description: Mississippi uses this share of state median income to split the co-payment bands under the Child Care Payment Program. +# Families at or below 50% of state median income use the lower co-payment band; +# families above 50% (up to the 85% entry limit) use the higher band. +values: + 2021-11-01: 0.5 + +metadata: + unit: /1 + period: year + label: Mississippi CCPP very low income SMI rate + reference: + - title: Mississippi CCPP Family Co-Payment Fee Scale (effective November 1, 2021) + href: https://www.mdhs.ms.gov/wp-content/uploads/2021/11/Copay-Table-Update-11_01_21.pdf diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/center.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/center.yaml new file mode 100644 index 00000000000..6aba708c1fc --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/center.yaml @@ -0,0 +1,59 @@ +description: Mississippi provides these maximum weekly payment rates for licensed child care centers under the Child Care Payment Program. +# Operative "Current CCPP Rates" schedule effective July 2023 (2024 Market Rate +# Survey Table 1, p.9). Rates vary by the facility's location (metro / non-metro); +# we use the household's county as a proxy for facility location. Special-needs +# children are paid the flat all-ages special-needs rate (see special_needs_center). +metadata: + period: week + unit: currency-USD + label: Mississippi CCPP center weekly rates + breakdown: + - ms_ccpp_facility_location + - ms_ccpp_age_group + - ms_ccpp_time_category + reference: + - title: 2024 Mississippi Child Care Market Rate Survey, Table 1 (Current CCPP Rates, Licensed Centers) + href: https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=9 + +METRO: + INFANT: + FULL_TIME: + 2023-07-01: 152 + PART_TIME: + 2023-07-01: 90 + TODDLER: + FULL_TIME: + 2023-07-01: 145 + PART_TIME: + 2023-07-01: 90 + PRESCHOOL: + FULL_TIME: + 2023-07-01: 135 + PART_TIME: + 2023-07-01: 75 + SCHOOL_AGE: + FULL_TIME: + 2023-07-01: 130 + PART_TIME: + 2023-07-01: 80 +NON_METRO: + INFANT: + FULL_TIME: + 2023-07-01: 125 + PART_TIME: + 2023-07-01: 80 + TODDLER: + FULL_TIME: + 2023-07-01: 120 + PART_TIME: + 2023-07-01: 75 + PRESCHOOL: + FULL_TIME: + 2023-07-01: 120 + PART_TIME: + 2023-07-01: 75 + SCHOOL_AGE: + FULL_TIME: + 2023-07-01: 110 + PART_TIME: + 2023-07-01: 74 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/family_home.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/family_home.yaml new file mode 100644 index 00000000000..51173d8d770 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/family_home.yaml @@ -0,0 +1,59 @@ +description: Mississippi provides these maximum weekly payment rates for registered family child care homes under the Child Care Payment Program. +# Operative "Current CCPP Rates" schedule effective July 2023 (2024 Market Rate +# Survey Table 2, p.10). Rates vary by the facility's location (metro / non-metro); +# we use the household's county as a proxy for facility location. Special-needs +# children are paid the flat all-ages special-needs rate (see special_needs_home). +metadata: + period: week + unit: currency-USD + label: Mississippi CCPP family home weekly rates + breakdown: + - ms_ccpp_facility_location + - ms_ccpp_age_group + - ms_ccpp_time_category + reference: + - title: 2024 Mississippi Child Care Market Rate Survey, Table 2 (Current CCPP Rates, Registered Family Homes) + href: https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=10 + +METRO: + INFANT: + FULL_TIME: + 2023-07-01: 115 + PART_TIME: + 2023-07-01: 68 + TODDLER: + FULL_TIME: + 2023-07-01: 120 + PART_TIME: + 2023-07-01: 75 + PRESCHOOL: + FULL_TIME: + 2023-07-01: 120 + PART_TIME: + 2023-07-01: 60 + SCHOOL_AGE: + FULL_TIME: + 2023-07-01: 95 + PART_TIME: + 2023-07-01: 58 +NON_METRO: + INFANT: + FULL_TIME: + 2023-07-01: 94 + PART_TIME: + 2023-07-01: 60 + TODDLER: + FULL_TIME: + 2023-07-01: 98 + PART_TIME: + 2023-07-01: 61 + PRESCHOOL: + FULL_TIME: + 2023-07-01: 106 + PART_TIME: + 2023-07-01: 60 + SCHOOL_AGE: + FULL_TIME: + 2023-07-01: 79 + PART_TIME: + 2023-07-01: 53 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_center.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_center.yaml new file mode 100644 index 00000000000..c986f0ceb5d --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_center.yaml @@ -0,0 +1,25 @@ +description: Mississippi provides these maximum weekly payment rates for special-needs children in licensed child care centers under the Child Care Payment Program. +# Flat all-ages special-needs rate effective July 2023 (2024 Market Rate Survey +# Table 1, p.9). This rate is the same for metro and non-metro facilities, but is +# keyed by location for structural consistency with the standard center rates. +metadata: + period: week + unit: currency-USD + label: Mississippi CCPP special-needs center weekly rates + breakdown: + - ms_ccpp_facility_location + - ms_ccpp_time_category + reference: + - title: 2024 Mississippi Child Care Market Rate Survey, Table 1 (Current CCPP Rates, Licensed Centers, Special Needs) + href: https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=9 + +METRO: + FULL_TIME: + 2023-07-01: 145 + PART_TIME: + 2023-07-01: 87 +NON_METRO: + FULL_TIME: + 2023-07-01: 145 + PART_TIME: + 2023-07-01: 87 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_home.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_home.yaml new file mode 100644 index 00000000000..e4dc0747a75 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_home.yaml @@ -0,0 +1,26 @@ +description: Mississippi provides these maximum weekly payment rates for special-needs children in registered family child care homes under the Child Care Payment Program. +# Flat all-ages special-needs rate effective July 2023 (2024 Market Rate Survey +# Table 2, p.10). This rate is the same for metro and non-metro facilities, but is +# keyed by location for structural consistency with the standard family-home rates. +# In-home care (special-needs only, child's own home) is paid this home-based rate. +metadata: + period: week + unit: currency-USD + label: Mississippi CCPP special-needs family home weekly rates + breakdown: + - ms_ccpp_facility_location + - ms_ccpp_time_category + reference: + - title: 2024 Mississippi Child Care Market Rate Survey, Table 2 (Current CCPP Rates, Registered Family Homes, Special Needs) + href: https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=10 + +METRO: + FULL_TIME: + 2023-07-01: 125 + PART_TIME: + 2023-07-01: 63 +NON_METRO: + FULL_TIME: + 2023-07-01: 125 + PART_TIME: + 2023-07-01: 63 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml new file mode 100644 index 00000000000..06c43a78c5e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml @@ -0,0 +1,25 @@ +description: Mississippi determines a child's care time category from daily care hours under the Child Care Payment Program. +# Maps childcare hours per day to the time-category index used by the rate tables: +# 0 = PART_TIME (fewer than 6 hours of a 24-hour day) +# 1 = FULL_TIME (6 or more hours of a 24-hour day) +# Threshold from the CCPP Policy Manual definitions of Full-Time (#44) and +# Part-Time (#65) care. +metadata: + type: single_amount + threshold_unit: hour + amount_unit: /1 + period: year + label: Mississippi CCPP time category by daily hours + reference: + - title: Mississippi CCPP Policy Manual, Definitions (Full-Time, Part-Time) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=14 + +brackets: + - threshold: + 2023-07-01: 0 + amount: + 2023-07-01: 0 + - threshold: + 2023-07-01: 6 + amount: + 2023-07-01: 1 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 83ef1f1f1a0..d7394fe7457 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -460,7 +460,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: AK, AR, AL, CA, CO, CT, DE, DC, FL, HI, IA, ID, IL, IN, KS, KY, MA, MD, ME, NC, NH, NJ, PA, RI, SC, TX, VA, VT, WA, WV + coverage: AK, AR, AL, CA, CO, CT, DE, DC, FL, HI, IA, ID, IL, IN, KS, KY, MA, MD, ME, MS, NC, NH, NJ, PA, RI, SC, TX, VA, VT, WA, WV state_implementations: - state: AK status: complete @@ -554,6 +554,12 @@ programs: name: Maine CCAP full_name: Maine Child Care Affordability Program variable: me_ccap + - state: MS + status: complete + name: CCPP + full_name: Mississippi Child Care Payment Program + variable: ms_ccpp + parameter_prefix: gov.states.ms.dhs.ccpp - state: IA status: complete name: Iowa CCA diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml new file mode 100644 index 00000000000..e25236a44a5 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml @@ -0,0 +1,341 @@ +# ms_ccpp_copay is SPMUnit, MONTH. +# Family copay = monthly countable income (floored at 0) x rate, where the rate +# comes from the family-size band selected by position relative to 50% SMI. +# $0 at/below the federal poverty line, for TANF, and for homeless-no-income. +# $10/month cap for minimum-fee categories (protective services, SSI-disabled +# parent, special-needs child) when income is above the poverty line. +# +# Monthly federal SMI / FPG (MS, 2024), and copay rates: +# Size 2: 50% SMI = 2,133.50; FPG = 1,703.33; very-low 5.5% / low 6.5% +# Size 3: 50% SMI = 2,635.50; FPG = 2,151.67; very-low 5.0% / low 6.0% +# Size 4: 50% SMI = 3,137.50; FPG = 2,600.00; very-low 4.5% / low 5.5% + +- name: Case 1, very-low-income band above FPL, family of 3. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 28_800 # YEAR -> 2,400/mo + person2: + age: 30 + person3: + age: 4 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + output: + # Monthly income 2,400: > FPG 2,151.67 (not exempt), <= 50% SMI 2,635.50 + # -> very-low band, family size 3 rate 5.0% + # Copay = 2,400 * 0.05 = 120 + ms_ccpp_copay: 120 + +- name: Case 2, low-income band (50-85 percent SMI), family of 4. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 48_000 # YEAR -> 4,000/mo + person2: + age: 33 + person3: + age: 4 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MS + output: + # Monthly income 4,000: > 50% SMI 3,137.50 -> low band, size 4 rate 5.5% + # Copay = 4,000 * 0.055 = 220 + ms_ccpp_copay: 220 + +- name: Case 3, income at or below the federal poverty line pays zero copay. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 18_000 # YEAR -> 1,500/mo + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Monthly income 1,500 <= FPG 1,703.33 (family of 2) -> $0 copay + ms_ccpp_copay: 0 + +- name: Case 4, special-needs child caps the copay at $10. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 28_800 # YEAR -> 2,400/mo + person2: + age: 30 + person3: + age: 4 + is_disabled: true # special-needs child -> minimum-fee category + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + output: + # Uncapped very-low band copay = 2,400 * 0.05 = 120; above FPL 2,151.67 + # -> minimum-fee category caps at $10 + ms_ccpp_copay: 10 + +- name: Case 5, protective-services child caps the copay at $10. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # YEAR -> 2,000/mo + person2: + age: 4 + receives_or_needs_protective_services: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Uncapped very-low band copay = 2,000 * 0.055 = 110; above FPL 1,703.33 + # -> minimum-fee category caps at $10 + ms_ccpp_copay: 10 + +- name: Case 6, SSI-disabled parent caps the copay at $10. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 24_000 # YEAR -> 2,000/mo + is_ssi_disabled: true + person2: + age: 4 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Uncapped very-low band copay = 2,000 * 0.055 = 110; above FPL 1,703.33 + # SSI-disabled parent -> minimum-fee category caps at $10 + ms_ccpp_copay: 10 + +- name: Case 7, TANF family pays zero copay even above FPL. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # YEAR -> 2,000/mo + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: MS + output: + # Income 2,000 > FPG 1,703.33, but TANF enrollment waives the copay + ms_ccpp_copay: 0 + +- name: Case 8, negative countable income floors at zero copay. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + self_employment_income: -60_000 # YEAR -> -5,000/mo + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Income floored at 0; 0 <= FPG -> $0 copay (no negative-income inflation) + ms_ccpp_copay: 0 + +- name: Case 9, band boundary just below 50 percent SMI uses very-low rate, family of 4. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 37_649.88 # YEAR -> 3,137.49/mo, 0.01 below 50% SMI + person2: + age: 33 + person3: + age: 4 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MS + output: + # Monthly 3,137.49 <= 50% SMI 3,137.50 -> very-low band, rate 4.5% + # Copay = 3,137.49 * 0.045 = 141.19 + ms_ccpp_copay: 141.19 + +- name: Case 10, band boundary just above 50 percent SMI uses low rate, family of 4. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 37_650.12 # YEAR -> 3,137.51/mo, 0.01 above 50% SMI + person2: + age: 33 + person3: + age: 4 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MS + output: + # Monthly 3,137.51 > 50% SMI 3,137.50 -> low band, rate 5.5% + # Copay = 3,137.51 * 0.055 = 172.56 + ms_ccpp_copay: 172.56 + +# === Edge cases (see Cases 1-10 above) === +- name: Case 11, zero income pays zero copay. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # No income; 0 <= FPG (family of 2, 1,703.33) -> $0 copay + ms_ccpp_copay: 0 + +# Family-size cap at 6: families of 7-8 use the published "6 or more" copay row. +# For size 7, FPG/mo = 3,945.00 and 50% SMI/mo = 4,235.63. +- name: Case 12, family of 7 in very-low band uses the size-6 capped rate. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 49_200 # YEAR -> 4,100/mo + person2: + age: 38 + person3: + age: 4 + person4: + age: 6 + person5: + age: 8 + person6: + age: 10 + person7: + age: 12 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: MS + output: + # Income 4,100/mo: > FPG 3,945.00 (not exempt), <= 50% SMI 4,235.63 + # -> very-low band; size 7 capped to size-6 row rate 3.5% + # Copay = 4,100 * 0.035 = 143.50 + ms_ccpp_copay: 143.50 + +- name: Case 13, family of 7 in low band uses the size-6 capped rate. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 60_000 # YEAR -> 5,000/mo + person2: + age: 38 + person3: + age: 4 + person4: + age: 6 + person5: + age: 8 + person6: + age: 10 + person7: + age: 12 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: MS + output: + # Income 5,000/mo: > 50% SMI 4,235.63 -> low band; size 7 capped to + # the size-6 row rate 4.5% + # Copay = 5,000 * 0.045 = 225.00 + ms_ccpp_copay: 225.00 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.yaml new file mode 100644 index 00000000000..105d2d540fd --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.yaml @@ -0,0 +1,171 @@ +# ms_ccpp_activity_eligible is SPMUnit, MONTH. +# Each parent/caretaker (tax unit head/spouse) must work >= 25 hr/wk OR be a +# full-time student OR be an SSI-disabled parent (activity waived). +# Uses weekly_hours_worked_before_lsr (default 40), NOT weekly_hours_worked. + +- name: Case 1, single parent working 40 hours per week. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_activity_eligible: true + +- name: Case 2, single parent working exactly 25 hours per week (lower boundary). + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 25 + person2: + age: 4 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_activity_eligible: true + +- name: Case 3, single parent working 24 hours per week and not a student. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 24 + is_full_time_student: false + person2: + age: 4 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_activity_eligible: false + +- name: Case 4, single parent full-time student working under 25 hours. + period: 2024-01 + input: + people: + person1: + age: 22 + weekly_hours_worked_before_lsr: 10 + is_full_time_student: true + person2: + age: 4 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_activity_eligible: true + +- name: Case 5, SSI-disabled parent has activity requirement waived. + period: 2024-01 + input: + people: + person1: + age: 40 + weekly_hours_worked_before_lsr: 0 + is_full_time_student: false + is_ssi_disabled: true + person2: + age: 4 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_activity_eligible: true + +- name: Case 6, two-parent household one parent working under 25 hours. + period: 2024-01 + input: + people: + person1: + age: 35 + weekly_hours_worked_before_lsr: 40 + person2: + age: 33 + weekly_hours_worked_before_lsr: 10 + is_full_time_student: false + is_ssi_disabled: false + person3: + age: 4 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + output: + # Every head/spouse must individually meet activity; person2 fails -> not eligible + ms_ccpp_activity_eligible: false + +- name: Case 7, two-parent household both meeting activity. + period: 2024-01 + input: + people: + person1: + age: 35 + weekly_hours_worked_before_lsr: 40 + person2: + age: 33 + weekly_hours_worked_before_lsr: 30 + person3: + age: 4 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + output: + ms_ccpp_activity_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.yaml new file mode 100644 index 00000000000..bd6cc96aa27 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.yaml @@ -0,0 +1,81 @@ +# ms_ccpp_categorically_eligible is SPMUnit, MONTH. +# Modeled categorical pathways that bypass the income test: TANF enrollment, +# homelessness, and protective services. TCC, Healthy Families Mississippi, and +# teen parents are not tracked at the moment. + +- name: Case 1, TANF-enrolled family is categorically eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_categorically_eligible: true + +- name: Case 2, homeless family is categorically eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + is_homeless: true + output: + ms_ccpp_categorically_eligible: true + +- name: Case 3, protective-services child is categorically eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + receives_or_needs_protective_services: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_categorically_eligible: true + +- name: Case 4, no categorical pathway. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: false + households: + household: + members: [person1, person2] + state_code: MS + is_homeless: false + output: + ms_ccpp_categorically_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.yaml new file mode 100644 index 00000000000..995fb31d79b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.yaml @@ -0,0 +1,139 @@ +# ms_ccpp_eligible is SPMUnit, MONTH. +# Standard path: eligible child AND assets AND income AND activity. +# Categorical path: eligible child AND assets AND (TANF | homeless | protective), +# which bypasses the income and activity tests. + +- name: Case 1, working low-income family with eligible child is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_income_eligible: true + ms_ccpp_activity_eligible: true + ms_ccpp_eligible: true + +- name: Case 2, income over 85 percent SMI and not working is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 70_000 + weekly_hours_worked_before_lsr: 10 + is_full_time_student: false + person2: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Family of 2: 70,000 > 43,523.40 (85% SMI) and activity not met + ms_ccpp_income_eligible: false + ms_ccpp_activity_eligible: false + ms_ccpp_eligible: false + +- name: Case 3, TANF family over income limit is eligible via categorical bypass. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 70_000 # above 85% SMI for family of 2 + weekly_hours_worked_before_lsr: 0 # activity not met + is_full_time_student: false + person2: + age: 4 + is_tax_unit_dependent: true + 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: MS + output: + # Income and activity both fail, but TANF categorical bypasses them + ms_ccpp_income_eligible: false + ms_ccpp_activity_eligible: false + ms_ccpp_categorically_eligible: true + ms_ccpp_eligible: true + +- name: Case 4, no eligible child means not eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked_before_lsr: 40 + person2: + age: 15 # over 13, not disabled -> not an eligible child + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_eligible: false + +- name: Case 5, non-Mississippi household is not eligible (defined_for gate). + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 6_000 + households: + household: + members: [person1, person2] + state_code: AL # not Mississippi + output: + # defined_for = StateCode.MS zeroes the gate and the benefit for non-MS + ms_ccpp_eligible: false + ms_ccpp: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.yaml new file mode 100644 index 00000000000..9e9c12468aa --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.yaml @@ -0,0 +1,127 @@ +# ms_ccpp_eligible_child is Person, MONTH. +# A child is eligible when under age 13 (under 19 if special-needs/disabled), +# immigration-eligible (citizen or qualified non-citizen), and a tax-unit dependent. + +- name: Case 1, age 12 child is eligible. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 12 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # age 12 < 13 -> eligible + ms_ccpp_eligible_child: [false, true] + +- name: Case 2, age 13 child is not eligible. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 13 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # age 13 not < 13 -> ineligible + ms_ccpp_eligible_child: [false, false] + +- name: Case 3, disabled child age 18 is eligible. + period: 2024-01 + input: + people: + person1: + age: 45 + person2: + age: 18 + is_disabled: true + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # disabled, age 18 < 19 -> eligible + ms_ccpp_eligible_child: [false, true] + +- name: Case 4, disabled child age 19 is not eligible. + period: 2024-01 + input: + people: + person1: + age: 45 + person2: + age: 19 + is_disabled: true + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # disabled, age 19 not < 19 -> ineligible + ms_ccpp_eligible_child: [false, false] + +- name: Case 5, undocumented child is not immigration eligible. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # undocumented child is not a qualified non-citizen -> ineligible + ms_ccpp_eligible_child: [false, false] + +- name: Case 6, refugee child is immigration eligible. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: REFUGEE + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # refugee is a qualified non-citizen -> eligible + ms_ccpp_eligible_child: [false, true] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.yaml new file mode 100644 index 00000000000..9ca7186cd7e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.yaml @@ -0,0 +1,112 @@ +# ms_ccpp_income_eligible is SPMUnit, MONTH. +# Eligible when monthly countable income <= 0.85 * monthly hhs_smi. +# Federal hhs_smi (MS, 2024), annual / 85% annual: +# Family of 2: 51,204 / 43,523.40 +# Family of 3: 63,252 / 53,764.20 +# Family of 4: 75,300 / 64,005.00 + +- name: Case 1, family of 2 well below 85 percent SMI. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # 24,000 < 43,523.40 -> eligible + ms_ccpp_income_eligible: true + +- name: Case 2, family of 2 just below 85 percent SMI boundary. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 43_523.39 # 0.01 below 85% SMI to avoid float round-trip flip + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_income_eligible: true + +- name: Case 3, family of 2 just above 85 percent SMI boundary. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 43_523.41 # 0.01 above 85% SMI + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_income_eligible: false + +- name: Case 4, family of 4 below 85 percent SMI. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income: 60_000 + person2: + age: 33 + person3: + age: 4 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MS + output: + # 60,000 < 64,005 (85% SMI, family of 4) -> eligible + ms_ccpp_income_eligible: true + +- name: Case 5, family of 4 above 85 percent SMI. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income: 70_000 + person2: + age: 33 + person3: + age: 4 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MS + output: + # 70,000 > 64,005 -> ineligible + ms_ccpp_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/integration.yaml new file mode 100644 index 00000000000..9bde83ba6f1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/integration.yaml @@ -0,0 +1,273 @@ +# MS CCPP integration tests — full pipeline at YEAR period. +# ms_ccpp is MONTH; the YEAR aggregator ms_child_care_subsidies sums 12 months +# and feeds the federal child_care_subsidies (YEAR). +# Weekly rate -> monthly: x 52/12. Monthly benefit x 12 = annual. +# Monthly federal SMI / FPG (MS, 2024): +# Size 2: 85% SMI = 3,626.95; 50% SMI = 2,133.50; FPG = 1,703.33 +# Size 3: 85% SMI = 4,480.35; 50% SMI = 2,635.50; FPG = 2,151.67 +# Size 4: 85% SMI = 5,333.75; 50% SMI = 3,137.50; FPG = 2,600.00 + +- name: Case 1, single parent one preschooler metro center full time, full pipeline. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # 2,000/mo + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Rate center metro FT preschool 135/wk -> 585/mo; copay 2,000*5.5% = 110 + # Monthly benefit = 585 - 110 = 475; annual = 5,700 + ms_child_care_subsidies: 5_700 + child_care_subsidies: 5_700 + +- name: Case 2, two-parent family two children family home non-metro low band. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 48_000 # 4,000/mo + weekly_hours_worked_before_lsr: 40 + person2: + age: 33 + weekly_hours_worked_before_lsr: 40 + person3: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + person4: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + 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 # 1,500/mo + households: + household: + members: [person1, person2, person3, person4] + state_code: MS + county: BOLIVAR_COUNTY_MS + output: + ms_ccpp_income_eligible: true + ms_ccpp_eligible: true + # Rates home non-metro FT: toddler 98 + school-age 79 = 177/wk -> 767/mo + # Copay: 4,000/mo size 4 > 50% SMI 3,137.50 -> low 5.5% = 220 + # Monthly benefit = min(1,500, 767) - 220 = 547; annual = 6,564 + ms_ccpp: 6_564 + child_care_subsidies: 6_564 + +- name: Case 3, homeless family above income limit eligible via categorical bypass. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 48_000 # 4,000/mo, above 85% SMI for family of 2 + weekly_hours_worked_before_lsr: 0 # activity not met + is_full_time_student: false + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + is_homeless: true + output: + # Income and activity both fail; homeless categorical bypass -> eligible + ms_ccpp_income_eligible: false + ms_ccpp_categorically_eligible: true + ms_ccpp_eligible: true + # Has income (4,000) so not homeless-no-income -> scale copay applies + # Copay: 4,000/mo size 2 > 50% SMI 2,133.50 -> low 6.5% = 260 + # Rate center metro FT preschool 135/wk -> 585/mo + # Monthly benefit = min(1,000, 585) - 260 = 325; annual = 3,900 + ms_ccpp: 3_900 + child_care_subsidies: 3_900 + +- name: Case 4, special-needs child draws special-needs rate with $10 copay cap. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 24_000 # 2,000/mo + weekly_hours_worked_before_lsr: 40 + person2: + age: 8 + is_disabled: true + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Disabled child age 8 < 19 -> eligible; draws special-needs center FT = 145/wk + # 145 * 52/12 = 628.33/mo + # Special-needs child -> minimum-fee cap; 2,000 > FPG 1,703.33 -> copay $10 + # Monthly benefit = min(1,000, 628.33) - 10 = 618.33; annual = 7,420 + ms_ccpp: 7_420 + child_care_subsidies: 7_420 + +- name: Case 5, single parent two children part time metro center very-low band. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 28_800 # 2,400/mo + weekly_hours_worked_before_lsr: 40 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 # part time + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + person3: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 # part time + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 18_000 # 1,500/mo + households: + household: + members: [person1, person2, person3] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Rates PT center metro: infant 90 + preschool 75 = 165/wk -> 715/mo + # Copay: 2,400/mo size 3 <= 50% SMI 2,635.50 -> very-low 5.0% = 120 + # Monthly benefit = min(1,500, 715) - 120 = 595; annual = 7,140 + ms_ccpp: 7_140 + child_care_subsidies: 7_140 + +- name: Case 6, family above 85 percent SMI without categorical pathway is ineligible. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 48_000 # 4,000/mo > 85% SMI for family of 2 + weekly_hours_worked_before_lsr: 10 + is_full_time_student: false + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: 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: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_income_eligible: false + ms_ccpp_eligible: false + ms_ccpp: 0 + child_care_subsidies: 0 + +- name: Case 7, non-Mississippi household is excluded (defined_for gate). + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: 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: AL # not Mississippi + county: BALDWIN_COUNTY_AL + output: + # defined_for = StateCode.MS zeroes the eligibility gate and the benefit + ms_ccpp_eligible: false + ms_ccpp: 0 + ms_child_care_subsidies: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp.yaml new file mode 100644 index 00000000000..a3452b3aea1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp.yaml @@ -0,0 +1,192 @@ +# ms_ccpp is SPMUnit, MONTH. +# Benefit = max( min(monthly childcare expenses, sum of per-child weekly max +# rates x 52/12) - monthly family copay, 0 ). +# spm_unit_pre_subsidy_childcare_expenses is annual; read monthly it divides by 12. + +- name: Case 1, single parent one preschooler in metro center full time. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # 2,000/mo + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 # full time + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Rate: center metro FT preschool = 135/wk -> 135 * 52/12 = 585.00/mo + # Copay: 2,000/mo, size 2, <= 50% SMI 2,133.50 -> very-low 5.5% = 110 + # Benefit = max(min(1,000, 585) - 110, 0) = 585 - 110 = 475.00 + ms_ccpp: 475 + +- name: Case 2, provider charge below the maximum rate caps the subsidy at the charge. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # 2,000/mo + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 3_000 # 250/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Monthly rate 585 > monthly expenses 250 -> capped at 250 + # Copay = 110 (very-low band, size 2) + # Benefit = max(min(250, 585) - 110, 0) = 250 - 110 = 140.00 + ms_ccpp: 140 + +- name: Case 3, copay exceeds capped expenses so benefit floors at zero. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 48_000 # 4,000/mo + weekly_hours_worked_before_lsr: 40 + person2: + age: 33 + person3: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person4: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: 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: 1_200 # 100/mo + households: + household: + members: [person1, person2, person3, person4] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Rates: preschool 135 + school-age 130 = 265/wk -> 1,148.33/mo + # Copay: 4,000/mo, size 4, > 50% SMI 3,137.50 -> low band 5.5% = 220 + # Monthly expenses = 100 + # Benefit = max(min(100, 1,148.33) - 220, 0) = max(100 - 220, 0) = 0 + ms_ccpp: 0 + +- name: Case 4, negative countable income does not inflate the benefit. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + self_employment_income: -60_000 # -5,000/mo + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Income floored at 0 -> copay $0 (at/below FPL) + # Rate: center metro FT preschool = 135/wk -> 585/mo + # Benefit = max(min(1,000, 585) - 0, 0) = 585.00 (capped at rate, not inflated) + ms_ccpp: 585 + +# Edge case: two children in care aggregate per-child rates, with the single +# family copay subtracted once (not per child). See Cases 1-4 above. +- name: Case 5, two children aggregate distinct per-child rates with one copay. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 28_800 # 2,400/mo + weekly_hours_worked_before_lsr: 40 + person2: # infant + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person3: # preschool + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 24_000 # 2,000/mo + households: + household: + members: [person1, person2, person3] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Per-child rates: infant 152 + preschool 135 = 287/wk -> 287 * 52/12 = 1,243.67/mo + # Copay: 2,400/mo, size 3, > FPG 2,151.67 and <= 50% SMI 2,635.50 + # -> very-low band 5.0% = 120 (single family copay, subtracted once) + # Benefit = max(min(2,000, 1,243.67) - 120, 0) = 1,243.67 - 120 = 1,123.67 + ms_ccpp: 1_123.67 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.yaml new file mode 100644 index 00000000000..7b7bd2bf4d2 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.yaml @@ -0,0 +1,96 @@ +# ms_ccpp_age_group is a Person enum derived from age (years): +# INFANT age < 1 +# TODDLER 1 <= age < 3 +# PRESCHOOL 3 <= age < 5 +# SCHOOL_AGE age >= 5 + +- name: Case 1, infant under 1 year. + period: 2024-01 + input: + people: + person1: + age: 0 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_age_group: INFANT + +- name: Case 2, toddler at age 1 (lower boundary). + period: 2024-01 + input: + people: + person1: + age: 1 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_age_group: TODDLER + +- name: Case 3, toddler at age 2. + period: 2024-01 + input: + people: + person1: + age: 2 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_age_group: TODDLER + +- name: Case 4, preschool at age 3 (lower boundary). + period: 2024-01 + input: + people: + person1: + age: 3 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_age_group: PRESCHOOL + +- name: Case 5, preschool at age 4. + period: 2024-01 + input: + people: + person1: + age: 4 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_age_group: PRESCHOOL + +- name: Case 6, school age at age 5 (lower boundary). + period: 2024-01 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_age_group: SCHOOL_AGE + +- name: Case 7, school age at age 10. + period: 2024-01 + input: + people: + person1: + age: 10 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_age_group: SCHOOL_AGE diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.yaml new file mode 100644 index 00000000000..0ceebb57ced --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.yaml @@ -0,0 +1,72 @@ +# ms_ccpp_countable_income is SPMUnit, MONTH (adds the countable income sources +# positive list). Gross income, no deductions. SSI and Social Security both count +# (for parent and child); child support received and EITC are not countable. + +- name: Case 1, employment, Social Security, and SSI count; child support does not. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # YEAR -> 2,000/mo + social_security: 6_000 # YEAR -> 500/mo, counts + ssi: 400 # MONTH -> 400/mo, counts (separate from social_security) + child_support_received: 12_000 # YEAR, NOT countable + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # 2,000 + 500 + 400 = 2,900 (child support excluded) + ms_ccpp_countable_income: 2_900 + +- name: Case 2, negative self-employment income reduces countable income. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # YEAR -> 2,000/mo + self_employment_income: -6_000 # YEAR -> -500/mo (countable, can be negative) + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # 2,000 + (-500) = 1,500 + ms_ccpp_countable_income: 1_500 + +- name: Case 3, child's SSI and Social Security count toward family income. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 18_000 # YEAR -> 1,500/mo + person2: + age: 6 + ssi: 300 # MONTH, child SSI counts + social_security: 2_400 # YEAR -> 200/mo, child SSA counts + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # 1,500 + 300 + 200 = 2,000 + ms_ccpp_countable_income: 2_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.yaml new file mode 100644 index 00000000000..f62949c06dc --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.yaml @@ -0,0 +1,74 @@ +# ms_ccpp_facility_location is a Household enum derived from county_str. +# Households in one of the 17 Mississippi metropolitan counties (OMB Feb-2013 +# MSA delineation) are METRO; every other Mississippi county is NON_METRO. +# We use the household's county as a proxy for the child care facility location. + +- name: Case 1, Hinds County (Jackson MSA) is metro. + period: 2024-01 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_facility_location: METRO + +- name: Case 2, DeSoto County (Memphis MSA portion) is metro. + period: 2024-01 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: MS + county: DESOTO_COUNTY_MS + output: + ms_ccpp_facility_location: METRO + +- name: Case 3, Lauderdale County (Meridian, micropolitan) is non-metro. + period: 2024-01 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: MS + county: LAUDERDALE_COUNTY_MS + output: + ms_ccpp_facility_location: NON_METRO + +- name: Case 4, Bolivar County (rural) is non-metro. + period: 2024-01 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: MS + county: BOLIVAR_COUNTY_MS + output: + ms_ccpp_facility_location: NON_METRO + +- name: Case 5, George County (not in Feb-2013 Gulfport MSA) is non-metro. + period: 2024-01 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: MS + county: GEORGE_COUNTY_MS + output: + ms_ccpp_facility_location: NON_METRO diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.yaml new file mode 100644 index 00000000000..006db66da49 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.yaml @@ -0,0 +1,598 @@ +# ms_ccpp_maximum_weekly_rate is Person, MONTH. +# Per-child weekly max rate by provider type x age band x full/part time x +# metro/non-metro, with a flat all-ages special-needs rate set. Gated to 0 when +# the child is not actually in care (childcare_hours_per_week < 1) or is not an +# eligible child. childcare_hours_per_day drives full/part time (>=6 = FT); +# childcare_hours_per_week drives the in-care gate. +# Operative weekly grid (eff 2023-07-01): +# Center metro FT: Infant 152 Toddler 145 Preschool 135 School-age 130 +# Center metro PT: Infant 90 Toddler 90 Preschool 75 School-age 80 +# Center nonmetro FT: Infant 125 Toddler 120 Preschool 120 School-age 110 +# Center nonmetro PT: Infant 80 Toddler 75 Preschool 75 School-age 74 +# Home metro FT: Infant 115 Toddler 120 Preschool 120 School-age 95 +# Home metro PT: Infant 68 Toddler 75 Preschool 60 School-age 58 +# Home nonmetro FT: Infant 94 Toddler 98 Preschool 106 School-age 79 +# Home nonmetro PT: Infant 60 Toddler 61 Preschool 60 School-age 53 +# Special-needs center FT 145 / PT 87 (metro = non-metro) +# Special-needs home FT 125 / PT 63 (metro = non-metro) + +# === Center, metro (Hinds County), full time — all 4 age bands === +- name: Case 1, center metro full time, all age bands. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: # infant + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person3: # toddler + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person4: # preschool + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person5: # school age + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Parent: not an eligible child -> 0 + # Infant 152, Toddler 145, Preschool 135, School-age 130 + ms_ccpp_maximum_weekly_rate: [0, 152, 145, 135, 130] + +# === Center, metro, part time — all 4 age bands === +- name: Case 2, center metro part time, all age bands. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + person3: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + person5: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Infant 90, Toddler 90, Preschool 75, School-age 80 + ms_ccpp_maximum_weekly_rate: [0, 90, 90, 75, 80] + +# === Center, non-metro (Bolivar County), full time — all 4 age bands === +- name: Case 3, center non-metro full time, all age bands. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person3: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person5: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MS + county: BOLIVAR_COUNTY_MS + output: + # Infant 125, Toddler 120, Preschool 120, School-age 110 + ms_ccpp_maximum_weekly_rate: [0, 125, 120, 120, 110] + +# === Center, non-metro, part time — all 4 age bands === +- name: Case 4, center non-metro part time, all age bands. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + person3: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + person5: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MS + county: BOLIVAR_COUNTY_MS + output: + # Infant 80, Toddler 75, Preschool 75, School-age 74 + ms_ccpp_maximum_weekly_rate: [0, 80, 75, 75, 74] + +# === Family home, metro, full time — all 4 age bands === +- name: Case 5, family home metro full time, all age bands. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + person3: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + person5: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Infant 115, Toddler 120, Preschool 120, School-age 95 + ms_ccpp_maximum_weekly_rate: [0, 115, 120, 120, 95] + +# === Family home, metro, part time — all 4 age bands === +- name: Case 6, family home metro part time, all age bands. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: FAMILY_HOME + person3: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: FAMILY_HOME + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: FAMILY_HOME + person5: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: FAMILY_HOME + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Infant 68, Toddler 75, Preschool 60, School-age 58 + ms_ccpp_maximum_weekly_rate: [0, 68, 75, 60, 58] + +# === Family home, non-metro, full time — all 4 age bands === +- name: Case 7, family home non-metro full time, all age bands. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + person3: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + person5: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MS + county: BOLIVAR_COUNTY_MS + output: + # Infant 94, Toddler 98, Preschool 106, School-age 79 + ms_ccpp_maximum_weekly_rate: [0, 94, 98, 106, 79] + +# === Family home, non-metro, part time — all 4 age bands === +- name: Case 8, family home non-metro part time, all age bands. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: FAMILY_HOME + person3: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: FAMILY_HOME + person4: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: FAMILY_HOME + person5: + age: 8 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: FAMILY_HOME + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MS + county: BOLIVAR_COUNTY_MS + output: + # Infant 60, Toddler 61, Preschool 60, School-age 53 + ms_ccpp_maximum_weekly_rate: [0, 60, 61, 60, 53] + +# === Special needs — center and home, full and part time === +- name: Case 9, special-needs child center full time draws flat special-needs rate. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: # disabled school-age child -> special-needs center rate, not age-band rate + age: 8 + is_disabled: true + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Special-needs center FT = 145 (flat all-ages; overrides the school-age 130) + ms_ccpp_maximum_weekly_rate: [0, 145] + +- name: Case 10, special-needs child center part time. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 1 + is_disabled: true + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + county: BOLIVAR_COUNTY_MS + output: + # Special-needs center PT = 87 (metro = non-metro) + ms_ccpp_maximum_weekly_rate: [0, 87] + +- name: Case 11, special-needs (in-home) child draws home-based special-needs rate. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: # disabled child in family-home/in-home setting + age: 3 + is_disabled: true + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Special-needs home FT = 125 + ms_ccpp_maximum_weekly_rate: [0, 125] + +- name: Case 12, special-needs home part time. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 0 + is_disabled: true + is_tax_unit_dependent: true + childcare_hours_per_day: 4 + childcare_hours_per_week: 20 + ms_ccpp_provider_type: FAMILY_HOME + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + county: BOLIVAR_COUNTY_MS + output: + # Special-needs home PT = 63 + ms_ccpp_maximum_weekly_rate: [0, 63] + +# === In-care gate === +- name: Case 13, child not in care draws no rate. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 0 # not in care + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_maximum_weekly_rate: [0, 0] + +# === Age-group rate-band transitions (edge cases; see Cases 1-13 above) === +# The center metro full-time rate changes at each age-band boundary. Each case +# places two children straddling one boundary so the rate band on each side is +# verified directly. Boundaries: infant<1, toddler 1-<3, preschool 3-<5, +# school-age >=5 (whole-year cuts). +- name: Case 14, infant-to-toddler rate transition (age 0 vs 1), center metro full time. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: # infant (age 0) + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person3: # toddler (age 1, lower boundary) + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Infant FT 152 -> Toddler FT 145 at age 1 + ms_ccpp_maximum_weekly_rate: [0, 152, 145] + +- name: Case 15, toddler-to-preschool rate transition (age 2 vs 3), center metro full time. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: # toddler (age 2) + age: 2 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person3: # preschool (age 3, lower boundary) + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Toddler FT 145 -> Preschool FT 135 at age 3 + ms_ccpp_maximum_weekly_rate: [0, 145, 135] + +- name: Case 16, preschool-to-school-age rate transition (age 4 vs 5), center metro full time. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: # preschool (age 4) + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + person3: # school-age (age 5, lower boundary) + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Preschool FT 135 -> School-age FT 130 at age 5 + ms_ccpp_maximum_weekly_rate: [0, 135, 130] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.yaml new file mode 100644 index 00000000000..2ba674d35e6 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.yaml @@ -0,0 +1,75 @@ +# ms_ccpp_time_category is a Person enum derived from childcare_hours_per_day: +# FULL_TIME hours/day >= 6 +# PART_TIME hours/day < 6 + +- name: Case 1, full time at 6 hours per day (lower boundary). + period: 2024-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 6 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_time_category: FULL_TIME + +- name: Case 2, full time at 8 hours per day. + period: 2024-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 8 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_time_category: FULL_TIME + +- name: Case 3, part time at 5 hours per day. + period: 2024-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 5 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_time_category: PART_TIME + +- name: Case 4, part time at 3 hours per day. + period: 2024-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 3 + households: + household: + members: [person1] + state_code: MS + output: + ms_ccpp_time_category: PART_TIME + +# Edge case: just below the 6-hour full-time threshold (see Case 1 at exactly 6). +- name: Case 5, part time at 5.99 hours per day (just below full-time boundary). + period: 2024-01 + input: + people: + person1: + age: 3 + childcare_hours_per_day: 5.99 + households: + household: + members: [person1] + state_code: MS + output: + # 5.99 < 6 -> part time (full time begins at exactly 6 hours, see Case 1) + ms_ccpp_time_category: PART_TIME diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py new file mode 100644 index 00000000000..7c51968605c --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py @@ -0,0 +1,67 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_copay(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Mississippi CCPP monthly family co-payment" + definition_period = MONTH + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=39" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ms.dhs.ccpp.copay + p_income = parameters(period).gov.states.ms.dhs.ccpp.income + + # Floor income at zero so negative self-employment income cannot inflate + # or reduce the co-payment. + monthly_income = max_(spm_unit("ms_ccpp_countable_income", period), 0) + + # Family size is capped at the published "6 or more" row. + size = spm_unit("spm_unit_size", period.this_year) + fee_scale_size = min_(size, p.max_family_size) + + # Select the co-payment rate band by position relative to 50% SMI. + monthly_smi = spm_unit("hhs_smi", period.this_year) / MONTHS_IN_YEAR + very_low_income = ( + monthly_income <= monthly_smi * p_income.very_low_income_smi_rate + ) + copay_rate = where( + very_low_income, + p.rate.very_low_income.calc(fee_scale_size), + p.rate.low_income.calc(fee_scale_size), + ) + scale_copay = monthly_income * copay_rate + + # Families at or below the federal poverty line, TANF recipients, and + # homeless families with no countable income pay no co-payment. + monthly_fpg = spm_unit("spm_unit_fpg", period.this_year) / MONTHS_IN_YEAR + at_or_below_fpl = monthly_income <= monthly_fpg * p.fpg_exempt_rate + is_tanf = spm_unit("is_tanf_enrolled", period) + is_homeless = spm_unit.household("is_homeless", period.this_year) + homeless_no_income = is_homeless & (monthly_income == 0) + zero_copay = at_or_below_fpl | is_tanf | homeless_no_income + + # Minimum-fee categories (income above the poverty line) cap the + # co-payment at $10/month. Of the manual's categories, only protective + # services, SSI-disabled parents, and special-needs children can be + # tracked at the moment. + person = spm_unit.members + has_protective_child = spm_unit.any( + person("receives_or_needs_protective_services", period.this_year) + ) + is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) + is_ssi_disabled = person("is_ssi_disabled", period.this_year) + has_ssi_disabled_parent = spm_unit.any(is_head_or_spouse & is_ssi_disabled) + has_special_needs_child = spm_unit.any(person("is_disabled", period.this_year)) + in_min_fee_category = ( + has_protective_child | has_ssi_disabled_parent | has_special_needs_child + ) + capped_copay = where( + in_min_fee_category, + min_(scale_copay, p.minimum_fee_categories_cap), + scale_copay, + ) + + return where(zero_copay, 0, capped_copay) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py new file mode 100644 index 00000000000..94f1617af63 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_activity_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Mississippi CCPP based on activity requirements" + definition_period = MONTH + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=24" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ms.dhs.ccpp.eligibility + person = spm_unit.members + is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) + # Use the pre-labor-supply-response hours to avoid a circular dependency + # with the labor supply response cycle. + hours_worked = person("weekly_hours_worked_before_lsr", period.this_year) + meets_work_requirement = hours_worked >= p.activity_hours + # Full-time school or approved training also satisfies the requirement. + is_student = person("is_full_time_student", period.this_year) + # The activity requirement is waived for an SSI-disabled parent. + is_ssi_disabled = person("is_ssi_disabled", period.this_year) + individually_eligible = meets_work_requirement | is_student | is_ssi_disabled + # Require at least one head/spouse so a unit of only dependents does not + # vacuously pass, and require every head/spouse to be individually + # eligible. + has_head_or_spouse = spm_unit.sum(is_head_or_spouse) >= 1 + all_covered = spm_unit.sum(is_head_or_spouse & ~individually_eligible) == 0 + return has_head_or_spouse & all_covered diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py new file mode 100644 index 00000000000..8fdb6713441 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_categorically_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Categorically eligible for Mississippi CCPP" + definition_period = MONTH + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=16" + + def formula(spm_unit, period, parameters): + # Categorical pathways bypass the income test. We model TANF + # recipients, homeless children, and children in protective services. + # Transitional Child Care, Healthy Families Mississippi, and teen-parent + # pathways are not tracked at the moment. + is_tanf = spm_unit("is_tanf_enrolled", period) + is_homeless = spm_unit.household("is_homeless", period.this_year) + has_protective_child = ( + add( + spm_unit, + period.this_year, + ["receives_or_needs_protective_services"], + ) + > 0 + ) + return is_tanf | is_homeless | has_protective_child diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py new file mode 100644 index 00000000000..56dd997c940 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py @@ -0,0 +1,33 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Mississippi CCPP" + definition_period = MONTH + defined_for = StateCode.MS + reference = ( + "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=16", + "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23", + ) + + def formula(spm_unit, period, parameters): + has_eligible_child = add(spm_unit, period, ["ms_ccpp_eligible_child"]) > 0 + asset_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) + income_eligible = spm_unit("ms_ccpp_income_eligible", period) + activity_eligible = spm_unit("ms_ccpp_activity_eligible", period) + + # Standard low-income pathway: eligible child, assets, income, and a + # qualifying parent activity. + standard = ( + has_eligible_child & asset_eligible & income_eligible & activity_eligible + ) + + # Categorical pathways (TANF, homeless, protective services) bypass the + # income and activity tests; the eligible child and asset tests still + # apply. + categorical = spm_unit("ms_ccpp_categorically_eligible", period) + categorical_path = has_eligible_child & asset_eligible & categorical + + return standard | categorical_path diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py new file mode 100644 index 00000000000..2e769ed54f8 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_eligible_child(Variable): + value_type = bool + entity = Person + label = "Eligible child for Mississippi CCPP" + definition_period = MONTH + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23" + + def formula(person, period, parameters): + p = parameters(period).gov.states.ms.dhs.ccpp.eligibility + age = person("age", period.this_year) + is_special_needs = person("is_disabled", period.this_year) + # Children must be under 13, or under 19 if they have special needs. + age_eligible = where( + is_special_needs, + age < p.special_needs_child_age_limit, + age < p.child_age_limit, + ) + # Children must be citizens or qualified non-citizens (no parent bar). + immigration_eligible = person( + "is_ccdf_immigration_eligible_child", period.this_year + ) + return age_eligible & immigration_eligible diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py new file mode 100644 index 00000000000..b3699195a89 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Mississippi CCPP based on income" + definition_period = MONTH + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ms.dhs.ccpp.income + countable_income = spm_unit("ms_ccpp_countable_income", period) + # hhs_smi is annual; compare against the monthly countable income. + monthly_smi = spm_unit("hhs_smi", period.this_year) / MONTHS_IN_YEAR + return countable_income <= monthly_smi * p.smi_rate diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py new file mode 100644 index 00000000000..e74b88072eb --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class ms_ccpp(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Mississippi CCPP benefit amount" + definition_period = MONTH + defined_for = "ms_ccpp_eligible" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=56" + + def formula(spm_unit, period, parameters): + copay = spm_unit("ms_ccpp_copay", period) + # Sum the per-child weekly maximum rates and convert to monthly. + weekly_rate = add(spm_unit, period, ["ms_ccpp_maximum_weekly_rate"]) + monthly_rate = weekly_rate * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) + # The subsidy covers the lesser of the provider's charge and the + # maximum rate, net of the family co-payment. + pre_subsidy_childcare_expenses = spm_unit( + "spm_unit_pre_subsidy_childcare_expenses", period + ) + capped_expenses = min_(pre_subsidy_childcare_expenses, monthly_rate) + return max_(capped_expenses - copay, 0) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.py new file mode 100644 index 00000000000..ada92e4f1be --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class MSCCPPAgeGroup(Enum): + INFANT = "Infant" + TODDLER = "Toddler" + PRESCHOOL = "Preschool" + SCHOOL_AGE = "School age" + + +class ms_ccpp_age_group(Variable): + value_type = Enum + entity = Person + possible_values = MSCCPPAgeGroup + default_value = MSCCPPAgeGroup.SCHOOL_AGE + definition_period = MONTH + label = "Mississippi CCPP child age group for payment rates" + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=14" + + def formula(person, period, parameters): + age = person("age", period.this_year) + p = parameters(period).gov.states.ms.dhs.ccpp.age_group + # The bracket returns 0=INFANT, 1=TODDLER, 2=PRESCHOOL, 3=SCHOOL_AGE, + # which PolicyEngine maps to the enum index. + return p.age.calc(age) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py new file mode 100644 index 00000000000..dc8939e26a0 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Mississippi CCPP countable income" + definition_period = MONTH + unit = USD + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=24" + + adds = "gov.states.ms.dhs.ccpp.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.py new file mode 100644 index 00000000000..f4ea1f37d31 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + + +class MSCCPPFacilityLocation(Enum): + METRO = "Metro" + NON_METRO = "Non-metro" + + +class ms_ccpp_facility_location(Variable): + value_type = Enum + entity = Household + possible_values = MSCCPPFacilityLocation + default_value = MSCCPPFacilityLocation.NON_METRO + definition_period = YEAR + label = "Mississippi CCPP facility metro or non-metro location" + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=56" + + def formula(household, period, parameters): + # CCPP rates vary by the facility's metro / non-metro location. We don't + # track the child care facility's location at the moment, so we use the + # household's county as a proxy for the facility location. + county = household("county_str", period) + p = parameters(period).gov.states.ms.dhs.ccpp.geography + is_metro = np.isin(county, p.metro_counties) + return where( + is_metro, + MSCCPPFacilityLocation.METRO, + MSCCPPFacilityLocation.NON_METRO, + ) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.py new file mode 100644 index 00000000000..da9bf7e9ad2 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.py @@ -0,0 +1,46 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.ms.dhs.ccpp.ms_ccpp_provider_type import ( + MSCCPPProviderType, +) + + +class ms_ccpp_maximum_weekly_rate(Variable): + value_type = float + entity = Person + unit = USD + label = "Mississippi CCPP maximum weekly rate per child" + definition_period = MONTH + defined_for = "ms_ccpp_eligible_child" + reference = ( + "https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=9", + "https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=10", + ) + + def formula(person, period, parameters): + rates = parameters(period).gov.states.ms.dhs.ccpp.rates + provider_type = person("ms_ccpp_provider_type", period) + time_category = person("ms_ccpp_time_category", period) + age_group = person("ms_ccpp_age_group", period) + location = person.household("ms_ccpp_facility_location", period.this_year) + + is_center = provider_type == MSCCPPProviderType.CENTER + + # Standard rates by location, age band, and time category. + center_rate = rates.center[location][age_group][time_category] + family_home_rate = rates.family_home[location][age_group][time_category] + standard_rate = where(is_center, center_rate, family_home_rate) + + # Special-needs (and in-home) children draw the flat all-ages + # special-needs rate set; in-home care is paid the home-based rate. + special_needs_center_rate = rates.special_needs_center[location][time_category] + special_needs_home_rate = rates.special_needs_home[location][time_category] + special_needs_rate = where( + is_center, special_needs_center_rate, special_needs_home_rate + ) + + is_special_needs = person("is_disabled", period.this_year) + rate = where(is_special_needs, special_needs_rate, standard_rate) + + # A child not actually in care draws no rate. + in_care = person("childcare_hours_per_week", period.this_year) > 0 + return where(in_care, rate, 0) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py new file mode 100644 index 00000000000..24f657de79b --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class MSCCPPProviderType(Enum): + CENTER = "Licensed child care center" + FAMILY_HOME = "Registered family child care home" + + +class ms_ccpp_provider_type(Variable): + value_type = Enum + entity = Person + possible_values = MSCCPPProviderType + default_value = MSCCPPProviderType.CENTER + definition_period = MONTH + label = "Mississippi CCPP child care provider type" + defined_for = StateCode.MS + # In-home care is special-needs-only and is paid the home-based special-needs + # rate, so there is no separate in-home provider type; route in-home and + # special-needs children through FAMILY_HOME (or CENTER) and the special-needs + # rate set. + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=56" diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py new file mode 100644 index 00000000000..8288689d002 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class MSCCPPTimeCategory(Enum): + PART_TIME = "Part time" + FULL_TIME = "Full time" + + +class ms_ccpp_time_category(Variable): + value_type = Enum + entity = Person + possible_values = MSCCPPTimeCategory + default_value = MSCCPPTimeCategory.FULL_TIME + definition_period = MONTH + label = "Mississippi CCPP care time category" + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=14" + + def formula(person, period, parameters): + hours_per_day = person("childcare_hours_per_day", period.this_year) + p = parameters(period).gov.states.ms.dhs.ccpp.time_category + # Part-time = care for fewer than 6 hours of a 24-hour day; full-time is + # 6 or more hours. The bracket returns 0=PART_TIME, 1=FULL_TIME, which + # PolicyEngine maps to the enum index. + return p.hours.calc(hours_per_day) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py new file mode 100644 index 00000000000..8cda6459bd9 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class ms_child_care_subsidies(Variable): + value_type = float + entity = SPMUnit + label = "Mississippi child care subsidies" + unit = USD + definition_period = YEAR + defined_for = StateCode.MS + adds = ["ms_ccpp"] From b388d223b8623dc64ed8f2df6fd05bae9b6a3b31 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Jun 2026 12:42:21 -0400 Subject: [PATCH 3/9] Add changelog fragment for Mississippi CCPP Co-Authored-By: Claude Opus 4.8 (1M context) --- changelog.d/ms-ccap.added.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/ms-ccap.added.md b/changelog.d/ms-ccap.added.md index 87b9b43ca48..1f1714ea2c6 100644 --- a/changelog.d/ms-ccap.added.md +++ b/changelog.d/ms-ccap.added.md @@ -1 +1 @@ -Initialize Mississippi Child Care Payment Program (CCPP/CCAP) implementation. +Add Mississippi Child Care Payment Program (CCPP). From 279a1ad785c429c954d84ef3018ef126848e6ee7 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Jun 2026 13:13:16 -0400 Subject: [PATCH 4/9] Review-fix round 1: correct CCPP Policy Manual citations and enrich references Co-Authored-By: Claude Opus 4.8 (1M context) --- .../gov/states/ms/dhs/ccpp/age_group/age.yaml | 4 +-- .../ms/dhs/ccpp/copay/fpg_exempt_rate.yaml | 4 +-- .../copay/minimum_fee_categories_cap.yaml | 4 +-- .../ms/dhs/ccpp/copay/rate/low_income.yaml | 2 ++ .../dhs/ccpp/copay/rate/very_low_income.yaml | 7 ++++- .../dhs/ccpp/eligibility/activity_hours.yaml | 4 +-- .../dhs/ccpp/eligibility/child_age_limit.yaml | 4 +-- .../special_needs_child_age_limit.yaml | 4 +-- .../ccpp/income/countable_income/sources.yaml | 9 +++--- .../states/ms/dhs/ccpp/income/smi_rate.yaml | 4 +-- .../ccpp/income/very_low_income_smi_rate.yaml | 2 ++ .../ms/dhs/ccpp/time_category/hours.yaml | 4 +-- .../ms/dhs/ccpp/copay/ms_ccpp_copay.yaml | 21 ++++++++++++++ .../ms_ccpp_activity_eligible.yaml | 25 ++++++++++++++++ .../ccpp/eligibility/ms_ccpp_eligible.yaml | 29 +++++++++++++++++++ .../states/ms/dhs/ccpp/copay/ms_ccpp_copay.py | 11 +++++-- .../eligibility/ms_ccpp_activity_eligible.py | 2 +- .../ms_ccpp_categorically_eligible.py | 5 +++- .../dhs/ccpp/eligibility/ms_ccpp_eligible.py | 4 +-- .../eligibility/ms_ccpp_eligible_child.py | 2 +- .../eligibility/ms_ccpp_income_eligible.py | 6 ++-- .../gov/states/ms/dhs/ccpp/ms_ccpp.py | 2 +- .../states/ms/dhs/ccpp/ms_ccpp_age_group.py | 2 +- .../ms/dhs/ccpp/ms_ccpp_countable_income.py | 2 +- .../ms/dhs/ccpp/ms_ccpp_facility_location.py | 4 ++- .../dhs/ccpp/ms_ccpp_maximum_weekly_rate.py | 7 ++--- .../ms/dhs/ccpp/ms_ccpp_provider_type.py | 2 +- .../ms/dhs/ccpp/ms_ccpp_time_category.py | 2 +- .../ms/dhs/ccpp/ms_child_care_subsidies.py | 1 + 29 files changed, 136 insertions(+), 43 deletions(-) diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml index 2c58f159940..30d4976131a 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml @@ -13,8 +13,8 @@ metadata: period: year label: Mississippi CCPP child age group by age reference: - - title: Mississippi CCPP Policy Manual, Definitions (Infant, Toddler, Preschool, School Age) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=14 + - title: Mississippi CCPP Policy Manual, Definitions (Infant #49 p.13, Toddler #87 p.17, Preschool #66 p.15, School Age #74 p.16) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=13 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml index e5ce4029431..f9d39fc1b35 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml @@ -9,5 +9,5 @@ metadata: period: year label: Mississippi CCPP co-payment poverty line exemption rate reference: - - title: Mississippi CCPP Policy Manual, Rule 6.2 (Co-payment Fees) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=39 + - title: Mississippi CCPP Policy Manual, Rule 6.2 (Co-Payment Fee) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=41 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/minimum_fee_categories_cap.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/minimum_fee_categories_cap.yaml index 1de32557494..4e499f32173 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/minimum_fee_categories_cap.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/minimum_fee_categories_cap.yaml @@ -12,5 +12,5 @@ metadata: period: month label: Mississippi CCPP minimum-fee co-payment cap reference: - - title: Mississippi CCPP Policy Manual, Rule 6.2 (Co-payment Fees) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=39 + - title: Mississippi CCPP Policy Manual, Rule 6.2 (Co-Payment Fee) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=41 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/low_income.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/low_income.yaml index 25681e58e7c..1402ee13a5a 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/low_income.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/low_income.yaml @@ -8,6 +8,8 @@ metadata: period: year label: Mississippi CCPP co-payment rate above 50% SMI reference: + - title: Mississippi CCDF State Plan FFY 2025-2027, Section 3.1 Family Co-payments (pp. 39-40) + href: https://www.mdhs.ms.gov/wp-content/uploads/2025/01/ACF-118-CCDF-FFY-2025-2027-For-Mississippi.pdf#page=39 - title: Mississippi CCPP Family Co-Payment Fee Scale (effective November 1, 2021) href: https://www.mdhs.ms.gov/wp-content/uploads/2021/11/Copay-Table-Update-11_01_21.pdf diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml index 29310141ee6..d77613bd0a1 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml @@ -1,6 +1,9 @@ description: Mississippi sets the co-payment as this share of gross income for families at or below 50% of state median income under the Child Care Payment Program. # Co-payment percentage by family size for the "up to 50% SMI" band. Family size -# is capped at 6 (the published table's "6 or more" row) before lookup. +# is capped at 6 (the published table's "6 or more" row) before lookup. These +# values are derived from the State Plan's 5.5% cap for the up-to-50%-SMI band +# (-0.5 percentage point per family size: 5.5/5/4.5/4/3.5%), not transcribed +# from a published per-size table. metadata: type: single_amount threshold_unit: person @@ -8,6 +11,8 @@ metadata: period: year label: Mississippi CCPP co-payment rate at or below 50% SMI reference: + - title: Mississippi CCDF State Plan FFY 2025-2027, Section 3.1 Family Co-payments (pp. 39-40) + href: https://www.mdhs.ms.gov/wp-content/uploads/2025/01/ACF-118-CCDF-FFY-2025-2027-For-Mississippi.pdf#page=39 - title: Mississippi CCPP Family Co-Payment Fee Scale (effective November 1, 2021) href: https://www.mdhs.ms.gov/wp-content/uploads/2021/11/Copay-Table-Update-11_01_21.pdf diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/activity_hours.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/activity_hours.yaml index 54f773a5704..ff3ec50a23c 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/activity_hours.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/activity_hours.yaml @@ -9,5 +9,5 @@ metadata: period: week label: Mississippi CCPP minimum weekly activity hours reference: - - title: Mississippi CCPP Policy Manual, Rule 5.9 (Activity Requirement) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=24 + - title: Mississippi CCPP Policy Manual, Rule 5.5 (Proof of Work/Education or Training) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=30 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml index 841f8484ab0..c09be12815d 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml @@ -7,5 +7,5 @@ metadata: period: year label: Mississippi CCPP child age limit reference: - - title: Mississippi CCPP Policy Manual, Rule 5.2 (Eligibility) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23 + - title: Mississippi CCPP Policy Manual, Rule 5.1 (Eligibility Requirements) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml index c61acc90bbc..6c805859f21 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml @@ -7,5 +7,5 @@ metadata: period: year label: Mississippi CCPP special-needs child age limit reference: - - title: Mississippi CCPP Policy Manual, Rule 5.2 (Eligibility) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23 + - title: Mississippi CCPP Policy Manual, Rule 5.1 (Eligibility Requirements) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml index c31d5e0b9a0..062e6227ef6 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml @@ -13,11 +13,10 @@ values: - veterans_benefits - pension_income # retirement and pension - rental_income - - dividend_income - - interest_income + - dividend_income # dividends (regular and ongoing); interest is not on the manual's list - capital_gains # Countable items in the manual with no matching variable at the moment: - # military allotments, lump sums. + # military allotments, lump sums, short-term disability payments. # Tips, commissions, and bonuses are captured by employment_income. metadata: @@ -25,5 +24,5 @@ metadata: period: year label: Mississippi CCPP countable income sources reference: - - title: Mississippi CCPP Policy Manual, Rule 5.9 (Income) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=24 + - title: Mississippi CCPP Policy Manual, Rule 5.4 (How Income is Calculated — Countable Income) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=29 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml index 255532bed4d..e34b2fd767a 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml @@ -7,5 +7,5 @@ metadata: period: year label: Mississippi CCPP SMI income limit rate reference: - - title: Mississippi CCPP Policy Manual, Rule 5.2 (Eligibility) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23 + - title: Mississippi CCPP Policy Manual, Rule 5.1 (Eligibility Requirements) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/very_low_income_smi_rate.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/very_low_income_smi_rate.yaml index 2dd42695df2..9087bdedb10 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/very_low_income_smi_rate.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/very_low_income_smi_rate.yaml @@ -9,5 +9,7 @@ metadata: period: year label: Mississippi CCPP very low income SMI rate reference: + - title: Mississippi CCDF State Plan FFY 2025-2027, Section 3.1 Family Co-payments (pp. 39-40) + href: https://www.mdhs.ms.gov/wp-content/uploads/2025/01/ACF-118-CCDF-FFY-2025-2027-For-Mississippi.pdf#page=39 - title: Mississippi CCPP Family Co-Payment Fee Scale (effective November 1, 2021) href: https://www.mdhs.ms.gov/wp-content/uploads/2021/11/Copay-Table-Update-11_01_21.pdf diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml index 06c43a78c5e..c115e41eb6c 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml @@ -11,8 +11,8 @@ metadata: period: year label: Mississippi CCPP time category by daily hours reference: - - title: Mississippi CCPP Policy Manual, Definitions (Full-Time, Part-Time) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=14 + - title: Mississippi CCPP Policy Manual, Definitions (Full-Time #44 p.13, Part-Time #65 p.15) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=13 brackets: - threshold: diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml index e25236a44a5..9eb7ef7cc4a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml @@ -339,3 +339,24 @@ # the size-6 row rate 4.5% # Copay = 5,000 * 0.045 = 225.00 ms_ccpp_copay: 225.00 + +- name: Case 14, homeless family with no countable income pays zero copay. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + is_homeless: true + output: + # is_homeless and zero countable income -> homeless_no_income branch -> $0 + ms_ccpp_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.yaml index 105d2d540fd..20f91d2f64b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.yaml @@ -169,3 +169,28 @@ state_code: MS output: ms_ccpp_activity_eligible: true + +- name: Case 8, assistance unit of only dependents has no head or spouse. + period: 2024-01 + input: + people: + person1: + age: 16 + is_tax_unit_dependent: true + person2: + age: 10 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # No head/spouse in the unit -> has_head_or_spouse is false, so the unit + # does not vacuously pass the activity requirement. + ms_ccpp_activity_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.yaml index 995fb31d79b..7e682b04a7d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.yaml @@ -137,3 +137,32 @@ # defined_for = StateCode.MS zeroes the gate and the benefit for non-MS ms_ccpp_eligible: false ms_ccpp: 0 + +- name: Case 6, otherwise-eligible family over the asset limit is not eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_100_000 # above the $1,000,000 CCDF asset limit + households: + household: + members: [person1, person2] + state_code: MS + output: + # Income and activity both pass, but the asset gate fails the AND, so + # neither the standard nor the categorical path is eligible. + ms_ccpp_income_eligible: true + ms_ccpp_activity_eligible: true + ms_ccpp_eligible: false diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py index 7c51968605c..ada67313fb8 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py @@ -8,9 +8,14 @@ class ms_ccpp_copay(Variable): label = "Mississippi CCPP monthly family co-payment" definition_period = MONTH defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=39" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=41" def formula(spm_unit, period, parameters): + # The published Copay Fee Scale snaps income up to the next $1,000 band + # before applying the rate and ties the band split to those $1,000 rows. + # We apply the percentage to exact monthly countable income and split the + # band at exactly 50% SMI, so results will not match the published + # per-row dollar cells to the cent. p = parameters(period).gov.states.ms.dhs.ccpp.copay p_income = parameters(period).gov.states.ms.dhs.ccpp.income @@ -23,7 +28,7 @@ def formula(spm_unit, period, parameters): fee_scale_size = min_(size, p.max_family_size) # Select the co-payment rate band by position relative to 50% SMI. - monthly_smi = spm_unit("hhs_smi", period.this_year) / MONTHS_IN_YEAR + monthly_smi = spm_unit("hhs_smi", period) very_low_income = ( monthly_income <= monthly_smi * p_income.very_low_income_smi_rate ) @@ -36,7 +41,7 @@ def formula(spm_unit, period, parameters): # Families at or below the federal poverty line, TANF recipients, and # homeless families with no countable income pay no co-payment. - monthly_fpg = spm_unit("spm_unit_fpg", period.this_year) / MONTHS_IN_YEAR + monthly_fpg = spm_unit("spm_unit_fpg", period) at_or_below_fpl = monthly_income <= monthly_fpg * p.fpg_exempt_rate is_tanf = spm_unit("is_tanf_enrolled", period) is_homeless = spm_unit.household("is_homeless", period.this_year) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py index 94f1617af63..4831841b429 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py @@ -7,7 +7,7 @@ class ms_ccpp_activity_eligible(Variable): label = "Eligible for Mississippi CCPP based on activity requirements" definition_period = MONTH defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=24" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=30" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.ms.dhs.ccpp.eligibility diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py index 8fdb6713441..99e38b1d993 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py @@ -7,7 +7,10 @@ class ms_ccpp_categorically_eligible(Variable): label = "Categorically eligible for Mississippi CCPP" definition_period = MONTH defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=16" + reference = ( + "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=19", + "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26", + ) def formula(spm_unit, period, parameters): # Categorical pathways bypass the income test. We model TANF diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py index 56dd997c940..3b066df7694 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py @@ -8,8 +8,8 @@ class ms_ccpp_eligible(Variable): definition_period = MONTH defined_for = StateCode.MS reference = ( - "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=16", - "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23", + "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26", + "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=19", ) def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py index 2e769ed54f8..9e17cc7636d 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py @@ -7,7 +7,7 @@ class ms_ccpp_eligible_child(Variable): label = "Eligible child for Mississippi CCPP" definition_period = MONTH defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26" def formula(person, period, parameters): p = parameters(period).gov.states.ms.dhs.ccpp.eligibility diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py index b3699195a89..5b16c676412 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py @@ -7,11 +7,11 @@ class ms_ccpp_income_eligible(Variable): label = "Eligible for Mississippi CCPP based on income" definition_period = MONTH defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=23" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.ms.dhs.ccpp.income countable_income = spm_unit("ms_ccpp_countable_income", period) - # hhs_smi is annual; compare against the monthly countable income. - monthly_smi = spm_unit("hhs_smi", period.this_year) / MONTHS_IN_YEAR + # hhs_smi is annual; reading it with the monthly period auto-converts. + monthly_smi = spm_unit("hhs_smi", period) return countable_income <= monthly_smi * p.smi_rate diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py index e74b88072eb..dad3342789a 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py @@ -8,7 +8,7 @@ class ms_ccpp(Variable): label = "Mississippi CCPP benefit amount" definition_period = MONTH defined_for = "ms_ccpp_eligible" - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=56" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=45" def formula(spm_unit, period, parameters): copay = spm_unit("ms_ccpp_copay", period) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.py index ada92e4f1be..2268a31bae9 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_age_group.py @@ -16,7 +16,7 @@ class ms_ccpp_age_group(Variable): definition_period = MONTH label = "Mississippi CCPP child age group for payment rates" defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=14" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=13" def formula(person, period, parameters): age = person("age", period.this_year) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py index dc8939e26a0..9fbcaa79ac8 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py @@ -8,6 +8,6 @@ class ms_ccpp_countable_income(Variable): definition_period = MONTH unit = USD defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=24" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=29" adds = "gov.states.ms.dhs.ccpp.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.py index f4ea1f37d31..d5096262022 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_facility_location.py @@ -14,7 +14,9 @@ class ms_ccpp_facility_location(Variable): definition_period = YEAR label = "Mississippi CCPP facility metro or non-metro location" defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=56" + # The metro / non-metro split is a Market Rate Survey rate-table dimension + # (Table 1 and Table 2 disaggregate rates by metro status), not a manual rule. + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=9" def formula(household, period, parameters): # CCPP rates vary by the facility's metro / non-metro location. We don't diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.py index da9bf7e9ad2..3eb01f91624 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_maximum_weekly_rate.py @@ -11,10 +11,9 @@ class ms_ccpp_maximum_weekly_rate(Variable): label = "Mississippi CCPP maximum weekly rate per child" definition_period = MONTH defined_for = "ms_ccpp_eligible_child" - reference = ( - "https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=9", - "https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=10", - ) + # 2024 Market Rate Survey, Table 1 (licensed center, p.9) and Table 2 + # (registered family home, p.10); operative "Current CCPP Rates" pp.9-10. + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=9" def formula(person, period, parameters): rates = parameters(period).gov.states.ms.dhs.ccpp.rates diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py index 24f657de79b..facc6774ad6 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py @@ -18,4 +18,4 @@ class ms_ccpp_provider_type(Variable): # rate, so there is no separate in-home provider type; route in-home and # special-needs children through FAMILY_HOME (or CENTER) and the special-needs # rate set. - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=56" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=45" diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py index 8288689d002..4dc63631aba 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py @@ -14,7 +14,7 @@ class ms_ccpp_time_category(Variable): definition_period = MONTH label = "Mississippi CCPP care time category" defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=14" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=13" def formula(person, period, parameters): hours_per_day = person("childcare_hours_per_day", period.this_year) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py index 8cda6459bd9..628ba9d7387 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py @@ -8,4 +8,5 @@ class ms_child_care_subsidies(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=45" adds = ["ms_ccpp"] From 67a66334042d430aca8fa259aa0229e63cdfdfb9 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Jun 2026 13:21:38 -0400 Subject: [PATCH 5/9] Review-fix round 2: collapse duplicate manual citations (one-link-per-document) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py | 5 +---- .../gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py index 99e38b1d993..68c3af43c20 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py @@ -7,10 +7,7 @@ class ms_ccpp_categorically_eligible(Variable): label = "Categorically eligible for Mississippi CCPP" definition_period = MONTH defined_for = StateCode.MS - reference = ( - "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=19", - "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26", - ) + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=19" def formula(spm_unit, period, parameters): # Categorical pathways bypass the income test. We model TANF diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py index 3b066df7694..8c079426462 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py @@ -7,10 +7,7 @@ class ms_ccpp_eligible(Variable): label = "Eligible for Mississippi CCPP" definition_period = MONTH defined_for = StateCode.MS - reference = ( - "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26", - "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=19", - ) + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26" def formula(spm_unit, period, parameters): has_eligible_child = add(spm_unit, period, ["ms_ccpp_eligible_child"]) > 0 From da96c1094bbd925d5c4a4c86fd486e4a482daea4 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Jun 2026 16:06:47 -0400 Subject: [PATCH 6/9] Add FY2025-2027 adopted full-time rates (eff 2024-10-01) alongside July-2023 schedule Center and family-home full-time rates now carry a second effective-dated entry from the FY2025-2027 CCDF State Plan (most-populous region = metro, lowest region = non-metro). Part-time and special-needs retain the prior-era values (the State Plan publishes full-time base rates only). Integration tests split into era-1 (2024-01) and era-2 (2025-01) cases. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../gov/states/ms/dhs/ccpp/rates/center.yaml | 26 ++- .../states/ms/dhs/ccpp/rates/family_home.yaml | 26 ++- .../dhs/ccpp/rates/special_needs_center.yaml | 3 + .../ms/dhs/ccpp/rates/special_needs_home.yaml | 3 + .../gov/states/ms/dhs/ccpp/integration.yaml | 208 ++++++++++++++++-- 5 files changed, 243 insertions(+), 23 deletions(-) diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/center.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/center.yaml index 6aba708c1fc..4984c5e0adf 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/center.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/center.yaml @@ -1,8 +1,16 @@ description: Mississippi provides these maximum weekly payment rates for licensed child care centers under the Child Care Payment Program. -# Operative "Current CCPP Rates" schedule effective July 2023 (2024 Market Rate -# Survey Table 1, p.9). Rates vary by the facility's location (metro / non-metro); -# we use the household's county as a proxy for facility location. Special-needs -# children are paid the flat all-ages special-needs rate (see special_needs_center). +# Two rate eras, keyed by the facility's location (metro / non-metro); we use the +# household's county as a proxy for facility location. +# - 2023-07-01 = July-2023 "Current CCPP Rates" (2024 Market Rate Survey Table 1, p.9). +# - 2024-10-01 = FY2025-2027 State Plan adopted full-time base rates. The State Plan +# reports rates by "most populous region" (encoded in the METRO slot) and "lowest +# region" (NON_METRO slot); the most-populous figure equals the statewide 75th +# percentile. +# The FY2025-2027 State Plan publishes FULL-TIME base rates only; the adopted part-time +# rates for that era are not publicly available (only the family copay fee scale is +# published), so the part-time leaves below retain their 2023-07 values — a documented +# limitation we don't track at the moment. Special-needs children are paid the flat +# all-ages special-needs rate (see special_needs_center). metadata: period: week unit: currency-USD @@ -14,25 +22,31 @@ metadata: reference: - title: 2024 Mississippi Child Care Market Rate Survey, Table 1 (Current CCPP Rates, Licensed Centers) href: https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=9 + - title: Mississippi FFY 2025-2027 CCDF State Plan, §4.3.2 (adopted full-time base rates, most-populous region pp.59-60); effective date §4.3.1(b) p.57 + href: https://www.mdhs.ms.gov/wp-content/uploads/2025/01/ACF-118-CCDF-FFY-2025-2027-For-Mississippi.pdf#page=59 METRO: INFANT: FULL_TIME: 2023-07-01: 152 + 2024-10-01: 167 PART_TIME: 2023-07-01: 90 TODDLER: FULL_TIME: 2023-07-01: 145 + 2024-10-01: 160 PART_TIME: 2023-07-01: 90 PRESCHOOL: FULL_TIME: 2023-07-01: 135 + 2024-10-01: 150 PART_TIME: 2023-07-01: 75 SCHOOL_AGE: FULL_TIME: + # Unchanged across eras (FY2025-2027 adopted full-time value is also $130). 2023-07-01: 130 PART_TIME: 2023-07-01: 80 @@ -40,20 +54,24 @@ NON_METRO: INFANT: FULL_TIME: 2023-07-01: 125 + 2024-10-01: 140 PART_TIME: 2023-07-01: 80 TODDLER: FULL_TIME: 2023-07-01: 120 + 2024-10-01: 135 PART_TIME: 2023-07-01: 75 PRESCHOOL: FULL_TIME: 2023-07-01: 120 + 2024-10-01: 125 PART_TIME: 2023-07-01: 75 SCHOOL_AGE: FULL_TIME: 2023-07-01: 110 + 2024-10-01: 120 PART_TIME: 2023-07-01: 74 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/family_home.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/family_home.yaml index 51173d8d770..46c02fc7bd9 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/family_home.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/family_home.yaml @@ -1,8 +1,16 @@ description: Mississippi provides these maximum weekly payment rates for registered family child care homes under the Child Care Payment Program. -# Operative "Current CCPP Rates" schedule effective July 2023 (2024 Market Rate -# Survey Table 2, p.10). Rates vary by the facility's location (metro / non-metro); -# we use the household's county as a proxy for facility location. Special-needs -# children are paid the flat all-ages special-needs rate (see special_needs_home). +# Two rate eras, keyed by the facility's location (metro / non-metro); we use the +# household's county as a proxy for facility location. +# - 2023-07-01 = July-2023 "Current CCPP Rates" (2024 Market Rate Survey Table 2, p.10). +# - 2024-10-01 = FY2025-2027 State Plan adopted full-time base rates. The State Plan +# reports rates by "most populous region" (encoded in the METRO slot) and "lowest +# region" (NON_METRO slot); the most-populous figure equals the statewide 75th +# percentile. +# The FY2025-2027 State Plan publishes FULL-TIME base rates only; the adopted part-time +# rates for that era are not publicly available (only the family copay fee scale is +# published), so the part-time leaves below retain their 2023-07 values — a documented +# limitation we don't track at the moment. Special-needs children are paid the flat +# all-ages special-needs rate (see special_needs_home). metadata: period: week unit: currency-USD @@ -14,46 +22,56 @@ metadata: reference: - title: 2024 Mississippi Child Care Market Rate Survey, Table 2 (Current CCPP Rates, Registered Family Homes) href: https://www.mdhs.ms.gov/wp-content/uploads/2024/06/Mississippi-Child-Care-Market-Rate-Survey-2024.pdf#page=10 + - title: Mississippi FFY 2025-2027 CCDF State Plan, §4.3.2 (adopted full-time base rates, most-populous region pp.59-60); effective date §4.3.1(b) p.57 + href: https://www.mdhs.ms.gov/wp-content/uploads/2025/01/ACF-118-CCDF-FFY-2025-2027-For-Mississippi.pdf#page=59 METRO: INFANT: FULL_TIME: 2023-07-01: 115 + 2024-10-01: 140 PART_TIME: 2023-07-01: 68 TODDLER: FULL_TIME: 2023-07-01: 120 + 2024-10-01: 131 PART_TIME: 2023-07-01: 75 PRESCHOOL: FULL_TIME: 2023-07-01: 120 + 2024-10-01: 125 PART_TIME: 2023-07-01: 60 SCHOOL_AGE: FULL_TIME: 2023-07-01: 95 + 2024-10-01: 115 PART_TIME: 2023-07-01: 58 NON_METRO: INFANT: FULL_TIME: 2023-07-01: 94 + 2024-10-01: 128 PART_TIME: 2023-07-01: 60 TODDLER: FULL_TIME: 2023-07-01: 98 + 2024-10-01: 125 PART_TIME: 2023-07-01: 61 PRESCHOOL: FULL_TIME: 2023-07-01: 106 + 2024-10-01: 120 PART_TIME: 2023-07-01: 60 SCHOOL_AGE: FULL_TIME: 2023-07-01: 79 + 2024-10-01: 95 PART_TIME: 2023-07-01: 53 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_center.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_center.yaml index c986f0ceb5d..3caf978f88a 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_center.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_center.yaml @@ -2,6 +2,9 @@ description: Mississippi provides these maximum weekly payment rates for special # Flat all-ages special-needs rate effective July 2023 (2024 Market Rate Survey # Table 1, p.9). This rate is the same for metro and non-metro facilities, but is # keyed by location for structural consistency with the standard center rates. +# These retain the 2023-07 values for the 2024-10 (FY2025-2027) era because the +# FY2025-2027 adopted special-needs dollar rates are not publicly available — a +# limitation we don't track at the moment. metadata: period: week unit: currency-USD diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_home.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_home.yaml index e4dc0747a75..95cbd34b251 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_home.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/rates/special_needs_home.yaml @@ -3,6 +3,9 @@ description: Mississippi provides these maximum weekly payment rates for special # Table 2, p.10). This rate is the same for metro and non-metro facilities, but is # keyed by location for structural consistency with the standard family-home rates. # In-home care (special-needs only, child's own home) is paid this home-based rate. +# These retain the 2023-07 values for the 2024-10 (FY2025-2027) era because the +# FY2025-2027 adopted special-needs dollar rates are not publicly available — a +# limitation we don't track at the moment. metadata: period: week unit: currency-USD diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/integration.yaml index 9bde83ba6f1..2bc63d42209 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/integration.yaml @@ -8,7 +8,8 @@ # Size 4: 85% SMI = 5,333.75; 50% SMI = 3,137.50; FPG = 2,600.00 - name: Case 1, single parent one preschooler metro center full time, full pipeline. - period: 2024 + # Era-1 month (2024-01): rates use the 2023-07 schedule, before the 2024-10 increase. + period: 2024-01 absolute_error_margin: 0.01 input: people: @@ -36,13 +37,14 @@ county: HINDS_COUNTY_MS output: ms_ccpp_eligible: true - # Rate center metro FT preschool 135/wk -> 585/mo; copay 2,000*5.5% = 110 - # Monthly benefit = 585 - 110 = 475; annual = 5,700 - ms_child_care_subsidies: 5_700 - child_care_subsidies: 5_700 + # Rate center metro FT preschool 135/wk -> 135 * 52/12 = 585/mo + # Copay: 2,000/mo, size 2, <= 50% SMI 2,133.50 -> very-low 5.5% = 110 + # Monthly benefit = min(1,000, 585) - 110 = 475 + ms_ccpp: 475 - name: Case 2, two-parent family two children family home non-metro low band. - period: 2024 + # Era-1 month (2024-01): rates use the 2023-07 schedule, before the 2024-10 increase. + period: 2024-01 absolute_error_margin: 0.01 input: people: @@ -80,14 +82,14 @@ output: ms_ccpp_income_eligible: true ms_ccpp_eligible: true - # Rates home non-metro FT: toddler 98 + school-age 79 = 177/wk -> 767/mo + # Rates home non-metro FT: toddler 98 + school-age 79 = 177/wk -> 177 * 52/12 = 767/mo # Copay: 4,000/mo size 4 > 50% SMI 3,137.50 -> low 5.5% = 220 - # Monthly benefit = min(1,500, 767) - 220 = 547; annual = 6,564 - ms_ccpp: 6_564 - child_care_subsidies: 6_564 + # Monthly benefit = min(1,500, 767) - 220 = 547 + ms_ccpp: 547 - name: Case 3, homeless family above income limit eligible via categorical bypass. - period: 2024 + # Era-1 month (2024-01): rates use the 2023-07 schedule, before the 2024-10 increase. + period: 2024-01 absolute_error_margin: 0.01 input: people: @@ -122,10 +124,9 @@ ms_ccpp_eligible: true # Has income (4,000) so not homeless-no-income -> scale copay applies # Copay: 4,000/mo size 2 > 50% SMI 2,133.50 -> low 6.5% = 260 - # Rate center metro FT preschool 135/wk -> 585/mo - # Monthly benefit = min(1,000, 585) - 260 = 325; annual = 3,900 - ms_ccpp: 3_900 - child_care_subsidies: 3_900 + # Rate center metro FT preschool 135/wk -> 135 * 52/12 = 585/mo + # Monthly benefit = min(1,000, 585) - 260 = 325 + ms_ccpp: 325 - name: Case 4, special-needs child draws special-needs rate with $10 copay cap. period: 2024 @@ -271,3 +272,180 @@ ms_ccpp_eligible: false ms_ccpp: 0 ms_child_care_subsidies: 0 + +# Era-2 coverage (period 2025-01, a pure 2024-10 schedule month, before the +# unmodeled July-2025 increase). Cases 8-11 confirm the FY2025-2027 full-time +# base rates flow through and that part-time + special-needs leaves correctly +# carry forward their era-1 (2023-07) values. +- name: Case 8, era-2 metro center infant full time draws the FY2025-2027 rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 12_000 # 1,000/mo, at/below FPL size 2 -> copay 0 + weekly_hours_worked_before_lsr: 40 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Era-2 metro center infant FT = 167/wk -> 167 * 52/12 = 723.67/mo + # Income 1,000/mo <= FPL (size 2) -> copay 0 + # Benefit = min(1,000, 723.67) - 0 = 723.67 + ms_ccpp: 723.67 + +- name: Case 9, era-2 non-metro center infant full time draws the lower regional rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 12_000 # 1,000/mo, at/below FPL size 2 -> copay 0 + weekly_hours_worked_before_lsr: 40 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: BOLIVAR_COUNTY_MS # non-metro + output: + ms_ccpp_eligible: true + # Era-2 non-metro center infant FT = 140/wk -> 140 * 52/12 = 606.67/mo + # Income 1,000/mo <= FPL (size 2) -> copay 0 + # Benefit = min(1,000, 606.67) - 0 = 606.67 + ms_ccpp: 606.67 + +- name: Case 10, era-2 family home metro infant full time draws the FY2025-2027 rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 12_000 # 1,000/mo, at/below FPL size 2 -> copay 0 + weekly_hours_worked_before_lsr: 40 + person2: + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: FAMILY_HOME + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Era-2 metro family home infant FT = 140/wk -> 140 * 52/12 = 606.67/mo + # Income 1,000/mo <= FPL (size 2) -> copay 0 + # Benefit = min(1,000, 606.67) - 0 = 606.67 + ms_ccpp: 606.67 + +- name: Case 11, era-2 part time and special needs leaves carry forward era-1 rates. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 12_000 # 1,000/mo, at/below FPL size 2 -> copay 0 + weekly_hours_worked_before_lsr: 40 + person2: # part-time infant: PT rate has no era-2 entry -> carries era-1 + age: 0 + is_tax_unit_dependent: true + childcare_hours_per_day: 4 # part time + childcare_hours_per_week: 20 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # PART_TIME has no 2024-10 entry, so the 2023-07 value carries forward: + # metro center infant PT = 90/wk -> 90 * 52/12 = 390/mo + # Income 1,000/mo <= FPL (size 2) -> copay 0 + # Benefit = min(1,000, 390) - 0 = 390 + ms_ccpp: 390 + +- name: Case 12, era-2 special needs child draws the carried-forward flat rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 12_000 # 1,000/mo, at/below FPL size 2 -> copay 0 + weekly_hours_worked_before_lsr: 40 + person2: + age: 8 + is_disabled: true + is_tax_unit_dependent: true + childcare_hours_per_day: 8 # full time + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + ms_ccpp_eligible: true + # Special-needs rate has no 2024-10 entry, so the 2023-07 flat value carries + # forward: special-needs center FT = 145/wk -> 145 * 52/12 = 628.33/mo + # Income 1,000/mo <= FPL (size 2) -> copay 0 (so the $10 min-fee cap does not bind) + # Benefit = min(1,000, 628.33) - 0 = 628.33 + ms_ccpp: 628.33 From c9e90d2448de59c631f965c636ffe23ee8f359c4 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Jun 2026 16:16:39 -0400 Subject: [PATCH 7/9] Clarify copay-rate provenance: per-size rates are published in Copay Fee Scale Table 2 The up-to-50%-SMI per-size copay rates (5.5/5/4.5/4/3.5%) are published directly in the Copay Fee Scale 'Table 2: Family Co-Pay Rates', not merely derived from the 5.5% cap. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../states/ms/dhs/ccpp/copay/rate/very_low_income.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml index d77613bd0a1..5ce939b72c2 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/rate/very_low_income.yaml @@ -1,9 +1,9 @@ description: Mississippi sets the co-payment as this share of gross income for families at or below 50% of state median income under the Child Care Payment Program. # Co-payment percentage by family size for the "up to 50% SMI" band. Family size -# is capped at 6 (the published table's "6 or more" row) before lookup. These -# values are derived from the State Plan's 5.5% cap for the up-to-50%-SMI band -# (-0.5 percentage point per family size: 5.5/5/4.5/4/3.5%), not transcribed -# from a published per-size table. +# is capped at 6 (the fee scale's "6 or more" column) before lookup. These per-size +# rates are published directly in the Copay Fee Scale "Table 2: Family Co-Pay Rates" +# (5.5/5/4.5/4/3.5%); they also equal the State Plan's 5.5% cap stepped down +# 0.5 percentage point per family size. metadata: type: single_amount threshold_unit: person From 877ce5b728f6e5da37a7ea4ef7856853a0286104 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Jun 2026 22:36:29 -0400 Subject: [PATCH 8/9] Review-fix round 3: correct CCPP Policy Manual citations; add tests - Page anchors: fix systematic +1 offset (Rule 5.1 #26->25, Rule 5.4 countable #29->28, priority populations #19->18, FPL exemption #41->40, FT/PT defs #13->12) and correct inline definition page numbers in age/hours titles. - Wrong-rule citations: subsidy/reimbursement #45 -> Rule 8.1 #57 (ms_ccpp, ms_child_care_subsidies); provider types #45 -> Rule 7.1 #43. - Copay test: $0 poverty-line exemption takes precedence over the $10 minimum-fee cap for a special-needs child at/below FPL. - Activity: note the unmodeled Rule 5.1(3) life-threatening-illness waiver. - Backdate age-group/time-category classification brackets to 2021-11-01. - Add an income-above-85%-SMI ineligible case to ms_ccpp.yaml. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../gov/states/ms/dhs/ccpp/age_group/age.yaml | 18 +++++----- .../ms/dhs/ccpp/copay/fpg_exempt_rate.yaml | 2 +- .../dhs/ccpp/eligibility/child_age_limit.yaml | 2 +- .../special_needs_child_age_limit.yaml | 2 +- .../ccpp/income/countable_income/sources.yaml | 2 +- .../states/ms/dhs/ccpp/income/smi_rate.yaml | 2 +- .../ms/dhs/ccpp/time_category/hours.yaml | 12 +++---- .../ms/dhs/ccpp/copay/ms_ccpp_copay.yaml | 24 ++++++++++++++ .../gov/states/ms/dhs/ccpp/ms_ccpp.yaml | 33 +++++++++++++++++++ .../eligibility/ms_ccpp_activity_eligible.py | 2 ++ .../ms_ccpp_categorically_eligible.py | 2 +- .../dhs/ccpp/eligibility/ms_ccpp_eligible.py | 2 +- .../eligibility/ms_ccpp_eligible_child.py | 2 +- .../eligibility/ms_ccpp_income_eligible.py | 2 +- .../gov/states/ms/dhs/ccpp/ms_ccpp.py | 2 +- .../ms/dhs/ccpp/ms_ccpp_countable_income.py | 2 +- .../ms/dhs/ccpp/ms_ccpp_provider_type.py | 2 +- .../ms/dhs/ccpp/ms_ccpp_time_category.py | 2 +- .../ms/dhs/ccpp/ms_child_care_subsidies.py | 2 +- 19 files changed, 88 insertions(+), 29 deletions(-) diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml index 30d4976131a..d673eaa4bdd 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/age_group/age.yaml @@ -13,23 +13,23 @@ metadata: period: year label: Mississippi CCPP child age group by age reference: - - title: Mississippi CCPP Policy Manual, Definitions (Infant #49 p.13, Toddler #87 p.17, Preschool #66 p.15, School Age #74 p.16) + - title: Mississippi CCPP Policy Manual, Definitions (Infant #49 p.13, Toddler #87 p.16, Preschool #66 p.14, School Age #74 p.15) href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=13 brackets: - threshold: - 2023-07-01: 0 + 2021-11-01: 0 amount: - 2023-07-01: 0 + 2021-11-01: 0 - threshold: - 2023-07-01: 1 + 2021-11-01: 1 amount: - 2023-07-01: 1 + 2021-11-01: 1 - threshold: - 2023-07-01: 3 + 2021-11-01: 3 amount: - 2023-07-01: 2 + 2021-11-01: 2 - threshold: - 2023-07-01: 5 + 2021-11-01: 5 amount: - 2023-07-01: 3 + 2021-11-01: 3 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml index f9d39fc1b35..fcb669fab81 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/copay/fpg_exempt_rate.yaml @@ -10,4 +10,4 @@ metadata: label: Mississippi CCPP co-payment poverty line exemption rate reference: - title: Mississippi CCPP Policy Manual, Rule 6.2 (Co-Payment Fee) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=41 + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=40 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml index c09be12815d..9e2a2a1ac8f 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/child_age_limit.yaml @@ -8,4 +8,4 @@ metadata: label: Mississippi CCPP child age limit reference: - title: Mississippi CCPP Policy Manual, Rule 5.1 (Eligibility Requirements) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26 + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=25 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml index 6c805859f21..c8624b9a820 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/eligibility/special_needs_child_age_limit.yaml @@ -8,4 +8,4 @@ metadata: label: Mississippi CCPP special-needs child age limit reference: - title: Mississippi CCPP Policy Manual, Rule 5.1 (Eligibility Requirements) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26 + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=25 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml index 062e6227ef6..fc2ee34db1b 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml @@ -25,4 +25,4 @@ metadata: label: Mississippi CCPP countable income sources reference: - title: Mississippi CCPP Policy Manual, Rule 5.4 (How Income is Calculated — Countable Income) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=29 + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=28 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml index e34b2fd767a..ec79519e969 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/smi_rate.yaml @@ -8,4 +8,4 @@ metadata: label: Mississippi CCPP SMI income limit rate reference: - title: Mississippi CCPP Policy Manual, Rule 5.1 (Eligibility Requirements) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26 + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=25 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml index c115e41eb6c..679f44683d0 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/time_category/hours.yaml @@ -11,15 +11,15 @@ metadata: period: year label: Mississippi CCPP time category by daily hours reference: - - title: Mississippi CCPP Policy Manual, Definitions (Full-Time #44 p.13, Part-Time #65 p.15) - href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=13 + - title: Mississippi CCPP Policy Manual, Definitions (Full-Time #44 p.12, Part-Time #65 p.14) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=12 brackets: - threshold: - 2023-07-01: 0 + 2021-11-01: 0 amount: - 2023-07-01: 0 + 2021-11-01: 0 - threshold: - 2023-07-01: 6 + 2021-11-01: 6 amount: - 2023-07-01: 1 + 2021-11-01: 1 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml index 9eb7ef7cc4a..ff8d59ccce0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml @@ -360,3 +360,27 @@ output: # is_homeless and zero countable income -> homeless_no_income branch -> $0 ms_ccpp_copay: 0 + +- name: Case 15, special-needs child at or below the poverty line pays zero copay. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 18_000 # YEAR -> 1,500/mo + person2: + age: 4 + is_disabled: true # special-needs child -> minimum-fee category + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Monthly income 1,500 <= FPG 1,703.33 (family of 2): minimum-fee category + # (special-needs child) would cap at $10, but the $0 poverty-line exemption + # takes precedence -> $0 copay + ms_ccpp_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp.yaml index a3452b3aea1..a3ab0854b42 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp.yaml @@ -190,3 +190,36 @@ # -> very-low band 5.0% = 120 (single family copay, subtracted once) # Benefit = max(min(2,000, 1,243.67) - 120, 0) = 1,243.67 - 120 = 1,123.67 ms_ccpp: 1_123.67 + +- name: Case 6, income above 85 percent SMI is ineligible and receives no subsidy. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 60_000 # 5,000/mo + weekly_hours_worked_before_lsr: 40 + person2: + age: 4 + is_tax_unit_dependent: true + childcare_hours_per_day: 8 + childcare_hours_per_week: 40 + ms_ccpp_provider_type: CENTER + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 # 1,000/mo + households: + household: + members: [person1, person2] + state_code: MS + county: HINDS_COUNTY_MS + output: + # Monthly income 5,000 > 85% SMI for family of 2 (4,267 * 0.85 = 3,626.95) + # -> income-ineligible, no categorical pathway -> not eligible, $0 subsidy + ms_ccpp_eligible: false + ms_ccpp: 0 diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py index 4831841b429..c9c2c93654f 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_activity_eligible.py @@ -21,6 +21,8 @@ def formula(spm_unit, period, parameters): is_student = person("is_full_time_student", period.this_year) # The activity requirement is waived for an SSI-disabled parent. is_ssi_disabled = person("is_ssi_disabled", period.this_year) + # Rule 5.1(3) also waives the requirement for a parent with a + # life-threatening illness; we don't track that at the moment. individually_eligible = meets_work_requirement | is_student | is_ssi_disabled # Require at least one head/spouse so a unit of only dependents does not # vacuously pass, and require every head/spouse to be individually diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py index 68c3af43c20..178028c21eb 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_categorically_eligible.py @@ -7,7 +7,7 @@ class ms_ccpp_categorically_eligible(Variable): label = "Categorically eligible for Mississippi CCPP" definition_period = MONTH defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=19" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=18" def formula(spm_unit, period, parameters): # Categorical pathways bypass the income test. We model TANF diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py index 8c079426462..1f8eb7406eb 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible.py @@ -7,7 +7,7 @@ class ms_ccpp_eligible(Variable): label = "Eligible for Mississippi CCPP" definition_period = MONTH defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=25" def formula(spm_unit, period, parameters): has_eligible_child = add(spm_unit, period, ["ms_ccpp_eligible_child"]) > 0 diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py index 9e17cc7636d..a250f2dedef 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_eligible_child.py @@ -7,7 +7,7 @@ class ms_ccpp_eligible_child(Variable): label = "Eligible child for Mississippi CCPP" definition_period = MONTH defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=25" def formula(person, period, parameters): p = parameters(period).gov.states.ms.dhs.ccpp.eligibility diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py index 5b16c676412..85a93447c1a 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/eligibility/ms_ccpp_income_eligible.py @@ -7,7 +7,7 @@ class ms_ccpp_income_eligible(Variable): label = "Eligible for Mississippi CCPP based on income" definition_period = MONTH defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=26" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=25" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.ms.dhs.ccpp.income diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py index dad3342789a..a2d4fd22fa2 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp.py @@ -8,7 +8,7 @@ class ms_ccpp(Variable): label = "Mississippi CCPP benefit amount" definition_period = MONTH defined_for = "ms_ccpp_eligible" - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=45" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=57" def formula(spm_unit, period, parameters): copay = spm_unit("ms_ccpp_copay", period) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py index 9fbcaa79ac8..35c9813dbac 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py @@ -8,6 +8,6 @@ class ms_ccpp_countable_income(Variable): definition_period = MONTH unit = USD defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=29" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=28" adds = "gov.states.ms.dhs.ccpp.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py index facc6774ad6..c5b8c97bc7c 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_provider_type.py @@ -18,4 +18,4 @@ class ms_ccpp_provider_type(Variable): # rate, so there is no separate in-home provider type; route in-home and # special-needs children through FAMILY_HOME (or CENTER) and the special-needs # rate set. - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=45" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=43" diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py index 4dc63631aba..b1d950f3d36 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_time_category.py @@ -14,7 +14,7 @@ class ms_ccpp_time_category(Variable): definition_period = MONTH label = "Mississippi CCPP care time category" defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=13" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=12" def formula(person, period, parameters): hours_per_day = person("childcare_hours_per_day", period.this_year) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py index 628ba9d7387..e3885c4a698 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_child_care_subsidies.py @@ -8,5 +8,5 @@ class ms_child_care_subsidies(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MS - reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=45" + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=57" adds = ["ms_ccpp"] From 03f54370daa3d20667abe0a6d42cc16e4c413bbf Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 16 Jun 2026 23:39:40 -0400 Subject: [PATCH 9/9] Exclude minor-student earnings, floor self-employment loss, refine copay categories - Income (Rule 5.4): exclude earned income of students under 18 (new ms_ccpp_countable_earned_income) and floor the self-employment sum at zero so a business loss does not offset other income. Split the countable income sources into self_employment_sources and unearned_sources. - Co-payment (Rule 6.2): decompose ms_ccpp_copay into ms_ccpp_income_based_copay, ms_ccpp_minimum_fee_category, and ms_ccpp_copay_waived. The $10 minimum-fee cap now requires a parent with a disability who is receiving SSI (ssi > 0), and a special-needs child must be a disabled dependent under 19. - Add tests for the new variables and the corrected income/copay behavior. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../self_employment_sources.yaml | 18 +++ .../{sources.yaml => unearned_sources.yaml} | 9 +- .../ccpp/income/student_earner_age_limit.yaml | 11 ++ .../ms/dhs/ccpp/copay/ms_ccpp_copay.yaml | 57 +++++++++- .../dhs/ccpp/copay/ms_ccpp_copay_waived.yaml | 57 ++++++++++ .../copay/ms_ccpp_income_based_copay.yaml | 61 ++++++++++ .../copay/ms_ccpp_minimum_fee_category.yaml | 104 ++++++++++++++++++ .../ms/dhs/ccpp/ms_ccpp_countable_income.yaml | 39 +++++-- .../states/ms/dhs/ccpp/copay/ms_ccpp_copay.py | 62 +---------- .../ms/dhs/ccpp/copay/ms_ccpp_copay_waived.py | 23 ++++ .../ccpp/copay/ms_ccpp_income_based_copay.py | 31 ++++++ .../copay/ms_ccpp_minimum_fee_category.py | 30 +++++ .../ccpp/ms_ccpp_countable_earned_income.py | 27 +++++ .../ms/dhs/ccpp/ms_ccpp_countable_income.py | 6 +- 14 files changed, 461 insertions(+), 74 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/self_employment_sources.yaml rename policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/{sources.yaml => unearned_sources.yaml} (65%) create mode 100644 policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/student_earner_age_limit.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay_waived.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_income_based_copay.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_minimum_fee_category.yaml create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay_waived.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_income_based_copay.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_minimum_fee_category.py create mode 100644 policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_earned_income.py diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/self_employment_sources.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/self_employment_sources.yaml new file mode 100644 index 00000000000..77d895f6a7f --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/self_employment_sources.yaml @@ -0,0 +1,18 @@ +description: Mississippi counts these self-employment income sources for eligibility and the co-payment under the Child Care Payment Program. +# Self-employment is counted as gross income (Rule 5.3 "Total Sales and +# Receipts"), so the variable floors the sum of these net sources at zero: a +# business loss does not offset other income. PolicyEngine's self-employment +# income is net, so this may still understate gross receipts. +values: + 2021-11-01: + - self_employment_income + - sstb_self_employment_income + - farm_operations_income + +metadata: + unit: list + period: year + label: Mississippi CCPP countable self-employment income sources + reference: + - title: Mississippi CCPP Policy Manual, Rule 5.4 (How Income is Calculated — Countable Income) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=28 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/unearned_sources.yaml similarity index 65% rename from policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml rename to policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/unearned_sources.yaml index fc2ee34db1b..3386d136047 100644 --- a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/countable_income/unearned_sources.yaml @@ -1,10 +1,6 @@ -description: Mississippi counts these gross income sources for eligibility and the co-payment under the Child Care Payment Program. +description: Mississippi counts these gross unearned income sources for eligibility and the co-payment under the Child Care Payment Program. values: 2021-11-01: - - employment_income # wages, salary, military base pay, commissions, bonuses, tips - - self_employment_income # gross self-employment income (can be negative; floored at 0 downstream) - - sstb_self_employment_income - - farm_operations_income - social_security # SSA benefits for parent and child (umbrella; do not also add social_security_disability) - ssi # SSI for parent and child (separate from the social_security umbrella) - unemployment_compensation # counted at redetermination only; simplified to always countable @@ -17,12 +13,11 @@ values: - capital_gains # Countable items in the manual with no matching variable at the moment: # military allotments, lump sums, short-term disability payments. - # Tips, commissions, and bonuses are captured by employment_income. metadata: unit: list period: year - label: Mississippi CCPP countable income sources + label: Mississippi CCPP countable unearned income sources reference: - title: Mississippi CCPP Policy Manual, Rule 5.4 (How Income is Calculated — Countable Income) href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=28 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/student_earner_age_limit.yaml b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/student_earner_age_limit.yaml new file mode 100644 index 00000000000..f534594399e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/ccpp/income/student_earner_age_limit.yaml @@ -0,0 +1,11 @@ +description: Mississippi excludes the earned income of students younger than this age from countable income under the Child Care Payment Program. +values: + 2021-11-01: 18 + +metadata: + unit: year + period: year + label: Mississippi CCPP student earner age limit + reference: + - title: Mississippi CCPP Policy Manual, Rule 5.4 (How Income is Calculated — Non-Countable Income) + href: https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=29 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml index ff8d59ccce0..6ac834ee3ad 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.yaml @@ -130,7 +130,7 @@ # -> minimum-fee category caps at $10 ms_ccpp_copay: 10 -- name: Case 6, SSI-disabled parent caps the copay at $10. +- name: Case 6, parent with a disability receiving SSI caps the copay at $10. period: 2024-01 absolute_error_margin: 0.01 input: @@ -139,6 +139,7 @@ age: 40 employment_income: 24_000 # YEAR -> 2,000/mo is_ssi_disabled: true + ssi: 300 # MONTH, receiving SSI (counts as income) person2: age: 4 tax_units: @@ -152,8 +153,8 @@ members: [person1, person2] state_code: MS output: - # Uncapped very-low band copay = 2,000 * 0.055 = 110; above FPL 1,703.33 - # SSI-disabled parent -> minimum-fee category caps at $10 + # Income 2,300/mo (2,000 wages + 300 SSI) > 50% SMI 2,133.50 -> low band; + # above FPL 1,703.33; disabled parent receiving SSI -> minimum-fee cap $10 ms_ccpp_copay: 10 - name: Case 7, TANF family pays zero copay even above FPL. @@ -372,6 +373,7 @@ person2: age: 4 is_disabled: true # special-needs child -> minimum-fee category + is_tax_unit_dependent: true spm_units: spm_unit: members: [person1, person2] @@ -384,3 +386,52 @@ # (special-needs child) would cap at $10, but the $0 poverty-line exemption # takes precedence -> $0 copay ms_ccpp_copay: 0 + +- name: Case 16, a disabled parent not receiving SSI is not a minimum-fee category. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # YEAR -> 2,000/mo + is_disabled: true # disabled but not receiving SSI, and an adult (not a child) + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Above FPL 1,703.33 and <= 50% SMI 2,133.50 -> very-low band 5.5% = 110. + # The parent's disability does not cap: not receiving SSI, and a disabled + # adult is not a special-needs child (under 19). + ms_ccpp_copay: 110 + +- name: Case 17, a disabled 18-year-old head is not a special-needs child. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 18 + employment_income: 24_000 # YEAR -> 2,000/mo + is_disabled: true + is_tax_unit_head: true + person2: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # The disabled head is under 19 but is not a dependent child, so the + # special-needs child minimum-fee cap does not apply. + ms_ccpp_copay: 110 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay_waived.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay_waived.yaml new file mode 100644 index 00000000000..af14fafc716 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay_waived.yaml @@ -0,0 +1,57 @@ +- name: Case 1, family at or below the poverty line has waived copay. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 18_000 # YEAR -> 1,500/mo + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_copay_waived: true + +- name: Case 2, TANF family has waived copay. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 60_000 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_copay_waived: true + +- name: Case 3, family above the poverty line without waiver category does not have waived copay. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # YEAR -> 2,000/mo + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_copay_waived: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_income_based_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_income_based_copay.yaml new file mode 100644 index 00000000000..3557ae6cf47 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_income_based_copay.yaml @@ -0,0 +1,61 @@ +- name: Case 1, family of two in the very-low-income band. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 # YEAR -> 2,000/mo + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Family of 2, income <= 50% SMI, rate = 5.5%. + ms_ccpp_income_based_copay: 110 + +- name: Case 2, family of two in the low-income band. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 27_600 # YEAR -> 2,300/mo + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Family of 2, income > 50% SMI, rate = 6.5%. + ms_ccpp_income_based_copay: 149.5 + +- name: Case 3, negative countable income is floored at zero. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + self_employment_income: -12_000 # YEAR -> -1,000/mo, floored + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_income_based_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_minimum_fee_category.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_minimum_fee_category.yaml new file mode 100644 index 00000000000..9b2f1b3eb64 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/copay/ms_ccpp_minimum_fee_category.yaml @@ -0,0 +1,104 @@ +- name: Case 1, protective-services child is a minimum-fee category. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + receives_or_needs_protective_services: true + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_minimum_fee_category: true + +- name: Case 2, SSI-disabled parent receiving SSI is a minimum-fee category. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head: true + is_ssi_disabled: true + ssi: 300 + person2: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_minimum_fee_category: true + +- name: Case 3, disabled parent not receiving SSI is not a minimum-fee category. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head: true + is_disabled: true + person2: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_minimum_fee_category: false + +- name: Case 4, disabled dependent child under nineteen is a minimum-fee category. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head: true + person2: + age: 18 + is_disabled: true + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_minimum_fee_category: true + +- name: Case 5, disabled 18-year-old head is not a minimum-fee category. + period: 2024-01 + input: + people: + person1: + age: 18 + is_disabled: true + is_tax_unit_head: true + person2: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + ms_ccpp_minimum_fee_category: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.yaml index 0ceebb57ced..d9640aadaa0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.yaml @@ -1,6 +1,8 @@ -# ms_ccpp_countable_income is SPMUnit, MONTH (adds the countable income sources -# positive list). Gross income, no deductions. SSI and Social Security both count -# (for parent and child); child support received and EITC are not countable. +# ms_ccpp_countable_income is SPMUnit, MONTH. Gross income, no deductions. +# Earned income of students under 18 is excluded (Rule 5.4); the self-employment +# sum is floored at zero (a loss does not offset other income). SSI and Social +# Security both count (for parent and child); child support received and EITC are +# not countable. - name: Case 1, employment, Social Security, and SSI count; child support does not. period: 2024-01 @@ -26,7 +28,7 @@ # 2,000 + 500 + 400 = 2,900 (child support excluded) ms_ccpp_countable_income: 2_900 -- name: Case 2, negative self-employment income reduces countable income. +- name: Case 2, a self-employment loss is floored and does not reduce countable income. period: 2024-01 absolute_error_margin: 0.01 input: @@ -34,7 +36,7 @@ person1: age: 30 employment_income: 24_000 # YEAR -> 2,000/mo - self_employment_income: -6_000 # YEAR -> -500/mo (countable, can be negative) + self_employment_income: -6_000 # YEAR -> -500/mo loss, floored at 0 person2: age: 4 spm_units: @@ -45,8 +47,8 @@ members: [person1, person2] state_code: MS output: - # 2,000 + (-500) = 1,500 - ms_ccpp_countable_income: 1_500 + # 2,000 + max(-500, 0) = 2,000 (the loss does not offset wages) + ms_ccpp_countable_income: 2_000 - name: Case 3, child's SSI and Social Security count toward family income. period: 2024-01 @@ -70,3 +72,26 @@ output: # 1,500 + 300 + 200 = 2,000 ms_ccpp_countable_income: 2_000 + +- name: Case 4, earned income of a student under 18 is excluded; their unearned income still counts. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 24_000 # YEAR -> 2,000/mo, adult, counts + person2: + age: 16 + employment_income: 6_000 # YEAR -> 500/mo, student under 18 -> excluded + ssi: 100 # MONTH, the student's unearned income still counts + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # adult 2,000 + excluded student wages 0 + student SSI 100 = 2,100 + ms_ccpp_countable_income: 2_100 diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py index ada67313fb8..5f1656c5d96 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay.py @@ -11,62 +11,12 @@ class ms_ccpp_copay(Variable): reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=41" def formula(spm_unit, period, parameters): - # The published Copay Fee Scale snaps income up to the next $1,000 band - # before applying the rate and ties the band split to those $1,000 rows. - # We apply the percentage to exact monthly countable income and split the - # band at exactly 50% SMI, so results will not match the published - # per-row dollar cells to the cent. p = parameters(period).gov.states.ms.dhs.ccpp.copay - p_income = parameters(period).gov.states.ms.dhs.ccpp.income - - # Floor income at zero so negative self-employment income cannot inflate - # or reduce the co-payment. - monthly_income = max_(spm_unit("ms_ccpp_countable_income", period), 0) - - # Family size is capped at the published "6 or more" row. - size = spm_unit("spm_unit_size", period.this_year) - fee_scale_size = min_(size, p.max_family_size) - - # Select the co-payment rate band by position relative to 50% SMI. - monthly_smi = spm_unit("hhs_smi", period) - very_low_income = ( - monthly_income <= monthly_smi * p_income.very_low_income_smi_rate - ) - copay_rate = where( - very_low_income, - p.rate.very_low_income.calc(fee_scale_size), - p.rate.low_income.calc(fee_scale_size), - ) - scale_copay = monthly_income * copay_rate - - # Families at or below the federal poverty line, TANF recipients, and - # homeless families with no countable income pay no co-payment. - monthly_fpg = spm_unit("spm_unit_fpg", period) - at_or_below_fpl = monthly_income <= monthly_fpg * p.fpg_exempt_rate - is_tanf = spm_unit("is_tanf_enrolled", period) - is_homeless = spm_unit.household("is_homeless", period.this_year) - homeless_no_income = is_homeless & (monthly_income == 0) - zero_copay = at_or_below_fpl | is_tanf | homeless_no_income - - # Minimum-fee categories (income above the poverty line) cap the - # co-payment at $10/month. Of the manual's categories, only protective - # services, SSI-disabled parents, and special-needs children can be - # tracked at the moment. - person = spm_unit.members - has_protective_child = spm_unit.any( - person("receives_or_needs_protective_services", period.this_year) - ) - is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) - is_ssi_disabled = person("is_ssi_disabled", period.this_year) - has_ssi_disabled_parent = spm_unit.any(is_head_or_spouse & is_ssi_disabled) - has_special_needs_child = spm_unit.any(person("is_disabled", period.this_year)) - in_min_fee_category = ( - has_protective_child | has_ssi_disabled_parent | has_special_needs_child - ) - capped_copay = where( - in_min_fee_category, - min_(scale_copay, p.minimum_fee_categories_cap), - scale_copay, + income_based_copay = spm_unit("ms_ccpp_income_based_copay", period) + minimum_fee_copay = where( + spm_unit("ms_ccpp_minimum_fee_category", period), + min_(income_based_copay, p.minimum_fee_categories_cap), + income_based_copay, ) - return where(zero_copay, 0, capped_copay) + return where(spm_unit("ms_ccpp_copay_waived", period), 0, minimum_fee_copay) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay_waived.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay_waived.py new file mode 100644 index 00000000000..df45bf9f0fc --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_copay_waived.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_copay_waived(Variable): + value_type = bool + entity = SPMUnit + label = "Mississippi CCPP co-payment is waived" + definition_period = MONTH + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=40" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ms.dhs.ccpp.copay + monthly_income = max_(spm_unit("ms_ccpp_countable_income", period), 0) + at_or_below_fpl = monthly_income <= ( + spm_unit("spm_unit_fpg", period) * p.fpg_exempt_rate + ) + homeless_no_income = spm_unit.household("is_homeless", period.this_year) & ( + monthly_income == 0 + ) + return ( + at_or_below_fpl | spm_unit("is_tanf_enrolled", period) | homeless_no_income + ) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_income_based_copay.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_income_based_copay.py new file mode 100644 index 00000000000..66a15382504 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_income_based_copay.py @@ -0,0 +1,31 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_income_based_copay(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Mississippi CCPP monthly income-based co-payment" + definition_period = MONTH + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=41" + + def formula(spm_unit, period, parameters): + # NOTE: Applies the published rate to exact monthly income, not to the + # fee scale's rounded $1,000 income rows. + p = parameters(period).gov.states.ms.dhs.ccpp.copay + p_income = parameters(period).gov.states.ms.dhs.ccpp.income + monthly_income = max_(spm_unit("ms_ccpp_countable_income", period), 0) + fee_scale_size = min_( + spm_unit("spm_unit_size", period.this_year), p.max_family_size + ) + monthly_smi = spm_unit("hhs_smi", period) + very_low_income = ( + monthly_income <= monthly_smi * p_income.very_low_income_smi_rate + ) + copay_rate = where( + very_low_income, + p.rate.very_low_income.calc(fee_scale_size), + p.rate.low_income.calc(fee_scale_size), + ) + return monthly_income * copay_rate diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_minimum_fee_category.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_minimum_fee_category.py new file mode 100644 index 00000000000..ea117ad8145 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/copay/ms_ccpp_minimum_fee_category.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_minimum_fee_category(Variable): + value_type = bool + entity = SPMUnit + label = "Mississippi CCPP minimum-fee category" + definition_period = MONTH + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=41" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ms.dhs.ccpp.eligibility + person = spm_unit.members + has_protective_child = spm_unit.any( + person("receives_or_needs_protective_services", period.this_year) + ) + is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) + has_ssi_disabled_parent = spm_unit.any( + is_head_or_spouse + & person("is_ssi_disabled", period.this_year) + & (person("ssi", period) > 0) + ) + age = person("age", period.this_year) + has_special_needs_child = spm_unit.any( + person("is_tax_unit_dependent", period.this_year) + & person("is_disabled", period.this_year) + & (age < p.special_needs_child_age_limit) + ) + return has_protective_child | has_ssi_disabled_parent | has_special_needs_child diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_earned_income.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_earned_income.py new file mode 100644 index 00000000000..e36dd33cccc --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_earned_income.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class ms_ccpp_countable_earned_income(Variable): + value_type = float + entity = Person + label = "Mississippi CCPP countable earned income" + definition_period = MONTH + unit = USD + defined_for = StateCode.MS + reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=28" + + def formula(person, period, parameters): + p = parameters(period).gov.states.ms.dhs.ccpp.income + # Rule 5.4: earned income of students under 18 is non-countable; the + # countable wage list applies to adults only. + age = person("age", period.this_year) + is_excluded_student = person("is_in_k12_school", period.this_year) & ( + age < p.student_earner_age_limit + ) + # Self-employment is counted as gross (Rule 5.3); a net business loss + # does not offset other income, so floor the self-employment sum at zero. + self_employment = max_( + add(person, period, p.countable_income.self_employment_sources), 0 + ) + earned = person("employment_income", period) + self_employment + return where(is_excluded_student, 0, earned) diff --git a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py index 35c9813dbac..350c6669976 100644 --- a/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py +++ b/policyengine_us/variables/gov/states/ms/dhs/ccpp/ms_ccpp_countable_income.py @@ -10,4 +10,8 @@ class ms_ccpp_countable_income(Variable): defined_for = StateCode.MS reference = "https://www.mdhs.ms.gov/wp-content/uploads/2026/01/CCPP-Policy-Manual_Final_1142025.pdf#page=28" - adds = "gov.states.ms.dhs.ccpp.income.countable_income.sources" + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ms.dhs.ccpp.income + earned = add(spm_unit, period, ["ms_ccpp_countable_earned_income"]) + unearned = add(spm_unit, period, p.countable_income.unearned_sources) + return earned + unearned