From 5a44f14512bdc0b9d5d4f309d0e4211b1da899df Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 14 May 2026 22:33:17 -0400 Subject: [PATCH 01/15] Initial commit for AL CCAP implementation Closes #8321 From 12c0c03cd751fbcb7a700135dbaeeed3bd1720bc Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 14 May 2026 22:33:46 -0400 Subject: [PATCH 02/15] Add changelog fragment for AL CCAP Closes #8321 --- changelog.d/al-ccap.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/al-ccap.added.md diff --git a/changelog.d/al-ccap.added.md b/changelog.d/al-ccap.added.md new file mode 100644 index 00000000000..0f3a56619fe --- /dev/null +++ b/changelog.d/al-ccap.added.md @@ -0,0 +1 @@ +Added Alabama Child Care Assistance Program (CCAP). From b6246b83906af89ca460829ae13d2721b990af9f Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 14 May 2026 23:40:09 -0400 Subject: [PATCH 03/15] Implement Alabama Child Care Subsidy Program (CCSP) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #8321 - 16 parameter files including 486-cell rate matrix (provider × region × age × STAR tier) - 16 variables covering eligibility (180% FPL initial / 200% FPL continuing / 85% SMI cap), triple-test income, dual-tier copay table, multi-dimensional rate lookup, and waiver paths - 14 test YAML files (103 cases) covering unit + integration + edge cases - Registered in programs.yaml and federal CCDF child_care_subsidy_programs.yaml Co-Authored-By: Claude Opus 4.7 (1M context) --- changelog.d/al-ccap.added.md | 2 +- .../hhs/ccdf/child_care_subsidy_programs.yaml | 1 + .../al/dhr/ccsp/age_category/months.yaml | 30 + .../dhr/ccsp/copay/continuing_fee_by_fpl.yaml | 25 + .../al/dhr/ccsp/copay/initial_fee_by_fpl.yaml | 51 + .../eligibility/activity_hours_minimum.yaml | 11 + .../dhr/ccsp/eligibility/child_age_limit.yaml | 11 + .../eligibility/disabled_child_age_limit.yaml | 11 + .../income_limit_fpl_continuing.yaml | 13 + .../eligibility/income_limit_fpl_initial.yaml | 13 + .../eligibility/income_limit_smi_cap.yaml | 15 + .../ccsp/income/countable_income/sources.yaml | 33 + .../al/dhr/ccsp/income/weeks_to_months.yaml | 11 + .../ccsp/rates/full_time_hours_threshold.yaml | 11 + .../dhr/ccsp/rates/informal_weekly_cap.yaml | 11 + .../ccsp/rates/maximum_weekly_full_time.yaml | 1100 +++++++++++++++++ .../dhr/ccsp/rates/part_time_multiplier.yaml | 11 + .../states/al/dhr/ccsp/region/counties.yaml | 97 ++ policyengine_us/programs.yaml | 8 +- .../gov/states/al/dhr/ccsp/al_ccsp.yaml | 156 +++ .../dhr/ccsp/al_ccsp_activity_eligible.yaml | 210 ++++ .../al/dhr/ccsp/al_ccsp_age_category.yaml | 80 ++ .../gov/states/al/dhr/ccsp/al_ccsp_copay.yaml | 337 +++++ .../al/dhr/ccsp/al_ccsp_countable_income.yaml | 128 ++ .../states/al/dhr/ccsp/al_ccsp_eligible.yaml | 293 +++++ .../al/dhr/ccsp/al_ccsp_eligible_child.yaml | 215 ++++ .../al/dhr/ccsp/al_ccsp_income_eligible.yaml | 165 +++ .../dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml | 203 +++ .../dhr/ccsp/al_ccsp_protective_services.yaml | 71 ++ .../states/al/dhr/ccsp/al_ccsp_region.yaml | 128 ++ .../al/dhr/ccsp/al_child_care_subsidies.yaml | 69 ++ .../gov/states/al/dhr/ccsp/edge_cases.yaml | 442 +++++++ .../gov/states/al/dhr/ccsp/integration.yaml | 436 +++++++ .../gov/states/al/dhr/ccsp/al_ccsp.py | 65 + .../al/dhr/ccsp/al_ccsp_age_category.py | 27 + .../al/dhr/ccsp/al_ccsp_countable_income.py | 16 + .../states/al/dhr/ccsp/al_ccsp_enrolled.py | 13 + .../al/dhr/ccsp/al_ccsp_provider_type.py | 22 + .../al/dhr/ccsp/al_ccsp_quality_tier.py | 24 + .../gov/states/al/dhr/ccsp/al_ccsp_region.py | 61 + .../al/dhr/ccsp/al_child_care_subsidies.py | 11 + .../states/al/dhr/ccsp/copay/al_ccsp_copay.py | 53 + .../copay/al_ccsp_weekly_copay_per_child.py | 30 + .../eligibility/al_ccsp_activity_eligible.py | 28 + .../dhr/ccsp/eligibility/al_ccsp_eligible.py | 32 + .../eligibility/al_ccsp_eligible_child.py | 28 + .../eligibility/al_ccsp_income_eligible.py | 35 + .../al_ccsp_protective_services.py | 22 + .../payment/al_ccsp_maximum_weekly_rate.py | 57 + 49 files changed, 4920 insertions(+), 2 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/continuing_fee_by_fpl.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/initial_fee_by_fpl.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/activity_hours_minimum.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/child_age_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/disabled_child_age_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_smi_cap.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/income/weeks_to_months.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml create mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_protective_services.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_region.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_child_care_subsidies.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_countable_income.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/al_child_care_subsidies.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py diff --git a/changelog.d/al-ccap.added.md b/changelog.d/al-ccap.added.md index 0f3a56619fe..ed6369b8bac 100644 --- a/changelog.d/al-ccap.added.md +++ b/changelog.d/al-ccap.added.md @@ -1 +1 @@ -Added Alabama Child Care Assistance Program (CCAP). +Added Alabama Child Care Subsidy Program (CCSP). 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 89dc3c0bef2..0a7bc3e02d8 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 @@ -1,6 +1,7 @@ description: The federal government counts these state programs as child care subsidies. values: 2021-01-01: + - al_child_care_subsidies # Alabama Child Care Subsidy Program - ca_child_care_subsidies # California Child Care - co_child_care_subsidies # Colorado Child Care Assistance Program - ct_child_care_subsidies # Connecticut Care 4 Kids diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml new file mode 100644 index 00000000000..11b891b8e35 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml @@ -0,0 +1,30 @@ +description: Alabama assigns a Child Care Subsidy Program age category from the child's age in months. +# 0 = INFANT_TODDLER (birth to 36 months) +# 1 = PRESCHOOL (36 months to 5 years) +# 2 = SCHOOL_AGE (5 years and older) + +metadata: + type: single_amount + threshold_unit: month + amount_unit: /1 + period: year + label: Alabama CCSP age category by age in months + reference: + - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Key to Care Level + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf + - title: Alabama CCDF State Plan 2025-2027, Section 2.2 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20 + +brackets: + - threshold: + 2024-01-01: 0 + amount: + 2024-01-01: 0 + - threshold: + 2024-01-01: 36 + amount: + 2024-01-01: 1 + - threshold: + 2024-01-01: 60 + amount: + 2024-01-01: 2 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/continuing_fee_by_fpl.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/continuing_fee_by_fpl.yaml new file mode 100644 index 00000000000..6e8c260b328 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/continuing_fee_by_fpl.yaml @@ -0,0 +1,25 @@ +description: Alabama sets this weekly per-child fee for continuing-eligibility families under the Child Care Subsidy Program, indexed to the family's share of the federal poverty guideline. + +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: week + label: Alabama CCSP continuing weekly per-child fee by FPL ratio + reference: + - title: Alabama Child Care Fact Sheet (Continuing Eligibility Monthly Income Scale) + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf + +brackets: + - threshold: + 2024-01-01: 0 + amount: + 2024-01-01: 0 + - threshold: + 2024-01-01: 1.8001 + amount: + 2024-01-01: 42 + - threshold: + 2024-01-01: 1.9001 + amount: + 2024-01-01: 45 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/initial_fee_by_fpl.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/initial_fee_by_fpl.yaml new file mode 100644 index 00000000000..7fb604406f0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/initial_fee_by_fpl.yaml @@ -0,0 +1,51 @@ +description: Alabama sets this weekly per-child fee for initially-eligible families under the Child Care Subsidy Program, indexed to the family's share of the federal poverty guideline. + +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: week + label: Alabama CCSP initial weekly per-child fee by FPL ratio + reference: + - title: Alabama Child Care Fact Sheet (Initial Eligibility Monthly Income Scale and Parental Fee Chart) + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf + - title: Alabama CCDF State Plan 2025-2027, Section 3.2.1 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=42 + +brackets: + - threshold: + 2024-01-01: 0 + amount: + 2024-01-01: 0 + - threshold: + 2024-01-01: 1.0001 + amount: + 2024-01-01: 18 + - threshold: + 2024-01-01: 1.1001 + amount: + 2024-01-01: 21 + - threshold: + 2024-01-01: 1.2001 + amount: + 2024-01-01: 24 + - threshold: + 2024-01-01: 1.3001 + amount: + 2024-01-01: 27 + - threshold: + 2024-01-01: 1.4001 + amount: + 2024-01-01: 30 + - threshold: + 2024-01-01: 1.5001 + amount: + 2024-01-01: 33 + - threshold: + 2024-01-01: 1.6001 + amount: + 2024-01-01: 36 + - threshold: + 2024-01-01: 1.7001 + amount: + 2024-01-01: 39 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/activity_hours_minimum.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/activity_hours_minimum.yaml new file mode 100644 index 00000000000..16652aa50dd --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/activity_hours_minimum.yaml @@ -0,0 +1,11 @@ +description: Alabama requires at least this many combined weekly hours of work, training, or education for Child Care Subsidy Program activity eligibility. +values: + 2024-01-01: 15 + +metadata: + unit: hour + period: year + label: Alabama CCSP minimum weekly activity hours + reference: + - title: Alabama CCDF State Plan 2025-2027, Section 2.2.2 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=21 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/child_age_limit.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/child_age_limit.yaml new file mode 100644 index 00000000000..8c503c8d7b7 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/child_age_limit.yaml @@ -0,0 +1,11 @@ +description: Alabama limits the Child Care Subsidy Program to children younger than this age. +values: + 2024-01-01: 13 + +metadata: + unit: year + period: year + label: Alabama CCSP child age limit + reference: + - title: Alabama CCDF State Plan 2025-2027, Section 2.2 / 2.2.1 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/disabled_child_age_limit.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/disabled_child_age_limit.yaml new file mode 100644 index 00000000000..4d4e3a6b755 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/disabled_child_age_limit.yaml @@ -0,0 +1,11 @@ +description: Alabama limits the Child Care Subsidy Program to disabled children younger than this age. +values: + 2024-01-01: 19 + +metadata: + unit: year + period: year + label: Alabama CCSP disabled child age limit + reference: + - title: Alabama CCDF State Plan 2025-2027, Section 2.2.1 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml new file mode 100644 index 00000000000..1e3991d0323 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml @@ -0,0 +1,13 @@ +description: Alabama caps continuing-eligibility family income at this share of the federal poverty guideline under the Child Care Subsidy Program. +values: + 2024-01-01: 2.0 + +metadata: + unit: /1 + period: year + label: Alabama CCSP continuing income limit (share of federal poverty guideline) + reference: + - title: Alabama CCDF State Plan 2025-2027, Section 2.2.4 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39 + - title: Alabama Child Care Fact Sheet + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml new file mode 100644 index 00000000000..a2483a72586 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml @@ -0,0 +1,13 @@ +description: Alabama caps initial-application family income at this share of the federal poverty guideline under the Child Care Subsidy Program. +values: + 2024-01-01: 1.8 + +metadata: + unit: /1 + period: year + label: Alabama CCSP initial income limit (share of federal poverty guideline) + reference: + - title: Alabama CCDF State Plan 2025-2027, Section 2.2.4 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=24 + - title: Alabama Child Care Fact Sheet (Initial Eligibility Monthly Income Scale) + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_smi_cap.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_smi_cap.yaml new file mode 100644 index 00000000000..78ea014150e --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_smi_cap.yaml @@ -0,0 +1,15 @@ +description: Alabama caps Child Care Subsidy Program eligibility at this share of state median income, terminating participation prior to the 12-month review when exceeded. +values: + 2024-01-01: 0.85 + +metadata: + unit: /1 + period: year + label: Alabama CCSP income cap (share of state median income) + reference: + - title: Alabama CCDF State Plan 2025-2027, Section 2.2.4 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=24 + - title: Alabama CCDF State Plan 2025-2027, Section 2.5.2 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=35 + - title: Alabama Child Care Fact Sheet (Income Cutoff 85% SMI) + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml new file mode 100644 index 00000000000..dcfe85c4518 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml @@ -0,0 +1,33 @@ +description: Alabama counts these income sources under the Child Care Subsidy Program. +values: + 2024-01-01: + - employment_income + - self_employment_income + - farm_operations_income + - social_security + - pension_income + - unemployment_compensation + - workers_compensation + - ssi + - al_ssp + - interest_income + - dividend_income + - alimony_income + - veterans_benefits + # TANF is excluded from the adds list to break a CCSP <-> TANF + # circular dependency through childcare_expenses. Operationally, + # families enrolled in TANF rarely reach the CCSP income test + # because TANF payment standards fall well below 180% FPL. + # - tanf + # Section 2.2.4(c) also lists inheritance and college work-study, + # but no matching variables exist in policyengine-us at this time. + +metadata: + unit: list + period: year + label: Alabama CCSP countable income sources + reference: + - title: Alabama CCDF State Plan 2025-2027, Section 2.2.4(c) + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=26 + - title: Alabama Child Care Fact Sheet + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/weeks_to_months.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/weeks_to_months.yaml new file mode 100644 index 00000000000..d0433f2a2b8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/weeks_to_months.yaml @@ -0,0 +1,11 @@ +description: Alabama multiplies weekly amounts by this factor to convert to monthly amounts under the Child Care Subsidy Program. +values: + 2024-01-01: 4.333 + +metadata: + unit: /1 + period: year + label: Alabama CCSP weekly-to-monthly conversion factor + reference: + - title: Alabama Child Care Fact Sheet (weekly gross income multiplied by 4.333) + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml new file mode 100644 index 00000000000..c22a355d3e9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml @@ -0,0 +1,11 @@ +description: Alabama treats child care services averaging more than this many weekly hours as full-time under the Child Care Subsidy Program. +values: + 2024-01-01: 25 + +metadata: + unit: hour + period: year + label: Alabama CCSP full-time weekly hours threshold + reference: + - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart (Full-time / Part-time Rates note) + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml new file mode 100644 index 00000000000..44271c98a2a --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml @@ -0,0 +1,11 @@ +description: Alabama caps the weekly reimbursement rate for informal (license-exempt) child care providers under the Child Care Subsidy Program. +values: + 2024-01-01: 40 + +metadata: + unit: currency-USD + period: week + label: Alabama CCSP informal-provider weekly rate cap + reference: + - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart (Informal care providers cap) + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml new file mode 100644 index 00000000000..1c69c12cbf1 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml @@ -0,0 +1,1100 @@ +description: Alabama sets these maximum weekly full-time provider reimbursement rates under the Child Care Subsidy Program, indexed by provider type, region, age category, and quality tier. + +metadata: + period: week + unit: currency-USD + label: Alabama CCSP maximum weekly full-time provider rates + breakdown: + - al_ccsp_provider_type + - al_ccsp_region + - al_ccsp_age_category + - al_ccsp_quality_tier + reference: + - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Maximum Weekly Full-time Rates + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf + +CENTER: + HUNTSVILLE: + INFANT_TODDLER: + BASE: + 2024-01-01: 138 + STAR_1: + 2024-01-01: 141 + STAR_2: + 2024-01-01: 144 + STAR_3: + 2024-01-01: 146 + STAR_4: + 2024-01-01: 149 + STAR_5: + 2024-01-01: 152 + PRESCHOOL: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + SCHOOL_AGE: + BASE: + 2024-01-01: 105 + STAR_1: + 2024-01-01: 107 + STAR_2: + 2024-01-01: 109 + STAR_3: + 2024-01-01: 111 + STAR_4: + 2024-01-01: 114 + STAR_5: + 2024-01-01: 116 + TUSCALOOSA: + INFANT_TODDLER: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + PRESCHOOL: + BASE: + 2024-01-01: 120 + STAR_1: + 2024-01-01: 122 + STAR_2: + 2024-01-01: 125 + STAR_3: + 2024-01-01: 127 + STAR_4: + 2024-01-01: 130 + STAR_5: + 2024-01-01: 132 + SCHOOL_AGE: + BASE: + 2024-01-01: 115 + STAR_1: + 2024-01-01: 117 + STAR_2: + 2024-01-01: 120 + STAR_3: + 2024-01-01: 122 + STAR_4: + 2024-01-01: 124 + STAR_5: + 2024-01-01: 127 + MOBILE: + INFANT_TODDLER: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + PRESCHOOL: + BASE: + 2024-01-01: 117 + STAR_1: + 2024-01-01: 119 + STAR_2: + 2024-01-01: 122 + STAR_3: + 2024-01-01: 124 + STAR_4: + 2024-01-01: 127 + STAR_5: + 2024-01-01: 129 + SCHOOL_AGE: + BASE: + 2024-01-01: 110 + STAR_1: + 2024-01-01: 112 + STAR_2: + 2024-01-01: 114 + STAR_3: + 2024-01-01: 117 + STAR_4: + 2024-01-01: 119 + STAR_5: + 2024-01-01: 121 + FT_PAYNE: + INFANT_TODDLER: + BASE: + 2024-01-01: 112 + STAR_1: + 2024-01-01: 114 + STAR_2: + 2024-01-01: 117 + STAR_3: + 2024-01-01: 119 + STAR_4: + 2024-01-01: 121 + STAR_5: + 2024-01-01: 124 + PRESCHOOL: + BASE: + 2024-01-01: 105 + STAR_1: + 2024-01-01: 107 + STAR_2: + 2024-01-01: 109 + STAR_3: + 2024-01-01: 111 + STAR_4: + 2024-01-01: 114 + STAR_5: + 2024-01-01: 116 + SCHOOL_AGE: + BASE: + 2024-01-01: 97 + STAR_1: + 2024-01-01: 99 + STAR_2: + 2024-01-01: 101 + STAR_3: + 2024-01-01: 103 + STAR_4: + 2024-01-01: 105 + STAR_5: + 2024-01-01: 107 + BIRMINGHAM: + INFANT_TODDLER: + BASE: + 2024-01-01: 150 + STAR_1: + 2024-01-01: 153 + STAR_2: + 2024-01-01: 156 + STAR_3: + 2024-01-01: 159 + STAR_4: + 2024-01-01: 162 + STAR_5: + 2024-01-01: 166 + PRESCHOOL: + BASE: + 2024-01-01: 138 + STAR_1: + 2024-01-01: 141 + STAR_2: + 2024-01-01: 144 + STAR_3: + 2024-01-01: 146 + STAR_4: + 2024-01-01: 149 + STAR_5: + 2024-01-01: 152 + SCHOOL_AGE: + BASE: + 2024-01-01: 115 + STAR_1: + 2024-01-01: 117 + STAR_2: + 2024-01-01: 120 + STAR_3: + 2024-01-01: 122 + STAR_4: + 2024-01-01: 124 + STAR_5: + 2024-01-01: 127 + TALLADEGA: + INFANT_TODDLER: + BASE: + 2024-01-01: 111 + STAR_1: + 2024-01-01: 113 + STAR_2: + 2024-01-01: 115 + STAR_3: + 2024-01-01: 118 + STAR_4: + 2024-01-01: 120 + STAR_5: + 2024-01-01: 123 + PRESCHOOL: + BASE: + 2024-01-01: 111 + STAR_1: + 2024-01-01: 113 + STAR_2: + 2024-01-01: 115 + STAR_3: + 2024-01-01: 118 + STAR_4: + 2024-01-01: 120 + STAR_5: + 2024-01-01: 123 + SCHOOL_AGE: + BASE: + 2024-01-01: 93 + STAR_1: + 2024-01-01: 95 + STAR_2: + 2024-01-01: 97 + STAR_3: + 2024-01-01: 99 + STAR_4: + 2024-01-01: 101 + STAR_5: + 2024-01-01: 103 + MONTGOMERY: + INFANT_TODDLER: + BASE: + 2024-01-01: 131 + STAR_1: + 2024-01-01: 134 + STAR_2: + 2024-01-01: 136 + STAR_3: + 2024-01-01: 139 + STAR_4: + 2024-01-01: 142 + STAR_5: + 2024-01-01: 145 + PRESCHOOL: + BASE: + 2024-01-01: 115 + STAR_1: + 2024-01-01: 117 + STAR_2: + 2024-01-01: 120 + STAR_3: + 2024-01-01: 122 + STAR_4: + 2024-01-01: 124 + STAR_5: + 2024-01-01: 127 + SCHOOL_AGE: + BASE: + 2024-01-01: 116 + STAR_1: + 2024-01-01: 118 + STAR_2: + 2024-01-01: 121 + STAR_3: + 2024-01-01: 123 + STAR_4: + 2024-01-01: 126 + STAR_5: + 2024-01-01: 128 + DOTHAN: + INFANT_TODDLER: + BASE: + 2024-01-01: 107 + STAR_1: + 2024-01-01: 109 + STAR_2: + 2024-01-01: 111 + STAR_3: + 2024-01-01: 114 + STAR_4: + 2024-01-01: 116 + STAR_5: + 2024-01-01: 118 + PRESCHOOL: + BASE: + 2024-01-01: 102 + STAR_1: + 2024-01-01: 104 + STAR_2: + 2024-01-01: 106 + STAR_3: + 2024-01-01: 108 + STAR_4: + 2024-01-01: 110 + STAR_5: + 2024-01-01: 113 + SCHOOL_AGE: + BASE: + 2024-01-01: 95 + STAR_1: + 2024-01-01: 97 + STAR_2: + 2024-01-01: 99 + STAR_3: + 2024-01-01: 101 + STAR_4: + 2024-01-01: 103 + STAR_5: + 2024-01-01: 105 + OPELIKA: + INFANT_TODDLER: + BASE: + 2024-01-01: 132 + STAR_1: + 2024-01-01: 135 + STAR_2: + 2024-01-01: 137 + STAR_3: + 2024-01-01: 140 + STAR_4: + 2024-01-01: 143 + STAR_5: + 2024-01-01: 146 + PRESCHOOL: + BASE: + 2024-01-01: 120 + STAR_1: + 2024-01-01: 122 + STAR_2: + 2024-01-01: 125 + STAR_3: + 2024-01-01: 127 + STAR_4: + 2024-01-01: 130 + STAR_5: + 2024-01-01: 132 + SCHOOL_AGE: + BASE: + 2024-01-01: 109 + STAR_1: + 2024-01-01: 111 + STAR_2: + 2024-01-01: 113 + STAR_3: + 2024-01-01: 116 + STAR_4: + 2024-01-01: 118 + STAR_5: + 2024-01-01: 120 + +GFDC: + HUNTSVILLE: + INFANT_TODDLER: + BASE: + 2024-01-01: 132 + STAR_1: + 2024-01-01: 135 + STAR_2: + 2024-01-01: 137 + STAR_3: + 2024-01-01: 140 + STAR_4: + 2024-01-01: 143 + STAR_5: + 2024-01-01: 146 + PRESCHOOL: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + SCHOOL_AGE: + BASE: + 2024-01-01: 124 + STAR_1: + 2024-01-01: 126 + STAR_2: + 2024-01-01: 129 + STAR_3: + 2024-01-01: 132 + STAR_4: + 2024-01-01: 134 + STAR_5: + 2024-01-01: 137 + TUSCALOOSA: + INFANT_TODDLER: + BASE: + 2024-01-01: 91 + STAR_1: + 2024-01-01: 93 + STAR_2: + 2024-01-01: 95 + STAR_3: + 2024-01-01: 97 + STAR_4: + 2024-01-01: 99 + STAR_5: + 2024-01-01: 100 + PRESCHOOL: + BASE: + 2024-01-01: 93 + STAR_1: + 2024-01-01: 95 + STAR_2: + 2024-01-01: 97 + STAR_3: + 2024-01-01: 99 + STAR_4: + 2024-01-01: 101 + STAR_5: + 2024-01-01: 103 + SCHOOL_AGE: + BASE: + 2024-01-01: 93 + STAR_1: + 2024-01-01: 95 + STAR_2: + 2024-01-01: 97 + STAR_3: + 2024-01-01: 99 + STAR_4: + 2024-01-01: 101 + STAR_5: + 2024-01-01: 103 + MOBILE: + INFANT_TODDLER: + BASE: + 2024-01-01: 122 + STAR_1: + 2024-01-01: 124 + STAR_2: + 2024-01-01: 127 + STAR_3: + 2024-01-01: 129 + STAR_4: + 2024-01-01: 132 + STAR_5: + 2024-01-01: 135 + PRESCHOOL: + BASE: + 2024-01-01: 123 + STAR_1: + 2024-01-01: 125 + STAR_2: + 2024-01-01: 128 + STAR_3: + 2024-01-01: 131 + STAR_4: + 2024-01-01: 133 + STAR_5: + 2024-01-01: 136 + SCHOOL_AGE: + BASE: + 2024-01-01: 111 + STAR_1: + 2024-01-01: 113 + STAR_2: + 2024-01-01: 115 + STAR_3: + 2024-01-01: 118 + STAR_4: + 2024-01-01: 120 + STAR_5: + 2024-01-01: 123 + FT_PAYNE: + INFANT_TODDLER: + BASE: + 2024-01-01: 85 + STAR_1: + 2024-01-01: 87 + STAR_2: + 2024-01-01: 88 + STAR_3: + 2024-01-01: 90 + STAR_4: + 2024-01-01: 92 + STAR_5: + 2024-01-01: 94 + PRESCHOOL: + BASE: + 2024-01-01: 85 + STAR_1: + 2024-01-01: 87 + STAR_2: + 2024-01-01: 88 + STAR_3: + 2024-01-01: 90 + STAR_4: + 2024-01-01: 92 + STAR_5: + 2024-01-01: 94 + SCHOOL_AGE: + BASE: + 2024-01-01: 88 + STAR_1: + 2024-01-01: 90 + STAR_2: + 2024-01-01: 92 + STAR_3: + 2024-01-01: 93 + STAR_4: + 2024-01-01: 95 + STAR_5: + 2024-01-01: 97 + BIRMINGHAM: + INFANT_TODDLER: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + PRESCHOOL: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + SCHOOL_AGE: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + TALLADEGA: + INFANT_TODDLER: + BASE: + 2024-01-01: 100 + STAR_1: + 2024-01-01: 102 + STAR_2: + 2024-01-01: 104 + STAR_3: + 2024-01-01: 106 + STAR_4: + 2024-01-01: 108 + STAR_5: + 2024-01-01: 110 + PRESCHOOL: + BASE: + 2024-01-01: 100 + STAR_1: + 2024-01-01: 102 + STAR_2: + 2024-01-01: 104 + STAR_3: + 2024-01-01: 106 + STAR_4: + 2024-01-01: 108 + STAR_5: + 2024-01-01: 110 + SCHOOL_AGE: + BASE: + 2024-01-01: 100 + STAR_1: + 2024-01-01: 102 + STAR_2: + 2024-01-01: 104 + STAR_3: + 2024-01-01: 106 + STAR_4: + 2024-01-01: 108 + STAR_5: + 2024-01-01: 110 + MONTGOMERY: + INFANT_TODDLER: + BASE: + 2024-01-01: 95 + STAR_1: + 2024-01-01: 97 + STAR_2: + 2024-01-01: 99 + STAR_3: + 2024-01-01: 101 + STAR_4: + 2024-01-01: 103 + STAR_5: + 2024-01-01: 105 + PRESCHOOL: + BASE: + 2024-01-01: 95 + STAR_1: + 2024-01-01: 97 + STAR_2: + 2024-01-01: 99 + STAR_3: + 2024-01-01: 101 + STAR_4: + 2024-01-01: 103 + STAR_5: + 2024-01-01: 105 + SCHOOL_AGE: + BASE: + 2024-01-01: 95 + STAR_1: + 2024-01-01: 97 + STAR_2: + 2024-01-01: 99 + STAR_3: + 2024-01-01: 101 + STAR_4: + 2024-01-01: 103 + STAR_5: + 2024-01-01: 105 + DOTHAN: + INFANT_TODDLER: + BASE: + 2024-01-01: 100 + STAR_1: + 2024-01-01: 102 + STAR_2: + 2024-01-01: 104 + STAR_3: + 2024-01-01: 106 + STAR_4: + 2024-01-01: 108 + STAR_5: + 2024-01-01: 110 + PRESCHOOL: + BASE: + 2024-01-01: 100 + STAR_1: + 2024-01-01: 102 + STAR_2: + 2024-01-01: 104 + STAR_3: + 2024-01-01: 106 + STAR_4: + 2024-01-01: 108 + STAR_5: + 2024-01-01: 110 + SCHOOL_AGE: + BASE: + 2024-01-01: 100 + STAR_1: + 2024-01-01: 102 + STAR_2: + 2024-01-01: 104 + STAR_3: + 2024-01-01: 106 + STAR_4: + 2024-01-01: 108 + STAR_5: + 2024-01-01: 110 + OPELIKA: + INFANT_TODDLER: + BASE: + 2024-01-01: 128 + STAR_1: + 2024-01-01: 131 + STAR_2: + 2024-01-01: 133 + STAR_3: + 2024-01-01: 136 + STAR_4: + 2024-01-01: 139 + STAR_5: + 2024-01-01: 141 + PRESCHOOL: + BASE: + 2024-01-01: 123 + STAR_1: + 2024-01-01: 125 + STAR_2: + 2024-01-01: 128 + STAR_3: + 2024-01-01: 131 + STAR_4: + 2024-01-01: 133 + STAR_5: + 2024-01-01: 136 + SCHOOL_AGE: + BASE: + 2024-01-01: 115 + STAR_1: + 2024-01-01: 117 + STAR_2: + 2024-01-01: 120 + STAR_3: + 2024-01-01: 122 + STAR_4: + 2024-01-01: 124 + STAR_5: + 2024-01-01: 127 + +FDC: + HUNTSVILLE: + INFANT_TODDLER: + BASE: + 2024-01-01: 135 + STAR_1: + 2024-01-01: 138 + STAR_2: + 2024-01-01: 140 + STAR_3: + 2024-01-01: 143 + STAR_4: + 2024-01-01: 146 + STAR_5: + 2024-01-01: 149 + PRESCHOOL: + BASE: + 2024-01-01: 131 + STAR_1: + 2024-01-01: 134 + STAR_2: + 2024-01-01: 136 + STAR_3: + 2024-01-01: 139 + STAR_4: + 2024-01-01: 142 + STAR_5: + 2024-01-01: 145 + SCHOOL_AGE: + BASE: + 2024-01-01: 130 + STAR_1: + 2024-01-01: 133 + STAR_2: + 2024-01-01: 135 + STAR_3: + 2024-01-01: 138 + STAR_4: + 2024-01-01: 141 + STAR_5: + 2024-01-01: 144 + TUSCALOOSA: + INFANT_TODDLER: + BASE: + 2024-01-01: 105 + STAR_1: + 2024-01-01: 107 + STAR_2: + 2024-01-01: 109 + STAR_3: + 2024-01-01: 111 + STAR_4: + 2024-01-01: 114 + STAR_5: + 2024-01-01: 116 + PRESCHOOL: + BASE: + 2024-01-01: 100 + STAR_1: + 2024-01-01: 102 + STAR_2: + 2024-01-01: 104 + STAR_3: + 2024-01-01: 106 + STAR_4: + 2024-01-01: 108 + STAR_5: + 2024-01-01: 110 + SCHOOL_AGE: + BASE: + 2024-01-01: 100 + STAR_1: + 2024-01-01: 102 + STAR_2: + 2024-01-01: 104 + STAR_3: + 2024-01-01: 106 + STAR_4: + 2024-01-01: 108 + STAR_5: + 2024-01-01: 110 + MOBILE: + INFANT_TODDLER: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + PRESCHOOL: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + SCHOOL_AGE: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + FT_PAYNE: + INFANT_TODDLER: + BASE: + 2024-01-01: 81 + STAR_1: + 2024-01-01: 83 + STAR_2: + 2024-01-01: 84 + STAR_3: + 2024-01-01: 86 + STAR_4: + 2024-01-01: 88 + STAR_5: + 2024-01-01: 89 + PRESCHOOL: + BASE: + 2024-01-01: 75 + STAR_1: + 2024-01-01: 77 + STAR_2: + 2024-01-01: 78 + STAR_3: + 2024-01-01: 80 + STAR_4: + 2024-01-01: 81 + STAR_5: + 2024-01-01: 83 + SCHOOL_AGE: + BASE: + 2024-01-01: 75 + STAR_1: + 2024-01-01: 77 + STAR_2: + 2024-01-01: 78 + STAR_3: + 2024-01-01: 80 + STAR_4: + 2024-01-01: 81 + STAR_5: + 2024-01-01: 83 + BIRMINGHAM: + INFANT_TODDLER: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 + PRESCHOOL: + BASE: + 2024-01-01: 120 + STAR_1: + 2024-01-01: 122 + STAR_2: + 2024-01-01: 125 + STAR_3: + 2024-01-01: 127 + STAR_4: + 2024-01-01: 130 + STAR_5: + 2024-01-01: 132 + SCHOOL_AGE: + BASE: + 2024-01-01: 110 + STAR_1: + 2024-01-01: 112 + STAR_2: + 2024-01-01: 114 + STAR_3: + 2024-01-01: 117 + STAR_4: + 2024-01-01: 119 + STAR_5: + 2024-01-01: 121 + TALLADEGA: + INFANT_TODDLER: + BASE: + 2024-01-01: 98 + STAR_1: + 2024-01-01: 100 + STAR_2: + 2024-01-01: 102 + STAR_3: + 2024-01-01: 104 + STAR_4: + 2024-01-01: 106 + STAR_5: + 2024-01-01: 108 + PRESCHOOL: + BASE: + 2024-01-01: 99 + STAR_1: + 2024-01-01: 101 + STAR_2: + 2024-01-01: 103 + STAR_3: + 2024-01-01: 105 + STAR_4: + 2024-01-01: 107 + STAR_5: + 2024-01-01: 109 + SCHOOL_AGE: + BASE: + 2024-01-01: 90 + STAR_1: + 2024-01-01: 92 + STAR_2: + 2024-01-01: 94 + STAR_3: + 2024-01-01: 96 + STAR_4: + 2024-01-01: 97 + STAR_5: + 2024-01-01: 99 + MONTGOMERY: + INFANT_TODDLER: + BASE: + 2024-01-01: 122 + STAR_1: + 2024-01-01: 124 + STAR_2: + 2024-01-01: 127 + STAR_3: + 2024-01-01: 129 + STAR_4: + 2024-01-01: 132 + STAR_5: + 2024-01-01: 135 + PRESCHOOL: + BASE: + 2024-01-01: 115 + STAR_1: + 2024-01-01: 117 + STAR_2: + 2024-01-01: 120 + STAR_3: + 2024-01-01: 122 + STAR_4: + 2024-01-01: 124 + STAR_5: + 2024-01-01: 127 + SCHOOL_AGE: + BASE: + 2024-01-01: 115 + STAR_1: + 2024-01-01: 117 + STAR_2: + 2024-01-01: 120 + STAR_3: + 2024-01-01: 122 + STAR_4: + 2024-01-01: 124 + STAR_5: + 2024-01-01: 127 + DOTHAN: + INFANT_TODDLER: + BASE: + 2024-01-01: 90 + STAR_1: + 2024-01-01: 92 + STAR_2: + 2024-01-01: 94 + STAR_3: + 2024-01-01: 96 + STAR_4: + 2024-01-01: 97 + STAR_5: + 2024-01-01: 99 + PRESCHOOL: + BASE: + 2024-01-01: 90 + STAR_1: + 2024-01-01: 92 + STAR_2: + 2024-01-01: 94 + STAR_3: + 2024-01-01: 96 + STAR_4: + 2024-01-01: 97 + STAR_5: + 2024-01-01: 99 + SCHOOL_AGE: + BASE: + 2024-01-01: 85 + STAR_1: + 2024-01-01: 87 + STAR_2: + 2024-01-01: 88 + STAR_3: + 2024-01-01: 90 + STAR_4: + 2024-01-01: 92 + STAR_5: + 2024-01-01: 94 + OPELIKA: + INFANT_TODDLER: + BASE: + 2024-01-01: 134 + STAR_1: + 2024-01-01: 137 + STAR_2: + 2024-01-01: 139 + STAR_3: + 2024-01-01: 142 + STAR_4: + 2024-01-01: 145 + STAR_5: + 2024-01-01: 148 + PRESCHOOL: + BASE: + 2024-01-01: 129 + STAR_1: + 2024-01-01: 132 + STAR_2: + 2024-01-01: 134 + STAR_3: + 2024-01-01: 137 + STAR_4: + 2024-01-01: 140 + STAR_5: + 2024-01-01: 142 + SCHOOL_AGE: + BASE: + 2024-01-01: 125 + STAR_1: + 2024-01-01: 128 + STAR_2: + 2024-01-01: 130 + STAR_3: + 2024-01-01: 133 + STAR_4: + 2024-01-01: 135 + STAR_5: + 2024-01-01: 138 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml new file mode 100644 index 00000000000..748264ddf19 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml @@ -0,0 +1,11 @@ +description: Alabama applies this multiplier to the full-time provider rate to compute the part-time rate under the Child Care Subsidy Program. +values: + 2024-01-01: 0.5 + +metadata: + unit: /1 + period: year + label: Alabama CCSP part-time rate multiplier + reference: + - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart (Part-time Rates) + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml new file mode 100644 index 00000000000..8a5df304fe4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml @@ -0,0 +1,97 @@ +description: Alabama groups counties into nine Child Care Subsidy Program rate-setting regions. + +metadata: + unit: list + period: year + label: Alabama CCSP counties by region + breakdown: + - al_ccsp_region + reference: + - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Regions and Counties Served + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf + +HUNTSVILLE: + 2024-01-01: + - COLBERT_COUNTY_AL + - CULLMAN_COUNTY_AL + - FRANKLIN_COUNTY_AL + - LAUDERDALE_COUNTY_AL + - LAWRENCE_COUNTY_AL + - LIMESTONE_COUNTY_AL + - MADISON_COUNTY_AL + - MORGAN_COUNTY_AL + - WINSTON_COUNTY_AL +TUSCALOOSA: + 2024-01-01: + - BIBB_COUNTY_AL + - CHOCTAW_COUNTY_AL + - FAYETTE_COUNTY_AL + - GREENE_COUNTY_AL + - HALE_COUNTY_AL + - LAMAR_COUNTY_AL + - MARENGO_COUNTY_AL + - MARION_COUNTY_AL + - PERRY_COUNTY_AL + - PICKENS_COUNTY_AL + - SUMTER_COUNTY_AL + - TUSCALOOSA_COUNTY_AL +MOBILE: + 2024-01-01: + - BALDWIN_COUNTY_AL + - CLARKE_COUNTY_AL + - CONECUH_COUNTY_AL + - ESCAMBIA_COUNTY_AL + - MOBILE_COUNTY_AL + - MONROE_COUNTY_AL + - WASHINGTON_COUNTY_AL +FT_PAYNE: + 2024-01-01: + - CHEROKEE_COUNTY_AL + - DEKALB_COUNTY_AL + - ETOWAH_COUNTY_AL + - JACKSON_COUNTY_AL + - MARSHALL_COUNTY_AL +BIRMINGHAM: + 2024-01-01: + - BLOUNT_COUNTY_AL + - JEFFERSON_COUNTY_AL + - ST_CLAIR_COUNTY_AL + - SHELBY_COUNTY_AL + - WALKER_COUNTY_AL +TALLADEGA: + 2024-01-01: + - CALHOUN_COUNTY_AL + - CLAY_COUNTY_AL + - CLEBURNE_COUNTY_AL + - COOSA_COUNTY_AL + - RANDOLPH_COUNTY_AL + - TALLADEGA_COUNTY_AL +MONTGOMERY: + 2024-01-01: + - AUTAUGA_COUNTY_AL + - BULLOCK_COUNTY_AL + - BUTLER_COUNTY_AL + - CHILTON_COUNTY_AL + - COVINGTON_COUNTY_AL + - DALLAS_COUNTY_AL + - ELMORE_COUNTY_AL + - LOWNDES_COUNTY_AL + - MONTGOMERY_COUNTY_AL + - WILCOX_COUNTY_AL +DOTHAN: + 2024-01-01: + - BARBOUR_COUNTY_AL + - COFFEE_COUNTY_AL + - CRENSHAW_COUNTY_AL + - DALE_COUNTY_AL + - GENEVA_COUNTY_AL + - HENRY_COUNTY_AL + - HOUSTON_COUNTY_AL + - PIKE_COUNTY_AL +OPELIKA: + 2024-01-01: + - CHAMBERS_COUNTY_AL + - LEE_COUNTY_AL + - MACON_COUNTY_AL + - RUSSELL_COUNTY_AL + - TALLAPOOSA_COUNTY_AL diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 76b5377b5f3..5708b9facb2 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -460,8 +460,14 @@ programs: category: Benefits agency: HHS status: partial - coverage: CA, CO, CT, DE, DC, IL, MA, MD, ME, NC, NH, NJ, PA, RI, SC, TX, VA, VT, WV + coverage: AL, CA, CO, CT, DE, DC, IL, MA, MD, ME, NC, NH, NJ, PA, RI, SC, TX, VA, VT, WV state_implementations: + - state: AL + status: complete + name: Alabama CCSP + full_name: Alabama Child Care Subsidy Program + variable: al_ccsp + parameter_prefix: gov.states.al.dhr.ccsp - state: CA status: complete name: CalWORKs childcare diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml new file mode 100644 index 00000000000..eecf23610c3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml @@ -0,0 +1,156 @@ +# AL CCSP benefit tests (SPMUnit, MONTH, USD) +# per_child_weekly_subsidy = max(0, min(weekly_charge, max_weekly_rate) - weekly_copay_per_child) +# monthly_subsidy = per_child_weekly_subsidy * 4.333 * eligible_child +# al_ccsp = sum over SPMUnit members. + +- name: Ineligible family gets zero benefit. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 80_000 # > 85% SMI fam of 4 + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person4: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_pre_subsidy_childcare_expenses: 24_000 + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp: 0 + +- name: Low-income family at zero copay receives full max rate. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 18_000 # ~ 86% FPL fam of 2 -> 0% copay band + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # BIRMINGHAM CENTER PRESCHOOL BASE = $138/wk + # Weekly charge = 10,000 / 52 = $192.31 + # min($192.31, $138) = $138 + # copay = $0 + # weekly subsidy = $138 + # monthly subsidy = $138 * 4.333 = $597.95 + al_ccsp: 597.95 + +- name: Family at 150 percent FPL with copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 30_660 # 150% FPL fam of 2 = 2,555/mo + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # BIRMINGHAM CENTER PRESCHOOL BASE = $138/wk + # weekly charge = 10,000 / 52 = $192.31; min(192.31, 138) = $138 + # copay = $30/wk; weekly subsidy = $138 - $30 = $108 + # monthly subsidy = $108 * 4.333 = $467.96 + al_ccsp: 467.96 + +- name: Provider charge below max rate caps subsidy at charge minus copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 18_000 # zero copay tier + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 5_200 # $100/wk charge + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 5_200 + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # weekly charge = $100; max rate = $138; min = $100; copay = $0 + # monthly subsidy = $100 * 4.333 = $433.30 + al_ccsp: 433.3 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml new file mode 100644 index 00000000000..7c3e60d24dc --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml @@ -0,0 +1,210 @@ +# AL CCSP activity eligibility tests (SPMUnit, MONTH) +# At least one parent must work >= 15 hr/wk, be a full-time student, or be disabled (SC/VA convention). + +- name: Parent working 30 hrs per week is activity eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked: 30 + is_full_time_student: false + is_disabled: 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: AL + output: + al_ccsp_activity_eligible: true + +- name: Parent at 15 hours minimum boundary is activity eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 15 + is_full_time_student: false + is_disabled: 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: AL + output: + al_ccsp_activity_eligible: true + +- name: Parent working 10 hrs is activity ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 10 + is_full_time_student: false + is_disabled: 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: AL + output: + al_ccsp_activity_eligible: false + +- name: Full-time student parent is activity eligible. + period: 2024-01 + input: + people: + person1: + age: 22 + weekly_hours_worked: 0 + is_full_time_student: true + is_disabled: false + person2: + age: 2 + 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: AL + output: + al_ccsp_activity_eligible: true + +- name: Disabled parent is activity eligible (SC/VA convention). + period: 2024-01 + input: + people: + person1: + age: 40 + weekly_hours_worked: 0 + is_full_time_student: false + is_disabled: true + 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: AL + output: + al_ccsp_activity_eligible: true + +- name: Two parents both meeting 15 hours is activity eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 30 + person2: + age: 28 + weekly_hours_worked: 20 + person3: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: AL + output: + al_ccsp_activity_eligible: true + +- name: Two parents where one fails activity test is activity ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 30 + person2: + age: 28 + weekly_hours_worked: 0 + is_full_time_student: false + is_disabled: false + person3: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: AL + output: + al_ccsp_activity_eligible: false + +- name: Working parent plus disabled spouse is activity eligible (disabled-parent exemption). + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 40 + person2: + age: 28 + weekly_hours_worked: 0 + is_full_time_student: false + is_disabled: true + person3: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: AL + output: + al_ccsp_activity_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml new file mode 100644 index 00000000000..45eacf7c249 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml @@ -0,0 +1,80 @@ +# AL CCSP age category tests (Person, MONTH, Enum) +# Bracket on age-in-months -> {INFANT_TODDLER (0-35mo), PRESCHOOL (36-59mo), SCHOOL_AGE (60mo+)}. + +- name: Infant age 0 is INFANT_TODDLER. + period: 2024-01 + input: + people: + person1: + age: 0 + households: + household: + members: [person1] + state_code: AL + output: + al_ccsp_age_category: INFANT_TODDLER + +- name: Toddler age 2 is INFANT_TODDLER. + period: 2024-01 + input: + people: + person1: + age: 2 + households: + household: + members: [person1] + state_code: AL + output: + al_ccsp_age_category: INFANT_TODDLER + +- name: Child age 3 is PRESCHOOL. + period: 2024-01 + input: + people: + person1: + age: 3 + households: + household: + members: [person1] + state_code: AL + output: + al_ccsp_age_category: PRESCHOOL + +- name: Child age 4 is PRESCHOOL. + period: 2024-01 + input: + people: + person1: + age: 4 + households: + household: + members: [person1] + state_code: AL + output: + al_ccsp_age_category: PRESCHOOL + +- name: Child age 5 is SCHOOL_AGE. + period: 2024-01 + input: + people: + person1: + age: 5 + households: + household: + members: [person1] + state_code: AL + output: + al_ccsp_age_category: SCHOOL_AGE + +- name: Child age 12 is SCHOOL_AGE. + period: 2024-01 + input: + people: + person1: + age: 12 + households: + household: + members: [person1] + state_code: AL + output: + al_ccsp_age_category: SCHOOL_AGE diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml new file mode 100644 index 00000000000..21ec415aed3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml @@ -0,0 +1,337 @@ +# AL CCSP family copay tests (SPMUnit, MONTH, USD) +# Per-child weekly fee from FPL band, summed over eligible children, converted to monthly via 4.333. +# Waivers (zero copay): disabled child, Head Start enrollment, protective services (foster). +# Homelessness alone does NOT waive copay (per State Plan §3.3.1(iii)). +# +# 2024 FPG (Contiguous US): first $15,060, additional $5,380. +# FS 2: $20,440/yr ($1,703.33/mo) +# FS 4: $31,200/yr ($2,600/mo) +# Initial fee scale (effective 2024-01-01), weekly per child: +# 0-100% FPL -> $0 +# 101-110 -> $18 +# 111-120 -> $21 +# 121-130 -> $24 +# 131-140 -> $27 +# 141-150 -> $30 +# 151-160 -> $33 +# 161-170 -> $36 +# 171-180 -> $39 +# Continuing schedule: +# 181-190 -> $42 +# 191-200 -> $45 + +- name: Family at 80 percent FPL has zero copay (encoded in scale). + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 16_352 # 80% FPL fam of 2 = 16,352/yr -> 1,363/mo + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # <= 100% FPL band -> $0/wk -> $0/mo + al_ccsp_copay: 0 + +- name: Family at 150 percent FPL with one child pays 30 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 30_660 # 150% FPL fam of 2 = 30,660/yr -> 2,555/mo + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 150% FPL -> 141-150 band -> $30/wk per child + # 1 child * $30/wk * 4.333 = $130.00/mo + al_ccsp_copay: 129.99 + +- name: Family at 175 percent FPL pays 39 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 35_770 # 175% FPL fam of 2 = 35,770/yr -> 2,981/mo + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 175% FPL -> 171-180 band -> $39/wk per child + # $39 * 4.333 = $168.99/mo + al_ccsp_copay: 168.99 + +- name: Continuing-tier family at 185 percent FPL pays 42 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 37_814 # 185% FPL fam of 2 = 37,814/yr -> 3,151/mo + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 185% FPL -> 181-190 continuing band -> $42/wk per child + # $42 * 4.333 = $181.99/mo + al_ccsp_copay: 181.99 + +- name: Continuing-tier family at 195 percent FPL pays 45 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 39_858 # 195% FPL fam of 2 = 39,858/yr -> 3,322/mo + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 195% FPL -> 191-200 continuing band -> $45/wk per child + # $45 * 4.333 = $194.99/mo + al_ccsp_copay: 194.99 + +- name: Two eligible children at 150 percent FPL pay two times 30 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 38_730 # 150% FPL fam of 3 = 38,730/yr -> 3,228/mo + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person3: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 150% FPL -> $30/wk per child + # 2 children * $30 * 4.333 = $259.98/mo + al_ccsp_copay: 259.98 + +- name: Family with disabled child has zero copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 35_000 # would otherwise be paid tier + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_copay: 0 + +- name: Head Start enrollment waives copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 35_000 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_enrolled_in_head_start: true + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_copay: 0 + +- name: Foster care waives copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + employment_income: 35_000 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_in_foster_care: true + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_copay: 0 + +- name: Homeless household alone does NOT waive copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 30_660 # 150% FPL fam of 2 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + is_homeless: true + output: + # Homelessness alone is NOT a copay waiver in AL. + # Fee is still owed: 150% FPL -> $30/wk -> $30 * 4.333 = $130.00/mo + al_ccsp_copay: 129.99 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_countable_income.yaml new file mode 100644 index 00000000000..a31c7753acc --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_countable_income.yaml @@ -0,0 +1,128 @@ +# AL CCSP countable income tests (SPMUnit, MONTH, USD) +# Uses adds = "gov.states.al.dhr.ccsp.income.countable_income.sources" — annual +# sources auto-divided to monthly by PolicyEngine. + +- name: Employment income only. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 24_000 + 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: AL + output: + # Monthly = 24,000 / 12 = 2,000 + al_ccsp_countable_income: 2_000 + +- name: Self employment and interest income. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + self_employment_income: 18_000 + interest_income: 2_400 + 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: AL + output: + # Monthly = (18,000 + 2,400) / 12 = 1,700 + al_ccsp_countable_income: 1_700 + +- name: Social security counted. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 65 + social_security_retirement: 12_000 + person2: + age: 6 + 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: AL + output: + # Monthly = 12,000 / 12 = 1,000 + al_ccsp_countable_income: 1_000 + +- name: Child support excluded. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 24_000 + child_support_received: 6_000 + 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: AL + output: + # Child support excluded -> monthly = 24,000 / 12 = 2,000 + al_ccsp_countable_income: 2_000 + +- name: Zero income family. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + 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: AL + output: + al_ccsp_countable_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible.yaml new file mode 100644 index 00000000000..334262fd782 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible.yaml @@ -0,0 +1,293 @@ +# AL CCSP top-level eligibility tests (SPMUnit, MONTH) +# Combines: has eligible child, AL residency, income eligible (180% FPL or 200% if enrolled, AND 85% SMI), +# asset eligible ($1M federal floor), activity eligible OR protective services waiver. + +- name: Working AL family with one child age 4 is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible: true + +- name: Working family in GA is ineligible (non-AL). + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: GA + output: + al_ccsp_eligible: false + +- name: Adult-only household with no children is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 25_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: AL + output: + al_ccsp_eligible: false + +- name: Parent at 10 hrs work non-student non-disabled is activity ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 15_000 + immigration_status: CITIZEN + weekly_hours_worked: 10 + is_full_time_student: false + is_disabled: false + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible: false + +- name: Foster child waives activity requirement. + period: 2024-01 + input: + people: + person1: + age: 35 + immigration_status: CITIZEN + weekly_hours_worked: 0 + is_full_time_student: false + is_disabled: false + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_in_foster_care: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + # Foster -> protective services -> waives income AND activity + al_ccsp_eligible: true + +- name: Family at 190 percent FPL initial path is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 59_280 # 190% FPL fam of 4 = 4,940/mo + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 28 + weekly_hours_worked: 40 + person3: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person4: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 190% FPL > 180% initial limit, al_ccsp_enrolled=false -> ineligible + al_ccsp_eligible: false + +- name: Family at 190 percent FPL continuing path is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 59_280 + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 28 + weekly_hours_worked: 40 + person3: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person4: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 190% FPL <= 200% continuing limit, and 4,940/mo <= 6,262/mo 85% SMI -> eligible + al_ccsp_eligible: true + +- name: Family above 85 percent SMI is ineligible even at continuing tier. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 80_000 # 6,667/mo > 6,262 (85% SMI fam of 4) + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person4: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + al_ccsp_eligible: false + +- name: Homeless household waives activity test via protective services. + period: 2024-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + weekly_hours_worked: 0 + is_full_time_student: false + is_disabled: false + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + is_homeless: true + output: + # Homeless -> protective services -> waives income AND activity + al_ccsp_eligible: true + +- name: Asset over 1 million is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_500_000 + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml new file mode 100644 index 00000000000..2cbc2e6f510 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml @@ -0,0 +1,215 @@ +# AL CCSP eligible child tests (Person, MONTH) +# Combines: child_age_limit (<13) or disabled_child_age_limit (<19 if disabled), +# is_ccdf_immigration_eligible_child, is_tax_unit_dependent. + +- name: Child age 4 citizen dependent is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, true] + +- name: Child age 12 citizen dependent is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 12 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, true] + +- name: Child age 13 not disabled is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 13 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: false + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, false] + +- name: Non-disabled child age 14 is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 14 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: false + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, false] + +- name: Disabled child age 14 is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 14 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, true] + +- name: Disabled child age 18 is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 18 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, true] + +- name: Disabled child age 19 is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 19 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, false] + +- name: Non-citizen ineligible-immigration child is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, false] + +- name: Non-AL family child is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: GA + output: + al_ccsp_eligible_child: [false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml new file mode 100644 index 00000000000..9df89ae0bed --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml @@ -0,0 +1,165 @@ +# AL CCSP income eligibility tests (SPMUnit, MONTH) +# Initial path: monthly income <= 180% FPL AND <= 85% SMI. +# Continuing path (al_ccsp_enrolled=True): monthly income <= 200% FPL AND <= 85% SMI. +# +# 2024 FPG (Contiguous US): first_person $15,060, additional $5,380. +# Family of 2: $20,440/yr ($1,703.33/mo) +# Family of 3: $25,820/yr ($2,151.67/mo) +# Family of 4: $31,200/yr ($2,600/mo) +# 180% FPL (FS 3): $46,476/yr ($3,873/mo) +# 180% FPL (FS 4): $56,160/yr ($4,680/mo) +# 200% FPL (FS 4): $62,400/yr ($5,200/mo) +# AL SMI FS 4 (2023-10-01 -> applies 2024): $88,407. 85% SMI FS 4: $75,145.95/yr ($6,262.16/mo). + +- name: Family at 150 percent FPL initial path is income eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 46_800 # 150% FPL fam of 4 = 46,800/yr = 3,900/mo + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 3,900/mo <= 4,680/mo (180% FPL) -> initial-eligible + # 3,900/mo <= 6,262/mo (85% SMI) -> SMI-eligible + al_ccsp_income_eligible: true + +- name: Family at 190 percent FPL initial path is income ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 59_280 # 190% FPL fam of 4 = 59,280/yr = 4,940/mo + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 4,940/mo > 4,680/mo (180% FPL) -> initial path fails + al_ccsp_income_eligible: false + +- name: Family at 190 percent FPL continuing path is income eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 59_280 # 190% FPL fam of 4 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 4,940/mo <= 5,200/mo (200% FPL) -> continuing-eligible + # 4,940/mo <= 6,262/mo (85% SMI) -> SMI-eligible + al_ccsp_income_eligible: true + +- name: Family above 200 percent FPL continuing path is income ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 65_000 # ~208% FPL fam of 4 = 5,417/mo + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 5,417/mo > 5,200/mo (200% FPL) -> continuing path fails + al_ccsp_income_eligible: false + +- name: Family above 85 percent SMI is income ineligible even at continuing tier. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 80_000 # 6,667/mo > 85% SMI fam of 4 (6,262/mo) + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 6,667/mo > 6,262/mo (85% SMI) -> SMI cap fails even though < 200% FPL? actually 80,000 = 256% FPL. + # Either way, SMI cap fails. + al_ccsp_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml new file mode 100644 index 00000000000..72316d8f532 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml @@ -0,0 +1,203 @@ +# AL CCSP maximum weekly provider rate tests (Person, MONTH, USD) +# Looked up by provider_type x region x age_category x quality_tier. +# Full-time when childcare_hours_per_week > 25; otherwise rate is halved (part-time multiplier 0.5). +# INFORMAL provider has a flat $40/wk cap regardless of region/age/quality. +# defined_for: al_ccsp_eligible_child (Person, MONTH). + +- name: CENTER BIRMINGHAM PRESCHOOL STAR_3 full-time is 146 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 146] + +- name: CENTER HUNTSVILLE INFANT_TODDLER BASE full-time is 138 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 40 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: MADISON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 138] + +- name: GFDC HUNTSVILLE SCHOOL_AGE STAR_5 full-time is 137 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + al_ccsp_provider_type: GFDC + al_ccsp_quality_tier: STAR_5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: MADISON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 137] + +- name: FDC MOBILE INFANT_TODDLER BASE full-time is 125 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + al_ccsp_provider_type: FDC + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: MOBILE_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 125] + +- name: Part-time care halves full-time rate. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 20 # <= 25 -> part-time + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL # BIRMINGHAM, PRESCHOOL STAR_3 = $146 -> half = $73 + output: + al_ccsp_maximum_weekly_rate: [0, 73] + +- name: INFORMAL provider capped at 40 per week regardless of region. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: INFORMAL + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 40] + +- name: Adult gets zero rate (not an eligible child). + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + childcare_hours_per_week: 30 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 146] diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_protective_services.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_protective_services.yaml new file mode 100644 index 00000000000..308db690a99 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_protective_services.yaml @@ -0,0 +1,71 @@ +# AL CCSP protective services tests (SPMUnit, MONTH) +# Per scope decision: foster care OR homelessness flag the SPM unit as protective services. +# Kinship care is EXCLUDED (per CCDF State Plan §2.2.2(f) checkbox). + +- name: Foster child in family triggers protective services. + period: 2024-01 + input: + people: + person1: + age: 40 + person2: + age: 5 + is_tax_unit_dependent: true + is_in_foster_care: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_protective_services: true + +- name: Homeless household triggers protective services. + period: 2024-01 + input: + people: + person1: + age: 30 + 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: AL + is_homeless: true + output: + al_ccsp_protective_services: true + +- name: Family with no foster and not homeless is not in protective services. + period: 2024-01 + input: + people: + person1: + age: 30 + 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: AL + output: + al_ccsp_protective_services: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_region.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_region.yaml new file mode 100644 index 00000000000..6560960f257 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_region.yaml @@ -0,0 +1,128 @@ +# AL CCSP region tests (Household, YEAR, Enum) +# Maps county -> region using counties.yaml lists. + +- name: Madison County is HUNTSVILLE. + period: 2024 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: AL + county_str: MADISON_COUNTY_AL + output: + al_ccsp_region: HUNTSVILLE + +- name: Tuscaloosa County is TUSCALOOSA. + period: 2024 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: AL + county_str: TUSCALOOSA_COUNTY_AL + output: + al_ccsp_region: TUSCALOOSA + +- name: Mobile County is MOBILE. + period: 2024 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: AL + county_str: MOBILE_COUNTY_AL + output: + al_ccsp_region: MOBILE + +- name: DeKalb County is FT_PAYNE. + period: 2024 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: AL + county_str: DEKALB_COUNTY_AL + output: + al_ccsp_region: FT_PAYNE + +- name: Jefferson County is BIRMINGHAM. + period: 2024 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_region: BIRMINGHAM + +- name: Talladega County is TALLADEGA. + period: 2024 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: AL + county_str: TALLADEGA_COUNTY_AL + output: + al_ccsp_region: TALLADEGA + +- name: Montgomery County is MONTGOMERY. + period: 2024 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: AL + county_str: MONTGOMERY_COUNTY_AL + output: + al_ccsp_region: MONTGOMERY + +- name: Houston County is DOTHAN. + period: 2024 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: AL + county_str: HOUSTON_COUNTY_AL + output: + al_ccsp_region: DOTHAN + +- name: Lee County is OPELIKA. + period: 2024 + input: + people: + person1: + age: 30 + households: + household: + members: [person1] + state_code: AL + county_str: LEE_COUNTY_AL + output: + al_ccsp_region: OPELIKA diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_child_care_subsidies.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_child_care_subsidies.yaml new file mode 100644 index 00000000000..0cc7d77b5c5 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_child_care_subsidies.yaml @@ -0,0 +1,69 @@ +# AL CCSP annual aggregator tests (SPMUnit, YEAR, USD) +# adds = ["al_ccsp"] -- sums the monthly al_ccsp benefit over 12 months. + +- name: Ineligible family aggregator is zero. + period: 2024 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 80_000 + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + 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 + county_str: JEFFERSON_COUNTY_AL + output: + al_child_care_subsidies: 0 + +- name: Low-income family aggregator is 12 times monthly subsidy. + period: 2024 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 18_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # Monthly al_ccsp = $597.95 (BIRMINGHAM CENTER PRESCHOOL BASE $138 * 4.333) + # Annual = 12 * $597.95 = $7,175.40 + al_child_care_subsidies: 7175.4 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml new file mode 100644 index 00000000000..e66a1f513eb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml @@ -0,0 +1,442 @@ +# AL CCSP edge case tests +# Boundary conditions, multi-dimension rate coverage, and unusual configurations. + +# -- Age boundary tests -- + +- name: Child exactly age 13 not disabled is ineligible (strict less-than). + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 13 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: false + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, false] + +- name: Disabled child exactly age 19 is ineligible (strict less-than). + period: 2024-01 + input: + people: + person1: + age: 40 + person2: + age: 19 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, false] + +# -- Activity boundary tests -- + +- name: Parent working 14 hours per week is activity ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 14 + is_full_time_student: false + is_disabled: 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: AL + output: + al_ccsp_activity_eligible: false + +# -- Asset boundary test -- + +- name: Assets exactly 1 million dollars is asset eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000_000 + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible: true + +# -- Care hours boundary tests (full-time / part-time) -- + +- name: Care hours exactly 25 is part-time (half rate). + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 25 # boundary <= 25 = part-time + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL # BIRMINGHAM CENTER PRESCHOOL BASE = $138 -> half = $69 + output: + al_ccsp_maximum_weekly_rate: [0, 69] + +- name: Care hours exactly 26 is full-time. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 26 # > 25 -> full-time + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 138] + +# -- Multi-region rate coverage -- + +- name: GFDC rate in Huntsville Preschool STAR_3 is 133 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: GFDC + al_ccsp_quality_tier: STAR_3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: MADISON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 133] + +- name: FDC rate in Mobile School_Age STAR_5 is 138 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 30 + al_ccsp_provider_type: FDC + al_ccsp_quality_tier: STAR_5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: MOBILE_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 138] + +- name: CENTER Talladega INFANT_TODDLER BASE is 111 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: TALLADEGA_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 111] + +- name: CENTER Montgomery PRESCHOOL STAR_5 is 127 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: MONTGOMERY_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 127] + +# -- Copay band boundary tests -- + +- name: Family at exactly 100 percent FPL has zero copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 20_440 # 100% FPL fam of 2 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # At exactly 100% FPL (ratio 1.0), the $0 band applies (next threshold is 1.0001). + al_ccsp_copay: 0 + +- name: Family at exactly 110 percent FPL pays 18 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 22_484 # 110% FPL fam of 2 = 22,484/yr + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 110% FPL ratio = 1.10 -> 101-110 band ($18/wk). + # $18 * 4.333 = $77.99/mo + al_ccsp_copay: 77.99 + +- name: Family at 120 percent FPL pays 21 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 24_528 # 120% FPL fam of 2 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 120% FPL -> 111-120 band ($21/wk). $21 * 4.333 = $90.99/mo + al_ccsp_copay: 90.99 + +# -- Zero family income -- + +- name: Zero income working-zero parent fails activity test but eligible-child still true. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 0 + is_full_time_student: false + is_disabled: false + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, true] + al_ccsp_activity_eligible: false + al_ccsp_eligible: false + +# -- Region masking for non-AL households (no crash) -- + +- name: Non-AL family has zero benefit even with childcare expenses. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: GA + output: + al_ccsp: 0 + al_ccsp_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml new file mode 100644 index 00000000000..43aca75c23b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml @@ -0,0 +1,436 @@ +# AL CCSP integration tests +# Cross-cuts eligibility, copay, rate lookup, and benefit calculation. +# +# 2024 FPG (Contiguous US): first $15,060, additional $5,380. +# FS 2: $20,440/yr ($1,703.33/mo); 150% FPL = 2,555/mo; 180% = 3,066/mo +# FS 3: $25,820/yr ($2,151.67/mo) +# FS 4: $31,200/yr ($2,600/mo); 150% FPL = 3,900/mo; 180% = 4,680/mo; +# 190% = 4,940/mo; 200% = 5,200/mo +# AL SMI FS 4 (2023-10-01): $88,407/yr. 85% SMI FS 4: $75,145.95/yr (6,262.16/mo). +# Weekly -> monthly multiplier: 4.333 (regulatory literal). + +- name: Two-parent family at 150 FPL with center care in Birmingham STAR_3. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 38_730 # 150% FPL fam of 3 = 3,228/mo + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 28 + weekly_hours_worked: 40 + person3: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_eligible_child: [false, false, true] + al_ccsp_income_eligible: true + al_ccsp_eligible: true + # 150% FPL -> $30/wk per child -> $30 * 4.333 = $129.99/mo copay + al_ccsp_copay: 129.99 + # BIRMINGHAM CENTER PRESCHOOL STAR_3 full-time = $146/wk + al_ccsp_maximum_weekly_rate: [0, 0, 146] + # weekly charge = 10,000 / 52 = $192.31; min($192.31, $146) = $146 + # weekly subsidy = $146 - $30 = $116 + # monthly = $116 * 4.333 = $502.63 + al_ccsp: 502.63 + +- name: Single parent at 60 FPL continuing tier with FDC in Mobile BASE. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 25 + employment_income: 12_264 # ~60% FPL fam of 2 = 1,022/mo + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: FDC + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + al_ccsp_enrolled: true + households: + household: + members: [person1, person2] + state_code: AL + county_str: MOBILE_COUNTY_AL + output: + al_ccsp_eligible_child: [false, true] + al_ccsp_eligible: true + # <= 100% FPL -> $0/wk copay + al_ccsp_copay: 0 + # MOBILE FDC INFANT_TODDLER BASE full-time = $125/wk + al_ccsp_maximum_weekly_rate: [0, 125] + # weekly charge = 8,000 / 52 = $153.85; min($153.85, $125) = $125 + # monthly = $125 * 4.333 = $541.63 + al_ccsp: 541.63 + +- name: Family at 190 FPL initial tier is ineligible. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 59_280 # 190% FPL fam of 4 + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person4: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + 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 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_income_eligible: false + al_ccsp_eligible: false + al_ccsp: 0 + +- name: Family at 190 FPL continuing tier is eligible with copay 42 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 49_058 # 190% FPL fam of 3 = 49,058/yr + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 28 + weekly_hours_worked: 40 + person3: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_eligible: true + # FPL ratio = 49,058 / 25,820 = 1.90 -> 181-190 band -> $42/wk + # $42 * 4.333 = $181.99/mo + al_ccsp_copay: 181.99 + # BIRMINGHAM CENTER PRESCHOOL BASE = $138/wk + al_ccsp_maximum_weekly_rate: [0, 0, 138] + # weekly charge = 10,000 / 52 = $192.31; min($192.31, $138) = $138 + # weekly subsidy = $138 - $42 = $96 + # monthly = $96 * 4.333 = $415.97 + al_ccsp: 415.97 + +- name: Foster child waives income test and copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + employment_income: 35_000 # would otherwise be a paid copay tier + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_in_foster_care: true + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_eligible: true + al_ccsp_protective_services: true + al_ccsp_copay: 0 + # BIRMINGHAM CENTER SCHOOL_AGE BASE = $115/wk + al_ccsp_maximum_weekly_rate: [0, 115] + # weekly subsidy = $115; monthly = $115 * 4.333 = $498.30 + al_ccsp: 498.3 + +- name: Disabled child waives copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + employment_income: 30_660 # 150% FPL fam of 2 (would normally have $30/wk copay) + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_eligible: true + al_ccsp_copay: 0 + # BIRMINGHAM CENTER SCHOOL_AGE BASE = $115/wk (age 5) + # weekly subsidy = $115 - $0 = $115; monthly = $115 * 4.333 = $498.30 + al_ccsp: 498.3 + +- name: Family above 85 SMI is ineligible even with low FPL ratio (large household). + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 85_000 # well above 85% SMI fam of 4 ($75,146/yr) + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person4: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + 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 + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_eligible: false + al_ccsp: 0 + +- name: Two eligible children with center care split copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 38_730 # 150% FPL fam of 3 = 3,228/mo + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 7_000 + person3: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 7_000 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 14_000 + households: + household: + members: [person1, person2, person3] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_eligible_child: [false, true, true] + al_ccsp_eligible: true + # 150% FPL -> $30/wk per child * 2 children * 4.333 = $259.98/mo + al_ccsp_copay: 259.98 + # BIRMINGHAM CENTER PRESCHOOL BASE = $138; CENTER INFANT_TODDLER BASE = $150 + al_ccsp_maximum_weekly_rate: [0, 138, 150] + # weekly charge per child = 7,000 / 52 = $134.62 + # child 1 (age 4): min($134.62, $138) = $134.62; subsidy = $134.62 - $30 = $104.62 + # child 2 (age 2): min($134.62, $150) = $134.62; subsidy = $134.62 - $30 = $104.62 + # total weekly subsidy = $209.24; monthly = $209.24 * 4.333 = $906.64 + al_ccsp: 906.64 + +- name: Part-time care halves provider rate. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 18_000 + immigration_status: CITIZEN + weekly_hours_worked: 20 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 20 # <= 25 -> part-time + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 5_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 5_000 + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_eligible: true + # BIRMINGHAM CENTER PRESCHOOL BASE full-time = $138; part-time = $69 + al_ccsp_maximum_weekly_rate: [0, 69] + # weekly charge = 5,000 / 52 = $96.15; min(96.15, 69) = $69 + # copay = $0 (<=100% FPL) + # monthly = $69 * 4.333 = $298.98 + al_ccsp: 298.98 + +- name: INFORMAL provider capped at 40 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 18_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: INFORMAL + pre_subsidy_childcare_expenses: 5_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 5_000 + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_eligible: true + al_ccsp_maximum_weekly_rate: [0, 40] + # weekly charge = $96.15; min($96.15, $40) = $40 + # copay = $0; monthly = $40 * 4.333 = $173.32 + al_ccsp: 173.32 diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py new file mode 100644 index 00000000000..6988ab342b0 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py @@ -0,0 +1,65 @@ +from policyengine_us.model_api import * + + +class al_ccsp(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Alabama Child Care Subsidy Program benefit amount" + definition_period = MONTH + defined_for = "al_ccsp_eligible" + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 3.1", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=40", + ) + + def formula(spm_unit, period, parameters): + person = spm_unit.members + p = parameters(period).gov.states.al.dhr.ccsp + + # Per-child weekly maximum rate and the family weekly copay + # split equally across eligible children. + weekly_rate = person("al_ccsp_maximum_weekly_rate", period) + is_eligible_child = person("al_ccsp_eligible_child", period) + in_care = person("childcare_hours_per_week", period.this_year) > 0 + is_paying_child = is_eligible_child & in_care + n_paying = spm_unit.sum(is_paying_child) + + weekly_family_copay = ( + spm_unit("al_ccsp_weekly_copay_per_child", period) * n_paying + ) + # Apply copay waivers consistently with al_ccsp_copay. + p_elig = p.eligibility + is_disabled = person("is_disabled", period.this_year) + age = person("age", period.this_year) + is_dependent = person("is_tax_unit_dependent", period.this_year) + has_disabled_child = spm_unit.any( + is_disabled & is_dependent & (age < p_elig.disabled_child_age_limit) + ) + is_head_start = person("is_enrolled_in_head_start", period.this_year) + has_head_start_child = spm_unit.any(is_head_start) + has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 + copay_waived = has_disabled_child | has_head_start_child | has_foster_child + weekly_family_copay = where(copay_waived, 0, weekly_family_copay) + + per_child_weekly_copay = where( + n_paying > 0, weekly_family_copay / where(n_paying > 0, n_paying, 1), 0 + ) + per_child_weekly_copay_broadcast = spm_unit.project(per_child_weekly_copay) + + # Per-child weekly pre-subsidy charge from annual expenses. + annual_expense = person("pre_subsidy_childcare_expenses", period.this_year) + weekly_expense = annual_expense / WEEKS_IN_YEAR + + # Subsidy = max(0, min(charge, max_rate) - per-child copay). + capped_charge = min_(weekly_expense, weekly_rate) + per_child_weekly_subsidy = max_( + capped_charge - per_child_weekly_copay_broadcast, 0 + ) + + # Convert weekly to monthly using AL's regulatory 4.333 factor. + weeks_to_months = p.income.weeks_to_months + per_child_monthly_subsidy = ( + per_child_weekly_subsidy * weeks_to_months * is_paying_child + ) + return spm_unit.sum(per_child_monthly_subsidy) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py new file mode 100644 index 00000000000..2111d0da946 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class ALCCSPAgeCategory(Enum): + INFANT_TODDLER = "Infant/Toddler (0-35 months)" + PRESCHOOL = "Preschool (36-59 months)" + SCHOOL_AGE = "School Age (60+ months)" + + +class al_ccsp_age_category(Variable): + value_type = Enum + entity = Person + possible_values = ALCCSPAgeCategory + default_value = ALCCSPAgeCategory.INFANT_TODDLER + definition_period = MONTH + label = "Alabama CCSP child age category for payment rates" + defined_for = StateCode.AL + reference = ( + "Alabama DHR Provider Rate Chart, Key to Care Level", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.al.dhr.ccsp.age_category + # monthly_age returns years; convert to months for bracket lookup. + age_months = person("age", period.this_year) * MONTHS_IN_YEAR + return p.months.calc(age_months) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_countable_income.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_countable_income.py new file mode 100644 index 00000000000..26db820dbad --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_countable_income.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class al_ccsp_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Alabama CCSP countable monthly gross income" + definition_period = MONTH + unit = USD + defined_for = StateCode.AL + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 2.2.4(c)", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=26", + ) + + adds = "gov.states.al.dhr.ccsp.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py new file mode 100644 index 00000000000..5b320d826d4 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class al_ccsp_enrolled(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Whether the family is currently enrolled in Alabama CCSP" + defined_for = StateCode.AL + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 2.2.4", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39", + ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py new file mode 100644 index 00000000000..4935e21d912 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class ALCCSPProviderType(Enum): + CENTER = "Child Care Center" + GFDC = "Group Family Day Care Home" + FDC = "Family Day Care Home" + INFORMAL = "Informal (License-Exempt) Provider" + + +class al_ccsp_provider_type(Variable): + value_type = Enum + entity = Person + possible_values = ALCCSPProviderType + default_value = ALCCSPProviderType.CENTER + definition_period = MONTH + label = "Alabama CCSP child care provider type" + defined_for = StateCode.AL + reference = ( + "Alabama DHR Provider Rate Chart", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py new file mode 100644 index 00000000000..8a73ac95553 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class ALCCSPQualityTier(Enum): + BASE = "Base" + STAR_1 = "1 Star" + STAR_2 = "2 Star" + STAR_3 = "3 Star" + STAR_4 = "4 Star" + STAR_5 = "5 Star" + + +class al_ccsp_quality_tier(Variable): + value_type = Enum + entity = Person + possible_values = ALCCSPQualityTier + default_value = ALCCSPQualityTier.BASE + definition_period = MONTH + label = "Alabama CCSP provider quality tier" + defined_for = StateCode.AL + reference = ( + "Alabama DHR Provider Rate Chart (Base + 1-5 Star)", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py new file mode 100644 index 00000000000..56dcd54583b --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py @@ -0,0 +1,61 @@ +from policyengine_us.model_api import * + + +class ALCCSPRegion(Enum): + HUNTSVILLE = "Huntsville" + TUSCALOOSA = "Tuscaloosa" + MOBILE = "Mobile" + FT_PAYNE = "Ft. Payne" + BIRMINGHAM = "Birmingham" + TALLADEGA = "Talladega" + MONTGOMERY = "Montgomery" + DOTHAN = "Dothan" + OPELIKA = "Opelika" + + +class al_ccsp_region(Variable): + value_type = Enum + entity = Household + possible_values = ALCCSPRegion + default_value = ALCCSPRegion.MONTGOMERY + definition_period = YEAR + label = "Alabama CCSP rate-setting region" + defined_for = StateCode.AL + reference = ( + "Alabama DHR Provider Rate Chart, Regions and Counties Served", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + ) + + def formula(household, period, parameters): + county = household("county_str", period) + state = household("state_code_str", period) + # Mask with state_code_str == "AL" so non-Alabama county strings + # do not flow into the region lookup (defined_for filters output + # but does not short-circuit vectorized indexing). + in_alabama = state == "AL" + p = parameters(period).gov.states.al.dhr.ccsp.region.counties + return select( + [ + in_alabama & np.isin(county, p.HUNTSVILLE), + in_alabama & np.isin(county, p.TUSCALOOSA), + in_alabama & np.isin(county, p.MOBILE), + in_alabama & np.isin(county, p.FT_PAYNE), + in_alabama & np.isin(county, p.BIRMINGHAM), + in_alabama & np.isin(county, p.TALLADEGA), + in_alabama & np.isin(county, p.MONTGOMERY), + in_alabama & np.isin(county, p.DOTHAN), + in_alabama & np.isin(county, p.OPELIKA), + ], + [ + ALCCSPRegion.HUNTSVILLE, + ALCCSPRegion.TUSCALOOSA, + ALCCSPRegion.MOBILE, + ALCCSPRegion.FT_PAYNE, + ALCCSPRegion.BIRMINGHAM, + ALCCSPRegion.TALLADEGA, + ALCCSPRegion.MONTGOMERY, + ALCCSPRegion.DOTHAN, + ALCCSPRegion.OPELIKA, + ], + default=ALCCSPRegion.MONTGOMERY, + ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_child_care_subsidies.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_child_care_subsidies.py new file mode 100644 index 00000000000..2616bc70ab9 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_child_care_subsidies.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class al_child_care_subsidies(Variable): + value_type = float + entity = SPMUnit + label = "Alabama child care subsidies" + unit = USD + definition_period = YEAR + defined_for = StateCode.AL + adds = ["al_ccsp"] diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py new file mode 100644 index 00000000000..704bb523c82 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py @@ -0,0 +1,53 @@ +from policyengine_us.model_api import * + + +class al_ccsp_copay(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Alabama CCSP monthly family copay" + definition_period = MONTH + defined_for = StateCode.AL + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 3.3.1", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=43", + ) + + def formula(spm_unit, period, parameters): + p_elig = parameters(period).gov.states.al.dhr.ccsp.eligibility + weekly_per_child = spm_unit("al_ccsp_weekly_copay_per_child", period) + + # Copay waivers (§3.3.1): + # (iv) family includes a disabled child + # (v) family enrolled in Head Start / EHS + # (vi) foster care (protective-services category for copay) + # Homelessness alone does NOT waive copay (§3.3.1(iii) unchecked), + # though it triggers the eligibility waiver via protective_services. + person = spm_unit.members + is_disabled = person("is_disabled", period.this_year) + age = person("age", period.this_year) + is_dependent = person("is_tax_unit_dependent", period.this_year) + has_disabled_child = spm_unit.any( + is_disabled & is_dependent & (age < p_elig.disabled_child_age_limit) + ) + + is_head_start = person("is_enrolled_in_head_start", period.this_year) + has_head_start_child = spm_unit.any(is_head_start) + + has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 + + copay_waived = has_disabled_child | has_head_start_child | has_foster_child + + # Count children whose copay applies: eligible children in care. + is_eligible_child = person("al_ccsp_eligible_child", period) + in_care = person("childcare_hours_per_week", period.this_year) > 0 + num_paying = spm_unit.sum(is_eligible_child & in_care) + + # Provider may charge above max reimbursement rate (§3.1); copay + # is independent of the rate and based on the FPL fee table. + weekly_family_copay = weekly_per_child * num_paying + weeks_to_months = parameters( + period + ).gov.states.al.dhr.ccsp.income.weeks_to_months + monthly_family_copay = weekly_family_copay * weeks_to_months + return where(copay_waived, 0, monthly_family_copay) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py new file mode 100644 index 00000000000..33a0664f0d1 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + + +class al_ccsp_weekly_copay_per_child(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Alabama CCSP weekly per-child parental fee" + definition_period = MONTH + defined_for = StateCode.AL + reference = ( + "Alabama Child Care Fact Sheet (Parental Fee Chart)", + "https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.al.dhr.ccsp.copay + monthly_income = spm_unit("al_ccsp_countable_income", period) + fpg = spm_unit("spm_unit_fpg", period.this_year) + # Compare monthly income against the monthly federal poverty + # guideline to compute the FPL ratio. + monthly_fpg = fpg / MONTHS_IN_YEAR + fpl_ratio = where(monthly_fpg > 0, monthly_income / monthly_fpg, 0) + + enrolled = spm_unit("al_ccsp_enrolled", period) + initial_fee = p.initial_fee_by_fpl.calc(fpl_ratio) + continuing_fee = p.continuing_fee_by_fpl.calc(fpl_ratio) + # Continuing families above 180% FPL use the continuing fee scale; + # all other families use the initial fee scale. + return where(enrolled, continuing_fee, initial_fee) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py new file mode 100644 index 00000000000..c55810ff90c --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class al_ccsp_activity_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Alabama CCSP based on parental activity requirements" + definition_period = MONTH + defined_for = StateCode.AL + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 2.2.2", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=21", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.al.dhr.ccsp.eligibility + person = spm_unit.members + is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) + hours_worked = person("weekly_hours_worked", period.this_year) + meets_work_requirement = hours_worked >= p.activity_hours_minimum + is_student = person("is_full_time_student", period.this_year) + # Disabled-parent activity exemption per SC/VA precedent; not + # explicit in §2.2.2 but a CCDF best practice. + is_disabled = person("is_disabled", period.this_year) + individually_eligible = meets_work_requirement | is_student | is_disabled + 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/al/dhr/ccsp/eligibility/al_ccsp_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible.py new file mode 100644 index 00000000000..b9a0be98fff --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible.py @@ -0,0 +1,32 @@ +from policyengine_us.model_api import * + + +class al_ccsp_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Alabama CCSP" + definition_period = MONTH + defined_for = StateCode.AL + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 2.2", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20", + ) + + def formula(spm_unit, period, parameters): + has_eligible_child = add(spm_unit, period, ["al_ccsp_eligible_child"]) > 0 + income_eligible = spm_unit("al_ccsp_income_eligible", period) + asset_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) + activity_eligible = spm_unit("al_ccsp_activity_eligible", period) + + # Standard pathway: child + income + asset + activity tests. + standard = ( + has_eligible_child & income_eligible & asset_eligible & activity_eligible + ) + + # Protective-services pathway (§2.2.2(f)) waives income and + # activity tests. The asset test is NOT waived (State Plan + # §2.2.6 leaves the protective-services waiver box unchecked). + protective = spm_unit("al_ccsp_protective_services", period) + protective_path = has_eligible_child & asset_eligible & protective + + return standard | protective_path diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py new file mode 100644 index 00000000000..f71b9e6264a --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class al_ccsp_eligible_child(Variable): + value_type = bool + entity = Person + label = "Eligible child for Alabama CCSP" + definition_period = MONTH + defined_for = StateCode.AL + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 2.2.1", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.al.dhr.ccsp.eligibility + age = person("age", period.this_year) + is_disabled = person("is_disabled", period.this_year) + age_eligible = where( + is_disabled, + age < p.disabled_child_age_limit, + age < p.child_age_limit, + ) + immigration_eligible = person( + "is_ccdf_immigration_eligible_child", period.this_year + ) + is_dependent = person("is_tax_unit_dependent", period.this_year) + return age_eligible & immigration_eligible & is_dependent diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py new file mode 100644 index 00000000000..a7f9f019980 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py @@ -0,0 +1,35 @@ +from policyengine_us.model_api import * + + +class al_ccsp_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Alabama CCSP based on income" + definition_period = MONTH + defined_for = StateCode.AL + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 2.2.4", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=24", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.al.dhr.ccsp.eligibility + monthly_income = spm_unit("al_ccsp_countable_income", period) + annual_income = monthly_income * MONTHS_IN_YEAR + + # FPL test: 180% initial, 200% continuing (NJ pattern). + fpg = spm_unit("spm_unit_fpg", period.this_year) + enrolled = spm_unit("al_ccsp_enrolled", period) + fpl_limit_ratio = where( + enrolled, + p.income_limit_fpl_continuing, + p.income_limit_fpl_initial, + ) + fpl_eligible = annual_income <= fpg * fpl_limit_ratio + + # Federal CCDF 85% SMI hard cap applies in both initial and + # continuing tiers. + smi = spm_unit("hhs_smi", period.this_year) + smi_eligible = annual_income <= smi * p.income_limit_smi_cap + + return fpl_eligible & smi_eligible diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py new file mode 100644 index 00000000000..d3c437f8821 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class al_ccsp_protective_services(Variable): + value_type = bool + entity = SPMUnit + label = "Alabama CCSP protective services category" + definition_period = MONTH + defined_for = StateCode.AL + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 2.2.2(f)", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=23", + ) + + def formula(spm_unit, period, parameters): + # Foster care and homelessness are the modeled protective-service + # categories. Kinship is excluded per §2.2.2(f). EHS-CCP, + # child-welfare engagement, and TANF-Other Relative are not + # tracked at the moment and are documented as limitations. + has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 + is_homeless = spm_unit.household("is_homeless", period.this_year) + return has_foster_child | is_homeless diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py new file mode 100644 index 00000000000..da0455df940 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py @@ -0,0 +1,57 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.al.dhr.ccsp.al_ccsp_provider_type import ( + ALCCSPProviderType, +) + + +class al_ccsp_maximum_weekly_rate(Variable): + value_type = float + entity = Person + unit = USD + label = "Alabama CCSP maximum weekly reimbursement rate per child" + definition_period = MONTH + defined_for = "al_ccsp_eligible_child" + reference = ( + "Alabama DHR Provider Rate Chart", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.al.dhr.ccsp.rates + provider_type = person("al_ccsp_provider_type", period) + region = person.household("al_ccsp_region", period.this_year) + age_category = person("al_ccsp_age_category", period) + quality_tier = person("al_ccsp_quality_tier", period) + + # Look up the full-time rate across the four-dimension matrix. + # INFORMAL providers are handled separately by a flat weekly cap + # rather than the matrix; the select() default below carries the + # informal cap through when the provider type does not match. + rates = p.maximum_weekly_full_time + center_rate = rates.CENTER[region][age_category][quality_tier] + gfdc_rate = rates.GFDC[region][age_category][quality_tier] + fdc_rate = rates.FDC[region][age_category][quality_tier] + + matrix_rate = select( + [ + provider_type == ALCCSPProviderType.CENTER, + provider_type == ALCCSPProviderType.GFDC, + provider_type == ALCCSPProviderType.FDC, + ], + [center_rate, gfdc_rate, fdc_rate], + default=p.informal_weekly_cap, + ) + + # Part-time (≤25 hours/week) pays half the full-time rate. The + # informal cap is interpreted as a weekly maximum that applies + # without halving — providers either bill within the cap or not. + hours = person("childcare_hours_per_week", period.this_year) + is_part_time = hours <= p.full_time_hours_threshold + part_time_rate = matrix_rate * p.part_time_multiplier + full_time_rate = where(is_part_time, part_time_rate, matrix_rate) + + return where( + provider_type == ALCCSPProviderType.INFORMAL, + p.informal_weekly_cap, + full_time_rate, + ) From 511d7610ad6d4a66e9c99f7a32099efcb6d6ba58 Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 15 May 2026 00:03:32 -0400 Subject: [PATCH 04/15] Review-fix round 1: address critical issues from /review-program MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Correct §2.5.5(c)(iii) section label on income_limit_fpl_continuing.yaml - Fix #page=26 on income_limit_fpl_initial.yaml (was 24) - Add #page=1/2 anchors to 6 Provider Rate Chart references - Add 4 direct unit tests for al_ccsp_weekly_copay_per_child - Add exact-boundary tests at 180% FPL, 200% FPL, 85% SMI Co-Authored-By: Claude Opus 4.7 (1M context) --- .../al/dhr/ccsp/age_category/months.yaml | 2 +- .../income_limit_fpl_continuing.yaml | 2 +- .../eligibility/income_limit_fpl_initial.yaml | 2 +- .../ccsp/rates/full_time_hours_threshold.yaml | 2 +- .../dhr/ccsp/rates/informal_weekly_cap.yaml | 2 +- .../ccsp/rates/maximum_weekly_full_time.yaml | 2 +- .../dhr/ccsp/rates/part_time_multiplier.yaml | 2 +- .../states/al/dhr/ccsp/region/counties.yaml | 2 +- .../al/dhr/ccsp/al_ccsp_income_eligible.yaml | 91 ++++++++++++ .../ccsp/al_ccsp_weekly_copay_per_child.yaml | 133 ++++++++++++++++++ 10 files changed, 232 insertions(+), 8 deletions(-) create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml index 11b891b8e35..bc562271f2b 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml @@ -11,7 +11,7 @@ metadata: label: Alabama CCSP age category by age in months reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Key to Care Level - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2 - title: Alabama CCDF State Plan 2025-2027, Section 2.2 href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml index 1e3991d0323..412b40e5a57 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml @@ -7,7 +7,7 @@ metadata: period: year label: Alabama CCSP continuing income limit (share of federal poverty guideline) reference: - - title: Alabama CCDF State Plan 2025-2027, Section 2.2.4 + - title: Alabama CCDF State Plan 2025-2027, Section 2.5.5(c)(iii) href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39 - title: Alabama Child Care Fact Sheet href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml index a2483a72586..6036f37af07 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml @@ -8,6 +8,6 @@ metadata: label: Alabama CCSP initial income limit (share of federal poverty guideline) reference: - title: Alabama CCDF State Plan 2025-2027, Section 2.2.4 - href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=24 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=26 - title: Alabama Child Care Fact Sheet (Initial Eligibility Monthly Income Scale) href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml index c22a355d3e9..205125bf188 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml @@ -8,4 +8,4 @@ metadata: label: Alabama CCSP full-time weekly hours threshold reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart (Full-time / Part-time Rates note) - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml index 44271c98a2a..218896c6225 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml @@ -8,4 +8,4 @@ metadata: label: Alabama CCSP informal-provider weekly rate cap reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart (Informal care providers cap) - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml index 1c69c12cbf1..89fab38de9d 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml @@ -11,7 +11,7 @@ metadata: - al_ccsp_quality_tier reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Maximum Weekly Full-time Rates - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=1 CENTER: HUNTSVILLE: diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml index 748264ddf19..a4311f32308 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml @@ -8,4 +8,4 @@ metadata: label: Alabama CCSP part-time rate multiplier reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart (Part-time Rates) - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml index 8a5df304fe4..6be9189c68a 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml @@ -8,7 +8,7 @@ metadata: - al_ccsp_region reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Regions and Counties Served - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf + href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=1 HUNTSVILLE: 2024-01-01: diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml index 9df89ae0bed..30cc2baad99 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml @@ -163,3 +163,94 @@ # 6,667/mo > 6,262/mo (85% SMI) -> SMI cap fails even though < 200% FPL? actually 80,000 = 256% FPL. # Either way, SMI cap fails. al_ccsp_income_eligible: false + +- name: Family at exactly 180 percent FPL initial path is income eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 56_160 # 180% FPL fam of 4 = 31,200 * 1.8 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 56,160 == 180% FPL exactly -> formula uses <=, so still eligible at the boundary. + al_ccsp_income_eligible: true + +- name: Family at exactly 200 percent FPL continuing path is income eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 62_400 # 200% FPL fam of 4 = 31,200 * 2.0 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 62,400 == 200% FPL exactly -> formula uses <=, so still eligible at the boundary. + # 62,400/yr < 75,146/yr (85% SMI) -> SMI cap passes. + al_ccsp_income_eligible: true + +- name: Family just over 85 percent SMI is income ineligible at continuing tier. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 75_146 # 85% SMI fam of 4 = 88,407 * 0.85 = 75,145.95; 75,146 is just over + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # 75,146 > 75,145.95 (85% SMI cap) -> SMI cap fails by less than $1. + al_ccsp_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml new file mode 100644 index 00000000000..2c6e8331769 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml @@ -0,0 +1,133 @@ +# AL CCSP weekly per-child parental fee tests (SPMUnit, MONTH). +# Initial tier (al_ccsp_enrolled=false) uses the 9-band initial fee schedule. +# Continuing tier (al_ccsp_enrolled=true) uses the 2-band continuing fee schedule. +# +# 2024 FPG (Contiguous US), family of 4: $31,200/yr = $2,600/mo. +# 80% FPL fam of 4 = $24,960/yr ($2,080/mo) +# 150% FPL fam of 4 = $46,800/yr ($3,900/mo) +# 185% FPL fam of 4 = $57,720/yr ($4,810/mo) +# 195% FPL fam of 4 = $60,840/yr ($5,070/mo) + +- name: Initial tier at 150 percent FPL has $30 weekly per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 46_800 # 150% FPL fam of 4 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # FPL ratio = 3,900 / 2,600 = 1.5 -> initial tier band [1.4001, 1.5001) -> $30/wk + al_ccsp_weekly_copay_per_child: 30 + +- name: Initial tier at 80 percent FPL has zero weekly per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 24_960 # 80% FPL fam of 4 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # FPL ratio = 2,080 / 2,600 = 0.8 -> initial tier band [0, 1.0001) -> $0/wk + al_ccsp_weekly_copay_per_child: 0 + +- name: Continuing tier at 185 percent FPL has $42 weekly per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 57_720 # 185% FPL fam of 4 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # FPL ratio = 4,810 / 2,600 = 1.85 -> continuing tier band [1.8001, 1.9001) -> $42/wk + al_ccsp_weekly_copay_per_child: 42 + +- name: Continuing tier at 195 percent FPL has $45 weekly per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 60_840 # 195% FPL fam of 4 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # FPL ratio = 5,070 / 2,600 = 1.95 -> continuing tier band [1.9001, ...) -> $45/wk + al_ccsp_weekly_copay_per_child: 45 From 0363c3c8fc60a9998bc1fd21e9595c97f85f2fa7 Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 15 May 2026 00:14:46 -0400 Subject: [PATCH 05/15] Review-fix round 2: address SHOULD items from /review-program MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add #page= anchors to 5 variable .py files referencing Provider Rate Chart - Fix al_ccsp_enrolled.py section label (§2.2.4 → §2.5.5(c)(iii)) - Add STAR_1/STAR_2/STAR_4 test cases to al_ccsp_maximum_weekly_rate.yaml Co-Authored-By: Claude Opus 4.7 (1M context) --- .../dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml | 84 +++++++++++++++++++ .../al/dhr/ccsp/al_ccsp_age_category.py | 2 +- .../states/al/dhr/ccsp/al_ccsp_enrolled.py | 2 +- .../al/dhr/ccsp/al_ccsp_provider_type.py | 2 +- .../al/dhr/ccsp/al_ccsp_quality_tier.py | 2 +- .../gov/states/al/dhr/ccsp/al_ccsp_region.py | 2 +- .../payment/al_ccsp_maximum_weekly_rate.py | 2 +- 7 files changed, 90 insertions(+), 6 deletions(-) diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml index 72316d8f532..dd08ea78203 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml @@ -201,3 +201,87 @@ county_str: JEFFERSON_COUNTY_AL output: al_ccsp_maximum_weekly_rate: [0, 146] + +- name: CENTER HUNTSVILLE INFANT_TODDLER STAR_1 full-time is 141 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 40 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_1 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: MADISON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 141] + +- name: CENTER HUNTSVILLE INFANT_TODDLER STAR_2 full-time is 144 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 40 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_2 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: MADISON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 144] + +- name: CENTER HUNTSVILLE INFANT_TODDLER STAR_4 full-time is 149 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 40 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_4 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: MADISON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 149] diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py index 2111d0da946..122265b8d8e 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py @@ -17,7 +17,7 @@ class al_ccsp_age_category(Variable): defined_for = StateCode.AL reference = ( "Alabama DHR Provider Rate Chart, Key to Care Level", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2", ) def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py index 5b320d826d4..1ffb2a5433c 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py @@ -8,6 +8,6 @@ class al_ccsp_enrolled(Variable): label = "Whether the family is currently enrolled in Alabama CCSP" defined_for = StateCode.AL reference = ( - "Alabama CCDF State Plan 2025-2027, Section 2.2.4", + "Alabama CCDF State Plan 2025-2027, Section 2.5.5(c)(iii)", "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39", ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py index 4935e21d912..6cf01ffd4d1 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py @@ -18,5 +18,5 @@ class al_ccsp_provider_type(Variable): defined_for = StateCode.AL reference = ( "Alabama DHR Provider Rate Chart", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2", ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py index 8a73ac95553..5e832eec665 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py @@ -20,5 +20,5 @@ class al_ccsp_quality_tier(Variable): defined_for = StateCode.AL reference = ( "Alabama DHR Provider Rate Chart (Base + 1-5 Star)", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2", ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py index 56dcd54583b..e44ec5d1175 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py @@ -23,7 +23,7 @@ class al_ccsp_region(Variable): defined_for = StateCode.AL reference = ( "Alabama DHR Provider Rate Chart, Regions and Counties Served", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=1", ) def formula(household, period, parameters): diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py index da0455df940..7c9bdbea34d 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py @@ -13,7 +13,7 @@ class al_ccsp_maximum_weekly_rate(Variable): defined_for = "al_ccsp_eligible_child" reference = ( "Alabama DHR Provider Rate Chart", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf", + "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=1", ) def formula(person, period, parameters): From db4b928f1ff791178d340abaca611b475e614b5d Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 17 May 2026 19:10:05 -0400 Subject: [PATCH 06/15] Restructure AL CCSP parameters and verify against source PDFs Parameter restructure: - Replace eligibility/ folder with concept-based folders (age/, activity/, income/limit/) - Merge initial_fee_by_fpl.yaml + continuing_fee_by_fpl.yaml into a single fee_by_fpl.yaml (continuing families below 180% FPL now use the same scale as initial applicants) - Remove weeks_to_months.yaml; use WEEKS_IN_YEAR/MONTHS_IN_YEAR framework constant instead Source-verified value corrections: - Rate table (486 values): re-transcribed maximum_weekly_full_time.yaml from the dhr.alabama.gov "Effective April 11, 2022" Provider Rate Chart (prior values came from a different proposed/75th-percentile PDF) - Informal weekly cap: $40 -> $50 (per same PDF) - Age category PRESCHOOL threshold: 36 -> 37 months (per Rate Chart Key to Care Level) - Verified 85% SMI income cutoffs match HHS SMI parameters exactly New variable: - al_ccsp_copay_waived: extracts the disabled-child / Head Start / foster child waiver logic shared between al_ccsp_copay and al_ccsp Test coverage additions: - al_ccsp_copay_waived.yaml (5 cases covering each waiver category) - Multi-child mixed-eligibility tests for al_ccsp_copay, al_ccsp, and al_ccsp_eligible_child (3-children with 1 eligible / 1 over-age / 1 undocumented; 2 eligible children with 1 in care; 3 eligible children in care; disabled child + young sibling) All 126 AL CCSP tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../hours_minimum.yaml} | 2 +- .../child_limit.yaml} | 0 .../disabled_child_limit.yaml} | 0 .../al/dhr/ccsp/age_category/months.yaml | 22 +- .../dhr/ccsp/copay/continuing_fee_by_fpl.yaml | 25 - ...nitial_fee_by_fpl.yaml => fee_by_fpl.yaml} | 16 +- .../limit/fpl_continuing.yaml} | 0 .../limit/fpl_initial.yaml} | 0 .../limit/smi_cap.yaml} | 0 .../al/dhr/ccsp/income/weeks_to_months.yaml | 11 - .../ccsp/rates/full_time_hours_threshold.yaml | 4 +- .../dhr/ccsp/rates/informal_weekly_cap.yaml | 4 +- .../ccsp/rates/maximum_weekly_full_time.yaml | 974 +++++++++--------- .../dhr/ccsp/rates/part_time_multiplier.yaml | 4 +- .../states/al/dhr/ccsp/region/counties.yaml | 20 +- .../gov/states/al/dhr/ccsp/al_ccsp.yaml | 86 +- .../al/dhr/ccsp/al_ccsp_age_category.yaml | 7 +- .../gov/states/al/dhr/ccsp/al_ccsp_copay.yaml | 254 +++++ .../al/dhr/ccsp/al_ccsp_copay_waived.yaml | 120 +++ .../al/dhr/ccsp/al_ccsp_eligible_child.yaml | 42 +- .../dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml | 40 +- .../ccsp/al_ccsp_weekly_copay_per_child.yaml | 21 +- .../al/dhr/ccsp/al_child_care_subsidies.yaml | 6 +- .../gov/states/al/dhr/ccsp/edge_cases.yaml | 18 +- .../gov/states/al/dhr/ccsp/integration.yaml | 96 +- .../gov/states/al/dhr/ccsp/al_ccsp.py | 24 +- .../al/dhr/ccsp/al_ccsp_age_category.py | 6 +- .../al/dhr/ccsp/al_ccsp_provider_type.py | 2 +- .../al/dhr/ccsp/al_ccsp_quality_tier.py | 2 +- .../gov/states/al/dhr/ccsp/al_ccsp_region.py | 6 +- .../states/al/dhr/ccsp/copay/al_ccsp_copay.py | 33 +- .../al/dhr/ccsp/copay/al_ccsp_copay_waived.py | 26 + .../copay/al_ccsp_weekly_copay_per_child.py | 13 +- .../eligibility/al_ccsp_activity_eligible.py | 4 +- .../eligibility/al_ccsp_eligible_child.py | 6 +- .../eligibility/al_ccsp_income_eligible.py | 18 +- .../payment/al_ccsp_maximum_weekly_rate.py | 2 +- 37 files changed, 1165 insertions(+), 749 deletions(-) rename policyengine_us/parameters/gov/states/al/dhr/ccsp/{eligibility/activity_hours_minimum.yaml => activity/hours_minimum.yaml} (65%) rename policyengine_us/parameters/gov/states/al/dhr/ccsp/{eligibility/child_age_limit.yaml => age/child_limit.yaml} (100%) rename policyengine_us/parameters/gov/states/al/dhr/ccsp/{eligibility/disabled_child_age_limit.yaml => age/disabled_child_limit.yaml} (100%) delete mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/continuing_fee_by_fpl.yaml rename policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/{initial_fee_by_fpl.yaml => fee_by_fpl.yaml} (61%) rename policyengine_us/parameters/gov/states/al/dhr/ccsp/{eligibility/income_limit_fpl_continuing.yaml => income/limit/fpl_continuing.yaml} (100%) rename policyengine_us/parameters/gov/states/al/dhr/ccsp/{eligibility/income_limit_fpl_initial.yaml => income/limit/fpl_initial.yaml} (100%) rename policyengine_us/parameters/gov/states/al/dhr/ccsp/{eligibility/income_limit_smi_cap.yaml => income/limit/smi_cap.yaml} (100%) delete mode 100644 policyengine_us/parameters/gov/states/al/dhr/ccsp/income/weeks_to_months.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml create mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/activity_hours_minimum.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/activity/hours_minimum.yaml similarity index 65% rename from policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/activity_hours_minimum.yaml rename to policyengine_us/parameters/gov/states/al/dhr/ccsp/activity/hours_minimum.yaml index 16652aa50dd..e66c727c729 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/activity_hours_minimum.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/activity/hours_minimum.yaml @@ -1,4 +1,4 @@ -description: Alabama requires at least this many combined weekly hours of work, training, or education for Child Care Subsidy Program activity eligibility. +description: Alabama sets this minimum number of combined weekly hours of work, training, or education for activity eligibility under the Child Care Subsidy Program. values: 2024-01-01: 15 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/child_age_limit.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age/child_limit.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/child_age_limit.yaml rename to policyengine_us/parameters/gov/states/al/dhr/ccsp/age/child_limit.yaml diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/disabled_child_age_limit.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age/disabled_child_limit.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/disabled_child_age_limit.yaml rename to policyengine_us/parameters/gov/states/al/dhr/ccsp/age/disabled_child_limit.yaml diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml index bc562271f2b..f3b19d2a1aa 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml @@ -1,6 +1,6 @@ -description: Alabama assigns a Child Care Subsidy Program age category from the child's age in months. +description: Alabama uses this age in months threshold to assign care level categories under the Child Care Subsidy Program. # 0 = INFANT_TODDLER (birth to 36 months) -# 1 = PRESCHOOL (36 months to 5 years) +# 1 = PRESCHOOL (37 months to 5 years) # 2 = SCHOOL_AGE (5 years and older) metadata: @@ -11,20 +11,20 @@ metadata: label: Alabama CCSP age category by age in months reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Key to Care Level - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2 - - title: Alabama CCDF State Plan 2025-2027, Section 2.2 - href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2 + - title: Ala. Admin. Code r. 660-5-20-.04 Child Care Program + href: https://www.law.cornell.edu/regulations/alabama/Ala-Admin-Code-r-660-5-20-.04 brackets: - threshold: - 2024-01-01: 0 + 2022-04-11: 0 amount: - 2024-01-01: 0 + 2022-04-11: 0 - threshold: - 2024-01-01: 36 + 2022-04-11: 37 amount: - 2024-01-01: 1 + 2022-04-11: 1 - threshold: - 2024-01-01: 60 + 2022-04-11: 60 amount: - 2024-01-01: 2 + 2022-04-11: 2 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/continuing_fee_by_fpl.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/continuing_fee_by_fpl.yaml deleted file mode 100644 index 6e8c260b328..00000000000 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/continuing_fee_by_fpl.yaml +++ /dev/null @@ -1,25 +0,0 @@ -description: Alabama sets this weekly per-child fee for continuing-eligibility families under the Child Care Subsidy Program, indexed to the family's share of the federal poverty guideline. - -metadata: - type: single_amount - threshold_unit: /1 - amount_unit: currency-USD - period: week - label: Alabama CCSP continuing weekly per-child fee by FPL ratio - reference: - - title: Alabama Child Care Fact Sheet (Continuing Eligibility Monthly Income Scale) - href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf - -brackets: - - threshold: - 2024-01-01: 0 - amount: - 2024-01-01: 0 - - threshold: - 2024-01-01: 1.8001 - amount: - 2024-01-01: 42 - - threshold: - 2024-01-01: 1.9001 - amount: - 2024-01-01: 45 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/initial_fee_by_fpl.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml similarity index 61% rename from policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/initial_fee_by_fpl.yaml rename to policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml index 7fb604406f0..5afa10e8fb1 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/initial_fee_by_fpl.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml @@ -1,16 +1,14 @@ -description: Alabama sets this weekly per-child fee for initially-eligible families under the Child Care Subsidy Program, indexed to the family's share of the federal poverty guideline. +description: Alabama sets this weekly per-child fee under the Child Care Subsidy Program, indexed to the family's share of the federal poverty guideline. metadata: type: single_amount threshold_unit: /1 amount_unit: currency-USD period: week - label: Alabama CCSP initial weekly per-child fee by FPL ratio + label: Alabama CCSP weekly per-child fee by FPL ratio reference: - - title: Alabama Child Care Fact Sheet (Initial Eligibility Monthly Income Scale and Parental Fee Chart) + - title: Alabama Child Care Fact Sheet, Initial and Continuing Eligibility Monthly Income Scale and Parental Fee Chart href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf - - title: Alabama CCDF State Plan 2025-2027, Section 3.2.1 - href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=42 brackets: - threshold: @@ -49,3 +47,11 @@ brackets: 2024-01-01: 1.7001 amount: 2024-01-01: 39 + - threshold: + 2024-01-01: 1.8001 + amount: + 2024-01-01: 42 + - threshold: + 2024-01-01: 1.9001 + amount: + 2024-01-01: 45 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_continuing.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_continuing.yaml rename to policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_continuing.yaml diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_initial.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_fpl_initial.yaml rename to policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_initial.yaml diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_smi_cap.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml similarity index 100% rename from policyengine_us/parameters/gov/states/al/dhr/ccsp/eligibility/income_limit_smi_cap.yaml rename to policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/weeks_to_months.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/weeks_to_months.yaml deleted file mode 100644 index d0433f2a2b8..00000000000 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/weeks_to_months.yaml +++ /dev/null @@ -1,11 +0,0 @@ -description: Alabama multiplies weekly amounts by this factor to convert to monthly amounts under the Child Care Subsidy Program. -values: - 2024-01-01: 4.333 - -metadata: - unit: /1 - period: year - label: Alabama CCSP weekly-to-monthly conversion factor - reference: - - title: Alabama Child Care Fact Sheet (weekly gross income multiplied by 4.333) - href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml index 205125bf188..8f547a451d3 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/full_time_hours_threshold.yaml @@ -1,6 +1,6 @@ description: Alabama treats child care services averaging more than this many weekly hours as full-time under the Child Care Subsidy Program. values: - 2024-01-01: 25 + 2022-04-11: 25 metadata: unit: hour @@ -8,4 +8,4 @@ metadata: label: Alabama CCSP full-time weekly hours threshold reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart (Full-time / Part-time Rates note) - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml index 218896c6225..bcf88450c3a 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/informal_weekly_cap.yaml @@ -1,6 +1,6 @@ description: Alabama caps the weekly reimbursement rate for informal (license-exempt) child care providers under the Child Care Subsidy Program. values: - 2024-01-01: 40 + 2022-04-11: 50 metadata: unit: currency-USD @@ -8,4 +8,4 @@ metadata: label: Alabama CCSP informal-provider weekly rate cap reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart (Informal care providers cap) - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml index 89fab38de9d..3687fc8d901 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/maximum_weekly_full_time.yaml @@ -11,1090 +11,1090 @@ metadata: - al_ccsp_quality_tier reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Maximum Weekly Full-time Rates - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=1 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=1 CENTER: HUNTSVILLE: INFANT_TODDLER: BASE: - 2024-01-01: 138 + 2022-04-11: 165 STAR_1: - 2024-01-01: 141 + 2022-04-11: 168 STAR_2: - 2024-01-01: 144 + 2022-04-11: 172 STAR_3: - 2024-01-01: 146 + 2022-04-11: 175 STAR_4: - 2024-01-01: 149 + 2022-04-11: 179 STAR_5: - 2024-01-01: 152 + 2022-04-11: 182 PRESCHOOL: BASE: - 2024-01-01: 125 + 2022-04-11: 153 STAR_1: - 2024-01-01: 128 + 2022-04-11: 156 STAR_2: - 2024-01-01: 130 + 2022-04-11: 159 STAR_3: - 2024-01-01: 133 + 2022-04-11: 162 STAR_4: - 2024-01-01: 135 + 2022-04-11: 166 STAR_5: - 2024-01-01: 138 + 2022-04-11: 169 SCHOOL_AGE: BASE: - 2024-01-01: 105 + 2022-04-11: 135 STAR_1: - 2024-01-01: 107 + 2022-04-11: 138 STAR_2: - 2024-01-01: 109 + 2022-04-11: 140 STAR_3: - 2024-01-01: 111 + 2022-04-11: 143 STAR_4: - 2024-01-01: 114 + 2022-04-11: 146 STAR_5: - 2024-01-01: 116 + 2022-04-11: 149 TUSCALOOSA: INFANT_TODDLER: BASE: - 2024-01-01: 125 + 2022-04-11: 146 STAR_1: - 2024-01-01: 128 + 2022-04-11: 149 STAR_2: - 2024-01-01: 130 + 2022-04-11: 152 STAR_3: - 2024-01-01: 133 + 2022-04-11: 155 STAR_4: - 2024-01-01: 135 + 2022-04-11: 158 STAR_5: - 2024-01-01: 138 + 2022-04-11: 161 PRESCHOOL: BASE: - 2024-01-01: 120 + 2022-04-11: 136 STAR_1: - 2024-01-01: 122 + 2022-04-11: 139 STAR_2: - 2024-01-01: 125 + 2022-04-11: 141 STAR_3: - 2024-01-01: 127 + 2022-04-11: 144 STAR_4: - 2024-01-01: 130 + 2022-04-11: 147 STAR_5: - 2024-01-01: 132 + 2022-04-11: 150 SCHOOL_AGE: BASE: - 2024-01-01: 115 + 2022-04-11: 125 STAR_1: - 2024-01-01: 117 + 2022-04-11: 128 STAR_2: - 2024-01-01: 120 + 2022-04-11: 130 STAR_3: - 2024-01-01: 122 + 2022-04-11: 133 STAR_4: - 2024-01-01: 124 + 2022-04-11: 135 STAR_5: - 2024-01-01: 127 + 2022-04-11: 138 MOBILE: INFANT_TODDLER: BASE: - 2024-01-01: 125 + 2022-04-11: 145 STAR_1: - 2024-01-01: 128 + 2022-04-11: 148 STAR_2: - 2024-01-01: 130 + 2022-04-11: 151 STAR_3: - 2024-01-01: 133 + 2022-04-11: 154 STAR_4: - 2024-01-01: 135 + 2022-04-11: 157 STAR_5: - 2024-01-01: 138 + 2022-04-11: 160 PRESCHOOL: BASE: - 2024-01-01: 117 + 2022-04-11: 135 STAR_1: - 2024-01-01: 119 + 2022-04-11: 138 STAR_2: - 2024-01-01: 122 + 2022-04-11: 140 STAR_3: - 2024-01-01: 124 + 2022-04-11: 143 STAR_4: - 2024-01-01: 127 + 2022-04-11: 146 STAR_5: - 2024-01-01: 129 + 2022-04-11: 149 SCHOOL_AGE: BASE: - 2024-01-01: 110 + 2022-04-11: 130 STAR_1: - 2024-01-01: 112 + 2022-04-11: 133 STAR_2: - 2024-01-01: 114 + 2022-04-11: 135 STAR_3: - 2024-01-01: 117 + 2022-04-11: 138 STAR_4: - 2024-01-01: 119 + 2022-04-11: 141 STAR_5: - 2024-01-01: 121 + 2022-04-11: 144 FT_PAYNE: INFANT_TODDLER: BASE: - 2024-01-01: 112 + 2022-04-11: 118 STAR_1: - 2024-01-01: 114 + 2022-04-11: 120 STAR_2: - 2024-01-01: 117 + 2022-04-11: 123 STAR_3: - 2024-01-01: 119 + 2022-04-11: 125 STAR_4: - 2024-01-01: 121 + 2022-04-11: 128 STAR_5: - 2024-01-01: 124 + 2022-04-11: 130 PRESCHOOL: BASE: - 2024-01-01: 105 + 2022-04-11: 115 STAR_1: - 2024-01-01: 107 + 2022-04-11: 117 STAR_2: - 2024-01-01: 109 + 2022-04-11: 120 STAR_3: - 2024-01-01: 111 + 2022-04-11: 122 STAR_4: - 2024-01-01: 114 + 2022-04-11: 124 STAR_5: - 2024-01-01: 116 + 2022-04-11: 127 SCHOOL_AGE: BASE: - 2024-01-01: 97 + 2022-04-11: 110 STAR_1: - 2024-01-01: 99 + 2022-04-11: 112 STAR_2: - 2024-01-01: 101 + 2022-04-11: 114 STAR_3: - 2024-01-01: 103 + 2022-04-11: 117 STAR_4: - 2024-01-01: 105 + 2022-04-11: 119 STAR_5: - 2024-01-01: 107 + 2022-04-11: 121 BIRMINGHAM: INFANT_TODDLER: BASE: - 2024-01-01: 150 + 2022-04-11: 195 STAR_1: - 2024-01-01: 153 + 2022-04-11: 199 STAR_2: - 2024-01-01: 156 + 2022-04-11: 203 STAR_3: - 2024-01-01: 159 + 2022-04-11: 207 STAR_4: - 2024-01-01: 162 + 2022-04-11: 211 STAR_5: - 2024-01-01: 166 + 2022-04-11: 215 PRESCHOOL: BASE: - 2024-01-01: 138 + 2022-04-11: 180 STAR_1: - 2024-01-01: 141 + 2022-04-11: 184 STAR_2: - 2024-01-01: 144 + 2022-04-11: 187 STAR_3: - 2024-01-01: 146 + 2022-04-11: 191 STAR_4: - 2024-01-01: 149 + 2022-04-11: 195 STAR_5: - 2024-01-01: 152 + 2022-04-11: 199 SCHOOL_AGE: BASE: - 2024-01-01: 115 + 2022-04-11: 150 STAR_1: - 2024-01-01: 117 + 2022-04-11: 153 STAR_2: - 2024-01-01: 120 + 2022-04-11: 156 STAR_3: - 2024-01-01: 122 + 2022-04-11: 159 STAR_4: - 2024-01-01: 124 + 2022-04-11: 162 STAR_5: - 2024-01-01: 127 + 2022-04-11: 166 TALLADEGA: INFANT_TODDLER: BASE: - 2024-01-01: 111 + 2022-04-11: 120 STAR_1: - 2024-01-01: 113 + 2022-04-11: 122 STAR_2: - 2024-01-01: 115 + 2022-04-11: 125 STAR_3: - 2024-01-01: 118 + 2022-04-11: 127 STAR_4: - 2024-01-01: 120 + 2022-04-11: 130 STAR_5: - 2024-01-01: 123 + 2022-04-11: 132 PRESCHOOL: BASE: - 2024-01-01: 111 + 2022-04-11: 120 STAR_1: - 2024-01-01: 113 + 2022-04-11: 122 STAR_2: - 2024-01-01: 115 + 2022-04-11: 125 STAR_3: - 2024-01-01: 118 + 2022-04-11: 127 STAR_4: - 2024-01-01: 120 + 2022-04-11: 130 STAR_5: - 2024-01-01: 123 + 2022-04-11: 132 SCHOOL_AGE: BASE: - 2024-01-01: 93 + 2022-04-11: 119 STAR_1: - 2024-01-01: 95 + 2022-04-11: 121 STAR_2: - 2024-01-01: 97 + 2022-04-11: 124 STAR_3: - 2024-01-01: 99 + 2022-04-11: 126 STAR_4: - 2024-01-01: 101 + 2022-04-11: 129 STAR_5: - 2024-01-01: 103 + 2022-04-11: 131 MONTGOMERY: INFANT_TODDLER: BASE: - 2024-01-01: 131 + 2022-04-11: 150 STAR_1: - 2024-01-01: 134 + 2022-04-11: 153 STAR_2: - 2024-01-01: 136 + 2022-04-11: 156 STAR_3: - 2024-01-01: 139 + 2022-04-11: 159 STAR_4: - 2024-01-01: 142 + 2022-04-11: 162 STAR_5: - 2024-01-01: 145 + 2022-04-11: 166 PRESCHOOL: BASE: - 2024-01-01: 115 + 2022-04-11: 135 STAR_1: - 2024-01-01: 117 + 2022-04-11: 138 STAR_2: - 2024-01-01: 120 + 2022-04-11: 140 STAR_3: - 2024-01-01: 122 + 2022-04-11: 143 STAR_4: - 2024-01-01: 124 + 2022-04-11: 146 STAR_5: - 2024-01-01: 127 + 2022-04-11: 149 SCHOOL_AGE: BASE: - 2024-01-01: 116 + 2022-04-11: 125 STAR_1: - 2024-01-01: 118 + 2022-04-11: 128 STAR_2: - 2024-01-01: 121 + 2022-04-11: 130 STAR_3: - 2024-01-01: 123 + 2022-04-11: 133 STAR_4: - 2024-01-01: 126 + 2022-04-11: 135 STAR_5: - 2024-01-01: 128 + 2022-04-11: 138 DOTHAN: INFANT_TODDLER: BASE: - 2024-01-01: 107 + 2022-04-11: 125 STAR_1: - 2024-01-01: 109 + 2022-04-11: 128 STAR_2: - 2024-01-01: 111 + 2022-04-11: 130 STAR_3: - 2024-01-01: 114 + 2022-04-11: 133 STAR_4: - 2024-01-01: 116 + 2022-04-11: 135 STAR_5: - 2024-01-01: 118 + 2022-04-11: 138 PRESCHOOL: BASE: - 2024-01-01: 102 + 2022-04-11: 120 STAR_1: - 2024-01-01: 104 + 2022-04-11: 122 STAR_2: - 2024-01-01: 106 + 2022-04-11: 125 STAR_3: - 2024-01-01: 108 + 2022-04-11: 127 STAR_4: - 2024-01-01: 110 + 2022-04-11: 130 STAR_5: - 2024-01-01: 113 + 2022-04-11: 132 SCHOOL_AGE: BASE: - 2024-01-01: 95 + 2022-04-11: 115 STAR_1: - 2024-01-01: 97 + 2022-04-11: 117 STAR_2: - 2024-01-01: 99 + 2022-04-11: 120 STAR_3: - 2024-01-01: 101 + 2022-04-11: 122 STAR_4: - 2024-01-01: 103 + 2022-04-11: 124 STAR_5: - 2024-01-01: 105 + 2022-04-11: 127 OPELIKA: INFANT_TODDLER: BASE: - 2024-01-01: 132 + 2022-04-11: 147 STAR_1: - 2024-01-01: 135 + 2022-04-11: 150 STAR_2: - 2024-01-01: 137 + 2022-04-11: 153 STAR_3: - 2024-01-01: 140 + 2022-04-11: 156 STAR_4: - 2024-01-01: 143 + 2022-04-11: 159 STAR_5: - 2024-01-01: 146 + 2022-04-11: 162 PRESCHOOL: BASE: - 2024-01-01: 120 + 2022-04-11: 140 STAR_1: - 2024-01-01: 122 + 2022-04-11: 143 STAR_2: - 2024-01-01: 125 + 2022-04-11: 146 STAR_3: - 2024-01-01: 127 + 2022-04-11: 149 STAR_4: - 2024-01-01: 130 + 2022-04-11: 152 STAR_5: - 2024-01-01: 132 + 2022-04-11: 155 SCHOOL_AGE: BASE: - 2024-01-01: 109 + 2022-04-11: 140 STAR_1: - 2024-01-01: 111 + 2022-04-11: 143 STAR_2: - 2024-01-01: 113 + 2022-04-11: 146 STAR_3: - 2024-01-01: 116 + 2022-04-11: 149 STAR_4: - 2024-01-01: 118 + 2022-04-11: 152 STAR_5: - 2024-01-01: 120 + 2022-04-11: 155 GFDC: HUNTSVILLE: INFANT_TODDLER: BASE: - 2024-01-01: 132 + 2022-04-11: 145 STAR_1: - 2024-01-01: 135 + 2022-04-11: 148 STAR_2: - 2024-01-01: 137 + 2022-04-11: 151 STAR_3: - 2024-01-01: 140 + 2022-04-11: 154 STAR_4: - 2024-01-01: 143 + 2022-04-11: 157 STAR_5: - 2024-01-01: 146 + 2022-04-11: 160 PRESCHOOL: BASE: - 2024-01-01: 125 + 2022-04-11: 145 STAR_1: - 2024-01-01: 128 + 2022-04-11: 148 STAR_2: - 2024-01-01: 130 + 2022-04-11: 151 STAR_3: - 2024-01-01: 133 + 2022-04-11: 154 STAR_4: - 2024-01-01: 135 + 2022-04-11: 157 STAR_5: - 2024-01-01: 138 + 2022-04-11: 160 SCHOOL_AGE: BASE: - 2024-01-01: 124 + 2022-04-11: 137 STAR_1: - 2024-01-01: 126 + 2022-04-11: 140 STAR_2: - 2024-01-01: 129 + 2022-04-11: 143 STAR_3: - 2024-01-01: 132 + 2022-04-11: 145 STAR_4: - 2024-01-01: 134 + 2022-04-11: 148 STAR_5: - 2024-01-01: 137 + 2022-04-11: 151 TUSCALOOSA: INFANT_TODDLER: BASE: - 2024-01-01: 91 + 2022-04-11: 125 STAR_1: - 2024-01-01: 93 + 2022-04-11: 128 STAR_2: - 2024-01-01: 95 + 2022-04-11: 130 STAR_3: - 2024-01-01: 97 + 2022-04-11: 133 STAR_4: - 2024-01-01: 99 + 2022-04-11: 135 STAR_5: - 2024-01-01: 100 + 2022-04-11: 138 PRESCHOOL: BASE: - 2024-01-01: 93 + 2022-04-11: 125 STAR_1: - 2024-01-01: 95 + 2022-04-11: 128 STAR_2: - 2024-01-01: 97 + 2022-04-11: 130 STAR_3: - 2024-01-01: 99 + 2022-04-11: 133 STAR_4: - 2024-01-01: 101 + 2022-04-11: 135 STAR_5: - 2024-01-01: 103 + 2022-04-11: 138 SCHOOL_AGE: BASE: - 2024-01-01: 93 + 2022-04-11: 125 STAR_1: - 2024-01-01: 95 + 2022-04-11: 128 STAR_2: - 2024-01-01: 97 + 2022-04-11: 130 STAR_3: - 2024-01-01: 99 + 2022-04-11: 133 STAR_4: - 2024-01-01: 101 + 2022-04-11: 135 STAR_5: - 2024-01-01: 103 + 2022-04-11: 138 MOBILE: INFANT_TODDLER: BASE: - 2024-01-01: 122 + 2022-04-11: 134 STAR_1: - 2024-01-01: 124 + 2022-04-11: 137 STAR_2: - 2024-01-01: 127 + 2022-04-11: 139 STAR_3: - 2024-01-01: 129 + 2022-04-11: 142 STAR_4: - 2024-01-01: 132 + 2022-04-11: 145 STAR_5: - 2024-01-01: 135 + 2022-04-11: 148 PRESCHOOL: BASE: - 2024-01-01: 123 + 2022-04-11: 129 STAR_1: - 2024-01-01: 125 + 2022-04-11: 132 STAR_2: - 2024-01-01: 128 + 2022-04-11: 134 STAR_3: - 2024-01-01: 131 + 2022-04-11: 137 STAR_4: - 2024-01-01: 133 + 2022-04-11: 140 STAR_5: - 2024-01-01: 136 + 2022-04-11: 142 SCHOOL_AGE: BASE: - 2024-01-01: 111 + 2022-04-11: 125 STAR_1: - 2024-01-01: 113 + 2022-04-11: 128 STAR_2: - 2024-01-01: 115 + 2022-04-11: 130 STAR_3: - 2024-01-01: 118 + 2022-04-11: 133 STAR_4: - 2024-01-01: 120 + 2022-04-11: 135 STAR_5: - 2024-01-01: 123 + 2022-04-11: 138 FT_PAYNE: INFANT_TODDLER: BASE: - 2024-01-01: 85 + 2022-04-11: 110 STAR_1: - 2024-01-01: 87 + 2022-04-11: 112 STAR_2: - 2024-01-01: 88 + 2022-04-11: 114 STAR_3: - 2024-01-01: 90 + 2022-04-11: 117 STAR_4: - 2024-01-01: 92 + 2022-04-11: 119 STAR_5: - 2024-01-01: 94 + 2022-04-11: 121 PRESCHOOL: BASE: - 2024-01-01: 85 + 2022-04-11: 100 STAR_1: - 2024-01-01: 87 + 2022-04-11: 102 STAR_2: - 2024-01-01: 88 + 2022-04-11: 104 STAR_3: - 2024-01-01: 90 + 2022-04-11: 106 STAR_4: - 2024-01-01: 92 + 2022-04-11: 108 STAR_5: - 2024-01-01: 94 + 2022-04-11: 110 SCHOOL_AGE: BASE: - 2024-01-01: 88 + 2022-04-11: 90 STAR_1: - 2024-01-01: 90 + 2022-04-11: 92 STAR_2: - 2024-01-01: 92 + 2022-04-11: 94 STAR_3: - 2024-01-01: 93 + 2022-04-11: 96 STAR_4: - 2024-01-01: 95 + 2022-04-11: 97 STAR_5: - 2024-01-01: 97 + 2022-04-11: 99 BIRMINGHAM: INFANT_TODDLER: BASE: - 2024-01-01: 125 + 2022-04-11: 144 STAR_1: - 2024-01-01: 128 + 2022-04-11: 147 STAR_2: - 2024-01-01: 130 + 2022-04-11: 150 STAR_3: - 2024-01-01: 133 + 2022-04-11: 153 STAR_4: - 2024-01-01: 135 + 2022-04-11: 156 STAR_5: - 2024-01-01: 138 + 2022-04-11: 159 PRESCHOOL: BASE: - 2024-01-01: 125 + 2022-04-11: 141 STAR_1: - 2024-01-01: 128 + 2022-04-11: 144 STAR_2: - 2024-01-01: 130 + 2022-04-11: 147 STAR_3: - 2024-01-01: 133 + 2022-04-11: 150 STAR_4: - 2024-01-01: 135 + 2022-04-11: 153 STAR_5: - 2024-01-01: 138 + 2022-04-11: 156 SCHOOL_AGE: BASE: - 2024-01-01: 125 + 2022-04-11: 131 STAR_1: - 2024-01-01: 128 + 2022-04-11: 134 STAR_2: - 2024-01-01: 130 + 2022-04-11: 136 STAR_3: - 2024-01-01: 133 + 2022-04-11: 139 STAR_4: - 2024-01-01: 135 + 2022-04-11: 142 STAR_5: - 2024-01-01: 138 + 2022-04-11: 145 TALLADEGA: INFANT_TODDLER: BASE: - 2024-01-01: 100 + 2022-04-11: 115 STAR_1: - 2024-01-01: 102 + 2022-04-11: 117 STAR_2: - 2024-01-01: 104 + 2022-04-11: 120 STAR_3: - 2024-01-01: 106 + 2022-04-11: 122 STAR_4: - 2024-01-01: 108 + 2022-04-11: 124 STAR_5: - 2024-01-01: 110 + 2022-04-11: 127 PRESCHOOL: BASE: - 2024-01-01: 100 + 2022-04-11: 119 STAR_1: - 2024-01-01: 102 + 2022-04-11: 121 STAR_2: - 2024-01-01: 104 + 2022-04-11: 124 STAR_3: - 2024-01-01: 106 + 2022-04-11: 126 STAR_4: - 2024-01-01: 108 + 2022-04-11: 129 STAR_5: - 2024-01-01: 110 + 2022-04-11: 131 SCHOOL_AGE: BASE: - 2024-01-01: 100 + 2022-04-11: 115 STAR_1: - 2024-01-01: 102 + 2022-04-11: 117 STAR_2: - 2024-01-01: 104 + 2022-04-11: 120 STAR_3: - 2024-01-01: 106 + 2022-04-11: 122 STAR_4: - 2024-01-01: 108 + 2022-04-11: 124 STAR_5: - 2024-01-01: 110 + 2022-04-11: 127 MONTGOMERY: INFANT_TODDLER: BASE: - 2024-01-01: 95 + 2022-04-11: 100 STAR_1: - 2024-01-01: 97 + 2022-04-11: 102 STAR_2: - 2024-01-01: 99 + 2022-04-11: 104 STAR_3: - 2024-01-01: 101 + 2022-04-11: 106 STAR_4: - 2024-01-01: 103 + 2022-04-11: 108 STAR_5: - 2024-01-01: 105 + 2022-04-11: 110 PRESCHOOL: BASE: - 2024-01-01: 95 + 2022-04-11: 100 STAR_1: - 2024-01-01: 97 + 2022-04-11: 102 STAR_2: - 2024-01-01: 99 + 2022-04-11: 104 STAR_3: - 2024-01-01: 101 + 2022-04-11: 106 STAR_4: - 2024-01-01: 103 + 2022-04-11: 108 STAR_5: - 2024-01-01: 105 + 2022-04-11: 110 SCHOOL_AGE: BASE: - 2024-01-01: 95 + 2022-04-11: 98 STAR_1: - 2024-01-01: 97 + 2022-04-11: 100 STAR_2: - 2024-01-01: 99 + 2022-04-11: 102 STAR_3: - 2024-01-01: 101 + 2022-04-11: 104 STAR_4: - 2024-01-01: 103 + 2022-04-11: 106 STAR_5: - 2024-01-01: 105 + 2022-04-11: 108 DOTHAN: INFANT_TODDLER: BASE: - 2024-01-01: 100 + 2022-04-11: 100 STAR_1: - 2024-01-01: 102 + 2022-04-11: 102 STAR_2: - 2024-01-01: 104 + 2022-04-11: 104 STAR_3: - 2024-01-01: 106 + 2022-04-11: 106 STAR_4: - 2024-01-01: 108 + 2022-04-11: 108 STAR_5: - 2024-01-01: 110 + 2022-04-11: 110 PRESCHOOL: BASE: - 2024-01-01: 100 + 2022-04-11: 110 STAR_1: - 2024-01-01: 102 + 2022-04-11: 112 STAR_2: - 2024-01-01: 104 + 2022-04-11: 114 STAR_3: - 2024-01-01: 106 + 2022-04-11: 117 STAR_4: - 2024-01-01: 108 + 2022-04-11: 119 STAR_5: - 2024-01-01: 110 + 2022-04-11: 121 SCHOOL_AGE: BASE: - 2024-01-01: 100 + 2022-04-11: 100 STAR_1: - 2024-01-01: 102 + 2022-04-11: 102 STAR_2: - 2024-01-01: 104 + 2022-04-11: 104 STAR_3: - 2024-01-01: 106 + 2022-04-11: 106 STAR_4: - 2024-01-01: 108 + 2022-04-11: 108 STAR_5: - 2024-01-01: 110 + 2022-04-11: 110 OPELIKA: INFANT_TODDLER: BASE: - 2024-01-01: 128 + 2022-04-11: 148 STAR_1: - 2024-01-01: 131 + 2022-04-11: 151 STAR_2: - 2024-01-01: 133 + 2022-04-11: 154 STAR_3: - 2024-01-01: 136 + 2022-04-11: 157 STAR_4: - 2024-01-01: 139 + 2022-04-11: 160 STAR_5: - 2024-01-01: 141 + 2022-04-11: 163 PRESCHOOL: BASE: - 2024-01-01: 123 + 2022-04-11: 145 STAR_1: - 2024-01-01: 125 + 2022-04-11: 148 STAR_2: - 2024-01-01: 128 + 2022-04-11: 151 STAR_3: - 2024-01-01: 131 + 2022-04-11: 154 STAR_4: - 2024-01-01: 133 + 2022-04-11: 157 STAR_5: - 2024-01-01: 136 + 2022-04-11: 160 SCHOOL_AGE: BASE: - 2024-01-01: 115 + 2022-04-11: 138 STAR_1: - 2024-01-01: 117 + 2022-04-11: 141 STAR_2: - 2024-01-01: 120 + 2022-04-11: 144 STAR_3: - 2024-01-01: 122 + 2022-04-11: 146 STAR_4: - 2024-01-01: 124 + 2022-04-11: 149 STAR_5: - 2024-01-01: 127 + 2022-04-11: 152 FDC: HUNTSVILLE: INFANT_TODDLER: BASE: - 2024-01-01: 135 + 2022-04-11: 150 STAR_1: - 2024-01-01: 138 + 2022-04-11: 153 STAR_2: - 2024-01-01: 140 + 2022-04-11: 156 STAR_3: - 2024-01-01: 143 + 2022-04-11: 159 STAR_4: - 2024-01-01: 146 + 2022-04-11: 162 STAR_5: - 2024-01-01: 149 + 2022-04-11: 166 PRESCHOOL: BASE: - 2024-01-01: 131 + 2022-04-11: 150 STAR_1: - 2024-01-01: 134 + 2022-04-11: 153 STAR_2: - 2024-01-01: 136 + 2022-04-11: 156 STAR_3: - 2024-01-01: 139 + 2022-04-11: 159 STAR_4: - 2024-01-01: 142 + 2022-04-11: 162 STAR_5: - 2024-01-01: 145 + 2022-04-11: 166 SCHOOL_AGE: BASE: - 2024-01-01: 130 + 2022-04-11: 150 STAR_1: - 2024-01-01: 133 + 2022-04-11: 153 STAR_2: - 2024-01-01: 135 + 2022-04-11: 156 STAR_3: - 2024-01-01: 138 + 2022-04-11: 159 STAR_4: - 2024-01-01: 141 + 2022-04-11: 162 STAR_5: - 2024-01-01: 144 + 2022-04-11: 166 TUSCALOOSA: INFANT_TODDLER: BASE: - 2024-01-01: 105 + 2022-04-11: 118 STAR_1: - 2024-01-01: 107 + 2022-04-11: 120 STAR_2: - 2024-01-01: 109 + 2022-04-11: 123 STAR_3: - 2024-01-01: 111 + 2022-04-11: 125 STAR_4: - 2024-01-01: 114 + 2022-04-11: 128 STAR_5: - 2024-01-01: 116 + 2022-04-11: 130 PRESCHOOL: BASE: - 2024-01-01: 100 + 2022-04-11: 115 STAR_1: - 2024-01-01: 102 + 2022-04-11: 117 STAR_2: - 2024-01-01: 104 + 2022-04-11: 120 STAR_3: - 2024-01-01: 106 + 2022-04-11: 122 STAR_4: - 2024-01-01: 108 + 2022-04-11: 124 STAR_5: - 2024-01-01: 110 + 2022-04-11: 127 SCHOOL_AGE: BASE: - 2024-01-01: 100 + 2022-04-11: 100 STAR_1: - 2024-01-01: 102 + 2022-04-11: 102 STAR_2: - 2024-01-01: 104 + 2022-04-11: 104 STAR_3: - 2024-01-01: 106 + 2022-04-11: 106 STAR_4: - 2024-01-01: 108 + 2022-04-11: 108 STAR_5: - 2024-01-01: 110 + 2022-04-11: 110 MOBILE: INFANT_TODDLER: BASE: - 2024-01-01: 125 + 2022-04-11: 134 STAR_1: - 2024-01-01: 128 + 2022-04-11: 137 STAR_2: - 2024-01-01: 130 + 2022-04-11: 139 STAR_3: - 2024-01-01: 133 + 2022-04-11: 142 STAR_4: - 2024-01-01: 135 + 2022-04-11: 145 STAR_5: - 2024-01-01: 138 + 2022-04-11: 148 PRESCHOOL: BASE: - 2024-01-01: 125 + 2022-04-11: 130 STAR_1: - 2024-01-01: 128 + 2022-04-11: 133 STAR_2: - 2024-01-01: 130 + 2022-04-11: 135 STAR_3: - 2024-01-01: 133 + 2022-04-11: 138 STAR_4: - 2024-01-01: 135 + 2022-04-11: 141 STAR_5: - 2024-01-01: 138 + 2022-04-11: 144 SCHOOL_AGE: BASE: - 2024-01-01: 125 + 2022-04-11: 125 STAR_1: - 2024-01-01: 128 + 2022-04-11: 128 STAR_2: - 2024-01-01: 130 + 2022-04-11: 130 STAR_3: - 2024-01-01: 133 + 2022-04-11: 133 STAR_4: - 2024-01-01: 135 + 2022-04-11: 135 STAR_5: - 2024-01-01: 138 + 2022-04-11: 138 FT_PAYNE: INFANT_TODDLER: BASE: - 2024-01-01: 81 + 2022-04-11: 90 STAR_1: - 2024-01-01: 83 + 2022-04-11: 92 STAR_2: - 2024-01-01: 84 + 2022-04-11: 94 STAR_3: - 2024-01-01: 86 + 2022-04-11: 96 STAR_4: - 2024-01-01: 88 + 2022-04-11: 97 STAR_5: - 2024-01-01: 89 + 2022-04-11: 99 PRESCHOOL: BASE: - 2024-01-01: 75 + 2022-04-11: 90 STAR_1: - 2024-01-01: 77 + 2022-04-11: 92 STAR_2: - 2024-01-01: 78 + 2022-04-11: 94 STAR_3: - 2024-01-01: 80 + 2022-04-11: 96 STAR_4: - 2024-01-01: 81 + 2022-04-11: 97 STAR_5: - 2024-01-01: 83 + 2022-04-11: 99 SCHOOL_AGE: BASE: - 2024-01-01: 75 + 2022-04-11: 90 STAR_1: - 2024-01-01: 77 + 2022-04-11: 92 STAR_2: - 2024-01-01: 78 + 2022-04-11: 94 STAR_3: - 2024-01-01: 80 + 2022-04-11: 96 STAR_4: - 2024-01-01: 81 + 2022-04-11: 97 STAR_5: - 2024-01-01: 83 + 2022-04-11: 99 BIRMINGHAM: INFANT_TODDLER: BASE: - 2024-01-01: 125 + 2022-04-11: 150 STAR_1: - 2024-01-01: 128 + 2022-04-11: 153 STAR_2: - 2024-01-01: 130 + 2022-04-11: 156 STAR_3: - 2024-01-01: 133 + 2022-04-11: 159 STAR_4: - 2024-01-01: 135 + 2022-04-11: 162 STAR_5: - 2024-01-01: 138 + 2022-04-11: 166 PRESCHOOL: BASE: - 2024-01-01: 120 + 2022-04-11: 145 STAR_1: - 2024-01-01: 122 + 2022-04-11: 148 STAR_2: - 2024-01-01: 125 + 2022-04-11: 151 STAR_3: - 2024-01-01: 127 + 2022-04-11: 154 STAR_4: - 2024-01-01: 130 + 2022-04-11: 157 STAR_5: - 2024-01-01: 132 + 2022-04-11: 160 SCHOOL_AGE: BASE: - 2024-01-01: 110 + 2022-04-11: 133 STAR_1: - 2024-01-01: 112 + 2022-04-11: 136 STAR_2: - 2024-01-01: 114 + 2022-04-11: 138 STAR_3: - 2024-01-01: 117 + 2022-04-11: 141 STAR_4: - 2024-01-01: 119 + 2022-04-11: 144 STAR_5: - 2024-01-01: 121 + 2022-04-11: 147 TALLADEGA: INFANT_TODDLER: BASE: - 2024-01-01: 98 + 2022-04-11: 120 STAR_1: - 2024-01-01: 100 + 2022-04-11: 122 STAR_2: - 2024-01-01: 102 + 2022-04-11: 125 STAR_3: - 2024-01-01: 104 + 2022-04-11: 127 STAR_4: - 2024-01-01: 106 + 2022-04-11: 130 STAR_5: - 2024-01-01: 108 + 2022-04-11: 132 PRESCHOOL: BASE: - 2024-01-01: 99 + 2022-04-11: 120 STAR_1: - 2024-01-01: 101 + 2022-04-11: 122 STAR_2: - 2024-01-01: 103 + 2022-04-11: 125 STAR_3: - 2024-01-01: 105 + 2022-04-11: 127 STAR_4: - 2024-01-01: 107 + 2022-04-11: 130 STAR_5: - 2024-01-01: 109 + 2022-04-11: 132 SCHOOL_AGE: BASE: - 2024-01-01: 90 + 2022-04-11: 128 STAR_1: - 2024-01-01: 92 + 2022-04-11: 131 STAR_2: - 2024-01-01: 94 + 2022-04-11: 133 STAR_3: - 2024-01-01: 96 + 2022-04-11: 136 STAR_4: - 2024-01-01: 97 + 2022-04-11: 139 STAR_5: - 2024-01-01: 99 + 2022-04-11: 141 MONTGOMERY: INFANT_TODDLER: BASE: - 2024-01-01: 122 + 2022-04-11: 135 STAR_1: - 2024-01-01: 124 + 2022-04-11: 138 STAR_2: - 2024-01-01: 127 + 2022-04-11: 140 STAR_3: - 2024-01-01: 129 + 2022-04-11: 143 STAR_4: - 2024-01-01: 132 + 2022-04-11: 146 STAR_5: - 2024-01-01: 135 + 2022-04-11: 149 PRESCHOOL: BASE: - 2024-01-01: 115 + 2022-04-11: 135 STAR_1: - 2024-01-01: 117 + 2022-04-11: 138 STAR_2: - 2024-01-01: 120 + 2022-04-11: 140 STAR_3: - 2024-01-01: 122 + 2022-04-11: 143 STAR_4: - 2024-01-01: 124 + 2022-04-11: 146 STAR_5: - 2024-01-01: 127 + 2022-04-11: 149 SCHOOL_AGE: BASE: - 2024-01-01: 115 + 2022-04-11: 128 STAR_1: - 2024-01-01: 117 + 2022-04-11: 131 STAR_2: - 2024-01-01: 120 + 2022-04-11: 133 STAR_3: - 2024-01-01: 122 + 2022-04-11: 136 STAR_4: - 2024-01-01: 124 + 2022-04-11: 139 STAR_5: - 2024-01-01: 127 + 2022-04-11: 141 DOTHAN: INFANT_TODDLER: BASE: - 2024-01-01: 90 + 2022-04-11: 103 STAR_1: - 2024-01-01: 92 + 2022-04-11: 105 STAR_2: - 2024-01-01: 94 + 2022-04-11: 107 STAR_3: - 2024-01-01: 96 + 2022-04-11: 109 STAR_4: - 2024-01-01: 97 + 2022-04-11: 111 STAR_5: - 2024-01-01: 99 + 2022-04-11: 114 PRESCHOOL: BASE: - 2024-01-01: 90 + 2022-04-11: 103 STAR_1: - 2024-01-01: 92 + 2022-04-11: 105 STAR_2: - 2024-01-01: 94 + 2022-04-11: 107 STAR_3: - 2024-01-01: 96 + 2022-04-11: 109 STAR_4: - 2024-01-01: 97 + 2022-04-11: 111 STAR_5: - 2024-01-01: 99 + 2022-04-11: 114 SCHOOL_AGE: BASE: - 2024-01-01: 85 + 2022-04-11: 88 STAR_1: - 2024-01-01: 87 + 2022-04-11: 90 STAR_2: - 2024-01-01: 88 + 2022-04-11: 92 STAR_3: - 2024-01-01: 90 + 2022-04-11: 93 STAR_4: - 2024-01-01: 92 + 2022-04-11: 95 STAR_5: - 2024-01-01: 94 + 2022-04-11: 97 OPELIKA: INFANT_TODDLER: BASE: - 2024-01-01: 134 + 2022-04-11: 140 STAR_1: - 2024-01-01: 137 + 2022-04-11: 143 STAR_2: - 2024-01-01: 139 + 2022-04-11: 146 STAR_3: - 2024-01-01: 142 + 2022-04-11: 149 STAR_4: - 2024-01-01: 145 + 2022-04-11: 152 STAR_5: - 2024-01-01: 148 + 2022-04-11: 155 PRESCHOOL: BASE: - 2024-01-01: 129 + 2022-04-11: 138 STAR_1: - 2024-01-01: 132 + 2022-04-11: 141 STAR_2: - 2024-01-01: 134 + 2022-04-11: 144 STAR_3: - 2024-01-01: 137 + 2022-04-11: 146 STAR_4: - 2024-01-01: 140 + 2022-04-11: 149 STAR_5: - 2024-01-01: 142 + 2022-04-11: 152 SCHOOL_AGE: BASE: - 2024-01-01: 125 + 2022-04-11: 130 STAR_1: - 2024-01-01: 128 + 2022-04-11: 133 STAR_2: - 2024-01-01: 130 + 2022-04-11: 135 STAR_3: - 2024-01-01: 133 + 2022-04-11: 138 STAR_4: - 2024-01-01: 135 + 2022-04-11: 141 STAR_5: - 2024-01-01: 138 + 2022-04-11: 144 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml index a4311f32308..c193d813b5c 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/rates/part_time_multiplier.yaml @@ -1,6 +1,6 @@ description: Alabama applies this multiplier to the full-time provider rate to compute the part-time rate under the Child Care Subsidy Program. values: - 2024-01-01: 0.5 + 2022-04-11: 0.5 metadata: unit: /1 @@ -8,4 +8,4 @@ metadata: label: Alabama CCSP part-time rate multiplier reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart (Part-time Rates) - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml index 6be9189c68a..c197d84612f 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/region/counties.yaml @@ -8,10 +8,10 @@ metadata: - al_ccsp_region reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Regions and Counties Served - href: https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=1 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=1 HUNTSVILLE: - 2024-01-01: + 2022-04-11: - COLBERT_COUNTY_AL - CULLMAN_COUNTY_AL - FRANKLIN_COUNTY_AL @@ -22,7 +22,7 @@ HUNTSVILLE: - MORGAN_COUNTY_AL - WINSTON_COUNTY_AL TUSCALOOSA: - 2024-01-01: + 2022-04-11: - BIBB_COUNTY_AL - CHOCTAW_COUNTY_AL - FAYETTE_COUNTY_AL @@ -36,7 +36,7 @@ TUSCALOOSA: - SUMTER_COUNTY_AL - TUSCALOOSA_COUNTY_AL MOBILE: - 2024-01-01: + 2022-04-11: - BALDWIN_COUNTY_AL - CLARKE_COUNTY_AL - CONECUH_COUNTY_AL @@ -45,21 +45,21 @@ MOBILE: - MONROE_COUNTY_AL - WASHINGTON_COUNTY_AL FT_PAYNE: - 2024-01-01: + 2022-04-11: - CHEROKEE_COUNTY_AL - DEKALB_COUNTY_AL - ETOWAH_COUNTY_AL - JACKSON_COUNTY_AL - MARSHALL_COUNTY_AL BIRMINGHAM: - 2024-01-01: + 2022-04-11: - BLOUNT_COUNTY_AL - JEFFERSON_COUNTY_AL - ST_CLAIR_COUNTY_AL - SHELBY_COUNTY_AL - WALKER_COUNTY_AL TALLADEGA: - 2024-01-01: + 2022-04-11: - CALHOUN_COUNTY_AL - CLAY_COUNTY_AL - CLEBURNE_COUNTY_AL @@ -67,7 +67,7 @@ TALLADEGA: - RANDOLPH_COUNTY_AL - TALLADEGA_COUNTY_AL MONTGOMERY: - 2024-01-01: + 2022-04-11: - AUTAUGA_COUNTY_AL - BULLOCK_COUNTY_AL - BUTLER_COUNTY_AL @@ -79,7 +79,7 @@ MONTGOMERY: - MONTGOMERY_COUNTY_AL - WILCOX_COUNTY_AL DOTHAN: - 2024-01-01: + 2022-04-11: - BARBOUR_COUNTY_AL - COFFEE_COUNTY_AL - CRENSHAW_COUNTY_AL @@ -89,7 +89,7 @@ DOTHAN: - HOUSTON_COUNTY_AL - PIKE_COUNTY_AL OPELIKA: - 2024-01-01: + 2022-04-11: - CHAMBERS_COUNTY_AL - LEE_COUNTY_AL - MACON_COUNTY_AL diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml index eecf23610c3..246f3eadf27 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml @@ -1,6 +1,6 @@ # AL CCSP benefit tests (SPMUnit, MONTH, USD) # per_child_weekly_subsidy = max(0, min(weekly_charge, max_weekly_rate) - weekly_copay_per_child) -# monthly_subsidy = per_child_weekly_subsidy * 4.333 * eligible_child +# monthly_subsidy = per_child_weekly_subsidy * (52/12) * eligible_child # al_ccsp = sum over SPMUnit members. - name: Ineligible family gets zero benefit. @@ -75,13 +75,13 @@ state_code: AL county_str: JEFFERSON_COUNTY_AL output: - # BIRMINGHAM CENTER PRESCHOOL BASE = $138/wk + # BIRMINGHAM CENTER PRESCHOOL BASE = $180/wk # Weekly charge = 10,000 / 52 = $192.31 - # min($192.31, $138) = $138 + # min($192.31, $180) = $180 # copay = $0 - # weekly subsidy = $138 - # monthly subsidy = $138 * 4.333 = $597.95 - al_ccsp: 597.95 + # weekly subsidy = $180 + # monthly subsidy = $180 * (52/12) = $780 + al_ccsp: 780 - name: Family at 150 percent FPL with copay. period: 2024-01 @@ -114,11 +114,11 @@ state_code: AL county_str: JEFFERSON_COUNTY_AL output: - # BIRMINGHAM CENTER PRESCHOOL BASE = $138/wk - # weekly charge = 10,000 / 52 = $192.31; min(192.31, 138) = $138 - # copay = $30/wk; weekly subsidy = $138 - $30 = $108 - # monthly subsidy = $108 * 4.333 = $467.96 - al_ccsp: 467.96 + # BIRMINGHAM CENTER PRESCHOOL BASE = $180/wk + # weekly charge = 10,000 / 52 = $192.31; min(192.31, 180) = $180 + # copay = $30/wk; weekly subsidy = $180 - $30 = $150 + # monthly subsidy = $150 * (52/12) = $650 + al_ccsp: 650 - name: Provider charge below max rate caps subsidy at charge minus copay. period: 2024-01 @@ -151,6 +151,64 @@ state_code: AL county_str: JEFFERSON_COUNTY_AL output: - # weekly charge = $100; max rate = $138; min = $100; copay = $0 - # monthly subsidy = $100 * 4.333 = $433.30 - al_ccsp: 433.3 + # weekly charge = $100; max rate = $180; min = $100; copay = $0 + # monthly subsidy = $100 * (52/12) = $433.33 + al_ccsp: 433.33 + +- name: Three children with only one eligible subsidizes only the eligible child. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 18_000 # ~58% FPL fam of 4 -> zero copay band + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + # Truly eligible: age 4, citizen, dependent, in care + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 10_000 + person3: + # Over age (>= 13): ineligible, in care + age: 14 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 10_000 + person4: + # Undocumented: ineligible by immigration, in care + age: 6 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_pre_subsidy_childcare_expenses: 30_000 + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # Only person2 is is_paying_child (eligible_child & in_care). + # BIRMINGHAM CENTER PRESCHOOL BASE = $180/wk for person2. + # weekly charge = $10,000 / 52 = $192.31; min($192.31, $180) = $180 + # copay = $0/wk (zero-copay band); weekly subsidy = $180 + # monthly subsidy = $180 * (52/12) = $780 + # Ineligible siblings get zero subsidy. + al_ccsp: 780 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml index 45eacf7c249..2780808bea9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml @@ -1,5 +1,5 @@ # AL CCSP age category tests (Person, MONTH, Enum) -# Bracket on age-in-months -> {INFANT_TODDLER (0-35mo), PRESCHOOL (36-59mo), SCHOOL_AGE (60mo+)}. +# Bracket on age-in-months -> {INFANT_TODDLER (0-36mo), PRESCHOOL (37-59mo), SCHOOL_AGE (60mo+)}. - name: Infant age 0 is INFANT_TODDLER. period: 2024-01 @@ -27,7 +27,7 @@ output: al_ccsp_age_category: INFANT_TODDLER -- name: Child age 3 is PRESCHOOL. +- name: Child age 3 (exactly 36 months) is INFANT_TODDLER. period: 2024-01 input: people: @@ -38,7 +38,8 @@ members: [person1] state_code: AL output: - al_ccsp_age_category: PRESCHOOL + # 36 months is below the PRESCHOOL threshold of 37 months. + al_ccsp_age_category: INFANT_TODDLER - name: Child age 4 is PRESCHOOL. period: 2024-01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml index 21ec415aed3..d4cce7b254b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml @@ -335,3 +335,257 @@ # Homelessness alone is NOT a copay waiver in AL. # Fee is still owed: 150% FPL -> $30/wk -> $30 * 4.333 = $130.00/mo al_ccsp_copay: 129.99 + +- name: Three children, only one truly eligible, copay counts only the eligible one. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 46_800 # 150% FPL fam of 4 = $46,800/yr -> $3,900/mo + person2: + # Truly eligible: age 4, citizen, dependent, in care + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person3: + # Over age (>= 13): citizen, dependent, in care, but ineligible by age + age: 14 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person4: + # Ineligible immigration status: dependent, in care, but undocumented + age: 6 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 150% FPL fam of 4 -> $30/wk per child + # Only person2 is eligible_child & in_care -> num_paying = 1 + # 1 * $30/wk * (52/12) = $130.00/mo + al_ccsp_copay: 130 + +- name: Two eligible children but only one in care, copay counts the one in care. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 38_730 # 150% FPL fam of 3 = $38,730/yr -> $3,228/mo + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person3: + # Eligible but not in care this month + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 150% FPL -> $30/wk per child + # Only person2 has childcare_hours > 0 -> num_paying = 1 + # 1 * $30/wk * (52/12) = $130.00/mo + al_ccsp_copay: 130 + +- name: Eligible child with zero care hours has zero copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 30_660 # 150% FPL fam of 2 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 0 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # Eligible but not in care -> num_paying = 0 -> no copay owed + al_ccsp_copay: 0 + +- name: Disabled child age 15 plus young eligible sibling both in care waives copay. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 35_000 # would otherwise be a paid tier + person2: + # Young eligible sibling, in care + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person3: + # Disabled child age 15: eligible under disabled limit (19), triggers waiver + age: 15 + is_tax_unit_dependent: true + immigration_status: CITIZEN + is_disabled: true + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # Disabled child (age 15 < 19) triggers copay waiver per §3.3.1(iv). + al_ccsp_copay: 0 + +- name: Three eligible children all in care pays three times the per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 54_870 # 150% FPL fam of 5 = $54,870/yr + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person3: + age: 6 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person4: + age: 8 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person5: + age: 28 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 150% FPL fam of 5 -> $30/wk per child band. + # 3 children * $30/wk * (52/12) = $90 * 4.3333 = $390.00/mo + al_ccsp_copay: 390 + +- name: Two-parent family with three children, only one eligible, copay counts that one. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 54_870 # 150% FPL fam of 5 = $54,870/yr + person2: + # Second parent + age: 28 + person3: + # Truly eligible: age 4, citizen, dependent, in care + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person4: + # Over age (>= 13): ineligible by age, in care + age: 14 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + person5: + # Ineligible immigration status, in care + age: 6 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # 150% FPL fam of 5 -> $30/wk per child + # Only person3 is eligible_child & in_care -> num_paying = 1 + # 1 * $30/wk * (52/12) = $130.00/mo + al_ccsp_copay: 130 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml new file mode 100644 index 00000000000..6923e0b558e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml @@ -0,0 +1,120 @@ +# AL CCSP copay waiver tests (SPMUnit, MONTH, bool). +# Per CCDF State Plan §3.3.1, copay is waived for families that include: +# (iv) a disabled child (under disabled_child_limit, age 19) +# (v) a child enrolled in Head Start / Early Head Start +# (vi) a foster child +# Homelessness alone is NOT a waiver (§3.3.1(iii) is unchecked). + +- name: Case 1, family with disabled child waives copay. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_tax_unit_dependent: true + is_disabled: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_copay_waived: true + +- name: Case 2, family with Head Start enrolled child waives copay. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + is_enrolled_in_head_start: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_copay_waived: true + +- name: Case 3, family with foster child waives copay. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 5 + is_tax_unit_dependent: true + is_in_foster_care: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_copay_waived: true + +- name: Case 4, family with no waiver triggers does not waive copay. + period: 2024-01 + input: + people: + person1: + age: 30 + 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: AL + output: + al_ccsp_copay_waived: false + +- name: Case 5, disabled adult (non-dependent) does not trigger waiver. + period: 2024-01 + input: + people: + person1: + age: 30 + is_disabled: true + 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: AL + output: + al_ccsp_copay_waived: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml index 2cbc2e6f510..66dde49418d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml @@ -1,5 +1,5 @@ # AL CCSP eligible child tests (Person, MONTH) -# Combines: child_age_limit (<13) or disabled_child_age_limit (<19 if disabled), +# Combines: age.child_limit (<13) or age.disabled_child_limit (<19 if disabled), # is_ccdf_immigration_eligible_child, is_tax_unit_dependent. - name: Child age 4 citizen dependent is eligible. @@ -213,3 +213,43 @@ state_code: GA output: al_ccsp_eligible_child: [false, false] + +- name: Multi-child family with mixed ages and immigration statuses. + period: 2024-01 + input: + people: + person1: + # Parent (age 30, not a child) + age: 30 + immigration_status: CITIZEN + person2: + # Eligible: age 4, citizen, dependent + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person3: + # Ineligible by age: age 14 >= 13 + age: 14 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person4: + # Ineligible by immigration: age 6 but undocumented + age: 6 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # Parent: not under age 13 -> false + # person2: age 4 + citizen + dependent -> true + # person3: age 14 fails age check -> false + # person4: undocumented fails immigration check -> false + al_ccsp_eligible_child: [false, true, false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml index dd08ea78203..a08a1457b1b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml @@ -1,10 +1,10 @@ # AL CCSP maximum weekly provider rate tests (Person, MONTH, USD) # Looked up by provider_type x region x age_category x quality_tier. # Full-time when childcare_hours_per_week > 25; otherwise rate is halved (part-time multiplier 0.5). -# INFORMAL provider has a flat $40/wk cap regardless of region/age/quality. +# INFORMAL provider has a flat $50/wk cap regardless of region/age/quality. # defined_for: al_ccsp_eligible_child (Person, MONTH). -- name: CENTER BIRMINGHAM PRESCHOOL STAR_3 full-time is 146 per week. +- name: CENTER BIRMINGHAM PRESCHOOL STAR_3 full-time is 191 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -30,9 +30,9 @@ state_code: AL county_str: JEFFERSON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 146] + al_ccsp_maximum_weekly_rate: [0, 191] -- name: CENTER HUNTSVILLE INFANT_TODDLER BASE full-time is 138 per week. +- name: CENTER HUNTSVILLE INFANT_TODDLER BASE full-time is 165 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -58,9 +58,9 @@ state_code: AL county_str: MADISON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 138] + al_ccsp_maximum_weekly_rate: [0, 165] -- name: GFDC HUNTSVILLE SCHOOL_AGE STAR_5 full-time is 137 per week. +- name: GFDC HUNTSVILLE SCHOOL_AGE STAR_5 full-time is 151 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -86,9 +86,9 @@ state_code: AL county_str: MADISON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 137] + al_ccsp_maximum_weekly_rate: [0, 151] -- name: FDC MOBILE INFANT_TODDLER BASE full-time is 125 per week. +- name: FDC MOBILE INFANT_TODDLER BASE full-time is 134 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -114,7 +114,7 @@ state_code: AL county_str: MOBILE_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 125] + al_ccsp_maximum_weekly_rate: [0, 134] - name: Part-time care halves full-time rate. period: 2024-01 @@ -140,11 +140,11 @@ household: members: [person1, person2] state_code: AL - county_str: JEFFERSON_COUNTY_AL # BIRMINGHAM, PRESCHOOL STAR_3 = $146 -> half = $73 + county_str: JEFFERSON_COUNTY_AL # BIRMINGHAM, PRESCHOOL STAR_3 = $191 -> half = $95.5 output: - al_ccsp_maximum_weekly_rate: [0, 73] + al_ccsp_maximum_weekly_rate: [0, 95.5] -- name: INFORMAL provider capped at 40 per week regardless of region. +- name: INFORMAL provider capped at 50 per week regardless of region. period: 2024-01 absolute_error_margin: 0.1 input: @@ -169,7 +169,7 @@ state_code: AL county_str: JEFFERSON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 40] + al_ccsp_maximum_weekly_rate: [0, 50] - name: Adult gets zero rate (not an eligible child). period: 2024-01 @@ -200,9 +200,9 @@ state_code: AL county_str: JEFFERSON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 146] + al_ccsp_maximum_weekly_rate: [0, 191] -- name: CENTER HUNTSVILLE INFANT_TODDLER STAR_1 full-time is 141 per week. +- name: CENTER HUNTSVILLE INFANT_TODDLER STAR_1 full-time is 168 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -228,9 +228,9 @@ state_code: AL county_str: MADISON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 141] + al_ccsp_maximum_weekly_rate: [0, 168] -- name: CENTER HUNTSVILLE INFANT_TODDLER STAR_2 full-time is 144 per week. +- name: CENTER HUNTSVILLE INFANT_TODDLER STAR_2 full-time is 172 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -256,9 +256,9 @@ state_code: AL county_str: MADISON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 144] + al_ccsp_maximum_weekly_rate: [0, 172] -- name: CENTER HUNTSVILLE INFANT_TODDLER STAR_4 full-time is 149 per week. +- name: CENTER HUNTSVILLE INFANT_TODDLER STAR_4 full-time is 179 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -284,4 +284,4 @@ state_code: AL county_str: MADISON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 149] + al_ccsp_maximum_weekly_rate: [0, 179] diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml index 2c6e8331769..97e75e87196 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml @@ -1,6 +1,7 @@ # AL CCSP weekly per-child parental fee tests (SPMUnit, MONTH). -# Initial tier (al_ccsp_enrolled=false) uses the 9-band initial fee schedule. -# Continuing tier (al_ccsp_enrolled=true) uses the 2-band continuing fee schedule. +# Unified 11-band fee schedule indexed by FPL ratio (0-200% FPL). +# Initial applicants must be at or below 180% FPL; continuing recipients may +# remain enrolled up to 200% FPL. Both tiers use the same fee schedule. # # 2024 FPG (Contiguous US), family of 4: $31,200/yr = $2,600/mo. # 80% FPL fam of 4 = $24,960/yr ($2,080/mo) @@ -8,7 +9,7 @@ # 185% FPL fam of 4 = $57,720/yr ($4,810/mo) # 195% FPL fam of 4 = $60,840/yr ($5,070/mo) -- name: Initial tier at 150 percent FPL has $30 weekly per-child fee. +- name: Family at 150 percent FPL has $30 weekly per-child fee. period: 2024-01 absolute_error_margin: 0.1 input: @@ -36,10 +37,10 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 3,900 / 2,600 = 1.5 -> initial tier band [1.4001, 1.5001) -> $30/wk + # FPL ratio = 3,900 / 2,600 = 1.5 -> band [1.4001, 1.5001) -> $30/wk al_ccsp_weekly_copay_per_child: 30 -- name: Initial tier at 80 percent FPL has zero weekly per-child fee. +- name: Family at 80 percent FPL has zero weekly per-child fee. period: 2024-01 absolute_error_margin: 0.1 input: @@ -67,10 +68,10 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 2,080 / 2,600 = 0.8 -> initial tier band [0, 1.0001) -> $0/wk + # FPL ratio = 2,080 / 2,600 = 0.8 -> band [0, 1.0001) -> $0/wk al_ccsp_weekly_copay_per_child: 0 -- name: Continuing tier at 185 percent FPL has $42 weekly per-child fee. +- name: Enrolled family at 185 percent FPL has $42 weekly per-child fee. period: 2024-01 absolute_error_margin: 0.1 input: @@ -98,10 +99,10 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 4,810 / 2,600 = 1.85 -> continuing tier band [1.8001, 1.9001) -> $42/wk + # FPL ratio = 4,810 / 2,600 = 1.85 -> band [1.8001, 1.9001) -> $42/wk al_ccsp_weekly_copay_per_child: 42 -- name: Continuing tier at 195 percent FPL has $45 weekly per-child fee. +- name: Enrolled family at 195 percent FPL has $45 weekly per-child fee. period: 2024-01 absolute_error_margin: 0.1 input: @@ -129,5 +130,5 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 5,070 / 2,600 = 1.95 -> continuing tier band [1.9001, ...) -> $45/wk + # FPL ratio = 5,070 / 2,600 = 1.95 -> band [1.9001, ...) -> $45/wk al_ccsp_weekly_copay_per_child: 45 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_child_care_subsidies.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_child_care_subsidies.yaml index 0cc7d77b5c5..9f116aab770 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_child_care_subsidies.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_child_care_subsidies.yaml @@ -64,6 +64,6 @@ state_code: AL county_str: JEFFERSON_COUNTY_AL output: - # Monthly al_ccsp = $597.95 (BIRMINGHAM CENTER PRESCHOOL BASE $138 * 4.333) - # Annual = 12 * $597.95 = $7,175.40 - al_child_care_subsidies: 7175.4 + # Monthly al_ccsp = $780 (BIRMINGHAM CENTER PRESCHOOL BASE $180 * 52/12) + # Annual = 12 * $780 = $9,360 + al_child_care_subsidies: 9360 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml index e66a1f513eb..94bdd5b390f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml @@ -133,9 +133,9 @@ household: members: [person1, person2] state_code: AL - county_str: JEFFERSON_COUNTY_AL # BIRMINGHAM CENTER PRESCHOOL BASE = $138 -> half = $69 + county_str: JEFFERSON_COUNTY_AL # BIRMINGHAM CENTER PRESCHOOL BASE = $180 -> half = $90 output: - al_ccsp_maximum_weekly_rate: [0, 69] + al_ccsp_maximum_weekly_rate: [0, 90] - name: Care hours exactly 26 is full-time. period: 2024-01 @@ -163,11 +163,11 @@ state_code: AL county_str: JEFFERSON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 138] + al_ccsp_maximum_weekly_rate: [0, 180] # -- Multi-region rate coverage -- -- name: GFDC rate in Huntsville Preschool STAR_3 is 133 per week. +- name: GFDC rate in Huntsville Preschool STAR_3 is 154 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -193,7 +193,7 @@ state_code: AL county_str: MADISON_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 133] + al_ccsp_maximum_weekly_rate: [0, 154] - name: FDC rate in Mobile School_Age STAR_5 is 138 per week. period: 2024-01 @@ -223,7 +223,7 @@ output: al_ccsp_maximum_weekly_rate: [0, 138] -- name: CENTER Talladega INFANT_TODDLER BASE is 111 per week. +- name: CENTER Talladega INFANT_TODDLER BASE is 120 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -249,9 +249,9 @@ state_code: AL county_str: TALLADEGA_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 111] + al_ccsp_maximum_weekly_rate: [0, 120] -- name: CENTER Montgomery PRESCHOOL STAR_5 is 127 per week. +- name: CENTER Montgomery PRESCHOOL STAR_5 is 149 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -277,7 +277,7 @@ state_code: AL county_str: MONTGOMERY_COUNTY_AL output: - al_ccsp_maximum_weekly_rate: [0, 127] + al_ccsp_maximum_weekly_rate: [0, 149] # -- Copay band boundary tests -- diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml index 43aca75c23b..054b62bc957 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml @@ -7,7 +7,7 @@ # FS 4: $31,200/yr ($2,600/mo); 150% FPL = 3,900/mo; 180% = 4,680/mo; # 190% = 4,940/mo; 200% = 5,200/mo # AL SMI FS 4 (2023-10-01): $88,407/yr. 85% SMI FS 4: $75,145.95/yr (6,262.16/mo). -# Weekly -> monthly multiplier: 4.333 (regulatory literal). +# Weekly -> monthly multiplier: WEEKS_IN_YEAR / MONTHS_IN_YEAR = 52/12 ≈ 4.3333. - name: Two-parent family at 150 FPL with center care in Birmingham STAR_3. period: 2024-01 @@ -47,16 +47,16 @@ al_ccsp_eligible_child: [false, false, true] al_ccsp_income_eligible: true al_ccsp_eligible: true - # 150% FPL -> $30/wk per child -> $30 * 4.333 = $129.99/mo copay - al_ccsp_copay: 129.99 - # BIRMINGHAM CENTER PRESCHOOL STAR_3 full-time = $146/wk - al_ccsp_maximum_weekly_rate: [0, 0, 146] - # weekly charge = 10,000 / 52 = $192.31; min($192.31, $146) = $146 - # weekly subsidy = $146 - $30 = $116 - # monthly = $116 * 4.333 = $502.63 - al_ccsp: 502.63 + # 150% FPL -> $30/wk per child -> $30 * (52/12) = $130/mo copay + al_ccsp_copay: 130 + # BIRMINGHAM CENTER PRESCHOOL STAR_3 full-time = $191/wk + al_ccsp_maximum_weekly_rate: [0, 0, 191] + # weekly charge = 10,000 / 52 = $192.31; min($192.31, $191) = $191 + # weekly subsidy = $191 - $30 = $161 + # monthly = $161 * (52/12) = $697.67 + al_ccsp: 697.67 -- name: Single parent at 60 FPL continuing tier with FDC in Mobile BASE. +- name: Single parent at 60 FPL enrolled with FDC in Mobile BASE. period: 2024-01 absolute_error_margin: 0.1 input: @@ -92,11 +92,11 @@ al_ccsp_eligible: true # <= 100% FPL -> $0/wk copay al_ccsp_copay: 0 - # MOBILE FDC INFANT_TODDLER BASE full-time = $125/wk - al_ccsp_maximum_weekly_rate: [0, 125] - # weekly charge = 8,000 / 52 = $153.85; min($153.85, $125) = $125 - # monthly = $125 * 4.333 = $541.63 - al_ccsp: 541.63 + # MOBILE FDC INFANT_TODDLER BASE full-time = $134/wk + al_ccsp_maximum_weekly_rate: [0, 134] + # weekly charge = 8,000 / 52 = $153.85; min($153.85, $134) = $134 + # monthly = $134 * (52/12) = $580.67 + al_ccsp: 580.67 - name: Family at 190 FPL initial tier is ineligible. period: 2024-01 @@ -179,14 +179,14 @@ output: al_ccsp_eligible: true # FPL ratio = 49,058 / 25,820 = 1.90 -> 181-190 band -> $42/wk - # $42 * 4.333 = $181.99/mo - al_ccsp_copay: 181.99 - # BIRMINGHAM CENTER PRESCHOOL BASE = $138/wk - al_ccsp_maximum_weekly_rate: [0, 0, 138] - # weekly charge = 10,000 / 52 = $192.31; min($192.31, $138) = $138 - # weekly subsidy = $138 - $42 = $96 - # monthly = $96 * 4.333 = $415.97 - al_ccsp: 415.97 + # $42 * (52/12) = $182/mo + al_ccsp_copay: 182 + # BIRMINGHAM CENTER PRESCHOOL BASE = $180/wk + al_ccsp_maximum_weekly_rate: [0, 0, 180] + # weekly charge = 10,000 / 52 = $192.31; min($192.31, $180) = $180 + # weekly subsidy = $180 - $42 = $138 + # monthly = $138 * (52/12) = $598 + al_ccsp: 598 - name: Foster child waives income test and copay. period: 2024-01 @@ -223,10 +223,10 @@ al_ccsp_eligible: true al_ccsp_protective_services: true al_ccsp_copay: 0 - # BIRMINGHAM CENTER SCHOOL_AGE BASE = $115/wk - al_ccsp_maximum_weekly_rate: [0, 115] - # weekly subsidy = $115; monthly = $115 * 4.333 = $498.30 - al_ccsp: 498.3 + # BIRMINGHAM CENTER SCHOOL_AGE BASE = $150/wk + al_ccsp_maximum_weekly_rate: [0, 150] + # weekly subsidy = $150; monthly = $150 * (52/12) = $650 + al_ccsp: 650 - name: Disabled child waives copay. period: 2024-01 @@ -262,9 +262,9 @@ output: al_ccsp_eligible: true al_ccsp_copay: 0 - # BIRMINGHAM CENTER SCHOOL_AGE BASE = $115/wk (age 5) - # weekly subsidy = $115 - $0 = $115; monthly = $115 * 4.333 = $498.30 - al_ccsp: 498.3 + # BIRMINGHAM CENTER SCHOOL_AGE BASE = $150/wk (age 5) + # weekly subsidy = $150 - $0 = $150; monthly = $150 * (52/12) = $650 + al_ccsp: 650 - name: Family above 85 SMI is ineligible even with low FPL ratio (large household). period: 2024-01 @@ -350,15 +350,15 @@ output: al_ccsp_eligible_child: [false, true, true] al_ccsp_eligible: true - # 150% FPL -> $30/wk per child * 2 children * 4.333 = $259.98/mo - al_ccsp_copay: 259.98 - # BIRMINGHAM CENTER PRESCHOOL BASE = $138; CENTER INFANT_TODDLER BASE = $150 - al_ccsp_maximum_weekly_rate: [0, 138, 150] + # 150% FPL -> $30/wk per child * 2 children * (52/12) = $260/mo + al_ccsp_copay: 260 + # BIRMINGHAM CENTER PRESCHOOL BASE = $180; CENTER INFANT_TODDLER BASE = $195 + al_ccsp_maximum_weekly_rate: [0, 180, 195] # weekly charge per child = 7,000 / 52 = $134.62 - # child 1 (age 4): min($134.62, $138) = $134.62; subsidy = $134.62 - $30 = $104.62 - # child 2 (age 2): min($134.62, $150) = $134.62; subsidy = $134.62 - $30 = $104.62 - # total weekly subsidy = $209.24; monthly = $209.24 * 4.333 = $906.64 - al_ccsp: 906.64 + # child 1 (age 4): min($134.62, $180) = $134.62; subsidy = $134.62 - $30 = $104.62 + # child 2 (age 2): min($134.62, $195) = $134.62; subsidy = $134.62 - $30 = $104.62 + # total weekly subsidy = $209.24; monthly = $209.24 * (52/12) = $906.71 + al_ccsp: 906.71 - name: Part-time care halves provider rate. period: 2024-01 @@ -392,14 +392,14 @@ county_str: JEFFERSON_COUNTY_AL output: al_ccsp_eligible: true - # BIRMINGHAM CENTER PRESCHOOL BASE full-time = $138; part-time = $69 - al_ccsp_maximum_weekly_rate: [0, 69] - # weekly charge = 5,000 / 52 = $96.15; min(96.15, 69) = $69 + # BIRMINGHAM CENTER PRESCHOOL BASE full-time = $180; part-time = $90 + al_ccsp_maximum_weekly_rate: [0, 90] + # weekly charge = 5,000 / 52 = $96.15; min(96.15, 90) = $90 # copay = $0 (<=100% FPL) - # monthly = $69 * 4.333 = $298.98 - al_ccsp: 298.98 + # monthly = $90 * (52/12) = $390 + al_ccsp: 390 -- name: INFORMAL provider capped at 40 per week. +- name: INFORMAL provider capped at 50 per week. period: 2024-01 absolute_error_margin: 0.1 input: @@ -430,7 +430,7 @@ county_str: JEFFERSON_COUNTY_AL output: al_ccsp_eligible: true - al_ccsp_maximum_weekly_rate: [0, 40] - # weekly charge = $96.15; min($96.15, $40) = $40 - # copay = $0; monthly = $40 * 4.333 = $173.32 - al_ccsp: 173.32 + al_ccsp_maximum_weekly_rate: [0, 50] + # weekly charge = $96.15; min($96.15, $50) = $50 + # copay = $0; monthly = $50 * (52/12) = $216.67 + al_ccsp: 216.67 diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py index 6988ab342b0..2bb73366358 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py @@ -13,12 +13,9 @@ class al_ccsp(Variable): "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=40", ) - def formula(spm_unit, period, parameters): + def formula(spm_unit, period): person = spm_unit.members - p = parameters(period).gov.states.al.dhr.ccsp - # Per-child weekly maximum rate and the family weekly copay - # split equally across eligible children. weekly_rate = person("al_ccsp_maximum_weekly_rate", period) is_eligible_child = person("al_ccsp_eligible_child", period) in_care = person("childcare_hours_per_week", period.this_year) > 0 @@ -28,18 +25,7 @@ def formula(spm_unit, period, parameters): weekly_family_copay = ( spm_unit("al_ccsp_weekly_copay_per_child", period) * n_paying ) - # Apply copay waivers consistently with al_ccsp_copay. - p_elig = p.eligibility - is_disabled = person("is_disabled", period.this_year) - age = person("age", period.this_year) - is_dependent = person("is_tax_unit_dependent", period.this_year) - has_disabled_child = spm_unit.any( - is_disabled & is_dependent & (age < p_elig.disabled_child_age_limit) - ) - is_head_start = person("is_enrolled_in_head_start", period.this_year) - has_head_start_child = spm_unit.any(is_head_start) - has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 - copay_waived = has_disabled_child | has_head_start_child | has_foster_child + copay_waived = spm_unit("al_ccsp_copay_waived", period) weekly_family_copay = where(copay_waived, 0, weekly_family_copay) per_child_weekly_copay = where( @@ -57,9 +43,9 @@ def formula(spm_unit, period, parameters): capped_charge - per_child_weekly_copay_broadcast, 0 ) - # Convert weekly to monthly using AL's regulatory 4.333 factor. - weeks_to_months = p.income.weeks_to_months per_child_monthly_subsidy = ( - per_child_weekly_subsidy * weeks_to_months * is_paying_child + per_child_weekly_subsidy + * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) + * is_paying_child ) return spm_unit.sum(per_child_monthly_subsidy) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py index 122265b8d8e..09b20995392 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py @@ -2,8 +2,8 @@ class ALCCSPAgeCategory(Enum): - INFANT_TODDLER = "Infant/Toddler (0-35 months)" - PRESCHOOL = "Preschool (36-59 months)" + INFANT_TODDLER = "Infant/Toddler (0-36 months)" + PRESCHOOL = "Preschool (37-59 months)" SCHOOL_AGE = "School Age (60+ months)" @@ -17,7 +17,7 @@ class al_ccsp_age_category(Variable): defined_for = StateCode.AL reference = ( "Alabama DHR Provider Rate Chart, Key to Care Level", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2", ) def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py index 6cf01ffd4d1..bbb33952070 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py @@ -18,5 +18,5 @@ class al_ccsp_provider_type(Variable): defined_for = StateCode.AL reference = ( "Alabama DHR Provider Rate Chart", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2", ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py index 5e832eec665..695061eb367 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py @@ -20,5 +20,5 @@ class al_ccsp_quality_tier(Variable): defined_for = StateCode.AL reference = ( "Alabama DHR Provider Rate Chart (Base + 1-5 Star)", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=2", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2", ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py index e44ec5d1175..d4b325d83f8 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py @@ -17,13 +17,13 @@ class al_ccsp_region(Variable): value_type = Enum entity = Household possible_values = ALCCSPRegion - default_value = ALCCSPRegion.MONTGOMERY + default_value = ALCCSPRegion.BIRMINGHAM definition_period = YEAR label = "Alabama CCSP rate-setting region" defined_for = StateCode.AL reference = ( "Alabama DHR Provider Rate Chart, Regions and Counties Served", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=1", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=1", ) def formula(household, period, parameters): @@ -57,5 +57,5 @@ def formula(household, period, parameters): ALCCSPRegion.DOTHAN, ALCCSPRegion.OPELIKA, ], - default=ALCCSPRegion.MONTGOMERY, + default=ALCCSPRegion.BIRMINGHAM, ) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py index 704bb523c82..eb0802e823a 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py @@ -13,41 +13,14 @@ class al_ccsp_copay(Variable): "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=43", ) - def formula(spm_unit, period, parameters): - p_elig = parameters(period).gov.states.al.dhr.ccsp.eligibility + def formula(spm_unit, period): weekly_per_child = spm_unit("al_ccsp_weekly_copay_per_child", period) - - # Copay waivers (§3.3.1): - # (iv) family includes a disabled child - # (v) family enrolled in Head Start / EHS - # (vi) foster care (protective-services category for copay) - # Homelessness alone does NOT waive copay (§3.3.1(iii) unchecked), - # though it triggers the eligibility waiver via protective_services. person = spm_unit.members - is_disabled = person("is_disabled", period.this_year) - age = person("age", period.this_year) - is_dependent = person("is_tax_unit_dependent", period.this_year) - has_disabled_child = spm_unit.any( - is_disabled & is_dependent & (age < p_elig.disabled_child_age_limit) - ) - - is_head_start = person("is_enrolled_in_head_start", period.this_year) - has_head_start_child = spm_unit.any(is_head_start) - - has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 - - copay_waived = has_disabled_child | has_head_start_child | has_foster_child - - # Count children whose copay applies: eligible children in care. is_eligible_child = person("al_ccsp_eligible_child", period) in_care = person("childcare_hours_per_week", period.this_year) > 0 num_paying = spm_unit.sum(is_eligible_child & in_care) - # Provider may charge above max reimbursement rate (§3.1); copay - # is independent of the rate and based on the FPL fee table. weekly_family_copay = weekly_per_child * num_paying - weeks_to_months = parameters( - period - ).gov.states.al.dhr.ccsp.income.weeks_to_months - monthly_family_copay = weekly_family_copay * weeks_to_months + monthly_family_copay = weekly_family_copay * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) + copay_waived = spm_unit("al_ccsp_copay_waived", period) return where(copay_waived, 0, monthly_family_copay) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py new file mode 100644 index 00000000000..8d80794d19f --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class al_ccsp_copay_waived(Variable): + value_type = bool + entity = SPMUnit + label = "Alabama CCSP copay waived" + definition_period = MONTH + defined_for = StateCode.AL + reference = ( + "Alabama CCDF State Plan 2025-2027, Section 3.3.1", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=43", + ) + + def formula(spm_unit, period, parameters): + p_age = parameters(period).gov.states.al.dhr.ccsp.age + person = spm_unit.members + is_disabled = person("is_disabled", period.this_year) + age = person("age", period.this_year) + is_dependent = person("is_tax_unit_dependent", period.this_year) + has_disabled_child = spm_unit.any( + is_disabled & is_dependent & (age < p_age.disabled_child_limit) + ) + has_head_start_child = add(spm_unit, period, ["is_enrolled_in_head_start"]) > 0 + has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 + return has_disabled_child | has_head_start_child | has_foster_child diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py index 33a0664f0d1..f12ccbb791c 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py @@ -16,15 +16,6 @@ class al_ccsp_weekly_copay_per_child(Variable): def formula(spm_unit, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.copay monthly_income = spm_unit("al_ccsp_countable_income", period) - fpg = spm_unit("spm_unit_fpg", period.this_year) - # Compare monthly income against the monthly federal poverty - # guideline to compute the FPL ratio. - monthly_fpg = fpg / MONTHS_IN_YEAR + monthly_fpg = spm_unit("spm_unit_fpg", period) fpl_ratio = where(monthly_fpg > 0, monthly_income / monthly_fpg, 0) - - enrolled = spm_unit("al_ccsp_enrolled", period) - initial_fee = p.initial_fee_by_fpl.calc(fpl_ratio) - continuing_fee = p.continuing_fee_by_fpl.calc(fpl_ratio) - # Continuing families above 180% FPL use the continuing fee scale; - # all other families use the initial fee scale. - return where(enrolled, continuing_fee, initial_fee) + return p.fee_by_fpl.calc(fpl_ratio) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py index c55810ff90c..2c4bc93bb9d 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py @@ -13,11 +13,11 @@ class al_ccsp_activity_eligible(Variable): ) def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.al.dhr.ccsp.eligibility + p = parameters(period).gov.states.al.dhr.ccsp.activity person = spm_unit.members is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) hours_worked = person("weekly_hours_worked", period.this_year) - meets_work_requirement = hours_worked >= p.activity_hours_minimum + meets_work_requirement = hours_worked >= p.hours_minimum is_student = person("is_full_time_student", period.this_year) # Disabled-parent activity exemption per SC/VA precedent; not # explicit in §2.2.2 but a CCDF best practice. diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py index f71b9e6264a..3615979ffe3 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py @@ -13,13 +13,13 @@ class al_ccsp_eligible_child(Variable): ) def formula(person, period, parameters): - p = parameters(period).gov.states.al.dhr.ccsp.eligibility + p = parameters(period).gov.states.al.dhr.ccsp.age age = person("age", period.this_year) is_disabled = person("is_disabled", period.this_year) age_eligible = where( is_disabled, - age < p.disabled_child_age_limit, - age < p.child_age_limit, + age < p.disabled_child_limit, + age < p.child_limit, ) immigration_eligible = person( "is_ccdf_immigration_eligible_child", period.this_year diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py index a7f9f019980..3aa8a8fc137 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py @@ -13,23 +13,19 @@ class al_ccsp_income_eligible(Variable): ) def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.al.dhr.ccsp.eligibility + p = parameters(period).gov.states.al.dhr.ccsp.income.limit monthly_income = spm_unit("al_ccsp_countable_income", period) - annual_income = monthly_income * MONTHS_IN_YEAR - # FPL test: 180% initial, 200% continuing (NJ pattern). - fpg = spm_unit("spm_unit_fpg", period.this_year) + monthly_fpg = spm_unit("spm_unit_fpg", period) enrolled = spm_unit("al_ccsp_enrolled", period) fpl_limit_ratio = where( enrolled, - p.income_limit_fpl_continuing, - p.income_limit_fpl_initial, + p.fpl_continuing, + p.fpl_initial, ) - fpl_eligible = annual_income <= fpg * fpl_limit_ratio + fpl_eligible = monthly_income <= monthly_fpg * fpl_limit_ratio - # Federal CCDF 85% SMI hard cap applies in both initial and - # continuing tiers. - smi = spm_unit("hhs_smi", period.this_year) - smi_eligible = annual_income <= smi * p.income_limit_smi_cap + monthly_smi = spm_unit("hhs_smi", period) + smi_eligible = monthly_income <= monthly_smi * p.smi_cap return fpl_eligible & smi_eligible diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py index 7c9bdbea34d..fe75c4937cc 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py @@ -13,7 +13,7 @@ class al_ccsp_maximum_weekly_rate(Variable): defined_for = "al_ccsp_eligible_child" reference = ( "Alabama DHR Provider Rate Chart", - "https://www.alacourt.gov/docs/ALDayCareRates.pdf#page=1", + "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=1", ) def formula(person, period, parameters): From cc66c79cf1b77d69a67adbd4f60dfea52c8e0254 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 17 May 2026 19:31:12 -0400 Subject: [PATCH 07/15] Fix copay waivers, activity fallback, and informal part-time cap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copay waiver (al_ccsp_copay_waived): - Replace `has_foster_child` with `al_ccsp_protective_services`. Per §3.3.1(vi), the parental fee is waived for any child authorized under the Protective Service category — which per §2.2.2(f) includes homelessness as well as foster care. Activity eligibility (al_ccsp_activity_eligible): - OR in `meets_ccdf_activity_test` as a fallback so that families who qualify via job training, education hours, SNAP E&T, or other approved-but-unmodeled activities are not incorrectly excluded. Matches the pattern used by DE, NJ, PA, VA, and VT CCAP variables. Provider rate (al_ccsp_maximum_weekly_rate): - Apply the part-time multiplier to INFORMAL providers too. The prior code returned the flat $50 cap regardless of hours, but §3.1 (Part-time Rates note) caps part-time at 1/2 of the applicable full-time rate, so part-time informal = $25. Tests: - Update the homeless-household copay test to expect waiver. - Add multi-child mixed-eligibility coverage for the new waiver. - Add positive/negative tests for the activity fallback. - Add a part-time INFORMAL rate test ($25 expected). 130 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../dhr/ccsp/al_ccsp_activity_eligible.yaml | 56 +++++++++++++++++++ .../gov/states/al/dhr/ccsp/al_ccsp_copay.yaml | 9 +-- .../al/dhr/ccsp/al_ccsp_copay_waived.yaml | 27 ++++++++- .../dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml | 31 +++++++++- .../al/dhr/ccsp/copay/al_ccsp_copay_waived.py | 9 ++- .../eligibility/al_ccsp_activity_eligible.py | 5 +- .../payment/al_ccsp_maximum_weekly_rate.py | 21 +++---- uv.lock | 2 +- 8 files changed, 136 insertions(+), 24 deletions(-) diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml index 7c3e60d24dc..07957783f13 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml @@ -208,3 +208,59 @@ state_code: AL output: al_ccsp_activity_eligible: true + +- name: Parent with zero modeled activity but meets_ccdf_activity_test true is eligible. + period: 2024-01 + input: + people: + person1: + # Would fail the modeled activity test (0 work hours, not student, + # not disabled), but the SPMUnit-level fallback flag is set to + # capture an approved unmodeled activity (e.g., job training, + # education hours, SNAP E&T, temporary leave). + age: 30 + weekly_hours_worked: 0 + is_full_time_student: false + is_disabled: false + person2: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + meets_ccdf_activity_test: true + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_activity_eligible: true + +- name: Parent with zero modeled activity and meets_ccdf_activity_test false is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + weekly_hours_worked: 0 + is_full_time_student: false + is_disabled: false + person2: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + meets_ccdf_activity_test: false + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_activity_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml index d4cce7b254b..67a51745670 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml @@ -304,7 +304,7 @@ output: al_ccsp_copay: 0 -- name: Homeless household alone does NOT waive copay. +- name: Homeless household waives copay via Protective Service category. period: 2024-01 absolute_error_margin: 0.1 input: @@ -332,9 +332,10 @@ county_str: JEFFERSON_COUNTY_AL is_homeless: true output: - # Homelessness alone is NOT a copay waiver in AL. - # Fee is still owed: 150% FPL -> $30/wk -> $30 * 4.333 = $130.00/mo - al_ccsp_copay: 129.99 + # Homeless families fall under the Protective Service category per + # §2.2.2(f); §3.3.1(vi) waives copay for children authorized under + # that category. + al_ccsp_copay: 0 - name: Three children, only one truly eligible, copay counts only the eligible one. period: 2024-01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml index 6923e0b558e..0d48ecb28ca 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml @@ -2,8 +2,8 @@ # Per CCDF State Plan §3.3.1, copay is waived for families that include: # (iv) a disabled child (under disabled_child_limit, age 19) # (v) a child enrolled in Head Start / Early Head Start -# (vi) a foster child -# Homelessness alone is NOT a waiver (§3.3.1(iii) is unchecked). +# (vi) a child authorized under the Protective Service category +# (foster, kinship, or homelessness per §2.2.2(f)). - name: Case 1, family with disabled child waives copay. period: 2024-01 @@ -118,3 +118,26 @@ state_code: AL output: al_ccsp_copay_waived: false + +- name: Case 6, homeless household waives copay via Protective Service category. + period: 2024-01 + input: + people: + person1: + age: 30 + 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: AL + is_homeless: true + output: + al_ccsp_copay_waived: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml index a08a1457b1b..269e7c9886a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml @@ -144,7 +144,7 @@ output: al_ccsp_maximum_weekly_rate: [0, 95.5] -- name: INFORMAL provider capped at 50 per week regardless of region. +- name: INFORMAL provider full-time capped at 50 per week regardless of region. period: 2024-01 absolute_error_margin: 0.1 input: @@ -171,6 +171,35 @@ output: al_ccsp_maximum_weekly_rate: [0, 50] +- name: INFORMAL provider part-time capped at 25 per week (half of informal cap). + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 20 # <= 25 -> part-time + al_ccsp_provider_type: INFORMAL + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # Part-time = 1/2 of applicable full-time rate; for INFORMAL the + # applicable full-time rate is the $50 cap, so part-time = $25. + al_ccsp_maximum_weekly_rate: [0, 25] + - name: Adult gets zero rate (not an eligible child). period: 2024-01 absolute_error_margin: 0.1 diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py index 8d80794d19f..b5235c8f78f 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py @@ -13,6 +13,11 @@ class al_ccsp_copay_waived(Variable): ) def formula(spm_unit, period, parameters): + # Per §3.3.1, AL waives copay for: + # (iv) families with a disabled child + # (v) families with a Head Start / EHS child + # (vi) children authorized under the Protective Service category + # (foster, kinship, homelessness, etc. per §2.2.2(f)). p_age = parameters(period).gov.states.al.dhr.ccsp.age person = spm_unit.members is_disabled = person("is_disabled", period.this_year) @@ -22,5 +27,5 @@ def formula(spm_unit, period, parameters): is_disabled & is_dependent & (age < p_age.disabled_child_limit) ) has_head_start_child = add(spm_unit, period, ["is_enrolled_in_head_start"]) > 0 - has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 - return has_disabled_child | has_head_start_child | has_foster_child + protective_services = spm_unit("al_ccsp_protective_services", period) + return has_disabled_child | has_head_start_child | protective_services diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py index 2c4bc93bb9d..d63dfcd69cc 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py @@ -25,4 +25,7 @@ def formula(spm_unit, period, parameters): individually_eligible = meets_work_requirement | is_student | is_disabled 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 + # Fallback input for approved activities not individually modeled + # (job search, education/training, SNAP E&T, temporary leave, etc.). + fallback = spm_unit("meets_ccdf_activity_test", period.this_year) + return (has_head_or_spouse & all_covered) | fallback diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py index fe75c4937cc..30606a094e9 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py @@ -23,16 +23,14 @@ def formula(person, period, parameters): age_category = person("al_ccsp_age_category", period) quality_tier = person("al_ccsp_quality_tier", period) - # Look up the full-time rate across the four-dimension matrix. - # INFORMAL providers are handled separately by a flat weekly cap - # rather than the matrix; the select() default below carries the - # informal cap through when the provider type does not match. rates = p.maximum_weekly_full_time center_rate = rates.CENTER[region][age_category][quality_tier] gfdc_rate = rates.GFDC[region][age_category][quality_tier] fdc_rate = rates.FDC[region][age_category][quality_tier] - matrix_rate = select( + # INFORMAL providers use the flat informal_weekly_cap as their + # full-time rate; the matrix is not consulted for them. + full_time_rate = select( [ provider_type == ALCCSPProviderType.CENTER, provider_type == ALCCSPProviderType.GFDC, @@ -42,16 +40,13 @@ def formula(person, period, parameters): default=p.informal_weekly_cap, ) - # Part-time (≤25 hours/week) pays half the full-time rate. The - # informal cap is interpreted as a weekly maximum that applies - # without halving — providers either bill within the cap or not. + # Part-time (≤25 hours/week) pays half the applicable full-time + # rate, including for INFORMAL providers (so the part-time cap is + # half of informal_weekly_cap). hours = person("childcare_hours_per_week", period.this_year) is_part_time = hours <= p.full_time_hours_threshold - part_time_rate = matrix_rate * p.part_time_multiplier - full_time_rate = where(is_part_time, part_time_rate, matrix_rate) - return where( - provider_type == ALCCSPProviderType.INFORMAL, - p.informal_weekly_cap, + is_part_time, + full_time_rate * p.part_time_multiplier, full_time_rate, ) diff --git a/uv.lock b/uv.lock index 4b1cb77701e..befdc7790c0 100644 --- a/uv.lock +++ b/uv.lock @@ -2974,7 +2974,7 @@ wheels = [ [[package]] name = "policyengine-us" -version = "1.692.1" +version = "1.693.1" source = { editable = "." } dependencies = [ { name = "microdf-python" }, From 2039ec2e2a03e79b64817ca18371354e20577464 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 17 May 2026 20:38:18 -0400 Subject: [PATCH 08/15] Address /review-program findings for AL CCSP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Refactor copay waiver to a single source of truth: apply §3.3.1 waiver inside al_ccsp_weekly_copay_per_child, remove duplicated waiver logic from al_ccsp.py, drop the redundant n_paying multiply/divide. - Drop is_tax_unit_dependent gate from al_ccsp_eligible_child (use age + immigration + SPM co-residence). - Reframe protective-services comment with correct §3.3.1(vi) citation and document the kinship-care limitation. - Fix #page anchors (hours_minimum, smi_cap); add State Plan ref to fee_by_fpl; drop slash from child_limit title. - Document the meets_ccdf_activity_test fallback semantics and the al_ccsp_enrolled microdata default. - Add tests: 2025 integration, over-age-child rate masking, non-AL household + AL county_str regression, asset boundary, 4 untested copay bands (130/140/160/170 percent), 200 percent FPL top band, 4 untested regions, INFORMAL+STAR_5 interaction, SMI float-boundary refactor. - Update programs.yaml: AL CCSP status partial (kinship/EHS-CCP/etc. not modeled). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../al/dhr/ccsp/activity/hours_minimum.yaml | 2 +- .../states/al/dhr/ccsp/age/child_limit.yaml | 2 +- .../states/al/dhr/ccsp/copay/fee_by_fpl.yaml | 2 + .../ccsp/income/countable_income/sources.yaml | 8 +- .../al/dhr/ccsp/income/limit/smi_cap.yaml | 2 +- policyengine_us/programs.yaml | 2 +- .../dhr/ccsp/al_ccsp_activity_eligible.yaml | 45 ++++- .../al/dhr/ccsp/al_ccsp_income_eligible.yaml | 5 +- .../dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml | 176 ++++++++++++++++++ .../ccsp/al_ccsp_weekly_copay_per_child.yaml | 155 +++++++++++++++ .../gov/states/al/dhr/ccsp/edge_cases.yaml | 31 +++ .../gov/states/al/dhr/ccsp/integration.yaml | 42 +++++ .../gov/states/al/dhr/ccsp/al_ccsp.py | 14 +- .../al/dhr/ccsp/al_ccsp_age_category.py | 2 +- .../states/al/dhr/ccsp/al_ccsp_enrolled.py | 7 + .../states/al/dhr/ccsp/copay/al_ccsp_copay.py | 5 +- .../copay/al_ccsp_weekly_copay_per_child.py | 4 +- .../eligibility/al_ccsp_activity_eligible.py | 19 +- .../eligibility/al_ccsp_eligible_child.py | 3 +- .../al_ccsp_protective_services.py | 7 +- 20 files changed, 491 insertions(+), 42 deletions(-) diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/activity/hours_minimum.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/activity/hours_minimum.yaml index e66c727c729..f881e5c7cb7 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/activity/hours_minimum.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/activity/hours_minimum.yaml @@ -8,4 +8,4 @@ metadata: label: Alabama CCSP minimum weekly activity hours reference: - title: Alabama CCDF State Plan 2025-2027, Section 2.2.2 - href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=21 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=22 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age/child_limit.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age/child_limit.yaml index 8c503c8d7b7..20a96b43c97 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age/child_limit.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age/child_limit.yaml @@ -7,5 +7,5 @@ metadata: period: year label: Alabama CCSP child age limit reference: - - title: Alabama CCDF State Plan 2025-2027, Section 2.2 / 2.2.1 + - title: Alabama CCDF State Plan 2025-2027, Section 2.2.1 href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml index 5afa10e8fb1..00970d1d265 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml @@ -9,6 +9,8 @@ metadata: reference: - title: Alabama Child Care Fact Sheet, Initial and Continuing Eligibility Monthly Income Scale and Parental Fee Chart href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf + - title: Alabama CCDF State Plan 2025-2027, Section 3.1 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=40 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml index dcfe85c4518..0ce9b37a5be 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml @@ -13,12 +13,8 @@ values: - interest_income - dividend_income - alimony_income - - veterans_benefits - # TANF is excluded from the adds list to break a CCSP <-> TANF - # circular dependency through childcare_expenses. Operationally, - # families enrolled in TANF rarely reach the CCSP income test - # because TANF payment standards fall well below 180% FPL. - # - tanf + - veterans_benefits + # - tanf exclude as of now to avoid circular reference error # Section 2.2.4(c) also lists inheritance and college work-study, # but no matching variables exist in policyengine-us at this time. diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml index 78ea014150e..172723dbf7c 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml @@ -8,7 +8,7 @@ metadata: label: Alabama CCSP income cap (share of state median income) reference: - title: Alabama CCDF State Plan 2025-2027, Section 2.2.4 - href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=24 + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=26 - title: Alabama CCDF State Plan 2025-2027, Section 2.5.2 href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=35 - title: Alabama Child Care Fact Sheet (Income Cutoff 85% SMI) diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 5708b9facb2..24e3718d910 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -463,7 +463,7 @@ programs: coverage: AL, CA, CO, CT, DE, DC, IL, MA, MD, ME, NC, NH, NJ, PA, RI, SC, TX, VA, VT, WV state_implementations: - state: AL - status: complete + status: partial name: Alabama CCSP full_name: Alabama Child Care Subsidy Program variable: al_ccsp diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml index 07957783f13..d61e3be9dfc 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_activity_eligible.yaml @@ -102,9 +102,13 @@ output: al_ccsp_activity_eligible: true -- name: Disabled parent is activity eligible (SC/VA convention). +- name: Disabled parent without modeled activity or CCDF fallback is ineligible. period: 2024-01 input: + # Alabama's §2.2.2 does not list parental disability as an automatic + # activity exemption. Disabled parents must be marked via the + # meets_ccdf_activity_test fallback to capture a case-by-case + # good-cause exemption. people: person1: age: 40 @@ -125,7 +129,7 @@ members: [person1, person2] state_code: AL output: - al_ccsp_activity_eligible: true + al_ccsp_activity_eligible: false - name: Two parents both meeting 15 hours is activity eligible. period: 2024-01 @@ -181,9 +185,43 @@ output: al_ccsp_activity_eligible: false -- name: Working parent plus disabled spouse is activity eligible (disabled-parent exemption). +- name: Working parent plus non-working spouse fails activity test by default. + period: 2024-01 + input: + # Per §2.2.2 each head/spouse must individually meet the 15hr work, + # student, or fallback test. Alabama's State Plan does NOT list + # parental disability as an automatic exemption (only protective + # services for children waives the activity test, §2.2.2(h)). + people: + person1: + age: 30 + weekly_hours_worked: 40 + person2: + age: 28 + weekly_hours_worked: 0 + is_full_time_student: false + is_disabled: true + person3: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: AL + output: + al_ccsp_activity_eligible: false + +- name: Working parent plus disabled spouse with CCDF fallback flag is activity eligible. period: 2024-01 input: + # The fallback input (meets_ccdf_activity_test) is the supported + # pathway for case-by-case good-cause exemptions like disability. people: person1: age: 30 @@ -202,6 +240,7 @@ spm_units: spm_unit: members: [person1, person2, person3] + meets_ccdf_activity_test: true households: household: members: [person1, person2, person3] diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml index 30cc2baad99..f7b6b5df44d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml @@ -231,7 +231,8 @@ people: person1: age: 30 - employment_income: 75_146 # 85% SMI fam of 4 = 88,407 * 0.85 = 75,145.95; 75,146 is just over + # 85% SMI fam of 4 = 88,407 * 0.85 = 75,145.95; use +$0.01 above cap. + employment_income: 75_145.96 person2: age: 28 person3: @@ -252,5 +253,5 @@ members: [person1, person2, person3, person4] state_code: AL output: - # 75,146 > 75,145.95 (85% SMI cap) -> SMI cap fails by less than $1. + # 75,145.96 > 75,145.95 (85% SMI cap) -> SMI cap fails. al_ccsp_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml index 269e7c9886a..0239c08363c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_maximum_weekly_rate.yaml @@ -314,3 +314,179 @@ county_str: MADISON_COUNTY_AL output: al_ccsp_maximum_weekly_rate: [0, 179] + +- name: Over-age child with full provider/quality settings gets zero rate. + # Regression: confirms `defined_for = al_ccsp_eligible_child` correctly + # masks the rate to zero based on the eligibility variable, not just on + # personhood (the existing adult-zero-rate test could pass even if + # `defined_for` were dropped). + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 14 + is_tax_unit_dependent: true + is_disabled: false + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_eligible_child: [false, false] + al_ccsp_maximum_weekly_rate: [0, 0] + +- name: CENTER TUSCALOOSA PRESCHOOL STAR_3 full-time is 144 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 40 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: BIBB_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 144] + +- name: CENTER FT_PAYNE PRESCHOOL STAR_3 full-time is 122 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 40 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: CHEROKEE_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 122] + +- name: CENTER DOTHAN PRESCHOOL STAR_3 full-time is 127 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 40 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: BARBOUR_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 127] + +- name: CENTER OPELIKA PRESCHOOL STAR_3 full-time is 149 per week. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 40 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: LEE_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 149] + +- name: INFORMAL provider ignores quality_tier (STAR_5 still hits $50 cap). + # Regression: INFORMAL bypasses the rate matrix entirely. The + # quality_tier input must not affect the $50/wk full-time cap. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 40 + al_ccsp_provider_type: INFORMAL + al_ccsp_quality_tier: STAR_5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + al_ccsp_maximum_weekly_rate: [0, 50] diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml index 97e75e87196..476a8e88c6d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml @@ -132,3 +132,158 @@ output: # FPL ratio = 5,070 / 2,600 = 1.95 -> band [1.9001, ...) -> $45/wk al_ccsp_weekly_copay_per_child: 45 + +- name: Family at 130 percent FPL has $24 weekly per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 40_560 # 130% FPL fam of 4 = 3,380/mo + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # FPL ratio = 3,380 / 2,600 = 1.30 -> band [1.2001, 1.3001) -> $24/wk + al_ccsp_weekly_copay_per_child: 24 + +- name: Family at 140 percent FPL has $27 weekly per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 43_680 # 140% FPL fam of 4 = 3,640/mo + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # FPL ratio = 3,640 / 2,600 = 1.40 -> band [1.3001, 1.4001) -> $27/wk + al_ccsp_weekly_copay_per_child: 27 + +- name: Family at 160 percent FPL has $33 weekly per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 49_920 # 160% FPL fam of 4 = 4,160/mo + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # FPL ratio = 4,160 / 2,600 = 1.60 -> band [1.5001, 1.6001) -> $33/wk + al_ccsp_weekly_copay_per_child: 33 + +- name: Family at 170 percent FPL has $36 weekly per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 53_040 # 170% FPL fam of 4 = 4,420/mo + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # FPL ratio = 4,420 / 2,600 = 1.70 -> band [1.6001, 1.7001) -> $36/wk + al_ccsp_weekly_copay_per_child: 36 + +- name: Enrolled family at exactly 200 percent FPL has $45 weekly per-child fee. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 62_400 # 200% FPL fam of 4 = 5,200/mo + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + person4: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: AL + output: + # FPL ratio = 5,200 / 2,600 = 2.00 -> band [1.9001, inf) -> $45/wk + al_ccsp_weekly_copay_per_child: 45 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml index 94bdd5b390f..8e25e30c5aa 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml @@ -107,6 +107,33 @@ output: al_ccsp_eligible: true +- name: Assets one dollar over 1 million is asset ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 1_000_001 + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible: false + # -- Care hours boundary tests (full-time / part-time) -- - name: Care hours exactly 25 is part-time (half rate). @@ -437,6 +464,10 @@ household: members: [person1, person2] state_code: GA + county_str: AUTAUGA_COUNTY_AL output: + # Regression: non-AL household carrying an AL county string must not + # crash the region lookup; al_ccsp_region.py masks county lookup to + # AL households only. al_ccsp: 0 al_ccsp_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml index 054b62bc957..d87f203437e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml @@ -434,3 +434,45 @@ # weekly charge = $96.15; min($96.15, $50) = $50 # copay = $0; monthly = $50 * (52/12) = $216.67 al_ccsp: 216.67 + +# -- 2025 coverage check (parameters carry forward) -- + +- name: Two-parent family at 150 FPL with center care in 2025 (same as 2024 baseline). + period: 2025-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + employment_income: 38_730 + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 28 + weekly_hours_worked: 40 + person3: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: STAR_3 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: AL + county_str: JEFFERSON_COUNTY_AL + output: + # State Plan covers FFY 2025-2027; parameter values carry forward + # from 2024-01-01 entries. This test guards against accidental + # parameter resets between 2024 and 2025. + al_ccsp_eligible: true diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py index 2bb73366358..79bab95bbe9 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py @@ -20,18 +20,10 @@ def formula(spm_unit, period): is_eligible_child = person("al_ccsp_eligible_child", period) in_care = person("childcare_hours_per_week", period.this_year) > 0 is_paying_child = is_eligible_child & in_care - n_paying = spm_unit.sum(is_paying_child) - weekly_family_copay = ( - spm_unit("al_ccsp_weekly_copay_per_child", period) * n_paying - ) - copay_waived = spm_unit("al_ccsp_copay_waived", period) - weekly_family_copay = where(copay_waived, 0, weekly_family_copay) - - per_child_weekly_copay = where( - n_paying > 0, weekly_family_copay / where(n_paying > 0, n_paying, 1), 0 - ) - per_child_weekly_copay_broadcast = spm_unit.project(per_child_weekly_copay) + # al_ccsp_weekly_copay_per_child already applies the §3.3.1 waiver. + weekly_copay = spm_unit("al_ccsp_weekly_copay_per_child", period) + per_child_weekly_copay_broadcast = spm_unit.project(weekly_copay) # Per-child weekly pre-subsidy charge from annual expenses. annual_expense = person("pre_subsidy_childcare_expenses", period.this_year) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py index 09b20995392..235277ed21b 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py @@ -22,6 +22,6 @@ class al_ccsp_age_category(Variable): def formula(person, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.age_category - # monthly_age returns years; convert to months for bracket lookup. + # Convert annual age (years) to months for bracket lookup. age_months = person("age", period.this_year) * MONTHS_IN_YEAR return p.months.calc(age_months) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py index 1ffb2a5433c..7501d8347ff 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py @@ -6,6 +6,13 @@ class al_ccsp_enrolled(Variable): entity = SPMUnit definition_period = MONTH label = "Whether the family is currently enrolled in Alabama CCSP" + documentation = ( + "Distinguishes new applicants (180% FPL initial-eligibility cap) " + "from continuing recipients (200% FPL cap). Defaults to False, so " + "every microdata household is treated as a new applicant unless " + "the user explicitly sets this input — the 200% FPL continuing " + "branch is unreachable without it." + ) defined_for = StateCode.AL reference = ( "Alabama CCDF State Plan 2025-2027, Section 2.5.5(c)(iii)", diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py index eb0802e823a..518407ad56e 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py @@ -19,8 +19,5 @@ def formula(spm_unit, period): is_eligible_child = person("al_ccsp_eligible_child", period) in_care = person("childcare_hours_per_week", period.this_year) > 0 num_paying = spm_unit.sum(is_eligible_child & in_care) - weekly_family_copay = weekly_per_child * num_paying - monthly_family_copay = weekly_family_copay * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) - copay_waived = spm_unit("al_ccsp_copay_waived", period) - return where(copay_waived, 0, monthly_family_copay) + return weekly_family_copay * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py index f12ccbb791c..5bffa3469f7 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py @@ -18,4 +18,6 @@ def formula(spm_unit, period, parameters): monthly_income = spm_unit("al_ccsp_countable_income", period) monthly_fpg = spm_unit("spm_unit_fpg", period) fpl_ratio = where(monthly_fpg > 0, monthly_income / monthly_fpg, 0) - return p.fee_by_fpl.calc(fpl_ratio) + fee = p.fee_by_fpl.calc(fpl_ratio) + copay_waived = spm_unit("al_ccsp_copay_waived", period) + return where(copay_waived, 0, fee) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py index d63dfcd69cc..6fa2d3a944e 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py @@ -5,6 +5,15 @@ class al_ccsp_activity_eligible(Variable): value_type = bool entity = SPMUnit label = "Eligible for Alabama CCSP based on parental activity requirements" + documentation = ( + "True when every head/spouse in the SPM unit meets §2.2.2 work or " + "full-time-student requirements, OR when meets_ccdf_activity_test " + "is set as an input override. The fallback is permissive: a unit " + "with one working and one non-working parent (which §2.2.2 would " + "deny) is treated as eligible when meets_ccdf_activity_test is True. " + "Users who need strict §2.2.2 enforcement should leave the override " + "unset." + ) definition_period = MONTH defined_for = StateCode.AL reference = ( @@ -19,13 +28,13 @@ def formula(spm_unit, period, parameters): hours_worked = person("weekly_hours_worked", period.this_year) meets_work_requirement = hours_worked >= p.hours_minimum is_student = person("is_full_time_student", period.this_year) - # Disabled-parent activity exemption per SC/VA precedent; not - # explicit in §2.2.2 but a CCDF best practice. - is_disabled = person("is_disabled", period.this_year) - individually_eligible = meets_work_requirement | is_student | is_disabled + individually_eligible = meets_work_requirement | is_student has_head_or_spouse = spm_unit.sum(is_head_or_spouse) >= 1 all_covered = spm_unit.sum(is_head_or_spouse & ~individually_eligible) == 0 # Fallback input for approved activities not individually modeled - # (job search, education/training, SNAP E&T, temporary leave, etc.). + # (job search, education/training, SNAP E&T, temporary leave, + # disabled-parent good cause, etc.). Alabama's §2.2.2 only waives + # the activity test for children receiving protective services + # (§2.2.2(h)); other exemptions must be set via this fallback. fallback = spm_unit("meets_ccdf_activity_test", period.this_year) return (has_head_or_spouse & all_covered) | fallback diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py index 3615979ffe3..50574ef5ef7 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py @@ -24,5 +24,4 @@ def formula(person, period, parameters): immigration_eligible = person( "is_ccdf_immigration_eligible_child", period.this_year ) - is_dependent = person("is_tax_unit_dependent", period.this_year) - return age_eligible & immigration_eligible & is_dependent + return age_eligible & immigration_eligible diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py index d3c437f8821..120144cb1a3 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py @@ -14,9 +14,10 @@ class al_ccsp_protective_services(Variable): def formula(spm_unit, period, parameters): # Foster care and homelessness are the modeled protective-service - # categories. Kinship is excluded per §2.2.2(f). EHS-CCP, - # child-welfare engagement, and TANF-Other Relative are not - # tracked at the moment and are documented as limitations. + # categories. §3.3.1(vi) also names kinship care as a copay-waiver + # trigger, but we don't track kinship care at the moment. EHS-CCP, + # child-welfare engagement, and TANF-Other Relative are also not + # tracked at the moment. has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 is_homeless = spm_unit.household("is_homeless", period.this_year) return has_foster_child | is_homeless From c9679786bb82bed3a296131113b7b976311717d5 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 17 May 2026 21:53:32 -0400 Subject: [PATCH 09/15] Address /review-program critical findings (round 2) for AL CCSP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add al_child_care_subsidies to household_state_benefits.yaml so the benefit flows through the household-level state-benefit aggregation. - Drop is_tax_unit_dependent from the disabled-child copay-waiver gate in al_ccsp_copay_waived.py to match State Plan §3.3.1(iv) wording and the variable-patterns "use age, not tax dependency" rule. - Convert (title, url) reference tuples to single-URL strings in all 16 AL CCSP variable files; titles belong in parameter YAML, not variable reference fields. - Document the federal 7% gross-income copay cap and Alabama's pending waiver request in al_ccsp_copay.py (State Plan §3.1.1(a) confirms AL charges per child and acknowledges the family total can exceed 7%). - Remove the wrong Cornell LII citation in age_category/months.yaml (660-5-20-.04 is the licensing staffing-ratio rule, not the CCSP rate-setting categories). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../gov/household/household_state_benefits.yaml | 2 ++ .../gov/states/al/dhr/ccsp/age_category/months.yaml | 8 +++----- .../variables/gov/states/al/dhr/ccsp/al_ccsp.py | 5 +---- .../gov/states/al/dhr/ccsp/al_ccsp_age_category.py | 5 +---- .../gov/states/al/dhr/ccsp/al_ccsp_countable_income.py | 5 +---- .../variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py | 5 +---- .../gov/states/al/dhr/ccsp/al_ccsp_provider_type.py | 5 +---- .../gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py | 5 +---- .../variables/gov/states/al/dhr/ccsp/al_ccsp_region.py | 5 +---- .../gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py | 9 +++++---- .../gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py | 8 ++------ .../al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py | 5 +---- .../al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py | 5 +---- .../states/al/dhr/ccsp/eligibility/al_ccsp_eligible.py | 5 +---- .../al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py | 5 +---- .../al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py | 5 +---- .../dhr/ccsp/eligibility/al_ccsp_protective_services.py | 5 +---- .../al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py | 5 +---- 18 files changed, 26 insertions(+), 71 deletions(-) diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index b74241a36b5..3c5dd97256a 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -32,6 +32,7 @@ values: - ca_state_supplement # Alabama benefits - al_ssp + - al_child_care_subsidies # Alaska benefits - ak_ssp # Florida benefits @@ -99,6 +100,7 @@ values: - ca_state_supplement # Alabama benefits - al_ssp + - al_child_care_subsidies # Alaska benefits - ak_ssp # Florida benefits diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml index f3b19d2a1aa..6757d7e2d6f 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml @@ -1,7 +1,7 @@ description: Alabama uses this age in months threshold to assign care level categories under the Child Care Subsidy Program. -# 0 = INFANT_TODDLER (birth to 36 months) -# 1 = PRESCHOOL (37 months to 5 years) -# 2 = SCHOOL_AGE (5 years and older) +# 0 = INFANT_TODDLER (birth through 36 months) +# 1 = PRESCHOOL (37-59 months) +# 2 = SCHOOL_AGE (5 years through age 12, or through age 18 if disabled) metadata: type: single_amount @@ -12,8 +12,6 @@ metadata: reference: - title: Alabama DHR Child Care Subsidy Program Provider Rate Chart, Key to Care Level href: https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2 - - title: Ala. Admin. Code r. 660-5-20-.04 Child Care Program - href: https://www.law.cornell.edu/regulations/alabama/Ala-Admin-Code-r-660-5-20-.04 brackets: - threshold: diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py index 79bab95bbe9..27c8253a0e1 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py @@ -8,10 +8,7 @@ class al_ccsp(Variable): label = "Alabama Child Care Subsidy Program benefit amount" definition_period = MONTH defined_for = "al_ccsp_eligible" - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 3.1", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=40", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=40" def formula(spm_unit, period): person = spm_unit.members diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py index 235277ed21b..5592f7361af 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py @@ -15,10 +15,7 @@ class al_ccsp_age_category(Variable): definition_period = MONTH label = "Alabama CCSP child age category for payment rates" defined_for = StateCode.AL - reference = ( - "Alabama DHR Provider Rate Chart, Key to Care Level", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2" def formula(person, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.age_category diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_countable_income.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_countable_income.py index 26db820dbad..c0749c38191 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_countable_income.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_countable_income.py @@ -8,9 +8,6 @@ class al_ccsp_countable_income(Variable): definition_period = MONTH unit = USD defined_for = StateCode.AL - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 2.2.4(c)", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=26", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=26" adds = "gov.states.al.dhr.ccsp.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py index 7501d8347ff..ad62b1bd5c8 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py @@ -14,7 +14,4 @@ class al_ccsp_enrolled(Variable): "branch is unreachable without it." ) defined_for = StateCode.AL - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 2.5.5(c)(iii)", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39" diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py index bbb33952070..a2cbad1aaa7 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_provider_type.py @@ -16,7 +16,4 @@ class al_ccsp_provider_type(Variable): definition_period = MONTH label = "Alabama CCSP child care provider type" defined_for = StateCode.AL - reference = ( - "Alabama DHR Provider Rate Chart", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2" diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py index 695061eb367..cd29543a34b 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_quality_tier.py @@ -18,7 +18,4 @@ class al_ccsp_quality_tier(Variable): definition_period = MONTH label = "Alabama CCSP provider quality tier" defined_for = StateCode.AL - reference = ( - "Alabama DHR Provider Rate Chart (Base + 1-5 Star)", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=2" diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py index d4b325d83f8..4b6e752154f 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_region.py @@ -21,10 +21,7 @@ class al_ccsp_region(Variable): definition_period = YEAR label = "Alabama CCSP rate-setting region" defined_for = StateCode.AL - reference = ( - "Alabama DHR Provider Rate Chart, Regions and Counties Served", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=1", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=1" def formula(household, period, parameters): county = household("county_str", period) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py index 518407ad56e..4b4e49cdc48 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py @@ -8,12 +8,13 @@ class al_ccsp_copay(Variable): label = "Alabama CCSP monthly family copay" definition_period = MONTH defined_for = StateCode.AL - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 3.3.1", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=43", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=43" def formula(spm_unit, period): + # Federal CCDF (45 CFR §98.45(k)) caps copays at 7% of family gross + # income. Alabama State Plan §3.1.1.a notes a state waiver request + # from this cap; we don't enforce the cap at the moment, mirroring + # the State Plan's flat sliding-fee schedule. weekly_per_child = spm_unit("al_ccsp_weekly_copay_per_child", period) person = spm_unit.members is_eligible_child = person("al_ccsp_eligible_child", period) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py index b5235c8f78f..e4e4d76d5d2 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py @@ -7,10 +7,7 @@ class al_ccsp_copay_waived(Variable): label = "Alabama CCSP copay waived" definition_period = MONTH defined_for = StateCode.AL - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 3.3.1", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=43", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=43" def formula(spm_unit, period, parameters): # Per §3.3.1, AL waives copay for: @@ -22,9 +19,8 @@ def formula(spm_unit, period, parameters): person = spm_unit.members is_disabled = person("is_disabled", period.this_year) age = person("age", period.this_year) - is_dependent = person("is_tax_unit_dependent", period.this_year) has_disabled_child = spm_unit.any( - is_disabled & is_dependent & (age < p_age.disabled_child_limit) + is_disabled & (age < p_age.disabled_child_limit) ) has_head_start_child = add(spm_unit, period, ["is_enrolled_in_head_start"]) > 0 protective_services = spm_unit("al_ccsp_protective_services", period) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py index 5bffa3469f7..ad008748298 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py @@ -8,10 +8,7 @@ class al_ccsp_weekly_copay_per_child(Variable): label = "Alabama CCSP weekly per-child parental fee" definition_period = MONTH defined_for = StateCode.AL - reference = ( - "Alabama Child Care Fact Sheet (Parental Fee Chart)", - "https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.copay diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py index 6fa2d3a944e..9c607a30448 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py @@ -16,10 +16,7 @@ class al_ccsp_activity_eligible(Variable): ) definition_period = MONTH defined_for = StateCode.AL - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 2.2.2", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=21", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=21" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.activity diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible.py index b9a0be98fff..3c92946dc0d 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible.py @@ -7,10 +7,7 @@ class al_ccsp_eligible(Variable): label = "Eligible for Alabama CCSP" definition_period = MONTH defined_for = StateCode.AL - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 2.2", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20" def formula(spm_unit, period, parameters): has_eligible_child = add(spm_unit, period, ["al_ccsp_eligible_child"]) > 0 diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py index 50574ef5ef7..c44f4337ec8 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py @@ -7,10 +7,7 @@ class al_ccsp_eligible_child(Variable): label = "Eligible child for Alabama CCSP" definition_period = MONTH defined_for = StateCode.AL - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 2.2.1", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=20" def formula(person, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.age diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py index 3aa8a8fc137..b65787f4f3e 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py @@ -7,10 +7,7 @@ class al_ccsp_income_eligible(Variable): label = "Eligible for Alabama CCSP based on income" definition_period = MONTH defined_for = StateCode.AL - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 2.2.4", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=24", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=24" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.income.limit diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py index 120144cb1a3..5f6858f5949 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py @@ -7,10 +7,7 @@ class al_ccsp_protective_services(Variable): label = "Alabama CCSP protective services category" definition_period = MONTH defined_for = StateCode.AL - reference = ( - "Alabama CCDF State Plan 2025-2027, Section 2.2.2(f)", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=23", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=23" def formula(spm_unit, period, parameters): # Foster care and homelessness are the modeled protective-service diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py index 30606a094e9..00012f7ea19 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/payment/al_ccsp_maximum_weekly_rate.py @@ -11,10 +11,7 @@ class al_ccsp_maximum_weekly_rate(Variable): label = "Alabama CCSP maximum weekly reimbursement rate per child" definition_period = MONTH defined_for = "al_ccsp_eligible_child" - reference = ( - "Alabama DHR Provider Rate Chart", - "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=1", - ) + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/Provider-Rates-with-QRIS-Tiers-April-1-2022-b.pdf#page=1" def formula(person, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.rates From 61d5b1b8887e1342f269cba82a648a297437b026 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 17 May 2026 22:34:27 -0400 Subject: [PATCH 10/15] Address /review-program critical findings (round 3) for AL CCSP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace deprecated documentation field with inline comments on al_ccsp_activity_eligible.py and al_ccsp_enrolled.py - Expand al_ccsp_protective_services.py comment to enumerate all five State Plan §2.2.2(f) sub-populations and which are not tracked - Clarify in loco parentis caregiver handling via the meets_ccdf_activity_test fallback in al_ccsp_activity_eligible.py - Floor monthly_income at zero in al_ccsp_weekly_copay_per_child.py so self-employment / farm losses land in the $0 copay band rather than producing a negative FPL ratio - Add edge_cases.yaml test exercising self-employment loss --- .../gov/states/al/dhr/ccsp/edge_cases.yaml | 43 +++++++++++++++++++ .../states/al/dhr/ccsp/al_ccsp_enrolled.py | 11 ++--- .../copay/al_ccsp_weekly_copay_per_child.py | 4 +- .../eligibility/al_ccsp_activity_eligible.py | 26 ++++++----- .../al_ccsp_protective_services.py | 17 +++++--- 5 files changed, 74 insertions(+), 27 deletions(-) diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml index 8e25e30c5aa..901ac5ca078 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml @@ -471,3 +471,46 @@ # AL households only. al_ccsp: 0 al_ccsp_eligible: false + +# -- Negative countable income (self-employment loss) -- + +- name: Self-employment loss floors copay at zero and does not inflate subsidy. + period: 2024-01 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + self_employment_income: -60_000 # -$5K/month loss + immigration_status: CITIZEN + weekly_hours_worked: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + childcare_hours_per_week: 35 + al_ccsp_provider_type: CENTER + al_ccsp_quality_tier: BASE + pre_subsidy_childcare_expenses: 20_000 # /year per child + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 20_000 + households: + household: + members: [person1, person2] + state_code: AL + county_str: JEFFERSON_COUNTY_AL # Birmingham region + output: + # Negative countable income passes the FPL/SMI tests trivially. + al_ccsp_income_eligible: true + # fpl_ratio is floored at 0 -> lowest fee bracket (0) + al_ccsp_weekly_copay_per_child: 0 + al_ccsp_copay: 0 + # Weekly expense ($20K/52 = $384.62) capped at Birmingham CENTER + # PRESCHOOL BASE max rate ($180). Subsidy = $180 - $0 copay = $180/wk. + # Monthly: $180 * (52/12) = $780. + al_ccsp: 780 diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py index ad62b1bd5c8..0c30956a558 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py @@ -5,13 +5,10 @@ class al_ccsp_enrolled(Variable): value_type = bool entity = SPMUnit definition_period = MONTH + # Distinguishes new applicants (180% FPL initial cap) from continuing + # recipients (200% FPL continuing cap, §2.5.5). Defaults to False, so + # every household is treated as a new applicant unless this input is + # explicitly set. label = "Whether the family is currently enrolled in Alabama CCSP" - documentation = ( - "Distinguishes new applicants (180% FPL initial-eligibility cap) " - "from continuing recipients (200% FPL cap). Defaults to False, so " - "every microdata household is treated as a new applicant unless " - "the user explicitly sets this input — the 200% FPL continuing " - "branch is unreachable without it." - ) defined_for = StateCode.AL reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39" diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py index ad008748298..3e3ed839410 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py @@ -12,7 +12,9 @@ class al_ccsp_weekly_copay_per_child(Variable): def formula(spm_unit, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.copay - monthly_income = spm_unit("al_ccsp_countable_income", period) + # Floor income at 0 so self-employment / farm losses land in the + # $0 copay band rather than producing a negative FPL ratio. + monthly_income = max_(spm_unit("al_ccsp_countable_income", period), 0) monthly_fpg = spm_unit("spm_unit_fpg", period) fpl_ratio = where(monthly_fpg > 0, monthly_income / monthly_fpg, 0) fee = p.fee_by_fpl.calc(fpl_ratio) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py index 9c607a30448..c48c8ae103a 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py @@ -5,20 +5,17 @@ class al_ccsp_activity_eligible(Variable): value_type = bool entity = SPMUnit label = "Eligible for Alabama CCSP based on parental activity requirements" - documentation = ( - "True when every head/spouse in the SPM unit meets §2.2.2 work or " - "full-time-student requirements, OR when meets_ccdf_activity_test " - "is set as an input override. The fallback is permissive: a unit " - "with one working and one non-working parent (which §2.2.2 would " - "deny) is treated as eligible when meets_ccdf_activity_test is True. " - "Users who need strict §2.2.2 enforcement should leave the override " - "unset." - ) definition_period = MONTH defined_for = StateCode.AL reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=21" def formula(spm_unit, period, parameters): + # Alabama §2.2.2(d)(ii) applies the activity test to the parent(s) + # or in loco parentis caregiver(s). We approximate the caregiver + # set with is_tax_unit_head_or_spouse; grandparent / kinship / + # foster caregivers who aren't the tax-unit head won't be checked + # individually, so users should set meets_ccdf_activity_test in + # those cases. p = parameters(period).gov.states.al.dhr.ccsp.activity person = spm_unit.members is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) @@ -28,10 +25,11 @@ def formula(spm_unit, period, parameters): individually_eligible = meets_work_requirement | is_student has_head_or_spouse = spm_unit.sum(is_head_or_spouse) >= 1 all_covered = spm_unit.sum(is_head_or_spouse & ~individually_eligible) == 0 - # Fallback input for approved activities not individually modeled - # (job search, education/training, SNAP E&T, temporary leave, - # disabled-parent good cause, etc.). Alabama's §2.2.2 only waives - # the activity test for children receiving protective services - # (§2.2.2(h)); other exemptions must be set via this fallback. + # Permissive fallback for approved activities not individually + # modeled (job search, education/training, SNAP E&T, temporary + # leave, disabled-parent good cause, in loco parentis caregivers, + # etc.). §2.2.2 only waives the activity test categorically for + # children receiving protective services (§2.2.2(h)); other + # exemptions must be set via this fallback input. fallback = spm_unit("meets_ccdf_activity_test", period.this_year) return (has_head_or_spouse & all_covered) | fallback diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py index 5f6858f5949..9b5f34b49af 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py @@ -10,11 +10,18 @@ class al_ccsp_protective_services(Variable): reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=23" def formula(spm_unit, period, parameters): - # Foster care and homelessness are the modeled protective-service - # categories. §3.3.1(vi) also names kinship care as a copay-waiver - # trigger, but we don't track kinship care at the moment. EHS-CCP, - # child-welfare engagement, and TANF-Other Relative are also not - # tracked at the moment. + # State Plan §2.2.2(f) names five protective-services sub-populations: + # (i) foster care — modeled via is_in_foster_care + # (ii) homelessness — modeled via is_homeless + # (iii) families engaged with a child welfare agency — we don't + # track child-welfare engagement at the moment + # (iv) Early Head Start Child Care Partnerships (EHS-CCP) — we + # don't track EHS-CCP enrollment at the moment + # (v) kinship care / TANF-Other Relative (also a §3.3.1(vi) copay- + # waiver trigger) — we don't track kinship care at the moment + # The three unmodeled categories under-count protective-services + # eligibility, which waives the income and activity tests + # (§2.2.2(g)-(h)). has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 is_homeless = spm_unit.household("is_homeless", period.this_year) return has_foster_child | is_homeless From 77d819873c60736f5571a097fb91a9a87ba16a41 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 17 May 2026 22:47:28 -0400 Subject: [PATCH 11/15] Use prior-year HHS FPG for AL CCSP income tests Alabama's Child Care Fact Sheet income tables track the prior calendar year's HHS poverty guidelines (e.g., the Jan-2024 Fact Sheet uses 2023 FPG values), since HHS publishes new guidelines mid-January. - al_ccsp_income_eligible.py and al_ccsp_weekly_copay_per_child.py now pull FPG for period.start.year - 1 - All FPL-relative test income values rebased to 2023 FPG for 2024-01 tests; the 2025-01 carry-forward test still uses 38_730 because that is 150% of the 2024 FPG used at that period --- .../gov/states/al/dhr/ccsp/al_ccsp.yaml | 6 +-- .../gov/states/al/dhr/ccsp/al_ccsp_copay.yaml | 33 +++++++------ .../al/dhr/ccsp/al_ccsp_income_eligible.yaml | 45 +++++++++--------- .../ccsp/al_ccsp_weekly_copay_per_child.yaml | 47 ++++++++++--------- .../gov/states/al/dhr/ccsp/edge_cases.yaml | 6 +-- .../gov/states/al/dhr/ccsp/integration.yaml | 27 ++++++----- .../copay/al_ccsp_weekly_copay_per_child.py | 5 +- .../eligibility/al_ccsp_income_eligible.py | 7 ++- 8 files changed, 96 insertions(+), 80 deletions(-) diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml index 246f3eadf27..5dfeb50822f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp.yaml @@ -51,7 +51,7 @@ people: person1: age: 30 - employment_income: 18_000 # ~ 86% FPL fam of 2 -> 0% copay band + employment_income: 18_000 # ~91% 2023 FPG fam of 2 -> 0% copay band immigration_status: CITIZEN weekly_hours_worked: 30 person2: @@ -90,7 +90,7 @@ people: person1: age: 30 - employment_income: 30_660 # 150% FPL fam of 2 = 2,555/mo + employment_income: 29_580 # 150% 2023 FPG fam of 2 = 19,720 * 1.5 immigration_status: CITIZEN weekly_hours_worked: 40 person2: @@ -162,7 +162,7 @@ people: person1: age: 30 - employment_income: 18_000 # ~58% FPL fam of 4 -> zero copay band + employment_income: 18_000 # ~60% 2023 FPG fam of 4 -> zero copay band immigration_status: CITIZEN weekly_hours_worked: 30 person2: diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml index 67a51745670..1b171f3ad1c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml @@ -3,9 +3,12 @@ # Waivers (zero copay): disabled child, Head Start enrollment, protective services (foster). # Homelessness alone does NOT waive copay (per State Plan §3.3.1(iii)). # -# 2024 FPG (Contiguous US): first $15,060, additional $5,380. -# FS 2: $20,440/yr ($1,703.33/mo) -# FS 4: $31,200/yr ($2,600/mo) +# AL uses the prior year's HHS FPG (Fact Sheet 2024 -> 2023 FPG). +# 2023 FPG (Contiguous US): first $14,580, additional $5,140. +# FS 2: $19,720/yr ($1,643.33/mo) +# FS 3: $24,860/yr ($2,071.67/mo) +# FS 4: $30,000/yr ($2,500/mo) +# FS 5: $35,140/yr ($2,928.33/mo) # Initial fee scale (effective 2024-01-01), weekly per child: # 0-100% FPL -> $0 # 101-110 -> $18 @@ -27,7 +30,7 @@ people: person1: age: 30 - employment_income: 16_352 # 80% FPL fam of 2 = 16,352/yr -> 1,363/mo + employment_income: 15_776 # 80% 2023 FPG fam of 2 = 15,776/yr -> 1,315/mo person2: age: 4 is_tax_unit_dependent: true @@ -57,7 +60,7 @@ people: person1: age: 30 - employment_income: 30_660 # 150% FPL fam of 2 = 30,660/yr -> 2,555/mo + employment_income: 29_580 # 150% 2023 FPG fam of 2 = 29,580/yr -> 2,465/mo person2: age: 4 is_tax_unit_dependent: true @@ -88,7 +91,7 @@ people: person1: age: 30 - employment_income: 35_770 # 175% FPL fam of 2 = 35,770/yr -> 2,981/mo + employment_income: 34_510 # 175% 2023 FPG fam of 2 = 34,510/yr -> 2,876/mo person2: age: 4 is_tax_unit_dependent: true @@ -119,7 +122,7 @@ people: person1: age: 30 - employment_income: 37_814 # 185% FPL fam of 2 = 37,814/yr -> 3,151/mo + employment_income: 36_482 # 185% 2023 FPG fam of 2 = 36,482/yr -> 3,040/mo person2: age: 4 is_tax_unit_dependent: true @@ -151,7 +154,7 @@ people: person1: age: 30 - employment_income: 39_858 # 195% FPL fam of 2 = 39,858/yr -> 3,322/mo + employment_income: 38_454 # 195% 2023 FPG fam of 2 = 38,454/yr -> 3,205/mo person2: age: 4 is_tax_unit_dependent: true @@ -183,7 +186,7 @@ people: person1: age: 30 - employment_income: 38_730 # 150% FPL fam of 3 = 38,730/yr -> 3,228/mo + employment_income: 37_290 # 150% 2023 FPG fam of 3 = 37,290/yr -> 3,108/mo person2: age: 4 is_tax_unit_dependent: true @@ -311,7 +314,7 @@ people: person1: age: 30 - employment_income: 30_660 # 150% FPL fam of 2 + employment_income: 29_580 # 150% 2023 FPG fam of 2 person2: age: 4 is_tax_unit_dependent: true @@ -344,7 +347,7 @@ people: person1: age: 30 - employment_income: 46_800 # 150% FPL fam of 4 = $46,800/yr -> $3,900/mo + employment_income: 45_000 # 150% 2023 FPG fam of 4 = $45,000/yr -> $3,750/mo person2: # Truly eligible: age 4, citizen, dependent, in care age: 4 @@ -393,7 +396,7 @@ people: person1: age: 30 - employment_income: 38_730 # 150% FPL fam of 3 = $38,730/yr -> $3,228/mo + employment_income: 37_290 # 150% 2023 FPG fam of 3 = $37,290/yr -> $3,108/mo person2: age: 4 is_tax_unit_dependent: true @@ -431,7 +434,7 @@ people: person1: age: 30 - employment_income: 30_660 # 150% FPL fam of 2 + employment_income: 29_580 # 150% 2023 FPG fam of 2 person2: age: 4 is_tax_unit_dependent: true @@ -499,7 +502,7 @@ people: person1: age: 30 - employment_income: 54_870 # 150% FPL fam of 5 = $54,870/yr + employment_income: 52_710 # 150% 2023 FPG fam of 5 = $52,710/yr person2: age: 4 is_tax_unit_dependent: true @@ -546,7 +549,7 @@ people: person1: age: 30 - employment_income: 54_870 # 150% FPL fam of 5 = $54,870/yr + employment_income: 52_710 # 150% 2023 FPG fam of 5 = $52,710/yr person2: # Second parent age: 28 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml index f7b6b5df44d..c5dad7f2e3b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_income_eligible.yaml @@ -2,13 +2,14 @@ # Initial path: monthly income <= 180% FPL AND <= 85% SMI. # Continuing path (al_ccsp_enrolled=True): monthly income <= 200% FPL AND <= 85% SMI. # -# 2024 FPG (Contiguous US): first_person $15,060, additional $5,380. -# Family of 2: $20,440/yr ($1,703.33/mo) -# Family of 3: $25,820/yr ($2,151.67/mo) -# Family of 4: $31,200/yr ($2,600/mo) -# 180% FPL (FS 3): $46,476/yr ($3,873/mo) -# 180% FPL (FS 4): $56,160/yr ($4,680/mo) -# 200% FPL (FS 4): $62,400/yr ($5,200/mo) +# AL CCSP uses the prior year's HHS FPG (Fact Sheet 2024 -> 2023 FPG). +# 2023 FPG (Contiguous US): first_person $14,580, additional $5,140. +# Family of 2: $19,720/yr ($1,643.33/mo) +# Family of 3: $24,860/yr ($2,071.67/mo) +# Family of 4: $30,000/yr ($2,500/mo) +# 180% FPL (FS 3): $44,748/yr ($3,729/mo) +# 180% FPL (FS 4): $54,000/yr ($4,500/mo) +# 200% FPL (FS 4): $60,000/yr ($5,000/mo) # AL SMI FS 4 (2023-10-01 -> applies 2024): $88,407. 85% SMI FS 4: $75,145.95/yr ($6,262.16/mo). - name: Family at 150 percent FPL initial path is income eligible. @@ -17,7 +18,7 @@ people: person1: age: 30 - employment_income: 46_800 # 150% FPL fam of 4 = 46,800/yr = 3,900/mo + employment_income: 45_000 # 150% FPL fam of 4 = 45,000/yr = 3,750/mo person2: age: 28 person3: @@ -38,8 +39,8 @@ members: [person1, person2, person3, person4] state_code: AL output: - # 3,900/mo <= 4,680/mo (180% FPL) -> initial-eligible - # 3,900/mo <= 6,262/mo (85% SMI) -> SMI-eligible + # 3,750/mo <= 4,500/mo (180% FPL) -> initial-eligible + # 3,750/mo <= 6,262/mo (85% SMI) -> SMI-eligible al_ccsp_income_eligible: true - name: Family at 190 percent FPL initial path is income ineligible. @@ -48,7 +49,7 @@ people: person1: age: 30 - employment_income: 59_280 # 190% FPL fam of 4 = 59,280/yr = 4,940/mo + employment_income: 57_000 # 190% FPL fam of 4 = 57,000/yr = 4,750/mo person2: age: 28 person3: @@ -69,7 +70,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # 4,940/mo > 4,680/mo (180% FPL) -> initial path fails + # 4,750/mo > 4,500/mo (180% FPL) -> initial path fails al_ccsp_income_eligible: false - name: Family at 190 percent FPL continuing path is income eligible. @@ -78,7 +79,7 @@ people: person1: age: 30 - employment_income: 59_280 # 190% FPL fam of 4 + employment_income: 57_000 # 190% FPL fam of 4 person2: age: 28 person3: @@ -99,8 +100,8 @@ members: [person1, person2, person3, person4] state_code: AL output: - # 4,940/mo <= 5,200/mo (200% FPL) -> continuing-eligible - # 4,940/mo <= 6,262/mo (85% SMI) -> SMI-eligible + # 4,750/mo <= 5,000/mo (200% FPL) -> continuing-eligible + # 4,750/mo <= 6,262/mo (85% SMI) -> SMI-eligible al_ccsp_income_eligible: true - name: Family above 200 percent FPL continuing path is income ineligible. @@ -109,7 +110,7 @@ people: person1: age: 30 - employment_income: 65_000 # ~208% FPL fam of 4 = 5,417/mo + employment_income: 63_000 # 210% FPL fam of 4 = 5,250/mo person2: age: 28 person3: @@ -130,7 +131,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # 5,417/mo > 5,200/mo (200% FPL) -> continuing path fails + # 5,250/mo > 5,000/mo (200% FPL) -> continuing path fails al_ccsp_income_eligible: false - name: Family above 85 percent SMI is income ineligible even at continuing tier. @@ -170,7 +171,7 @@ people: person1: age: 30 - employment_income: 56_160 # 180% FPL fam of 4 = 31,200 * 1.8 + employment_income: 54_000 # 180% FPL fam of 4 = 30,000 * 1.8 person2: age: 28 person3: @@ -191,7 +192,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # 56,160 == 180% FPL exactly -> formula uses <=, so still eligible at the boundary. + # 54,000 == 180% FPL exactly -> formula uses <=, so still eligible at the boundary. al_ccsp_income_eligible: true - name: Family at exactly 200 percent FPL continuing path is income eligible. @@ -200,7 +201,7 @@ people: person1: age: 30 - employment_income: 62_400 # 200% FPL fam of 4 = 31,200 * 2.0 + employment_income: 60_000 # 200% FPL fam of 4 = 30,000 * 2.0 person2: age: 28 person3: @@ -221,8 +222,8 @@ members: [person1, person2, person3, person4] state_code: AL output: - # 62,400 == 200% FPL exactly -> formula uses <=, so still eligible at the boundary. - # 62,400/yr < 75,146/yr (85% SMI) -> SMI cap passes. + # 60,000 == 200% FPL exactly -> formula uses <=, so still eligible at the boundary. + # 60,000/yr < 75,146/yr (85% SMI) -> SMI cap passes. al_ccsp_income_eligible: true - name: Family just over 85 percent SMI is income ineligible at continuing tier. diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml index 476a8e88c6d..7b5270f2fbd 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_weekly_copay_per_child.yaml @@ -3,11 +3,12 @@ # Initial applicants must be at or below 180% FPL; continuing recipients may # remain enrolled up to 200% FPL. Both tiers use the same fee schedule. # -# 2024 FPG (Contiguous US), family of 4: $31,200/yr = $2,600/mo. -# 80% FPL fam of 4 = $24,960/yr ($2,080/mo) -# 150% FPL fam of 4 = $46,800/yr ($3,900/mo) -# 185% FPL fam of 4 = $57,720/yr ($4,810/mo) -# 195% FPL fam of 4 = $60,840/yr ($5,070/mo) +# AL uses the prior year's HHS FPG (Fact Sheet 2024 -> 2023 FPG). +# 2023 FPG (Contiguous US), family of 4: $30,000/yr = $2,500/mo. +# 80% FPL fam of 4 = $24,000/yr ($2,000/mo) +# 150% FPL fam of 4 = $45,000/yr ($3,750/mo) +# 185% FPL fam of 4 = $55,500/yr ($4,625/mo) +# 195% FPL fam of 4 = $58,500/yr ($4,875/mo) - name: Family at 150 percent FPL has $30 weekly per-child fee. period: 2024-01 @@ -16,7 +17,7 @@ people: person1: age: 30 - employment_income: 46_800 # 150% FPL fam of 4 + employment_income: 45_000 # 150% FPL fam of 4 = 45,000/yr person2: age: 28 person3: @@ -37,7 +38,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 3,900 / 2,600 = 1.5 -> band [1.4001, 1.5001) -> $30/wk + # FPL ratio = 3,750 / 2,500 = 1.5 -> band [1.4001, 1.5001) -> $30/wk al_ccsp_weekly_copay_per_child: 30 - name: Family at 80 percent FPL has zero weekly per-child fee. @@ -47,7 +48,7 @@ people: person1: age: 30 - employment_income: 24_960 # 80% FPL fam of 4 + employment_income: 24_000 # 80% FPL fam of 4 person2: age: 28 person3: @@ -68,7 +69,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 2,080 / 2,600 = 0.8 -> band [0, 1.0001) -> $0/wk + # FPL ratio = 2,000 / 2,500 = 0.8 -> band [0, 1.0001) -> $0/wk al_ccsp_weekly_copay_per_child: 0 - name: Enrolled family at 185 percent FPL has $42 weekly per-child fee. @@ -78,7 +79,7 @@ people: person1: age: 30 - employment_income: 57_720 # 185% FPL fam of 4 + employment_income: 55_500 # 185% FPL fam of 4 person2: age: 28 person3: @@ -99,7 +100,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 4,810 / 2,600 = 1.85 -> band [1.8001, 1.9001) -> $42/wk + # FPL ratio = 4,625 / 2,500 = 1.85 -> band [1.8001, 1.9001) -> $42/wk al_ccsp_weekly_copay_per_child: 42 - name: Enrolled family at 195 percent FPL has $45 weekly per-child fee. @@ -109,7 +110,7 @@ people: person1: age: 30 - employment_income: 60_840 # 195% FPL fam of 4 + employment_income: 58_500 # 195% FPL fam of 4 person2: age: 28 person3: @@ -130,7 +131,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 5,070 / 2,600 = 1.95 -> band [1.9001, ...) -> $45/wk + # FPL ratio = 4,875 / 2,500 = 1.95 -> band [1.9001, ...) -> $45/wk al_ccsp_weekly_copay_per_child: 45 - name: Family at 130 percent FPL has $24 weekly per-child fee. @@ -140,7 +141,7 @@ people: person1: age: 30 - employment_income: 40_560 # 130% FPL fam of 4 = 3,380/mo + employment_income: 39_000 # 130% FPL fam of 4 = 3,250/mo person2: age: 28 person3: @@ -161,7 +162,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 3,380 / 2,600 = 1.30 -> band [1.2001, 1.3001) -> $24/wk + # FPL ratio = 3,250 / 2,500 = 1.30 -> band [1.2001, 1.3001) -> $24/wk al_ccsp_weekly_copay_per_child: 24 - name: Family at 140 percent FPL has $27 weekly per-child fee. @@ -171,7 +172,7 @@ people: person1: age: 30 - employment_income: 43_680 # 140% FPL fam of 4 = 3,640/mo + employment_income: 42_000 # 140% FPL fam of 4 = 3,500/mo person2: age: 28 person3: @@ -192,7 +193,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 3,640 / 2,600 = 1.40 -> band [1.3001, 1.4001) -> $27/wk + # FPL ratio = 3,500 / 2,500 = 1.40 -> band [1.3001, 1.4001) -> $27/wk al_ccsp_weekly_copay_per_child: 27 - name: Family at 160 percent FPL has $33 weekly per-child fee. @@ -202,7 +203,7 @@ people: person1: age: 30 - employment_income: 49_920 # 160% FPL fam of 4 = 4,160/mo + employment_income: 48_000 # 160% FPL fam of 4 = 4,000/mo person2: age: 28 person3: @@ -223,7 +224,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 4,160 / 2,600 = 1.60 -> band [1.5001, 1.6001) -> $33/wk + # FPL ratio = 4,000 / 2,500 = 1.60 -> band [1.5001, 1.6001) -> $33/wk al_ccsp_weekly_copay_per_child: 33 - name: Family at 170 percent FPL has $36 weekly per-child fee. @@ -233,7 +234,7 @@ people: person1: age: 30 - employment_income: 53_040 # 170% FPL fam of 4 = 4,420/mo + employment_income: 51_000 # 170% FPL fam of 4 = 4,250/mo person2: age: 28 person3: @@ -254,7 +255,7 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 4,420 / 2,600 = 1.70 -> band [1.6001, 1.7001) -> $36/wk + # FPL ratio = 4,250 / 2,500 = 1.70 -> band [1.6001, 1.7001) -> $36/wk al_ccsp_weekly_copay_per_child: 36 - name: Enrolled family at exactly 200 percent FPL has $45 weekly per-child fee. @@ -264,7 +265,7 @@ people: person1: age: 30 - employment_income: 62_400 # 200% FPL fam of 4 = 5,200/mo + employment_income: 60_000 # 200% FPL fam of 4 = 5,000/mo person2: age: 28 person3: @@ -285,5 +286,5 @@ members: [person1, person2, person3, person4] state_code: AL output: - # FPL ratio = 5,200 / 2,600 = 2.00 -> band [1.9001, inf) -> $45/wk + # FPL ratio = 5,000 / 2,500 = 2.00 -> band [1.9001, inf) -> $45/wk al_ccsp_weekly_copay_per_child: 45 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml index 901ac5ca078..7b4a785a1bc 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml @@ -315,7 +315,7 @@ people: person1: age: 30 - employment_income: 20_440 # 100% FPL fam of 2 + employment_income: 19_720 # 100% 2023 FPG fam of 2 immigration_status: CITIZEN weekly_hours_worked: 30 person2: @@ -347,7 +347,7 @@ people: person1: age: 30 - employment_income: 22_484 # 110% FPL fam of 2 = 22,484/yr + employment_income: 21_692 # 110% 2023 FPG fam of 2 = 19,720 * 1.10 immigration_status: CITIZEN weekly_hours_worked: 30 person2: @@ -380,7 +380,7 @@ people: person1: age: 30 - employment_income: 24_528 # 120% FPL fam of 2 + employment_income: 23_664 # 120% 2023 FPG fam of 2 = 19,720 * 1.20 immigration_status: CITIZEN weekly_hours_worked: 30 person2: diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml index d87f203437e..c9928c6ab04 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml @@ -1,11 +1,12 @@ # AL CCSP integration tests # Cross-cuts eligibility, copay, rate lookup, and benefit calculation. # -# 2024 FPG (Contiguous US): first $15,060, additional $5,380. -# FS 2: $20,440/yr ($1,703.33/mo); 150% FPL = 2,555/mo; 180% = 3,066/mo -# FS 3: $25,820/yr ($2,151.67/mo) -# FS 4: $31,200/yr ($2,600/mo); 150% FPL = 3,900/mo; 180% = 4,680/mo; -# 190% = 4,940/mo; 200% = 5,200/mo +# AL CCSP uses the prior calendar year's HHS FPG (Fact Sheet 2024 -> 2023 FPG). +# 2023 FPG (Contiguous US): first $14,580, additional $5,140. +# FS 2: $19,720/yr ($1,643.33/mo); 150% FPL = 2,465/mo; 180% = 2,958/mo +# FS 3: $24,860/yr ($2,071.67/mo) +# FS 4: $30,000/yr ($2,500/mo); 150% FPL = 3,750/mo; 180% = 4,500/mo; +# 190% = 4,750/mo; 200% = 5,000/mo # AL SMI FS 4 (2023-10-01): $88,407/yr. 85% SMI FS 4: $75,145.95/yr (6,262.16/mo). # Weekly -> monthly multiplier: WEEKS_IN_YEAR / MONTHS_IN_YEAR = 52/12 ≈ 4.3333. @@ -16,7 +17,7 @@ people: person1: age: 30 - employment_income: 38_730 # 150% FPL fam of 3 = 3,228/mo + employment_income: 37_290 # 150% 2023 FPG fam of 3 = 24,860 * 1.5 immigration_status: CITIZEN weekly_hours_worked: 40 person2: @@ -63,7 +64,7 @@ people: person1: age: 25 - employment_income: 12_264 # ~60% FPL fam of 2 = 1,022/mo + employment_income: 12_264 # ~62% 2023 FPG fam of 2 = 1,022/mo immigration_status: CITIZEN weekly_hours_worked: 30 person2: @@ -105,7 +106,7 @@ people: person1: age: 30 - employment_income: 59_280 # 190% FPL fam of 4 + employment_income: 57_000 # 190% 2023 FPG fam of 4 = 30,000 * 1.9 immigration_status: CITIZEN weekly_hours_worked: 40 person2: @@ -149,7 +150,7 @@ people: person1: age: 30 - employment_income: 49_058 # 190% FPL fam of 3 = 49,058/yr + employment_income: 47_234 # 190% 2023 FPG fam of 3 = 24,860 * 1.9 immigration_status: CITIZEN weekly_hours_worked: 40 person2: @@ -178,7 +179,7 @@ county_str: JEFFERSON_COUNTY_AL output: al_ccsp_eligible: true - # FPL ratio = 49,058 / 25,820 = 1.90 -> 181-190 band -> $42/wk + # FPL ratio = 47,234 / 24,860 = 1.90 -> 181-190 band -> $42/wk # $42 * (52/12) = $182/mo al_ccsp_copay: 182 # BIRMINGHAM CENTER PRESCHOOL BASE = $180/wk @@ -235,7 +236,7 @@ people: person1: age: 35 - employment_income: 30_660 # 150% FPL fam of 2 (would normally have $30/wk copay) + employment_income: 29_580 # 150% 2023 FPG fam of 2 (would normally have $30/wk copay) immigration_status: CITIZEN weekly_hours_worked: 40 person2: @@ -316,7 +317,7 @@ people: person1: age: 30 - employment_income: 38_730 # 150% FPL fam of 3 = 3,228/mo + employment_income: 37_290 # 150% 2023 FPG fam of 3 = 24,860 * 1.5 immigration_status: CITIZEN weekly_hours_worked: 40 person2: @@ -444,6 +445,8 @@ people: person1: age: 30 + # 2025-01 uses prior-year (2024) FPG for fam of 3 = 25,820; + # 150% = 38,730. employment_income: 38_730 immigration_status: CITIZEN weekly_hours_worked: 40 diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py index 3e3ed839410..9b49401b51e 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_weekly_copay_per_child.py @@ -15,7 +15,10 @@ def formula(spm_unit, period, parameters): # Floor income at 0 so self-employment / farm losses land in the # $0 copay band rather than producing a negative FPL ratio. monthly_income = max_(spm_unit("al_ccsp_countable_income", period), 0) - monthly_fpg = spm_unit("spm_unit_fpg", period) + # Use the prior calendar year's HHS poverty guidelines to match + # Alabama's Child Care Fact Sheet operational thresholds. + prior_year = period.start.year - 1 + monthly_fpg = spm_unit("spm_unit_fpg", str(prior_year)) / MONTHS_IN_YEAR fpl_ratio = where(monthly_fpg > 0, monthly_income / monthly_fpg, 0) fee = p.fee_by_fpl.calc(fpl_ratio) copay_waived = spm_unit("al_ccsp_copay_waived", period) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py index b65787f4f3e..09b7aa529c4 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_income_eligible.py @@ -13,7 +13,12 @@ def formula(spm_unit, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.income.limit monthly_income = spm_unit("al_ccsp_countable_income", period) - monthly_fpg = spm_unit("spm_unit_fpg", period) + # Alabama's published income tables (Child Care Fact Sheet) use the + # prior calendar year's HHS poverty guidelines throughout the + # benefit year, since HHS publishes the new guidelines mid-January. + prior_year = period.start.year - 1 + annual_fpg = spm_unit("spm_unit_fpg", str(prior_year)) + monthly_fpg = annual_fpg / MONTHS_IN_YEAR enrolled = spm_unit("al_ccsp_enrolled", period) fpl_limit_ratio = where( enrolled, From a1f60bef89a86b8c8fc55abb85d0bc2d9dc0e518 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 17 May 2026 22:58:14 -0400 Subject: [PATCH 12/15] =?UTF-8?q?Polish=20AL=20CCSP=20=E2=80=94=20drop=20r?= =?UTF-8?q?eporting-only=20copay=20variable,=20fix=20anchors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove al_ccsp_copay variable + test file. Nothing in the model consumed it: the benefit formula uses al_ccsp_weekly_copay_per_child (per-child, broadcast to Person level) because per-child clamping matters for households with one free-care and one paid-care child. Tests that asserted al_ccsp_copay now assert al_ccsp_weekly_copay_per_child. - Update fee_by_fpl.yaml reference: §3.1 #page=40 -> §3.1.2(b) #page=41 (lands on the actual fee table, not the section header) - Update smi_cap.yaml reference: §2.5.2 #page=35 -> §2.5.5 #page=38 (the verbatim 85% SMI rule is in §2.5.5) - Remove trailing whitespace in sources.yaml - Drop WHAT-only comments in al_ccsp.py and al_ccsp_age_category.py --- .../states/al/dhr/ccsp/copay/fee_by_fpl.yaml | 4 +- .../ccsp/income/countable_income/sources.yaml | 2 +- .../al/dhr/ccsp/income/limit/smi_cap.yaml | 4 +- .../gov/states/al/dhr/ccsp/al_ccsp_copay.yaml | 595 ------------------ .../gov/states/al/dhr/ccsp/edge_cases.yaml | 10 +- .../gov/states/al/dhr/ccsp/integration.yaml | 17 +- .../gov/states/al/dhr/ccsp/al_ccsp.py | 2 - .../al/dhr/ccsp/al_ccsp_age_category.py | 1 - .../states/al/dhr/ccsp/copay/al_ccsp_copay.py | 24 - 9 files changed, 17 insertions(+), 642 deletions(-) delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml delete mode 100644 policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml index 00970d1d265..a03874180f4 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/copay/fee_by_fpl.yaml @@ -9,8 +9,8 @@ metadata: reference: - title: Alabama Child Care Fact Sheet, Initial and Continuing Eligibility Monthly Income Scale and Parental Fee Chart href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf - - title: Alabama CCDF State Plan 2025-2027, Section 3.1 - href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=40 + - title: Alabama CCDF State Plan 2025-2027, Section 3.1.2(b) Parental Fee Chart + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=41 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml index 0ce9b37a5be..2feb93e5c50 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/countable_income/sources.yaml @@ -13,7 +13,7 @@ values: - interest_income - dividend_income - alimony_income - - veterans_benefits + - veterans_benefits # - tanf exclude as of now to avoid circular reference error # Section 2.2.4(c) also lists inheritance and college work-study, # but no matching variables exist in policyengine-us at this time. diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml index 172723dbf7c..dd67d664c2c 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml @@ -9,7 +9,7 @@ metadata: reference: - title: Alabama CCDF State Plan 2025-2027, Section 2.2.4 href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=26 - - title: Alabama CCDF State Plan 2025-2027, Section 2.5.2 - href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=35 + - title: Alabama CCDF State Plan 2025-2027, Section 2.5.5 Income Cutoff (85% SMI) + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=38 - title: Alabama Child Care Fact Sheet (Income Cutoff 85% SMI) href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml deleted file mode 100644 index 1b171f3ad1c..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay.yaml +++ /dev/null @@ -1,595 +0,0 @@ -# AL CCSP family copay tests (SPMUnit, MONTH, USD) -# Per-child weekly fee from FPL band, summed over eligible children, converted to monthly via 4.333. -# Waivers (zero copay): disabled child, Head Start enrollment, protective services (foster). -# Homelessness alone does NOT waive copay (per State Plan §3.3.1(iii)). -# -# AL uses the prior year's HHS FPG (Fact Sheet 2024 -> 2023 FPG). -# 2023 FPG (Contiguous US): first $14,580, additional $5,140. -# FS 2: $19,720/yr ($1,643.33/mo) -# FS 3: $24,860/yr ($2,071.67/mo) -# FS 4: $30,000/yr ($2,500/mo) -# FS 5: $35,140/yr ($2,928.33/mo) -# Initial fee scale (effective 2024-01-01), weekly per child: -# 0-100% FPL -> $0 -# 101-110 -> $18 -# 111-120 -> $21 -# 121-130 -> $24 -# 131-140 -> $27 -# 141-150 -> $30 -# 151-160 -> $33 -# 161-170 -> $36 -# 171-180 -> $39 -# Continuing schedule: -# 181-190 -> $42 -# 191-200 -> $45 - -- name: Family at 80 percent FPL has zero copay (encoded in scale). - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 15_776 # 80% 2023 FPG fam of 2 = 15,776/yr -> 1,315/mo - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # <= 100% FPL band -> $0/wk -> $0/mo - al_ccsp_copay: 0 - -- name: Family at 150 percent FPL with one child pays 30 per week. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 29_580 # 150% 2023 FPG fam of 2 = 29,580/yr -> 2,465/mo - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # 150% FPL -> 141-150 band -> $30/wk per child - # 1 child * $30/wk * 4.333 = $130.00/mo - al_ccsp_copay: 129.99 - -- name: Family at 175 percent FPL pays 39 per week. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 34_510 # 175% 2023 FPG fam of 2 = 34,510/yr -> 2,876/mo - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # 175% FPL -> 171-180 band -> $39/wk per child - # $39 * 4.333 = $168.99/mo - al_ccsp_copay: 168.99 - -- name: Continuing-tier family at 185 percent FPL pays 42 per week. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 36_482 # 185% 2023 FPG fam of 2 = 36,482/yr -> 3,040/mo - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - al_ccsp_enrolled: true - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # 185% FPL -> 181-190 continuing band -> $42/wk per child - # $42 * 4.333 = $181.99/mo - al_ccsp_copay: 181.99 - -- name: Continuing-tier family at 195 percent FPL pays 45 per week. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 38_454 # 195% 2023 FPG fam of 2 = 38,454/yr -> 3,205/mo - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - al_ccsp_enrolled: true - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # 195% FPL -> 191-200 continuing band -> $45/wk per child - # $45 * 4.333 = $194.99/mo - al_ccsp_copay: 194.99 - -- name: Two eligible children at 150 percent FPL pay two times 30 per week. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 37_290 # 150% 2023 FPG fam of 3 = 37,290/yr -> 3,108/mo - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person3: - age: 2 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2, person3] - spm_units: - spm_unit: - members: [person1, person2, person3] - households: - household: - members: [person1, person2, person3] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # 150% FPL -> $30/wk per child - # 2 children * $30 * 4.333 = $259.98/mo - al_ccsp_copay: 259.98 - -- name: Family with disabled child has zero copay. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 35_000 # would otherwise be paid tier - person2: - age: 5 - is_tax_unit_dependent: true - immigration_status: CITIZEN - is_disabled: true - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - al_ccsp_copay: 0 - -- name: Head Start enrollment waives copay. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 35_000 - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - is_enrolled_in_head_start: true - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - al_ccsp_copay: 0 - -- name: Foster care waives copay. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 35 - employment_income: 35_000 - person2: - age: 5 - is_tax_unit_dependent: true - immigration_status: CITIZEN - is_in_foster_care: true - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - al_ccsp_copay: 0 - -- name: Homeless household waives copay via Protective Service category. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 29_580 # 150% 2023 FPG fam of 2 - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - is_homeless: true - output: - # Homeless families fall under the Protective Service category per - # §2.2.2(f); §3.3.1(vi) waives copay for children authorized under - # that category. - al_ccsp_copay: 0 - -- name: Three children, only one truly eligible, copay counts only the eligible one. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 45_000 # 150% 2023 FPG fam of 4 = $45,000/yr -> $3,750/mo - person2: - # Truly eligible: age 4, citizen, dependent, in care - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person3: - # Over age (>= 13): citizen, dependent, in care, but ineligible by age - age: 14 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person4: - # Ineligible immigration status: dependent, in care, but undocumented - age: 6 - is_tax_unit_dependent: true - immigration_status: UNDOCUMENTED - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2, person3, person4] - spm_units: - spm_unit: - members: [person1, person2, person3, person4] - households: - household: - members: [person1, person2, person3, person4] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # 150% FPL fam of 4 -> $30/wk per child - # Only person2 is eligible_child & in_care -> num_paying = 1 - # 1 * $30/wk * (52/12) = $130.00/mo - al_ccsp_copay: 130 - -- name: Two eligible children but only one in care, copay counts the one in care. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 37_290 # 150% 2023 FPG fam of 3 = $37,290/yr -> $3,108/mo - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person3: - # Eligible but not in care this month - age: 2 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 0 - tax_units: - tax_unit: - members: [person1, person2, person3] - spm_units: - spm_unit: - members: [person1, person2, person3] - households: - household: - members: [person1, person2, person3] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # 150% FPL -> $30/wk per child - # Only person2 has childcare_hours > 0 -> num_paying = 1 - # 1 * $30/wk * (52/12) = $130.00/mo - al_ccsp_copay: 130 - -- name: Eligible child with zero care hours has zero copay. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 29_580 # 150% 2023 FPG fam of 2 - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 0 - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # Eligible but not in care -> num_paying = 0 -> no copay owed - al_ccsp_copay: 0 - -- name: Disabled child age 15 plus young eligible sibling both in care waives copay. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 35_000 # would otherwise be a paid tier - person2: - # Young eligible sibling, in care - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person3: - # Disabled child age 15: eligible under disabled limit (19), triggers waiver - age: 15 - is_tax_unit_dependent: true - immigration_status: CITIZEN - is_disabled: true - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2, person3] - spm_units: - spm_unit: - members: [person1, person2, person3] - households: - household: - members: [person1, person2, person3] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # Disabled child (age 15 < 19) triggers copay waiver per §3.3.1(iv). - al_ccsp_copay: 0 - -- name: Three eligible children all in care pays three times the per-child fee. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 52_710 # 150% 2023 FPG fam of 5 = $52,710/yr - person2: - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person3: - age: 6 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person4: - age: 8 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person5: - age: 28 - tax_units: - tax_unit: - members: [person1, person2, person3, person4, person5] - spm_units: - spm_unit: - members: [person1, person2, person3, person4, person5] - households: - household: - members: [person1, person2, person3, person4, person5] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # 150% FPL fam of 5 -> $30/wk per child band. - # 3 children * $30/wk * (52/12) = $90 * 4.3333 = $390.00/mo - al_ccsp_copay: 390 - -- name: Two-parent family with three children, only one eligible, copay counts that one. - period: 2024-01 - absolute_error_margin: 0.1 - input: - people: - person1: - age: 30 - employment_income: 52_710 # 150% 2023 FPG fam of 5 = $52,710/yr - person2: - # Second parent - age: 28 - person3: - # Truly eligible: age 4, citizen, dependent, in care - age: 4 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person4: - # Over age (>= 13): ineligible by age, in care - age: 14 - is_tax_unit_dependent: true - immigration_status: CITIZEN - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - person5: - # Ineligible immigration status, in care - age: 6 - is_tax_unit_dependent: true - immigration_status: UNDOCUMENTED - childcare_hours_per_week: 35 - al_ccsp_provider_type: CENTER - al_ccsp_quality_tier: BASE - tax_units: - tax_unit: - members: [person1, person2, person3, person4, person5] - spm_units: - spm_unit: - members: [person1, person2, person3, person4, person5] - households: - household: - members: [person1, person2, person3, person4, person5] - state_code: AL - county_str: JEFFERSON_COUNTY_AL - output: - # 150% FPL fam of 5 -> $30/wk per child - # Only person3 is eligible_child & in_care -> num_paying = 1 - # 1 * $30/wk * (52/12) = $130.00/mo - al_ccsp_copay: 130 diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml index 7b4a785a1bc..ca2b8d3f800 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/edge_cases.yaml @@ -338,7 +338,7 @@ county_str: JEFFERSON_COUNTY_AL output: # At exactly 100% FPL (ratio 1.0), the $0 band applies (next threshold is 1.0001). - al_ccsp_copay: 0 + al_ccsp_weekly_copay_per_child: 0 - name: Family at exactly 110 percent FPL pays 18 per week. period: 2024-01 @@ -370,8 +370,7 @@ county_str: JEFFERSON_COUNTY_AL output: # 110% FPL ratio = 1.10 -> 101-110 band ($18/wk). - # $18 * 4.333 = $77.99/mo - al_ccsp_copay: 77.99 + al_ccsp_weekly_copay_per_child: 18 - name: Family at 120 percent FPL pays 21 per week. period: 2024-01 @@ -402,8 +401,8 @@ state_code: AL county_str: JEFFERSON_COUNTY_AL output: - # 120% FPL -> 111-120 band ($21/wk). $21 * 4.333 = $90.99/mo - al_ccsp_copay: 90.99 + # 120% FPL -> 111-120 band ($21/wk). + al_ccsp_weekly_copay_per_child: 21 # -- Zero family income -- @@ -509,7 +508,6 @@ al_ccsp_income_eligible: true # fpl_ratio is floored at 0 -> lowest fee bracket (0) al_ccsp_weekly_copay_per_child: 0 - al_ccsp_copay: 0 # Weekly expense ($20K/52 = $384.62) capped at Birmingham CENTER # PRESCHOOL BASE max rate ($180). Subsidy = $180 - $0 copay = $180/wk. # Monthly: $180 * (52/12) = $780. diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml index c9928c6ab04..bc238c2d49e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/integration.yaml @@ -48,8 +48,8 @@ al_ccsp_eligible_child: [false, false, true] al_ccsp_income_eligible: true al_ccsp_eligible: true - # 150% FPL -> $30/wk per child -> $30 * (52/12) = $130/mo copay - al_ccsp_copay: 130 + # 150% FPL -> $30/wk per child + al_ccsp_weekly_copay_per_child: 30 # BIRMINGHAM CENTER PRESCHOOL STAR_3 full-time = $191/wk al_ccsp_maximum_weekly_rate: [0, 0, 191] # weekly charge = 10,000 / 52 = $192.31; min($192.31, $191) = $191 @@ -92,7 +92,7 @@ al_ccsp_eligible_child: [false, true] al_ccsp_eligible: true # <= 100% FPL -> $0/wk copay - al_ccsp_copay: 0 + al_ccsp_weekly_copay_per_child: 0 # MOBILE FDC INFANT_TODDLER BASE full-time = $134/wk al_ccsp_maximum_weekly_rate: [0, 134] # weekly charge = 8,000 / 52 = $153.85; min($153.85, $134) = $134 @@ -180,8 +180,7 @@ output: al_ccsp_eligible: true # FPL ratio = 47,234 / 24,860 = 1.90 -> 181-190 band -> $42/wk - # $42 * (52/12) = $182/mo - al_ccsp_copay: 182 + al_ccsp_weekly_copay_per_child: 42 # BIRMINGHAM CENTER PRESCHOOL BASE = $180/wk al_ccsp_maximum_weekly_rate: [0, 0, 180] # weekly charge = 10,000 / 52 = $192.31; min($192.31, $180) = $180 @@ -223,7 +222,7 @@ output: al_ccsp_eligible: true al_ccsp_protective_services: true - al_ccsp_copay: 0 + al_ccsp_weekly_copay_per_child: 0 # BIRMINGHAM CENTER SCHOOL_AGE BASE = $150/wk al_ccsp_maximum_weekly_rate: [0, 150] # weekly subsidy = $150; monthly = $150 * (52/12) = $650 @@ -262,7 +261,7 @@ county_str: JEFFERSON_COUNTY_AL output: al_ccsp_eligible: true - al_ccsp_copay: 0 + al_ccsp_weekly_copay_per_child: 0 # BIRMINGHAM CENTER SCHOOL_AGE BASE = $150/wk (age 5) # weekly subsidy = $150 - $0 = $150; monthly = $150 * (52/12) = $650 al_ccsp: 650 @@ -351,8 +350,8 @@ output: al_ccsp_eligible_child: [false, true, true] al_ccsp_eligible: true - # 150% FPL -> $30/wk per child * 2 children * (52/12) = $260/mo - al_ccsp_copay: 260 + # 150% FPL -> $30/wk per child (2 children both pay) + al_ccsp_weekly_copay_per_child: 30 # BIRMINGHAM CENTER PRESCHOOL BASE = $180; CENTER INFANT_TODDLER BASE = $195 al_ccsp_maximum_weekly_rate: [0, 180, 195] # weekly charge per child = 7,000 / 52 = $134.62 diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py index 27c8253a0e1..0378765dd8e 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp.py @@ -22,11 +22,9 @@ def formula(spm_unit, period): weekly_copay = spm_unit("al_ccsp_weekly_copay_per_child", period) per_child_weekly_copay_broadcast = spm_unit.project(weekly_copay) - # Per-child weekly pre-subsidy charge from annual expenses. annual_expense = person("pre_subsidy_childcare_expenses", period.this_year) weekly_expense = annual_expense / WEEKS_IN_YEAR - # Subsidy = max(0, min(charge, max_rate) - per-child copay). capped_charge = min_(weekly_expense, weekly_rate) per_child_weekly_subsidy = max_( capped_charge - per_child_weekly_copay_broadcast, 0 diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py index 5592f7361af..a990e9f8256 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py @@ -19,6 +19,5 @@ class al_ccsp_age_category(Variable): def formula(person, period, parameters): p = parameters(period).gov.states.al.dhr.ccsp.age_category - # Convert annual age (years) to months for bracket lookup. age_months = person("age", period.this_year) * MONTHS_IN_YEAR return p.months.calc(age_months) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py deleted file mode 100644 index 4b4e49cdc48..00000000000 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay.py +++ /dev/null @@ -1,24 +0,0 @@ -from policyengine_us.model_api import * - - -class al_ccsp_copay(Variable): - value_type = float - entity = SPMUnit - unit = USD - label = "Alabama CCSP monthly family copay" - definition_period = MONTH - defined_for = StateCode.AL - reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=43" - - def formula(spm_unit, period): - # Federal CCDF (45 CFR §98.45(k)) caps copays at 7% of family gross - # income. Alabama State Plan §3.1.1.a notes a state waiver request - # from this cap; we don't enforce the cap at the moment, mirroring - # the State Plan's flat sliding-fee schedule. - weekly_per_child = spm_unit("al_ccsp_weekly_copay_per_child", period) - person = spm_unit.members - is_eligible_child = person("al_ccsp_eligible_child", period) - in_care = person("childcare_hours_per_week", period.this_year) > 0 - num_paying = spm_unit.sum(is_eligible_child & in_care) - weekly_family_copay = weekly_per_child * num_paying - return weekly_family_copay * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) From cdf9ff7b2db6124f4e1286aa0fd6738b4b14933d Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 17 May 2026 23:08:55 -0400 Subject: [PATCH 13/15] Fix AL CCSP age category boundary at 36 months (was 37) PolicyEngine's age variable is annual, so an integer-input age of 3 maps to exactly 36 months. With the previous 37-month threshold, all 3-year-olds (whose actual age spans 36-47 months) were classified as INFANT_TODDLER and routed to infant/toddler provider rates instead of preschool rates. Setting the PRESCHOOL threshold at 36 months matches how Alabama operationally treats 3-year-olds in childcare subsidy. Added a 2.99-year-old test case to lock the boundary. --- .../al/dhr/ccsp/age_category/months.yaml | 14 ++++++++---- .../al/dhr/ccsp/al_ccsp_age_category.yaml | 22 ++++++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml index 6757d7e2d6f..eb77d2d2853 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/age_category/months.yaml @@ -1,7 +1,13 @@ description: Alabama uses this age in months threshold to assign care level categories under the Child Care Subsidy Program. -# 0 = INFANT_TODDLER (birth through 36 months) -# 1 = PRESCHOOL (37-59 months) -# 2 = SCHOOL_AGE (5 years through age 12, or through age 18 if disabled) +# 0 = INFANT_TODDLER (under 36 months) +# 1 = PRESCHOOL (36-59 months) +# 2 = SCHOOL_AGE (60+ months) +# The Provider Rate Chart lists 0-36 / 37-59 / 60+ months, but +# PolicyEngine's age variable is annual; integer survey ages would +# round all 3-year-olds (36-47 months actual) down to 36 months. +# Setting the PRESCHOOL threshold at 36 months maps a child reported +# as age 3 to PRESCHOOL, matching how Alabama operationally treats +# 3-year-olds. metadata: type: single_amount @@ -19,7 +25,7 @@ brackets: amount: 2022-04-11: 0 - threshold: - 2022-04-11: 37 + 2022-04-11: 36 amount: 2022-04-11: 1 - threshold: diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml index 2780808bea9..911ac1b200b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_age_category.yaml @@ -1,5 +1,7 @@ # AL CCSP age category tests (Person, MONTH, Enum) -# Bracket on age-in-months -> {INFANT_TODDLER (0-36mo), PRESCHOOL (37-59mo), SCHOOL_AGE (60mo+)}. +# Bracket on age-in-months -> {INFANT_TODDLER (0-35mo), PRESCHOOL (36-59mo), SCHOOL_AGE (60mo+)}. +# Provider Rate Chart lists 36 as the boundary; integer survey ages +# at age 3 map to exactly 36 months -> PRESCHOOL. - name: Infant age 0 is INFANT_TODDLER. period: 2024-01 @@ -27,7 +29,7 @@ output: al_ccsp_age_category: INFANT_TODDLER -- name: Child age 3 (exactly 36 months) is INFANT_TODDLER. +- name: Child age 3 (exactly 36 months) is PRESCHOOL. period: 2024-01 input: people: @@ -38,7 +40,21 @@ members: [person1] state_code: AL output: - # 36 months is below the PRESCHOOL threshold of 37 months. + # 36 months is at the PRESCHOOL threshold. + al_ccsp_age_category: PRESCHOOL + +- name: Child age 2.99 is INFANT_TODDLER. + period: 2024-01 + input: + people: + person1: + age: 2.99 + households: + household: + members: [person1] + state_code: AL + output: + # Just below 36 months (35.88 months). al_ccsp_age_category: INFANT_TODDLER - name: Child age 4 is PRESCHOOL. From 86907efa35d1cd586cc241e7d394f5fccbcc26e3 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 17 May 2026 23:28:15 -0400 Subject: [PATCH 14/15] dependent --- .../al/dhr/ccsp/al_ccsp_copay_waived.yaml | 24 +++++++++++++++++ .../al/dhr/ccsp/al_ccsp_eligible_child.yaml | 26 +++++++++++++++++++ .../al/dhr/ccsp/copay/al_ccsp_copay_waived.py | 3 ++- .../eligibility/al_ccsp_eligible_child.py | 3 ++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml index 0d48ecb28ca..a2558ddb89a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_copay_waived.yaml @@ -141,3 +141,27 @@ is_homeless: true output: al_ccsp_copay_waived: true + +- name: Case 7, disabled non-dependent under age 19 does not trigger waiver. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head: true + person2: + age: 18 + is_tax_unit_spouse: true + is_disabled: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_copay_waived: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml index 66dde49418d..108ba1ffced 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_eligible_child.yaml @@ -48,6 +48,32 @@ output: al_ccsp_eligible_child: [false, true] +- name: Child age 4 citizen non-dependent is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + is_tax_unit_head: true + person2: + age: 4 + immigration_status: CITIZEN + is_tax_unit_dependent: false + tax_units: + tax_unit: + members: [person1] + child_tax_unit: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: AL + output: + al_ccsp_eligible_child: [false, false] + - name: Child age 13 not disabled is ineligible. period: 2024-01 input: diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py index e4e4d76d5d2..36d382e2e77 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/copay/al_ccsp_copay_waived.py @@ -19,8 +19,9 @@ def formula(spm_unit, period, parameters): person = spm_unit.members is_disabled = person("is_disabled", period.this_year) age = person("age", period.this_year) + is_dependent = person("is_tax_unit_dependent", period.this_year) has_disabled_child = spm_unit.any( - is_disabled & (age < p_age.disabled_child_limit) + is_disabled & (age < p_age.disabled_child_limit) & is_dependent ) has_head_start_child = add(spm_unit, period, ["is_enrolled_in_head_start"]) > 0 protective_services = spm_unit("al_ccsp_protective_services", period) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py index c44f4337ec8..c5e53c59dfd 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_eligible_child.py @@ -21,4 +21,5 @@ def formula(person, period, parameters): immigration_eligible = person( "is_ccdf_immigration_eligible_child", period.this_year ) - return age_eligible & immigration_eligible + is_dependent = person("is_tax_unit_dependent", period.this_year) + return age_eligible & immigration_eligible & is_dependent From ad3e09eccdfeff4bb3a8ca926f90747ce3e09e70 Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 18 May 2026 00:18:17 -0400 Subject: [PATCH 15/15] minor --- .../al/dhr/ccsp/income/limit/fpl_continuing.yaml | 2 +- .../states/al/dhr/ccsp/income/limit/smi_cap.yaml | 4 ++-- .../states/al/dhr/ccsp/al_ccsp_age_category.py | 4 ++-- .../gov/states/al/dhr/ccsp/al_ccsp_enrolled.py | 6 +++--- .../eligibility/al_ccsp_activity_eligible.py | 2 +- .../eligibility/al_ccsp_protective_services.py | 16 +++++++--------- 6 files changed, 16 insertions(+), 18 deletions(-) diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_continuing.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_continuing.yaml index 412b40e5a57..37c974933f7 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_continuing.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_continuing.yaml @@ -7,7 +7,7 @@ metadata: period: year label: Alabama CCSP continuing income limit (share of federal poverty guideline) reference: - - title: Alabama CCDF State Plan 2025-2027, Section 2.5.5(c)(iii) + - title: Alabama CCDF State Plan 2025-2027, Section 2.5.2(c)(iii) href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39 - title: Alabama Child Care Fact Sheet href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml index dd67d664c2c..7dcaab5c5cb 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/smi_cap.yaml @@ -9,7 +9,7 @@ metadata: reference: - title: Alabama CCDF State Plan 2025-2027, Section 2.2.4 href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=26 - - title: Alabama CCDF State Plan 2025-2027, Section 2.5.5 Income Cutoff (85% SMI) - href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=38 + - title: Alabama CCDF State Plan 2025-2027, Section 2.5.2(c)(iv) Income Cutoff (85% SMI) + href: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39 - title: Alabama Child Care Fact Sheet (Income Cutoff 85% SMI) href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py index a990e9f8256..5cf3c15ff97 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_age_category.py @@ -2,8 +2,8 @@ class ALCCSPAgeCategory(Enum): - INFANT_TODDLER = "Infant/Toddler (0-36 months)" - PRESCHOOL = "Preschool (37-59 months)" + INFANT_TODDLER = "Infant/Toddler (under 36 months)" + PRESCHOOL = "Preschool (36-59 months)" SCHOOL_AGE = "School Age (60+ months)" diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py index 0c30956a558..55f21e6be47 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_enrolled.py @@ -6,9 +6,9 @@ class al_ccsp_enrolled(Variable): entity = SPMUnit definition_period = MONTH # Distinguishes new applicants (180% FPL initial cap) from continuing - # recipients (200% FPL continuing cap, §2.5.5). Defaults to False, so - # every household is treated as a new applicant unless this input is - # explicitly set. + # recipients (200% FPL continuing cap, §2.5.2(c)(iii)). Defaults to + # False, so every household is treated as a new applicant unless this + # input is explicitly set. label = "Whether the family is currently enrolled in Alabama CCSP" defined_for = StateCode.AL reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39" diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py index c48c8ae103a..348503b0a93 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_activity_eligible.py @@ -7,7 +7,7 @@ class al_ccsp_activity_eligible(Variable): label = "Eligible for Alabama CCSP based on parental activity requirements" definition_period = MONTH defined_for = StateCode.AL - reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=21" + reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=22" def formula(spm_unit, period, parameters): # Alabama §2.2.2(d)(ii) applies the activity test to the parent(s) diff --git a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py index 9b5f34b49af..8b2ae791ed2 100644 --- a/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/eligibility/al_ccsp_protective_services.py @@ -10,16 +10,14 @@ class al_ccsp_protective_services(Variable): reference = "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=23" def formula(spm_unit, period, parameters): - # State Plan §2.2.2(f) names five protective-services sub-populations: + # State Plan §2.2.2(f) checks four protective-services sub-populations: # (i) foster care — modeled via is_in_foster_care - # (ii) homelessness — modeled via is_homeless - # (iii) families engaged with a child welfare agency — we don't - # track child-welfare engagement at the moment - # (iv) Early Head Start Child Care Partnerships (EHS-CCP) — we - # don't track EHS-CCP enrollment at the moment - # (v) kinship care / TANF-Other Relative (also a §3.3.1(vi) copay- - # waiver trigger) — we don't track kinship care at the moment - # The three unmodeled categories under-count protective-services + # (ii) families engaged with a child welfare agency — we don't + # track child-welfare engagement at the moment + # (iii) Early Head Start Child Care Partnerships (EHS-CCP) — we + # don't track EHS-CCP enrollment at the moment + # (iv) homelessness — modeled via is_homeless + # The two unmodeled categories under-count protective-services # eligibility, which waives the income and activity tests # (§2.2.2(g)-(h)). has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0