diff --git a/changelog.d/child-care-posted-limits.added.md b/changelog.d/child-care-posted-limits.added.md new file mode 100644 index 00000000000..f72924184a0 --- /dev/null +++ b/changelog.d/child-care-posted-limits.added.md @@ -0,0 +1 @@ +Add Ohio's Child Care Choice Voucher Program and the priority groups that decide which new applicants Georgia's Childcare and Parent Services program serves. diff --git a/changelog.d/child-care-posted-limits.fixed.md b/changelog.d/child-care-posted-limits.fixed.md new file mode 100644 index 00000000000..51cad6af6cc --- /dev/null +++ b/changelog.d/child-care-posted-limits.fixed.md @@ -0,0 +1 @@ +Bring state child care income limits into line with what states post: Alabama's June 2026 limits, with families of eight or more on the chart's last row; Idaho's 130% limit for new applicants from January 2025 and before April 2023; the poverty guideline year that Idaho, Indiana, Missouri, West Virginia and Montana apply; the caps at 85% of state median income that Indiana's and West Virginia's charts print for their largest families; Maryland's initial and continuation scales on the federal fiscal 2025 median that MSDE posts; Missouri's transitional limits; Montana's 185% limit for new applicants from July 2023 and 200% graduated limit from July 2025; Nevada's dated intake and renewal limits, including 130% of the poverty guideline for new applicants from October 2018 through June 2022, and its copay schedules back to 2015; and Georgia's dated limits for new applicants since 2016. 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 23ed336402b..e618d61dfd8 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 @@ -33,7 +33,7 @@ values: - nh_child_care_subsidies # New Hampshire Child Care Scholarship Program - pa_child_care_subsidies # Pennsylvania Child Care Works - nj_child_care_subsidies # New Jersey Child Care Assistance Program - - oh_child_care_subsidies # Ohio Publicly Funded Child Care + - oh_child_care_subsidies # Ohio Publicly Funded Child Care and Child Care Choice Voucher Program - nv_child_care_subsidies # Nevada Child Care and Development Program (CCDP) - ny_child_care_subsidies # New York Child Care Assistance Program - ri_child_care_subsidies # Rhode Island Child Care Assistance Program @@ -80,7 +80,7 @@ values: - nh_child_care_subsidies # New Hampshire Child Care Scholarship Program - pa_child_care_subsidies # Pennsylvania Child Care Works - nj_child_care_subsidies # New Jersey Child Care Assistance Program - - oh_child_care_subsidies # Ohio Publicly Funded Child Care + - oh_child_care_subsidies # Ohio Publicly Funded Child Care and Child Care Choice Voucher Program - nv_child_care_subsidies # Nevada Child Care and Development Program (CCDP) - or_child_care_subsidies # Oregon Employment Related Day Care - ri_child_care_subsidies # Rhode Island Child Care Assistance Program @@ -129,7 +129,7 @@ values: - nh_child_care_subsidies # New Hampshire Child Care Scholarship Program - pa_child_care_subsidies # Pennsylvania Child Care Works - nj_child_care_subsidies # New Jersey Child Care Assistance Program - - oh_child_care_subsidies # Ohio Publicly Funded Child Care + - oh_child_care_subsidies # Ohio Publicly Funded Child Care and Child Care Choice Voucher Program - nv_child_care_subsidies # Nevada Child Care and Development Program (CCDP) - or_child_care_subsidies # Oregon Employment Related Day Care - ri_child_care_subsidies # Rhode Island Child Care Assistance Program 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 37c974933f7..8312f3fb52a 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 @@ -1,6 +1,8 @@ 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 + # The June 2026 continuing scale stops at the 161-170% column. + 2026-06-01: 1.7 metadata: unit: /1 @@ -9,5 +11,9 @@ metadata: reference: - 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 + - title: Alabama Child Care Fact Sheet, January 1, 2024 + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf#page=1 + - title: Alabama Child Care Fact Sheet, January 1, 2026 (Continuing Eligibility Monthly Income Scale, top column 191-200% FPL) + href: https://dhr.alabama.gov/wp-content/uploads/2025/12/CHILD-CARE-FACT-SHEET-Jan2026.pdf#page=1 + - title: Alabama Child Care Fact Sheet, June 1, 2026 (Continuing Eligibility Monthly Income Scale, top column 161-170% FPL) + href: https://dhr.alabama.gov/wp-content/uploads/2026/06/CHILD-CARE-FACT-SHEET-Jun2026-1.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_initial.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_initial.yaml index 6036f37af07..4607f29d834 100644 --- a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_initial.yaml +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_initial.yaml @@ -1,6 +1,8 @@ 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 + # The June 2026 scale stops at the 141-150% column and tells new applicants to enter under it. + 2026-06-01: 1.5 metadata: unit: /1 @@ -9,5 +11,9 @@ 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 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 + - title: Alabama Child Care Fact Sheet, January 1, 2024 (Initial Eligibility Monthly Income Scale) + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf#page=1 + - title: Alabama Child Care Fact Sheet, January 1, 2026 (Initial Eligibility Monthly Income Scale, top column 171-180% FPL) + href: https://dhr.alabama.gov/wp-content/uploads/2025/12/CHILD-CARE-FACT-SHEET-Jan2026.pdf#page=1 + - title: Alabama Child Care Fact Sheet, June 1, 2026 (Initial Eligibility Monthly Income Scale, top column 141-150% FPL) + href: https://dhr.alabama.gov/wp-content/uploads/2026/06/CHILD-CARE-FACT-SHEET-Jun2026-1.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/max_family_size.yaml b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/max_family_size.yaml new file mode 100644 index 00000000000..d54b016f1c8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/al/dhr/ccsp/income/max_family_size.yaml @@ -0,0 +1,15 @@ +description: Alabama applies the income scale row for this family size to larger families under the Child Care Subsidy Program. +# Each fact sheet's income scales and fee charts end with one row for families of +# eight or more. +values: + 2024-01-01: 8 + +metadata: + unit: person + period: year + label: Alabama CCSP largest family size on the income scales + reference: + - title: Alabama Child Care Fact Sheet, January 1, 2024 (family size row ">=8") + href: https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf#page=1 + - title: Alabama Child Care Fact Sheet, June 1, 2026 (family size row ">=8") + href: https://dhr.alabama.gov/wp-content/uploads/2026/06/CHILD-CARE-FACT-SHEET-Jun2026-1.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_rate/initial_eligibility.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_rate/initial_eligibility.yaml index d0ed56c1b32..6d7f294a791 100644 --- a/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_rate/initial_eligibility.yaml +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_rate/initial_eligibility.yaml @@ -1,5 +1,18 @@ description: Georgia limits the Childcare and Parent Services program to new applicants with income at or below this share of state median income. + +# DECAL's letters date every change. An emergency waiver raised the limit to 85% +# from November 1, 2021, through December 15, 2022. The 2024 spending plan's +# "November 2021 - September 2024" and the governor's "through October 1, 2024" +# describe the funding window, and DECAL's December 2022 letter and emergency +# memorandum end the income waiver earlier. DECAL applies each limit by application +# received date. The model carries no application date, so it moves every new +# applicant at the first month that starts on or after the effective date. values: + 2016-10-01: 0.5 + 2021-11-01: 0.85 + 2022-12-16: 0.5 + 2024-09-01: 0.3 + 2025-10-06: 0.4 2026-03-02: 0.5 metadata: @@ -9,5 +22,19 @@ metadata: reference: - title: Georgia CAPS Policy Manual, Section 8.3 (Gross Income) href: https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=49 - - title: Georgia CAPS Appendix A - Maximum Income Limits by Family Size (effective March 2, 2026) - href: https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf + - title: Georgia CAPS Appendix A, Maximum Income Limits (effective October 5, 2026) + href: https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Families (October 21, 2021), 50% to 85% from November 1, 2021 + href: https://caps.decal.ga.gov/assets/downloads/CAPS_Letter_from_Elisabetta_Kasfir_Families_10-21-21.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Families (December 19, 2022), back to 50% from December 16, 2022 + href: https://caps.decal.ga.gov/assets/downloads/CAPS_Letter_to_Parents_Change_in_Income_Limits_12.19.2022.pdf#page=1 + - title: Georgia DECAL, CAPS Emergency Policy Memorandum, income limit waiver dates + href: https://caps.decal.ga.gov/assets/downloads/CAPS_Emergency_Policy_Memorandum.pdf#page=3 + - title: Georgia DECAL, Letter to CAPS Families (September 3, 2024), 50% to 30% from September 1, 2024 + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_from_Elisabetta_Kasfir_Families_09.03.2024.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Families (October 6, 2025), 30% to 40% from October 6, 2025 + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_to_Families_Policy_Revisions_10.06.25.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Families (March 2, 2026), 40% to 50% from March 2, 2026 + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_to_Families_Policy_Revisions_03.02.26.pdf#page=1 + - title: Georgia CCDF Plan FFY 2025-2027, Section 2.2.4, 40% of state median income effective October 6, 2025 + href: https://www.decal.ga.gov/documents/attachments/CCDFStatePlan25-27.pdf#page=22 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_rate/ongoing_eligibility.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_rate/ongoing_eligibility.yaml index 2231f1669c9..3b46f1731cc 100644 --- a/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_rate/ongoing_eligibility.yaml +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_rate/ongoing_eligibility.yaml @@ -1,6 +1,11 @@ description: Georgia limits the Childcare and Parent Services program to enrolled families with income at or below this share of state median income. + +# DECAL's June 2018 letter raises the limit at annual redetermination from 50% to +# 85% on March 26, 2018. Urban Institute's 2016 tables print 85% within the +# eligibility period and 50% at redetermination before that. The model carries one +# limit for enrolled families, so it reads 85% at every date. values: - 2026-03-02: 0.85 + 2016-10-01: 0.85 metadata: unit: /1 @@ -9,5 +14,9 @@ metadata: reference: - title: Georgia CAPS Policy Manual, Section 8.3 (Gross Income) href: https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=49 - - title: Georgia CAPS Appendix A - Maximum Income Limits by Family Size (effective March 2, 2026) - href: https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf + - title: Georgia CAPS Appendix A, Maximum Income Limits (effective October 5, 2026) + href: https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Child Care Providers (June 18, 2018), 85% at redetermination from March 26, 2018 + href: https://caps.decal.ga.gov/assets/downloads/CAPS_Letter_from_Elisabetta_Kasfir_6-18-2018.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Families (March 2, 2026), ongoing limit stays at 85% + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_to_Families_Policy_Revisions_03.02.26.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_year_lag.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_year_lag.yaml new file mode 100644 index 00000000000..96b3949d2fd --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/income/smi_year_lag.yaml @@ -0,0 +1,40 @@ +description: Georgia reads the state median income table from this many federal fiscal years before the one in effect for the month under the Childcare and Parent Services program. + +# Each Appendix A chart prints the date its state median income data took effect: +# - The charts from October 2020 through October 2023 take up each federal table on +# its October 1 start. +# - The September 1, 2024 chart takes up the fiscal year 2025 table a month early, +# at 30% ($26,686 a year for three), so September 2024 reads one year ahead. +# - The CCDF plan prints the 40% limits that took effect October 6, 2025 on the +# fiscal year 2026 table ($3,101 a month for three). The chart effective October 5, +# 2026 takes up the fiscal year 2027 table. The first days of each October keep the +# prior table. +# The model applies each date at the first month that starts on or after it, so the +# fiscal year 2026 and 2027 tables take effect in November 2025 and November 2026. No +# chart before October 2020 survives, so earlier months take each table on October 1. +values: + 2015-10-01: 0 + 2024-09-01: -1 + 2024-10-01: 0 + 2025-10-01: 1 + 2025-10-06: 0 + 2026-10-01: 1 + 2026-10-05: 0 + +metadata: + unit: year + period: month + label: Georgia CAPS state median income table year lag + reference: + - title: Georgia CAPS Appendix A, Maximum Income Limits (effective October 1, 2020), state median income effective October 1, 2020 + href: https://web.archive.org/web/20201124060600id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia CAPS Appendix A, Maximum Income Limits (archived December 8, 2023), state median income effective October 1, 2023 + href: https://web.archive.org/web/20231208060145id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia CAPS Appendix A, Maximum Income Limits (archived March 1, 2025), state median income effective September 1, 2024 + href: https://web.archive.org/web/20250301224420id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia CCDF Plan FFY 2025-2027, Section 2.2.4, 40% of state median income effective October 6, 2025 + href: https://www.decal.ga.gov/documents/attachments/CCDFStatePlan25-27.pdf#page=22 + - title: Georgia DECAL, Letter to CAPS Families (October 6, 2025), 30% to 40% from October 6, 2025 + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_to_Families_Policy_Revisions_10.06.25.pdf#page=1 + - title: Georgia CAPS Appendix A, Maximum Income Limits (effective October 5, 2026), state median income effective October 5, 2026 + href: https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/domestic_violence_in_effect.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/domestic_violence_in_effect.yaml new file mode 100644 index 00000000000..67b080de8ee --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/domestic_violence_in_effect.yaml @@ -0,0 +1,15 @@ +description: Georgia uses this indicator to determine whether families experiencing domestic violence form a priority group under the Childcare and Parent Services program. + +# The funding restriction started August 1, 2016 with seven groups. The funding Q&A +# adds the homeless, domestic violence and very low income groups on October 1, 2016. +values: + 2015-01-01: false + 2016-10-01: true + +metadata: + unit: bool + period: month + label: Georgia CAPS domestic violence priority group in effect + reference: + - title: Georgia DECAL, Questions about CAPS Funding Restrictions (2016), three groups added October 1, 2016 + href: https://www.decal.ga.gov/documents/attachments/fundingrestrictionsqa.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/homeless_in_effect.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/homeless_in_effect.yaml new file mode 100644 index 00000000000..b3aaa4bc3ee --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/homeless_in_effect.yaml @@ -0,0 +1,15 @@ +description: Georgia uses this indicator to determine whether families without fixed, regular and adequate housing form a priority group under the Childcare and Parent Services program. + +# The funding restriction started August 1, 2016 with seven groups. The funding Q&A +# adds the homeless, domestic violence and very low income groups on October 1, 2016. +values: + 2015-01-01: false + 2016-10-01: true + +metadata: + unit: bool + period: month + label: Georgia CAPS homeless priority group in effect + reference: + - title: Georgia DECAL, Questions about CAPS Funding Restrictions (2016), three groups added October 1, 2016 + href: https://www.decal.ga.gov/documents/attachments/fundingrestrictionsqa.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/in_effect.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/in_effect.yaml new file mode 100644 index 00000000000..d22e90c3a44 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/in_effect.yaml @@ -0,0 +1,20 @@ +description: Georgia uses this indicator to determine whether the Childcare and Parent Services program requires new applicants to belong to a priority group. + +# DECAL restricted funding to priority groups for new applicants from August 1, +# 2016. The funding Q&A adds the homeless, domestic violence and very low income +# groups on October 1, 2016, and each of those groups has its own indicator. +values: + 2015-01-01: false + 2016-08-01: true + +metadata: + unit: bool + period: month + label: Georgia CAPS priority group requirement in effect + reference: + - title: Georgia DECAL, Questions about CAPS Funding Restrictions (2016) + href: https://www.decal.ga.gov/documents/attachments/fundingrestrictionsqa.pdf#page=1 + - title: Georgia CAPS Policy CAPS/00-7, Section 7.3.1 (revised October 5, 2026) + href: https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=1 + - title: Georgia CCDF Plan FFY 2025-2027, Section 2.2.7 + href: https://www.decal.ga.gov/documents/attachments/CCDFStatePlan25-27.pdf#page=25 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/minor_parent_age.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/minor_parent_age.yaml new file mode 100644 index 00000000000..ba4ca2ee2a3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/minor_parent_age.yaml @@ -0,0 +1,16 @@ +description: Georgia limits the minor parent priority group to parents at or below this age under the Childcare and Parent Services program. + +# The 2016 funding Q&A names minor parents in school without an age. The revision +# history of CAPS/00-7 records no change to the age. +values: + 2016-08-01: 20 + +metadata: + unit: year + period: year + label: Georgia CAPS minor parent priority group age limit + reference: + - title: Georgia CAPS Policy CAPS/00-7, Section 7.14 (revised October 5, 2026) + href: https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=8 + - title: Georgia CCDF Plan FFY 2025-2027, Section 2.3.2 + href: https://www.decal.ga.gov/documents/attachments/CCDFStatePlan25-27.pdf#page=34 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/pre_k_redetermination_in_effect.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/pre_k_redetermination_in_effect.yaml new file mode 100644 index 00000000000..2eee2643fbd --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/pre_k_redetermination_in_effect.yaml @@ -0,0 +1,20 @@ +description: Georgia uses this indicator to determine whether families of children enrolled in Georgia's Pre-K Program at initial application or the previous eligibility determination must belong to a priority group at redetermination under the Childcare and Parent Services program. + +# DECAL's July 1, 2024 letter adds the requirement to CAPS/00-7 and CAPS/00-14, and +# its October 6, 2025 letter removes it. The model applies each date at the first +# month that starts on or after it, so the requirement covers July 2024 through +# October 2025. +values: + 2015-01-01: false + 2024-07-01: true + 2025-10-06: false + +metadata: + unit: bool + period: month + label: Georgia CAPS Pre-K redetermination requirement in effect + reference: + - title: Georgia DECAL, Letter to CAPS Families (July 1, 2024), requirement added July 1, 2024 + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_from_Elisabetta_Kasfir_Families_07.01.2024.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Families (October 6, 2025), requirement removed October 6, 2025 + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_to_Families_Policy_Revisions_10.06.25.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/student_parent_in_effect.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/student_parent_in_effect.yaml new file mode 100644 index 00000000000..ff698200374 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/student_parent_in_effect.yaml @@ -0,0 +1,12 @@ +description: Georgia uses this indicator to determine whether student parents form a priority group under the Childcare and Parent Services program. +values: + 2015-01-01: false + 2022-05-01: true + +metadata: + unit: bool + period: month + label: Georgia CAPS student parent priority group in effect + reference: + - title: "Georgia CAPS Policy CAPS/00-7, Section 7.16 (revised October 5, 2026) and revision history (May 1, 2022) #page 9-10" + href: https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=9 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/very_low_income_fpg_rate.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/very_low_income_fpg_rate.yaml new file mode 100644 index 00000000000..016132940cd --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/very_low_income_fpg_rate.yaml @@ -0,0 +1,39 @@ +description: Georgia limits the very low income priority group to families with income at or below this share of the federal poverty guideline under the Childcare and Parent Services program. + +# DECAL's letters date every change. DECAL applies each rate by application received +# date. The model carries no application date, so it moves every new applicant at +# the first month that starts on or after the effective date. The 50% back to +# October 2016 rests on the June 2018 letter's "previously". +values: + 2016-10-01: 0.5 + 2018-05-30: 1 + 2019-07-01: 0.5 + 2021-11-01: 1.5 + 2022-12-16: 0.5 + 2024-07-01: 0.1 + 2025-10-06: 0.3 + 2026-03-02: 0.5 + +metadata: + unit: /1 + period: year + label: Georgia CAPS very low income priority group poverty guideline rate + reference: + - title: Georgia CAPS Policy CAPS/00-7, Section 7.12 (revised October 5, 2026) + href: https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=7 + - title: Georgia CAPS Appendix A, Maximum Income Limits (effective October 5, 2026) + href: https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Child Care Providers (June 18, 2018), 50% to 100% from May 30, 2018 + href: https://caps.decal.ga.gov/assets/downloads/CAPS_Letter_from_Elisabetta_Kasfir_6-18-2018.pdf#page=1 + - title: Georgia DECAL, CAPS Policy Webinar (July 10, 2019), slide 4, back to 50% for applications from July 1, 2019 + href: http://caps.decal.ga.gov/Assets/downloads/CAPS_Policy_Webinar_for_Child_Care_Providers_7-10-19.pdf#page=4 + - title: Georgia DECAL, Letter to CAPS Families (October 21, 2021), 50% to 150% from November 1, 2021 + href: https://caps.decal.ga.gov/assets/downloads/CAPS_Letter_from_Elisabetta_Kasfir_Families_10-21-21.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Families (December 19, 2022), back to 50% from December 16, 2022 + href: https://caps.decal.ga.gov/assets/downloads/CAPS_Letter_to_Parents_Change_in_Income_Limits_12.19.2022.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Families (July 1, 2024), 50% to 10% from July 1, 2024 + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_from_Elisabetta_Kasfir_Families_07.01.2024.pdf#page=2 + - title: Georgia DECAL, Letter to CAPS Families (October 6, 2025), 10% to 30% from October 6, 2025 + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_to_Families_Policy_Revisions_10.06.25.pdf#page=1 + - title: Georgia DECAL, Letter to CAPS Families (March 2, 2026), 30% to 50% from March 2, 2026 + href: https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_to_Families_Policy_Revisions_03.02.26.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/very_low_income_fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/very_low_income_fpg_year_lag.yaml new file mode 100644 index 00000000000..0bfaba6d626 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/very_low_income_fpg_year_lag.yaml @@ -0,0 +1,43 @@ +description: Georgia uses the federal poverty guideline from this many years before the current date for the very low income priority group under the Childcare and Parent Services program. + +# Each Appendix A chart prints the date CAPS took up that year's guideline: March 1 +# in 2020 through 2025 and March 2 in 2026. The prior year's guideline holds until +# then. The model applies each date at the first month that starts on or after it, +# so the 2026 guideline takes effect in April 2026. No chart before 2020 survives, so +# earlier years read the current year's guideline. +values: + 2015-01-01: 0 + 2020-01-01: 1 + 2020-03-01: 0 + 2021-01-01: 1 + 2021-03-01: 0 + 2022-01-01: 1 + 2022-03-01: 0 + 2023-01-01: 1 + 2023-03-01: 0 + 2024-01-01: 1 + 2024-03-01: 0 + 2025-01-01: 1 + 2025-03-01: 0 + 2026-01-01: 1 + 2026-03-02: 0 + +metadata: + unit: year + period: month + label: Georgia CAPS very low income poverty guideline year lag + reference: + - title: Georgia CAPS Appendix A, Maximum Income Limits (effective October 1, 2020), guidelines effective for CAPS March 1, 2020 + href: https://web.archive.org/web/20201124060600id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia CAPS Appendix A, Maximum Income Limits (effective October 1, 2021), guidelines effective for CAPS March 1, 2021 + href: https://web.archive.org/web/20211026013823id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia CAPS Appendix A, Maximum Income Limits (archived March 1, 2022), guidelines effective for CAPS March 1, 2022 + href: https://web.archive.org/web/20220301180356id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia CAPS Appendix A, Maximum Income Limits (archived March 4, 2023), guidelines effective for CAPS March 1, 2023 + href: https://web.archive.org/web/20230304133123id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia CAPS Appendix A, Maximum Income Limits (archived May 20, 2024), guidelines effective for CAPS March 1, 2024 + href: https://web.archive.org/web/20240520214500id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia CAPS Appendix A, Maximum Income Limits (archived March 8, 2025), guidelines effective for CAPS March 1, 2025 + href: https://web.archive.org/web/20250308021446id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 + - title: Georgia CAPS Appendix A, Maximum Income Limits (archived March 8, 2026), guidelines effective for CAPS March 2, 2026 + href: https://web.archive.org/web/20260308171215id_/https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/very_low_income_in_effect.yaml b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/very_low_income_in_effect.yaml new file mode 100644 index 00000000000..ffab1319889 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ga/decal/caps/priority_groups/very_low_income_in_effect.yaml @@ -0,0 +1,15 @@ +description: Georgia uses this indicator to determine whether families with very low income form a priority group under the Childcare and Parent Services program. + +# The funding restriction started August 1, 2016 with seven groups. The funding Q&A +# adds the homeless, domestic violence and very low income groups on October 1, 2016. +values: + 2015-01-01: false + 2016-10-01: true + +metadata: + unit: bool + period: month + label: Georgia CAPS very low income priority group in effect + reference: + - title: Georgia DECAL, Questions about CAPS Funding Restrictions (2016), three groups added October 1, 2016 + href: https://www.decal.ga.gov/documents/attachments/fundingrestrictionsqa.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/id/dhw/iccp/income/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/id/dhw/iccp/income/fpg_year_lag.yaml new file mode 100644 index 00000000000..3e0dc8562f2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/iccp/income/fpg_year_lag.yaml @@ -0,0 +1,22 @@ +description: Idaho uses the federal poverty guideline from this many years before the current date to set initial income limits under the Idaho Child Care Program. +# The department reopened applications on January 13, 2025 at 130% of the 2024 +# guideline ($33,566 a year for three). Its table effective October 2025 uses the +# 2025 guideline ($2,888 a month for three), and the page still showed that table +# on November 5, 2026, so a lag of one holds it through 2026. A new table adds a +# date here. No source dates the guideline year before 2025, so the list keeps +# the current year until then. +values: + 2015-01-01: 0 + 2025-01-13: 1 + 2025-10-01: 0 + 2026-01-01: 1 + +metadata: + unit: year + period: year + label: Idaho Child Care Program poverty guideline year lag + reference: + - title: Idaho Department of Health and Welfare, Apply for Child Care (limits effective October 2025; page last updated September 30, 2025) + href: https://healthandwelfare.idaho.gov/services-programs/children-families/apply-child-care + - title: Idaho Department of Health and Welfare, DHW will resume applications for the Idaho Child Care Program in January (November 14, 2024) + href: https://healthandwelfare.idaho.gov/news/dhw-will-resume-applications-idaho-child-care-program-january diff --git a/policyengine_us/parameters/gov/states/id/dhw/iccp/income/fpl_rate/initial_eligibility.yaml b/policyengine_us/parameters/gov/states/id/dhw/iccp/income/fpl_rate/initial_eligibility.yaml index 486e3851b79..005e86d73c7 100644 --- a/policyengine_us/parameters/gov/states/id/dhw/iccp/income/fpl_rate/initial_eligibility.yaml +++ b/policyengine_us/parameters/gov/states/id/dhw/iccp/income/fpl_rate/initial_eligibility.yaml @@ -1,13 +1,33 @@ description: Idaho limits initial income to this share of the federal poverty guidelines under the Idaho Child Care Program. +# IDAPA 16.06.12.070 set the limit at 130% from at least 2013 and raised it to 175% +# on April 6, 2023. Until March 2, 2017, the rule required income below 130%; the +# model tests at or below the limit in every year. +# The department moved new applicants back to 130% when it reopened applications on +# January 13, 2025, to keep the program within its appropriation, and posts its +# limits at that rate. IDAPA 16.06.12.070.01 still prints 175%, and IDAPA +# 16.06.12.705 lets the department reduce child care benefits when it projects a +# funding shortfall. The model follows the department's 130% from that date. values: + 2015-01-01: 1.3 2023-04-06: 1.75 + 2025-01-13: 1.3 metadata: unit: /1 period: year label: Idaho Child Care Program initial income limit reference: - - title: IDAPA 16.06.12.070.01, Income at Application + - title: IDAPA 16.06.12.070, Income Limits (2014 compilation, effective April 4, 2013) + href: https://adminrules.idaho.gov/rules/2014/16/0612.pdf#page=7 + - title: IDAPA 16.06.12.070.01, Income at Application (2019 archive, effective March 2, 2017) + href: https://adminrules.idaho.gov/rules/2019%20Archive%20C2/16/160612.pdf#page=8 + - title: IDAPA 16.06.12.070.01, Income at Application (2022 archive, effective March 17, 2022) + href: https://adminrules.idaho.gov/rules/2022%20Archive/16/160612.pdf#page=7 + - title: "IDAPA 16.06.12.070.01, Income at Application (current, effective April 6, 2023), and 16.06.12.705, Funding Restrictions #page 7,18" href: https://adminrules.idaho.gov/rules/current/16/160612.pdf#page=7 + - title: Idaho Department of Health and Welfare, DHW will resume applications for the Idaho Child Care Program in January (November 14, 2024) + href: https://healthandwelfare.idaho.gov/news/dhw-will-resume-applications-idaho-child-care-program-january + - title: Idaho Department of Health and Welfare, Apply for Child Care (limits effective October 2025; page last updated September 30, 2025) + href: https://healthandwelfare.idaho.gov/services-programs/children-families/apply-child-care - title: Idaho Department of Health and Welfare, Idaho Child Care Program href: https://healthandwelfare.idaho.gov/services-programs/children-families-older-adults/idaho-child-care-program diff --git a/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/fpg_year_lag.yaml new file mode 100644 index 00000000000..a951aee1089 --- /dev/null +++ b/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/fpg_year_lag.yaml @@ -0,0 +1,42 @@ +description: Indiana uses the federal poverty guideline from this many years before the current date under the Child Care and Development Fund program. +# Indiana moves to a new year's guideline when FSSA posts that year's income eligibility +# and fee schedule, and the old guideline holds until then. Each schedule prints its +# effective date: +# - March 12, 2023: 127% of the 2023 guideline ($2,631 a month for three). +# - March 31, 2024: 150% of the 2024 guideline ($3,228 for three). +# - March 23, 2025: 150% of the 2025 guideline ($3,331 for three). +# - April 5, 2026: 135% of the 2026 guideline ($3,074 for three). +# Before March 12, 2023 the model reads the 2022 guideline, and before 2023 the current +# year's, since no earlier dated schedule is available. From 2027 a lag of 1 extrapolates: +# the model keeps the prior year's guideline because no 2027 schedule exists yet. +# Each schedule caps families at 85% of the state median income table that starts the +# October before its guideline year, so in_ccdf_smi reads that table through this lag. +values: + 2015-01-01: 0 + 2023-01-01: 1 + 2023-03-12: 0 + 2024-01-01: 1 + 2024-03-31: 0 + 2025-01-01: 1 + 2025-03-23: 0 + 2026-01-01: 1 + 2026-04-05: 0 + 2027-01-01: 1 + +metadata: + unit: year + period: year + label: Indiana CCDF poverty guideline year lag + reference: + - title: Indiana CCDF State Plan FFY 2025-2027, Amendment 2, Section 2.2.4 (limits effective March 31, 2024) + href: https://www.in.gov/dA/6307709ae5/ACF-118CCDFFFY2025-2027IndianaAmendment.pdf?language_id=1 + - title: Indiana FSSA, Child Care Income Eligibility Determination and Fee Schedule 2023 (effective March 12, 2023), archived May 1, 2023 + href: https://web.archive.org/web/20230501122705/https://www.in.gov/fssa/carefinder/files/CCDFSlidingFeeSchedule_withCopays.pdf#page=1 + - title: Indiana FSSA, Child Care Income Eligibility Determination and Fee Schedule 2024 (effective March 31, 2024), archived April 13, 2024 + href: https://web.archive.org/web/20240413093550/https://www.in.gov/fssa/carefinder/files/CCDFSlidingFeeSchedule_withCopays.pdf#page=1 + - title: Indiana FSSA, Child Care Income Eligibility Determination and Fee Schedule 2025 (effective March 23, 2025), archived April 3, 2025 + href: https://web.archive.org/web/20250403065234/https://www.in.gov/fssa/carefinder/files/CCDFSlidingFeeSchedule_withCopays.pdf#page=1 + - title: Indiana FSSA, Income to Get on CCDF (effective April 5, 2026) + href: https://www.in.gov/dA/3271c7180e/Income-Get-on-CCDF.pdf + - title: Indiana FSSA, CCDF Sliding Fee Schedule with copays, 2026 (effective April 5, 2026) + href: https://www.in.gov/dA/7fc32972de/CCDFSlidingFeeSchedule_withCopays_2026.pdf diff --git a/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/get_on_fpg_rate.yaml b/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/get_on_fpg_rate.yaml index 41ae02fa544..9b0467c5406 100644 --- a/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/get_on_fpg_rate.yaml +++ b/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/get_on_fpg_rate.yaml @@ -17,5 +17,7 @@ metadata: href: https://www.in.gov/fssa/carefinder/files/CCDF-Policy-Manual.pdf#page=5 - title: Income to Get on CCDF href: https://www.in.gov/fssa/carefinder/files/Income-Get-on-CCDF.pdf + - title: Indiana CCDF State Plan FFY 2025-2027, Amendment 2, Section 2.2.4 (150% limits effective March 31, 2024) + href: https://www.in.gov/dA/6307709ae5/ACF-118CCDFFFY2025-2027IndianaAmendment.pdf?language_id=1 - title: OECOSL bulletin, New CCDF Reimbursement Rates and Expanded Income Eligibility (127% to 150% FPL eff. Aug 1, 2023) href: https://www.in.gov/fssa/carefinder/system-updates-2023 diff --git a/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/stay_on_smi_rate.yaml b/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/stay_on_smi_rate.yaml index e3c68579087..7c63613a485 100644 --- a/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/stay_on_smi_rate.yaml +++ b/policyengine_us/parameters/gov/states/in/fssa/ccdf/income/stay_on_smi_rate.yaml @@ -1,12 +1,20 @@ -description: Indiana limits continuing eligibility to families with income at or below this percentage of the state median income under the Child Care and Development Fund program. +description: Indiana limits income to this share of the state median income under the Child Care and Development Fund program. +# Enrolled families stay eligible up to this share. New applicants face the lower of +# this share and the get-on share of the guideline; on the April 5, 2026 schedule this +# share binds from 19 people ($13,028 a month). Each schedule rounds this limit up to +# the next dollar. values: 2023-08-01: 0.85 metadata: unit: /1 period: year - label: Indiana CCDF continuing income limit rate + label: Indiana CCDF state median income limit rate reference: + - title: "Indiana FSSA, CCDF Sliding Fee Schedule with copays, 2026 (effective April 5, 2026), Max SMI column #page 1-2" + href: https://www.in.gov/dA/7fc32972de/CCDFSlidingFeeSchedule_withCopays_2026.pdf#page=1 + - title: Indiana CCDF State Plan FFY 2025-2027, Amendment 2, Section 2.2.4(a)(ii) + href: https://www.in.gov/dA/6307709ae5/ACF-118CCDFFFY2025-2027IndianaAmendment.pdf?language_id=1#page=22 - title: Indiana CCDF Policy Manual, Change in Physical Custody Policy (income below 85% SMI) href: https://www.in.gov/fssa/carefinder/files/CCDF-Policy-Manual.pdf#page=10 - title: Income to Stay On CCDF diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/continuation_smi_freeze_in_effect.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/continuation_smi_freeze_in_effect.yaml new file mode 100644 index 00000000000..42809ea6f04 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/continuation_smi_freeze_in_effect.yaml @@ -0,0 +1,17 @@ +description: Maryland uses this indicator to determine whether the State Median Income base year is frozen for the Child Care Scholarship continuation income scale. +# The model gives continuing families the initial scale's frozen base years until MSDE's +# Continuation Income Scale took effect on April 22, 2024: 85% of the federal fiscal 2025 +# median, $106,563 a year for three. MSDE's page still posts that scale in October 2026. +values: + 2016-01-01: false + 2018-07-01: true + +metadata: + unit: bool + period: year + label: Maryland CCS continuation SMI freeze in effect + reference: + - title: MSDE Child Care Scholarship Program Briefing (Feb 4, 2026), slide 21 - fiscal-year freeze schedule + href: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf#page=21 + - title: MSDE, Child Care Scholarship Program, Continuation Income Scale effective April 22, 2024 (captured October 9, 2026) + href: https://web.archive.org/web/20261009215322/https://earlychildhood.marylandpublicschools.org/child-care-providers/child-care-scholarship-program diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/continuation_smi_frozen_year.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/continuation_smi_frozen_year.yaml new file mode 100644 index 00000000000..748f36e1036 --- /dev/null +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/continuation_smi_frozen_year.yaml @@ -0,0 +1,17 @@ +description: Maryland pins the State Median Income (SMI) base year used for the Child Care Scholarship continuation income scale when continuation_smi_freeze_in_effect is true. Maryland's fiscal year starts July 1. +values: + 2018-07-01: 2018 + 2022-07-01: 2021 + # The posted Continuation Income Scale effective April 22, 2024 uses the median HHS + # published for federal fiscal 2025, which starts October 1, 2024. + 2024-04-22: 2024 + +metadata: + unit: year + period: year + label: Maryland CCS continuation SMI frozen year + reference: + - title: MSDE Child Care Scholarship Program Briefing (Feb 4, 2026), slide 21 - fiscal-year base years + href: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf#page=21 + - title: MSDE, Child Care Scholarship Program, Continuation Income Scale effective April 22, 2024 (captured October 9, 2026) + href: https://web.archive.org/web/20261009215322/https://earlychildhood.marylandpublicschools.org/child-care-providers/child-care-scholarship-program diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_freeze_in_effect.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_freeze_in_effect.yaml index a8cbe7a2fe8..ba8a6edb55d 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_freeze_in_effect.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_freeze_in_effect.yaml @@ -1,8 +1,13 @@ -description: Maryland uses this indicator to determine whether the State Median Income base year is frozen for Child Care Scholarship income eligibility. +description: Maryland uses this indicator to determine whether the State Median Income base year is frozen for the Child Care Scholarship initial income scale. +# MSDE's scholarship page, captured October 9, 2026, still posts the Initial Income Scale +# effective December 15, 2024 as the table for new applications: 75% of the federal +# fiscal 2025 median, $94,026 a year for three. The model holds that median from October +# 1, 2025, when HHS's fiscal 2026 estimates took effect; a new posted table adds a date here. values: 2016-01-01: false 2018-07-01: true 2024-12-15: false + 2025-10-01: true metadata: unit: bool @@ -13,3 +18,5 @@ metadata: href: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf#page=21 - title: MSDE Jan 23, 2025 OCC Info Session - Dec 15, 2024 SMI unfreeze href: https://earlychildhood.marylandpublicschools.org/system/files/filedepot/3/january_2025_occ_info_session.pdf#page=7 + - title: MSDE, Child Care Scholarship Program, Initial Income Scale effective December 15, 2024 (captured October 9, 2026) + href: https://web.archive.org/web/20261009215322/https://earlychildhood.marylandpublicschools.org/child-care-providers/child-care-scholarship-program diff --git a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_frozen_year.yaml b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_frozen_year.yaml index c3c1ab7017a..f6dc1f4c629 100644 --- a/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_frozen_year.yaml +++ b/policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_frozen_year.yaml @@ -1,7 +1,10 @@ -description: Maryland pins the State Median Income (SMI) base year used for Child Care Scholarship income eligibility when smi_freeze_in_effect is true. Maryland's fiscal year starts July 1. +description: Maryland pins the State Median Income (SMI) base year used for the Child Care Scholarship initial income scale when smi_freeze_in_effect is true. Maryland's fiscal year starts July 1. values: 2018-07-01: 2018 2022-07-01: 2021 + # The posted Initial Income Scale effective December 15, 2024 uses the median HHS + # published for federal fiscal 2025, which starts October 1, 2024. + 2025-10-01: 2024 metadata: unit: year @@ -10,3 +13,5 @@ metadata: reference: - title: MSDE Child Care Scholarship Program Briefing (Feb 4, 2026), slide 21 - fiscal-year base years href: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf#page=21 + - title: MSDE, Child Care Scholarship Program, Initial Income Scale effective December 15, 2024 (captured October 9, 2026) + href: https://web.archive.org/web/20261009215322/https://earlychildhood.marylandpublicschools.org/child-care-providers/child-care-scholarship-program diff --git a/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpg_year_lag.yaml new file mode 100644 index 00000000000..cf0524c4d3d --- /dev/null +++ b/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpg_year_lag.yaml @@ -0,0 +1,17 @@ +description: Missouri uses the federal poverty guideline from this many years before the current date under the Child Care Subsidy program. +# DESE's chart headed November 2025 and updated July 1, 2026 prints 150% of the 2025 +# guideline ($3,331 a month for three). A lag of one holds the 2025 guideline through +# 2026; a new chart adds a date here. From 2027 the lag of one extrapolates, since no +# chart prints a 2027 limit. No source dates the guideline year before the October +# 2025 chart, so the list keeps the current year until then. +values: + 2015-01-01: 0 + 2026-01-01: 1 + +metadata: + unit: year + period: year + label: Missouri Child Care Subsidy poverty guideline year lag + reference: + - title: November 2025 Child Care Eligibility Income Guidelines and Sliding Fee Chart (updated July 1, 2026) + href: https://dese.mo.gov/sites/g/files/zuston521/files/media/pdf/2026/07/Income%20Elig%20_Updated%206.29.26.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpl_rate/initial_eligibility.yaml b/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpl_rate/initial_eligibility.yaml index 6d9b7307be2..44d3c95e486 100644 --- a/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpl_rate/initial_eligibility.yaml +++ b/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpl_rate/initial_eligibility.yaml @@ -13,3 +13,5 @@ metadata: href: https://web.archive.org/web/20250831220820id_/https://dese.mo.gov/childhood/quality-programs/child-care-subsidy/child-care-manual/2010/045/00 - title: November 2025 Child Care Eligibility Income Guidelines and Sliding Fee Chart href: https://dese.mo.gov/sites/g/files/zuston521/files/media/pdf/2025/10/10.2025%20Income%20Eligibility%20Table%20%282%29.pdf#page=1 + - title: November 2025 Child Care Eligibility Income Guidelines and Sliding Fee Chart, updated July 1, 2026 + href: https://dese.mo.gov/sites/g/files/zuston521/files/media/pdf/2026/07/Income%20Elig%20_Updated%206.29.26.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpl_rate/transitional.yaml b/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpl_rate/transitional.yaml index 9b6f524919b..2e6e842e45c 100644 --- a/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpl_rate/transitional.yaml +++ b/policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpl_rate/transitional.yaml @@ -1,6 +1,8 @@ description: Missouri limits adjusted gross income to this multiple of the federal poverty guideline for existing families under the Child Care Subsidy program. values: 2025-10-01: 2.42 + # DESE removed Transitional Level 3 (216-242%) on July 1, 2026, leaving Level 2 at the top. + 2026-07-01: 2.15 metadata: unit: /1 @@ -17,3 +19,5 @@ metadata: href: https://www.law.cornell.edu/regulations/missouri/5-CSR-25-200-060 - title: November 2025 Child Care Eligibility Income Guidelines and Sliding Fee Chart href: https://dese.mo.gov/sites/g/files/zuston521/files/media/pdf/2025/10/10.2025%20Income%20Eligibility%20Table%20%282%29.pdf#page=1 + - title: November 2025 Child Care Eligibility Income Guidelines and Sliding Fee Chart, updated July 1, 2026 ("Transitional Level 3 removed July 1, 2026") + href: https://dese.mo.gov/sites/g/files/zuston521/files/media/pdf/2026/07/Income%20Elig%20_Updated%206.29.26.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/mo/dese/ccs/transitional/funding_rate.yaml b/policyengine_us/parameters/gov/states/mo/dese/ccs/transitional/funding_rate.yaml index 5f3b92b7ad9..fc218d52b07 100644 --- a/policyengine_us/parameters/gov/states/mo/dese/ccs/transitional/funding_rate.yaml +++ b/policyengine_us/parameters/gov/states/mo/dese/ccs/transitional/funding_rate.yaml @@ -2,7 +2,12 @@ description: Missouri funds this share of the base reimbursement rate by federal # Traditional families (at or below 150% FPL) are funded at the full base rate. # Transitional Child Care families are funded at a reduced share: # Level 1 (above 150% up to 185%) = 80%, Level 2 (above 185% up to 215%) = 60%, -# Level 3 (above 215% up to 242%) = 50%. +# Level 3 (above 215% up to 242%) = 50%. DESE removed Level 3 on July 1, 2026, so no +# eligible family reaches the 50% share from that date. +# Each threshold gives, as a multiple of the guideline, the top of the level below +# it. DESE's chart prints each top as the nearest dollar ($3,331, $4,109 and $4,775 +# a month for three from July 2026), and mo_ccs_funding_rate rounds them the same +# way. metadata: type: single_amount threshold_unit: /1 @@ -27,14 +32,14 @@ brackets: amount: 2025-10-01: 1 - threshold: - 2025-10-01: 1.5001 + 2025-10-01: 1.5 amount: 2025-10-01: 0.8 - threshold: - 2025-10-01: 1.8501 + 2025-10-01: 1.85 amount: 2025-10-01: 0.6 - threshold: - 2025-10-01: 2.1501 + 2025-10-01: 2.15 amount: 2025-10-01: 0.5 diff --git a/policyengine_us/parameters/gov/states/mt/dphhs/ccap/copayment/copay_rate.yaml b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/copayment/copay_rate.yaml index 019e5f2b962..1d78c219785 100644 --- a/policyengine_us/parameters/gov/states/mt/dphhs/ccap/copayment/copay_rate.yaml +++ b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/copayment/copay_rate.yaml @@ -7,9 +7,8 @@ description: Montana sets this share of gross monthly income as the copayment un # FPG (inclusive) up to but not including 115% FPG. PolicyEngine single_amount is "at # or above threshold," and the scale places a family exactly at a step into the higher # tier (e.g. 105% -> 1.0%), so thresholds use the named % directly with no shift. The -# published scale's top tier (7.0%) runs through 200% FPG, but income eligibility caps -# at 185% FPG for non-TANF families (ARM 37.80.202(2)), so the tiers above 185% are -# unreachable for eligible families and retained only to mirror the published scale. +# published scale's top tier (7.0%) runs through 200% FPG, which enrolled families reach +# through graduated eligibility. # # (S6) The graduated-eligibility STRUCTURE dates to 2016-11-01, but these copay # percentages come from the 2025 Best Beginnings Sliding Fee Scale (2025 Federal diff --git a/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/graduated.yaml b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/graduated.yaml index c7686161ba6..cf5022338ab 100644 --- a/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/graduated.yaml +++ b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/graduated.yaml @@ -1,17 +1,23 @@ description: Montana limits gross income to this share of the federal poverty guideline for graduated eligibility at redetermination under the Best Beginnings Child Care Scholarship program. -# ARM 37.80.202(2): a non-TANF household whose income exceeds 150% and is below -# 185% of the FPG qualifies for graduated eligibility at annual redetermination -# (12-month eligibility period). We proxy "at redetermination / continuing -# recipient" with the mt_ccap_enrolled input; first-time applicants use the -# initial 150% share (see initial.yaml). +# ARM 37.80.202(2) still prints 185%. The department's scale effective July 1, 2025 +# runs Graduated Eligibility to 200% for families already on the Non-TANF program at +# annual redetermination. That scale is the earliest dated source for 200%, so the +# list moves on its date; with the initial share at 185% from July 2023, the two match +# until then. We proxy "at redetermination / continuing recipient" with the +# mt_ccap_enrolled input; first-time applicants use the initial share (see initial.yaml). values: 2016-11-01: 1.85 + 2025-07-01: 2 metadata: unit: /1 period: year label: Montana CCAP graduated income limit share of federal poverty guideline reference: + - title: Best Beginnings Child Care Sliding Fee Scale (document header "Effective 07-01-2025"; URL filename says 2023) + href: https://dphhs.mt.gov/assets/ecfsd/childcare/policymanual/SlidingFeeScale07012023.pdf#page=1 + - title: MCA 52-2-715(2) (En. Sec. 2, Ch. 773, L. 2023), maximum qualifying income level + href: https://archive.legmt.gov/bills/MCA/title_0520/chapter_0020/part_0070/section_0150/0520-0020-0070-0150.html - title: Mont. Admin. R. 37.80.202(2) href: https://rules.mt.gov/gateway/ruleno.asp?RN=37.80.202 - title: Mont. Admin. R. 37.80.202(2) — Cornell LII diff --git a/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/initial.yaml b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/initial.yaml index d26f80f7574..3dd39be6ab0 100644 --- a/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/initial.yaml +++ b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/initial.yaml @@ -1,16 +1,28 @@ description: Montana limits gross income to this share of the federal poverty guideline for initial eligibility under the Best Beginnings Child Care Scholarship program. -# ARM 37.80.202(1): a household whose income is below 150% of the FPG is eligible. -# This is the initial / first-time applicant standard; continuing recipients at -# annual redetermination use the higher graduated share (see graduated.yaml), -# selected via the mt_ccap_enrolled input. +# ARM 37.80.202(1) still prints 150%. MCA 52-2-715, enacted by House Bill 648 in 2023, +# requires a threshold of no less than 185%, and the department has applied 185% since +# July 1, 2023; its scale ends Standard Eligibility there. The model follows the statute +# and the scale from that date. The Legislative Fiscal Division's timeline, adapted from +# the department's communications, also lists 185% from July 2021 through December 2022 +# under pandemic CCDF policies; the model keeps the rule's 150% for that period. This is +# the initial / first-time applicant standard; continuing recipients at annual +# redetermination use the higher graduated share (see graduated.yaml), selected via the +# mt_ccap_enrolled input. values: 2016-11-01: 1.5 + 2023-07-01: 1.85 metadata: unit: /1 period: year label: Montana CCAP initial income limit share of federal poverty guideline reference: + - title: MCA 52-2-715 (En. Sec. 2, Ch. 773, L. 2023), Income eligibility for best beginnings child care scholarship program + href: https://archive.legmt.gov/bills/MCA/title_0520/chapter_0020/part_0070/section_0150/0520-0020-0070-0150.html + - title: Best Beginnings Child Care Sliding Fee Scale (document header "Effective 07-01-2025"; URL filename says 2023) + href: https://dphhs.mt.gov/assets/ecfsd/childcare/policymanual/SlidingFeeScale07012023.pdf#page=1 + - title: "Montana Legislative Fiscal Division, Child Care Overview (June 2024), HB 648 in the 2023 Session and Policy Timeline #page 4,13" + href: https://leg.mt.gov/content/Publications/fiscal/2025-Biennium/Special-Topics/Childcare/Childcare-Overview-LEG-Days-June2024.pdf#page=4 - title: Mont. Admin. R. 37.80.202(1) href: https://rules.mt.gov/gateway/ruleno.asp?RN=37.80.202 - title: Mont. Admin. R. 37.80.202(1) — Cornell LII diff --git a/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_year_lag.yaml new file mode 100644 index 00000000000..ed5e1cac151 --- /dev/null +++ b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_year_lag.yaml @@ -0,0 +1,22 @@ +description: Montana uses the federal poverty guideline from this many years before the current date under the Best Beginnings Child Care Scholarship program. +# The Sliding Fee Scale effective July 1, 2025 prints the 2025 guideline (its footnote +# cites Federal Register Vol. 90, No. 11, January 17, 2025, though it says "2023"), so +# a lag of one holds that scale through 2026. ACF's January 2025 table prints 185% of +# the 2024 guideline ($3,981 a month for three), so a lag of one also covers the first +# half of 2025. A new scale adds a date here. No source dates the guideline year before +# 2025, so the list keeps the current year until then. +values: + 2015-01-01: 0 + 2025-01-01: 1 + 2025-07-01: 0 + 2026-01-01: 1 + +metadata: + unit: year + period: year + label: Montana CCAP poverty guideline year lag + reference: + - title: Best Beginnings Child Care Sliding Fee Scale (document header "Effective 07-01-2025"; URL filename says 2023) + href: https://dphhs.mt.gov/assets/ecfsd/childcare/policymanual/SlidingFeeScale07012023.pdf#page=1 + - title: ACF, CCDF Family Income Eligibility Levels by State (January 2025) + href: https://acf.gov/sites/default/files/documents/occ/CCDF-Family-Income-Eligibility-Levels-by-State.pdf diff --git a/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/income_limit_smi_rate.yaml b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/income_limit_smi_rate.yaml index e13e649ce79..150b9d891c6 100644 --- a/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/income_limit_smi_rate.yaml +++ b/policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/income_limit_smi_rate.yaml @@ -5,10 +5,10 @@ description: Montana limits gross income to this share of state median income un # Fee Scale and mirrors the federal CCDF maximum at 45 CFR 98.20(a)(2) (no child care # subsidy above 85% of State median income). It is NOT in ARM 37.80.202. # -# (S3) Binding behavior: with the 185% FPG graduated limit (ARM 37.80.202(2)), the FPG -# limit binds before this 85% SMI cap for all but the largest households. It only binds -# (0.85*SMI < 1.85*FPG) at very large household sizes, e.g. size 13+ in 2026 once HHS -# SMI uprating is applied. For typical sizes the cap is non-binding. +# (S3) Binding behavior: the FPG limits in fpg_limit bind before this 85% SMI cap for +# all but the largest households. In 2026 the cap binds from 11 people for enrolled +# families (the 200% graduated limit) and from 12 people for new applicants (the 185% +# initial limit). For typical sizes the cap does not bind. # # (S6) The SMI ceiling STRUCTURE dates to 2016-11-01, while the 0.85 share reflects the # 2025 Sliding Fee Scale (2025 Federal Register poverty guidelines context). The diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/chart_rounds_to_nearest_dollar.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/chart_rounds_to_nearest_dollar.yaml new file mode 100644 index 00000000000..49271560d85 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/chart_rounds_to_nearest_dollar.yaml @@ -0,0 +1,22 @@ +description: Nevada uses this indicator to determine whether its income chart rounds each income limit and copayment band to the nearest dollar under the Child Care and Development Program. + +# The charts effective October 1, 2025 and October 1, 2026 print every limit and band +# top as the nearest dollar of its share of state median income ($1,789 a month for one +# at 41% in 2025, from $1,788.77). CC PT 07-23 prints the 85% tops of the October 2023 +# chart in cents ($5,314.84 for three). The model treats the flat schedule's charts, +# from October 1, 2024, as rounded and earlier charts as unrounded. +values: + 2015-01-01: false + 2024-10-01: true + +metadata: + unit: bool + period: month + label: Nevada CCDP chart rounds to the nearest dollar + reference: + - title: Nevada DWSS Policy Transmittal CC PT 06-25 (October 2, 2025), Household Size and Monthly Income Charts + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/CC_PT_06-25_ANNUAL_INCOME_CHANGES_10.02.2025.pdf#page=2 + - title: Nevada DSS Policy Transmittal, Annual Changes to the CCDP Household Size and Monthly Income Limits (October 1, 2026) + href: https://prod.dss.nv.gov/siteassets/dwss.nv.gov/ccdp-annual-income-changes-2026_1.pdf#page=2 + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/amount.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/amount.yaml index 3dfa29d2d80..a16f06095e0 100644 --- a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/amount.yaml +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/amount.yaml @@ -12,15 +12,19 @@ metadata: - title: Nevada DWSS Policy Transmittal CC PT 06-25 (Oct 2, 2025) — Annual Income Changes href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/CC_PT_06-25_ANNUAL_INCOME_CHANGES_10.02.2025.pdf#page=1 +# Before October 2024 the formula reads reimbursed and percent_of_income instead. +# Before July 2022 Nevada set the copayment by income, county, age of child and type +# of care (FFY 2022-2024 plan, Section 3.2.2). The model does not carry that schedule, +# so this one stands in for those dates. # The flat $0/$90/$150 copay and two-tier copay structure took effect # Oct 1, 2024 (State Plan Section 2.4.v); CC PT 06-25 is the Oct 1, 2025 annual # income-chart refresh that restates the same percentages and bands. -# Income up to 32.99% SMI -> $0; 33%-42% SMI -> $90; above 42% SMI -> $150. -# The State Plan summary prose ("33%-42% -> $90, 43%-49% -> $150") leaves an -# undefined 42%-43% gap; the operational CC PT 06-25 fee chart resolves it, with -# the $90 band topping out at 42% SMI and the $150 band beginning just above it. -# The scale is at-or-above, so 0.33 belongs to the $90 band and 0.4201 to the -# $150 band (a family at exactly 42% SMI stays in the $90 band, per the chart). +# Each threshold gives, as a share of SMI, the top of the band below it: income up to +# 33% SMI pays $0, up to 42% SMI pays $90, and above 42% SMI pays $150. The charts +# print each top as the nearest dollar ($2,326 and $2,890 a month for three in October +# 2025), and nv_ccdp_copay rounds them the same way. The State Plan summary prose +# ("33%-42% -> $90, 43%-49% -> $150") leaves an undefined 42%-43% gap; the operational +# fee charts resolve it, with the $90 band topping out at 42% SMI. brackets: - threshold: 2024-10-01: 0 @@ -31,6 +35,6 @@ brackets: amount: 2024-10-01: 90 - threshold: - 2024-10-01: 0.4201 + 2024-10-01: 0.42 amount: 2024-10-01: 150 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/in_effect.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/in_effect.yaml new file mode 100644 index 00000000000..0f2f866225c --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/in_effect.yaml @@ -0,0 +1,18 @@ +description: Nevada sets family copayments as a percent of gross income under the Child Care and Development Program when this indicator is true. +# The chart effective October 1, 2023 prints the percent-of-income schedule. Families +# paid nothing until copayments returned on April 1, 2024, and the flat schedule replaced +# this one on October 1, 2024. +values: + 2015-01-01: false + 2024-04-01: true + 2024-10-01: false + +metadata: + unit: bool + period: month + label: Nevada CCDP percent-of-income copayment schedule in effect + reference: + - title: Nevada DWSS, Changes to the Child Care and Development Subsidy Program (March 27, 2024) + href: https://nevadachildcare.netlify.app/static/200a0b5ae99f788e8c99d6f7824dc92b/Child-Care-Updates-Parents-.pdf#page=1 + - title: Nevada DWSS, Copayment Webinar Questions and Answers (November 2024) + href: https://nevadachildcare.netlify.app/static/bba7e54af87b3b89e51dd500b42629bf/Copayment-Webinar-QA_FINAL_NOV24.pdf#page=3 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_1.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_1.yaml new file mode 100644 index 00000000000..9c1a7961581 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_1.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a one-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($3,290.14 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for one-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 1475.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 1735.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 1995.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 2255.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 2515.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 2775.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 3035.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_10.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_10.yaml new file mode 100644 index 00000000000..3a411361084 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_10.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a ten-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($9,111.15 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for ten-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 5576.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 6082.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 6588.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 7094.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 7600.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 8106.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 8612.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_11.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_11.yaml new file mode 100644 index 00000000000..b7dfba2595e --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_11.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a eleven-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($9,300.97 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for eleven-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 5974.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 6450.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 6926.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 7402.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 7878.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 8354.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 8830.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_12.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_12.yaml new file mode 100644 index 00000000000..913b2726bc4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_12.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a twelve-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($9,490.78 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for twelve-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 6373.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 6819.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 7265.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 7711.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 8157.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 8603.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 9049.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_13.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_13.yaml new file mode 100644 index 00000000000..4e475517e51 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_13.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a thirteen-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($9,680.60 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for thirteen-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 6772.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 7189.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 7606.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 8023.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 8440.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 8857.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 9274.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_14.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_14.yaml new file mode 100644 index 00000000000..0191f1bcd11 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_14.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a fourteen-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($9,870.41 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for fourteen-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 7170.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 7557.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 7944.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 8331.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 8718.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 9105.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 9492.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_2.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_2.yaml new file mode 100644 index 00000000000..c5c587d4e6f --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_2.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a two-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($4,302.49 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for two-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 1976.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 2309.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 2642.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 2975.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 3308.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 3641.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 3974.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_3.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_3.yaml new file mode 100644 index 00000000000..d62a9e24c04 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_3.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a three-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($5,314.84 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for three-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 2478.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 2884.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 3290.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 3696.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 4102.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 4508.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 4914.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_4.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_4.yaml new file mode 100644 index 00000000000..5ef5359e793 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_4.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a four-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($6,327.19 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for four-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 2979.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 3458.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 3937.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 4416.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 4895.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 5374.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 5853.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_5.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_5.yaml new file mode 100644 index 00000000000..b7f4fb3cc0a --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_5.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a five-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($7,339.54 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for five-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 3480.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 4032.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 4584.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 5136.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 5688.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 6240.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 6792.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_6.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_6.yaml new file mode 100644 index 00000000000..9009726c0f0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_6.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a six-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($8,351.89 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for six-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 3982.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 4607.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 5232.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 5857.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 6482.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 7107.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 7732.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_7.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_7.yaml new file mode 100644 index 00000000000..6392f073083 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_7.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a seven-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($8,541.70 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for seven-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 4381.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 4977.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 5573.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 6169.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 6765.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 7361.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 7957.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_8.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_8.yaml new file mode 100644 index 00000000000..6de0e94d4aa --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_8.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a eight-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($8,731.52 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for eight-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 4779.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 5345.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 5911.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 6477.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 7043.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 7609.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 8175.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_9.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_9.yaml new file mode 100644 index 00000000000..898f9e4c6dd --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/percent_of_income/size_9.yaml @@ -0,0 +1,50 @@ +description: Nevada sets the family copayment at this share of gross income for a nine-person household under the Child Care and Development Program. +# Chart effective October 1, 2023. Each threshold sits just above the top of the +# printed row, so income at a row's top stays in that row. Income tops out at 85% of +# SMI ($8,921.33 a month), where the copayment reaches 7%. +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + threshold_period: month + period: month + label: Nevada CCDP copayment share of income for nine-person household + reference: + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2 + - title: Nevada Child Care Policy Manual (July 1, 2024), MS 170, Household Size Monthly Income Chart + href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=32 + +brackets: + - threshold: + 2024-04-01: 0 + amount: + 2024-04-01: 0 + - threshold: + 2024-04-01: 5178.0001 + amount: + 2024-04-01: 0.01 + - threshold: + 2024-04-01: 5714.0001 + amount: + 2024-04-01: 0.02 + - threshold: + 2024-04-01: 6250.0001 + amount: + 2024-04-01: 0.03 + - threshold: + 2024-04-01: 6786.0001 + amount: + 2024-04-01: 0.04 + - threshold: + 2024-04-01: 7322.0001 + amount: + 2024-04-01: 0.05 + - threshold: + 2024-04-01: 7858.0001 + amount: + 2024-04-01: 0.06 + - threshold: + 2024-04-01: 8394.0001 + amount: + 2024-04-01: 0.07 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/reimbursed.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/reimbursed.yaml new file mode 100644 index 00000000000..3b81ef7ab27 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/copay/reimbursed.yaml @@ -0,0 +1,19 @@ +description: Nevada reimburses family copayments under the Child Care and Development Program when this indicator is true. +# Urban's 2022 Book of Tables says families received reimbursement from March 2023 for +# copayments paid back to July 1, 2022. DWSS's letter of March 27, 2024 says American +# Rescue Plan funds let the program eliminate copayments, and that most families pay a +# copayment again as of April 1, 2024. +values: + 2015-01-01: false + 2022-07-01: true + 2024-04-01: false + +metadata: + unit: bool + period: month + label: Nevada CCDP copayments reimbursed + reference: + - title: Urban Institute, CCDF Policies Database Book of Tables 2022, Table 30 notes + href: https://ccdf.urban.org/sites/default/files/CCDF%20Policies%20Database%202022%20Book%20of%20Tables%20%28final%29.pdf#page=288 + - title: Nevada DWSS, Changes to the Child Care and Development Subsidy Program (March 27, 2024) + href: https://nevadachildcare.netlify.app/static/200a0b5ae99f788e8c99d6f7824dc92b/Child-Care-Updates-Parents-.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/fpg_intake/in_effect.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/fpg_intake/in_effect.yaml new file mode 100644 index 00000000000..e3c114214ed --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/fpg_intake/in_effect.yaml @@ -0,0 +1,27 @@ +description: Nevada uses this indicator to determine whether new applicants face a limit set as a share of the federal poverty guideline under the Child Care and Development Program. + +# Urban's CCDF Policies Database prints 85% of state median income for new applicants +# in October 2017 and a lower limit by October 2018, so the start date falls between +# those two snapshots. The state's own figures from February 2019 through October 2021 +# all equal 130% of the poverty guideline. The FFY 2022-2024 plan moves new applicants +# to 85% of state median income on July 1, 2022. +values: + 2015-01-01: false + 2018-10-01: true + 2022-07-01: false + +metadata: + unit: bool + period: month + label: Nevada CCDP poverty-guideline intake limit in effect + reference: + - title: Urban Institute, CCDF Policies Database Book of Tables 2018, Changes in Financial Eligibility Tests from 2017 to 2018 + href: https://ccdf.urban.org/sites/default/files/CrossStateVariationCCDFPolicies2018%20%28final%2011%2021%202019%29.pdf#page=41 + - title: "National Women's Law Center, State Child Care Assistance Policies: Nevada (February 2020) #page 1-2" + href: https://nwlc.org/wp-content/uploads/2020/02/nevada-childcare-subsidy2019_v1.pdf#page=1 + - title: Nevada draft CCDF State Plan FFY 2022-2024, Section 3.1.3 (limits effective October 1, 2020) + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Home/Features/2022-2024%20Child%20Care%20PrePrint%20Draft(1).pdf#page=45 + - title: Urban Institute, CCDF Policies Database Book of Tables 2021, Table B-1 (thresholds reported for October 1, 2021) + href: https://ccdf.urban.org/sites/default/files/CCDF%20Policies%20Database%202021%20Book%20of%20Tables%20%28final%29_1.pdf#page=393 + - title: "Nevada CCDF State Plan FFY 2022-2024, Amendment approved May 16, 2023, Section 3.1.3 (85% of SMI effective July 1, 2022) #page 50-51" + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/Amended%20State%20Plan.pdf#page=50 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/fpg_intake/rate.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/fpg_intake/rate.yaml new file mode 100644 index 00000000000..06e998751d0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/fpg_intake/rate.yaml @@ -0,0 +1,19 @@ +description: Nevada limits new applicants to income at or below this multiple of the federal poverty guideline under the Child Care and Development Program, while the poverty-guideline intake limit applies. + +# The state's figures for a family of three all equal 130% of the guideline Nevada had +# taken up that October: $27,012 a year in February 2019 (2018 guideline), $27,729 from +# October 2019, $2,353 a month from October 1, 2020 and $2,379 on October 1, 2021. +values: + 2018-10-01: 1.3 + +metadata: + unit: /1 + period: month + label: Nevada CCDP poverty-guideline intake rate + reference: + - title: "National Women's Law Center, State Child Care Assistance Policies: Nevada (February 2020) #page 1-2" + href: https://nwlc.org/wp-content/uploads/2020/02/nevada-childcare-subsidy2019_v1.pdf#page=1 + - title: Nevada draft CCDF State Plan FFY 2022-2024, Section 3.1.3 (limits effective October 1, 2020) + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Home/Features/2022-2024%20Child%20Care%20PrePrint%20Draft(1).pdf#page=45 + - title: Urban Institute, CCDF Policies Database Book of Tables 2021, Table B-1 (thresholds reported for October 1, 2021) + href: https://ccdf.urban.org/sites/default/files/CCDF%20Policies%20Database%202021%20Book%20of%20Tables%20%28final%29_1.pdf#page=393 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_intake.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_intake.yaml index a7b1fa4e923..698c5c8c060 100644 --- a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_intake.yaml +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_intake.yaml @@ -1,5 +1,18 @@ description: Nevada limits new applicants to income at or below this share of state median income under the Child Care and Development Program. +# Nevada has moved the limit for new applicants three times: +# - Through 2017 Urban's CCDF Policies Database prints 85% of SMI each October ($3,954, +# $4,104 and $4,127 a month for three in 2015, 2016 and 2017). No Nevada document +# from those years survives on its site. +# - From October 2018 through June 2022 most new applicants faced 130% of the poverty +# guideline instead (fpg_intake). NWLC reports that families with a child in foster +# care or protective services and homeless families still qualified at 85% of SMI, +# which this parameter keeps for them. +# - The FFY 2022-2024 plan moves every new applicant to 85% of SMI effective July 1, +# 2022 ($5,066 for three), and CC PT 07-23 keeps 85% for October 2023 ($5,314.84). +# - From October 1, 2024 new applicants face 41% and renewals 49%. The chart effective +# October 1, 2026 keeps both shares. values: + 2015-01-01: 0.85 2024-10-01: 0.41 metadata: @@ -7,11 +20,19 @@ metadata: period: year label: Nevada CCDP intake income limit share of state median income reference: + - title: Urban Institute, CCDF Policies Database Book of Tables 2015, Table 14 + href: https://ccdf.urban.org/sites/default/files/CCDF%20Policies%20Database%202015%20Book%20of%20Tables%20%28final%2011%2023%2016%29.pdf#page=124 + - title: Urban Institute, CCDF Policies Database Book of Tables 2017, Table 14 + href: https://ccdf.urban.org/sites/default/files/CCDF%20Policies%20Database%202017%20Book%20of%20Tables%20%28final%2010%2009%2018%29.pdf#page=122 + - title: "National Women's Law Center, State Child Care Assistance Policies: Nevada (February 2020), note 1" + href: https://nwlc.org/wp-content/uploads/2020/02/nevada-childcare-subsidy2019_v1.pdf#page=2 + - title: "Nevada CCDF State Plan FFY 2022-2024, Amendment approved May 16, 2023, Section 3.1.3 (85% of SMI effective July 1, 2022) #page 50-51" + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/Amended%20State%20Plan.pdf#page=50 + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=1 - title: Nevada DWSS Policy Transmittal CC PT 06-25 (Oct 2, 2025) — Annual Income Changes href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/CC_PT_06-25_ANNUAL_INCOME_CHANGES_10.02.2025.pdf#page=1 - title: Nevada CCDF State Plan FFY 2025-2027, Section 2.5.5 — Eligibility income thresholds (initial and graduated) href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/ACF-118_CCDF_FFY_2025-2027_For_Nevada__3.pdf#page=35 - -# The flat $0/$90/$150 copay and two-tier 41%/49% SMI eligibility took effect -# Oct 1, 2024 (State Plan Section 2.4.v); CC PT 06-25 is the Oct 1, 2025 annual -# income-chart refresh that restates the same percentages and bands. + - title: Nevada DSS Policy Transmittal, Annual Changes to the CCDP Household Size and Monthly Income Limits (October 1, 2026) + href: https://prod.dss.nv.gov/siteassets/dwss.nv.gov/ccdp-annual-income-changes-2026_1.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_renewal.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_renewal.yaml index db8109ba9f4..bb7470c99f0 100644 --- a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_renewal.yaml +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_renewal.yaml @@ -1,5 +1,12 @@ description: Nevada limits renewing households to income at or below this share of state median income under the Child Care and Development Program. +# Urban's CCDF Policies Database prints 85% of SMI for enrolled families every October +# from 2015 through 2022 ($4,260 a month for three in 2018, while new applicants faced +# $2,366). The FFY 2022-2024 plan and CC PT 07-23 keep 85% through September 2024. +# From October 1, 2024 renewals face 49%. The Nevada DWSS copay Q&A of November 2024 +# says the change reaches a family only at its first renewal after that date. The model +# has no certificate dates, so every enrolled family moves on October 1, 2024. values: + 2015-01-01: 0.85 2024-10-01: 0.49 metadata: @@ -7,11 +14,19 @@ metadata: period: year label: Nevada CCDP renewal income limit share of state median income reference: + - title: Urban Institute, CCDF Policies Database Book of Tables 2017, Table 16 + href: https://ccdf.urban.org/sites/default/files/CCDF%20Policies%20Database%202017%20Book%20of%20Tables%20%28final%2010%2009%2018%29.pdf#page=122 + - title: Urban Institute, CCDF Policies Database Book of Tables 2022, Table F-3 (initial and continuing limits, 2018-2022) + href: https://ccdf.urban.org/sites/default/files/CCDF%20Policies%20Database%202022%20Book%20of%20Tables%20%28final%29.pdf#page=428 + - title: "Nevada CCDF State Plan FFY 2022-2024, Amendment approved May 16, 2023, Section 3.1.3 #page 50-51" + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/Amended%20State%20Plan.pdf#page=50 + - title: Nevada DWSS Policy Transmittal CC PT 07-23 (October 9, 2023), Household Size Monthly Income Chart + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=1 + - title: Nevada DWSS, Copayment Webinar Questions and Answers (November 2024) + href: https://nevadachildcare.netlify.app/static/bba7e54af87b3b89e51dd500b42629bf/Copayment-Webinar-QA_FINAL_NOV24.pdf#page=1 - title: Nevada DWSS Policy Transmittal CC PT 06-25 (Oct 2, 2025) — Annual Income Changes href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/CC_PT_06-25_ANNUAL_INCOME_CHANGES_10.02.2025.pdf#page=1 - title: Nevada CCDF State Plan FFY 2025-2027, Section 2.5.5 — Graduated phase-out of assistance at redetermination href: https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/ACF-118_CCDF_FFY_2025-2027_For_Nevada__3.pdf#page=36 - -# The flat $0/$90/$150 copay and two-tier 41%/49% SMI eligibility took effect -# Oct 1, 2024 (State Plan Section 2.4.v); CC PT 06-25 is the Oct 1, 2025 annual -# income-chart refresh that restates the same percentages and bands. + - title: Nevada DSS Policy Transmittal, Annual Changes to the CCDP Household Size and Monthly Income Limits (October 1, 2026) + href: https://prod.dss.nv.gov/siteassets/dwss.nv.gov/ccdp-annual-income-changes-2026_1.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_year_lag.yaml b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_year_lag.yaml new file mode 100644 index 00000000000..86ee72b475d --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/ccdp/income/smi_year_lag.yaml @@ -0,0 +1,17 @@ +description: Nevada reads the state median income table from this many federal fiscal years before the program year in effect under the Child Care and Development Program. + +# Nevada takes up each federal table on its October 1 start, with one exception: the +# FFY 2022-2024 plan dates its 85% limits ($5,066 a month for three) to July 1, 2022, +# and builds them on the LIHEAP fiscal year 2023 table, which starts October 1, 2022. +values: + 2015-01-01: 0 + 2022-07-01: -1 + 2022-10-01: 0 + +metadata: + unit: year + period: month + label: Nevada CCDP state median income table year lag + reference: + - title: "Nevada CCDF State Plan FFY 2022-2024, Amendment approved May 16, 2023, Section 3.1.3(b), (d) and (f), 85% of the LIHEAP FFY23 state median income from July 1, 2022 #page 50-51" + href: https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/Amended%20State%20Plan.pdf#page=50 diff --git a/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/child_age_limit.yaml b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/child_age_limit.yaml new file mode 100644 index 00000000000..4a3a3e06df7 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/child_age_limit.yaml @@ -0,0 +1,15 @@ +description: Ohio limits child eligibility to under this age under the Child Care Choice Voucher Program. + +# The voucher's school-age row runs to age 15, two years past the Publicly +# Funded Child Care limit of 13. Its special-needs limit of 18 matches that +# program, so eligibility/special_needs_child_age_limit.yaml serves both. +values: + 2025-11-01: 15 + +metadata: + unit: year + period: year + label: Ohio CCVP child age limit + reference: + - title: DCY Procedure Letter 36, voucher payment rates, school age row (October 29, 2025) + href: https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_36.pdf#page=3 diff --git a/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/fpl_rate.yaml b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/fpl_rate.yaml new file mode 100644 index 00000000000..dd292f9e8c0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/fpl_rate.yaml @@ -0,0 +1,17 @@ +description: Ohio limits family income to this share of the federal poverty guideline under the Child Care Choice Voucher Program. +values: + 2025-11-01: 2 + +metadata: + unit: /1 + period: year + label: Ohio CCVP income limit rate + reference: + - title: DCY Procedure Letter 36, Child Care Choice Voucher Program (October 29, 2025) + href: https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_36.pdf#page=3 + - title: DCY Procedure Letter 21, 2025 income eligibility standards (August 29, 2025) + href: https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_21.pdf#page=2 + - title: DCY Procedure Letter 45, 2026 income eligibility standards (August 18, 2026) + href: https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners%20and%20Providers/Rules%20and%20Resources/2026/PL_45.pdf#page=2 + - title: LSC Final Analysis of H.B. 96 (136th General Assembly), Section 423.190 + href: https://www.lsc.ohio.gov/assets/legislation/136/hb96/en0/files/hb96-kid-bill-analysis-as-enacted-136th-general-assembly.pdf#page=10 diff --git a/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/in_effect.yaml b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/in_effect.yaml new file mode 100644 index 00000000000..6ba7c915e37 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/in_effect.yaml @@ -0,0 +1,19 @@ +description: Ohio uses this indicator to determine whether the modeled Child Care Choice Voucher Program rules apply. + +# DCY launched the voucher administratively in April 2024 (H.B. 96 final +# analysis). The model starts it in November 2025, when the Procedure Letter 36 +# payment chart and the modeled Publicly Funded Child Care rules both begin. +# This MONTH-period parameter is read at the month start. +values: + 2000-01-01: false + 2025-11-01: true + +metadata: + unit: bool + period: month + label: Ohio CCVP rules in effect + reference: + - title: DCY Procedure Letter 36, Child Care Choice Voucher Program (October 29, 2025) + href: https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_36.pdf#page=2 + - title: LSC Final Analysis of H.B. 96 (136th General Assembly), Section 423.190 + href: https://www.lsc.ohio.gov/assets/legislation/136/hb96/en0/files/hb96-kid-bill-analysis-as-enacted-136th-general-assembly.pdf#page=10 diff --git a/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/payment.yaml b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/payment.yaml new file mode 100644 index 00000000000..ac9b8079249 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/payment.yaml @@ -0,0 +1,42 @@ +description: Ohio provides this monthly amount per child under the Child Care Choice Voucher Program until the program adopts the Publicly Funded Child Care payment rates. +metadata: + propagate_metadata_to_children: true + period: month + unit: currency-USD + label: Ohio CCVP monthly voucher payment + breakdown: + - oh_ccap_provider_type + - oh_ccvp_child_age_group + reference: + - title: "DCY Procedure Letter 36, voucher payment rates for enrollment and attendance on or after November 1, 2025 #page 2-3" + href: https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_36.pdf#page=2 + +# Procedure Letter 36 charts centers and school-based programs apart from +# type A and type B family child care homes, with one school-age row for children +# enrolled in or eligible to enroll in kindergarten, so the school-age summer group +# takes the school-age amount. It prices enrollment and attendance from November 1, +# 2025; the model carries no earlier chart. The letter also pays programs an initial +# enrollment payment on authorization, at most three per child in an eligibility +# year; the model pays only the monthly amounts. +CENTER: + INFANT: + 2025-11-01: 900 + TODDLER: + 2025-11-01: 800 + PRESCHOOL: + 2025-11-01: 750 + SCHOOL_AGE: + 2025-11-01: 375 + SCHOOL_AGE_SUMMER: + 2025-11-01: 375 +HOME: + INFANT: + 2025-11-01: 600 + TODDLER: + 2025-11-01: 550 + PRESCHOOL: + 2025-11-01: 500 + SCHOOL_AGE: + 2025-11-01: 300 + SCHOOL_AGE_SUMMER: + 2025-11-01: 300 diff --git a/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/pfcc_rates_in_effect.yaml b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/pfcc_rates_in_effect.yaml new file mode 100644 index 00000000000..a32d9b478d0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/dcy/ccap/ccvp/pfcc_rates_in_effect.yaml @@ -0,0 +1,17 @@ +description: Ohio uses this indicator to determine whether the Child Care Choice Voucher Program pays at the Publicly Funded Child Care payment rates. + +# H.B. 96, Section 423.190, requires the voucher to use those rates, without +# the Step Up to Quality enhancement, not later than November 1, 2026. This +# parameter uses that deadline because the DCY procedure letters we could read +# name no other date. +values: + 2000-01-01: false + 2026-11-01: true + +metadata: + unit: bool + period: month + label: Ohio CCVP pays Publicly Funded Child Care rates + reference: + - title: LSC Final Analysis of H.B. 96 (136th General Assembly), Section 423.190 + href: https://www.lsc.ohio.gov/assets/legislation/136/hb96/en0/files/hb96-kid-bill-analysis-as-enacted-136th-general-assembly.pdf#page=10 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpg_year_lag.yaml new file mode 100644 index 00000000000..b024caf55c0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpg_year_lag.yaml @@ -0,0 +1,20 @@ +description: West Virginia uses the federal poverty guideline from this many years before the current date under the Child Care Assistance Program. +# Appendix A's sliding fee scale, created October 1, 2024, prints the 2024 guideline +# (headed "FY 2024 Federal Poverty Level"; $3,981 a month for three at 185%). The +# Bureau's Child Care Policy page still linked that scale on November 5, 2026, so the +# lag grows to keep the 2024 guideline. A new scale adds a date here. From 2027 the +# lag of two extrapolates: it reads the 2025 guideline, which no scale prints. +values: + 2015-01-01: 0 + 2025-01-01: 1 + 2026-01-01: 2 + +metadata: + unit: year + period: year + label: West Virginia CCAP poverty guideline year lag + reference: + - title: WV Child Care Subsidy Appendix A, Sliding Fee Scale (FY 2024 Federal Poverty Level) + href: https://bfa.wv.gov/media/6826/download?inline#page=1 + - title: WV Bureau for Family Assistance, Child Care Policy + href: https://bfa.wv.gov/bfa-policy-and-plans/child-care-policy diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_limit.yaml new file mode 100644 index 00000000000..2e0e5f278af --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_limit.yaml @@ -0,0 +1,19 @@ +description: West Virginia limits income to this share of the state median income under the Child Care Assistance Program. +# Federal rules cap child care eligibility at 85% of the state median income, and the +# CCDF plan allows no higher limit. Appendix A ends the ten- and eleven-person scales at +# that cap, below 185% of the guideline: $9,247 and $9,440 a month on the October 2024 +# state median income table. +values: + 2015-01-01: 0.85 + +metadata: + unit: /1 + period: year + label: West Virginia CCAP income limit as share of state median income + reference: + - title: 45 CFR 98.20(a)(2)(i) + href: https://www.ecfr.gov/current/title-45/section-98.20#p-98.20(a)(2)(i) + - title: West Virginia CCDF State Plan FFY 2025-2027, 2.2.4(a)(ii) + href: https://bfa.wv.gov/media/39915/download?inline#page=21 + - title: "WV Child Care Subsidy Appendix A, Sliding Fee Scale (FY 2024 Federal Poverty Level), ten- and eleven-person families #page 5-6" + href: https://bfa.wv.gov/media/6826/download?inline#page=5 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_year_lag.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_year_lag.yaml new file mode 100644 index 00000000000..156f0f33e90 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_year_lag.yaml @@ -0,0 +1,20 @@ +description: West Virginia reads the state median income table from this many federal fiscal years before the program year under the Child Care Assistance Program. +# Appendix A's sliding fee scale, created October 1, 2024, caps the largest families at +# 85% of the October 2024 table ($9,247 a month for ten people). The Bureau's Child Care +# Policy page still linked that scale on November 5, 2026, so the lag grows to keep the +# October 2024 table. A new scale adds a date here. From October 2027 the lag of two +# extrapolates: it reads the October 2025 table, which no scale prints. +values: + 2015-01-01: 0 + 2025-10-01: 1 + 2026-10-01: 2 + +metadata: + unit: year + period: month + label: West Virginia CCAP state median income table year lag + reference: + - title: "WV Child Care Subsidy Appendix A, Sliding Fee Scale (FY 2024 Federal Poverty Level), ten- and eleven-person families #page 5-6" + href: https://bfa.wv.gov/media/6826/download?inline#page=5 + - title: WV Bureau for Family Assistance, Child Care Policy + href: https://bfa.wv.gov/bfa-policy-and-plans/child-care-policy diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index a7cef450f8b..19c7743304d 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -853,9 +853,10 @@ programs: - state: OH status: complete name: Ohio Publicly Funded Child Care - full_name: Ohio Child Care Assistance Program (Publicly Funded Child Care) + full_name: Ohio Child Care Assistance Program (Publicly Funded Child Care and Child Care Choice Voucher Program) variable: oh_child_care_subsidies parameter_prefix: gov.states.oh.dcy.ccap + notes: The Child Care Choice Voucher Program starts in November 2025 with Procedure Letter 36's monthly payment chart; the model leaves out the voucher from its April 2024 launch until then and the initial enrollment payment the letter adds on top of the monthly payments. - state: PA status: complete name: Pennsylvania CCW @@ -911,6 +912,7 @@ programs: full_name: Georgia Childcare and Parent Services variable: ga_caps parameter_prefix: gov.states.ga.decal.caps + notes: Models the dated limits for new applicants since 2016 (50% of state median income from October 2016, 85% from November 2021, 50% from December 2022, 30% from September 2024, 40% from October 2025 and 50% from March 2026), the 85% limit for enrolled families, and the priority groups that decide which new applicants DECAL serves from August 2016. Not modeled - application dates, the 2020 Essential Services Workforce group, and DECAL's discretionary waivers - state: ND status: partial name: North Dakota CCAP diff --git a/policyengine_us/tests/code_health/test_source_conflicts.py b/policyengine_us/tests/code_health/test_source_conflicts.py index 2bc5e9d4e84..2fcec5b2b42 100644 --- a/policyengine_us/tests/code_health/test_source_conflicts.py +++ b/policyengine_us/tests/code_health/test_source_conflicts.py @@ -175,7 +175,6 @@ "policyengine_us/variables/gov/states/md/tax/income/capital_gains/md_net_capital_gain.py": 1, "policyengine_us/variables/gov/states/mn/dcyf/mfip/income/earned/mn_mfip_dependent_care_deduction.py": 1, "policyengine_us/variables/gov/states/mn/tax/income/deductions/mn_itemized_deductions.py": 1, - "policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.py": 1, "policyengine_us/variables/gov/states/nm/tax/income/exemptions/nm_medical_expense_exemption.py": 1, "policyengine_us/variables/gov/states/ny/tax/income/credits/ny_household_credit_potential.py": 2, "policyengine_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_survivors.py": 1, diff --git a/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_fpg.yaml new file mode 100644 index 00000000000..351ef19a391 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/al/dhr/ccsp/al_ccsp_fpg.yaml @@ -0,0 +1,108 @@ +# Alabama CCSP monthly federal poverty guideline (SPMUnit, MONTH). +# The fact sheets use the prior calendar year's guideline and one row for families +# of eight or more. + +- name: A family of nine uses the eight-person guideline in June 2026. + period: 2026-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + is_tax_unit_dependent: true + person4: + age: 13 + is_tax_unit_dependent: true + person5: + age: 11 + is_tax_unit_dependent: true + person6: + age: 9 + is_tax_unit_dependent: true + person7: + age: 7 + is_tax_unit_dependent: true + person8: + age: 5 + is_tax_unit_dependent: true + person9: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + # (15,650 + 7 x 5,500) / 12 = 4,512.50; the June 2026 fact sheet's >=8 row prints 0-4,513 dollars at 0-100% FPL. + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: + 2026: AL + output: + al_ccsp_fpg: 4_512.50 + +- name: A family of three uses the prior year's guideline in June 2026. + period: 2026-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + # 26,650 / 12 = 2,220.83; the June 2026 fact sheet prints 0-2,221 dollars at 0-100% FPL. + households: + household: + members: [person1, person2, person3] + state_code: + 2026: AL + output: + al_ccsp_fpg: 2_220.83 + +- name: A family of eight uses the 2023 guideline in January 2024. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + is_tax_unit_dependent: true + person4: + age: 13 + is_tax_unit_dependent: true + person5: + age: 11 + is_tax_unit_dependent: true + person6: + age: 9 + is_tax_unit_dependent: true + person7: + age: 7 + is_tax_unit_dependent: true + person8: + age: 5 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + # (14,580 + 7 x 5,140) / 12 = 4,213.33; the January 2024 fact sheet's >=8 row prints 0-4,213 dollars at 0-100% FPL. + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2024: AL + output: + al_ccsp_fpg: 4_213.33 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 c5dad7f2e3b..bc522840c33 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 @@ -256,3 +256,731 @@ output: # 75,145.96 > 75,145.95 (85% SMI cap) -> SMI cap fails. al_ccsp_income_eligible: false + +# Family of three on the 2025 guideline ($26,650): the January 1, 2026 fact sheet +# tops at 180% ($3,998) for new applicants and 200% ($4,442) for continuing families; +# the June 1, 2026 fact sheet tops at 150% ($3,331) and 170% ($3,775). +- name: New applicant of three at 3,998 dollars qualifies in May 2026. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + al_ccsp_countable_income: 3_998 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: AL + output: + al_ccsp_income_eligible: true + +- name: New applicant of three at the June 2026 top of 3,331 dollars qualifies. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + al_ccsp_countable_income: 3_331 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: AL + output: + al_ccsp_income_eligible: true + +- name: New applicant of three at 3,332 dollars doesn't qualify from June 2026. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + al_ccsp_countable_income: 3_332 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: AL + output: + al_ccsp_income_eligible: false + +- name: Continuing family of three at the January 2026 top of 4,442 dollars stays eligible in May 2026. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + al_ccsp_countable_income: 4_442 + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: AL + output: + al_ccsp_income_eligible: true + +- name: Continuing family of three at the June 2026 top of 3,775 dollars stays eligible. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + al_ccsp_countable_income: 3_775 + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: AL + output: + al_ccsp_income_eligible: true + +- name: Continuing family of three at 3,776 dollars loses eligibility from June 2026. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 28 + person3: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + al_ccsp_countable_income: 3_776 + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: AL + output: + al_ccsp_income_eligible: false + +- name: A half-dollar limit prints up, so a family of two at 3,173 dollars qualifies in May 2026. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + # 21,150 x 1.8 / 12 = 3,172.50, printed as 3,173 on the January 2026 fact sheet. + al_ccsp_countable_income: 3_173 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2] + state_code: + 2026: AL + output: + al_ccsp_income_eligible: true + +- name: A new applicant family of nine uses the eight-or-more row, so 6,769 dollars qualifies in June 2026. + period: 2026-06 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + is_tax_unit_dependent: true + person4: + age: 13 + is_tax_unit_dependent: true + person5: + age: 11 + is_tax_unit_dependent: true + person6: + age: 9 + is_tax_unit_dependent: true + person7: + age: 7 + is_tax_unit_dependent: true + person8: + age: 5 + is_tax_unit_dependent: true + person9: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + # The June 2026 fact sheet's >=8 row tops out at 6,769 dollars (141-150% FPL). + al_ccsp_countable_income: 6_769 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: + 2026: AL + output: + al_ccsp_income_eligible: true + +- name: A new applicant family of nine at 6,770 dollars doesn't qualify in June 2026. + period: 2026-06 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + is_tax_unit_dependent: true + person4: + age: 13 + is_tax_unit_dependent: true + person5: + age: 11 + is_tax_unit_dependent: true + person6: + age: 9 + is_tax_unit_dependent: true + person7: + age: 7 + is_tax_unit_dependent: true + person8: + age: 5 + is_tax_unit_dependent: true + person9: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + al_ccsp_countable_income: 6_770 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: + 2026: AL + output: + al_ccsp_income_eligible: false + +- name: A continuing family of nine at the eight-or-more top of 8,427 dollars stays eligible in January 2024. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + is_tax_unit_dependent: true + person4: + age: 13 + is_tax_unit_dependent: true + person5: + age: 11 + is_tax_unit_dependent: true + person6: + age: 9 + is_tax_unit_dependent: true + person7: + age: 7 + is_tax_unit_dependent: true + person8: + age: 5 + is_tax_unit_dependent: true + person9: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + # The January 2024 fact sheet's >=8 row tops out at 8,427 dollars (191-200% FPL). + al_ccsp_countable_income: 8_427 + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: + 2024: AL + output: + al_ccsp_income_eligible: true + +- name: A continuing family of nine at 8,428 dollars loses eligibility in January 2024. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + is_tax_unit_dependent: true + person4: + age: 13 + is_tax_unit_dependent: true + person5: + age: 11 + is_tax_unit_dependent: true + person6: + age: 9 + is_tax_unit_dependent: true + person7: + age: 7 + is_tax_unit_dependent: true + person8: + age: 5 + is_tax_unit_dependent: true + person9: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + al_ccsp_countable_income: 8_428 + al_ccsp_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: + 2024: AL + output: + al_ccsp_income_eligible: false + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. + +- name: The June 1, 2026 fact sheet's initial scale holds at every family size. + period: 2026-06 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 2 + al_ccsp_countable_income: 2_644 + al_ccsp_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 2 + al_ccsp_countable_income: 2_645 + al_ccsp_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 3 + al_ccsp_countable_income: 3_331 + al_ccsp_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 3 + al_ccsp_countable_income: 3_332 + al_ccsp_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 4 + al_ccsp_countable_income: 4_019 + al_ccsp_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 4 + al_ccsp_countable_income: 4_020 + al_ccsp_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 5 + al_ccsp_countable_income: 4_706 + al_ccsp_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 5 + al_ccsp_countable_income: 4_707 + al_ccsp_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 6 + al_ccsp_countable_income: 5_394 + al_ccsp_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 6 + al_ccsp_countable_income: 5_395 + al_ccsp_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 7 + al_ccsp_countable_income: 6_081 + al_ccsp_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 7 + al_ccsp_countable_income: 6_082 + al_ccsp_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 8 + al_ccsp_countable_income: 6_769 + al_ccsp_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 8 + al_ccsp_countable_income: 6_770 + al_ccsp_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: AL + h2: + members: [p2] + state_code: + 2026: AL + h3: + members: [p3] + state_code: + 2026: AL + h4: + members: [p4] + state_code: + 2026: AL + h5: + members: [p5] + state_code: + 2026: AL + h6: + members: [p6] + state_code: + 2026: AL + h7: + members: [p7] + state_code: + 2026: AL + h8: + members: [p8] + state_code: + 2026: AL + h9: + members: [p9] + state_code: + 2026: AL + h10: + members: [p10] + state_code: + 2026: AL + h11: + members: [p11] + state_code: + 2026: AL + h12: + members: [p12] + state_code: + 2026: AL + h13: + members: [p13] + state_code: + 2026: AL + h14: + members: [p14] + state_code: + 2026: AL + output: + # Initial Eligibility Monthly Income Scale, 141-150% FPL column, sizes 2 to 8. + al_ccsp_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: The June 1, 2026 fact sheet's continuing scale holds at every family size. + period: 2026-06 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 2 + al_ccsp_countable_income: 2_996 + al_ccsp_enrolled: true + u2: + members: [p2] + spm_unit_size: + 2026: 2 + al_ccsp_countable_income: 2_997 + al_ccsp_enrolled: true + u3: + members: [p3] + spm_unit_size: + 2026: 3 + al_ccsp_countable_income: 3_775 + al_ccsp_enrolled: true + u4: + members: [p4] + spm_unit_size: + 2026: 3 + al_ccsp_countable_income: 3_776 + al_ccsp_enrolled: true + u5: + members: [p5] + spm_unit_size: + 2026: 4 + al_ccsp_countable_income: 4_555 + al_ccsp_enrolled: true + u6: + members: [p6] + spm_unit_size: + 2026: 4 + al_ccsp_countable_income: 4_556 + al_ccsp_enrolled: true + u7: + members: [p7] + spm_unit_size: + 2026: 5 + al_ccsp_countable_income: 5_334 + al_ccsp_enrolled: true + u8: + members: [p8] + spm_unit_size: + 2026: 5 + al_ccsp_countable_income: 5_335 + al_ccsp_enrolled: true + u9: + members: [p9] + spm_unit_size: + 2026: 6 + al_ccsp_countable_income: 6_113 + al_ccsp_enrolled: true + u10: + members: [p10] + spm_unit_size: + 2026: 6 + al_ccsp_countable_income: 6_114 + al_ccsp_enrolled: true + u11: + members: [p11] + spm_unit_size: + 2026: 7 + al_ccsp_countable_income: 6_892 + al_ccsp_enrolled: true + u12: + members: [p12] + spm_unit_size: + 2026: 7 + al_ccsp_countable_income: 6_893 + al_ccsp_enrolled: true + u13: + members: [p13] + spm_unit_size: + 2026: 8 + al_ccsp_countable_income: 7_671 + al_ccsp_enrolled: true + u14: + members: [p14] + spm_unit_size: + 2026: 8 + al_ccsp_countable_income: 7_672 + al_ccsp_enrolled: true + households: + h1: + members: [p1] + state_code: + 2026: AL + h2: + members: [p2] + state_code: + 2026: AL + h3: + members: [p3] + state_code: + 2026: AL + h4: + members: [p4] + state_code: + 2026: AL + h5: + members: [p5] + state_code: + 2026: AL + h6: + members: [p6] + state_code: + 2026: AL + h7: + members: [p7] + state_code: + 2026: AL + h8: + members: [p8] + state_code: + 2026: AL + h9: + members: [p9] + state_code: + 2026: AL + h10: + members: [p10] + state_code: + 2026: AL + h11: + members: [p11] + state_code: + 2026: AL + h12: + members: [p12] + state_code: + 2026: AL + h13: + members: [p13] + state_code: + 2026: AL + h14: + members: [p14] + state_code: + 2026: AL + output: + # Continuing Eligibility Monthly Income Scale, 161-170% FPL column, sizes 2 to 8. + al_ccsp_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, 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 index 665a5ed724b..1631f695217 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 @@ -414,3 +414,46 @@ # Homeless is NOT a §3.3.1 copay-waiver category (§3.3.1(iii) # unchecked); 105% FPL -> band [1.0001, 1.1001) -> $18/wk, not $0. al_ccsp_weekly_copay_per_child: 18 + +- name: A family of nine at 6,500 dollars pays the eight-or-more row's 30 dollars a week in June 2026. + period: 2026-06 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 15 + is_tax_unit_dependent: true + person4: + age: 13 + is_tax_unit_dependent: true + person5: + age: 11 + is_tax_unit_dependent: true + person6: + age: 9 + is_tax_unit_dependent: true + person7: + age: 7 + is_tax_unit_dependent: true + person8: + age: 5 + is_tax_unit_dependent: true + person9: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + # The June 2026 fact sheet's >=8 row charges 30 dollars from 6,319 to 6,769 dollars (141-150% FPL). + al_ccsp_countable_income: 6_500 + al_ccsp_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: + 2026: AL + output: + al_ccsp_weekly_copay_per_child: 30 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/copay/ga_caps_family_fee.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/copay/ga_caps_family_fee.yaml index ba693f91c25..03a595a003f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/copay/ga_caps_family_fee.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/copay/ga_caps_family_fee.yaml @@ -8,8 +8,8 @@ # strict "above X%" semantics while single_amount brackets use "at or above". # Weekly fee = floor(annual_income * rate / 52) # Monthly fee = weekly_fee * 52 / 12 -# Fee waived (§ 9.5.1) for: minor parents (age <= 17), -# children in DFCS custody, and income <= 10% FPL. +# Fee waived (§ 9.5.1) for minor parents (age <= 17) and income <= 10% FPL. A child in +# DFCS custody forms a family unit of one that owes no fee, which ga_caps pays apart. # # 2026 FPG family of 3: 15,960 + 5,680 * 2 = $27,320 # 2026 FPG family of 2: 15,960 + 5,680 = $21,640 @@ -454,7 +454,7 @@ # monthly fee = 20 * 52 / 12 = $86.67 ga_caps_family_fee: 86.67 -- name: Case 19, child in DFCS custody waives the family fee. +- name: Case 19, a child in DFCS custody leaves the family's unit, which still owes its fee. period: 2026-01 absolute_error_margin: 0.01 input: @@ -475,6 +475,9 @@ members: [person1, person2, person3] state_code: GA output: - # Same income/family as Case 1 (fee would be $173.33), - # but child in DFCS custody triggers the § 9.5.1 waiver -> $0. - ga_caps_family_fee: 0 + # The child in DFCS custody forms a family unit of one that owes no fee (CAPS/00-5, + # 5.4.1; Manual 9.5.1), so the family's own unit has two members. + # FPL ratio = 30,000 / 21,640 = 1.386 -> 7% rate + # weekly fee = floor(30,000 * 0.07 / 52) = floor(40.38) = $40 + # monthly fee = 40 * 52 / 12 = $173.33 + ga_caps_family_fee: 173.33 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/dfcs_custody.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/dfcs_custody.yaml new file mode 100644 index 00000000000..4e6b5428787 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/dfcs_custody.yaml @@ -0,0 +1,249 @@ +# GA CAPS children in DFCS custody. +# CAPS/00-5, 5.4.1: the State stands as the parent of each child in DFCS custody, and the +# child forms a family unit of one. CAPS/00-7, 7.5: foster parents need not meet the income +# or activity requirements, and Manual 9.5.1 assesses no family fee for these children. The +# family's own case covers its other children on its own tests. +# +# GA SMI 4-person at 2026-01 (October 2025 table): $110,736. New applicants in January 2026 +# face 40% of it: $30,121 for two, $37,208 for three. +# Center, full time, preschool, Zone 1: $221 a week, or 221 * 52 / 12 = $957.67 a month. + +- name: Each child in DFCS custody leaves the family's own unit. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 2 + is_in_foster_care: true + person4: + age: 6 + is_in_foster_care: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: GA + output: + ga_caps_family_size: 2 + ga_caps_dfcs_custody_child: [false, false, true, true] + +- name: The family's income test counts a family of two beside a child in DFCS custody, at the limit. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 2 + is_in_foster_care: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_510.08 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # 2,510.08 * 12 = 30,120.96, within $30,121 for two. + ga_caps_income_eligible: true + +- name: The family's income test counts a family of two beside a child in DFCS custody, over the limit. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 2 + is_in_foster_care: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_510.09 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # 2,510.09 * 12 = 30,121.08 exceeds $30,121 for two, though it falls within $37,208 + # for three. + ga_caps_income_eligible: false + +- name: A child in DFCS custody qualifies when the family's own case does not. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 0 + immigration_status: CITIZEN + person2: + age: 2 + immigration_status: CITIZEN + is_in_foster_care: true + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 9_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # The family of two fails its own income, activity and priority group tests. + ga_caps_income_eligible: false + ga_caps_activity_eligible: false + ga_caps_priority_group_eligible: false + ga_caps_family_eligible: false + ga_caps_dfcs_custody_child: [false, true, false] + ga_caps_eligible: true + +- name: CAPS pays only the DFCS child's care when the family's own case fails. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 0 + employment_income: 108_000 + immigration_status: CITIZEN + person2: + age: 4 + immigration_status: CITIZEN + is_in_foster_care: true + ga_caps_provider_type: CENTER + ga_caps_care_type: FULL_TIME + ga_caps_quality_rating: NONE + person3: + age: 4 + immigration_status: CITIZEN + ga_caps_provider_type: CENTER + ga_caps_care_type: FULL_TIME + ga_caps_quality_rating: NONE + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 24_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + county_str: FULTON_COUNTY_GA + output: + ga_caps_family_eligible: false + ga_caps_eligible: true + # Expenses of $2,000 a month split evenly: $1,000 for each child. + # DFCS child: min(1,000, 957.67) = $957.67, with no fee. The sibling gets nothing. + ga_caps: 957.67 + +- name: A child in DFCS custody doesn't waive the income test for a working, enrolled family. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + employment_income: 108_000 + immigration_status: CITIZEN + person2: + age: 4 + immigration_status: CITIZEN + is_in_foster_care: true + ga_caps_provider_type: CENTER + ga_caps_care_type: FULL_TIME + ga_caps_quality_rating: NONE + person3: + age: 4 + immigration_status: CITIZEN + ga_caps_provider_type: CENTER + ga_caps_care_type: FULL_TIME + ga_caps_quality_rating: NONE + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 24_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + county_str: FULTON_COUNTY_GA + output: + # The family of two passes the activity test and, as an enrolled family, needs no + # priority group, but $108,000 exceeds 85% of the median for two: + # 110,736 * 0.68 * 0.85 = 64,005.41, printed as $64,006. + ga_caps_income_eligible: false + ga_caps_activity_eligible: true + ga_caps_family_eligible: false + ga_caps_eligible: true + # Only the DFCS child's care: min(1,000, 957.67) = $957.67, with no fee. + ga_caps: 957.67 + +- name: The family's own case pays its fee while the DFCS child's care owes none. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + age: 4 + immigration_status: CITIZEN + is_in_foster_care: true + ga_caps_provider_type: CENTER + ga_caps_care_type: FULL_TIME + ga_caps_quality_rating: NONE + person3: + age: 4 + immigration_status: CITIZEN + ga_caps_provider_type: CENTER + ga_caps_care_type: FULL_TIME + ga_caps_quality_rating: NONE + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 24_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + county_str: FULTON_COUNTY_GA + output: + ga_caps_family_size: 2 + ga_caps_family_eligible: true + # FPL ratio for two = 24,000 / 21,640 = 1.109 -> 7% + # weekly fee = floor(24,000 * 0.07 / 52) = floor(32.31) = $32 + # monthly fee = 32 * 52 / 12 = $138.67 + ga_caps_family_fee: 138.67 + # Family's case: min(2,000 - 1,000, 957.67) - 138.67 = $819.00 + # DFCS child: min(1,000, 957.67) = $957.67 + ga_caps: 1_776.67 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_eligible.yaml index c2d75fa0596..fde18e265e3 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_eligible.yaml @@ -1,9 +1,12 @@ # GA CAPS family eligibility -# Requires: eligible child, income eligible, activity eligible, asset eligible +# Requires: eligible child, income eligible, activity eligible, asset eligible, +# and a priority group or current enrollment # -# GA SMI for 4-person household at 2026-01: $116,773.19 (uprated) -# Family of 2: 116,773.19 * 0.68 = $79,405.77 -# 50% SMI = $39,702.88 +# GA SMI 4-person at 2026-01 (October 2025 table): $110,736 +# New applicants in January 2026 face 40% of it, rounded up to the next dollar: +# Family of 2: 110,736 * 0.68 * 0.4 -> $30,121 +# Family of 3: 110,736 * 0.84 * 0.4 -> $37,208 +# Family of 4: 110,736 * 1.00 * 0.4 -> $44,295 - name: Case 1, eligible family with child under 13 and low income. period: 2026-01 @@ -24,6 +27,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true households: household: members: [person1, person2] @@ -31,7 +35,7 @@ output: ga_caps_eligible: true -- name: Case 2, ineligible due to income above 50 percent SMI. +- name: Case 2, ineligible due to income above the initial limit. period: 2026-01 input: people: @@ -49,12 +53,13 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true households: household: members: [person1, person2] state_code: GA output: - # income 40,000 > 39,702.88 (50% SMI for family of 2) -> ineligible + # income 40,000 > 30,121 (40% SMI for family of 2) -> ineligible ga_caps_eligible: false - name: Case 3, ineligible with no eligible child. @@ -71,6 +76,7 @@ spm_units: spm_unit: members: [person1] + ga_caps_priority_group_eligible: true households: household: members: [person1] @@ -97,6 +103,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_assets: 1_500_000 households: household: @@ -123,6 +130,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true households: household: members: [person1, person2] @@ -150,6 +158,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true households: household: members: [person1, person2] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_eligible_priority_groups.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_eligible_priority_groups.yaml new file mode 100644 index 00000000000..e3f3475d8d7 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_eligible_priority_groups.yaml @@ -0,0 +1,500 @@ +# GA CAPS eligibility with the priority group requirement. + +- name: New family earning $40,000 meets the October 2026 income limit but has no priority group. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_333.33 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + # CAPS/00-7, 7.3.1: new applicants outside a priority group are denied. + ga_caps_income_eligible: true + ga_caps_priority_group_eligible: false + ga_caps_eligible: false + +- name: Enrolled family at the same income keeps CAPS without a priority group. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_333.33 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + # CAPS/00-7, 7.3.1.3: no priority group at annual redetermination. + ga_caps_priority_group_eligible: false + ga_caps_eligible: true + +- name: New family at the same income with a child in Georgia's Pre-K qualifies. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + ga_caps_pre_k_enrolled: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_333.33 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_priority_group_eligible: true + ga_caps_eligible: true + +- name: A family earning $40,000 fails the January 2026 limit even with a priority group. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + immigration_status: CITIZEN + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + ga_caps_pre_k_enrolled: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_333.33 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_income_eligible: false + ga_caps_priority_group_eligible: true + ga_caps_eligible: false + +- name: Before August 2016 a family needed no priority group. + period: 2016-07 + input: + people: + person1: + age: + 2016: 30 + weekly_hours_worked_before_lsr: + 2016: 40 + immigration_status: + 2016: CITIZEN + person2: + age: + 2016: 2 + immigration_status: + 2016: CITIZEN + person3: + age: + 2016: 4 + immigration_status: + 2016: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + output: + ga_caps_eligible: true + +- name: From August 2016 the same family needs one. + period: 2016-08 + input: + people: + person1: + age: + 2016: 30 + weekly_hours_worked_before_lsr: + 2016: 40 + immigration_status: + 2016: CITIZEN + person2: + age: + 2016: 2 + immigration_status: + 2016: CITIZEN + person3: + age: + 2016: 4 + immigration_status: + 2016: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + output: + ga_caps_eligible: false + +- name: Grandparents raising grandchildren need no qualifying activity. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 0 + immigration_status: CITIZEN + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_grandparents_raising_grandchildren: true + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.13. + ga_caps_activity_eligible: true + ga_caps_eligible: true + +- name: Grandparents raising grandchildren still meet the income limit. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 0 + immigration_status: CITIZEN + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 5_000 + ga_caps_grandparents_raising_grandchildren: true + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_activity_eligible: true + ga_caps_income_eligible: false + ga_caps_eligible: false + +- name: Without the group the same family needs a qualifying activity. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 0 + immigration_status: CITIZEN + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + ga_caps_pre_k_enrolled: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_activity_eligible: false + ga_caps_eligible: false + +- name: June 2024, an enrolled family first admitted through Pre-K needs no priority group. + period: 2024-06 + input: + people: + person1: + age: + 2024: 30 + weekly_hours_worked_before_lsr: + 2024: 40 + immigration_status: + 2024: CITIZEN + person2: + age: + 2024: 2 + immigration_status: + 2024: CITIZEN + person3: + age: + 2024: 6 + immigration_status: + 2024: CITIZEN + ga_caps_pre_k_at_previous_determination: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + # CAPS/00-7, 7.3.1.3 exempts enrolled families at redetermination. + ga_caps_eligible: true + +- name: July 2024, an enrolled family first admitted through Pre-K needs a priority group. + period: 2024-07 + input: + people: + person1: + age: + 2024: 30 + weekly_hours_worked_before_lsr: + 2024: 40 + immigration_status: + 2024: CITIZEN + person2: + age: + 2024: 2 + immigration_status: + 2024: CITIZEN + person3: + age: + 2024: 6 + immigration_status: + 2024: CITIZEN + ga_caps_pre_k_at_previous_determination: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + # DECAL letter, July 1, 2024: families whose child attended Georgia's Pre-K at the + # initial application or previous determination must belong to a group at redetermination. + ga_caps_priority_group_eligible: false + ga_caps_eligible: false + +- name: July 2024, an enrolled family first admitted through Pre-K keeps CAPS through another group. + period: 2024-07 + input: + people: + person1: + age: + 2024: 30 + weekly_hours_worked_before_lsr: + 2024: 40 + immigration_status: + 2024: CITIZEN + person2: + age: + 2024: 2 + immigration_status: + 2024: CITIZEN + person3: + age: + 2024: 6 + immigration_status: + 2024: CITIZEN + ga_caps_pre_k_at_previous_determination: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_enrolled: true + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_eligible: true + +- name: July 2024, an enrolled family with no Pre-K child needs no priority group. + period: 2024-07 + input: + people: + person1: + age: + 2024: 30 + weekly_hours_worked_before_lsr: + 2024: 40 + immigration_status: + 2024: CITIZEN + person2: + age: + 2024: 2 + immigration_status: + 2024: CITIZEN + person3: + age: + 2024: 6 + immigration_status: + 2024: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_eligible: true + +- name: October 2025 reads October 1, so an enrolled family first admitted through Pre-K still needs a group. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + weekly_hours_worked_before_lsr: + 2025: 40 + immigration_status: + 2025: CITIZEN + person2: + age: + 2025: 2 + immigration_status: + 2025: CITIZEN + person3: + age: + 2025: 6 + immigration_status: + 2025: CITIZEN + ga_caps_pre_k_at_previous_determination: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + # DECAL letter, October 6, 2025 removes the requirement; the model applies it from November. + ga_caps_eligible: false + +- name: November 2025, an enrolled family first admitted through Pre-K needs no priority group again. + period: 2025-11 + input: + people: + person1: + age: + 2025: 30 + weekly_hours_worked_before_lsr: + 2025: 40 + immigration_status: + 2025: CITIZEN + person2: + age: + 2025: 2 + immigration_status: + 2025: CITIZEN + person3: + age: + 2025: 6 + immigration_status: + 2025: CITIZEN + ga_caps_pre_k_at_previous_determination: true + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + ga_caps_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible.yaml index 7f085dc5cd1..1a96a4a5673 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible.yaml @@ -1,13 +1,13 @@ # GA CAPS income eligibility -# Initial (not enrolled): income <= 50% SMI -# Ongoing (enrolled): income <= 85% SMI +# Initial (not enrolled) in January 2026: income <= 40% SMI, rounded up +# Ongoing (enrolled): income <= 85% SMI, rounded up # # GA SMI for 4-person household at 2026-01 (2025-10-01 entry): $110,736 # Family of 2: 110,736 * 0.68 = $75,300.48 -# 50% SMI = $37,650.24 -# 85% SMI = $64,005.41 +# 40% SMI = $30,120.19 -> $30,121 +# 85% SMI = $64,005.41 -> $64,006 -- name: Case 1, new applicant income below 50 percent SMI. +- name: Case 1, new applicant income below 40 percent SMI. period: 2026-01 input: people: @@ -24,10 +24,10 @@ members: [person1, person2] state_code: GA output: - # income 30,000 <= 37,650.24 (50% SMI for family of 2) -> eligible + # income 30,000 <= 30,121 (40% SMI for family of 2) -> eligible ga_caps_income_eligible: true -- name: Case 2, new applicant income above 50 percent SMI. +- name: Case 2, new applicant income above 40 percent SMI. period: 2026-01 input: people: @@ -44,10 +44,10 @@ members: [person1, person2] state_code: GA output: - # income 40,000 > 37,650.24 (50% SMI for family of 2) -> ineligible + # income 40,000 > 30,121 (40% SMI for family of 2) -> ineligible ga_caps_income_eligible: false -- name: Case 3, enrolled family income between 50 and 85 percent SMI. +- name: Case 3, enrolled family income between 40 and 85 percent SMI. period: 2026-01 input: people: @@ -65,7 +65,7 @@ members: [person1, person2] state_code: GA output: - # enrolled: income 50,000 <= 64,005.41 (85% SMI) -> eligible + # enrolled: income 50,000 <= 64,006 (85% SMI) -> eligible ga_caps_income_eligible: true - name: Case 4, enrolled family income above 85 percent SMI. @@ -86,10 +86,10 @@ members: [person1, person2] state_code: GA output: - # enrolled: income 68,000 > 64,005.41 (85% SMI) -> ineligible + # enrolled: income 68,000 > 64,006 (85% SMI) -> ineligible ga_caps_income_eligible: false -- name: Case 5, non-enrolled family between 50 and 85 percent SMI. +- name: Case 5, non-enrolled family between 40 and 85 percent SMI. period: 2026-01 input: people: @@ -107,7 +107,7 @@ members: [person1, person2] state_code: GA output: - # not enrolled: income 50,000 > 37,650.24 (50% SMI) -> ineligible + # not enrolled: income 50,000 > 30,121 (40% SMI) -> ineligible ga_caps_income_eligible: false - name: Case 6, zero income family is eligible. @@ -130,18 +130,18 @@ # Additional family sizes for boundary tests: # Family of 3: 110,736 * 0.84 = $93,018.24 -# 50% SMI = $46,509.12; 85% SMI = $79,065.51 +# 40% SMI -> $37,208; 85% SMI -> $79,066 # Family of 5: 110,736 * 1.16 = $128,453.76 -# 50% SMI = $64,226.88; 85% SMI = $109,185.70 +# 40% SMI -> $51,382; 85% SMI -> $109,186 -- name: Case 7, income exactly at 50 percent SMI threshold for family of 2. +- name: Case 7, income exactly at 40 percent SMI threshold for family of 2. period: 2026-01 input: people: person1: age: 30 - # 50% SMI for family of 2 is $37,650.24/yr - employment_income: 37_650 + # 40% SMI for family of 2 rounds up to $30,121/yr + employment_income: 30_121 person2: age: 5 spm_units: @@ -152,16 +152,16 @@ members: [person1, person2] state_code: GA output: - # income 37,650 <= 37,650.24 -> eligible (just at threshold) + # income 30,121 <= 30,121 -> eligible (at threshold) ga_caps_income_eligible: true -- name: Case 8, income one dollar above 50 percent SMI threshold. +- name: Case 8, income one dollar above 40 percent SMI threshold. period: 2026-01 input: people: person1: age: 30 - employment_income: 37_651 + employment_income: 30_122 person2: age: 5 spm_units: @@ -172,7 +172,7 @@ members: [person1, person2] state_code: GA output: - # income 37,651 > 37,650.24 -> ineligible + # income 30,122 > 30,121 -> ineligible ga_caps_income_eligible: false - name: Case 9, enrolled income exactly at 85 percent SMI threshold. @@ -181,7 +181,7 @@ people: person1: age: 30 - employment_income: 64_005 + employment_income: 64_006 person2: age: 5 spm_units: @@ -193,7 +193,7 @@ members: [person1, person2] state_code: GA output: - # enrolled: income 64,005 <= 64,005.41 -> eligible + # enrolled: income 64,006 <= 64,006 -> eligible ga_caps_income_eligible: true - name: Case 10, enrolled income one dollar above 85 percent SMI. @@ -202,7 +202,7 @@ people: person1: age: 30 - employment_income: 64_006 + employment_income: 64_007 person2: age: 5 spm_units: @@ -214,7 +214,7 @@ members: [person1, person2] state_code: GA output: - # enrolled: income 64,006 > 64,005.41 -> ineligible + # enrolled: income 64,007 > 64,006 -> ineligible ga_caps_income_eligible: false - name: Case 11, very high income family ineligible. @@ -236,13 +236,13 @@ output: ga_caps_income_eligible: false -- name: Case 12, larger family of 5 at 50 percent SMI threshold. +- name: Case 12, larger family of 5 at 40 percent SMI threshold. period: 2026-01 input: people: person1: age: 35 - employment_income: 64_226 + employment_income: 51_382 person2: age: 30 person3: @@ -259,8 +259,8 @@ members: [person1, person2, person3, person4, person5] state_code: GA output: - # 50% SMI family of 5 = $64,226.88 - # income 64,226 <= 64,226.88 -> eligible + # 40% SMI family of 5 rounds up to $51,382 + # income 51,382 <= 51,382 -> eligible ga_caps_income_eligible: true - name: Case 13, larger family of 5 one dollar over threshold. @@ -269,7 +269,7 @@ people: person1: age: 35 - employment_income: 64_227 + employment_income: 51_383 person2: age: 30 person3: @@ -286,8 +286,8 @@ members: [person1, person2, person3, person4, person5] state_code: GA output: - # 50% SMI family of 5 = $64,226.88 - # income 64,227 > 64,226.88 -> ineligible + # 40% SMI family of 5 rounds up to $51,382 + # income 51,383 > 51,382 -> ineligible ga_caps_income_eligible: false - name: Case 14, enrolled family of 3 at ongoing threshold. @@ -296,7 +296,7 @@ people: person1: age: 30 - employment_income: 79_065 + employment_income: 79_066 person2: age: 28 person3: @@ -310,8 +310,8 @@ members: [person1, person2, person3] state_code: GA output: - # 85% SMI family of 3 = $79,065.51 - # enrolled: income 79,065 <= 79,065.51 -> eligible + # 85% SMI family of 3 rounds up to $79,066 + # enrolled: income 79,066 <= 79,066 -> eligible ga_caps_income_eligible: true - name: Case 15, multiple income sources combined. @@ -320,7 +320,7 @@ people: person1: age: 30 - employment_income: 25_000 + employment_income: 20_000 self_employment_income: 10_000 person2: age: 5 @@ -332,5 +332,761 @@ members: [person1, person2] state_code: GA output: - # total income = 25,000 + 10,000 = 35,000 <= 37,650.24 -> eligible + # total income = 20,000 + 10,000 = 30,000 <= 30,121 -> eligible ga_caps_income_eligible: true + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. + +- name: Appendix A's initial limits effective October 5, 2026 hold at sizes 1 to 14 in November 2026. + period: 2026-11 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + p25: + age: + 2026: 30 + p26: + age: + 2026: 30 + p27: + age: + 2026: 30 + p28: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + ga_caps_countable_income: 2_494.25 + ga_caps_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 1 + ga_caps_countable_income: 2_494.34 + ga_caps_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 2 + ga_caps_countable_income: 3_261.75 + ga_caps_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 2 + ga_caps_countable_income: 3_261.84 + ga_caps_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 3 + ga_caps_countable_income: 4_029.16 + ga_caps_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 3 + ga_caps_countable_income: 4_029.25 + ga_caps_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 4 + ga_caps_countable_income: 4_796.58 + ga_caps_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 4 + ga_caps_countable_income: 4_796.67 + ga_caps_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 5 + ga_caps_countable_income: 5_564.08 + ga_caps_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 5 + ga_caps_countable_income: 5_564.17 + ga_caps_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 6 + ga_caps_countable_income: 6_331.50 + ga_caps_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 6 + ga_caps_countable_income: 6_331.59 + ga_caps_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 7 + ga_caps_countable_income: 6_475.41 + ga_caps_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 7 + ga_caps_countable_income: 6_475.50 + ga_caps_enrolled: false + u15: + members: [p15] + spm_unit_size: + 2026: 8 + ga_caps_countable_income: 6_619.33 + ga_caps_enrolled: false + u16: + members: [p16] + spm_unit_size: + 2026: 8 + ga_caps_countable_income: 6_619.42 + ga_caps_enrolled: false + u17: + members: [p17] + spm_unit_size: + 2026: 9 + ga_caps_countable_income: 6_763.25 + ga_caps_enrolled: false + u18: + members: [p18] + spm_unit_size: + 2026: 9 + ga_caps_countable_income: 6_763.34 + ga_caps_enrolled: false + u19: + members: [p19] + spm_unit_size: + 2026: 10 + ga_caps_countable_income: 6_907.08 + ga_caps_enrolled: false + u20: + members: [p20] + spm_unit_size: + 2026: 10 + ga_caps_countable_income: 6_907.17 + ga_caps_enrolled: false + u21: + members: [p21] + spm_unit_size: + 2026: 11 + ga_caps_countable_income: 7_051 + ga_caps_enrolled: false + u22: + members: [p22] + spm_unit_size: + 2026: 11 + ga_caps_countable_income: 7_051.09 + ga_caps_enrolled: false + u23: + members: [p23] + spm_unit_size: + 2026: 12 + ga_caps_countable_income: 7_194.91 + ga_caps_enrolled: false + u24: + members: [p24] + spm_unit_size: + 2026: 12 + ga_caps_countable_income: 7_195 + ga_caps_enrolled: false + u25: + members: [p25] + spm_unit_size: + 2026: 13 + ga_caps_countable_income: 7_338.83 + ga_caps_enrolled: false + u26: + members: [p26] + spm_unit_size: + 2026: 13 + ga_caps_countable_income: 7_338.92 + ga_caps_enrolled: false + u27: + members: [p27] + spm_unit_size: + 2026: 14 + ga_caps_countable_income: 7_482.75 + ga_caps_enrolled: false + u28: + members: [p28] + spm_unit_size: + 2026: 14 + ga_caps_countable_income: 7_482.84 + ga_caps_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: GA + h2: + members: [p2] + state_code: + 2026: GA + h3: + members: [p3] + state_code: + 2026: GA + h4: + members: [p4] + state_code: + 2026: GA + h5: + members: [p5] + state_code: + 2026: GA + h6: + members: [p6] + state_code: + 2026: GA + h7: + members: [p7] + state_code: + 2026: GA + h8: + members: [p8] + state_code: + 2026: GA + h9: + members: [p9] + state_code: + 2026: GA + h10: + members: [p10] + state_code: + 2026: GA + h11: + members: [p11] + state_code: + 2026: GA + h12: + members: [p12] + state_code: + 2026: GA + h13: + members: [p13] + state_code: + 2026: GA + h14: + members: [p14] + state_code: + 2026: GA + h15: + members: [p15] + state_code: + 2026: GA + h16: + members: [p16] + state_code: + 2026: GA + h17: + members: [p17] + state_code: + 2026: GA + h18: + members: [p18] + state_code: + 2026: GA + h19: + members: [p19] + state_code: + 2026: GA + h20: + members: [p20] + state_code: + 2026: GA + h21: + members: [p21] + state_code: + 2026: GA + h22: + members: [p22] + state_code: + 2026: GA + h23: + members: [p23] + state_code: + 2026: GA + h24: + members: [p24] + state_code: + 2026: GA + h25: + members: [p25] + state_code: + 2026: GA + h26: + members: [p26] + state_code: + 2026: GA + h27: + members: [p27] + state_code: + 2026: GA + h28: + members: [p28] + state_code: + 2026: GA + output: + # Annual tops as monthly income: the top rounded down to the cent, then a + # dollar more a year rounded up to the cent. The chart takes effect October 5, + # 2026, so the model applies it from November 2026. + ga_caps_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: Appendix A's ongoing limits effective October 5, 2026 hold at sizes 1 to 14 in November 2026. + period: 2026-11 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + p25: + age: + 2026: 30 + p26: + age: + 2026: 30 + p27: + age: + 2026: 30 + p28: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + ga_caps_countable_income: 4_240.25 + ga_caps_enrolled: true + u2: + members: [p2] + spm_unit_size: + 2026: 1 + ga_caps_countable_income: 4_240.34 + ga_caps_enrolled: true + u3: + members: [p3] + spm_unit_size: + 2026: 2 + ga_caps_countable_income: 5_544.91 + ga_caps_enrolled: true + u4: + members: [p4] + spm_unit_size: + 2026: 2 + ga_caps_countable_income: 5_545 + ga_caps_enrolled: true + u5: + members: [p5] + spm_unit_size: + 2026: 3 + ga_caps_countable_income: 6_849.58 + ga_caps_enrolled: true + u6: + members: [p6] + spm_unit_size: + 2026: 3 + ga_caps_countable_income: 6_849.67 + ga_caps_enrolled: true + u7: + members: [p7] + spm_unit_size: + 2026: 4 + ga_caps_countable_income: 8_154.25 + ga_caps_enrolled: true + u8: + members: [p8] + spm_unit_size: + 2026: 4 + ga_caps_countable_income: 8_154.34 + ga_caps_enrolled: true + u9: + members: [p9] + spm_unit_size: + 2026: 5 + ga_caps_countable_income: 9_458.91 + ga_caps_enrolled: true + u10: + members: [p10] + spm_unit_size: + 2026: 5 + ga_caps_countable_income: 9_459 + ga_caps_enrolled: true + u11: + members: [p11] + spm_unit_size: + 2026: 6 + ga_caps_countable_income: 10_763.58 + ga_caps_enrolled: true + u12: + members: [p12] + spm_unit_size: + 2026: 6 + ga_caps_countable_income: 10_763.67 + ga_caps_enrolled: true + u13: + members: [p13] + spm_unit_size: + 2026: 7 + ga_caps_countable_income: 11_008.16 + ga_caps_enrolled: true + u14: + members: [p14] + spm_unit_size: + 2026: 7 + ga_caps_countable_income: 11_008.25 + ga_caps_enrolled: true + u15: + members: [p15] + spm_unit_size: + 2026: 8 + ga_caps_countable_income: 11_252.83 + ga_caps_enrolled: true + u16: + members: [p16] + spm_unit_size: + 2026: 8 + ga_caps_countable_income: 11_252.92 + ga_caps_enrolled: true + u17: + members: [p17] + spm_unit_size: + 2026: 9 + ga_caps_countable_income: 11_497.41 + ga_caps_enrolled: true + u18: + members: [p18] + spm_unit_size: + 2026: 9 + ga_caps_countable_income: 11_497.50 + ga_caps_enrolled: true + u19: + members: [p19] + spm_unit_size: + 2026: 10 + ga_caps_countable_income: 11_742.08 + ga_caps_enrolled: true + u20: + members: [p20] + spm_unit_size: + 2026: 10 + ga_caps_countable_income: 11_742.17 + ga_caps_enrolled: true + u21: + members: [p21] + spm_unit_size: + 2026: 11 + ga_caps_countable_income: 11_986.66 + ga_caps_enrolled: true + u22: + members: [p22] + spm_unit_size: + 2026: 11 + ga_caps_countable_income: 11_986.75 + ga_caps_enrolled: true + u23: + members: [p23] + spm_unit_size: + 2026: 12 + ga_caps_countable_income: 12_231.33 + ga_caps_enrolled: true + u24: + members: [p24] + spm_unit_size: + 2026: 12 + ga_caps_countable_income: 12_231.42 + ga_caps_enrolled: true + u25: + members: [p25] + spm_unit_size: + 2026: 13 + ga_caps_countable_income: 12_475.91 + ga_caps_enrolled: true + u26: + members: [p26] + spm_unit_size: + 2026: 13 + ga_caps_countable_income: 12_476 + ga_caps_enrolled: true + u27: + members: [p27] + spm_unit_size: + 2026: 14 + ga_caps_countable_income: 12_720.58 + ga_caps_enrolled: true + u28: + members: [p28] + spm_unit_size: + 2026: 14 + ga_caps_countable_income: 12_720.67 + ga_caps_enrolled: true + households: + h1: + members: [p1] + state_code: + 2026: GA + h2: + members: [p2] + state_code: + 2026: GA + h3: + members: [p3] + state_code: + 2026: GA + h4: + members: [p4] + state_code: + 2026: GA + h5: + members: [p5] + state_code: + 2026: GA + h6: + members: [p6] + state_code: + 2026: GA + h7: + members: [p7] + state_code: + 2026: GA + h8: + members: [p8] + state_code: + 2026: GA + h9: + members: [p9] + state_code: + 2026: GA + h10: + members: [p10] + state_code: + 2026: GA + h11: + members: [p11] + state_code: + 2026: GA + h12: + members: [p12] + state_code: + 2026: GA + h13: + members: [p13] + state_code: + 2026: GA + h14: + members: [p14] + state_code: + 2026: GA + h15: + members: [p15] + state_code: + 2026: GA + h16: + members: [p16] + state_code: + 2026: GA + h17: + members: [p17] + state_code: + 2026: GA + h18: + members: [p18] + state_code: + 2026: GA + h19: + members: [p19] + state_code: + 2026: GA + h20: + members: [p20] + state_code: + 2026: GA + h21: + members: [p21] + state_code: + 2026: GA + h22: + members: [p22] + state_code: + 2026: GA + h23: + members: [p23] + state_code: + 2026: GA + h24: + members: [p24] + state_code: + 2026: GA + h25: + members: [p25] + state_code: + 2026: GA + h26: + members: [p26] + state_code: + 2026: GA + h27: + members: [p27] + state_code: + 2026: GA + h28: + members: [p28] + state_code: + 2026: GA + output: + # Annual tops as monthly income: the top rounded down to the cent, then a + # dollar more a year rounded up to the cent. The chart takes effect October 5, + # 2026, so the model applies it from November 2026. + ga_caps_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible_by_date.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible_by_date.yaml new file mode 100644 index 00000000000..b932fb94a6c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible_by_date.yaml @@ -0,0 +1,1092 @@ +# GA CAPS income limits by date. +# DECAL's letters date each change. A monthly variable reads the parameter at the first day of +# the month, so a change after the first applies from the next month. Each chart also dates +# the median income table it takes up, which smi_year_lag carries. + +- name: September 2019, 50 percent for four, at the limit. + period: 2019-09 + input: + people: + person1: + age: + 2019: 30 + person2: + age: + 2019: 5 + person3: + age: + 2019: 5 + person4: + age: + 2019: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 3_050 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2019: GA + output: + # DECAL webinar, September 24, 2019: $36,601 for four before October 2019. + ga_caps_income_eligible: true +- name: September 2019, 50 percent for four, over the limit. + period: 2019-09 + input: + people: + person1: + age: + 2019: 30 + person2: + age: + 2019: 5 + person3: + age: + 2019: 5 + person4: + age: + 2019: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 3_051 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2019: GA + output: + ga_caps_income_eligible: false +- name: October 2019, 50 percent for four on the new median income table, at the limit. + period: 2019-10 + input: + people: + person1: + age: + 2019: 30 + person2: + age: + 2019: 5 + person3: + age: + 2019: 5 + person4: + age: + 2019: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 3_175.25 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2019: GA + output: + # DECAL webinar, September 24, 2019: $38,103 for four in October 2019. + ga_caps_income_eligible: true +- name: October 2019, 50 percent for four on the new median income table, over the limit. + period: 2019-10 + input: + people: + person1: + age: + 2019: 30 + person2: + age: + 2019: 5 + person3: + age: + 2019: 5 + person4: + age: + 2019: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 3_176 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2019: GA + output: + ga_caps_income_eligible: false +- name: October 2021, 50 percent for four, at the limit. + period: 2021-10 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + person4: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 3_535.5 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2021: GA + output: + # DECAL letter, October 21, 2021: $42,426 for four before the waiver. + ga_caps_income_eligible: true +- name: October 2021, 50 percent for four, over the limit. + period: 2021-10 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + person4: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 3_536 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2021: GA + output: + ga_caps_income_eligible: false +- name: November 2021, 85 percent for four, at the limit. + period: 2021-11 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + person4: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 6_010.33 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2021: GA + output: + # DECAL letter, October 21, 2021: $72,124 for four from November 1, 2021. + ga_caps_income_eligible: true +- name: November 2021, 85 percent for four, over the limit. + period: 2021-11 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + person4: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 6_011 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2021: GA + output: + ga_caps_income_eligible: false +- name: October 2021, 50 percent for three, at the limit. + period: 2021-10 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_969 + households: + household: + members: [person1, person2, person3] + state_code: + 2021: GA + output: + # Urban Institute CCDF tables print $2,969 for three in October 2021. + ga_caps_income_eligible: true +- name: October 2021, 50 percent for three, over the limit. + period: 2021-10 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_970 + households: + household: + members: [person1, person2, person3] + state_code: + 2021: GA + output: + ga_caps_income_eligible: false +- name: November 2021, 85 percent for three, at the limit. + period: 2021-11 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 5_048 + households: + household: + members: [person1, person2, person3] + state_code: + 2021: GA + output: + ga_caps_income_eligible: true +- name: November 2021, 85 percent for three, over the limit. + period: 2021-11 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 5_049 + households: + household: + members: [person1, person2, person3] + state_code: + 2021: GA + output: + ga_caps_income_eligible: false +- name: October 2022, 85 percent for three, at the limit. + period: 2022-10 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 5_351 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: GA + output: + # Urban Institute CCDF tables print $5,351 for three in October 2022. + ga_caps_income_eligible: true +- name: October 2022, 85 percent for three, over the limit. + period: 2022-10 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 5_352 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: GA + output: + ga_caps_income_eligible: false +- name: December 2022 reads December 1, so 85 percent still applies. + period: 2022-12 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 5_351 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: GA + output: + # DECAL letter, December 19, 2022: the waiver ended December 15, 2022. + ga_caps_income_eligible: true +- name: January 2023, back to 50 percent for three, at the limit. + period: 2023-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_147 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_income_eligible: true +- name: January 2023, back to 50 percent for three, over the limit. + period: 2023-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_148 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_income_eligible: false +- name: August 2024, 50 percent for three, at the limit. + period: 2024-08 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_333.33 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_income_eligible: true +- name: August 2024, 50 percent for three, over the limit. + period: 2024-08 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_334 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_income_eligible: false +- name: September 2024, 30 percent for three on the fiscal year 2025 median income table, at the limit. + period: 2024-09 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_223.83 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + # DECAL letter, September 3, 2024: 50% to 30% from September 1, 2024. Appendix A, + # effective September 1, 2024, prints $26,686 for three on the fiscal year 2025 + # median income table. + ga_caps_income_eligible: true +- name: September 2024, 30 percent for three on the fiscal year 2025 median income table, over the limit. + period: 2024-09 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_223.84 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_income_eligible: false +- name: October 2024, 30 percent for three on the new median income table, at the limit. + period: 2024-10 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_223 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_income_eligible: true +- name: October 2024, 30 percent for three on the new median income table, over the limit. + period: 2024-10 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_224 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_income_eligible: false +- name: October 2025 reads October 1, so the September 2024 chart still applies, at the limit. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_223.83 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + # The chart effective March 1, 2025 still prints $26,686 for three until October 6. + ga_caps_income_eligible: true +- name: October 2025 reads October 1, so the September 2024 chart still applies, over the limit. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_223.84 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + ga_caps_income_eligible: false +- name: November 2025, 40 percent for three, at the limit. + period: 2025-11 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_100.6 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + # DECAL letter, October 6, 2025: 30% to 40%. The CCDF plan prints $3,101 a month for three, + # which rounds $37,208 a year divided by 12. Manual 8.8.4 compares income times 12 with the + # annual chart, so $3,101 a month fails. + ga_caps_income_eligible: true +- name: November 2025, 40 percent for three, over the limit. + period: 2025-11 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_101 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + ga_caps_income_eligible: false +- name: A family of three earning $40,000 fails in January 2026. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_333.33 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_income_eligible: false +- name: March 2026 reads March 1, so 40 percent still applies. + period: 2026-03 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_101 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_income_eligible: false +- name: April 2026, 50 percent for three, at the limit. + period: 2026-04 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_875 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + # DECAL letter, March 2, 2026: 40% to 50% from March 2, 2026. + ga_caps_income_eligible: true +- name: April 2026, 50 percent for three, over the limit. + period: 2026-04 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_876 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_income_eligible: false +- name: October 2026 reads October 1, so the March 2026 chart still applies, at the limit. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_875 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + # The chart effective March 2, 2026 prints $46,510 for three on the fiscal year 2026 + # median income table until October 5. + ga_caps_income_eligible: true + +- name: October 2026 reads October 1, so the March 2026 chart still applies, over the limit. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_876 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_income_eligible: false + +- name: October 2026, 85 percent for an enrolled family of three on the March 2026 chart, at the limit. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 6_588.83 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + # The chart effective March 2, 2026 prints $79,066 for three. + ga_caps_income_eligible: true + +- name: October 2026, 85 percent for an enrolled family of three on the March 2026 chart, over the limit. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 6_588.84 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_income_eligible: false + +- name: November 2026, 50 percent for three, at the limit. + period: 2026-11 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 4_029.16 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + # Appendix A, effective October 5, 2026, prints $48,350 for three. The model + # applies it at the first month that starts after October 5. + ga_caps_income_eligible: true +- name: November 2026, 50 percent for three, over the limit. + period: 2026-11 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 4_029.25 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_income_eligible: false +- name: November 2026, 50 percent for two, at the limit. + period: 2026-11 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2] + ga_caps_countable_income: 3_261.75 + households: + household: + members: [person1, person2] + state_code: + 2026: GA + output: + # Appendix A prints $39,141 for two. + ga_caps_income_eligible: true +- name: November 2026, 50 percent for two, over the limit. + period: 2026-11 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2] + ga_caps_countable_income: 3_262 + households: + household: + members: [person1, person2] + state_code: + 2026: GA + output: + ga_caps_income_eligible: false +- name: November 2026, 50 percent for six, at the limit. + period: 2026-11 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + person4: + age: + 2026: 5 + person5: + age: + 2026: 5 + person6: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + ga_caps_countable_income: 6_331.5 + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: GA + output: + # Appendix A prints $75,978 for six. + ga_caps_income_eligible: true +- name: November 2026, 50 percent for six, over the limit. + period: 2026-11 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + person4: + age: + 2026: 5 + person5: + age: + 2026: 5 + person6: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + ga_caps_countable_income: 6_332 + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: GA + output: + ga_caps_income_eligible: false +- name: November 2026, 85 percent for an enrolled family of three, at the limit. + period: 2026-11 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 6_849.58 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + # Appendix A prints $82,195 for three. + ga_caps_income_eligible: true +- name: November 2026, 85 percent for an enrolled family of three, over the limit. + period: 2026-11 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 6_850 + ga_caps_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_priority_group_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_priority_group_eligible.yaml new file mode 100644 index 00000000000..7fc11f279a1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_priority_group_eligible.yaml @@ -0,0 +1,1985 @@ +# GA CAPS priority groups (CAPS/00-7). +# New applicants must belong to one. The very low income group tests income against a dated +# share of the poverty guideline. + +- name: Family with income over the very low income limit and no group. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_priority_group_eligible: false + +- name: Child under court-ordered supervision. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_under_court_supervision: true + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.4. + ga_caps_priority_group_eligible: true + +- name: Child receiving or needing protective services. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + receives_or_needs_protective_services: true + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.4 and 7.15. + ga_caps_priority_group_eligible: true + +- name: A child in DFCS custody doesn't place the rest of the family in a priority group. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_in_foster_care: true + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-5, 5.4.1: the child forms a family unit of one, which + # ga_caps_dfcs_custody_child serves (CAPS/00-7, 7.5). + ga_caps_priority_group_eligible: false + ga_caps_dfcs_custody_child: [false, true, false] + +- name: Child with a disability. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_disabled: true + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.7. + ga_caps_priority_group_eligible: true + +- name: Child with a developmental delay. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + has_developmental_delay: true + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.7. + ga_caps_priority_group_eligible: true + +- name: A parent's disability does not form a group. + period: 2026-01 + input: + people: + person1: + age: 30 + is_disabled: true + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_priority_group_eligible: false + +- name: A 25-year-old with a disability is not an eligible child, so forms no group. + period: 2026-01 + input: + people: + person1: + age: 50 + person2: + age: 25 + is_disabled: true + spm_units: + spm_unit: + members: [person1, person2] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2] + state_code: GA + output: + ga_caps_priority_group_eligible: false + +- name: Child enrolled in Georgia's Pre-K. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + ga_caps_pre_k_enrolled: true + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.8. + ga_caps_priority_group_eligible: true + +- name: Parent aged 20. + period: 2026-01 + input: + people: + person1: + age: 20 + person2: + age: 2 + person3: + age: 1 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.14: minor parents aged 20 and younger. + ga_caps_priority_group_eligible: true + +- name: Parent aged 21. + period: 2026-01 + input: + people: + person1: + age: 21 + person2: + age: 2 + person3: + age: 1 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_priority_group_eligible: false + +- name: Full-time student parent. + period: 2026-01 + input: + people: + person1: + age: 30 + is_full_time_student: true + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.16. + ga_caps_priority_group_eligible: true + +- name: Student parent before the group began. + period: 2022-04 + input: + people: + person1: + age: + 2022: 30 + is_full_time_student: + 2022: true + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: GA + output: + ga_caps_priority_group_eligible: false + +- name: Student parent from the month the group began. + period: 2022-05 + input: + people: + person1: + age: + 2022: 30 + is_full_time_student: + 2022: true + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: GA + output: + # CAPS/00-7 revision history: added May 1, 2022. + ga_caps_priority_group_eligible: true + +- name: Family in TANF. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.9. + ga_caps_priority_group_eligible: true + +- name: Family without fixed, regular and adequate housing. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: GA + is_homeless: true + output: + # CAPS/00-7, 7.11. + ga_caps_priority_group_eligible: true + +- name: Family experiencing domestic violence. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + ga_caps_domestic_violence: true + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.6. + ga_caps_priority_group_eligible: true + +- name: Family after a natural disaster. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + ga_caps_natural_disaster: true + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.10. + ga_caps_priority_group_eligible: true + +- name: Grandparents raising grandchildren. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 3_000 + ga_caps_grandparents_raising_grandchildren: true + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # CAPS/00-7, 7.13. + ga_caps_priority_group_eligible: true + +- name: Before August 2016 Georgia required no group. + period: 2016-07 + input: + people: + person1: + age: + 2016: 30 + person2: + age: + 2016: 5 + person3: + age: + 2016: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + output: + ga_caps_priority_group_eligible: true + +- name: From August 2016 Georgia required a group. + period: 2016-08 + input: + people: + person1: + age: + 2016: 30 + person2: + age: + 2016: 5 + person3: + age: + 2016: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + output: + # DECAL funding Q&A: new applicants from August 1, 2016 must belong to a priority group. + ga_caps_priority_group_eligible: false + +- name: Family after a natural disaster, August 2016, in a group from the start. + period: 2016-08 + input: + people: + person1: + age: + 2016: 30 + person2: + age: + 2016: 5 + person3: + age: + 2016: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_natural_disaster: true + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + output: + # DECAL funding Q&A: natural disaster victims form a group from August 1, 2016. + ga_caps_priority_group_eligible: true + +- name: Homeless family, September 2016, before the group began. + period: 2016-09 + input: + people: + person1: + age: + 2016: 30 + person2: + age: + 2016: 5 + person3: + age: + 2016: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + is_homeless: + 2016: true + output: + # DECAL funding Q&A: the homeless, domestic violence and very low income groups start October 1, 2016. + ga_caps_priority_group_eligible: false + +- name: Homeless family, October 2016, from the month the group began. + period: 2016-10 + input: + people: + person1: + age: + 2016: 30 + person2: + age: + 2016: 5 + person3: + age: + 2016: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + is_homeless: + 2016: true + output: + ga_caps_priority_group_eligible: true + +- name: Family experiencing domestic violence, September 2016, before the group began. + period: 2016-09 + input: + people: + person1: + age: + 2016: 30 + person2: + age: + 2016: 5 + person3: + age: + 2016: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_domestic_violence: true + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + output: + # DECAL funding Q&A: the homeless, domestic violence and very low income groups start October 1, 2016. + ga_caps_priority_group_eligible: false + +- name: Family experiencing domestic violence, October 2016, from the month the group began. + period: 2016-10 + input: + people: + person1: + age: + 2016: 30 + person2: + age: + 2016: 5 + person3: + age: + 2016: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_000 + ga_caps_domestic_violence: true + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + output: + ga_caps_priority_group_eligible: true + +- name: Very low income, September 2016, before the group began. + period: 2016-09 + input: + people: + person1: + age: + 2016: 30 + person2: + age: + 2016: 5 + person3: + age: + 2016: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 500 + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + output: + # DECAL funding Q&A: the homeless, domestic violence and very low income groups start October 1, 2016. + # 50% of the 2016 guideline is $10,100 for three. + ga_caps_priority_group_eligible: false + +- name: Very low income, October 2016, from the month the group began. + period: 2016-10 + input: + people: + person1: + age: + 2016: 30 + person2: + age: + 2016: 5 + person3: + age: + 2016: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 500 + households: + household: + members: [person1, person2, person3] + state_code: + 2016: GA + output: + ga_caps_priority_group_eligible: true + +- name: Very low income, May 2018 reads May 1, so 50 percent, at the limit. + period: 2018-05 + input: + people: + person1: + age: + 2018: 30 + person2: + age: + 2018: 5 + person3: + age: + 2018: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 865 + households: + household: + members: [person1, person2, person3] + state_code: + 2018: GA + output: + ga_caps_priority_group_eligible: true + +- name: Very low income, May 2018 reads May 1, so 50 percent, over the limit. + period: 2018-05 + input: + people: + person1: + age: + 2018: 30 + person2: + age: + 2018: 5 + person3: + age: + 2018: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 866 + households: + household: + members: [person1, person2, person3] + state_code: + 2018: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, June 2018, 100 percent, at the limit. + period: 2018-06 + input: + people: + person1: + age: + 2018: 30 + person2: + age: + 2018: 5 + person3: + age: + 2018: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_731 + households: + household: + members: [person1, person2, person3] + state_code: + 2018: GA + output: + # DECAL letter, June 18, 2018: 100% from May 30, 2018. + ga_caps_priority_group_eligible: true + +- name: Very low income, June 2018, 100 percent, over the limit. + period: 2018-06 + input: + people: + person1: + age: + 2018: 30 + person2: + age: + 2018: 5 + person3: + age: + 2018: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_732 + households: + household: + members: [person1, person2, person3] + state_code: + 2018: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, June 2019, 100 percent, at the limit. + period: 2019-06 + input: + people: + person1: + age: + 2019: 30 + person2: + age: + 2019: 5 + person3: + age: + 2019: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_777 + households: + household: + members: [person1, person2, person3] + state_code: + 2019: GA + output: + ga_caps_priority_group_eligible: true + +- name: Very low income, June 2019, 100 percent, over the limit. + period: 2019-06 + input: + people: + person1: + age: + 2019: 30 + person2: + age: + 2019: 5 + person3: + age: + 2019: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_778 + households: + household: + members: [person1, person2, person3] + state_code: + 2019: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, July 2019, 50 percent, at the limit. + period: 2019-07 + input: + people: + person1: + age: + 2019: 30 + person2: + age: + 2019: 5 + person3: + age: + 2019: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 888 + households: + household: + members: [person1, person2, person3] + state_code: + 2019: GA + output: + # DECAL webinar, July 10, 2019: 50% for applications from July 1, 2019. + ga_caps_priority_group_eligible: true + +- name: Very low income, July 2019, 50 percent, over the limit. + period: 2019-07 + input: + people: + person1: + age: + 2019: 30 + person2: + age: + 2019: 5 + person3: + age: + 2019: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 889 + households: + household: + members: [person1, person2, person3] + state_code: + 2019: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, November 2021, 150 percent for four, at the limit. + period: 2021-11 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + person4: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 3_312.5 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2021: GA + output: + # DECAL letter, October 21, 2021: $39,750 for four. + ga_caps_priority_group_eligible: true + +- name: Very low income, November 2021, 150 percent for four, over the limit. + period: 2021-11 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + person4: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 3_313 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2021: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, October 2021, 50 percent for four, at the limit. + period: 2021-10 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + person4: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 1_104 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2021: GA + output: + # DECAL letter, October 21, 2021: $13,250 for four. + ga_caps_priority_group_eligible: true + +- name: Very low income, October 2021, 50 percent for four, over the limit. + period: 2021-10 + input: + people: + person1: + age: + 2021: 30 + person2: + age: + 2021: 5 + person3: + age: + 2021: 5 + person4: + age: + 2021: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ga_caps_countable_income: 1_105 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2021: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, December 2022 reads December 1, so 150 percent, at the limit. + period: 2022-12 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_878 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: GA + output: + ga_caps_priority_group_eligible: true + +- name: Very low income, December 2022 reads December 1, so 150 percent, over the limit. + period: 2022-12 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 2_879 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, January 2023, 50 percent of the 2022 guideline, at the limit. + period: 2023-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 959.58 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # DECAL letter, December 19, 2022: 50% from December 16, 2022. The chart takes up + # the 2023 guideline on March 1, 2023, so 50% of the 2022 guideline, $11,515 for + # three, applies until then. + ga_caps_priority_group_eligible: true + +- name: Very low income, January 2023, 50 percent of the 2022 guideline, over the limit. + period: 2023-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 959.59 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, March 2023, 50 percent of the 2023 guideline, at the limit. + period: 2023-03 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_035 + households: + household: + members: [person1, person2, person3] + state_code: + 2023: GA + output: + # Appendix A, guidelines effective for CAPS March 1, 2023: $12,430 for three. + ga_caps_priority_group_eligible: true + +- name: Very low income, March 2023, 50 percent of the 2023 guideline, over the limit. + period: 2023-03 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_036 + households: + household: + members: [person1, person2, person3] + state_code: + 2023: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, June 2024, 50 percent, at the limit. + period: 2024-06 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_075 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_priority_group_eligible: true + +- name: Very low income, June 2024, 50 percent, over the limit. + period: 2024-06 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_076 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, July 2024, 10 percent, at the limit. + period: 2024-07 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 215 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + # DECAL letter, July 1, 2024: 10% from July 1, 2024. + ga_caps_priority_group_eligible: true + +- name: Very low income, July 2024, 10 percent, over the limit. + period: 2024-07 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 216 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, January 2025, 10 percent of the 2024 guideline, at the limit. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 215.16 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # The chart effective July 1, 2024 holds until March 1, 2025: $2,582 for three. + ga_caps_priority_group_eligible: true + +- name: Very low income, January 2025, 10 percent of the 2024 guideline, over the limit. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 215.17 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, March 2025, 10 percent of the 2025 guideline, at the limit. + period: 2025-03 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 222.08 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + # Appendix A, guidelines effective for CAPS March 1, 2025: $2,665 for three. + ga_caps_priority_group_eligible: true + +- name: Very low income, March 2025, 10 percent of the 2025 guideline, over the limit. + period: 2025-03 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 222.09 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, October 2025 reads October 1, so 10 percent, at the limit. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 222 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + ga_caps_priority_group_eligible: true + +- name: Very low income, October 2025 reads October 1, so 10 percent, over the limit. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 223 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, November 2025, 30 percent, at the limit. + period: 2025-11 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 666 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + # DECAL letter, October 6, 2025: 10% to 30%. + ga_caps_priority_group_eligible: true + +- name: Very low income, November 2025, 30 percent, over the limit. + period: 2025-11 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 667 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, January 2026, 30 percent of the 2025 guideline, at the limit. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 666.25 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + # The chart takes up the 2026 guideline on March 2, 2026: $7,995 for three until then. + ga_caps_priority_group_eligible: true + +- name: Very low income, January 2026, 30 percent of the 2025 guideline, over the limit. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 666.26 + households: + household: + members: [person1, person2, person3] + state_code: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, March 2026 reads March 1, so 30 percent of the 2025 guideline, at the limit. + period: 2026-03 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 666.25 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_priority_group_eligible: true + +- name: Very low income, March 2026 reads March 1, so 30 percent of the 2025 guideline, over the limit. + period: 2026-03 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 666.26 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, April 2026, 50 percent, at the limit. + period: 2026-04 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_138 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + # DECAL letter, March 2, 2026: 30% to 50%. + ga_caps_priority_group_eligible: true + +- name: Very low income, April 2026, 50 percent, over the limit. + period: 2026-04 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_139 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_priority_group_eligible: false + +- name: Very low income, October 2026, 50 percent, at the limit. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_138 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + # Appendix A, effective October 5, 2026, prints $13,660 for three. + ga_caps_priority_group_eligible: true + +- name: Very low income, October 2026, 50 percent, over the limit. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + ga_caps_countable_income: 1_139 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: GA + output: + ga_caps_priority_group_eligible: false + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. + +- name: Appendix A's very low income limits hold at sizes 1 to 14 in November 2026. + period: 2026-11 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + p25: + age: + 2026: 30 + p26: + age: + 2026: 30 + p27: + age: + 2026: 30 + p28: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + ga_caps_countable_income: 665 + u2: + members: [p2] + spm_unit_size: + 2026: 1 + ga_caps_countable_income: 665.09 + u3: + members: [p3] + spm_unit_size: + 2026: 2 + ga_caps_countable_income: 901.66 + u4: + members: [p4] + spm_unit_size: + 2026: 2 + ga_caps_countable_income: 901.75 + u5: + members: [p5] + spm_unit_size: + 2026: 3 + ga_caps_countable_income: 1_138.33 + u6: + members: [p6] + spm_unit_size: + 2026: 3 + ga_caps_countable_income: 1_138.42 + u7: + members: [p7] + spm_unit_size: + 2026: 4 + ga_caps_countable_income: 1_375 + u8: + members: [p8] + spm_unit_size: + 2026: 4 + ga_caps_countable_income: 1_375.09 + u9: + members: [p9] + spm_unit_size: + 2026: 5 + ga_caps_countable_income: 1_611.66 + u10: + members: [p10] + spm_unit_size: + 2026: 5 + ga_caps_countable_income: 1_611.75 + u11: + members: [p11] + spm_unit_size: + 2026: 6 + ga_caps_countable_income: 1_848.33 + u12: + members: [p12] + spm_unit_size: + 2026: 6 + ga_caps_countable_income: 1_848.42 + u13: + members: [p13] + spm_unit_size: + 2026: 7 + ga_caps_countable_income: 2_085 + u14: + members: [p14] + spm_unit_size: + 2026: 7 + ga_caps_countable_income: 2_085.09 + u15: + members: [p15] + spm_unit_size: + 2026: 8 + ga_caps_countable_income: 2_321.66 + u16: + members: [p16] + spm_unit_size: + 2026: 8 + ga_caps_countable_income: 2_321.75 + u17: + members: [p17] + spm_unit_size: + 2026: 9 + ga_caps_countable_income: 2_558.33 + u18: + members: [p18] + spm_unit_size: + 2026: 9 + ga_caps_countable_income: 2_558.42 + u19: + members: [p19] + spm_unit_size: + 2026: 10 + ga_caps_countable_income: 2_795 + u20: + members: [p20] + spm_unit_size: + 2026: 10 + ga_caps_countable_income: 2_795.09 + u21: + members: [p21] + spm_unit_size: + 2026: 11 + ga_caps_countable_income: 3_031.66 + u22: + members: [p22] + spm_unit_size: + 2026: 11 + ga_caps_countable_income: 3_031.75 + u23: + members: [p23] + spm_unit_size: + 2026: 12 + ga_caps_countable_income: 3_268.33 + u24: + members: [p24] + spm_unit_size: + 2026: 12 + ga_caps_countable_income: 3_268.42 + u25: + members: [p25] + spm_unit_size: + 2026: 13 + ga_caps_countable_income: 3_505 + u26: + members: [p26] + spm_unit_size: + 2026: 13 + ga_caps_countable_income: 3_505.09 + u27: + members: [p27] + spm_unit_size: + 2026: 14 + ga_caps_countable_income: 3_741.66 + u28: + members: [p28] + spm_unit_size: + 2026: 14 + ga_caps_countable_income: 3_741.75 + households: + h1: + members: [p1] + state_code: + 2026: GA + h2: + members: [p2] + state_code: + 2026: GA + h3: + members: [p3] + state_code: + 2026: GA + h4: + members: [p4] + state_code: + 2026: GA + h5: + members: [p5] + state_code: + 2026: GA + h6: + members: [p6] + state_code: + 2026: GA + h7: + members: [p7] + state_code: + 2026: GA + h8: + members: [p8] + state_code: + 2026: GA + h9: + members: [p9] + state_code: + 2026: GA + h10: + members: [p10] + state_code: + 2026: GA + h11: + members: [p11] + state_code: + 2026: GA + h12: + members: [p12] + state_code: + 2026: GA + h13: + members: [p13] + state_code: + 2026: GA + h14: + members: [p14] + state_code: + 2026: GA + h15: + members: [p15] + state_code: + 2026: GA + h16: + members: [p16] + state_code: + 2026: GA + h17: + members: [p17] + state_code: + 2026: GA + h18: + members: [p18] + state_code: + 2026: GA + h19: + members: [p19] + state_code: + 2026: GA + h20: + members: [p20] + state_code: + 2026: GA + h21: + members: [p21] + state_code: + 2026: GA + h22: + members: [p22] + state_code: + 2026: GA + h23: + members: [p23] + state_code: + 2026: GA + h24: + members: [p24] + state_code: + 2026: GA + h25: + members: [p25] + state_code: + 2026: GA + h26: + members: [p26] + state_code: + 2026: GA + h27: + members: [p27] + state_code: + 2026: GA + h28: + members: [p28] + state_code: + 2026: GA + output: + # 50% of the 2026 guideline, which CAPS took up on March 2, 2026. + # Annual tops as monthly income: the top rounded down to the cent, then a + # dollar more a year rounded up to the cent. + ga_caps_priority_group_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/ga_caps.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/ga_caps.yaml index 6cbd3ad2e3e..3144c26be7c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/ga_caps.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/ga_caps.yaml @@ -6,8 +6,11 @@ # Family of 2: 21,640 # Family of 3: 27,320 # -# GA SMI 4-person at 2026-01: $116,773.19 (uprated) -# Family of 2: 116,773.19 * 0.68 = $79,405.77 -> 50% = $39,702.88 +# GA SMI 4-person at 2026-01 (October 2025 table): $110,736 +# New applicants in January 2026 face 40% of it, rounded up to the next dollar: +# Family of 2: 110,736 * 0.68 * 0.4 -> $30,121 +# Family of 3: 110,736 * 0.84 * 0.4 -> $37,208 +# Family of 4: 110,736 * 1.00 * 0.4 -> $44,295 - name: Case 1, subsidy zero when fee exceeds expenses. period: 2026-01 @@ -32,6 +35,9 @@ spm_units: spm_unit: members: [person1, person2] + # Enrolled, so the 85% limit applies. New applicants face a lower limit in + # January 2026. + ga_caps_enrolled: true spm_unit_pre_subsidy_childcare_expenses: 2_000 households: household: @@ -75,6 +81,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: @@ -122,6 +129,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: @@ -163,6 +171,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: @@ -293,6 +302,7 @@ spm_units: spm_unit: members: [person1, person2, person3] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 12_000 households: household: @@ -382,6 +392,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 6_000 households: household: @@ -427,6 +438,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 0 households: household: @@ -464,6 +476,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 8_000 households: household: @@ -510,6 +523,9 @@ spm_units: spm_unit: members: [person1, person2] + # Enrolled, so the 85% limit applies. New applicants face a lower limit in + # January 2026. + ga_caps_enrolled: true # Expenses far above the max rate, so the base is capped at the max. spm_unit_pre_subsidy_childcare_expenses: 60_000 households: diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/integration.yaml index 2ecdbcdc222..3a38f2ffcaa 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/decal/caps/integration.yaml @@ -1,8 +1,10 @@ # GA CAPS Integration Tests # -# Period: tests use 2026-01 intentionally. CAPS parameters are dated -# 2026-03-02 (current Appendix C/D rates), and PolicyEngine backcasts the -# first dated value, so a 2026-01 test exercises the current rules. +# Period: tests use 2026-01 intentionally. The rate and fee parameters are +# dated 2026-03-02 (current Appendix C/D rates), and PolicyEngine backcasts the +# first dated value, so a 2026-01 test exercises the current payment rules. The +# income limit for new applicants has its own history, and it reads 40% of state +# median income in January 2026. # This avoids 2027-01 where FPG and SMI would be uprated rather than using # the published 2026 values cited in the inline calculation comments. # @@ -12,10 +14,11 @@ # Family of 3: 27,320 # Family of 4: 33,000 # -# GA SMI 4-person at 2026-01: $116,773.19 (uprated) -# Family of 2: 116,773.19 * 0.68 = $79,405.77 -> 50% = $39,702.88 -# Family of 3: 116,773.19 * 0.84 = $98,089.48 -> 50% = $49,044.74 -# Family of 4: 116,773.19 * 1.00 = $116,773.19 -> 50% = $58,386.59 +# GA SMI 4-person at 2026-01 (October 2025 table): $110,736 +# New applicants in January 2026 face 40% of it, rounded up to the next dollar: +# Family of 2: 110,736 * 0.68 * 0.4 -> $30,121 +# Family of 3: 110,736 * 0.84 * 0.4 -> $37,208 +# Family of 4: 110,736 * 1.00 * 0.4 -> $44,295 - name: Case 1, basic eligible family with Zone 1 center care. period: 2026-01 @@ -40,6 +43,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 11_000 households: household: @@ -52,7 +56,7 @@ # Citizen -> immigration eligible ga_caps_eligible_child: [false, true] - # income 30,000 <= 39,702.88 (50% SMI for family of 2) -> income eligible + # income 30,000 <= 30,121 (40% SMI for family of 2) -> income eligible ga_caps_income_eligible: true is_ccdf_asset_eligible: true ga_caps_eligible: true @@ -219,6 +223,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 12_000 households: household: @@ -226,7 +231,7 @@ state_code: GA county_str: FULTON_COUNTY_GA output: - # income 40,000 > 39,702.88 (50% SMI for family of 2) -> ineligible + # income 40,000 > 30,121 (40% SMI for family of 2) -> ineligible ga_caps_income_eligible: false ga_caps_eligible: false ga_caps: 0 @@ -261,6 +266,7 @@ spm_units: spm_unit: members: [person1, person2, person3] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: @@ -272,8 +278,8 @@ ga_caps_eligible_child: [false, true, true] # FPG family of 3: $27,320 - # 50% SMI family of 3 = $49,044.74 - # income 20,000 <= 49,044.74 -> eligible + # 40% SMI family of 3 = $37,208 + # income 20,000 <= 37,208 -> eligible ga_caps_income_eligible: true ga_caps_eligible: true @@ -325,6 +331,9 @@ spm_units: spm_unit: members: [person1, person2] + # Enrolled, so the 85% limit applies. New applicants face a lower limit in + # January 2026. Case 12 covers a disabled child as a priority group. + ga_caps_enrolled: true spm_unit_pre_subsidy_childcare_expenses: 7_000 households: household: @@ -336,7 +345,7 @@ # disabled, age 15 <= 17 -> eligible child ga_caps_eligible_child: [false, true] - # income 35,000 <= 39,702.88 (50% SMI for family of 2) -> eligible + # enrolled: income 35,000 <= 64,006 (85% SMI for family of 2) -> eligible ga_caps_income_eligible: true ga_caps_eligible: true @@ -394,7 +403,7 @@ ga_caps: 0 # 2026 FPG family of 5: 38,680; family of 6: 44,360 -# 50% SMI family of 5 = $67,728.45; family of 6 = $77,070.30 +# 40% SMI family of 5 = $51,382; family of 6 = $58,469 - name: Case 8, large family of 6 at income threshold boundary. period: 2026-01 @@ -404,7 +413,7 @@ person1: age: 40 weekly_hours_worked_before_lsr: 40 - employment_income: 73_085 + employment_income: 58_469 immigration_status: CITIZEN person2: age: 38 @@ -441,6 +450,7 @@ spm_units: spm_unit: members: [person1, person2, person3, person4, person5, person6] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 20_000 households: household: @@ -455,8 +465,8 @@ # person6 (14): age >= 13, not disabled -> ineligible ga_caps_eligible_child: [false, false, true, true, true, false] - # 50% SMI family of 6 = $77,070.30 - # income 73,085 <= 77,070.30 -> eligible + # 40% SMI family of 6 = 110,736 * 1.32 * 0.4, rounded up = $58,469 + # income 58,469 <= 58,469 -> eligible ga_caps_income_eligible: true ga_caps_eligible: true @@ -471,20 +481,20 @@ # === Family fee === # FPG family of 6: $44,360 - # FPL ratio = 73,085 / 44,360 = 1.648 -> 7% rate - # weekly fee = floor(73,085 * 0.07 / 52) = floor(98.38) = $98 - # monthly fee = 98 * 52 / 12 = $424.67 - ga_caps_family_fee: 424.67 + # FPL ratio = 58,469 / 44,360 = 1.318 -> 7% rate + # weekly fee = floor(58,469 * 0.07 / 52) = floor(78.71) = $78 + # monthly fee = 78 * 52 / 12 = $338.00 + ga_caps_family_fee: 338 # === Benefit === # sum_max_weekly = 84 + 180 + 260 = $524 # sum_max_monthly = $524 * 52/12 = $2,270.67 # expenses_monthly = 20,000 / 12 = $1,666.67 # base = min($1,666.67, $2,270.67) = $1,666.67 - # net_base = max($1,666.67 - $424.67, 0) = $1,242.00 + # net_base = max($1,666.67 - $338.00, 0) = $1,328.67 # weighted_bonus_rate = (84*0 + 180*0.05 + 260*0.05) / 524 = 0.04198 - # subsidy = $1,242.00 * 1.04198 = $1,294.14 - ga_caps: 1_294.14 + # subsidy = $1,328.67 * 1.04198 = $1,384.45 + ga_caps: 1_384.45 - name: Case 9, enrolled family between 50 and 85 percent SMI. period: 2026-01 @@ -520,7 +530,7 @@ # === Eligibility === ga_caps_eligible_child: [false, true] # enrolled: 50,000 <= 67,494.90 (85% SMI) -> eligible - # NOT eligible as new applicant: 50,000 > 39,702.88 (50% SMI) + # NOT eligible as new applicant: 50,000 > 30,121 (40% SMI) ga_caps_income_eligible: true ga_caps_eligible: true @@ -547,14 +557,14 @@ # subsidy = $784.33 * 1.10 = $862.77 ga_caps: 862.77 -- name: Case 10, non-enrolled family at 50 percent SMI plus 1 dollar is ineligible. +- name: Case 10, non-enrolled family at the 40 percent SMI limit plus 1 dollar is ineligible. period: 2026-01 absolute_error_margin: 0.01 input: people: person1: age: 35 - employment_income: 39_703 + employment_income: 30_122 immigration_status: CITIZEN person2: age: 4 @@ -569,6 +579,7 @@ spm_units: spm_unit: members: [person1, person2] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 12_000 households: household: @@ -577,7 +588,7 @@ county_str: FULTON_COUNTY_GA output: ga_caps_eligible_child: [false, true] - # 39,703 > 39,702.88 (50% SMI for family of 2) -> ineligible + # 30,122 > 30,121 (40% SMI for family of 2) -> ineligible ga_caps_income_eligible: false ga_caps_eligible: false ga_caps: 0 @@ -609,6 +620,7 @@ spm_units: spm_unit: members: [person1, person2, person3] + ga_caps_priority_group_eligible: true spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/eligibility/id_iccp_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/eligibility/id_iccp_fpg.yaml new file mode 100644 index 00000000000..8ff84ada4fc --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/eligibility/id_iccp_fpg.yaml @@ -0,0 +1,92 @@ +# The guideline year follows the department's posted tables: 2024 for applications +# from January 13, 2025, 2025 from October 2025, and 2025 again through 2026 because +# the page still showed that table on November 5, 2026. +- name: Case 1, February 2025 uses the 2024 guideline. + period: 2025-02 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + output: + # 25,820 / 12 + id_iccp_fpg: 2_151.67 + +- name: Case 2, October 2025 uses the 2025 guideline. + period: 2025-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + output: + # 26,650 / 12 + id_iccp_fpg: 2_220.83 + +- name: Case 3, November 2026 still uses the 2025 guideline. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + output: + id_iccp_fpg: 2_220.83 + +- name: Case 4, dates before 2025 keep the current year's guideline. + period: 2024-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + output: + id_iccp_fpg: 2_151.67 diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/eligibility/id_iccp_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/eligibility/id_iccp_income_eligible.yaml index 51f9292a6dc..8222afdd482 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/eligibility/id_iccp_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/eligibility/id_iccp_income_eligible.yaml @@ -1,4 +1,6 @@ -- name: Case 1, initial eligibility uses 175 percent of the federal poverty guideline. +# Limits for new applicants come from the department's Apply for Child Care page +# (effective October 2025): 130% of the 2025 guideline, rounded up to a dollar. +- name: Case 1, initial eligibility uses 130 percent of the guideline from January 2025. period: 2026-01 input: people: @@ -11,13 +13,13 @@ spm_units: spm_unit: members: [person1] - id_iccp_countable_income: 3_500 + id_iccp_countable_income: 2_600 id_iccp_enrolled: false - spm_unit_fpg: 24_000 + id_iccp_fpg: 2_000 output: id_iccp_income_eligible: true -- name: Case 2, initial eligibility fails above 175 percent of the federal poverty guideline. +- name: Case 2, initial eligibility fails above 130 percent of the guideline. period: 2026-01 input: people: @@ -30,9 +32,9 @@ spm_units: spm_unit: members: [person1] - id_iccp_countable_income: 3_501 + id_iccp_countable_income: 2_601 id_iccp_enrolled: false - spm_unit_fpg: 24_000 + id_iccp_fpg: 2_000 output: id_iccp_income_eligible: false @@ -73,3 +75,434 @@ hhs_smi: 60_000 output: id_iccp_income_eligible: false + +- name: Case 5, a family of three at the posted limit of 2,888 dollars qualifies as a new applicant. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + id_iccp_countable_income: 2_888 + id_iccp_enrolled: false + output: + id_iccp_income_eligible: true + +- name: Case 6, a family of three one dollar above the posted limit doesn't qualify as a new applicant. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + id_iccp_countable_income: 2_889 + id_iccp_enrolled: false + output: + id_iccp_income_eligible: false + +- name: Case 7, the old 175 percent rate still applies in January 2025, before the department's change takes hold. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + # 175% of the 2025 guideline for three: 26,650 x 1.75 / 12 = 3,886.46, so 3,887. + id_iccp_countable_income: 3_887 + id_iccp_enrolled: false + output: + id_iccp_income_eligible: true + +- name: Case 8, new applicants from February 2025 face 130 percent of the 2024 guideline. + period: 2025-02 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + # 25,820 x 1.3 / 12 = 2,797.17, so 2,798 (33,566 a year, as reported in November 2024). + id_iccp_countable_income: 2_798 + id_iccp_enrolled: false + output: + id_iccp_income_eligible: true + +- name: Case 9, one dollar above 130 percent of the 2024 guideline fails in February 2025. + period: 2025-02 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + id_iccp_countable_income: 2_799 + id_iccp_enrolled: false + output: + id_iccp_income_eligible: false + +- name: Case 10, an enrolled family keeps the 85 percent of state median income limit after the change. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + id_iccp_countable_income: 2_889 + id_iccp_enrolled: true + output: + id_iccp_income_eligible: true + +# IDAPA 16.06.12.070 set 130% before April 6, 2023 and 175% from then. +# 130% x 23,030 / 12 = 2,494.92, rounded up to 2,495 (June 2022). +# 175% x 24,860 / 12 = 3,625.42, rounded up to 3,626 (June 2023). + +- name: Case 11, in June 2022 a family of three at 130 percent of the 2022 guideline qualifies as a new applicant. + period: 2022-06 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + id_iccp_countable_income: 2_495 + id_iccp_enrolled: false + output: + id_iccp_income_eligible: true + +- name: Case 12, in June 2022 a family of three one dollar above 130 percent of the 2022 guideline doesn't qualify. + period: 2022-06 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + id_iccp_countable_income: 2_496 + id_iccp_enrolled: false + output: + id_iccp_income_eligible: false + +- name: Case 13, in June 2023 a family of three at 175 percent of the 2023 guideline qualifies as a new applicant. + period: 2023-06 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2023: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + id_iccp_countable_income: 3_626 + id_iccp_enrolled: false + output: + id_iccp_income_eligible: true + +- name: Case 14, in June 2023 a family of three one dollar above 175 percent of the 2023 guideline doesn't qualify. + period: 2023-06 + input: + people: + person1: + age: 30 + person2: + age: 30 + person3: + age: 4 + households: + household: + members: [person1, person2, person3] + state_code: + 2023: ID + spm_units: + spm_unit: + members: [person1, person2, person3] + id_iccp_countable_income: 3_627 + id_iccp_enrolled: false + output: + id_iccp_income_eligible: false + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. + +- name: The department's table effective October 2025 holds at every family size in January 2026. + period: 2026-01 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 2 + id_iccp_countable_income: 2_292 + id_iccp_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 2 + id_iccp_countable_income: 2_293 + id_iccp_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 3 + id_iccp_countable_income: 2_888 + id_iccp_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 3 + id_iccp_countable_income: 2_889 + id_iccp_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 4 + id_iccp_countable_income: 3_483 + id_iccp_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 4 + id_iccp_countable_income: 3_484 + id_iccp_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 5 + id_iccp_countable_income: 4_079 + id_iccp_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 5 + id_iccp_countable_income: 4_080 + id_iccp_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 6 + id_iccp_countable_income: 4_675 + id_iccp_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 6 + id_iccp_countable_income: 4_676 + id_iccp_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 7 + id_iccp_countable_income: 5_271 + id_iccp_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 7 + id_iccp_countable_income: 5_272 + id_iccp_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 8 + id_iccp_countable_income: 5_867 + id_iccp_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 8 + id_iccp_countable_income: 5_868 + id_iccp_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: ID + h2: + members: [p2] + state_code: + 2026: ID + h3: + members: [p3] + state_code: + 2026: ID + h4: + members: [p4] + state_code: + 2026: ID + h5: + members: [p5] + state_code: + 2026: ID + h6: + members: [p6] + state_code: + 2026: ID + h7: + members: [p7] + state_code: + 2026: ID + h8: + members: [p8] + state_code: + 2026: ID + h9: + members: [p9] + state_code: + 2026: ID + h10: + members: [p10] + state_code: + 2026: ID + h11: + members: [p11] + state_code: + 2026: ID + h12: + members: [p12] + state_code: + 2026: ID + h13: + members: [p13] + state_code: + 2026: ID + h14: + members: [p14] + state_code: + 2026: ID + output: + # Apply for Child Care, 130% of the 2025 guideline, sizes 2 to 8. + id_iccp_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/integration.yaml index 8240c8b04f6..d67f82da09f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/iccp/integration.yaml @@ -44,10 +44,11 @@ spm_unit: members: [person1, person2] spm_unit_pre_subsidy_childcare_expenses: 24_000 # 2,000/month - spm_unit_fpg: 24_000 # initial limit 1.75 x 24,000 / 12 = 3,500/month + spm_unit_fpg: 24_000 # sets the copay bands; the income limit reads id_iccp_fpg output: id_iccp_eligible: true - # countable income 2,000/month <= 3,500/month initial limit + # countable income 2,000/month <= 2,292/month initial limit + # (130% x the 2025 guideline for two, 21,150 / 12, rounded up) # max benefit: CENTER, CLUSTER_3, FULL_TIME, PRESCHOOL = 1,089/month # copay (size 2, full-time): income 2,000 in 1,940-2,116 band = 50/month # id_iccp = min(2,000, 1,089) - 50 = 1,039/month @@ -79,9 +80,11 @@ spm_unit: members: [person1, person2, person3] spm_unit_pre_subsidy_childcare_expenses: 60_000 # 5,000/month - spm_unit_fpg: 30_000 # initial limit 1.75 x 30,000 / 12 = 4,375/month + spm_unit_fpg: 30_000 # sets the copay bands; the income limit reads id_iccp_fpg output: id_iccp_eligible: true + # countable income 2,000/month <= 2,888/month initial limit + # (130% x the 2025 guideline for three, 26,650 / 12, rounded up) # size 3, full-time, countable income 2,000 in first band (< 2,222) = 20/child id_iccp_copay_per_child: [0, 20, 20] id_iccp_copay: 40 diff --git a/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/copay/in_ccdf_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/copay/in_ccdf_copay.yaml index 7582ba49531..6e1769ac29e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/copay/in_ccdf_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/copay/in_ccdf_copay.yaml @@ -5,7 +5,8 @@ # copay to monthly (* 52 / 12). $0 at or below 100% FPL. # Policy Manual Section 2.6; 2026 Sliding Fee Schedule. # defined_for = in_ccdf_eligible, so each unit is a fully eligible family -# (working parent, dependent citizen child). 2-person FPG 2026 = 21,640/yr. +# (working parent, dependent citizen child). January 2026 still uses the 2025 +# guideline: 2-person FPG = 21,150/yr. - name: Case 1, income at 100% FPL, zero copay. period: 2026-01 @@ -14,7 +15,7 @@ people: person1: age: 35 - employment_income: 21_640 # exactly 100% FPL + employment_income: 21_150 # exactly 100% FPL person2: age: 5 is_tax_unit_dependent: true @@ -29,7 +30,7 @@ # <= 100% FPL bracket fee factor is 0. in_ccdf_copay: 0 -- name: Case 2, income about 105% FPL, 0.0116 factor. +- name: Case 2, income about 107% FPL, 0.0116 factor. period: 2026-01 absolute_error_margin: 0.1 input: @@ -48,11 +49,11 @@ members: [person1, person2] state_code: IN output: - # income 1,893.33/mo, ratio ~1.05 -> factor 0.0116 + # income 1,893.33/mo, ratio ~1.07 -> factor 0.0116 # 1,893.33 * 0.0116 = 21.96/week -> 21.96 * 52/12 = 95.17/month in_ccdf_copay: 95.17 -- name: Case 3, income about 115% FPL, 0.0140 factor. +- name: Case 3, income about 118% FPL, 0.0140 factor. period: 2026-01 absolute_error_margin: 0.1 input: @@ -71,11 +72,11 @@ members: [person1, person2] state_code: IN output: - # income 2,073.67/mo, ratio ~1.15 -> factor 0.0140 + # income 2,073.67/mo, ratio ~1.18 -> factor 0.0140 # 2,073.67 * 0.0140 = 29.03/week -> 29.03 * 52/12 = 125.80/month in_ccdf_copay: 125.80 -- name: Case 4, income about 125% FPL, 0.0163 factor. +- name: Case 4, income about 128% FPL, 0.0163 factor. period: 2026-01 absolute_error_margin: 0.1 input: @@ -94,7 +95,7 @@ members: [person1, person2] state_code: IN output: - # income 2,254.17/mo, ratio ~1.25 -> factor 0.0163 + # income 2,254.17/mo, ratio ~1.28 -> factor 0.0163 # 2,254.17 * 0.0163 = 36.74/week -> 36.74 * 52/12 = 159.22/month in_ccdf_copay: 159.22 @@ -128,7 +129,7 @@ # Countable income is negative; floored at 0 before the multiply. in_ccdf_copay: 0 -# --- 100% FPL copay-zero cutoff boundary (2-person FPG 2026 = 21,640/yr) --- +# --- 100% FPL copay-zero cutoff boundary (2-person FPG in January 2026 = 21,150/yr) --- # The first non-zero fee-factor bracket starts above 100% FPL (threshold 1.0001 # of FPG), so income at or below 100% FPL yields a zero copay. @@ -139,7 +140,7 @@ people: person1: age: 35 - employment_income: 21_628 # just below 100% FPL (21,640) + employment_income: 21_138 # just below 100% FPL (21,150) person2: age: 5 is_tax_unit_dependent: true @@ -161,7 +162,7 @@ people: person1: age: 35 - employment_income: 21_900 # 1,825/mo, ratio ~1.012 FPL + employment_income: 21_900 # 1,825/mo, ratio ~1.035 FPL person2: age: 5 is_tax_unit_dependent: true @@ -180,9 +181,10 @@ # --- Operative fee-schedule era (effective 2026-04-05) --- # The fee_factor parameter starts 2026-04-05, so the 2026-01 cases above back- # extrapolate it. This case runs at 2027-01 to exercise the schedule as the -# live (forward) value. The 2027 2-person FPG is uprated to 22,147.39, so the -# ratio falls from ~1.05 to ~1.026 — still inside the 101-109% bracket (0.0116) — -# and since the copay multiplies income (not FPG), the expected value is unchanged. +# live (forward) value. January 2027 still uses the 2026 guideline (2-person FPG +# 21,640), so the ratio falls from ~1.07 to ~1.05 — still inside the 101-109% +# bracket (0.0116) — and since the copay multiplies income (not FPG), the expected +# value is unchanged. - name: Case 8, operative era at 2027-01, about 105% FPL, 0.0116 factor. period: 2027-01 @@ -203,6 +205,6 @@ members: [person1, person2] state_code: IN output: - # income 1,893.33/mo, ratio ~1.026 -> factor 0.0116 + # income 1,893.33/mo, ratio ~1.05 -> factor 0.0116 # 1,893.33 * 0.0116 = 21.96/week -> 21.96 * 52/12 = 95.17/month in_ccdf_copay: 95.17 diff --git a/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/eligibility/in_ccdf_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/eligibility/in_ccdf_fpg.yaml new file mode 100644 index 00000000000..e3905698e5d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/eligibility/in_ccdf_fpg.yaml @@ -0,0 +1,244 @@ +# Tests for in_ccdf_fpg (SPMUnit, MONTH). Indiana moves to a new year's guideline on each +# fee schedule's effective date: March 12, 2023, March 31, 2024, March 23, 2025 and April 5, +# 2026. A monthly period reads the parameter at its first day, so each switch shows in the +# next month. Before 2023 the model reads the current year's guideline. +- name: 2022-12 uses the 2022 guideline. + period: 2022-12 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2022: IN + output: + in_ccdf_fpg: 1_919.17 + +- name: 2023-03 still uses the 2022 guideline. + period: 2023-03 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2023: IN + output: + in_ccdf_fpg: 1_919.17 + +- name: 2023-04 uses the 2023 guideline. + period: 2023-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2023: IN + output: + in_ccdf_fpg: 2_071.67 + +- name: 2023-06 uses the 2023 guideline. + period: 2023-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2023: IN + output: + in_ccdf_fpg: 2_071.67 + +- name: 2024-03 uses the 2023 guideline. + period: 2024-03 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2024: IN + output: + in_ccdf_fpg: 2_071.67 + +- name: 2024-04 uses the 2024 guideline. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2024: IN + output: + in_ccdf_fpg: 2_151.67 + +- name: 2025-03 uses the 2024 guideline. + period: 2025-03 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2025: IN + output: + in_ccdf_fpg: 2_151.67 + +- name: 2025-04 uses the 2025 guideline. + period: 2025-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2025: IN + output: + in_ccdf_fpg: 2_220.83 + +- name: 2026-04 uses the 2025 guideline. + period: 2026-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2026: IN + output: + in_ccdf_fpg: 2_220.83 + +- name: 2026-05 uses the 2026 guideline. + period: 2026-05 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2026: IN + output: + in_ccdf_fpg: 2_276.67 + +- name: 2027-01 uses the 2026 guideline. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: IN + output: + in_ccdf_fpg: 2_276.67 diff --git a/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/eligibility/in_ccdf_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/eligibility/in_ccdf_income_eligible.yaml index c74576a46be..05457e44410 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/eligibility/in_ccdf_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/eligibility/in_ccdf_income_eligible.yaml @@ -6,7 +6,8 @@ # value takes effect 2026-04-05, so it is exercised with a 2027-01 period. # --- Applicant (get-on), 1.5 FPL era at 2026-01 --- -# 2-person FPG 2026 = 21,640/yr; limit = 1.5 * 21,640 = 32,460/yr. +# January 2026 still uses the 2025 guideline: 2-person FPG = 21,150/yr. The limit is +# 1.5 * 21,150 / 12 = 2,643.75, printed as 2,644 a month, or 31,728 a year. - name: Case 1, applicant income below get-on limit, eligible. period: 2026-01 @@ -35,7 +36,7 @@ people: person1: age: 35 - employment_income: 32_460 # 1.5 * 21,640 FPG + employment_income: 31_728 # 12 * 2,644, the rounded limit person2: age: 5 is_tax_unit_dependent: true @@ -57,7 +58,7 @@ people: person1: age: 35 - employment_income: 33_000 # above 32,460 limit + employment_income: 33_000 # above 31,728 limit person2: age: 5 is_tax_unit_dependent: true @@ -183,12 +184,11 @@ in_ccdf_income_eligible: false # --- 135% FPL applicant boundary at 2027-01 (1.35 era) --- -# 2-person 2027 FPG = 22,147.39/yr; 135% = 29,898.98/yr. The 2027 FPG is a -# CBO-CPI-forecast-uprated value that shifts when the actual 2027 guideline is -# published, so these cases keep a comfortable margin on each side of the -# limit rather than pinning the exact boundary (the inclusive <= boundary is -# exercised at 2026 with the published FPG in Case 2). The ineligible income -# stays below the 1.5-era limit (33,221), proving the 1.35 rate applies. +# January 2027 still uses the 2026 guideline: 2-person FPG = 21,640/yr; 135% prints +# as 2,435 a month, or 29,220 a year. These cases keep a comfortable margin on each +# side of the limit (the inclusive <= boundary is exercised at 2026 in Case 2). The +# ineligible income stays below the 1.5-era limit (32,460), proving the 1.35 rate +# applies. - name: Case 9, applicant income below 135% FPL, eligible. period: 2027-01 @@ -196,7 +196,7 @@ people: person1: age: 35 - employment_income: 29_000 # comfortably below the ~29,899 limit + employment_income: 29_000 # comfortably below the 29,220 limit person2: age: 5 is_tax_unit_dependent: true @@ -217,7 +217,7 @@ people: person1: age: 35 - employment_income: 30_800 # above the ~29,899 limit, below 1.5 * FPG + employment_income: 30_800 # above the 29,220 limit, below 1.5 * FPG person2: age: 5 is_tax_unit_dependent: true @@ -233,11 +233,9 @@ in_ccdf_income_eligible: false # --- 85% SMI enrolled boundary at 2026-01 --- -# 2-person IN SMI = 6,427.06/mo; 85% = 5,462.99/mo -> 65,555.88/yr. The 2026 -# SMI is uprated from the 2025-10-01 actual (107,555/yr) by the CBO AGI -# forecast, and reverts to the un-uprated base (85% = 62,166.79/yr) once an -# actual 2026-10-01 value is added, so these cases keep a comfortable margin -# below the un-uprated limit and above the uprated one. +# January 2026 still reads FSSA's schedule effective March 23, 2025, which caps a +# family of two at 85% of the October 2024 state median income (103,324 for four): +# 103,324 * 0.68 * 0.85 / 12 = 4,976.77, printed as 4,977 a month, or 59,724 a year. - name: Case 11, enrolled income below 85% SMI, eligible. period: 2026-01 @@ -245,7 +243,7 @@ people: person1: age: 35 - employment_income: 60_000 # below 85% SMI under either basis + employment_income: 59_000 # below the 59,724 limit person2: age: 5 is_tax_unit_dependent: true @@ -266,7 +264,7 @@ people: person1: age: 35 - employment_income: 70_000 # above 85% SMI (65,556) but below 100% SMI + employment_income: 70_000 # above the 59,724 limit, below 100% of SMI (70,260) person2: age: 5 is_tax_unit_dependent: true @@ -343,3 +341,2980 @@ # 5-person FPG 2026 = 38,680/yr; 150% limit = 58,020/yr (4,835/mo). # 3,333/mo < 4,835/mo -> eligible. A 2-person unit at this income fails. in_ccdf_income_eligible: true + +# Tops by family of three, from FSSA's fee schedules: 127% of the 2022 guideline ($2,437) +# until March 12, 2023; 127% of the 2023 guideline ($2,631) until August 1, 2023, when the +# rate rises to 150% ($3,108, OECOSL bulletin); 150% of the 2024 guideline ($3,228) from +# March 31, 2024; of the 2025 guideline ($3,331) from March 23, 2025; then 135% of the +# 2026 guideline ($3,074) from April 5, 2026. A monthly period reads each change from the +# next month's first day. + +- name: New applicant of 3 at 2,437 dollars qualifies in 2023-03. + period: 2023-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 2_437 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 3 at 2,438 dollars doesn't qualify in 2023-03. + period: 2023-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 2_438 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 3 at 2,631 dollars qualifies in 2023-06. + period: 2023-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 2_631 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 3 at 2,632 dollars doesn't qualify in 2023-06. + period: 2023-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 2_632 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 3 at 3,108 dollars qualifies in 2024-03. + period: 2024-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_108 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2024: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 3 at 3,109 dollars doesn't qualify in 2024-03. + period: 2024-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_109 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2024: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 3 at 3,228 dollars qualifies in 2024-04. + period: 2024-04 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_228 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2024: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 3 at 3,229 dollars doesn't qualify in 2024-04. + period: 2024-04 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_229 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2024: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 3 at 3,228 dollars qualifies in 2025-03. + period: 2025-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_228 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 3 at 3,229 dollars doesn't qualify in 2025-03. + period: 2025-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_229 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 3 at 3,331 dollars qualifies in 2025-04. + period: 2025-04 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_331 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 3 at 3,332 dollars doesn't qualify in 2025-04. + period: 2025-04 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_332 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 3 at 3,331 dollars qualifies in 2026-04. + period: 2026-04 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_331 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 3 at 3,332 dollars doesn't qualify in 2026-04. + period: 2026-04 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_332 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 2 at 2,435 dollars qualifies in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + in_ccdf_countable_income: 2_435 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 2 at 2,436 dollars doesn't qualify in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + in_ccdf_countable_income: 2_436 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 3 at 3,074 dollars qualifies in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_074 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 3 at 3,075 dollars doesn't qualify in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + in_ccdf_countable_income: 3_075 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 4 at 3,713 dollars qualifies in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + in_ccdf_countable_income: 3_713 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 4 at 3,714 dollars doesn't qualify in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + in_ccdf_countable_income: 3_714 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 5 at 4,352 dollars qualifies in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + in_ccdf_countable_income: 4_352 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 5 at 4,353 dollars doesn't qualify in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + in_ccdf_countable_income: 4_353 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 6 at 4,991 dollars qualifies in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + in_ccdf_countable_income: 4_991 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 6 at 4,992 dollars doesn't qualify in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + in_ccdf_countable_income: 4_992 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 7 at 5,630 dollars qualifies in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + in_ccdf_countable_income: 5_630 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 7 at 5,631 dollars doesn't qualify in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + in_ccdf_countable_income: 5_631 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: false + +- name: New applicant of 8 at 6,269 dollars qualifies in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + in_ccdf_countable_income: 6_269 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: true + +- name: New applicant of 8 at 6,270 dollars doesn't qualify in 2026-05. + period: 2026-05 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + in_ccdf_countable_income: 6_270 + is_in_ccdf_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: IN + output: + in_ccdf_income_eligible: false + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. + +- name: FSSA's chart effective April 5, 2026 holds at every family size in May 2026. + period: 2026-05 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + p25: + age: + 2026: 30 + p26: + age: + 2026: 30 + p27: + age: + 2026: 30 + p28: + age: + 2026: 30 + p29: + age: + 2026: 30 + p30: + age: + 2026: 30 + p31: + age: + 2026: 30 + p32: + age: + 2026: 30 + p33: + age: + 2026: 30 + p34: + age: + 2026: 30 + p35: + age: + 2026: 30 + p36: + age: + 2026: 30 + p37: + age: + 2026: 30 + p38: + age: + 2026: 30 + p39: + age: + 2026: 30 + p40: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + in_ccdf_countable_income: 1_796 + is_in_ccdf_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 1 + in_ccdf_countable_income: 1_797 + is_in_ccdf_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 2 + in_ccdf_countable_income: 2_435 + is_in_ccdf_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 2 + in_ccdf_countable_income: 2_436 + is_in_ccdf_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 3 + in_ccdf_countable_income: 3_074 + is_in_ccdf_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 3 + in_ccdf_countable_income: 3_075 + is_in_ccdf_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 4 + in_ccdf_countable_income: 3_713 + is_in_ccdf_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 4 + in_ccdf_countable_income: 3_714 + is_in_ccdf_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 5 + in_ccdf_countable_income: 4_352 + is_in_ccdf_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 5 + in_ccdf_countable_income: 4_353 + is_in_ccdf_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 6 + in_ccdf_countable_income: 4_991 + is_in_ccdf_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 6 + in_ccdf_countable_income: 4_992 + is_in_ccdf_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 7 + in_ccdf_countable_income: 5_630 + is_in_ccdf_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 7 + in_ccdf_countable_income: 5_631 + is_in_ccdf_enrolled: false + u15: + members: [p15] + spm_unit_size: + 2026: 8 + in_ccdf_countable_income: 6_269 + is_in_ccdf_enrolled: false + u16: + members: [p16] + spm_unit_size: + 2026: 8 + in_ccdf_countable_income: 6_270 + is_in_ccdf_enrolled: false + u17: + members: [p17] + spm_unit_size: + 2026: 9 + in_ccdf_countable_income: 6_908 + is_in_ccdf_enrolled: false + u18: + members: [p18] + spm_unit_size: + 2026: 9 + in_ccdf_countable_income: 6_909 + is_in_ccdf_enrolled: false + u19: + members: [p19] + spm_unit_size: + 2026: 10 + in_ccdf_countable_income: 7_547 + is_in_ccdf_enrolled: false + u20: + members: [p20] + spm_unit_size: + 2026: 10 + in_ccdf_countable_income: 7_548 + is_in_ccdf_enrolled: false + u21: + members: [p21] + spm_unit_size: + 2026: 11 + in_ccdf_countable_income: 8_186 + is_in_ccdf_enrolled: false + u22: + members: [p22] + spm_unit_size: + 2026: 11 + in_ccdf_countable_income: 8_187 + is_in_ccdf_enrolled: false + u23: + members: [p23] + spm_unit_size: + 2026: 12 + in_ccdf_countable_income: 8_825 + is_in_ccdf_enrolled: false + u24: + members: [p24] + spm_unit_size: + 2026: 12 + in_ccdf_countable_income: 8_826 + is_in_ccdf_enrolled: false + u25: + members: [p25] + spm_unit_size: + 2026: 13 + in_ccdf_countable_income: 9_464 + is_in_ccdf_enrolled: false + u26: + members: [p26] + spm_unit_size: + 2026: 13 + in_ccdf_countable_income: 9_465 + is_in_ccdf_enrolled: false + u27: + members: [p27] + spm_unit_size: + 2026: 14 + in_ccdf_countable_income: 10_103 + is_in_ccdf_enrolled: false + u28: + members: [p28] + spm_unit_size: + 2026: 14 + in_ccdf_countable_income: 10_104 + is_in_ccdf_enrolled: false + u29: + members: [p29] + spm_unit_size: + 2026: 15 + in_ccdf_countable_income: 10_742 + is_in_ccdf_enrolled: false + u30: + members: [p30] + spm_unit_size: + 2026: 15 + in_ccdf_countable_income: 10_743 + is_in_ccdf_enrolled: false + u31: + members: [p31] + spm_unit_size: + 2026: 16 + in_ccdf_countable_income: 11_381 + is_in_ccdf_enrolled: false + u32: + members: [p32] + spm_unit_size: + 2026: 16 + in_ccdf_countable_income: 11_382 + is_in_ccdf_enrolled: false + u33: + members: [p33] + spm_unit_size: + 2026: 17 + in_ccdf_countable_income: 12_020 + is_in_ccdf_enrolled: false + u34: + members: [p34] + spm_unit_size: + 2026: 17 + in_ccdf_countable_income: 12_021 + is_in_ccdf_enrolled: false + u35: + members: [p35] + spm_unit_size: + 2026: 18 + in_ccdf_countable_income: 12_659 + is_in_ccdf_enrolled: false + u36: + members: [p36] + spm_unit_size: + 2026: 18 + in_ccdf_countable_income: 12_660 + is_in_ccdf_enrolled: false + u37: + members: [p37] + spm_unit_size: + 2026: 19 + in_ccdf_countable_income: 13_028 + is_in_ccdf_enrolled: false + u38: + members: [p38] + spm_unit_size: + 2026: 19 + in_ccdf_countable_income: 13_029 + is_in_ccdf_enrolled: false + u39: + members: [p39] + spm_unit_size: + 2026: 20 + in_ccdf_countable_income: 13_257 + is_in_ccdf_enrolled: false + u40: + members: [p40] + spm_unit_size: + 2026: 20 + in_ccdf_countable_income: 13_258 + is_in_ccdf_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: IN + h2: + members: [p2] + state_code: + 2026: IN + h3: + members: [p3] + state_code: + 2026: IN + h4: + members: [p4] + state_code: + 2026: IN + h5: + members: [p5] + state_code: + 2026: IN + h6: + members: [p6] + state_code: + 2026: IN + h7: + members: [p7] + state_code: + 2026: IN + h8: + members: [p8] + state_code: + 2026: IN + h9: + members: [p9] + state_code: + 2026: IN + h10: + members: [p10] + state_code: + 2026: IN + h11: + members: [p11] + state_code: + 2026: IN + h12: + members: [p12] + state_code: + 2026: IN + h13: + members: [p13] + state_code: + 2026: IN + h14: + members: [p14] + state_code: + 2026: IN + h15: + members: [p15] + state_code: + 2026: IN + h16: + members: [p16] + state_code: + 2026: IN + h17: + members: [p17] + state_code: + 2026: IN + h18: + members: [p18] + state_code: + 2026: IN + h19: + members: [p19] + state_code: + 2026: IN + h20: + members: [p20] + state_code: + 2026: IN + h21: + members: [p21] + state_code: + 2026: IN + h22: + members: [p22] + state_code: + 2026: IN + h23: + members: [p23] + state_code: + 2026: IN + h24: + members: [p24] + state_code: + 2026: IN + h25: + members: [p25] + state_code: + 2026: IN + h26: + members: [p26] + state_code: + 2026: IN + h27: + members: [p27] + state_code: + 2026: IN + h28: + members: [p28] + state_code: + 2026: IN + h29: + members: [p29] + state_code: + 2026: IN + h30: + members: [p30] + state_code: + 2026: IN + h31: + members: [p31] + state_code: + 2026: IN + h32: + members: [p32] + state_code: + 2026: IN + h33: + members: [p33] + state_code: + 2026: IN + h34: + members: [p34] + state_code: + 2026: IN + h35: + members: [p35] + state_code: + 2026: IN + h36: + members: [p36] + state_code: + 2026: IN + h37: + members: [p37] + state_code: + 2026: IN + h38: + members: [p38] + state_code: + 2026: IN + h39: + members: [p39] + state_code: + 2026: IN + h40: + members: [p40] + state_code: + 2026: IN + output: + # 135% of the 2026 guideline, sizes 1 to 18. For 19 and 20 people the + # chart's cap binds instead: 85% of the October 2025 state median income, + # rounded up to the next dollar. + in_ccdf_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: FSSA's chart effective April 5, 2026 holds enrolled families at every family size in May 2026. + period: 2026-05 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + p25: + age: + 2026: 30 + p26: + age: + 2026: 30 + p27: + age: + 2026: 30 + p28: + age: + 2026: 30 + p29: + age: + 2026: 30 + p30: + age: + 2026: 30 + p31: + age: + 2026: 30 + p32: + age: + 2026: 30 + p33: + age: + 2026: 30 + p34: + age: + 2026: 30 + p35: + age: + 2026: 30 + p36: + age: + 2026: 30 + p37: + age: + 2026: 30 + p38: + age: + 2026: 30 + p39: + age: + 2026: 30 + p40: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + in_ccdf_countable_income: 3_962 + is_in_ccdf_enrolled: true + u2: + members: [p2] + spm_unit_size: + 2026: 1 + in_ccdf_countable_income: 3_963 + is_in_ccdf_enrolled: true + u3: + members: [p3] + spm_unit_size: + 2026: 2 + in_ccdf_countable_income: 5_181 + is_in_ccdf_enrolled: true + u4: + members: [p4] + spm_unit_size: + 2026: 2 + in_ccdf_countable_income: 5_182 + is_in_ccdf_enrolled: true + u5: + members: [p5] + spm_unit_size: + 2026: 3 + in_ccdf_countable_income: 6_400 + is_in_ccdf_enrolled: true + u6: + members: [p6] + spm_unit_size: + 2026: 3 + in_ccdf_countable_income: 6_401 + is_in_ccdf_enrolled: true + u7: + members: [p7] + spm_unit_size: + 2026: 4 + in_ccdf_countable_income: 7_619 + is_in_ccdf_enrolled: true + u8: + members: [p8] + spm_unit_size: + 2026: 4 + in_ccdf_countable_income: 7_620 + is_in_ccdf_enrolled: true + u9: + members: [p9] + spm_unit_size: + 2026: 5 + in_ccdf_countable_income: 8_838 + is_in_ccdf_enrolled: true + u10: + members: [p10] + spm_unit_size: + 2026: 5 + in_ccdf_countable_income: 8_839 + is_in_ccdf_enrolled: true + u11: + members: [p11] + spm_unit_size: + 2026: 6 + in_ccdf_countable_income: 10_057 + is_in_ccdf_enrolled: true + u12: + members: [p12] + spm_unit_size: + 2026: 6 + in_ccdf_countable_income: 10_058 + is_in_ccdf_enrolled: true + u13: + members: [p13] + spm_unit_size: + 2026: 7 + in_ccdf_countable_income: 10_285 + is_in_ccdf_enrolled: true + u14: + members: [p14] + spm_unit_size: + 2026: 7 + in_ccdf_countable_income: 10_286 + is_in_ccdf_enrolled: true + u15: + members: [p15] + spm_unit_size: + 2026: 8 + in_ccdf_countable_income: 10_514 + is_in_ccdf_enrolled: true + u16: + members: [p16] + spm_unit_size: + 2026: 8 + in_ccdf_countable_income: 10_515 + is_in_ccdf_enrolled: true + u17: + members: [p17] + spm_unit_size: + 2026: 9 + in_ccdf_countable_income: 10_743 + is_in_ccdf_enrolled: true + u18: + members: [p18] + spm_unit_size: + 2026: 9 + in_ccdf_countable_income: 10_744 + is_in_ccdf_enrolled: true + u19: + members: [p19] + spm_unit_size: + 2026: 10 + in_ccdf_countable_income: 10_971 + is_in_ccdf_enrolled: true + u20: + members: [p20] + spm_unit_size: + 2026: 10 + in_ccdf_countable_income: 10_972 + is_in_ccdf_enrolled: true + u21: + members: [p21] + spm_unit_size: + 2026: 11 + in_ccdf_countable_income: 11_200 + is_in_ccdf_enrolled: true + u22: + members: [p22] + spm_unit_size: + 2026: 11 + in_ccdf_countable_income: 11_201 + is_in_ccdf_enrolled: true + u23: + members: [p23] + spm_unit_size: + 2026: 12 + in_ccdf_countable_income: 11_428 + is_in_ccdf_enrolled: true + u24: + members: [p24] + spm_unit_size: + 2026: 12 + in_ccdf_countable_income: 11_429 + is_in_ccdf_enrolled: true + u25: + members: [p25] + spm_unit_size: + 2026: 13 + in_ccdf_countable_income: 11_657 + is_in_ccdf_enrolled: true + u26: + members: [p26] + spm_unit_size: + 2026: 13 + in_ccdf_countable_income: 11_658 + is_in_ccdf_enrolled: true + u27: + members: [p27] + spm_unit_size: + 2026: 14 + in_ccdf_countable_income: 11_885 + is_in_ccdf_enrolled: true + u28: + members: [p28] + spm_unit_size: + 2026: 14 + in_ccdf_countable_income: 11_886 + is_in_ccdf_enrolled: true + u29: + members: [p29] + spm_unit_size: + 2026: 15 + in_ccdf_countable_income: 12_114 + is_in_ccdf_enrolled: true + u30: + members: [p30] + spm_unit_size: + 2026: 15 + in_ccdf_countable_income: 12_115 + is_in_ccdf_enrolled: true + u31: + members: [p31] + spm_unit_size: + 2026: 16 + in_ccdf_countable_income: 12_342 + is_in_ccdf_enrolled: true + u32: + members: [p32] + spm_unit_size: + 2026: 16 + in_ccdf_countable_income: 12_343 + is_in_ccdf_enrolled: true + u33: + members: [p33] + spm_unit_size: + 2026: 17 + in_ccdf_countable_income: 12_571 + is_in_ccdf_enrolled: true + u34: + members: [p34] + spm_unit_size: + 2026: 17 + in_ccdf_countable_income: 12_572 + is_in_ccdf_enrolled: true + u35: + members: [p35] + spm_unit_size: + 2026: 18 + in_ccdf_countable_income: 12_800 + is_in_ccdf_enrolled: true + u36: + members: [p36] + spm_unit_size: + 2026: 18 + in_ccdf_countable_income: 12_801 + is_in_ccdf_enrolled: true + u37: + members: [p37] + spm_unit_size: + 2026: 19 + in_ccdf_countable_income: 13_028 + is_in_ccdf_enrolled: true + u38: + members: [p38] + spm_unit_size: + 2026: 19 + in_ccdf_countable_income: 13_029 + is_in_ccdf_enrolled: true + u39: + members: [p39] + spm_unit_size: + 2026: 20 + in_ccdf_countable_income: 13_257 + is_in_ccdf_enrolled: true + u40: + members: [p40] + spm_unit_size: + 2026: 20 + in_ccdf_countable_income: 13_258 + is_in_ccdf_enrolled: true + households: + h1: + members: [p1] + state_code: + 2026: IN + h2: + members: [p2] + state_code: + 2026: IN + h3: + members: [p3] + state_code: + 2026: IN + h4: + members: [p4] + state_code: + 2026: IN + h5: + members: [p5] + state_code: + 2026: IN + h6: + members: [p6] + state_code: + 2026: IN + h7: + members: [p7] + state_code: + 2026: IN + h8: + members: [p8] + state_code: + 2026: IN + h9: + members: [p9] + state_code: + 2026: IN + h10: + members: [p10] + state_code: + 2026: IN + h11: + members: [p11] + state_code: + 2026: IN + h12: + members: [p12] + state_code: + 2026: IN + h13: + members: [p13] + state_code: + 2026: IN + h14: + members: [p14] + state_code: + 2026: IN + h15: + members: [p15] + state_code: + 2026: IN + h16: + members: [p16] + state_code: + 2026: IN + h17: + members: [p17] + state_code: + 2026: IN + h18: + members: [p18] + state_code: + 2026: IN + h19: + members: [p19] + state_code: + 2026: IN + h20: + members: [p20] + state_code: + 2026: IN + h21: + members: [p21] + state_code: + 2026: IN + h22: + members: [p22] + state_code: + 2026: IN + h23: + members: [p23] + state_code: + 2026: IN + h24: + members: [p24] + state_code: + 2026: IN + h25: + members: [p25] + state_code: + 2026: IN + h26: + members: [p26] + state_code: + 2026: IN + h27: + members: [p27] + state_code: + 2026: IN + h28: + members: [p28] + state_code: + 2026: IN + h29: + members: [p29] + state_code: + 2026: IN + h30: + members: [p30] + state_code: + 2026: IN + h31: + members: [p31] + state_code: + 2026: IN + h32: + members: [p32] + state_code: + 2026: IN + h33: + members: [p33] + state_code: + 2026: IN + h34: + members: [p34] + state_code: + 2026: IN + h35: + members: [p35] + state_code: + 2026: IN + h36: + members: [p36] + state_code: + 2026: IN + h37: + members: [p37] + state_code: + 2026: IN + h38: + members: [p38] + state_code: + 2026: IN + h39: + members: [p39] + state_code: + 2026: IN + h40: + members: [p40] + state_code: + 2026: IN + output: + # The Max SMI column, sizes 1 to 20: 85% of the October 2025 state median + # income, rounded up to the next dollar. + in_ccdf_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: FSSA's chart effective March 23, 2025 still holds at every family size in January 2026. + period: 2026-01 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + p25: + age: + 2026: 30 + p26: + age: + 2026: 30 + p27: + age: + 2026: 30 + p28: + age: + 2026: 30 + p29: + age: + 2026: 30 + p30: + age: + 2026: 30 + p31: + age: + 2026: 30 + p32: + age: + 2026: 30 + p33: + age: + 2026: 30 + p34: + age: + 2026: 30 + p35: + age: + 2026: 30 + p36: + age: + 2026: 30 + p37: + age: + 2026: 30 + p38: + age: + 2026: 30 + p39: + age: + 2026: 30 + p40: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + in_ccdf_countable_income: 1_956 + is_in_ccdf_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 1 + in_ccdf_countable_income: 1_957 + is_in_ccdf_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 2 + in_ccdf_countable_income: 2_644 + is_in_ccdf_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 2 + in_ccdf_countable_income: 2_645 + is_in_ccdf_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 3 + in_ccdf_countable_income: 3_331 + is_in_ccdf_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 3 + in_ccdf_countable_income: 3_332 + is_in_ccdf_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 4 + in_ccdf_countable_income: 4_019 + is_in_ccdf_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 4 + in_ccdf_countable_income: 4_020 + is_in_ccdf_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 5 + in_ccdf_countable_income: 4_706 + is_in_ccdf_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 5 + in_ccdf_countable_income: 4_707 + is_in_ccdf_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 6 + in_ccdf_countable_income: 5_394 + is_in_ccdf_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 6 + in_ccdf_countable_income: 5_395 + is_in_ccdf_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 7 + in_ccdf_countable_income: 6_081 + is_in_ccdf_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 7 + in_ccdf_countable_income: 6_082 + is_in_ccdf_enrolled: false + u15: + members: [p15] + spm_unit_size: + 2026: 8 + in_ccdf_countable_income: 6_769 + is_in_ccdf_enrolled: false + u16: + members: [p16] + spm_unit_size: + 2026: 8 + in_ccdf_countable_income: 6_770 + is_in_ccdf_enrolled: false + u17: + members: [p17] + spm_unit_size: + 2026: 9 + in_ccdf_countable_income: 7_456 + is_in_ccdf_enrolled: false + u18: + members: [p18] + spm_unit_size: + 2026: 9 + in_ccdf_countable_income: 7_457 + is_in_ccdf_enrolled: false + u19: + members: [p19] + spm_unit_size: + 2026: 10 + in_ccdf_countable_income: 8_144 + is_in_ccdf_enrolled: false + u20: + members: [p20] + spm_unit_size: + 2026: 10 + in_ccdf_countable_income: 8_145 + is_in_ccdf_enrolled: false + u21: + members: [p21] + spm_unit_size: + 2026: 11 + in_ccdf_countable_income: 8_831 + is_in_ccdf_enrolled: false + u22: + members: [p22] + spm_unit_size: + 2026: 11 + in_ccdf_countable_income: 8_832 + is_in_ccdf_enrolled: false + u23: + members: [p23] + spm_unit_size: + 2026: 12 + in_ccdf_countable_income: 9_519 + is_in_ccdf_enrolled: false + u24: + members: [p24] + spm_unit_size: + 2026: 12 + in_ccdf_countable_income: 9_520 + is_in_ccdf_enrolled: false + u25: + members: [p25] + spm_unit_size: + 2026: 13 + in_ccdf_countable_income: 10_206 + is_in_ccdf_enrolled: false + u26: + members: [p26] + spm_unit_size: + 2026: 13 + in_ccdf_countable_income: 10_207 + is_in_ccdf_enrolled: false + u27: + members: [p27] + spm_unit_size: + 2026: 14 + in_ccdf_countable_income: 10_894 + is_in_ccdf_enrolled: false + u28: + members: [p28] + spm_unit_size: + 2026: 14 + in_ccdf_countable_income: 10_895 + is_in_ccdf_enrolled: false + u29: + members: [p29] + spm_unit_size: + 2026: 15 + in_ccdf_countable_income: 11_581 + is_in_ccdf_enrolled: false + u30: + members: [p30] + spm_unit_size: + 2026: 15 + in_ccdf_countable_income: 11_582 + is_in_ccdf_enrolled: false + u31: + members: [p31] + spm_unit_size: + 2026: 16 + in_ccdf_countable_income: 11_857 + is_in_ccdf_enrolled: false + u32: + members: [p32] + spm_unit_size: + 2026: 16 + in_ccdf_countable_income: 11_858 + is_in_ccdf_enrolled: false + u33: + members: [p33] + spm_unit_size: + 2026: 17 + in_ccdf_countable_income: 12_076 + is_in_ccdf_enrolled: false + u34: + members: [p34] + spm_unit_size: + 2026: 17 + in_ccdf_countable_income: 12_077 + is_in_ccdf_enrolled: false + u35: + members: [p35] + spm_unit_size: + 2026: 18 + in_ccdf_countable_income: 12_296 + is_in_ccdf_enrolled: false + u36: + members: [p36] + spm_unit_size: + 2026: 18 + in_ccdf_countable_income: 12_297 + is_in_ccdf_enrolled: false + u37: + members: [p37] + spm_unit_size: + 2026: 19 + in_ccdf_countable_income: 12_516 + is_in_ccdf_enrolled: false + u38: + members: [p38] + spm_unit_size: + 2026: 19 + in_ccdf_countable_income: 12_517 + is_in_ccdf_enrolled: false + u39: + members: [p39] + spm_unit_size: + 2026: 20 + in_ccdf_countable_income: 12_735 + is_in_ccdf_enrolled: false + u40: + members: [p40] + spm_unit_size: + 2026: 20 + in_ccdf_countable_income: 12_736 + is_in_ccdf_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: IN + h2: + members: [p2] + state_code: + 2026: IN + h3: + members: [p3] + state_code: + 2026: IN + h4: + members: [p4] + state_code: + 2026: IN + h5: + members: [p5] + state_code: + 2026: IN + h6: + members: [p6] + state_code: + 2026: IN + h7: + members: [p7] + state_code: + 2026: IN + h8: + members: [p8] + state_code: + 2026: IN + h9: + members: [p9] + state_code: + 2026: IN + h10: + members: [p10] + state_code: + 2026: IN + h11: + members: [p11] + state_code: + 2026: IN + h12: + members: [p12] + state_code: + 2026: IN + h13: + members: [p13] + state_code: + 2026: IN + h14: + members: [p14] + state_code: + 2026: IN + h15: + members: [p15] + state_code: + 2026: IN + h16: + members: [p16] + state_code: + 2026: IN + h17: + members: [p17] + state_code: + 2026: IN + h18: + members: [p18] + state_code: + 2026: IN + h19: + members: [p19] + state_code: + 2026: IN + h20: + members: [p20] + state_code: + 2026: IN + h21: + members: [p21] + state_code: + 2026: IN + h22: + members: [p22] + state_code: + 2026: IN + h23: + members: [p23] + state_code: + 2026: IN + h24: + members: [p24] + state_code: + 2026: IN + h25: + members: [p25] + state_code: + 2026: IN + h26: + members: [p26] + state_code: + 2026: IN + h27: + members: [p27] + state_code: + 2026: IN + h28: + members: [p28] + state_code: + 2026: IN + h29: + members: [p29] + state_code: + 2026: IN + h30: + members: [p30] + state_code: + 2026: IN + h31: + members: [p31] + state_code: + 2026: IN + h32: + members: [p32] + state_code: + 2026: IN + h33: + members: [p33] + state_code: + 2026: IN + h34: + members: [p34] + state_code: + 2026: IN + h35: + members: [p35] + state_code: + 2026: IN + h36: + members: [p36] + state_code: + 2026: IN + h37: + members: [p37] + state_code: + 2026: IN + h38: + members: [p38] + state_code: + 2026: IN + h39: + members: [p39] + state_code: + 2026: IN + h40: + members: [p40] + state_code: + 2026: IN + output: + # 150% of the 2025 guideline, sizes 1 to 15. From 16 people the chart's cap + # binds instead: 85% of the October 2024 state median income, rounded up + # to the next dollar. + in_ccdf_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: FSSA's chart effective March 23, 2025 still holds enrolled families at every family size in January 2026. + period: 2026-01 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + p25: + age: + 2026: 30 + p26: + age: + 2026: 30 + p27: + age: + 2026: 30 + p28: + age: + 2026: 30 + p29: + age: + 2026: 30 + p30: + age: + 2026: 30 + p31: + age: + 2026: 30 + p32: + age: + 2026: 30 + p33: + age: + 2026: 30 + p34: + age: + 2026: 30 + p35: + age: + 2026: 30 + p36: + age: + 2026: 30 + p37: + age: + 2026: 30 + p38: + age: + 2026: 30 + p39: + age: + 2026: 30 + p40: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + in_ccdf_countable_income: 3_806 + is_in_ccdf_enrolled: true + u2: + members: [p2] + spm_unit_size: + 2026: 1 + in_ccdf_countable_income: 3_807 + is_in_ccdf_enrolled: true + u3: + members: [p3] + spm_unit_size: + 2026: 2 + in_ccdf_countable_income: 4_977 + is_in_ccdf_enrolled: true + u4: + members: [p4] + spm_unit_size: + 2026: 2 + in_ccdf_countable_income: 4_978 + is_in_ccdf_enrolled: true + u5: + members: [p5] + spm_unit_size: + 2026: 3 + in_ccdf_countable_income: 6_148 + is_in_ccdf_enrolled: true + u6: + members: [p6] + spm_unit_size: + 2026: 3 + in_ccdf_countable_income: 6_149 + is_in_ccdf_enrolled: true + u7: + members: [p7] + spm_unit_size: + 2026: 4 + in_ccdf_countable_income: 7_319 + is_in_ccdf_enrolled: true + u8: + members: [p8] + spm_unit_size: + 2026: 4 + in_ccdf_countable_income: 7_320 + is_in_ccdf_enrolled: true + u9: + members: [p9] + spm_unit_size: + 2026: 5 + in_ccdf_countable_income: 8_490 + is_in_ccdf_enrolled: true + u10: + members: [p10] + spm_unit_size: + 2026: 5 + in_ccdf_countable_income: 8_491 + is_in_ccdf_enrolled: true + u11: + members: [p11] + spm_unit_size: + 2026: 6 + in_ccdf_countable_income: 9_661 + is_in_ccdf_enrolled: true + u12: + members: [p12] + spm_unit_size: + 2026: 6 + in_ccdf_countable_income: 9_662 + is_in_ccdf_enrolled: true + u13: + members: [p13] + spm_unit_size: + 2026: 7 + in_ccdf_countable_income: 9_881 + is_in_ccdf_enrolled: true + u14: + members: [p14] + spm_unit_size: + 2026: 7 + in_ccdf_countable_income: 9_882 + is_in_ccdf_enrolled: true + u15: + members: [p15] + spm_unit_size: + 2026: 8 + in_ccdf_countable_income: 10_100 + is_in_ccdf_enrolled: true + u16: + members: [p16] + spm_unit_size: + 2026: 8 + in_ccdf_countable_income: 10_101 + is_in_ccdf_enrolled: true + u17: + members: [p17] + spm_unit_size: + 2026: 9 + in_ccdf_countable_income: 10_320 + is_in_ccdf_enrolled: true + u18: + members: [p18] + spm_unit_size: + 2026: 9 + in_ccdf_countable_income: 10_321 + is_in_ccdf_enrolled: true + u19: + members: [p19] + spm_unit_size: + 2026: 10 + in_ccdf_countable_income: 10_540 + is_in_ccdf_enrolled: true + u20: + members: [p20] + spm_unit_size: + 2026: 10 + in_ccdf_countable_income: 10_541 + is_in_ccdf_enrolled: true + u21: + members: [p21] + spm_unit_size: + 2026: 11 + in_ccdf_countable_income: 10_759 + is_in_ccdf_enrolled: true + u22: + members: [p22] + spm_unit_size: + 2026: 11 + in_ccdf_countable_income: 10_760 + is_in_ccdf_enrolled: true + u23: + members: [p23] + spm_unit_size: + 2026: 12 + in_ccdf_countable_income: 10_979 + is_in_ccdf_enrolled: true + u24: + members: [p24] + spm_unit_size: + 2026: 12 + in_ccdf_countable_income: 10_980 + is_in_ccdf_enrolled: true + u25: + members: [p25] + spm_unit_size: + 2026: 13 + in_ccdf_countable_income: 11_198 + is_in_ccdf_enrolled: true + u26: + members: [p26] + spm_unit_size: + 2026: 13 + in_ccdf_countable_income: 11_199 + is_in_ccdf_enrolled: true + u27: + members: [p27] + spm_unit_size: + 2026: 14 + in_ccdf_countable_income: 11_418 + is_in_ccdf_enrolled: true + u28: + members: [p28] + spm_unit_size: + 2026: 14 + in_ccdf_countable_income: 11_419 + is_in_ccdf_enrolled: true + u29: + members: [p29] + spm_unit_size: + 2026: 15 + in_ccdf_countable_income: 11_637 + is_in_ccdf_enrolled: true + u30: + members: [p30] + spm_unit_size: + 2026: 15 + in_ccdf_countable_income: 11_638 + is_in_ccdf_enrolled: true + u31: + members: [p31] + spm_unit_size: + 2026: 16 + in_ccdf_countable_income: 11_857 + is_in_ccdf_enrolled: true + u32: + members: [p32] + spm_unit_size: + 2026: 16 + in_ccdf_countable_income: 11_858 + is_in_ccdf_enrolled: true + u33: + members: [p33] + spm_unit_size: + 2026: 17 + in_ccdf_countable_income: 12_076 + is_in_ccdf_enrolled: true + u34: + members: [p34] + spm_unit_size: + 2026: 17 + in_ccdf_countable_income: 12_077 + is_in_ccdf_enrolled: true + u35: + members: [p35] + spm_unit_size: + 2026: 18 + in_ccdf_countable_income: 12_296 + is_in_ccdf_enrolled: true + u36: + members: [p36] + spm_unit_size: + 2026: 18 + in_ccdf_countable_income: 12_297 + is_in_ccdf_enrolled: true + u37: + members: [p37] + spm_unit_size: + 2026: 19 + in_ccdf_countable_income: 12_516 + is_in_ccdf_enrolled: true + u38: + members: [p38] + spm_unit_size: + 2026: 19 + in_ccdf_countable_income: 12_517 + is_in_ccdf_enrolled: true + u39: + members: [p39] + spm_unit_size: + 2026: 20 + in_ccdf_countable_income: 12_735 + is_in_ccdf_enrolled: true + u40: + members: [p40] + spm_unit_size: + 2026: 20 + in_ccdf_countable_income: 12_736 + is_in_ccdf_enrolled: true + households: + h1: + members: [p1] + state_code: + 2026: IN + h2: + members: [p2] + state_code: + 2026: IN + h3: + members: [p3] + state_code: + 2026: IN + h4: + members: [p4] + state_code: + 2026: IN + h5: + members: [p5] + state_code: + 2026: IN + h6: + members: [p6] + state_code: + 2026: IN + h7: + members: [p7] + state_code: + 2026: IN + h8: + members: [p8] + state_code: + 2026: IN + h9: + members: [p9] + state_code: + 2026: IN + h10: + members: [p10] + state_code: + 2026: IN + h11: + members: [p11] + state_code: + 2026: IN + h12: + members: [p12] + state_code: + 2026: IN + h13: + members: [p13] + state_code: + 2026: IN + h14: + members: [p14] + state_code: + 2026: IN + h15: + members: [p15] + state_code: + 2026: IN + h16: + members: [p16] + state_code: + 2026: IN + h17: + members: [p17] + state_code: + 2026: IN + h18: + members: [p18] + state_code: + 2026: IN + h19: + members: [p19] + state_code: + 2026: IN + h20: + members: [p20] + state_code: + 2026: IN + h21: + members: [p21] + state_code: + 2026: IN + h22: + members: [p22] + state_code: + 2026: IN + h23: + members: [p23] + state_code: + 2026: IN + h24: + members: [p24] + state_code: + 2026: IN + h25: + members: [p25] + state_code: + 2026: IN + h26: + members: [p26] + state_code: + 2026: IN + h27: + members: [p27] + state_code: + 2026: IN + h28: + members: [p28] + state_code: + 2026: IN + h29: + members: [p29] + state_code: + 2026: IN + h30: + members: [p30] + state_code: + 2026: IN + h31: + members: [p31] + state_code: + 2026: IN + h32: + members: [p32] + state_code: + 2026: IN + h33: + members: [p33] + state_code: + 2026: IN + h34: + members: [p34] + state_code: + 2026: IN + h35: + members: [p35] + state_code: + 2026: IN + h36: + members: [p36] + state_code: + 2026: IN + h37: + members: [p37] + state_code: + 2026: IN + h38: + members: [p38] + state_code: + 2026: IN + h39: + members: [p39] + state_code: + 2026: IN + h40: + members: [p40] + state_code: + 2026: IN + output: + # The Max SMI column, sizes 1 to 20: 85% of the October 2024 state median + # income, rounded up to the next dollar. + in_ccdf_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: The CCDF plan's limits effective March 31, 2024 hold at every family size in June 2024. + period: 2024-06 + input: + people: + p1: + age: + 2024: 30 + p2: + age: + 2024: 30 + p3: + age: + 2024: 30 + p4: + age: + 2024: 30 + p5: + age: + 2024: 30 + p6: + age: + 2024: 30 + p7: + age: + 2024: 30 + p8: + age: + 2024: 30 + p9: + age: + 2024: 30 + p10: + age: + 2024: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2024: 1 + in_ccdf_countable_income: 1_883 + is_in_ccdf_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2024: 1 + in_ccdf_countable_income: 1_884 + is_in_ccdf_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2024: 2 + in_ccdf_countable_income: 2_555 + is_in_ccdf_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2024: 2 + in_ccdf_countable_income: 2_556 + is_in_ccdf_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2024: 3 + in_ccdf_countable_income: 3_228 + is_in_ccdf_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2024: 3 + in_ccdf_countable_income: 3_229 + is_in_ccdf_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2024: 4 + in_ccdf_countable_income: 3_900 + is_in_ccdf_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2024: 4 + in_ccdf_countable_income: 3_901 + is_in_ccdf_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2024: 5 + in_ccdf_countable_income: 4_573 + is_in_ccdf_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2024: 5 + in_ccdf_countable_income: 4_574 + is_in_ccdf_enrolled: false + households: + h1: + members: [p1] + state_code: + 2024: IN + h2: + members: [p2] + state_code: + 2024: IN + h3: + members: [p3] + state_code: + 2024: IN + h4: + members: [p4] + state_code: + 2024: IN + h5: + members: [p5] + state_code: + 2024: IN + h6: + members: [p6] + state_code: + 2024: IN + h7: + members: [p7] + state_code: + 2024: IN + h8: + members: [p8] + state_code: + 2024: IN + h9: + members: [p9] + state_code: + 2024: IN + h10: + members: [p10] + state_code: + 2024: IN + output: + # 150% of the 2024 guideline, sizes 1 to 5. + in_ccdf_income_eligible: [true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/in_ccdf.yaml b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/in_ccdf.yaml index c71d2d3017a..270c8cc44ad 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/in_ccdf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/in_ccdf.yaml @@ -12,7 +12,7 @@ people: person1: age: 35 - employment_income: 22_720 # ~105% FPL -> copay factor 0.0116 + employment_income: 22_720 # ~107% FPL -> copay factor 0.0116 person2: age: 0.5 is_tax_unit_dependent: true @@ -65,7 +65,7 @@ people: person1: age: 35 - employment_income: 27_050 # ~125% FPL, factor 0.0163 + employment_income: 27_050 # ~128% FPL, factor 0.0163 person2: age: 8 is_tax_unit_dependent: true @@ -176,7 +176,7 @@ people: person1: age: 35 - employment_income: 22_720 # ~83% FPL (3-person) -> zero copay + employment_income: 22_720 # ~85% FPL (3-person) -> zero copay person2: age: 0.5 # infant is_tax_unit_dependent: true @@ -198,6 +198,6 @@ output: # Infant rate 374.4 * 52/12 = 1,622.40; school-age before/after 71.5 * # 52/12 = 309.83; combined rate = 1,932.23. Expenses 5,000/mo capped to - # 1,932.23. Copay: 3-person FPG 2026 = 27,320/yr; income 22,720 -> ratio - # ~0.83 < 100% FPL -> zero copay. Benefit = 1,932.23 - 0 = 1,932.23. + # 1,932.23. Copay: 3-person FPG in January 2026 = 26,650/yr; income 22,720 -> ratio + # ~0.85 < 100% FPL -> zero copay. Benefit = 1,932.23 - 0 = 1,932.23. in_ccdf: 1_932.23 diff --git a/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/integration.yaml index 7128eb4c8a6..478a5c57344 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/integration.yaml @@ -4,8 +4,8 @@ # All monetary rates are Marion County FY2023 weekly rates after the Oct 5, # 2025 percentage cuts, * (52 / 12); the copay fee factor is the new-enrollee # (Year 1-3) tier of the 2026 schedule. -# 2-person FPG 2026 = 21,640/yr; 4-person = 33,000/yr. At 2026-01 the get-on -# rate is 1.5 (150% FPL). +# January 2026 still uses the 2025 guideline: 2-person FPG = 21,150/yr; 4-person = +# 32,150/yr. At 2026-01 the get-on rate is 1.5 (150% FPL). - name: Case 1, single working parent, infant in PTQ-4 licensed center, high expenses. period: 2026-01 @@ -14,7 +14,7 @@ people: person1: age: 30 - employment_income: 22_720 # ~105% FPL + employment_income: 22_720 # ~107% FPL person2: age: 0.5 is_tax_unit_dependent: true @@ -73,7 +73,7 @@ state_code: IN output: in_ccdf_eligible: true - # 4-person income 2,333.33/mo < 100% FPL (2,750) -> copay 0. + # 4-person income 2,333.33/mo < 100% FPL (2,679.17) -> copay 0. # toddler 176.4 + three-to-five 133.45 = 309.85/wk * 52/12 = 1,342.68/mo. # expenses 2,000 capped at 1,342.68; benefit = 1,342.68 - 0 = 1,342.68/mo in_ccdf: 1_342.68 @@ -102,7 +102,7 @@ state_code: IN output: in_ccdf_eligible: true - # income 3,750/mo, ratio ~2.08 FPL -> factor 0.0372. + # income 3,750/mo, ratio ~2.13 FPL -> factor 0.0372. # rate 374.4 * 52/12 = 1,622.40; copay 3,750 * 0.0372 = 139.50/wk -> 604.50/mo. # benefit = 1,622.40 - 604.50 = 1,017.90/mo in_ccdf: 1_017.90 @@ -114,7 +114,7 @@ people: person1: age: 40 - employment_income: 21_640 # 100% FPL -> copay 0 + employment_income: 21_150 # 100% FPL -> copay 0 person2: age: 15 is_tax_unit_dependent: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_income_eligible.yaml index ef692523db0..8644a0bbcad 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/msde/ccs/md_ccs_income_eligible.yaml @@ -140,3 +140,825 @@ # Monthly 75% SMI threshold: 124,807 * 0.75 / 12 = 7,800.44 # 8,333.33 > 7,800.44 -> not eligible md_ccs_income_eligible: false + +# MSDE posts an Initial Income Scale effective December 15, 2024 ($94,026 a year for three) +# and a Continuation Income Scale effective April 22, 2024 ($106,563), both at the federal +# fiscal 2025 median, and still posts them in October 2026. +- name: In November 2024 a new family of three still faced 75% of the median MSDE froze at its 2021 level. + period: 2024-11 + input: + people: + p1_1: + age: + 2024: 30 + p1_2: + age: + 2024: 8 + p1_3: + age: + 2024: 5 + p2_1: + age: + 2024: 30 + p2_2: + age: + 2024: 8 + p2_3: + age: + 2024: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + md_ccs_countable_income: 6_552 + md_ccs_enrolled: false + u2: + members: [p2_1, p2_2, p2_3] + md_ccs_countable_income: 6_553 + md_ccs_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2024: MD + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2024: MD + output: + # 75% * 124_807 * 0.84 / 12 = 6_552.37 + md_ccs_income_eligible: [true, false] + +- name: In March 2026 a new family of three faces the posted Initial Income Scale of $94,026 a year. + period: 2026-03 + input: + people: + p1_1: + age: + 2026: 30 + p1_2: + age: + 2026: 8 + p1_3: + age: + 2026: 5 + p2_1: + age: + 2026: 30 + p2_2: + age: + 2026: 8 + p2_3: + age: + 2026: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + md_ccs_countable_income: 7_835 + md_ccs_enrolled: false + u2: + members: [p2_1, p2_2, p2_3] + md_ccs_countable_income: 7_836 + md_ccs_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2026: MD + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2026: MD + output: + # 75% of the federal fiscal 2025 median: 0.75 * 149_249 * 0.84 / 12 = 7_835.57. + # The federal fiscal 2026 median would give 0.75 * 154_117 * 0.84 / 12 = 8_091.14 + md_ccs_income_eligible: [true, false] + +- name: In April 2024 an enrolled family of three faced 85% of the median MSDE froze at its 2021 level. + period: 2024-04 + input: + people: + p1_1: + age: + 2024: 30 + p1_2: + age: + 2024: 8 + p1_3: + age: + 2024: 5 + p2_1: + age: + 2024: 30 + p2_2: + age: + 2024: 8 + p2_3: + age: + 2024: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + md_ccs_countable_income: 7_426 + md_ccs_enrolled: true + u2: + members: [p2_1, p2_2, p2_3] + md_ccs_countable_income: 7_427 + md_ccs_enrolled: true + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2024: MD + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2024: MD + output: + # 0.85 * 124_807 * 0.84 / 12 = 7_426.02; the posted scale of April 22, 2024 shows from May + md_ccs_income_eligible: [true, false] + +- name: In May 2024 an enrolled family of three faces the posted Continuation Income Scale of $106,563 a year. + period: 2024-05 + input: + people: + p1_1: + age: + 2024: 30 + p1_2: + age: + 2024: 8 + p1_3: + age: + 2024: 5 + p2_1: + age: + 2024: 30 + p2_2: + age: + 2024: 8 + p2_3: + age: + 2024: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + md_ccs_countable_income: 8_880 + md_ccs_enrolled: true + u2: + members: [p2_1, p2_2, p2_3] + md_ccs_countable_income: 8_881 + md_ccs_enrolled: true + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2024: MD + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2024: MD + output: + # 85% of the federal fiscal 2025 median: 0.85 * 149_249 * 0.84 / 12 = 8_880.32 + md_ccs_income_eligible: [true, false] + +- name: In March 2026 an enrolled family of three still faces the posted Continuation Income Scale. + period: 2026-03 + input: + people: + p1_1: + age: + 2026: 30 + p1_2: + age: + 2026: 8 + p1_3: + age: + 2026: 5 + p2_1: + age: + 2026: 30 + p2_2: + age: + 2026: 8 + p2_3: + age: + 2026: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + md_ccs_countable_income: 8_880 + md_ccs_enrolled: true + u2: + members: [p2_1, p2_2, p2_3] + md_ccs_countable_income: 8_881 + md_ccs_enrolled: true + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2026: MD + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2026: MD + output: + # 0.85 * 149_249 * 0.84 / 12 = 8_880.32; the fiscal 2026 median would give 9_170.31 + md_ccs_income_eligible: [true, false] + +# Posted charts: MSDE rounds each cell of its scales, while PolicyEngine computes +# the limits from the federal fiscal 2025 state median income, so the two differ +# by less than $2 a year. Each case puts monthly income $2 a year below each +# printed maximum, which passes, and $2 a year above it, which fails, and lists +# the outcomes in size order. + +- name: MSDE's Initial Income Scale effective December 15, 2024 holds within $2 a year at sizes 2 to 12 in March 2026. + period: 2026-03 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 2 + md_ccs_countable_income: 6_342.91 + md_ccs_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 2 + md_ccs_countable_income: 6_343.25 + md_ccs_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 3 + md_ccs_countable_income: 7_835.33 + md_ccs_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 3 + md_ccs_countable_income: 7_835.67 + md_ccs_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 4 + md_ccs_countable_income: 9_327.83 + md_ccs_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 4 + md_ccs_countable_income: 9_328.17 + md_ccs_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 5 + md_ccs_countable_income: 10_820.33 + md_ccs_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 5 + md_ccs_countable_income: 10_820.67 + md_ccs_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 6 + md_ccs_countable_income: 12_312.83 + md_ccs_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 6 + md_ccs_countable_income: 12_313.17 + md_ccs_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 7 + md_ccs_countable_income: 12_592.66 + md_ccs_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 7 + md_ccs_countable_income: 12_593.00 + md_ccs_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 8 + md_ccs_countable_income: 12_872.50 + md_ccs_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 8 + md_ccs_countable_income: 12_872.84 + md_ccs_enrolled: false + u15: + members: [p15] + spm_unit_size: + 2026: 9 + md_ccs_countable_income: 13_152.33 + md_ccs_enrolled: false + u16: + members: [p16] + spm_unit_size: + 2026: 9 + md_ccs_countable_income: 13_152.67 + md_ccs_enrolled: false + u17: + members: [p17] + spm_unit_size: + 2026: 10 + md_ccs_countable_income: 13_432.16 + md_ccs_enrolled: false + u18: + members: [p18] + spm_unit_size: + 2026: 10 + md_ccs_countable_income: 13_432.50 + md_ccs_enrolled: false + u19: + members: [p19] + spm_unit_size: + 2026: 11 + md_ccs_countable_income: 13_712.00 + md_ccs_enrolled: false + u20: + members: [p20] + spm_unit_size: + 2026: 11 + md_ccs_countable_income: 13_712.34 + md_ccs_enrolled: false + u21: + members: [p21] + spm_unit_size: + 2026: 12 + md_ccs_countable_income: 13_991.83 + md_ccs_enrolled: false + u22: + members: [p22] + spm_unit_size: + 2026: 12 + md_ccs_countable_income: 13_992.17 + md_ccs_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: MD + h2: + members: [p2] + state_code: + 2026: MD + h3: + members: [p3] + state_code: + 2026: MD + h4: + members: [p4] + state_code: + 2026: MD + h5: + members: [p5] + state_code: + 2026: MD + h6: + members: [p6] + state_code: + 2026: MD + h7: + members: [p7] + state_code: + 2026: MD + h8: + members: [p8] + state_code: + 2026: MD + h9: + members: [p9] + state_code: + 2026: MD + h10: + members: [p10] + state_code: + 2026: MD + h11: + members: [p11] + state_code: + 2026: MD + h12: + members: [p12] + state_code: + 2026: MD + h13: + members: [p13] + state_code: + 2026: MD + h14: + members: [p14] + state_code: + 2026: MD + h15: + members: [p15] + state_code: + 2026: MD + h16: + members: [p16] + state_code: + 2026: MD + h17: + members: [p17] + state_code: + 2026: MD + h18: + members: [p18] + state_code: + 2026: MD + h19: + members: [p19] + state_code: + 2026: MD + h20: + members: [p20] + state_code: + 2026: MD + h21: + members: [p21] + state_code: + 2026: MD + h22: + members: [p22] + state_code: + 2026: MD + output: + # Maximum annual income from $76,117 for two to $167,904 for twelve. + md_ccs_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: MSDE's Continuation Income Scale effective April 22, 2024 holds within $2 a year at sizes 2 to 12 in March 2026. + period: 2026-03 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 2 + md_ccs_countable_income: 7_188.66 + md_ccs_enrolled: true + u2: + members: [p2] + spm_unit_size: + 2026: 2 + md_ccs_countable_income: 7_189.00 + md_ccs_enrolled: true + u3: + members: [p3] + spm_unit_size: + 2026: 3 + md_ccs_countable_income: 8_880.08 + md_ccs_enrolled: true + u4: + members: [p4] + spm_unit_size: + 2026: 3 + md_ccs_countable_income: 8_880.42 + md_ccs_enrolled: true + u5: + members: [p5] + spm_unit_size: + 2026: 4 + md_ccs_countable_income: 10_571.58 + md_ccs_enrolled: true + u6: + members: [p6] + spm_unit_size: + 2026: 4 + md_ccs_countable_income: 10_571.92 + md_ccs_enrolled: true + u7: + members: [p7] + spm_unit_size: + 2026: 5 + md_ccs_countable_income: 12_263.08 + md_ccs_enrolled: true + u8: + members: [p8] + spm_unit_size: + 2026: 5 + md_ccs_countable_income: 12_263.42 + md_ccs_enrolled: true + u9: + members: [p9] + spm_unit_size: + 2026: 6 + md_ccs_countable_income: 13_954.58 + md_ccs_enrolled: true + u10: + members: [p10] + spm_unit_size: + 2026: 6 + md_ccs_countable_income: 13_954.92 + md_ccs_enrolled: true + u11: + members: [p11] + spm_unit_size: + 2026: 7 + md_ccs_countable_income: 14_271.66 + md_ccs_enrolled: true + u12: + members: [p12] + spm_unit_size: + 2026: 7 + md_ccs_countable_income: 14_272.00 + md_ccs_enrolled: true + u13: + members: [p13] + spm_unit_size: + 2026: 8 + md_ccs_countable_income: 14_588.83 + md_ccs_enrolled: true + u14: + members: [p14] + spm_unit_size: + 2026: 8 + md_ccs_countable_income: 14_589.17 + md_ccs_enrolled: true + u15: + members: [p15] + spm_unit_size: + 2026: 9 + md_ccs_countable_income: 14_906.00 + md_ccs_enrolled: true + u16: + members: [p16] + spm_unit_size: + 2026: 9 + md_ccs_countable_income: 14_906.34 + md_ccs_enrolled: true + u17: + members: [p17] + spm_unit_size: + 2026: 10 + md_ccs_countable_income: 15_223.16 + md_ccs_enrolled: true + u18: + members: [p18] + spm_unit_size: + 2026: 10 + md_ccs_countable_income: 15_223.50 + md_ccs_enrolled: true + u19: + members: [p19] + spm_unit_size: + 2026: 11 + md_ccs_countable_income: 15_540.33 + md_ccs_enrolled: true + u20: + members: [p20] + spm_unit_size: + 2026: 11 + md_ccs_countable_income: 15_540.67 + md_ccs_enrolled: true + u21: + members: [p21] + spm_unit_size: + 2026: 12 + md_ccs_countable_income: 15_857.50 + md_ccs_enrolled: true + u22: + members: [p22] + spm_unit_size: + 2026: 12 + md_ccs_countable_income: 15_857.84 + md_ccs_enrolled: true + households: + h1: + members: [p1] + state_code: + 2026: MD + h2: + members: [p2] + state_code: + 2026: MD + h3: + members: [p3] + state_code: + 2026: MD + h4: + members: [p4] + state_code: + 2026: MD + h5: + members: [p5] + state_code: + 2026: MD + h6: + members: [p6] + state_code: + 2026: MD + h7: + members: [p7] + state_code: + 2026: MD + h8: + members: [p8] + state_code: + 2026: MD + h9: + members: [p9] + state_code: + 2026: MD + h10: + members: [p10] + state_code: + 2026: MD + h11: + members: [p11] + state_code: + 2026: MD + h12: + members: [p12] + state_code: + 2026: MD + h13: + members: [p13] + state_code: + 2026: MD + h14: + members: [p14] + state_code: + 2026: MD + h15: + members: [p15] + state_code: + 2026: MD + h16: + members: [p16] + state_code: + 2026: MD + h17: + members: [p17] + state_code: + 2026: MD + h18: + members: [p18] + state_code: + 2026: MD + h19: + members: [p19] + state_code: + 2026: MD + h20: + members: [p20] + state_code: + 2026: MD + h21: + members: [p21] + state_code: + 2026: MD + h22: + members: [p22] + state_code: + 2026: MD + output: + # Maximum annual income from $86,266 for two to $190,292 for twelve. + md_ccs_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/eligibility/mo_ccs_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/eligibility/mo_ccs_fpg.yaml new file mode 100644 index 00000000000..68b08e4849a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/eligibility/mo_ccs_fpg.yaml @@ -0,0 +1,87 @@ +# Tests for mo_ccs_fpg (SPMUnit, MONTH). DESE's chart updated July 1, 2026 prints the +# 2025 guideline, and a lag of one holds it through 2026. +- name: 2025-11 uses the 2025 guideline. + period: 2025-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MO + output: + mo_ccs_fpg: 2_220.83 + +- name: 2026-01 uses the 2025 guideline. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MO + output: + mo_ccs_fpg: 2_220.83 + +- name: 2026-10 uses the 2025 guideline. + period: 2026-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_fpg: 2_220.83 + +- name: 2027-01 uses the 2026 guideline. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MO + output: + mo_ccs_fpg: 2_276.67 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.yaml index 17c8a3afbd2..8cc9ede938d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.yaml @@ -180,7 +180,7 @@ people: person1: age: 30 - employment_income: 51_183 + employment_income: 51_180 person2: age: 5 spm_units: @@ -192,7 +192,7 @@ members: [person1, person2] state_code: MO output: - # Monthly income = 51,183 / 12 = 4,265.25 = 242% FPL limit -> <= -> eligible. + # 242% FPL prints as 4,265 on the chart; 51,180 / 12 = 4,265 -> <= -> eligible. mo_ccs_income_eligible: true - name: Case 10, existing family just above 242 percent FPL is ineligible. @@ -299,3 +299,1350 @@ # (85% SMI) -> the 85% SMI cap binds -> ineligible (would be eligible on the # FPL limit alone). mo_ccs_income_eligible: false + +# Tops from DESE's chart headed November 2025 and updated July 1, 2026: 150% of the +# 2025 guideline to the nearest dollar for new applicants, and Transitional Level 2 +# (215%) for existing families from July 1, 2026, when DESE removed Level 3. + +- name: New applicant of 2 at 2,644 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + mo_ccs_adjusted_income: 2_644 + mo_ccs_enrolled: false + households: + household: + members: [person1, person2] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: true + +- name: New applicant of 2 at 2,645 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + mo_ccs_adjusted_income: 2_645 + mo_ccs_enrolled: false + households: + household: + members: [person1, person2] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: false + +- name: New applicant of 3 at 3,331 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 3_331 + mo_ccs_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: true + +- name: New applicant of 3 at 3,332 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 3_332 + mo_ccs_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: false + +- name: New applicant of 4 at 4,019 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + mo_ccs_adjusted_income: 4_019 + mo_ccs_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: true + +- name: New applicant of 4 at 4,020 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + mo_ccs_adjusted_income: 4_020 + mo_ccs_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: false + +- name: New applicant of 3 at 3,331 dollars qualifies in 2025-11. + period: 2025-11 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 3_331 + mo_ccs_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MO + output: + mo_ccs_income_eligible: true + +- name: New applicant of 3 at 3,332 dollars doesn't qualify in 2025-11. + period: 2025-11 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 3_332 + mo_ccs_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MO + output: + mo_ccs_income_eligible: false + +- name: Continuing family of 3 at 5,374 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 5_374 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: true + +- name: Continuing family of 3 at 5,375 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 5_375 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: false + +- name: Continuing family of 3 at 4,775 dollars qualifies in 2026-07. + period: 2026-07 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 4_775 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: true + +- name: Continuing family of 3 at 4,776 dollars doesn't qualify in 2026-07. + period: 2026-07 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 4_776 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_income_eligible: false + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. + +- name: DESE's July 1, 2026 chart holds new applicants to the lower of its maximum and 85% of SMI at sizes 1 to 20. + period: 2026-07 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + p25: + age: + 2026: 30 + p26: + age: + 2026: 30 + p27: + age: + 2026: 30 + p28: + age: + 2026: 30 + p29: + age: + 2026: 30 + p30: + age: + 2026: 30 + p31: + age: + 2026: 30 + p32: + age: + 2026: 30 + p33: + age: + 2026: 30 + p34: + age: + 2026: 30 + p35: + age: + 2026: 30 + p36: + age: + 2026: 30 + p37: + age: + 2026: 30 + p38: + age: + 2026: 30 + p39: + age: + 2026: 30 + p40: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + mo_ccs_adjusted_income: 1_956 + mo_ccs_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 1 + mo_ccs_adjusted_income: 1_957 + mo_ccs_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 2 + mo_ccs_adjusted_income: 2_644 + mo_ccs_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 2 + mo_ccs_adjusted_income: 2_645 + mo_ccs_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 3 + mo_ccs_adjusted_income: 3_331 + mo_ccs_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 3 + mo_ccs_adjusted_income: 3_332 + mo_ccs_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 4 + mo_ccs_adjusted_income: 4_019 + mo_ccs_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 4 + mo_ccs_adjusted_income: 4_020 + mo_ccs_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 5 + mo_ccs_adjusted_income: 4_706 + mo_ccs_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 5 + mo_ccs_adjusted_income: 4_707 + mo_ccs_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 6 + mo_ccs_adjusted_income: 5_394 + mo_ccs_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 6 + mo_ccs_adjusted_income: 5_395 + mo_ccs_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 7 + mo_ccs_adjusted_income: 6_081 + mo_ccs_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 7 + mo_ccs_adjusted_income: 6_082 + mo_ccs_enrolled: false + u15: + members: [p15] + spm_unit_size: + 2026: 8 + mo_ccs_adjusted_income: 6_769 + mo_ccs_enrolled: false + u16: + members: [p16] + spm_unit_size: + 2026: 8 + mo_ccs_adjusted_income: 6_770 + mo_ccs_enrolled: false + u17: + members: [p17] + spm_unit_size: + 2026: 9 + mo_ccs_adjusted_income: 7_456 + mo_ccs_enrolled: false + u18: + members: [p18] + spm_unit_size: + 2026: 9 + mo_ccs_adjusted_income: 7_457 + mo_ccs_enrolled: false + u19: + members: [p19] + spm_unit_size: + 2026: 10 + mo_ccs_adjusted_income: 8_144 + mo_ccs_enrolled: false + u20: + members: [p20] + spm_unit_size: + 2026: 10 + mo_ccs_adjusted_income: 8_145 + mo_ccs_enrolled: false + u21: + members: [p21] + spm_unit_size: + 2026: 11 + mo_ccs_adjusted_income: 8_831 + mo_ccs_enrolled: false + u22: + members: [p22] + spm_unit_size: + 2026: 11 + mo_ccs_adjusted_income: 8_832 + mo_ccs_enrolled: false + u23: + members: [p23] + spm_unit_size: + 2026: 12 + mo_ccs_adjusted_income: 9_519 + mo_ccs_enrolled: false + u24: + members: [p24] + spm_unit_size: + 2026: 12 + mo_ccs_adjusted_income: 9_520 + mo_ccs_enrolled: false + u25: + members: [p25] + spm_unit_size: + 2026: 13 + mo_ccs_adjusted_income: 10_206 + mo_ccs_enrolled: false + u26: + members: [p26] + spm_unit_size: + 2026: 13 + mo_ccs_adjusted_income: 10_207 + mo_ccs_enrolled: false + u27: + members: [p27] + spm_unit_size: + 2026: 14 + mo_ccs_adjusted_income: 10_894 + mo_ccs_enrolled: false + u28: + members: [p28] + spm_unit_size: + 2026: 14 + mo_ccs_adjusted_income: 10_895 + mo_ccs_enrolled: false + u29: + members: [p29] + spm_unit_size: + 2026: 15 + mo_ccs_adjusted_income: 11_581 + mo_ccs_enrolled: false + u30: + members: [p30] + spm_unit_size: + 2026: 15 + mo_ccs_adjusted_income: 11_582 + mo_ccs_enrolled: false + u31: + members: [p31] + spm_unit_size: + 2026: 16 + mo_ccs_adjusted_income: 12_269 + mo_ccs_enrolled: false + u32: + members: [p32] + spm_unit_size: + 2026: 16 + mo_ccs_adjusted_income: 12_270 + mo_ccs_enrolled: false + u33: + members: [p33] + spm_unit_size: + 2026: 17 + mo_ccs_adjusted_income: 12_766 + mo_ccs_enrolled: false + u34: + members: [p34] + spm_unit_size: + 2026: 17 + mo_ccs_adjusted_income: 12_767 + mo_ccs_enrolled: false + u35: + members: [p35] + spm_unit_size: + 2026: 18 + mo_ccs_adjusted_income: 12_998 + mo_ccs_enrolled: false + u36: + members: [p36] + spm_unit_size: + 2026: 18 + mo_ccs_adjusted_income: 12_999 + mo_ccs_enrolled: false + u37: + members: [p37] + spm_unit_size: + 2026: 19 + mo_ccs_adjusted_income: 13_230 + mo_ccs_enrolled: false + u38: + members: [p38] + spm_unit_size: + 2026: 19 + mo_ccs_adjusted_income: 13_231 + mo_ccs_enrolled: false + u39: + members: [p39] + spm_unit_size: + 2026: 20 + mo_ccs_adjusted_income: 13_462 + mo_ccs_enrolled: false + u40: + members: [p40] + spm_unit_size: + 2026: 20 + mo_ccs_adjusted_income: 13_463 + mo_ccs_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: MO + h2: + members: [p2] + state_code: + 2026: MO + h3: + members: [p3] + state_code: + 2026: MO + h4: + members: [p4] + state_code: + 2026: MO + h5: + members: [p5] + state_code: + 2026: MO + h6: + members: [p6] + state_code: + 2026: MO + h7: + members: [p7] + state_code: + 2026: MO + h8: + members: [p8] + state_code: + 2026: MO + h9: + members: [p9] + state_code: + 2026: MO + h10: + members: [p10] + state_code: + 2026: MO + h11: + members: [p11] + state_code: + 2026: MO + h12: + members: [p12] + state_code: + 2026: MO + h13: + members: [p13] + state_code: + 2026: MO + h14: + members: [p14] + state_code: + 2026: MO + h15: + members: [p15] + state_code: + 2026: MO + h16: + members: [p16] + state_code: + 2026: MO + h17: + members: [p17] + state_code: + 2026: MO + h18: + members: [p18] + state_code: + 2026: MO + h19: + members: [p19] + state_code: + 2026: MO + h20: + members: [p20] + state_code: + 2026: MO + h21: + members: [p21] + state_code: + 2026: MO + h22: + members: [p22] + state_code: + 2026: MO + h23: + members: [p23] + state_code: + 2026: MO + h24: + members: [p24] + state_code: + 2026: MO + h25: + members: [p25] + state_code: + 2026: MO + h26: + members: [p26] + state_code: + 2026: MO + h27: + members: [p27] + state_code: + 2026: MO + h28: + members: [p28] + state_code: + 2026: MO + h29: + members: [p29] + state_code: + 2026: MO + h30: + members: [p30] + state_code: + 2026: MO + h31: + members: [p31] + state_code: + 2026: MO + h32: + members: [p32] + state_code: + 2026: MO + h33: + members: [p33] + state_code: + 2026: MO + h34: + members: [p34] + state_code: + 2026: MO + h35: + members: [p35] + state_code: + 2026: MO + h36: + members: [p36] + state_code: + 2026: MO + h37: + members: [p37] + state_code: + 2026: MO + h38: + members: [p38] + state_code: + 2026: MO + h39: + members: [p39] + state_code: + 2026: MO + h40: + members: [p40] + state_code: + 2026: MO + output: + # The chart's $5.00 row tops for sizes 1 to 20, except that the chart's + # July 1, 2026 clarification applies the lower of that top and its 85% State + # Median Income row, which binds from size 17 ($12,766.15 for 17). + mo_ccs_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: DESE's July 1, 2026 chart holds enrolled families to the lower of Transitional Level 2 and 85% of SMI at sizes 1 to 20. + period: 2026-07 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + p25: + age: + 2026: 30 + p26: + age: + 2026: 30 + p27: + age: + 2026: 30 + p28: + age: + 2026: 30 + p29: + age: + 2026: 30 + p30: + age: + 2026: 30 + p31: + age: + 2026: 30 + p32: + age: + 2026: 30 + p33: + age: + 2026: 30 + p34: + age: + 2026: 30 + p35: + age: + 2026: 30 + p36: + age: + 2026: 30 + p37: + age: + 2026: 30 + p38: + age: + 2026: 30 + p39: + age: + 2026: 30 + p40: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + mo_ccs_adjusted_income: 2_804 + mo_ccs_enrolled: true + u2: + members: [p2] + spm_unit_size: + 2026: 1 + mo_ccs_adjusted_income: 2_805 + mo_ccs_enrolled: true + u3: + members: [p3] + spm_unit_size: + 2026: 2 + mo_ccs_adjusted_income: 3_789 + mo_ccs_enrolled: true + u4: + members: [p4] + spm_unit_size: + 2026: 2 + mo_ccs_adjusted_income: 3_790 + mo_ccs_enrolled: true + u5: + members: [p5] + spm_unit_size: + 2026: 3 + mo_ccs_adjusted_income: 4_775 + mo_ccs_enrolled: true + u6: + members: [p6] + spm_unit_size: + 2026: 3 + mo_ccs_adjusted_income: 4_776 + mo_ccs_enrolled: true + u7: + members: [p7] + spm_unit_size: + 2026: 4 + mo_ccs_adjusted_income: 5_760 + mo_ccs_enrolled: true + u8: + members: [p8] + spm_unit_size: + 2026: 4 + mo_ccs_adjusted_income: 5_761 + mo_ccs_enrolled: true + u9: + members: [p9] + spm_unit_size: + 2026: 5 + mo_ccs_adjusted_income: 6_746 + mo_ccs_enrolled: true + u10: + members: [p10] + spm_unit_size: + 2026: 5 + mo_ccs_adjusted_income: 6_747 + mo_ccs_enrolled: true + u11: + members: [p11] + spm_unit_size: + 2026: 6 + mo_ccs_adjusted_income: 7_731 + mo_ccs_enrolled: true + u12: + members: [p12] + spm_unit_size: + 2026: 6 + mo_ccs_adjusted_income: 7_732 + mo_ccs_enrolled: true + u13: + members: [p13] + spm_unit_size: + 2026: 7 + mo_ccs_adjusted_income: 8_716 + mo_ccs_enrolled: true + u14: + members: [p14] + spm_unit_size: + 2026: 7 + mo_ccs_adjusted_income: 8_717 + mo_ccs_enrolled: true + u15: + members: [p15] + spm_unit_size: + 2026: 8 + mo_ccs_adjusted_income: 9_702 + mo_ccs_enrolled: true + u16: + members: [p16] + spm_unit_size: + 2026: 8 + mo_ccs_adjusted_income: 9_703 + mo_ccs_enrolled: true + u17: + members: [p17] + spm_unit_size: + 2026: 9 + mo_ccs_adjusted_income: 10_687 + mo_ccs_enrolled: true + u18: + members: [p18] + spm_unit_size: + 2026: 9 + mo_ccs_adjusted_income: 10_688 + mo_ccs_enrolled: true + u19: + members: [p19] + spm_unit_size: + 2026: 10 + mo_ccs_adjusted_income: 11_141 + mo_ccs_enrolled: true + u20: + members: [p20] + spm_unit_size: + 2026: 10 + mo_ccs_adjusted_income: 11_142 + mo_ccs_enrolled: true + u21: + members: [p21] + spm_unit_size: + 2026: 11 + mo_ccs_adjusted_income: 11_373 + mo_ccs_enrolled: true + u22: + members: [p22] + spm_unit_size: + 2026: 11 + mo_ccs_adjusted_income: 11_374 + mo_ccs_enrolled: true + u23: + members: [p23] + spm_unit_size: + 2026: 12 + mo_ccs_adjusted_income: 11_605 + mo_ccs_enrolled: true + u24: + members: [p24] + spm_unit_size: + 2026: 12 + mo_ccs_adjusted_income: 11_606 + mo_ccs_enrolled: true + u25: + members: [p25] + spm_unit_size: + 2026: 13 + mo_ccs_adjusted_income: 11_837 + mo_ccs_enrolled: true + u26: + members: [p26] + spm_unit_size: + 2026: 13 + mo_ccs_adjusted_income: 11_838 + mo_ccs_enrolled: true + u27: + members: [p27] + spm_unit_size: + 2026: 14 + mo_ccs_adjusted_income: 12_069 + mo_ccs_enrolled: true + u28: + members: [p28] + spm_unit_size: + 2026: 14 + mo_ccs_adjusted_income: 12_070 + mo_ccs_enrolled: true + u29: + members: [p29] + spm_unit_size: + 2026: 15 + mo_ccs_adjusted_income: 12_301 + mo_ccs_enrolled: true + u30: + members: [p30] + spm_unit_size: + 2026: 15 + mo_ccs_adjusted_income: 12_302 + mo_ccs_enrolled: true + u31: + members: [p31] + spm_unit_size: + 2026: 16 + mo_ccs_adjusted_income: 12_534 + mo_ccs_enrolled: true + u32: + members: [p32] + spm_unit_size: + 2026: 16 + mo_ccs_adjusted_income: 12_535 + mo_ccs_enrolled: true + u33: + members: [p33] + spm_unit_size: + 2026: 17 + mo_ccs_adjusted_income: 12_766 + mo_ccs_enrolled: true + u34: + members: [p34] + spm_unit_size: + 2026: 17 + mo_ccs_adjusted_income: 12_767 + mo_ccs_enrolled: true + u35: + members: [p35] + spm_unit_size: + 2026: 18 + mo_ccs_adjusted_income: 12_998 + mo_ccs_enrolled: true + u36: + members: [p36] + spm_unit_size: + 2026: 18 + mo_ccs_adjusted_income: 12_999 + mo_ccs_enrolled: true + u37: + members: [p37] + spm_unit_size: + 2026: 19 + mo_ccs_adjusted_income: 13_230 + mo_ccs_enrolled: true + u38: + members: [p38] + spm_unit_size: + 2026: 19 + mo_ccs_adjusted_income: 13_231 + mo_ccs_enrolled: true + u39: + members: [p39] + spm_unit_size: + 2026: 20 + mo_ccs_adjusted_income: 13_462 + mo_ccs_enrolled: true + u40: + members: [p40] + spm_unit_size: + 2026: 20 + mo_ccs_adjusted_income: 13_463 + mo_ccs_enrolled: true + households: + h1: + members: [p1] + state_code: + 2026: MO + h2: + members: [p2] + state_code: + 2026: MO + h3: + members: [p3] + state_code: + 2026: MO + h4: + members: [p4] + state_code: + 2026: MO + h5: + members: [p5] + state_code: + 2026: MO + h6: + members: [p6] + state_code: + 2026: MO + h7: + members: [p7] + state_code: + 2026: MO + h8: + members: [p8] + state_code: + 2026: MO + h9: + members: [p9] + state_code: + 2026: MO + h10: + members: [p10] + state_code: + 2026: MO + h11: + members: [p11] + state_code: + 2026: MO + h12: + members: [p12] + state_code: + 2026: MO + h13: + members: [p13] + state_code: + 2026: MO + h14: + members: [p14] + state_code: + 2026: MO + h15: + members: [p15] + state_code: + 2026: MO + h16: + members: [p16] + state_code: + 2026: MO + h17: + members: [p17] + state_code: + 2026: MO + h18: + members: [p18] + state_code: + 2026: MO + h19: + members: [p19] + state_code: + 2026: MO + h20: + members: [p20] + state_code: + 2026: MO + h21: + members: [p21] + state_code: + 2026: MO + h22: + members: [p22] + state_code: + 2026: MO + h23: + members: [p23] + state_code: + 2026: MO + h24: + members: [p24] + state_code: + 2026: MO + h25: + members: [p25] + state_code: + 2026: MO + h26: + members: [p26] + state_code: + 2026: MO + h27: + members: [p27] + state_code: + 2026: MO + h28: + members: [p28] + state_code: + 2026: MO + h29: + members: [p29] + state_code: + 2026: MO + h30: + members: [p30] + state_code: + 2026: MO + h31: + members: [p31] + state_code: + 2026: MO + h32: + members: [p32] + state_code: + 2026: MO + h33: + members: [p33] + state_code: + 2026: MO + h34: + members: [p34] + state_code: + 2026: MO + h35: + members: [p35] + state_code: + 2026: MO + h36: + members: [p36] + state_code: + 2026: MO + h37: + members: [p37] + state_code: + 2026: MO + h38: + members: [p38] + state_code: + 2026: MO + h39: + members: [p39] + state_code: + 2026: MO + h40: + members: [p40] + state_code: + 2026: MO + output: + # Transitional Level 2 tops for sizes 1 to 20, except that the 85% State + # Median Income row binds from size 10 ($11,141.38 for 10). + mo_ccs_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/mo_ccs.yaml b/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/mo_ccs.yaml index 25fdbed64d9..41da7430fe8 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/mo_ccs.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/mo_ccs.yaml @@ -349,3 +349,76 @@ # tier 7 full fee $5/day * 20 = $100. Disabled child waived. # Benefit = max(3,709.25 - 100, 0) = $3,609.25. mo_ccs: 3_609.25 + +- name: July 2026, an enrolled family of three at the $4,109 Level 1 top gets 80 percent of the remaining rate. + period: 2026-07 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 30 + person3: + age: + 2026: 4 + childcare_attending_days_per_month: + 2026: 20 + mo_ccs_maximum_daily_benefit: 60 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_eligible: true + mo_ccs_adjusted_income: 4_109 + mo_ccs_copay: 200 + spm_unit_pre_subsidy_childcare_expenses: + 2026: 36_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + # DESE's July 2026 chart puts $4,109 for three at the top of Transitional Level 1. + # Reimbursement = min($60 * 20, $36,000 / 12) = $1,200; less the $200 fee = $1,000. + # Benefit = 80% * $1,000 = $800. + mo_ccs_funding_rate: 0.8 + mo_ccs: 800 + +- name: July 2026, an enrolled family of three at $4,110 gets 60 percent of the remaining rate. + period: 2026-07 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 30 + person3: + age: + 2026: 4 + childcare_attending_days_per_month: + 2026: 20 + mo_ccs_maximum_daily_benefit: 60 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_eligible: true + mo_ccs_adjusted_income: 4_110 + mo_ccs_copay: 200 + spm_unit_pre_subsidy_childcare_expenses: + 2026: 36_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + # $4,110 for three falls in Transitional Level 2 on DESE's July 2026 chart. + # Benefit = 60% * ($1,200 - $200) = $600. + mo_ccs_funding_rate: 0.6 + mo_ccs: 600 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/mo_ccs_funding_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/mo_ccs_funding_rate.yaml new file mode 100644 index 00000000000..8924200aae5 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/mo/dese/ccs/mo_ccs_funding_rate.yaml @@ -0,0 +1,199 @@ +# mo_ccs_funding_rate: SPMUnit, MONTH. +# DESE's chart updated July 1, 2026 prints, for three on the 2025 guideline ($26,650): +# traditional up to $3,331, Transitional Level 1 $3,332 to $4,109, Level 2 $4,110 to $4,775. + +- name: July 2026, a family of three at the $3,331 traditional top keeps the full rate. + period: 2026-07 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 3_331 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_funding_rate: 1 + +- name: July 2026, a family of three at $3,332 enters Transitional Level 1. + period: 2026-07 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 3_332 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_funding_rate: 0.8 + +- name: July 2026, a family of three at the $4,109 Level 1 top keeps 80 percent. + period: 2026-07 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 4_109 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + # 185% * 26_650 / 12 = 4_108.54, which the chart prints as $4,109. + mo_ccs_funding_rate: 0.8 + +- name: July 2026, a family of three at $4,110 enters Transitional Level 2. + period: 2026-07 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 4_110 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_funding_rate: 0.6 + +- name: July 2026, a family of three at the $4,775 Level 2 top keeps 60 percent. + period: 2026-07 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + mo_ccs_adjusted_income: 4_775 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MO + output: + mo_ccs_funding_rate: 0.6 + +- name: July 2026, a family of one at the $2,413 Level 1 top keeps 80 percent. + period: 2026-07 + input: + people: + person1: + age: + 2026: 30 + spm_units: + spm_unit: + members: [person1] + mo_ccs_adjusted_income: 2_413 + mo_ccs_enrolled: true + households: + household: + members: [person1] + state_code: + 2026: MO + output: + # 185% * 15_650 / 12 = 2_412.71, which the chart prints as $2,413. + mo_ccs_funding_rate: 0.8 + +- name: July 2026, a family of one at $2,414 enters Transitional Level 2. + period: 2026-07 + input: + people: + person1: + age: + 2026: 30 + spm_units: + spm_unit: + members: [person1] + mo_ccs_adjusted_income: 2_414 + mo_ccs_enrolled: true + households: + household: + members: [person1] + state_code: + 2026: MO + output: + mo_ccs_funding_rate: 0.6 + +- name: January 2025, a family of two above 215 percent reaches Transitional Level 3. + period: 2025-01 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2] + mo_ccs_adjusted_income: 4_000 + mo_ccs_enrolled: true + households: + household: + members: [person1, person2] + state_code: + 2025: MO + output: + # Level 2 tops out at round(215% * 21_150 / 12) = $3,789 for two. + mo_ccs_funding_rate: 0.5 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/integration.yaml index 7b7f2378f87..34e7a7e9a1f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/integration.yaml @@ -1,9 +1,9 @@ # Integration tests for Montana Best Beginnings Child Care Scholarship (CCAP). # End-to-end scenarios exercising age classification, the 3-D provider rate lookup, -# the sliding-scale copay, the TANF flat-$10 copay, the income test (150% FPG -# initial / 185% FPG graduated, 85% SMI overlay), the activity requirement, and +# the sliding-scale copay, the TANF flat-$10 copay, the income test (185% FPG +# initial / 200% FPG graduated, 85% SMI overlay), the activity requirement, and # the final benefit + the state and federal child-care-subsidy aggregators. -# 2026 (contiguous) FPG: size 2 = 21,640; size 3 = 27,320 (annual). +# January 2026 uses the scale's 2025 FPG (contiguous): size 2 = 21,150; size 3 = 26,650 (annual). # Provider rates effective 07-01-2025 (BBS Provider Reimbursement Monthly Rates). - name: Case 1, single parent + preschooler at an FFN provider, full-time. @@ -13,7 +13,7 @@ people: person1: age: 28 - employment_income: 26_000 # size 2, ratio 26,000/21,640 = 1.2015 -> 1.5% + employment_income: 26_000 # size 2, ratio 26,000/21,150 = 1.2293 -> 1.5% weekly_hours_worked_before_lsr: 40 # ~173 hrs/month >> 60 person2: age: 4 # 48 months -> PRESCHOOL @@ -48,7 +48,7 @@ people: person1: age: 33 - employment_income: 41_520 # size 3, ratio 41,520/27,320 = 1.52 -> 3.5% + employment_income: 40_508 # size 3, ratio 40,508/26,650 = 1.52 -> 3.5% weekly_hours_worked_before_lsr: 20 # ~86.7 hrs/month person2: age: 31 @@ -74,10 +74,10 @@ mt_ccap_activity_eligible: true # combined ~173 hrs/month >= 120 mt_ccap_eligible: true mt_ccap_max_rate: [0, 0, 1_056] # group home infant/toddler full-time = 1,056 - mt_ccap_countable_income: 3_460 # 41,520 / 12 - mt_ccap_copay: 121.1 # 3,460 * 3.5% - # charge 2,000 > max rate 1,056 -> capped at 1,056; benefit = 1,056 - 121.10 - mt_ccap: 934.9 + mt_ccap_countable_income: 3_375.67 # 40,508 / 12 + mt_ccap_copay: 118.15 # 3,375.67 * 3.5% + # charge 2,000 > max rate 1,056 -> capped at 1,056; benefit = 1,056 - 118.15 + mt_ccap: 937.85 - name: Case 3, single parent + two children at a family home, 100% FPG. period: 2026-01 @@ -86,7 +86,7 @@ people: person1: age: 30 - employment_income: 27_320 # size 3, ratio 1.00 -> 0.5% + employment_income: 26_650 # size 3, ratio 1.00 -> 0.5% weekly_hours_worked_before_lsr: 40 person2: age: 4 # PRESCHOOL @@ -111,10 +111,10 @@ mt_ccap_income_eligible: true mt_ccap_eligible: true mt_ccap_max_rate: [0, 880, 880] # family home preschool / school age full-time = 880 - mt_ccap_countable_income: 2_276.67 # 27,320 / 12 - mt_ccap_copay: 11.38 # 2,276.67 * 0.5% - # each child: min(1,000, 880) = 880; sum 1,760; benefit = 1,760 - 11.38 - mt_ccap: 1_748.62 + mt_ccap_countable_income: 2_220.83 # 26,650 / 12 + mt_ccap_copay: 11.10 # 2,220.83 * 0.5% + # each child: min(1,000, 880) = 880; sum 1,760; benefit = 1,760 - 11.10 + mt_ccap: 1_748.90 - name: Case 4, TANF over-income family at a relative-care-exempt provider. period: 2026-01 @@ -154,7 +154,7 @@ people: person1: age: 33 - employment_income: 60_000 # size 3, ratio 2.196 -> above the 150% applicant limit (40,980) + employment_income: 60_000 # size 3, ratio 2.25 -> above the 185% applicant limit (49,308) weekly_hours_worked_before_lsr: 40 person2: age: 31 @@ -174,7 +174,7 @@ state_code: MT output: mt_ccap_eligible_child: [false, false, true] - mt_ccap_income_eligible: false # above the 150% applicant limit -> FPG limit binds + mt_ccap_income_eligible: false # above the 185% applicant limit -> FPG limit binds mt_ccap_eligible: false mt_ccap: 0 mt_child_care_subsidies: 0 @@ -251,12 +251,12 @@ - name: Case 8, family at 182% FPG (continuing recipient), center preschooler, full-time. period: 2026-01 absolute_error_margin: 0.1 - # ratio 39,384/21,640 = 1.82 -> 6.5% copay bracket; continuing recipient eligible (182% < 185% graduated limit, below 85% SMI). + # ratio 38,493/21,150 = 1.82 -> 6.5% copay bracket; continuing recipient eligible (182% < 200% graduated limit, below 85% SMI). input: people: person1: age: 31 - employment_income: 39_384 # size 2, 182% of FPG (3,282/mo) + employment_income: 38_493 # size 2, 182% of FPG (3,207.75/mo) weekly_hours_worked_before_lsr: 40 person2: age: 4 # PRESCHOOL @@ -274,24 +274,24 @@ state_code: MT output: mt_ccap_eligible_child: [false, true] - mt_ccap_income_eligible: true # 182% FPG < 185% graduated limit (enrolled), below 85% SMI + mt_ccap_income_eligible: true # 182% FPG < 200% graduated limit (enrolled), below 85% SMI mt_ccap_activity_eligible: true mt_ccap_eligible: true mt_ccap_max_rate: [0, 1_210] # center preschool full-time - mt_ccap_countable_income: 3_282 # 39,384 / 12 - mt_ccap_copay: 213.33 # 3,282.00 * 6.5% - # charge 1,500 > max rate 1,210 -> capped at 1,210; benefit = 1,210 - 213.33 - mt_ccap: 996.67 + mt_ccap_countable_income: 3_207.75 # 38,493 / 12 + mt_ccap_copay: 208.50 # 3,207.75 * 6.5% + # charge 1,500 > max rate 1,210 -> capped at 1,210; benefit = 1,210 - 208.50 + mt_ccap: 1_001.50 - name: Case 9, eligible family whose copay exceeds the small reimbursement (benefit floors at 0). period: 2026-01 absolute_error_margin: 0.1 - # continuing recipient with a tiny provider charge; copay 213.33 > reimbursement 200 -> benefit floored at 0 even though the family is eligible. + # continuing recipient with a tiny provider charge; copay 208.50 > reimbursement 200 -> benefit floored at 0 even though the family is eligible. input: people: person1: age: 31 - employment_income: 39_384 # 182% FPG, 6.5% copay bracket + employment_income: 38_493 # 182% FPG, 6.5% copay bracket weekly_hours_worked_before_lsr: 40 person2: age: 4 @@ -310,8 +310,8 @@ output: mt_ccap_eligible: true mt_ccap_max_rate: [0, 1_210] - mt_ccap_copay: 213.33 # 3,282.00 * 6.5% - # reimbursement = min(200, 1,210) = 200; max(200 - 213.33, 0) = 0 + mt_ccap_copay: 208.50 # 3,207.75 * 6.5% + # reimbursement = min(200, 1,210) = 200; max(200 - 208.50, 0) = 0 mt_ccap: 0 - name: Case 10, infant at a center, full-time (highest single max rate). @@ -322,7 +322,7 @@ people: person1: age: 26 - employment_income: 18_000 # size 2, ~83% FPG -> 0.5% bracket, copay at the $10 floor + employment_income: 18_000 # size 2, ~85% FPG -> 0.5% bracket, copay at the $10 floor weekly_hours_worked_before_lsr: 40 person2: age: 0 # newborn, INFANT_TODDLER diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap.yaml index 50cc498d61b..3a3c41a66d0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap.yaml @@ -3,7 +3,7 @@ # - household copay, 0). # Per-child charge comes from pre_subsidy_childcare_expenses, which prorates # spm_unit_pre_subsidy_childcare_expenses (annual) evenly across children. -# 2026 (contiguous) FPG: size 2 = 21,640 annual; size 3 = 27,320 annual. +# January 2026 uses the scale's 2025 FPG (contiguous): size 2 = 21,150 annual; size 3 = 26,650 annual. - name: Case 1, one child at a center, charge exceeds the max rate (capped at max rate). period: 2026-01 absolute_error_margin: 0.1 @@ -11,7 +11,7 @@ people: person1: age: 30 - employment_income: 24_000 # size 2, ~111% FPG -> 1.0% copay bracket + employment_income: 24_000 # size 2, ~113% FPG -> 1.0% copay bracket weekly_hours_worked_before_lsr: 40 person2: age: 4 # preschool @@ -66,7 +66,7 @@ people: person1: age: 30 - employment_income: 30_000 # size 3, ~110% FPG -> 1.0% copay bracket + employment_income: 30_000 # size 3, ~113% FPG -> 1.0% copay bracket weekly_hours_worked_before_lsr: 40 person2: age: 4 @@ -228,12 +228,12 @@ - name: Case 9, copay exceeds the reimbursement so the benefit floors at 0. period: 2026-01 absolute_error_margin: 0.1 - # continuing recipient with a small provider charge; copay 213.33 > reimbursement 200 -> benefit floored at 0. + # continuing recipient with a small provider charge; copay 208.50 > reimbursement 200 -> benefit floored at 0. input: people: person1: age: 30 - employment_income: 39_384 # size 2, 182% FPG (3,282/mo) -> 6.5% copay bracket + employment_income: 38_493 # size 2, 182% FPG (3,207.75/mo) -> 6.5% copay bracket weekly_hours_worked_before_lsr: 40 person2: age: 4 @@ -251,5 +251,5 @@ state_code: MT output: # reimbursement = min(200, 1,210) = 200 - # copay = 3,282.00 * 6.5% = 213.33 > 200 -> max(200 - 213.33, 0) = 0 + # copay = 3,207.75 * 6.5% = 208.50 > 200 -> max(200 - 208.50, 0) = 0 mt_ccap: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_copay.yaml index a96aa27db4e..2d3b439a88d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_copay.yaml @@ -2,7 +2,8 @@ # Non-TANF: copay = max(gross_monthly_income * copay_rate.calc(fpg_ratio), $10). # TANF (is_tanf_enrolled): flat $10. # fpg_ratio = countable monthly income / monthly FPG. -# 2026 FPG (contiguous), size 3 (1 parent + 2 children): 27,320 annual = 2,276.67/mo. +# January 2026 uses the scale's 2025 FPG (contiguous), size 3 (1 parent + 2 children): +# 26,650 annual = 2,220.83/mo. # Income inputs are annual; the MONTH formula reads the monthly portion. - name: Case 1, low income copay floors at the $10 minimum. period: 2026-01 @@ -11,7 +12,7 @@ people: person1: weekly_hours_worked_before_lsr: 40 - employment_income: 20_490 # 75% FPG; 0.5% of 1,707.50 = 8.54 < 10 + employment_income: 20_490 # 77% FPG; 0.5% of 1,707.50 = 8.54 < 10 person2: age: 4 person3: @@ -34,7 +35,7 @@ people: person1: weekly_hours_worked_before_lsr: 40 - employment_income: 27_320 # 100% FPG, ratio 1.0 -> 0.5% + employment_income: 26_650 # 100% FPG, ratio 1.0 -> 0.5% person2: age: 4 person3: @@ -48,17 +49,17 @@ members: [person1, person2, person3] state_code: MT output: - mt_ccap_copay: 11.38 # 2,276.67 * 0.005 = 11.38 + mt_ccap_copay: 11.10 # 2,220.83 * 0.005 = 11.10 - name: Case 3, continuing recipient at 152% FPG pays the 3.5% copay. period: 2026-01 absolute_error_margin: 0.1 - # 41,520 annual (152% FPG) -> 3.5% tier; enrolled (eligible up to 185% FPG). + # 40,508 annual (152% FPG) -> 3.5% tier; enrolled (eligible up to 200% FPG). input: people: person1: weekly_hours_worked_before_lsr: 40 - employment_income: 41_520 # 3,460/mo, 152% of size-3 FPG + employment_income: 40_508 # 3,375.67/mo, 152% of size-3 FPG person2: age: 4 person3: @@ -73,17 +74,17 @@ members: [person1, person2, person3] state_code: MT output: - mt_ccap_copay: 121.1 # 3,460.00 * 0.035 + mt_ccap_copay: 118.15 # 3,375.67 * 0.035 - name: Case 4, continuing recipient at 182% FPG pays the 6.5% copay. period: 2026-01 absolute_error_margin: 0.1 - # 49,716 annual (182% FPG) -> 6.5% tier; enrolled (eligible up to 185% FPG). + # 48,503 annual (182% FPG) -> 6.5% tier; enrolled (eligible up to 200% FPG). input: people: person1: weekly_hours_worked_before_lsr: 40 - employment_income: 49_716 # 4,143/mo, 182% of size-3 FPG + employment_income: 48_503 # 4,041.92/mo, 182% of size-3 FPG person2: age: 4 person3: @@ -98,17 +99,17 @@ members: [person1, person2, person3] state_code: MT output: - mt_ccap_copay: 269.3 # 4,143.00 * 0.065 + mt_ccap_copay: 262.72 # 4,041.92 * 0.065 - name: Case 5, continuing recipient at 172% FPG pays the 5.5% copay. period: 2026-01 absolute_error_margin: 0.1 - # 46,992 annual (172% FPG) -> 5.5% tier; enrolled (eligible up to 185% FPG). + # 45,838 annual (172% FPG) -> 5.5% tier; enrolled (eligible up to 200% FPG). input: people: person1: weekly_hours_worked_before_lsr: 40 - employment_income: 46_992 # 3,916/mo, 172% of size-3 FPG + employment_income: 45_838 # 3,819.83/mo, 172% of size-3 FPG person2: age: 4 person3: @@ -123,7 +124,7 @@ members: [person1, person2, person3] state_code: MT output: - mt_ccap_copay: 215.38 # 3,916.00 * 0.055 + mt_ccap_copay: 210.09 # 3,819.83 * 0.055 - name: Case 6, TANF recipient pays the flat $10 copay regardless of income. period: 2026-01 @@ -149,7 +150,7 @@ mt_ccap_copay: 10 # flat $10 for TANF, not the 119.53 scale amount # --- Edge cases: $10 floor exactly, zero income, and FPG-step bracket boundaries. -# Size 3 monthly FPG = 27,320 / 12 = 2,276.67. Per the sliding scale footnote, each +# Size 3 monthly FPG = 26,650 / 12 = 2,220.83. Per the sliding scale footnote, each # labeled % is the FLOOR of its tier: a family AT a step enters the higher tier and # just below stays in the lower tier (single_amount is "at or above threshold"). --- - name: Case 7, zero income copay floors at the $10 minimum. @@ -179,7 +180,7 @@ - name: Case 8, copay exactly at the $10 floor (scale amount equals the minimum). period: 2026-01 absolute_error_margin: 0.1 - # GMI 2,000/mo (24,000 annual, ~87.8% FPG) -> 0.5% bracket; 2,000 * 0.005 = 10 = minimum. + # GMI 2,000/mo (24,000 annual, ~90.1% FPG) -> 0.5% bracket; 2,000 * 0.005 = 10 = minimum. input: people: person1: @@ -203,13 +204,13 @@ - name: Case 9, just above 100% FPG stays in the 0.5% bracket (floor reading). period: 2026-01 absolute_error_margin: 0.1 - # ratio 28,140/27,320 = 1.03; floor keeps income below 105% in the 0.5% tier + # ratio 27,450/26,650 = 1.03; floor keeps income below 105% in the 0.5% tier # (a ceiling reading of the scale would instead charge 1.0% here). input: people: person1: weekly_hours_worked_before_lsr: 40 - employment_income: 28_140 # 103% of size-3 FPG (2,345/mo) + employment_income: 27_450 # 103% of size-3 FPG (2,287.50/mo) person2: age: 4 person3: @@ -223,17 +224,17 @@ members: [person1, person2, person3] state_code: MT output: - mt_ccap_copay: 11.73 # 2,345.00/mo * 0.005 + mt_ccap_copay: 11.44 # 2,287.50/mo * 0.005 - name: Case 10, above 105% FPG is in the 1.0% bracket. period: 2026-01 absolute_error_margin: 0.1 - # ratio 29,520/27,320 = 1.08; floor 1.0% tier runs 105% up to 115%. + # ratio 29,520/26,650 = 1.11; floor 1.0% tier runs 105% up to 115%. input: people: person1: weekly_hours_worked_before_lsr: 40 - employment_income: 29_520 # 108% of size-3 FPG (2,460/mo) + employment_income: 29_520 # 111% of size-3 FPG (2,460/mo) person2: age: 4 person3: @@ -252,13 +253,13 @@ - name: Case 11, just above 110% FPG stays in the 1.0% bracket (floor reading). period: 2026-01 absolute_error_margin: 0.1 - # ratio 30,600/27,320 = 1.12; floor keeps 110-115% in the 1.0% tier + # ratio 30,600/26,650 = 1.148; floor keeps 110-115% in the 1.0% tier # (a ceiling reading of the scale would instead charge 1.5% here). input: people: person1: weekly_hours_worked_before_lsr: 40 - employment_income: 30_600 # 112% of size-3 FPG (2,550/mo) + employment_income: 30_600 # 114.8% of size-3 FPG (2,550/mo) person2: age: 4 person3: @@ -277,12 +278,12 @@ - name: Case 12, above 115% FPG is in the 1.5% bracket. period: 2026-01 absolute_error_margin: 0.1 - # ratio 32,280/27,320 = 1.18; floor 1.5% tier runs 115% up to 125%. + # ratio 32,280/26,650 = 1.21; floor 1.5% tier runs 115% up to 125%. input: people: person1: weekly_hours_worked_before_lsr: 40 - employment_income: 32_280 # 118% of size-3 FPG (2,690/mo) + employment_income: 32_280 # 121% of size-3 FPG (2,690/mo) person2: age: 4 person3: diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_eligible.yaml index 10c00d0cd7b..eb48f39210e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_eligible.yaml @@ -8,7 +8,7 @@ people: person1: age: 30 - employment_income: 30_000 # ~110% FPG for size 2 + employment_income: 30_000 # ~142% FPG for size 2 weekly_hours_worked_before_lsr: 40 person2: age: 4 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_fpg.yaml new file mode 100644 index 00000000000..29e43aa010f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_fpg.yaml @@ -0,0 +1,110 @@ +# Tests for mt_ccap_fpg (SPMUnit, MONTH). The Sliding Fee Scale effective 07-01-2025 prints +# the 2025 guideline; ACF's January 2025 table prints the 2024 guideline. +- name: 2024-08 uses the 2024 guideline. + period: 2024-08 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2024: MT + output: + mt_ccap_fpg: 2_151.67 + +- name: 2025-03 uses the 2024 guideline. + period: 2025-03 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_fpg: 2_151.67 + +- name: 2025-08 uses the 2025 guideline. + period: 2025-08 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_fpg: 2_220.83 + +- name: 2026-06 uses the 2025 guideline. + period: 2026-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MT + output: + mt_ccap_fpg: 2_220.83 + +- name: 2027-01 uses the 2026 guideline. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MT + output: + mt_ccap_fpg: 2_276.67 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_income_eligible.yaml index f05b7859733..002d9783542 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/dphhs/ccap/mt_ccap_income_eligible.yaml @@ -1,17 +1,19 @@ # Unit tests for mt_ccap_income_eligible (SPMUnit, MONTH). -# ARM 37.80.202(1): first-time applicants eligible below 150% FPG. -# ARM 37.80.202(2): non-TANF continuing recipients (mt_ccap_enrolled) eligible at -# annual redetermination up to 185% FPG. TANF families are categorically eligible. -# An 85% SMI overlay applies to all non-TANF families (rarely binds). -# 2026 (contiguous), size 3 (1 parent + 2 children): FPG = 27,320 annual; -# 150% FPG = 40,980; 185% FPG = 50,542; 85% SMI = 81,374 (does not bind at size 3). +# MCA 52-2-715(1) and the Sliding Fee Scale effective 07-01-2025: applicants eligible +# through 185% FPG. The scale's Graduated Eligibility: non-TANF continuing recipients +# (mt_ccap_enrolled) eligible at annual redetermination through 200% FPG. TANF families +# are categorically eligible. An 85% SMI overlay applies to all non-TANF families +# (rarely binds). +# January 2026 uses the scale's 2025 guideline (contiguous), size 3 (1 parent + 2 +# children): FPG = 26,650 annual. The scale prints 185% as 4,109 a month (49,308 a year) +# and 200% as 4,442 a month (53,304 a year); 85% SMI = 81,374 (does not bind at size 3). # Income inputs are annual; the MONTH formula compares monthly portions. -- name: Case 1, applicant well below 150% FPG is eligible. +- name: Case 1, applicant well below 185% FPG is eligible. period: 2026-01 input: people: person1: - employment_income: 30_000 # ~110% FPG + employment_income: 30_000 # ~113% FPG person2: age: 4 person3: @@ -28,13 +30,13 @@ output: mt_ccap_income_eligible: true -- name: Case 2, applicant just below the 150% FPG limit is eligible. +- name: Case 2, applicant just below the 185% FPG limit is eligible. period: 2026-01 - # 40,500 annual (148.2% FPG) -> below the 150% initial limit. + # 49,000 annual (183.9% FPG) -> below the 185% initial limit. input: people: person1: - employment_income: 40_500 + employment_income: 49_000 person2: age: 4 person3: @@ -51,13 +53,13 @@ output: mt_ccap_income_eligible: true -- name: Case 3, applicant just above the 150% FPG limit is ineligible. +- name: Case 3, applicant just above the 185% FPG limit is ineligible. period: 2026-01 - # 41,500 annual (151.9% FPG) -> above the 150% initial limit; not enrolled. + # 49,500 annual (185.7% FPG) -> above the 185% initial limit; not enrolled. input: people: person1: - employment_income: 41_500 + employment_income: 49_500 person2: age: 4 person3: @@ -74,13 +76,13 @@ output: mt_ccap_income_eligible: false -- name: Case 4, continuing recipient between 150% and 185% FPG is eligible (graduated). +- name: Case 4, continuing recipient between 185% and 200% FPG is eligible (graduated). period: 2026-01 - # 44,000 annual (161% FPG): over the 150% applicant limit but under 185%; enrolled. + # 51,000 annual (191.4% FPG): over the 185% applicant limit but under 200%; enrolled. input: people: person1: - employment_income: 44_000 + employment_income: 51_000 person2: age: 4 person3: @@ -97,13 +99,13 @@ output: mt_ccap_income_eligible: true -- name: Case 5, continuing recipient just below the 185% FPG limit is eligible. +- name: Case 5, continuing recipient just below the 200% FPG limit is eligible. period: 2026-01 - # 50,000 annual (183% FPG) -> below the 185% graduated limit; enrolled. + # 53,000 annual (198.9% FPG) -> below the 200% graduated limit; enrolled. input: people: person1: - employment_income: 50_000 + employment_income: 53_000 person2: age: 4 person3: @@ -120,13 +122,13 @@ output: mt_ccap_income_eligible: true -- name: Case 6, continuing recipient just above the 185% FPG limit is ineligible. +- name: Case 6, continuing recipient just above the 200% FPG limit is ineligible. period: 2026-01 - # 51,500 annual (188.5% FPG) -> above the 185% graduated limit; enrolled. + # 53,500 annual (200.8% FPG) -> above the 200% graduated limit; enrolled. input: people: person1: - employment_income: 51_500 + employment_income: 53_500 person2: age: 4 person3: @@ -143,21 +145,16 @@ output: mt_ccap_income_eligible: false -# Tight boundary coverage around the exact-cent FPG limits (size 3, 2026): -# 150% FPG = 40,980/yr (3,415.00/mo); 185% FPG = 50,542/yr (4,211.83/mo). -# The formula uses an exclusive `<`, so the threshold is tested $1 on either -# side. NOTE: the exact-cent limit (e.g. income == 40,980) is float32-precision -# sensitive — monthly countable income and monthly FPG are each derived by -# dividing annual figures by 12, and the round-trip can leave the two within a -# float ULP of each other. These $1-offset cases pin the intended behavior -# without depending on that ambiguous exact-boundary rounding. -- name: Case 6a, applicant one dollar below the 150% FPG limit is eligible. +# Tight boundary coverage around the scale's printed limits (size 3, January 2026): +# 185% FPG = 4,109/mo (49,308/yr); 200% FPG = 4,442/mo (53,304/yr). +# A family at the printed limit qualifies, and one dollar a month above it doesn't. +- name: Case 6a, applicant at the scale's 185% FPG limit is eligible. period: 2026-01 - # 40,979/yr -> 3,414.92/mo, just under the 3,415.00/mo (150% FPG) initial limit. + # 49,308/yr -> 4,109/mo, the scale's Standard Eligibility top for three. input: people: person1: - employment_income: 40_979 + employment_income: 49_308 person2: age: 4 person3: @@ -174,13 +171,13 @@ output: mt_ccap_income_eligible: true -- name: Case 6b, applicant one dollar above the 150% FPG limit is ineligible. +- name: Case 6b, applicant one dollar a month above the 185% FPG limit is ineligible. period: 2026-01 - # 40,981/yr -> 3,415.08/mo, just over the 3,415.00/mo (150% FPG) initial limit. + # 49,320/yr -> 4,110/mo, just over the 4,109/mo (185% FPG) initial limit. input: people: person1: - employment_income: 40_981 + employment_income: 49_320 person2: age: 4 person3: @@ -197,13 +194,13 @@ output: mt_ccap_income_eligible: false -- name: Case 6c, continuing recipient one dollar below the 185% FPG limit is eligible. +- name: Case 6c, continuing recipient at the scale's 200% FPG limit is eligible. period: 2026-01 - # 50,541/yr -> 4,211.75/mo, just under the 4,211.83/mo (185% FPG) graduated limit. + # 53,304/yr -> 4,442/mo, the scale's Graduated Eligibility top for three. input: people: person1: - employment_income: 50_541 + employment_income: 53_304 person2: age: 4 person3: @@ -220,13 +217,13 @@ output: mt_ccap_income_eligible: true -- name: Case 6d, continuing recipient one dollar above the 185% FPG limit is ineligible. +- name: Case 6d, continuing recipient one dollar a month above the 200% FPG limit is ineligible. period: 2026-01 - # 50,543/yr -> 4,211.92/mo, just over the 4,211.83/mo (185% FPG) graduated limit. + # 53,316/yr -> 4,443/mo, just over the 4,442/mo (200% FPG) graduated limit. input: people: person1: - employment_income: 50_543 + employment_income: 53_316 person2: age: 4 person3: @@ -245,7 +242,7 @@ - name: Case 7, TANF recipient over the 185% FPG limit is still income-eligible. period: 2026-01 - # 52,000 annual (190% FPG): over the non-TANF limits, but categorically eligible. + # 52,000 annual (195% FPG): over the applicant limit, but categorically eligible. input: people: person1: @@ -310,13 +307,13 @@ output: mt_ccap_income_eligible: false -# --- 85% SMI overlay isolation (large household where 0.85*SMI < 1.85*FPG). -# Size 13 (2 parents + 11 children) 2026, contiguous: 185% FPG = 155,622 annual -# (12,968.50/mo); 85% SMI = 140,554 annual (11,712.84/mo). Between these two the SMI +# --- 85% SMI overlay isolation (large household where 0.85*SMI < 2.0*FPG). +# Size 13 (2 parents + 11 children) January 2026, contiguous: 200% FPG = 163,300 annual +# (13,608.33/mo); 85% SMI = 140,554 annual (11,712.84/mo). Between these two the SMI # overlay rejects an otherwise FPG-eligible continuing recipient. --- -- name: Case 10, continuing recipient above 85% SMI but below 185% FPG is ineligible (SMI overlay). +- name: Case 10, continuing recipient above 85% SMI but below 200% FPG is ineligible (SMI overlay). period: 2026-01 - # 148,000 annual = 12,333.33/mo: above 0.85 SMI (11,712.84) yet below 1.85 FPG (12,968.50). + # 148,000 annual = 12,333.33/mo: above 0.85 SMI (11,712.84) yet below 2.0 FPG (13,608.33). input: people: person1: @@ -360,7 +357,7 @@ - name: Case 11, continuing recipient below 85% SMI is eligible (companion to Case 10). period: 2026-01 - # 138,000 annual = 11,500.00/mo: below both 0.85 SMI (11,712.84) and 1.85 FPG (12,968.50). + # 138,000 annual = 11,500.00/mo: below both 0.85 SMI (11,712.84) and 2.0 FPG (13,608.33). input: people: person1: @@ -401,3 +398,1596 @@ state_code: MT output: mt_ccap_income_eligible: true + +# Tops from the Sliding Fee Scale effective 07-01-2025 (2025 guideline, nearest dollar), +# plus the same rates on the guideline years behind earlier published limits. + +- name: New applicant of 2 at 3,261 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + mt_ccap_countable_income: 3_261 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 2 at 3,262 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + mt_ccap_countable_income: 3_262 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 3 at 4,109 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 4_109 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 3 at 4,110 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 4_110 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 4 at 4,956 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + mt_ccap_countable_income: 4_956 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 4 at 4,957 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + mt_ccap_countable_income: 4_957 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 5 at 5,804 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + mt_ccap_countable_income: 5_804 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 5 at 5,805 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + mt_ccap_countable_income: 5_805 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 6 at 6,652 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + mt_ccap_countable_income: 6_652 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 6 at 6,653 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + mt_ccap_countable_income: 6_653 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 7 at 7,500 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + mt_ccap_countable_income: 7_500 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 7 at 7,501 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + mt_ccap_countable_income: 7_501 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 8 at 8,348 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + mt_ccap_countable_income: 8_348 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 8 at 8,349 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + mt_ccap_countable_income: 8_349 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: Continuing family of 2 at 3,525 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + mt_ccap_countable_income: 3_525 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: Continuing family of 2 at 3,526 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + mt_ccap_countable_income: 3_526 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: Continuing family of 3 at 4,442 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 4_442 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: Continuing family of 3 at 4,443 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 4_443 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: Continuing family of 4 at 5,358 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + mt_ccap_countable_income: 5_358 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: Continuing family of 4 at 5,359 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + mt_ccap_countable_income: 5_359 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: Continuing family of 5 at 6,275 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + mt_ccap_countable_income: 6_275 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: Continuing family of 5 at 6,276 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + mt_ccap_countable_income: 6_276 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: Continuing family of 6 at 7,192 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + mt_ccap_countable_income: 7_192 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: Continuing family of 6 at 7,193 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + mt_ccap_countable_income: 7_193 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: Continuing family of 7 at 8,108 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + mt_ccap_countable_income: 8_108 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: Continuing family of 7 at 8,109 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + mt_ccap_countable_income: 8_109 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: Continuing family of 8 at 9,025 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + mt_ccap_countable_income: 9_025 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: true + +- name: Continuing family of 8 at 9,026 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + mt_ccap_countable_income: 9_026 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 3 at 4,109 dollars qualifies in 2025-08. + period: 2025-08 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 4_109 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 3 at 4,110 dollars doesn't qualify in 2025-08. + period: 2025-08 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 4_110 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_income_eligible: false + +- name: Continuing family of 3 at 4,442 dollars qualifies in 2025-08. + period: 2025-08 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 4_442 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_income_eligible: true + +- name: Continuing family of 3 at 4,443 dollars doesn't qualify in 2025-08. + period: 2025-08 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 4_443 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 3 at 3,981 dollars qualifies in 2025-03. + period: 2025-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 3_981 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 3 at 3,982 dollars doesn't qualify in 2025-03. + period: 2025-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 3_982 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_income_eligible: false + +- name: Continuing family of 3 at 3,981 dollars qualifies in 2025-03. + period: 2025-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 3_981 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_income_eligible: true + +- name: Continuing family of 3 at 3,982 dollars doesn't qualify in 2025-03. + period: 2025-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 3_982 + is_tanf_enrolled: false + mt_ccap_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2025: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 3 at 3,833 dollars qualifies in 2023-08. + period: 2023-08 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 3_833 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 3 at 3,834 dollars doesn't qualify in 2023-08. + period: 2023-08 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 3_834 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: MT + output: + mt_ccap_income_eligible: false + +- name: New applicant of 3 at 3,108 dollars qualifies in 2023-03. + period: 2023-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 3_108 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: MT + output: + mt_ccap_income_eligible: true + +- name: New applicant of 3 at 3,109 dollars doesn't qualify in 2023-03. + period: 2023-03 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + mt_ccap_countable_income: 3_109 + is_tanf_enrolled: false + mt_ccap_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: MT + output: + mt_ccap_income_eligible: false + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. + +- name: The July 1, 2025 sliding fee scale's Standard Eligibility top holds at sizes 2 to 11 in January 2026. + period: 2026-01 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 2 + mt_ccap_countable_income: 3_261 + mt_ccap_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 2 + mt_ccap_countable_income: 3_262 + mt_ccap_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 3 + mt_ccap_countable_income: 4_109 + mt_ccap_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 3 + mt_ccap_countable_income: 4_110 + mt_ccap_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 4 + mt_ccap_countable_income: 4_956 + mt_ccap_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 4 + mt_ccap_countable_income: 4_957 + mt_ccap_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 5 + mt_ccap_countable_income: 5_804 + mt_ccap_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 5 + mt_ccap_countable_income: 5_805 + mt_ccap_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 6 + mt_ccap_countable_income: 6_652 + mt_ccap_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 6 + mt_ccap_countable_income: 6_653 + mt_ccap_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 7 + mt_ccap_countable_income: 7_500 + mt_ccap_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 7 + mt_ccap_countable_income: 7_501 + mt_ccap_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 8 + mt_ccap_countable_income: 8_348 + mt_ccap_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 8 + mt_ccap_countable_income: 8_349 + mt_ccap_enrolled: false + u15: + members: [p15] + spm_unit_size: + 2026: 9 + mt_ccap_countable_income: 9_196 + mt_ccap_enrolled: false + u16: + members: [p16] + spm_unit_size: + 2026: 9 + mt_ccap_countable_income: 9_197 + mt_ccap_enrolled: false + u17: + members: [p17] + spm_unit_size: + 2026: 10 + mt_ccap_countable_income: 10_044 + mt_ccap_enrolled: false + u18: + members: [p18] + spm_unit_size: + 2026: 10 + mt_ccap_countable_income: 10_045 + mt_ccap_enrolled: false + u19: + members: [p19] + spm_unit_size: + 2026: 11 + mt_ccap_countable_income: 10_892 + mt_ccap_enrolled: false + u20: + members: [p20] + spm_unit_size: + 2026: 11 + mt_ccap_countable_income: 10_893 + mt_ccap_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: MT + h2: + members: [p2] + state_code: + 2026: MT + h3: + members: [p3] + state_code: + 2026: MT + h4: + members: [p4] + state_code: + 2026: MT + h5: + members: [p5] + state_code: + 2026: MT + h6: + members: [p6] + state_code: + 2026: MT + h7: + members: [p7] + state_code: + 2026: MT + h8: + members: [p8] + state_code: + 2026: MT + h9: + members: [p9] + state_code: + 2026: MT + h10: + members: [p10] + state_code: + 2026: MT + h11: + members: [p11] + state_code: + 2026: MT + h12: + members: [p12] + state_code: + 2026: MT + h13: + members: [p13] + state_code: + 2026: MT + h14: + members: [p14] + state_code: + 2026: MT + h15: + members: [p15] + state_code: + 2026: MT + h16: + members: [p16] + state_code: + 2026: MT + h17: + members: [p17] + state_code: + 2026: MT + h18: + members: [p18] + state_code: + 2026: MT + h19: + members: [p19] + state_code: + 2026: MT + h20: + members: [p20] + state_code: + 2026: MT + output: + # 185% FPG GMI row, sizes 2 to 11. + mt_ccap_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: The July 1, 2025 sliding fee scale's Graduated Eligibility top holds at sizes 2 to 10 in January 2026. + period: 2026-01 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 2 + mt_ccap_countable_income: 3_525 + mt_ccap_enrolled: true + u2: + members: [p2] + spm_unit_size: + 2026: 2 + mt_ccap_countable_income: 3_526 + mt_ccap_enrolled: true + u3: + members: [p3] + spm_unit_size: + 2026: 3 + mt_ccap_countable_income: 4_442 + mt_ccap_enrolled: true + u4: + members: [p4] + spm_unit_size: + 2026: 3 + mt_ccap_countable_income: 4_443 + mt_ccap_enrolled: true + u5: + members: [p5] + spm_unit_size: + 2026: 4 + mt_ccap_countable_income: 5_358 + mt_ccap_enrolled: true + u6: + members: [p6] + spm_unit_size: + 2026: 4 + mt_ccap_countable_income: 5_359 + mt_ccap_enrolled: true + u7: + members: [p7] + spm_unit_size: + 2026: 5 + mt_ccap_countable_income: 6_275 + mt_ccap_enrolled: true + u8: + members: [p8] + spm_unit_size: + 2026: 5 + mt_ccap_countable_income: 6_276 + mt_ccap_enrolled: true + u9: + members: [p9] + spm_unit_size: + 2026: 6 + mt_ccap_countable_income: 7_192 + mt_ccap_enrolled: true + u10: + members: [p10] + spm_unit_size: + 2026: 6 + mt_ccap_countable_income: 7_193 + mt_ccap_enrolled: true + u11: + members: [p11] + spm_unit_size: + 2026: 7 + mt_ccap_countable_income: 8_108 + mt_ccap_enrolled: true + u12: + members: [p12] + spm_unit_size: + 2026: 7 + mt_ccap_countable_income: 8_109 + mt_ccap_enrolled: true + u13: + members: [p13] + spm_unit_size: + 2026: 8 + mt_ccap_countable_income: 9_025 + mt_ccap_enrolled: true + u14: + members: [p14] + spm_unit_size: + 2026: 8 + mt_ccap_countable_income: 9_026 + mt_ccap_enrolled: true + u15: + members: [p15] + spm_unit_size: + 2026: 9 + mt_ccap_countable_income: 9_942 + mt_ccap_enrolled: true + u16: + members: [p16] + spm_unit_size: + 2026: 9 + mt_ccap_countable_income: 9_943 + mt_ccap_enrolled: true + u17: + members: [p17] + spm_unit_size: + 2026: 10 + mt_ccap_countable_income: 10_858 + mt_ccap_enrolled: true + u18: + members: [p18] + spm_unit_size: + 2026: 10 + mt_ccap_countable_income: 10_859 + mt_ccap_enrolled: true + households: + h1: + members: [p1] + state_code: + 2026: MT + h2: + members: [p2] + state_code: + 2026: MT + h3: + members: [p3] + state_code: + 2026: MT + h4: + members: [p4] + state_code: + 2026: MT + h5: + members: [p5] + state_code: + 2026: MT + h6: + members: [p6] + state_code: + 2026: MT + h7: + members: [p7] + state_code: + 2026: MT + h8: + members: [p8] + state_code: + 2026: MT + h9: + members: [p9] + state_code: + 2026: MT + h10: + members: [p10] + state_code: + 2026: MT + h11: + members: [p11] + state_code: + 2026: MT + h12: + members: [p12] + state_code: + 2026: MT + h13: + members: [p13] + state_code: + 2026: MT + h14: + members: [p14] + state_code: + 2026: MT + h15: + members: [p15] + state_code: + 2026: MT + h16: + members: [p16] + state_code: + 2026: MT + h17: + members: [p17] + state_code: + 2026: MT + h18: + members: [p18] + state_code: + 2026: MT + output: + # 200% FPG GMI row, sizes 2 to 10. + mt_ccap_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/copay/nv_ccdp_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/copay/nv_ccdp_copay.yaml index 5a9abf5968c..4fa8979f4f4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/copay/nv_ccdp_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/copay/nv_ccdp_copay.yaml @@ -1,8 +1,13 @@ # nv_ccdp_copay: SPMUnit, float (USD), MONTH +# July 2022 through March 2024: federal funds reimburse the copayment, so it reads $0. +# April through September 2024: a share of gross income from the chart effective +# October 1, 2023, by household size. +# From October 2024, and standing in before July 2022, the flat schedule below applies. # Flat copay by income as a share of SMI (eff. Oct 1, 2024; State Plan 2.4.v): -# <= 32.99% SMI -> $0; 33%-42% SMI -> $90; above 42% SMI -> $150. -# The $150 band begins just above 42% SMI (threshold 0.4201) per the operational -# CC PT 06-25 fee chart; the State Plan summary's "43%" is superseded by the chart. +# up to 33% SMI -> $0; up to 42% SMI -> $90; above 42% SMI -> $150. +# The charts print each band top as the nearest dollar, and MS 316 rounds monthly +# income to the nearest dollar before reading them. The $150 band begins above 42% +# SMI per the operational fee charts; the State Plan summary's "43%" is superseded. # Waived for TANF/NEON (is_tanf_enrolled), CPS/foster placements, and homeless. # Family of 3, period 2025-01 -> monthly SMI = 6_721.82. @@ -153,10 +158,10 @@ # Eligible child in foster care -> protective-care waiver -> $0 nv_ccdp_copay: 0 -# Edge cases: copay-band cut-points. The scale is at-or-above (single_amount), -# so the 0.33 and 0.4201 thresholds belong to the HIGHER band: -# ratio < 0.33 -> $0; 0.33 <= ratio < 0.4201 -> $90; ratio >= 0.4201 -> $150. -# Family of 3, period 2025-01: monthly SMI = 6_721.82. +# Edge cases: copay-band cut-points. Each band top is a share of SMI rounded to the +# nearest dollar, and income above a top pays the next band. +# Family of 3, period 2025-01: monthly SMI = 6_721.82, so the $0 band tops out at +# round(0.33 * 6_721.82) = $2,218 and the $90 band at round(0.42 * 6_721.82) = $2,823. - name: Income just below the 33% SMI cut-point yields a zero copay. period: 2025-01 @@ -179,7 +184,7 @@ members: [person1, person2, person3] state_code: NV output: - # 2_200/mo / 6_721.82 = 0.3273 < 0.33 -> $0 + # 2_200 stays within the $2,218 top of the $0 band -> $0 nv_ccdp_copay: 0 - name: Income just above the 33% SMI cut-point yields a $90 copay. @@ -203,7 +208,7 @@ members: [person1, person2, person3] state_code: NV output: - # 2_225/mo / 6_721.82 = 0.3310 >= 0.33 -> $90 + # 2_225 exceeds the $2,218 top of the $0 band -> $90 nv_ccdp_copay: 90 - name: Income just below the 42% SMI cut-point stays in the $90 band. @@ -227,7 +232,7 @@ members: [person1, person2, person3] state_code: NV output: - # 2_800/mo / 6_721.82 = 0.4166 in [0.33, 0.4201) -> $90 + # 2_800 stays within the $2,823 top of the $90 band -> $90 nv_ccdp_copay: 90 - name: Income just above the 42% SMI cut-point yields a $150 copay. @@ -251,7 +256,7 @@ members: [person1, person2, person3] state_code: NV output: - # 2_850/mo / 6_721.82 = 0.4240 >= 0.4201 -> $150 + # 2_850 exceeds the $2,823 top of the $90 band -> $150 nv_ccdp_copay: 150 - name: Income at 42.8% SMI (above the operational 42% break) yields a $150 copay. @@ -275,7 +280,7 @@ members: [person1, person2, person3] state_code: NV output: - # 2_875/mo / 6_721.82 = 0.4277 >= 0.4201 -> $150. The State Plan summary + # 2_875 is 42.8% of SMI, above the $2,823 top -> $150. The State Plan summary # text ("43%-49% -> $150") would wrongly bucket this 42-43% SMI income as # $90; the operational chart (42% break) correctly makes it $150. nv_ccdp_copay: 150 @@ -383,3 +388,1230 @@ # 3_333/mo / 6_721.82 = 0.4959 >= 0.4201 -> $150; no eligible child in # protective care, so the waiver does not apply. nv_ccdp_copay: 150 + +- name: The flat schedule stands in for June 2022. + period: 2022-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2022: 30_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: NV + output: + # 2_500 / (82_509 * 0.84 / 12) = 0.4328 -> $150. + nv_ccdp_copay: 150 + +- name: In July 2022 federal funds reimburse the copayment. + period: 2022-07 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2022: 30_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2022: NV + output: + nv_ccdp_copay: 0 + +- name: In March 2024 federal funds still reimburse the copayment. + period: 2024-03 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 48_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + nv_ccdp_copay: 0 + +- name: In April 2024 the chart charges a family of three at $4,000 four percent. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 48_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + # Row $3,697 to $4,102 prints 4%. + nv_ccdp_copay: 160 + +- name: Under the April 2024 chart a family of 1 at $1,475 pays $0. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2024: 17_700 + households: + household: + members: [person1] + state_code: + 2024: NV + output: + nv_ccdp_copay: 0 + +- name: Under the April 2024 chart a family of 1 at $1,476 pays $14.76. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2024: 17_712 + households: + household: + members: [person1] + state_code: + 2024: NV + output: + nv_ccdp_copay: 14.76 + +- name: Under the April 2024 chart a family of 1 at $1,735 pays $17.35. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2024: 20_820 + households: + household: + members: [person1] + state_code: + 2024: NV + output: + nv_ccdp_copay: 17.35 + +- name: Under the April 2024 chart a family of 1 at $1,736 pays $34.72. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2024: 20_832 + households: + household: + members: [person1] + state_code: + 2024: NV + output: + nv_ccdp_copay: 34.72 + +- name: Under the April 2024 chart a family of 1 at $3,035 pays $182.1. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2024: 36_420 + households: + household: + members: [person1] + state_code: + 2024: NV + output: + nv_ccdp_copay: 182.1 + +- name: Under the April 2024 chart a family of 1 at $3,036 pays $212.52. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2024: 36_432 + households: + household: + members: [person1] + state_code: + 2024: NV + output: + nv_ccdp_copay: 212.52 + +- name: Under the April 2024 chart a family of 1 at $3,290.14 pays $230.31. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2024: 39_481.68 + households: + household: + members: [person1] + state_code: + 2024: NV + output: + nv_ccdp_copay: 230.31 + +- name: Under the April 2024 chart a family of 3 at $2,072 pays $0. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 24_864 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + nv_ccdp_copay: 0 + +- name: Under the April 2024 chart a family of 3 at $2,478 pays $0. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 29_736 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + nv_ccdp_copay: 0 + +- name: Under the April 2024 chart a family of 3 at $2,479 pays $24.79. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 29_748 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + nv_ccdp_copay: 24.79 + +- name: Under the April 2024 chart a family of 3 at $2,884 pays $28.84. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 34_608 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + nv_ccdp_copay: 28.84 + +- name: Under the April 2024 chart a family of 3 at $2,885 pays $57.7. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 34_620 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + nv_ccdp_copay: 57.7 + +- name: Under the April 2024 chart a family of 3 at $4,914 pays $294.84. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 58_968 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + nv_ccdp_copay: 294.84 + +- name: Under the April 2024 chart a family of 3 at $4,915 pays $344.05. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 58_980 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + nv_ccdp_copay: 344.05 + +- name: Under the April 2024 chart a family of 3 at $5,314 pays $371.98. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 63_768 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + # The top band charges 7%: 0.07 * 5_314 = 371.98. + nv_ccdp_copay: 371.98 + +- name: Under the April 2024 chart a family of 4 at $2,979 pays $0. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + person4: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2024: 35_748 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2024: NV + output: + nv_ccdp_copay: 0 + +- name: Under the April 2024 chart a family of 4 at $2,980 pays $29.8. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + person4: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2024: 35_760 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2024: NV + output: + nv_ccdp_copay: 29.8 + +- name: Under the April 2024 chart a family of 4 at $6,327.19 pays $442.9. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + person4: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2024: 75_926.28 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2024: NV + output: + nv_ccdp_copay: 442.9 + +- name: Under the April 2024 chart a family of 7 at $4,381 pays $0. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + person4: + age: + 2024: 5 + person5: + age: + 2024: 5 + person6: + age: + 2024: 5 + person7: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + nv_ccdp_countable_income: + 2024: 52_572 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2024: NV + output: + nv_ccdp_copay: 0 + +- name: Under the April 2024 chart a family of 7 at $4,382 pays $43.82. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + person4: + age: + 2024: 5 + person5: + age: + 2024: 5 + person6: + age: + 2024: 5 + person7: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + nv_ccdp_countable_income: + 2024: 52_584 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2024: NV + output: + nv_ccdp_copay: 43.82 + +- name: Under the April 2024 chart a family of 7 at $8,541 pays $597.87. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + person4: + age: + 2024: 5 + person5: + age: + 2024: 5 + person6: + age: + 2024: 5 + person7: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + nv_ccdp_countable_income: + 2024: 102_492 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2024: NV + output: + # The top band charges 7%: 0.07 * 8_541 = 597.87. + nv_ccdp_copay: 597.87 + +- name: Under the April 2024 chart a family of 14 at $7,170 pays $0. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + person4: + age: + 2024: 5 + person5: + age: + 2024: 5 + person6: + age: + 2024: 5 + person7: + age: + 2024: 5 + person8: + age: + 2024: 5 + person9: + age: + 2024: 5 + person10: + age: + 2024: 5 + person11: + age: + 2024: 5 + person12: + age: + 2024: 5 + person13: + age: + 2024: 5 + person14: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + nv_ccdp_countable_income: + 2024: 86_040 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: + 2024: NV + output: + nv_ccdp_copay: 0 + +- name: Under the April 2024 chart a family of 14 at $7,171 pays $71.71. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + person4: + age: + 2024: 5 + person5: + age: + 2024: 5 + person6: + age: + 2024: 5 + person7: + age: + 2024: 5 + person8: + age: + 2024: 5 + person9: + age: + 2024: 5 + person10: + age: + 2024: 5 + person11: + age: + 2024: 5 + person12: + age: + 2024: 5 + person13: + age: + 2024: 5 + person14: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + nv_ccdp_countable_income: + 2024: 86_052 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: + 2024: NV + output: + nv_ccdp_copay: 71.71 + +- name: Under the April 2024 chart a family of 14 at $9,870 pays $690.90. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + person4: + age: + 2024: 5 + person5: + age: + 2024: 5 + person6: + age: + 2024: 5 + person7: + age: + 2024: 5 + person8: + age: + 2024: 5 + person9: + age: + 2024: 5 + person10: + age: + 2024: 5 + person11: + age: + 2024: 5 + person12: + age: + 2024: 5 + person13: + age: + 2024: 5 + person14: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + nv_ccdp_countable_income: + 2024: 118_440 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: + 2024: NV + output: + # The top band charges 7%: 0.07 * 9_870 = 690.90. + nv_ccdp_copay: 690.9 + +- name: Copayments stay a share of income through September 2024. + period: 2024-09 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 30_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + # Row $2,479 to $2,884 prints 1%. + nv_ccdp_copay: 25 + +- name: Flat copayments start in October 2024. + period: 2024-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 30_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + # 2_500 / (96_026 * 0.84 / 12) = 0.3719 -> $90. + nv_ccdp_copay: 90 + +- name: Homeless households pay nothing under the April 2024 chart. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 48_000 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + is_homeless: + 2024: true + output: + nv_ccdp_copay: 0 + +- name: TANF families pay nothing under the April 2024 chart. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 48_000 + is_tanf_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + nv_ccdp_copay: 0 + +- name: Under the April 2024 chart a family of 3 at $2,478.25 rounds to $2,478 and pays $0. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 29_739 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + # MS 316 rounds monthly income to the nearest dollar before reading the chart. + nv_ccdp_copay: 0 + +- name: Under the April 2024 chart a family of 3 at $2,478.50 rounds to $2,479 and pays $24.79. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 29_742 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + # 1% of the rounded $2,479. + nv_ccdp_copay: 24.79 + +- name: Under the April 2024 chart a family of 2 at $1,976 pays $0. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2] + nv_ccdp_countable_income: + 2024: 23_712 + households: + household: + members: [person1, person2] + state_code: + 2024: NV + output: + nv_ccdp_copay: 0 + +- name: Under the April 2024 chart a family of 2 at $1,977 pays $19.77. + period: 2024-04 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2] + nv_ccdp_countable_income: + 2024: 23_724 + households: + household: + members: [person1, person2] + state_code: + 2024: NV + output: + nv_ccdp_copay: 19.77 + +- name: Under the October 2026 chart a new applicant of 1 at $1,502 pays $0. + period: 2026-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2026: 18_024 + nv_ccdp_enrolled: false + households: + household: + members: [person1] + state_code: + 2026: NV + output: + # The chart prints $1,502 as the top of the $0 band: 33% * 105_027 * 0.52 / 12 = 1_501.89. + nv_ccdp_copay: 0 + +- name: Under the October 2026 chart a new applicant of 1 at $1,503 pays $90. + period: 2026-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2026: 18_036 + nv_ccdp_enrolled: false + households: + household: + members: [person1] + state_code: + 2026: NV + output: + nv_ccdp_copay: 90 + +- name: Under the October 2026 chart a renewing family of 1 at $1,911 pays $90. + period: 2026-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2026: 22_932 + nv_ccdp_enrolled: true + households: + household: + members: [person1] + state_code: + 2026: NV + output: + # The renewal chart prints $1,911 as the top of the $90 band: 42% * 105_027 * 0.52 / 12 = 1_911.49. + nv_ccdp_copay: 90 + +- name: Under the October 2026 chart a renewing family of 1 at $1,912 pays $150. + period: 2026-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2026: 22_944 + nv_ccdp_enrolled: true + households: + household: + members: [person1] + state_code: + 2026: NV + output: + nv_ccdp_copay: 150 + +- name: Under the October 2026 chart a family of 3 at $2,426.49 rounds to $2,426 and pays $0. + period: 2026-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2026: 29_117.88 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: NV + output: + # The chart prints $2,426 as the top of the $0 band for three. + nv_ccdp_copay: 0 + +- name: Under the October 2026 chart a family of 3 at $2,426.50 rounds to $2,427 and pays $90. + period: 2026-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2026: 29_118 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: NV + output: + nv_ccdp_copay: 90 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/eligibility/nv_ccdp_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/eligibility/nv_ccdp_income_eligible.yaml index 332d78ad21a..545e44d56cc 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/eligibility/nv_ccdp_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/eligibility/nv_ccdp_income_eligible.yaml @@ -1,6 +1,8 @@ # nv_ccdp_income_eligible: SPMUnit, bool, MONTH +# From October 2024: # New applicants (not enrolled): monthly countable income <= 41% SMI (intake). # Enrolled families: monthly countable income <= 49% SMI (renewal/redetermination). +# Earlier dates carry their own shares; see the cases at the end of this file. # The 85% SMI federal mid-certification protection (45 CFR 98.21) is not modeled # because we don't track certification periods at the moment. # Family of 3, period 2025-01 -> monthly SMI = 6_721.82: @@ -308,3 +310,2394 @@ # intake limit = 0.41 * 11_042.99 = 4_527.63/mo. # 50_000 / 12 = 4_166.67/mo <= 4_527.63 -> eligible. nv_ccdp_income_eligible: true + +- name: Through 2017 a new applicant of three qualifies up to 85% of SMI. + period: 2017-10 + input: + people: + person1: + age: + 2017: 30 + person2: + age: + 2017: 5 + person3: + age: + 2017: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2017: 49_512 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2017: NV + output: + # Urban 2017 Table 14 prints $4,127: 85% * 69_361 * 0.84 / 12 = 4_126.98. + nv_ccdp_income_eligible: true + +- name: Through 2017 a new applicant of three above 85% of SMI fails. + period: 2017-10 + input: + people: + person1: + age: + 2017: 30 + person2: + age: + 2017: 5 + person3: + age: + 2017: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2017: 49_536 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2017: NV + output: + nv_ccdp_income_eligible: false + +- name: In October 2018 a new applicant of three at $4,000 fails the poverty-guideline limit. + period: 2018-10 + input: + people: + person1: + age: + 2018: 30 + person2: + age: + 2018: 5 + person3: + age: + 2018: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2018: 48_000 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2018: NV + output: + # 1.3 * 20_780 / 12 = 2_251.17, so the limit is $2,251. + nv_ccdp_income_eligible: false + +- name: In October 2018 an enrolled family of three at $4,000 stays within 85% of SMI. + period: 2018-10 + input: + people: + person1: + age: + 2018: 30 + person2: + age: + 2018: 5 + person3: + age: + 2018: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2018: 48_000 + nv_ccdp_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2018: NV + output: + # Urban 2022 Table F-3 prints $4,260 for continuing families: 85% * 71_593 * 0.84 / 12 = 4_259.78. + nv_ccdp_income_eligible: true + +- name: In June 2022 a new applicant of three at $4,000 still fails. + period: 2022-06 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2022: 48_000 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2022: NV + output: + # 1.3 * 21_960 / 12 = 2_379. + nv_ccdp_income_eligible: false + +- name: In July 2022 a new applicant of three at $4,000 qualifies under 85% of SMI. + period: 2022-07 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2022: 48_000 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2022: NV + output: + # The plan builds the July 2022 limits on the fiscal year 2023 table: + # 85% * 85_150 * 0.84 / 12 = 5_066.43, printed as $5,066 for three. + nv_ccdp_income_eligible: true + +- name: Under the October 2023 chart a new applicant of 1 at $3,290 qualifies. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2023: 39_480 + nv_ccdp_enrolled: false + households: + household: + members: [person1] + state_code: + 2023: NV + output: + # The chart's ceiling for 1 is $3,290.14. + nv_ccdp_income_eligible: true + +- name: Under the October 2023 chart a new applicant of 1 at $3,291 fails. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2023: 39_492 + nv_ccdp_enrolled: false + households: + household: + members: [person1] + state_code: + 2023: NV + output: + nv_ccdp_income_eligible: false + +- name: Under the October 2023 chart a new applicant of 3 at $5,314 qualifies. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2023: 63_768 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: NV + output: + # The chart's ceiling for 3 is $5,314.84. + nv_ccdp_income_eligible: true + +- name: Under the October 2023 chart a new applicant of 3 at $5,315 fails. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2023: 63_780 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2023: NV + output: + nv_ccdp_income_eligible: false + +- name: Under the October 2023 chart a new applicant of 4 at $6,327 qualifies. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + person4: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2023: 75_924 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2023: NV + output: + # The chart's ceiling for 4 is $6,327.19. + nv_ccdp_income_eligible: true + +- name: Under the October 2023 chart a new applicant of 4 at $6,328 fails. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + person4: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2023: 75_936 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2023: NV + output: + nv_ccdp_income_eligible: false + +- name: Under the October 2023 chart a new applicant of 7 at $8,541 qualifies. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + person4: + age: + 2023: 5 + person5: + age: + 2023: 5 + person6: + age: + 2023: 5 + person7: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + nv_ccdp_countable_income: + 2023: 102_492 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2023: NV + output: + # The chart's ceiling for 7 is $8,541.70. + nv_ccdp_income_eligible: true + +- name: Under the October 2023 chart a new applicant of 7 at $8,542 fails. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + person4: + age: + 2023: 5 + person5: + age: + 2023: 5 + person6: + age: + 2023: 5 + person7: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + nv_ccdp_countable_income: + 2023: 102_504 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2023: NV + output: + nv_ccdp_income_eligible: false + +- name: Under the October 2023 chart a new applicant of 14 at $9,870 qualifies. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + person4: + age: + 2023: 5 + person5: + age: + 2023: 5 + person6: + age: + 2023: 5 + person7: + age: + 2023: 5 + person8: + age: + 2023: 5 + person9: + age: + 2023: 5 + person10: + age: + 2023: 5 + person11: + age: + 2023: 5 + person12: + age: + 2023: 5 + person13: + age: + 2023: 5 + person14: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + nv_ccdp_countable_income: + 2023: 118_440 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: + 2023: NV + output: + # The chart's ceiling for 14 is $9,870.41. + nv_ccdp_income_eligible: true + +- name: Under the October 2023 chart a new applicant of 14 at $9,871 fails. + period: 2023-10 + input: + people: + person1: + age: + 2023: 30 + person2: + age: + 2023: 5 + person3: + age: + 2023: 5 + person4: + age: + 2023: 5 + person5: + age: + 2023: 5 + person6: + age: + 2023: 5 + person7: + age: + 2023: 5 + person8: + age: + 2023: 5 + person9: + age: + 2023: 5 + person10: + age: + 2023: 5 + person11: + age: + 2023: 5 + person12: + age: + 2023: 5 + person13: + age: + 2023: 5 + person14: + age: + 2023: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + nv_ccdp_countable_income: + 2023: 118_452 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: + 2023: NV + output: + nv_ccdp_income_eligible: false + +- name: The deck family of three at $40,000 qualifies as a new applicant in September 2024. + period: 2024-09 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 39_999.96 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + # 85% * 89_325 * 0.84 / 12 = 5_314.84. + nv_ccdp_income_eligible: true + +- name: The deck family of three at $40,000 fails as a new applicant in October 2024. + period: 2024-10 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 39_999.96 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + # 41% * 96_026 * 0.84 / 12 = 2_755.95; FFY 2025 chart prints $2,756. + nv_ccdp_income_eligible: false + +- name: The deck family of three at $40,000 fails at renewal in October 2024. + period: 2024-10 + input: + people: + person1: + age: + 2024: 30 + person2: + age: + 2024: 5 + person3: + age: + 2024: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2024: 39_999.96 + nv_ccdp_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2024: NV + output: + # 49% * 96_026 * 0.84 / 12 = 3_293.69. + nv_ccdp_income_eligible: false + +- name: Under the October 2026 chart a new applicant of 3 at $3,014 qualifies. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2026: 36_168 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: NV + output: + nv_ccdp_income_eligible: true + +- name: Under the October 2026 chart a new applicant of 3 at $3,015 fails. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2026: 36_180 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2026: NV + output: + nv_ccdp_income_eligible: false + +- name: Under the October 2026 chart a renewing family of 3 at $3,602 qualifies. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2026: 43_224 + nv_ccdp_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: NV + output: + nv_ccdp_income_eligible: true + +- name: Under the October 2026 chart a renewing family of 3 at $3,603 fails. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2026: 43_236 + nv_ccdp_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: + 2026: NV + output: + nv_ccdp_income_eligible: false + +- name: Under the October 2026 chart a new applicant of 4 at $3,588 qualifies. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + person4: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2026: 43_056 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: NV + output: + nv_ccdp_income_eligible: true + +- name: Under the October 2026 chart a new applicant of 4 at $3,589 fails. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + person4: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2026: 43_068 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: NV + output: + nv_ccdp_income_eligible: false + +- name: Under the October 2026 chart a renewing family of 4 at $4,288 qualifies. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + person4: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2026: 51_456 + nv_ccdp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: NV + output: + nv_ccdp_income_eligible: true + +- name: Under the October 2026 chart a renewing family of 4 at $4,290 fails. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + person4: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2026: 51_480 + nv_ccdp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: NV + output: + nv_ccdp_income_eligible: false + +- name: In September 2018 a new applicant of three at $4,000 still qualifies under 85% of SMI. + period: 2018-09 + input: + people: + p1_1: + age: + 2018: 30 + p1_2: + age: + 2018: 5 + p1_3: + age: + 2018: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + nv_ccdp_countable_income: + 2018: 48_000 + nv_ccdp_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2018: NV + output: + # The poverty-guideline limit starts in October 2018. Urban prints $4,127 a month, + # 85% of SMI for three, in October 2017. + nv_ccdp_income_eligible: [true] + +- name: In October 2018 new applicants of three face 130% of the 2018 guideline unless a protective or homeless exception applies. + period: 2018-10 + input: + people: + p1_1: + age: + 2018: 30 + p1_2: + age: + 2018: 5 + p1_3: + age: + 2018: 5 + p2_1: + age: + 2018: 30 + p2_2: + age: + 2018: 5 + p2_3: + age: + 2018: 5 + p3_1: + age: + 2018: 30 + p3_2: + age: + 2018: 5 + is_in_foster_care: true + p3_3: + age: + 2018: 5 + p4_1: + age: + 2018: 30 + p4_2: + age: + 2018: 5 + p4_3: + age: + 2018: 5 + receives_or_needs_protective_services: + 2018: true + p5_1: + age: + 2018: 30 + p5_2: + age: + 2018: 5 + p5_3: + age: + 2018: 5 + p6_1: + age: + 2018: 30 + p6_2: + age: + 2018: 15 + is_in_foster_care: true + p6_3: + age: + 2018: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + nv_ccdp_countable_income: + 2018: 27_012 + nv_ccdp_enrolled: false + u2: + members: [p2_1, p2_2, p2_3] + nv_ccdp_countable_income: + 2018: 27_024 + nv_ccdp_enrolled: false + u3: + members: [p3_1, p3_2, p3_3] + nv_ccdp_countable_income: + 2018: 48_000 + nv_ccdp_enrolled: false + u4: + members: [p4_1, p4_2, p4_3] + nv_ccdp_countable_income: + 2018: 48_000 + nv_ccdp_enrolled: false + u5: + members: [p5_1, p5_2, p5_3] + nv_ccdp_countable_income: + 2018: 48_000 + nv_ccdp_enrolled: false + u6: + members: [p6_1, p6_2, p6_3] + nv_ccdp_countable_income: + 2018: 48_000 + nv_ccdp_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2018: NV + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2018: NV + h3: + members: [p3_1, p3_2, p3_3] + state_code: + 2018: NV + h4: + members: [p4_1, p4_2, p4_3] + state_code: + 2018: NV + h5: + members: [p5_1, p5_2, p5_3] + state_code: + 2018: NV + is_homeless: + 2018: true + h6: + members: [p6_1, p6_2, p6_3] + state_code: + 2018: NV + output: + # 1.3 * 20_780 / 12 = 2_251.17, which rounds to $2,251. + # Units 3-5 keep 85% of SMI ($4,259.78) for a foster child, a child in protective + # services and a homeless family. Unit 6's 15-year-old in foster care is too old + # for CCDP, so the family faces the poverty-guideline limit. + nv_ccdp_income_eligible: [true, false, true, true, true, false] + +- name: In February 2019 a new applicant of three qualifies up to NWLC's $27,012 a year. + period: 2019-02 + input: + people: + p1_1: + age: + 2019: 30 + p1_2: + age: + 2019: 5 + p1_3: + age: + 2019: 5 + p2_1: + age: + 2019: 30 + p2_2: + age: + 2019: 5 + p2_3: + age: + 2019: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + nv_ccdp_countable_income: + 2019: 27_012 + nv_ccdp_enrolled: false + u2: + members: [p2_1, p2_2, p2_3] + nv_ccdp_countable_income: + 2019: 27_024 + nv_ccdp_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2019: NV + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2019: NV + output: + # NWLC prints $27,012 a year for three, or $2,251 a month: 130% of the 2018 guideline. + nv_ccdp_income_eligible: [true, false] + +- name: In September 2019 a new applicant of three still faces the 2018 guideline. + period: 2019-09 + input: + people: + p1_1: + age: + 2019: 30 + p1_2: + age: + 2019: 5 + p1_3: + age: + 2019: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + nv_ccdp_countable_income: + 2019: 27_024 + nv_ccdp_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2019: NV + output: + # The 2019 guideline would allow $2,311; Nevada takes it up on October 1. + nv_ccdp_income_eligible: [false] + +- name: In October 2019 a new applicant of three faces 130% of the 2019 guideline. + period: 2019-10 + input: + people: + p1_1: + age: + 2019: 30 + p1_2: + age: + 2019: 5 + p1_3: + age: + 2019: 5 + p2_1: + age: + 2019: 30 + p2_2: + age: + 2019: 5 + p2_3: + age: + 2019: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + nv_ccdp_countable_income: + 2019: 27_732 + nv_ccdp_enrolled: false + u2: + members: [p2_1, p2_2, p2_3] + nv_ccdp_countable_income: + 2019: 27_744 + nv_ccdp_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2019: NV + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2019: NV + output: + # NWLC prints $27,729 a year from October 2019: 1.3 * 21_330 / 12 = 2_310.75, which rounds to $2,311. + nv_ccdp_income_eligible: [true, false] + +- name: Under the October 2020 chart new applicants of one to five qualify up to each printed limit. + period: 2020-10 + input: + people: + p1_1: + age: + 2020: 30 + p2_1: + age: + 2020: 30 + p3_1: + age: + 2020: 30 + p3_2: + age: + 2020: 5 + p4_1: + age: + 2020: 30 + p4_2: + age: + 2020: 5 + p5_1: + age: + 2020: 30 + p5_2: + age: + 2020: 5 + p5_3: + age: + 2020: 5 + p6_1: + age: + 2020: 30 + p6_2: + age: + 2020: 5 + p6_3: + age: + 2020: 5 + p7_1: + age: + 2020: 30 + p7_2: + age: + 2020: 5 + p7_3: + age: + 2020: 5 + p7_4: + age: + 2020: 5 + p8_1: + age: + 2020: 30 + p8_2: + age: + 2020: 5 + p8_3: + age: + 2020: 5 + p8_4: + age: + 2020: 5 + p9_1: + age: + 2020: 30 + p9_2: + age: + 2020: 5 + p9_3: + age: + 2020: 5 + p9_4: + age: + 2020: 5 + p9_5: + age: + 2020: 5 + p10_1: + age: + 2020: 30 + p10_2: + age: + 2020: 5 + p10_3: + age: + 2020: 5 + p10_4: + age: + 2020: 5 + p10_5: + age: + 2020: 5 + spm_units: + u1: + members: [p1_1] + nv_ccdp_countable_income: + 2020: 16_584 + nv_ccdp_enrolled: false + u2: + members: [p2_1] + nv_ccdp_countable_income: + 2020: 16_596 + nv_ccdp_enrolled: false + u3: + members: [p3_1, p3_2] + nv_ccdp_countable_income: + 2020: 22_416 + nv_ccdp_enrolled: false + u4: + members: [p4_1, p4_2] + nv_ccdp_countable_income: + 2020: 22_428 + nv_ccdp_enrolled: false + u5: + members: [p5_1, p5_2, p5_3] + nv_ccdp_countable_income: + 2020: 28_236 + nv_ccdp_enrolled: false + u6: + members: [p6_1, p6_2, p6_3] + nv_ccdp_countable_income: + 2020: 28_248 + nv_ccdp_enrolled: false + u7: + members: [p7_1, p7_2, p7_3, p7_4] + nv_ccdp_countable_income: + 2020: 34_056 + nv_ccdp_enrolled: false + u8: + members: [p8_1, p8_2, p8_3, p8_4] + nv_ccdp_countable_income: + 2020: 34_068 + nv_ccdp_enrolled: false + u9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5] + nv_ccdp_countable_income: + 2020: 39_888 + nv_ccdp_enrolled: false + u10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5] + nv_ccdp_countable_income: + 2020: 39_900 + nv_ccdp_enrolled: false + households: + h1: + members: [p1_1] + state_code: + 2020: NV + h2: + members: [p2_1] + state_code: + 2020: NV + h3: + members: [p3_1, p3_2] + state_code: + 2020: NV + h4: + members: [p4_1, p4_2] + state_code: + 2020: NV + h5: + members: [p5_1, p5_2, p5_3] + state_code: + 2020: NV + h6: + members: [p6_1, p6_2, p6_3] + state_code: + 2020: NV + h7: + members: [p7_1, p7_2, p7_3, p7_4] + state_code: + 2020: NV + h8: + members: [p8_1, p8_2, p8_3, p8_4] + state_code: + 2020: NV + h9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5] + state_code: + 2020: NV + h10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5] + state_code: + 2020: NV + output: + # The draft FFY 2022-2024 plan prints $1,382, $1,868, $2,353, $2,838 and $3,324 for one + # to five people from October 1, 2020: 130% of the 2020 guideline to the nearest dollar. + nv_ccdp_income_eligible: [true, false, true, false, true, false, true, false, true, false] + +- name: In September 2021 a new applicant of three still faces the 2020 guideline. + period: 2021-09 + input: + people: + p1_1: + age: + 2021: 30 + p1_2: + age: + 2021: 5 + p1_3: + age: + 2021: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + nv_ccdp_countable_income: + 2021: 28_248 + nv_ccdp_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2021: NV + output: + # The 2021 guideline would allow $2,379; Nevada takes it up on October 1. + nv_ccdp_income_eligible: [false] + +- name: In October 2021 a new applicant of three faces 130% of the 2021 guideline. + period: 2021-10 + input: + people: + p1_1: + age: + 2021: 30 + p1_2: + age: + 2021: 5 + p1_3: + age: + 2021: 5 + p2_1: + age: + 2021: 30 + p2_2: + age: + 2021: 5 + p2_3: + age: + 2021: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + nv_ccdp_countable_income: + 2021: 28_548 + nv_ccdp_enrolled: false + u2: + members: [p2_1, p2_2, p2_3] + nv_ccdp_countable_income: + 2021: 28_560 + nv_ccdp_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2021: NV + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2021: NV + output: + # Urban's Table B-1 prints the state's $2,379 for October 1, 2021: 1.3 * 21_960 / 12 = 2_379. + nv_ccdp_income_eligible: [true, false] + +- name: In June 2022 a new applicant of three still faces 130% of the 2021 guideline. + period: 2022-06 + input: + people: + p1_1: + age: + 2022: 30 + p1_2: + age: + 2022: 5 + p1_3: + age: + 2022: 5 + p2_1: + age: + 2022: 30 + p2_2: + age: + 2022: 5 + p2_3: + age: + 2022: 5 + spm_units: + u1: + members: [p1_1, p1_2, p1_3] + nv_ccdp_countable_income: + 2022: 28_548 + nv_ccdp_enrolled: false + u2: + members: [p2_1, p2_2, p2_3] + nv_ccdp_countable_income: + 2022: 28_560 + nv_ccdp_enrolled: false + households: + h1: + members: [p1_1, p1_2, p1_3] + state_code: + 2022: NV + h2: + members: [p2_1, p2_2, p2_3] + state_code: + 2022: NV + output: + # The limit moves to 85% of SMI on July 1, 2022. + nv_ccdp_income_eligible: [true, false] + +- name: In July 2022 a new applicant of three at $5,000 qualifies on the fiscal year 2023 table. + period: 2022-07 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2022: 60_000 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2022: NV + output: + # The October 2021 table would give 4_909.29 and deny this family. + nv_ccdp_income_eligible: true + +- name: In July 2022 a new applicant of three at $5,066.49 rounds to $5,066 and qualifies. + period: 2022-07 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2022: 60_797.88 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2022: NV + output: + # MS 316 rounds monthly income to the nearest dollar. + nv_ccdp_income_eligible: true + +- name: In July 2022 a new applicant of three at $5,066.50 rounds to $5,067 and fails. + period: 2022-07 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2022: 60_798 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2022: NV + output: + nv_ccdp_income_eligible: false + +- name: In September 2022 a new applicant of three at $5,066 still qualifies on the fiscal year 2023 table. + period: 2022-09 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2022: 60_792 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2022: NV + output: + nv_ccdp_income_eligible: true + +- name: In October 2022 a new applicant of three at $5,067 fails on the fiscal year 2023 table. + period: 2022-10 + input: + people: + person1: + age: + 2022: 30 + person2: + age: + 2022: 5 + person3: + age: + 2022: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2022: 60_804 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2022: NV + output: + # The fiscal year 2023 table takes effect on its own start; the fiscal year 2024 table would give 5_314.84. + nv_ccdp_income_eligible: false + +- name: Under the October 2025 chart a new applicant of 3 at $2,890 qualifies. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2025: 34_680 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: NV + output: + # CC PT 06-25 prints $2,890 for three: 41% * 100_681 * 0.84 / 12 = 2_889.54, rounded to the nearest dollar. + nv_ccdp_income_eligible: true + +- name: Under the October 2025 chart a new applicant of 3 at $2,891 fails. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + person2: + age: + 2025: 5 + person3: + age: + 2025: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + nv_ccdp_countable_income: + 2025: 34_692 + nv_ccdp_enrolled: false + households: + household: + members: [person1, person2, person3] + state_code: + 2025: NV + output: + nv_ccdp_income_eligible: false + +- name: Under the October 2025 chart a new applicant of 1 at $1,789 qualifies. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2025: 21_468 + nv_ccdp_enrolled: false + households: + household: + members: [person1] + state_code: + 2025: NV + output: + # CC PT 06-25 prints $1,789 for one: 41% * 100_681 * 0.52 / 12 = 1_788.77. + nv_ccdp_income_eligible: true + +- name: Under the October 2025 chart a new applicant of 1 at $1,790 fails. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + spm_units: + spm_unit: + members: [person1] + nv_ccdp_countable_income: + 2025: 21_480 + nv_ccdp_enrolled: false + households: + household: + members: [person1] + state_code: + 2025: NV + output: + nv_ccdp_income_eligible: false + +- name: Under the October 2026 chart a renewing family of 4 at $4,289 qualifies. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 5 + person3: + age: + 2026: 5 + person4: + age: + 2026: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nv_ccdp_countable_income: + 2026: 51_468 + nv_ccdp_enrolled: true + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: NV + output: + # The chart prints $4,289 for four: 49% * 105_027 / 12 = 4_288.60, rounded to the nearest dollar. + nv_ccdp_income_eligible: true + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. +# Nevada's countable income is annual, so each case gives twelve times the +# monthly amount. + +- name: The October 1, 2026 intake chart holds at sizes 1 to 12. + period: 2026-10 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + nv_ccdp_countable_income: + 2026: 22_392 + nv_ccdp_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 1 + nv_ccdp_countable_income: + 2026: 22_404 + nv_ccdp_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 2 + nv_ccdp_countable_income: + 2026: 29_280 + nv_ccdp_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 2 + nv_ccdp_countable_income: + 2026: 29_292 + nv_ccdp_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 3 + nv_ccdp_countable_income: + 2026: 36_168 + nv_ccdp_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 3 + nv_ccdp_countable_income: + 2026: 36_180 + nv_ccdp_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 4 + nv_ccdp_countable_income: + 2026: 43_056 + nv_ccdp_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 4 + nv_ccdp_countable_income: + 2026: 43_068 + nv_ccdp_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 5 + nv_ccdp_countable_income: + 2026: 49_956 + nv_ccdp_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 5 + nv_ccdp_countable_income: + 2026: 49_968 + nv_ccdp_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 6 + nv_ccdp_countable_income: + 2026: 56_844 + nv_ccdp_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 6 + nv_ccdp_countable_income: + 2026: 56_856 + nv_ccdp_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 7 + nv_ccdp_countable_income: + 2026: 58_128 + nv_ccdp_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 7 + nv_ccdp_countable_income: + 2026: 58_140 + nv_ccdp_enrolled: false + u15: + members: [p15] + spm_unit_size: + 2026: 8 + nv_ccdp_countable_income: + 2026: 59_424 + nv_ccdp_enrolled: false + u16: + members: [p16] + spm_unit_size: + 2026: 8 + nv_ccdp_countable_income: + 2026: 59_436 + nv_ccdp_enrolled: false + u17: + members: [p17] + spm_unit_size: + 2026: 9 + nv_ccdp_countable_income: + 2026: 60_720 + nv_ccdp_enrolled: false + u18: + members: [p18] + spm_unit_size: + 2026: 9 + nv_ccdp_countable_income: + 2026: 60_732 + nv_ccdp_enrolled: false + u19: + members: [p19] + spm_unit_size: + 2026: 10 + nv_ccdp_countable_income: + 2026: 62_004 + nv_ccdp_enrolled: false + u20: + members: [p20] + spm_unit_size: + 2026: 10 + nv_ccdp_countable_income: + 2026: 62_016 + nv_ccdp_enrolled: false + u21: + members: [p21] + spm_unit_size: + 2026: 11 + nv_ccdp_countable_income: + 2026: 63_300 + nv_ccdp_enrolled: false + u22: + members: [p22] + spm_unit_size: + 2026: 11 + nv_ccdp_countable_income: + 2026: 63_312 + nv_ccdp_enrolled: false + u23: + members: [p23] + spm_unit_size: + 2026: 12 + nv_ccdp_countable_income: + 2026: 64_596 + nv_ccdp_enrolled: false + u24: + members: [p24] + spm_unit_size: + 2026: 12 + nv_ccdp_countable_income: + 2026: 64_608 + nv_ccdp_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: NV + h2: + members: [p2] + state_code: + 2026: NV + h3: + members: [p3] + state_code: + 2026: NV + h4: + members: [p4] + state_code: + 2026: NV + h5: + members: [p5] + state_code: + 2026: NV + h6: + members: [p6] + state_code: + 2026: NV + h7: + members: [p7] + state_code: + 2026: NV + h8: + members: [p8] + state_code: + 2026: NV + h9: + members: [p9] + state_code: + 2026: NV + h10: + members: [p10] + state_code: + 2026: NV + h11: + members: [p11] + state_code: + 2026: NV + h12: + members: [p12] + state_code: + 2026: NV + h13: + members: [p13] + state_code: + 2026: NV + h14: + members: [p14] + state_code: + 2026: NV + h15: + members: [p15] + state_code: + 2026: NV + h16: + members: [p16] + state_code: + 2026: NV + h17: + members: [p17] + state_code: + 2026: NV + h18: + members: [p18] + state_code: + 2026: NV + h19: + members: [p19] + state_code: + 2026: NV + h20: + members: [p20] + state_code: + 2026: NV + h21: + members: [p21] + state_code: + 2026: NV + h22: + members: [p22] + state_code: + 2026: NV + h23: + members: [p23] + state_code: + 2026: NV + h24: + members: [p24] + state_code: + 2026: NV + output: + # Household Size and Monthly Income Chart (Intake 41% SMI), sizes 1 to 12. + nv_ccdp_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: The October 1, 2026 renewal chart holds at sizes 1 to 12. + period: 2026-10 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + p23: + age: + 2026: 30 + p24: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + nv_ccdp_countable_income: + 2026: 26_760 + nv_ccdp_enrolled: true + u2: + members: [p2] + spm_unit_size: + 2026: 1 + nv_ccdp_countable_income: + 2026: 26_772 + nv_ccdp_enrolled: true + u3: + members: [p3] + spm_unit_size: + 2026: 2 + nv_ccdp_countable_income: + 2026: 34_992 + nv_ccdp_enrolled: true + u4: + members: [p4] + spm_unit_size: + 2026: 2 + nv_ccdp_countable_income: + 2026: 35_004 + nv_ccdp_enrolled: true + u5: + members: [p5] + spm_unit_size: + 2026: 3 + nv_ccdp_countable_income: + 2026: 43_224 + nv_ccdp_enrolled: true + u6: + members: [p6] + spm_unit_size: + 2026: 3 + nv_ccdp_countable_income: + 2026: 43_236 + nv_ccdp_enrolled: true + u7: + members: [p7] + spm_unit_size: + 2026: 4 + nv_ccdp_countable_income: + 2026: 51_468 + nv_ccdp_enrolled: true + u8: + members: [p8] + spm_unit_size: + 2026: 4 + nv_ccdp_countable_income: + 2026: 51_480 + nv_ccdp_enrolled: true + u9: + members: [p9] + spm_unit_size: + 2026: 5 + nv_ccdp_countable_income: + 2026: 59_700 + nv_ccdp_enrolled: true + u10: + members: [p10] + spm_unit_size: + 2026: 5 + nv_ccdp_countable_income: + 2026: 59_712 + nv_ccdp_enrolled: true + u11: + members: [p11] + spm_unit_size: + 2026: 6 + nv_ccdp_countable_income: + 2026: 67_932 + nv_ccdp_enrolled: true + u12: + members: [p12] + spm_unit_size: + 2026: 6 + nv_ccdp_countable_income: + 2026: 67_944 + nv_ccdp_enrolled: true + u13: + members: [p13] + spm_unit_size: + 2026: 7 + nv_ccdp_countable_income: + 2026: 69_480 + nv_ccdp_enrolled: true + u14: + members: [p14] + spm_unit_size: + 2026: 7 + nv_ccdp_countable_income: + 2026: 69_492 + nv_ccdp_enrolled: true + u15: + members: [p15] + spm_unit_size: + 2026: 8 + nv_ccdp_countable_income: + 2026: 71_016 + nv_ccdp_enrolled: true + u16: + members: [p16] + spm_unit_size: + 2026: 8 + nv_ccdp_countable_income: + 2026: 71_028 + nv_ccdp_enrolled: true + u17: + members: [p17] + spm_unit_size: + 2026: 9 + nv_ccdp_countable_income: + 2026: 72_564 + nv_ccdp_enrolled: true + u18: + members: [p18] + spm_unit_size: + 2026: 9 + nv_ccdp_countable_income: + 2026: 72_576 + nv_ccdp_enrolled: true + u19: + members: [p19] + spm_unit_size: + 2026: 10 + nv_ccdp_countable_income: + 2026: 74_112 + nv_ccdp_enrolled: true + u20: + members: [p20] + spm_unit_size: + 2026: 10 + nv_ccdp_countable_income: + 2026: 74_124 + nv_ccdp_enrolled: true + u21: + members: [p21] + spm_unit_size: + 2026: 11 + nv_ccdp_countable_income: + 2026: 75_648 + nv_ccdp_enrolled: true + u22: + members: [p22] + spm_unit_size: + 2026: 11 + nv_ccdp_countable_income: + 2026: 75_660 + nv_ccdp_enrolled: true + u23: + members: [p23] + spm_unit_size: + 2026: 12 + nv_ccdp_countable_income: + 2026: 77_196 + nv_ccdp_enrolled: true + u24: + members: [p24] + spm_unit_size: + 2026: 12 + nv_ccdp_countable_income: + 2026: 77_208 + nv_ccdp_enrolled: true + households: + h1: + members: [p1] + state_code: + 2026: NV + h2: + members: [p2] + state_code: + 2026: NV + h3: + members: [p3] + state_code: + 2026: NV + h4: + members: [p4] + state_code: + 2026: NV + h5: + members: [p5] + state_code: + 2026: NV + h6: + members: [p6] + state_code: + 2026: NV + h7: + members: [p7] + state_code: + 2026: NV + h8: + members: [p8] + state_code: + 2026: NV + h9: + members: [p9] + state_code: + 2026: NV + h10: + members: [p10] + state_code: + 2026: NV + h11: + members: [p11] + state_code: + 2026: NV + h12: + members: [p12] + state_code: + 2026: NV + h13: + members: [p13] + state_code: + 2026: NV + h14: + members: [p14] + state_code: + 2026: NV + h15: + members: [p15] + state_code: + 2026: NV + h16: + members: [p16] + state_code: + 2026: NV + h17: + members: [p17] + state_code: + 2026: NV + h18: + members: [p18] + state_code: + 2026: NV + h19: + members: [p19] + state_code: + 2026: NV + h20: + members: [p20] + state_code: + 2026: NV + h21: + members: [p21] + state_code: + 2026: NV + h22: + members: [p22] + state_code: + 2026: NV + h23: + members: [p23] + state_code: + 2026: NV + h24: + members: [p24] + state_code: + 2026: NV + output: + # Household Size and Monthly Income Chart (Renewal 49% SMI), sizes 1 to 12. + nv_ccdp_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/nv_ccdp.yaml b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/nv_ccdp.yaml index 242cf0bff4a..4e7fbd8fe1f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/nv_ccdp.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/ccdp/nv_ccdp.yaml @@ -388,10 +388,10 @@ # Income 17_160 / 12 = 1_430 per month; care 7_894 / 12 = 657.83 per month. # Age 5 -> PRESCHOOL; max rate = 51.50 * 21.67 = 1_116.005, so the charge binds. # 2015-09, FFY 2015 table: SMI = 65_832 * 0.68 / 12 = 3_730.48. - # 1_430 <= 41% * 3_730.48 = 1_529.50 -> eligible. + # 1_430 <= 85% * 3_730.48 = 3_170.91 -> eligible. # Ratio 1_430 / 3_730.48 = 0.3833 -> $90 copay (33% to 42% band). # 2015-10, FFY 2016 table: SMI = 66_461 * 0.68 / 12 = 3_766.12. - # 1_430 <= 41% * 3_766.12 = 1_544.11 -> eligible. + # 1_430 <= 85% * 3_766.12 = 3_201.20 -> eligible. # Ratio 1_430 / 3_766.12 = 0.3797 -> $90 copay. # benefit = min(657.83, 1_116.005) - 90 = 567.83 in both months. nv_ccdp_smi: diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp.yaml new file mode 100644 index 00000000000..527f15d6021 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp.yaml @@ -0,0 +1,354 @@ +# Procedure Letter 36, pages 2 and 4: one monthly payment per child, up to the provider's private rate. + +- name: Family of three earning $40,000 with a toddler and a preschooler at centers. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + person3: + age: 4 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_333.33 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + # Procedure Letter 36: 800 + 750. + oh_ccap_eligible: false + oh_ccap: 0 + oh_ccvp_eligible: true + oh_ccvp: 1_550 + +- name: The charge caps the payment for each child. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 6_000 + person3: + age: 4 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + # min(800, 6,000 / 12 = 500) + min(750, 2,000) = 1,250. + oh_ccvp: 1_250 + +- name: Each child takes its own provider's rate. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + person3: + age: 4 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + oh_ccap_provider_type: HOME + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + # Center toddler 800 + home preschooler 500. + oh_ccvp: 1_300 + +- name: A child without a charge draws no payment. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 0 + person3: + age: 4 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccvp: 750 + +- name: A family over the limit draws no payment. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + person3: + age: 4 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 4_443 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccvp_eligible: false + oh_ccvp: 0 + +- name: A family on Publicly Funded Child Care draws no voucher payment. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + person3: + age: 4 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 2_000 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccap_eligible: true + oh_ccvp: 0 + +- name: November 2026 pays the Publicly Funded Child Care rates. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + pre_subsidy_childcare_expenses: + 2026: 24_000 + childcare_hours_per_week: + 2026: 40 + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + pre_subsidy_childcare_expenses: + 2026: 24_000 + childcare_hours_per_week: + 2026: 40 + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # Category 1 center full-time: 780 + 693.33. + oh_ccvp: 1_473.33 + +- name: November 2026 adds no Step Up to Quality bonus. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + pre_subsidy_childcare_expenses: + 2026: 24_000 + childcare_hours_per_week: + 2026: 40 + oh_ccap_quality_tier: GOLD + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + pre_subsidy_childcare_expenses: + 2026: 24_000 + childcare_hours_per_week: + 2026: 40 + oh_ccap_quality_tier: GOLD + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # H.B. 96, Section 423.190, rules out Step Up to Quality rates: 780 + 693.33. + oh_ccvp: 1_473.33 + +- name: November 2026 adds the accreditation payment at an accredited gold-rated center. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + pre_subsidy_childcare_expenses: + 2026: 24_000 + childcare_hours_per_week: + 2026: 40 + oh_ccap_quality_tier: GOLD + oh_ccap_is_accredited: true + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + pre_subsidy_childcare_expenses: + 2026: 24_000 + childcare_hours_per_week: + 2026: 40 + oh_ccap_quality_tier: GOLD + oh_ccap_is_accredited: true + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # H.B. 96, Section 423.190, rules out only the Step Up to Quality rates, so 5180:6-1-10(D)(1) + # adds 10%: 780 x 1.10 + 693.33 x 1.10 = 858 + 762.67. + oh_ccvp: 1_620.67 + +- name: November 2026 caps the payment at the charge. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + pre_subsidy_childcare_expenses: + 2026: 6_000 + childcare_hours_per_week: + 2026: 40 + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + pre_subsidy_childcare_expenses: + 2026: 24_000 + childcare_hours_per_week: + 2026: 40 + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # min(780, 500) + min(693.33, 2,000) = 1,193.33. + oh_ccvp: 1_193.33 diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible.yaml new file mode 100644 index 00000000000..622377ba7b9 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible.yaml @@ -0,0 +1,2318 @@ +# Ohio Child Care Choice Voucher Program eligibility. +# Procedure Letter 36 (October 29, 2025), pages 3-4: income of 146-200% of poverty, all other +# Publicly Funded Child Care conditions, and no family eligible for that program. +# Procedure Letter 21, page 2, and Procedure Letter 45, page 2, print the monthly limits. +# H.B. 96, Section 423.190, sets the same income conditions in law. + +- name: Family of three at the January 2026 Publicly Funded Child Care intake limit stays on that program. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_221 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + # Procedure Letter 21: 145% prints $3,221 for three. + oh_ccap_income_eligible: true + oh_ccvp_eligible: false + +- name: One dollar over the January 2026 intake limit qualifies for the voucher. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_222 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccap_income_eligible: false + oh_ccvp_eligible: true + +- name: January 2026 voucher limit. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 4_442 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + # Procedure Letter 21: 200% prints $4,442 for three. + oh_ccvp_eligible: true + +- name: One dollar over the January 2026 voucher limit. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 4_443 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccvp_eligible: false + +- name: September 2026 still reads the 2025 guideline. + period: 2026-09 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_222 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + output: + oh_ccap_income_eligible: false + oh_ccvp_eligible: true + +- name: October 2026 moves the same family back to Publicly Funded Child Care. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_222 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + output: + # Procedure Letter 45: 145% prints $3,302 for three from October 1, 2026. + oh_ccap_income_eligible: true + oh_ccvp_eligible: false + +- name: October 2026 intake limit. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_302 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + output: + oh_ccap_income_eligible: true + oh_ccvp_eligible: false + +- name: One dollar over the October 2026 intake limit. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_303 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + output: + oh_ccap_income_eligible: false + oh_ccvp_eligible: true + +- name: October 2026 voucher limit for three. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 4_554 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + output: + # Procedure Letter 45: 200% prints $4,554 for three. + oh_ccvp_eligible: true + +- name: One dollar over the October 2026 voucher limit for three. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 4 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 4_555 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: OH + output: + oh_ccvp_eligible: false + +- name: October 2026 voucher limit for 2. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2] + oh_ccap_countable_income: 3_607 + households: + household: + members: [person1, person2] + state_code: + 2026: OH + output: + oh_ccvp_eligible: true + +- name: One dollar over the October 2026 voucher limit for 2. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2] + oh_ccap_countable_income: 3_608 + households: + household: + members: [person1, person2] + state_code: + 2026: OH + output: + oh_ccvp_eligible: false + +- name: October 2026 voucher limit for 4. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person4: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + oh_ccap_countable_income: 5_500 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: OH + output: + oh_ccvp_eligible: true + +- name: One dollar over the October 2026 voucher limit for 4. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person4: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + oh_ccap_countable_income: 5_501 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: OH + output: + oh_ccvp_eligible: false + +- name: October 2026 voucher limit for 8. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person4: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person5: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person6: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person7: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person8: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + oh_ccap_countable_income: 9_287 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: OH + output: + oh_ccvp_eligible: true + +- name: One dollar over the October 2026 voucher limit for 8. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person3: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person4: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person5: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person6: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person7: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + person8: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + oh_ccap_countable_income: 9_288 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: OH + output: + oh_ccvp_eligible: false + +- name: Enrolled Publicly Funded Child Care family keeps that program, not the voucher. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_400 + oh_ccap_enrolled: true + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + # Procedure Letter 36: families eligible for Publicly Funded Child Care are not eligible for the voucher. + oh_ccap_eligible: true + oh_ccvp_eligible: false + +- name: Special-needs family at 150% stays on Publicly Funded Child Care. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + is_disabled: true + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_332 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + # Procedure Letter 21: 150% prints $3,332 for three. + oh_ccap_income_eligible: true + oh_ccvp_eligible: false + +- name: Special-needs family one dollar over 150% qualifies for the voucher. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + is_disabled: true + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_333 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccap_income_eligible: false + oh_ccvp_eligible: true + +- name: Employed family in the transitional period stays on Publicly Funded Child Care at 150%. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + oh_ccap_owf_transitional: true + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_300 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccap_income_eligible: true + oh_ccvp_eligible: false + +- name: Caretaker without a qualifying activity gets no voucher. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 0 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccap_activity_eligible: false + oh_ccvp_eligible: false + +- name: Full-time student caretaker qualifies for the voucher. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 0 + is_full_time_student: true + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccap_activity_eligible: true + oh_ccvp_eligible: true + +- name: Assets at the federal limit pass. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + bank_account_assets: 1_000_000 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccvp_eligible: true + +- name: Assets over the federal limit fail. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + bank_account_assets: 1_000_001 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccvp_eligible: false + +- name: Homeless family goes to Publicly Funded Child Care whatever its income. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: OH + is_homeless: true + output: + oh_ccap_eligible: true + oh_ccvp_eligible: false + +- name: Protective care family goes to Publicly Funded Child Care whatever its income. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + receives_or_needs_protective_services: true + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: OH + output: + oh_ccap_eligible: true + oh_ccvp_eligible: false + +- name: October 2025 precedes the modeled voucher. + period: 2025-10 + input: + people: + person1: + age: + 2025: 30 + weekly_hours_worked_before_lsr: + 2025: 40 + person2: + age: + 2025: 2 + immigration_status: + 2025: CITIZEN + person3: + age: + 2025: 4 + immigration_status: + 2025: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: OH + output: + oh_ccvp_eligible: false + +- name: November 2025 starts the modeled voucher. + period: 2025-11 + input: + people: + person1: + age: + 2025: 30 + weekly_hours_worked_before_lsr: + 2025: 40 + person2: + age: + 2025: 2 + immigration_status: + 2025: CITIZEN + person3: + age: + 2025: 4 + immigration_status: + 2025: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: OH + output: + oh_ccvp_eligible: true + +- name: A 14-year-old qualifies the family for the voucher but not for Publicly Funded Child Care. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 14 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccap_eligible: false + oh_ccvp_eligible: true + +- name: A 15-year-old does not qualify the family. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 15 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_eligible: false + +- name: Below the intake limit a family with only a 14-year-old fails both programs. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 14 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2] + oh_ccap_countable_income: 2_500 + households: + household: + members: [person1, person2] + state_code: OH + output: + # H.B. 96, Section 423.190: the voucher serves families that fail the income conditions for Publicly Funded Child Care. + oh_ccap_income_eligible: true + oh_ccap_eligible: false + oh_ccvp_eligible: false + +- name: A family outside Ohio gets no voucher. + period: 2026-01 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + person2: + age: 2 + immigration_status: CITIZEN + person3: + age: 4 + immigration_status: CITIZEN + spm_units: + spm_unit: + members: [person1, person2, person3] + oh_ccap_countable_income: 3_500 + households: + household: + members: [person1, person2, person3] + state_code: PA + output: + oh_ccvp_eligible: false + +# Posted charts: a working parent with children of five at the voucher's printed top +# qualifies and a dollar more fails, at each printed family size in size order. + +- name: Procedure Letter 21's voucher limits hold at every family size in January 2026. + period: 2026-01 + input: + people: + p1_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p1_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p2_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p2_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p3_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p3_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p3_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p4_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p4_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p4_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p5_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p5_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p5_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p5_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p6_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p6_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p6_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p6_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p7_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p7_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p7_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p7_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p7_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p8_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p8_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p8_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p8_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p8_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p9_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p10_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p11_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_7: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p12_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_7: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p13_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_7: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_8: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p14_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_7: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_8: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + spm_units: + u1: + members: [p1_1, p1_2] + oh_ccap_countable_income: 3_525 + u2: + members: [p2_1, p2_2] + oh_ccap_countable_income: 3_526 + u3: + members: [p3_1, p3_2, p3_3] + oh_ccap_countable_income: 4_442 + u4: + members: [p4_1, p4_2, p4_3] + oh_ccap_countable_income: 4_443 + u5: + members: [p5_1, p5_2, p5_3, p5_4] + oh_ccap_countable_income: 5_359 + u6: + members: [p6_1, p6_2, p6_3, p6_4] + oh_ccap_countable_income: 5_360 + u7: + members: [p7_1, p7_2, p7_3, p7_4, p7_5] + oh_ccap_countable_income: 6_275 + u8: + members: [p8_1, p8_2, p8_3, p8_4, p8_5] + oh_ccap_countable_income: 6_276 + u9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5, p9_6] + oh_ccap_countable_income: 7_192 + u10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5, p10_6] + oh_ccap_countable_income: 7_193 + u11: + members: [p11_1, p11_2, p11_3, p11_4, p11_5, p11_6, p11_7] + oh_ccap_countable_income: 8_109 + u12: + members: [p12_1, p12_2, p12_3, p12_4, p12_5, p12_6, p12_7] + oh_ccap_countable_income: 8_110 + u13: + members: [p13_1, p13_2, p13_3, p13_4, p13_5, p13_6, p13_7, p13_8] + oh_ccap_countable_income: 9_025 + u14: + members: [p14_1, p14_2, p14_3, p14_4, p14_5, p14_6, p14_7, p14_8] + oh_ccap_countable_income: 9_026 + tax_units: + t1: + members: [p1_1, p1_2] + t2: + members: [p2_1, p2_2] + t3: + members: [p3_1, p3_2, p3_3] + t4: + members: [p4_1, p4_2, p4_3] + t5: + members: [p5_1, p5_2, p5_3, p5_4] + t6: + members: [p6_1, p6_2, p6_3, p6_4] + t7: + members: [p7_1, p7_2, p7_3, p7_4, p7_5] + t8: + members: [p8_1, p8_2, p8_3, p8_4, p8_5] + t9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5, p9_6] + t10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5, p10_6] + t11: + members: [p11_1, p11_2, p11_3, p11_4, p11_5, p11_6, p11_7] + t12: + members: [p12_1, p12_2, p12_3, p12_4, p12_5, p12_6, p12_7] + t13: + members: [p13_1, p13_2, p13_3, p13_4, p13_5, p13_6, p13_7, p13_8] + t14: + members: [p14_1, p14_2, p14_3, p14_4, p14_5, p14_6, p14_7, p14_8] + families: + f1: + members: [p1_1, p1_2] + f2: + members: [p2_1, p2_2] + f3: + members: [p3_1, p3_2, p3_3] + f4: + members: [p4_1, p4_2, p4_3] + f5: + members: [p5_1, p5_2, p5_3, p5_4] + f6: + members: [p6_1, p6_2, p6_3, p6_4] + f7: + members: [p7_1, p7_2, p7_3, p7_4, p7_5] + f8: + members: [p8_1, p8_2, p8_3, p8_4, p8_5] + f9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5, p9_6] + f10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5, p10_6] + f11: + members: [p11_1, p11_2, p11_3, p11_4, p11_5, p11_6, p11_7] + f12: + members: [p12_1, p12_2, p12_3, p12_4, p12_5, p12_6, p12_7] + f13: + members: [p13_1, p13_2, p13_3, p13_4, p13_5, p13_6, p13_7, p13_8] + f14: + members: [p14_1, p14_2, p14_3, p14_4, p14_5, p14_6, p14_7, p14_8] + marital_units: + m1_1: + members: [p1_1] + m1_2: + members: [p1_2] + m2_1: + members: [p2_1] + m2_2: + members: [p2_2] + m3_1: + members: [p3_1] + m3_2: + members: [p3_2] + m3_3: + members: [p3_3] + m4_1: + members: [p4_1] + m4_2: + members: [p4_2] + m4_3: + members: [p4_3] + m5_1: + members: [p5_1] + m5_2: + members: [p5_2] + m5_3: + members: [p5_3] + m5_4: + members: [p5_4] + m6_1: + members: [p6_1] + m6_2: + members: [p6_2] + m6_3: + members: [p6_3] + m6_4: + members: [p6_4] + m7_1: + members: [p7_1] + m7_2: + members: [p7_2] + m7_3: + members: [p7_3] + m7_4: + members: [p7_4] + m7_5: + members: [p7_5] + m8_1: + members: [p8_1] + m8_2: + members: [p8_2] + m8_3: + members: [p8_3] + m8_4: + members: [p8_4] + m8_5: + members: [p8_5] + m9_1: + members: [p9_1] + m9_2: + members: [p9_2] + m9_3: + members: [p9_3] + m9_4: + members: [p9_4] + m9_5: + members: [p9_5] + m9_6: + members: [p9_6] + m10_1: + members: [p10_1] + m10_2: + members: [p10_2] + m10_3: + members: [p10_3] + m10_4: + members: [p10_4] + m10_5: + members: [p10_5] + m10_6: + members: [p10_6] + m11_1: + members: [p11_1] + m11_2: + members: [p11_2] + m11_3: + members: [p11_3] + m11_4: + members: [p11_4] + m11_5: + members: [p11_5] + m11_6: + members: [p11_6] + m11_7: + members: [p11_7] + m12_1: + members: [p12_1] + m12_2: + members: [p12_2] + m12_3: + members: [p12_3] + m12_4: + members: [p12_4] + m12_5: + members: [p12_5] + m12_6: + members: [p12_6] + m12_7: + members: [p12_7] + m13_1: + members: [p13_1] + m13_2: + members: [p13_2] + m13_3: + members: [p13_3] + m13_4: + members: [p13_4] + m13_5: + members: [p13_5] + m13_6: + members: [p13_6] + m13_7: + members: [p13_7] + m13_8: + members: [p13_8] + m14_1: + members: [p14_1] + m14_2: + members: [p14_2] + m14_3: + members: [p14_3] + m14_4: + members: [p14_4] + m14_5: + members: [p14_5] + m14_6: + members: [p14_6] + m14_7: + members: [p14_7] + m14_8: + members: [p14_8] + households: + h1: + members: [p1_1, p1_2] + state_code: + 2026: OH + h2: + members: [p2_1, p2_2] + state_code: + 2026: OH + h3: + members: [p3_1, p3_2, p3_3] + state_code: + 2026: OH + h4: + members: [p4_1, p4_2, p4_3] + state_code: + 2026: OH + h5: + members: [p5_1, p5_2, p5_3, p5_4] + state_code: + 2026: OH + h6: + members: [p6_1, p6_2, p6_3, p6_4] + state_code: + 2026: OH + h7: + members: [p7_1, p7_2, p7_3, p7_4, p7_5] + state_code: + 2026: OH + h8: + members: [p8_1, p8_2, p8_3, p8_4, p8_5] + state_code: + 2026: OH + h9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5, p9_6] + state_code: + 2026: OH + h10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5, p10_6] + state_code: + 2026: OH + h11: + members: [p11_1, p11_2, p11_3, p11_4, p11_5, p11_6, p11_7] + state_code: + 2026: OH + h12: + members: [p12_1, p12_2, p12_3, p12_4, p12_5, p12_6, p12_7] + state_code: + 2026: OH + h13: + members: [p13_1, p13_2, p13_3, p13_4, p13_5, p13_6, p13_7, p13_8] + state_code: + 2026: OH + h14: + members: [p14_1, p14_2, p14_3, p14_4, p14_5, p14_6, p14_7, p14_8] + state_code: + 2026: OH + output: + # 200% of the 2025 guideline, rounded up, sizes 2 to 8. + oh_ccvp_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: Procedure Letter 45's voucher limits hold at every family size in October 2026. + period: 2026-10 + input: + people: + p1_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p1_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p2_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p2_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p3_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p3_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p3_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p4_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p4_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p4_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p5_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p5_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p5_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p5_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p6_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p6_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p6_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p6_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p7_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p7_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p7_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p7_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p7_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p8_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p8_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p8_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p8_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p8_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p9_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p9_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p10_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p10_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p11_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p11_7: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p12_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p12_7: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p13_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_7: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p13_8: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_1: + age: + 2026: 30 + weekly_hours_worked_before_lsr: + 2026: 40 + immigration_status: + 2026: CITIZEN + p14_2: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_3: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_4: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_5: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_6: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_7: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + p14_8: + age: + 2026: 5 + immigration_status: + 2026: CITIZEN + spm_units: + u1: + members: [p1_1, p1_2] + oh_ccap_countable_income: 3_607 + u2: + members: [p2_1, p2_2] + oh_ccap_countable_income: 3_608 + u3: + members: [p3_1, p3_2, p3_3] + oh_ccap_countable_income: 4_554 + u4: + members: [p4_1, p4_2, p4_3] + oh_ccap_countable_income: 4_555 + u5: + members: [p5_1, p5_2, p5_3, p5_4] + oh_ccap_countable_income: 5_500 + u6: + members: [p6_1, p6_2, p6_3, p6_4] + oh_ccap_countable_income: 5_501 + u7: + members: [p7_1, p7_2, p7_3, p7_4, p7_5] + oh_ccap_countable_income: 6_447 + u8: + members: [p8_1, p8_2, p8_3, p8_4, p8_5] + oh_ccap_countable_income: 6_448 + u9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5, p9_6] + oh_ccap_countable_income: 7_394 + u10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5, p10_6] + oh_ccap_countable_income: 7_395 + u11: + members: [p11_1, p11_2, p11_3, p11_4, p11_5, p11_6, p11_7] + oh_ccap_countable_income: 8_340 + u12: + members: [p12_1, p12_2, p12_3, p12_4, p12_5, p12_6, p12_7] + oh_ccap_countable_income: 8_341 + u13: + members: [p13_1, p13_2, p13_3, p13_4, p13_5, p13_6, p13_7, p13_8] + oh_ccap_countable_income: 9_287 + u14: + members: [p14_1, p14_2, p14_3, p14_4, p14_5, p14_6, p14_7, p14_8] + oh_ccap_countable_income: 9_288 + tax_units: + t1: + members: [p1_1, p1_2] + t2: + members: [p2_1, p2_2] + t3: + members: [p3_1, p3_2, p3_3] + t4: + members: [p4_1, p4_2, p4_3] + t5: + members: [p5_1, p5_2, p5_3, p5_4] + t6: + members: [p6_1, p6_2, p6_3, p6_4] + t7: + members: [p7_1, p7_2, p7_3, p7_4, p7_5] + t8: + members: [p8_1, p8_2, p8_3, p8_4, p8_5] + t9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5, p9_6] + t10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5, p10_6] + t11: + members: [p11_1, p11_2, p11_3, p11_4, p11_5, p11_6, p11_7] + t12: + members: [p12_1, p12_2, p12_3, p12_4, p12_5, p12_6, p12_7] + t13: + members: [p13_1, p13_2, p13_3, p13_4, p13_5, p13_6, p13_7, p13_8] + t14: + members: [p14_1, p14_2, p14_3, p14_4, p14_5, p14_6, p14_7, p14_8] + families: + f1: + members: [p1_1, p1_2] + f2: + members: [p2_1, p2_2] + f3: + members: [p3_1, p3_2, p3_3] + f4: + members: [p4_1, p4_2, p4_3] + f5: + members: [p5_1, p5_2, p5_3, p5_4] + f6: + members: [p6_1, p6_2, p6_3, p6_4] + f7: + members: [p7_1, p7_2, p7_3, p7_4, p7_5] + f8: + members: [p8_1, p8_2, p8_3, p8_4, p8_5] + f9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5, p9_6] + f10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5, p10_6] + f11: + members: [p11_1, p11_2, p11_3, p11_4, p11_5, p11_6, p11_7] + f12: + members: [p12_1, p12_2, p12_3, p12_4, p12_5, p12_6, p12_7] + f13: + members: [p13_1, p13_2, p13_3, p13_4, p13_5, p13_6, p13_7, p13_8] + f14: + members: [p14_1, p14_2, p14_3, p14_4, p14_5, p14_6, p14_7, p14_8] + marital_units: + m1_1: + members: [p1_1] + m1_2: + members: [p1_2] + m2_1: + members: [p2_1] + m2_2: + members: [p2_2] + m3_1: + members: [p3_1] + m3_2: + members: [p3_2] + m3_3: + members: [p3_3] + m4_1: + members: [p4_1] + m4_2: + members: [p4_2] + m4_3: + members: [p4_3] + m5_1: + members: [p5_1] + m5_2: + members: [p5_2] + m5_3: + members: [p5_3] + m5_4: + members: [p5_4] + m6_1: + members: [p6_1] + m6_2: + members: [p6_2] + m6_3: + members: [p6_3] + m6_4: + members: [p6_4] + m7_1: + members: [p7_1] + m7_2: + members: [p7_2] + m7_3: + members: [p7_3] + m7_4: + members: [p7_4] + m7_5: + members: [p7_5] + m8_1: + members: [p8_1] + m8_2: + members: [p8_2] + m8_3: + members: [p8_3] + m8_4: + members: [p8_4] + m8_5: + members: [p8_5] + m9_1: + members: [p9_1] + m9_2: + members: [p9_2] + m9_3: + members: [p9_3] + m9_4: + members: [p9_4] + m9_5: + members: [p9_5] + m9_6: + members: [p9_6] + m10_1: + members: [p10_1] + m10_2: + members: [p10_2] + m10_3: + members: [p10_3] + m10_4: + members: [p10_4] + m10_5: + members: [p10_5] + m10_6: + members: [p10_6] + m11_1: + members: [p11_1] + m11_2: + members: [p11_2] + m11_3: + members: [p11_3] + m11_4: + members: [p11_4] + m11_5: + members: [p11_5] + m11_6: + members: [p11_6] + m11_7: + members: [p11_7] + m12_1: + members: [p12_1] + m12_2: + members: [p12_2] + m12_3: + members: [p12_3] + m12_4: + members: [p12_4] + m12_5: + members: [p12_5] + m12_6: + members: [p12_6] + m12_7: + members: [p12_7] + m13_1: + members: [p13_1] + m13_2: + members: [p13_2] + m13_3: + members: [p13_3] + m13_4: + members: [p13_4] + m13_5: + members: [p13_5] + m13_6: + members: [p13_6] + m13_7: + members: [p13_7] + m13_8: + members: [p13_8] + m14_1: + members: [p14_1] + m14_2: + members: [p14_2] + m14_3: + members: [p14_3] + m14_4: + members: [p14_4] + m14_5: + members: [p14_5] + m14_6: + members: [p14_6] + m14_7: + members: [p14_7] + m14_8: + members: [p14_8] + households: + h1: + members: [p1_1, p1_2] + state_code: + 2026: OH + h2: + members: [p2_1, p2_2] + state_code: + 2026: OH + h3: + members: [p3_1, p3_2, p3_3] + state_code: + 2026: OH + h4: + members: [p4_1, p4_2, p4_3] + state_code: + 2026: OH + h5: + members: [p5_1, p5_2, p5_3, p5_4] + state_code: + 2026: OH + h6: + members: [p6_1, p6_2, p6_3, p6_4] + state_code: + 2026: OH + h7: + members: [p7_1, p7_2, p7_3, p7_4, p7_5] + state_code: + 2026: OH + h8: + members: [p8_1, p8_2, p8_3, p8_4, p8_5] + state_code: + 2026: OH + h9: + members: [p9_1, p9_2, p9_3, p9_4, p9_5, p9_6] + state_code: + 2026: OH + h10: + members: [p10_1, p10_2, p10_3, p10_4, p10_5, p10_6] + state_code: + 2026: OH + h11: + members: [p11_1, p11_2, p11_3, p11_4, p11_5, p11_6, p11_7] + state_code: + 2026: OH + h12: + members: [p12_1, p12_2, p12_3, p12_4, p12_5, p12_6, p12_7] + state_code: + 2026: OH + h13: + members: [p13_1, p13_2, p13_3, p13_4, p13_5, p13_6, p13_7, p13_8] + state_code: + 2026: OH + h14: + members: [p14_1, p14_2, p14_3, p14_4, p14_5, p14_6, p14_7, p14_8] + state_code: + 2026: OH + output: + # 200% of the 2026 guideline, rounded up, sizes 2 to 8. + oh_ccvp_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible_child.yaml new file mode 100644 index 00000000000..9f11f92cd5a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible_child.yaml @@ -0,0 +1,101 @@ +# Procedure Letter 36, page 3: school age runs to under 15, or under 18 with special needs. + +- name: Infant qualifies. + period: 2026-01 + input: + people: + person1: + age: 0 + immigration_status: CITIZEN + households: + household: + members: [person1] + state_code: OH + output: + oh_ccvp_eligible_child: true + +- name: A 13-year-old qualifies, past the Publicly Funded Child Care limit. + period: 2026-01 + input: + people: + person1: + age: 13 + immigration_status: CITIZEN + households: + household: + members: [person1] + state_code: OH + output: + oh_ccvp_eligible_child: true + +- name: Just under 15 qualifies. + period: 2026-01 + input: + people: + person1: + age: 14.99 + immigration_status: CITIZEN + households: + household: + members: [person1] + state_code: OH + output: + oh_ccvp_eligible_child: true + +- name: A 15-year-old does not qualify. + period: 2026-01 + input: + people: + person1: + age: 15 + immigration_status: CITIZEN + households: + household: + members: [person1] + state_code: OH + output: + oh_ccvp_eligible_child: false + +- name: Special-needs child just under 18 qualifies. + period: 2026-01 + input: + people: + person1: + age: 17.99 + immigration_status: CITIZEN + is_disabled: true + households: + household: + members: [person1] + state_code: OH + output: + oh_ccvp_eligible_child: true + +- name: Special-needs child at 18 does not qualify. + period: 2026-01 + input: + people: + person1: + age: 18 + immigration_status: CITIZEN + is_disabled: true + households: + household: + members: [person1] + state_code: OH + output: + oh_ccvp_eligible_child: false + +- name: An undocumented child does not qualify. + period: 2026-01 + input: + people: + person1: + age: 5 + immigration_status: UNDOCUMENTED + households: + household: + members: [person1] + state_code: OH + output: + oh_ccvp_eligible_child: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_rate.yaml new file mode 100644 index 00000000000..e1ebb821702 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_rate.yaml @@ -0,0 +1,777 @@ +# Procedure Letter 36, pages 2-3: monthly voucher payment by provider type and age from November 1, 2025. +# H.B. 96, Section 423.190: Publicly Funded Child Care payment rates by November 1, 2026, without the +# Step Up to Quality enhancement. OAC 5180:6-1-10(B)(1) caps the base at the provider's customary +# charge, and its (D), (F) and (G) add-ons for accreditation, non-traditional hours and special needs +# apply. + +- name: January 2026 center rate for an infant. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 0.5 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 900] + +- name: January 2026 home rate for an infant. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 0.5 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + oh_ccap_provider_type: HOME + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 600] + +- name: January 2026 center rate for a toddler. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 2 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 800] + +- name: January 2026 home rate for a toddler. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 2 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + oh_ccap_provider_type: HOME + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 550] + +- name: January 2026 center rate for a preschooler. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 750] + +- name: January 2026 home rate for a preschooler. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + oh_ccap_provider_type: HOME + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 500] + +- name: January 2026 center rate for a school-age child. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 7 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 375] + +- name: January 2026 home rate for a school-age child. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 7 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + oh_ccap_provider_type: HOME + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 300] + +- name: A 14-year-old takes the school-age rate. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 14 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 375] + +- name: A 16-year-old with special needs takes the school-age rate. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 16 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + is_disabled: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 375] + +- name: A 15-year-old without special needs has no rate. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 15 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 0] + +- name: The chart has no summer row, so July keeps the school-age center rate. + period: 2026-07 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 7 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + output: + oh_ccvp_rate: [0, 375] + +- name: The chart has no summer row, so July keeps the school-age home rate. + period: 2026-07 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 7 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + oh_ccap_provider_type: HOME + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + output: + oh_ccvp_rate: [0, 300] + +- name: The flat chart still applies in October 2026. + period: 2026-10 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + output: + oh_ccvp_rate: [0, 800] + +- name: November 2026 pays the Publicly Funded Child Care rate for a toddler at a center. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # OAC 5180:6-1-10 Appendix A, category 1 center toddler full-time: 180 a week x 52 / 12 = 780. + oh_ccvp_rate: [0, 780] + +- name: November 2026 pays the Publicly Funded Child Care rate for a toddler at a home. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + oh_ccap_provider_type: HOME + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # OAC 5180:6-1-10 Appendix A, category 1 home toddler full-time: 162.71 a week x 52 / 12 = 705.08. + oh_ccvp_rate: [0, 705.08] + +- name: November 2026 pays a 14-year-old the school-age rate. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 14 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # Category 1 center school-age full-time: 107.71 a week x 52 / 12 = 466.74. + oh_ccvp_rate: [0, 466.74] + +- name: November 2026 pays nothing for a child without care hours. + period: 2026-11 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 0 + pre_subsidy_childcare_expenses: + 2026: 24_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + oh_ccvp_rate: [0, 0] + +- name: A six-year-old outside school takes the school-age center rate. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 6 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + is_in_k12_school: false + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + # Procedure Letter 36, page 3: the school-age row covers children eligible to enroll in kindergarten. + oh_ccvp_rate: [0, 375] + +- name: A six-year-old outside school takes the school-age home rate. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 6 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + is_in_k12_school: false + oh_ccap_provider_type: HOME + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 300] + +- name: A four-year-old already in kindergarten takes the school-age center rate. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + is_in_k12_school: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 375] + +- name: A four-year-old outside school keeps the preschool center rate. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + immigration_status: CITIZEN + childcare_hours_per_week: 40 + is_in_k12_school: false + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_ccvp_rate: [0, 750] + +- name: November 2026 adds no Step Up to Quality bonus at a gold-rated center. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + oh_ccap_quality_tier: GOLD + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # Publicly Funded Child Care would pay 780 x 1.25 = 975; H.B. 96 leaves the 25% out. + oh_ccvp_rate: [0, 780] + +- name: November 2026 adds the accreditation payment. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + oh_ccap_is_accredited: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # 5180:6-1-10(D)(1): 780 x 1.10 = 858. + oh_ccvp_rate: [0, 858] + +- name: November 2026 adds the accreditation payment, not the larger gold bonus, at an accredited gold-rated center. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + oh_ccap_quality_tier: GOLD + oh_ccap_is_accredited: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # Without (C), (D)(2)'s higher of the two leaves the accreditation payment: 780 x 1.10 = 858. + oh_ccvp_rate: [0, 858] + +- name: November 2026 adds the special needs payment. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + is_disabled: + 2026: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # 5180:6-1-10(G)(1): 780 + 5% x 780 = 819. + oh_ccvp_rate: [0, 819] + +- name: November 2026 adds the non-traditional hours payment. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + oh_ccap_non_traditional_hours: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # 5180:6-1-10(F)(1): 780 + 5% x 780 = 819. + oh_ccvp_rate: [0, 819] + +- name: November 2026 doubles the rate for approved special accommodations. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + is_disabled: + 2026: true + oh_ccap_has_special_accommodations: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # 5180:6-1-10(G)(2): 2 x 780 = 1,560. + oh_ccvp_rate: [0, 1560] + +- name: November 2026 takes a customary charge below the county rate as the base. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 6_000 + oh_ccap_is_accredited: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # 5180:6-1-10(B)(1): min(780, 6,000 / 12) = 500; (D)(1) adds 10%: 550. + oh_ccvp_rate: [0, 550] + +- name: October 2026 adds nothing for special needs under the flat chart. + period: 2026-10 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 30 + person2: + age: + 2026: 2 + immigration_status: + 2026: CITIZEN + childcare_hours_per_week: + 2026: 40 + pre_subsidy_childcare_expenses: + 2026: 24_000 + is_disabled: + 2026: true + oh_ccap_is_accredited: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: + 2026: OH + county_str: + 2026: BROWN_COUNTY_OH + output: + # Procedure Letter 36 pays a center toddler 800 a month with no add-ons. + oh_ccvp_rate: [0, 800] diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_child_care_subsidies.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_child_care_subsidies.yaml new file mode 100644 index 00000000000..0bcb5252815 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/ccvp/oh_child_care_subsidies.yaml @@ -0,0 +1,61 @@ +- name: Annual subsidies add voucher payments across 2026. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + employment_income: 42_000 + person2: + age: 2 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + person3: + age: 4 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: OH + county_str: BROWN_COUNTY_OH + output: + # 10 months x 1,550 + 2 months x 1,473.33. + oh_child_care_subsidies: 18_446.67 + +- name: Annual subsidies count only the modeled months of 2025. + period: 2025 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 30 + weekly_hours_worked_before_lsr: 40 + employment_income: 42_000 + person2: + age: 2 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + person3: + age: 4 + immigration_status: CITIZEN + pre_subsidy_childcare_expenses: 24_000 + childcare_hours_per_week: 40 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: OH + county_str: BROWN_COUNTY_OH + output: + # November and December x 1,550. + oh_child_care_subsidies: 3_100 diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/oh_ccap_base_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/oh_ccap_base_rate.yaml index 5388cf8c588..d093bf1c1a8 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/oh_ccap_base_rate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/oh_ccap_base_rate.yaml @@ -1,10 +1,10 @@ -# Tests for oh_ccap_base_rate (Person, MONTH, defined_for oh_ccap_eligible_child). +# Tests for oh_ccap_base_rate (Person, MONTH, defined_for StateCode.OH). # 5180:6-1-10 Appendix A: maximum reimbursement ceilings keyed by county rate # category, age group, provider type, and time category. Hourly cells are # per-hour amounts applied to the child's authorized monthly hours; part-time # and full-time cells are weekly amounts converted to monthly (x 52 / 12). -# Rates start 2025-11-01, so cases use period 2026. The parent (person1) is not -# an eligible child, so its base rate is 0. +# Rates start 2025-11-01, so cases use period 2026. The parent (person1) has no +# care hours, so its base rate is 0. - name: Case 1, category 1 center infant full-time. period: 2026-01 absolute_error_margin: 0.01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/oh_ccap_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/oh_ccap_income_eligible.yaml index 6de9ab82f9d..c9805a46fe7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/oh_ccap_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/dcy/ccap/oh_ccap_income_eligible.yaml @@ -475,3 +475,391 @@ state_code: OH output: oh_ccap_income_eligible: true + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. + +- name: Procedure Letter 21's initial limits hold at every family size in January 2026. + period: 2026-01 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 2 + oh_ccap_countable_income: 2_556 + oh_ccap_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 2 + oh_ccap_countable_income: 2_557 + oh_ccap_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 3 + oh_ccap_countable_income: 3_221 + oh_ccap_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 3 + oh_ccap_countable_income: 3_222 + oh_ccap_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 4 + oh_ccap_countable_income: 3_885 + oh_ccap_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 4 + oh_ccap_countable_income: 3_886 + oh_ccap_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 5 + oh_ccap_countable_income: 4_550 + oh_ccap_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 5 + oh_ccap_countable_income: 4_551 + oh_ccap_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 6 + oh_ccap_countable_income: 5_214 + oh_ccap_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 6 + oh_ccap_countable_income: 5_215 + oh_ccap_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 7 + oh_ccap_countable_income: 5_879 + oh_ccap_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 7 + oh_ccap_countable_income: 5_880 + oh_ccap_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 8 + oh_ccap_countable_income: 6_544 + oh_ccap_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 8 + oh_ccap_countable_income: 6_545 + oh_ccap_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: OH + h2: + members: [p2] + state_code: + 2026: OH + h3: + members: [p3] + state_code: + 2026: OH + h4: + members: [p4] + state_code: + 2026: OH + h5: + members: [p5] + state_code: + 2026: OH + h6: + members: [p6] + state_code: + 2026: OH + h7: + members: [p7] + state_code: + 2026: OH + h8: + members: [p8] + state_code: + 2026: OH + h9: + members: [p9] + state_code: + 2026: OH + h10: + members: [p10] + state_code: + 2026: OH + h11: + members: [p11] + state_code: + 2026: OH + h12: + members: [p12] + state_code: + 2026: OH + h13: + members: [p13] + state_code: + 2026: OH + h14: + members: [p14] + state_code: + 2026: OH + output: + # 145% of the 2025 guideline, sizes 2 to 8. + oh_ccap_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: Procedure Letter 45's initial limits hold at every family size in October 2026. + period: 2026-10 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 2 + oh_ccap_countable_income: 2_615 + oh_ccap_enrolled: false + u2: + members: [p2] + spm_unit_size: + 2026: 2 + oh_ccap_countable_income: 2_616 + oh_ccap_enrolled: false + u3: + members: [p3] + spm_unit_size: + 2026: 3 + oh_ccap_countable_income: 3_302 + oh_ccap_enrolled: false + u4: + members: [p4] + spm_unit_size: + 2026: 3 + oh_ccap_countable_income: 3_303 + oh_ccap_enrolled: false + u5: + members: [p5] + spm_unit_size: + 2026: 4 + oh_ccap_countable_income: 3_988 + oh_ccap_enrolled: false + u6: + members: [p6] + spm_unit_size: + 2026: 4 + oh_ccap_countable_income: 3_989 + oh_ccap_enrolled: false + u7: + members: [p7] + spm_unit_size: + 2026: 5 + oh_ccap_countable_income: 4_674 + oh_ccap_enrolled: false + u8: + members: [p8] + spm_unit_size: + 2026: 5 + oh_ccap_countable_income: 4_675 + oh_ccap_enrolled: false + u9: + members: [p9] + spm_unit_size: + 2026: 6 + oh_ccap_countable_income: 5_361 + oh_ccap_enrolled: false + u10: + members: [p10] + spm_unit_size: + 2026: 6 + oh_ccap_countable_income: 5_362 + oh_ccap_enrolled: false + u11: + members: [p11] + spm_unit_size: + 2026: 7 + oh_ccap_countable_income: 6_047 + oh_ccap_enrolled: false + u12: + members: [p12] + spm_unit_size: + 2026: 7 + oh_ccap_countable_income: 6_048 + oh_ccap_enrolled: false + u13: + members: [p13] + spm_unit_size: + 2026: 8 + oh_ccap_countable_income: 6_733 + oh_ccap_enrolled: false + u14: + members: [p14] + spm_unit_size: + 2026: 8 + oh_ccap_countable_income: 6_734 + oh_ccap_enrolled: false + households: + h1: + members: [p1] + state_code: + 2026: OH + h2: + members: [p2] + state_code: + 2026: OH + h3: + members: [p3] + state_code: + 2026: OH + h4: + members: [p4] + state_code: + 2026: OH + h5: + members: [p5] + state_code: + 2026: OH + h6: + members: [p6] + state_code: + 2026: OH + h7: + members: [p7] + state_code: + 2026: OH + h8: + members: [p8] + state_code: + 2026: OH + h9: + members: [p9] + state_code: + 2026: OH + h10: + members: [p10] + state_code: + 2026: OH + h11: + members: [p11] + state_code: + 2026: OH + h12: + members: [p12] + state_code: + 2026: OH + h13: + members: [p13] + state_code: + 2026: OH + h14: + members: [p14] + state_code: + 2026: OH + output: + # 145% of the 2026 guideline, sizes 2 to 8. + oh_ccap_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/edge_cases.yaml index cc5ed1c6c19..ad5278b0e2f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/edge_cases.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/edge_cases.yaml @@ -1,10 +1,11 @@ # WV CCAP Edge Case Tests # Income test: 185% FPL initial intake cap (Manual §3.2.1, Appendix A). -# 2025 FPG (Contiguous US): first_person = 15_650, additional = 5_500. -# Family of 2 FPG = 21_150/yr = 1_762.50/mo; family of 3 = 26_650/yr. -# 185% FPL family of 2 = 21_150 * 1.85 = 39_127.50/yr -# 185% FPL family of 3 = 26_650 * 1.85 = 49_302.50/yr -# 185% FPL family of 11 = 70_650 * 1.85 = 130_702.50/yr +# Appendix A uses the 2024 FPG (Contiguous US): first_person = 15_060, additional = 5_380. +# Family of 2 FPG = 20_440/yr = 1_703.33/mo; family of 3 = 25_820/yr. +# Intake cap (185% FPL, nearest dollar a month): +# family of 2 = 3_151/mo = 37_812/yr +# family of 3 = 3_981/mo = 47_772/yr +# family of 11 = 68_860 * 1.85 / 12 -> 10_616/mo = 127_392/yr # ============================================================ # Income threshold boundaries (185% FPL) @@ -39,7 +40,7 @@ members: [person1, person2] state_code: WV output: - # $24,000/yr is well below 185% FPL family of 2 ($39,127.50/yr) → eligible. + # $24,000/yr is well below the family of 2 cap ($37,812/yr) → eligible. wv_ccap_income_eligible: true - name: Case 2, income just below 185% FPL eligible. @@ -49,8 +50,8 @@ person1: age: 30 weekly_hours_worked_before_lsr: 40 - # 185% FPL family of 2 = $39,127.50/yr - employment_income: 39_000 + # Family of 2 cap = $37,812/yr + employment_income: 37_800 immigration_status: CITIZEN person2: age: 3 @@ -82,8 +83,8 @@ person1: age: 30 weekly_hours_worked_before_lsr: 40 - # Just above 185% FPL family of 2 ($39,127.50/yr) - employment_income: 39_200 + # Just above the family of 2 cap ($37,812/yr) + employment_income: 37_900 immigration_status: CITIZEN person2: age: 3 @@ -119,8 +120,8 @@ person1: age: 30 weekly_hours_worked_before_lsr: 40 - # 185% FPL family of 3 = $49,302.50/yr - employment_income: 48_000 + # Family of 3 cap = $47,772/yr + employment_income: 47_700 immigration_status: CITIZEN person2: age: 3 @@ -178,8 +179,8 @@ person1: age: 30 weekly_hours_worked_before_lsr: 40 - # Just above 185% FPL family of 3 ($49,302.50/yr) - employment_income: 50_000 + # Just above the family of 3 cap ($47,772/yr) + employment_income: 47_800 immigration_status: CITIZEN person2: age: 3 @@ -214,8 +215,8 @@ person1: age: 30 weekly_hours_worked_before_lsr: 40 - # 185% FPL family of 11 = $130,702.50/yr - employment_income: 131_000 + # Family of 11 cap = $127,392/yr + employment_income: 127_500 immigration_status: CITIZEN person2: age: 3 @@ -278,7 +279,7 @@ person1: age: 30 weekly_hours_worked_before_lsr: 40 - # Below 185% FPL family of 11 ($130,702.50/yr) + # Below the family of 11 cap ($127,392/yr) employment_income: 100_000 immigration_status: CITIZEN person2: @@ -560,8 +561,8 @@ person1: age: 30 weekly_hours_worked_before_lsr: 40 - # 40% FPL family of 2 = 21_150 * 0.4 = 8_460/yr - employment_income: 8_460 + # 40% FPL family of 2 = 20_440 * 0.4 = 8_176/yr + employment_income: 8_176 immigration_status: CITIZEN person2: age: 3 @@ -583,8 +584,8 @@ members: [person1, person2] state_code: WV output: - # monthly income = 8_460 / 12 = 705 - # FPL ratio = 705 / 1_762.50 = 0.4 + # monthly income = 8_176 / 12 = 681.33 + # FPL ratio = 681.33 / 1_703.33 = 0.4 # Threshold for non-zero copay is 0.4001, so 0.4 -> 0% bracket wv_ccap_copay: 0 @@ -597,8 +598,8 @@ age: 30 weekly_hours_worked_before_lsr: 40 # Just above 40% FPL: need FPL ratio > 0.4001 - # 21_150 * 0.4001 = 8_462.12/yr; use 8_475 -> ratio ~0.4008 - employment_income: 8_475 + # 20_440 * 0.4001 = 8_178.04/yr; use 8_190 -> ratio ~0.4007 + employment_income: 8_190 immigration_status: CITIZEN person2: age: 3 @@ -620,10 +621,10 @@ members: [person1, person2] state_code: WV output: - # Monthly income = 8_475 / 12 = $706.25. FPL ratio = 0.4007 > 0.4001 → bracket + # Monthly income = 8_190 / 12 = $682.50. FPL ratio = 0.4007 > 0.4001 → bracket # "above 40% up to 50%" → Appendix A 2-person "50%" row daily fee = $2.00/child. # copay = $2.00 × 22 × 1 = $44. - # 7% cap = $706.25 × 0.07 = $49.44; cap does not bind. + # 7% cap = $682.50 × 0.07 = $47.78; cap does not bind. wv_ccap_copay: 44 # ============================================================ @@ -638,8 +639,8 @@ person1: age: 30 weekly_hours_worked_before_lsr: 40 - # ~170% FPL family of 2: 21_150 * 1.7 = 35_955/yr. - employment_income: 35_955 + # ~170% FPL family of 2: 20_440 * 1.7 = 34_748/yr. + employment_income: 34_748 immigration_status: CITIZEN person2: age: 3 @@ -661,10 +662,10 @@ members: [person1, person2] state_code: WV output: - # Monthly income = $2_996.25. FPL ratio = 1.7000 → bracket "above 160% up to 170%" + # Monthly income = $2_895.67. FPL ratio = 1.7000 → bracket "above 160% up to 170%" # → Appendix A 2-person "170%" row daily fee = $8.25/child. # uncapped copay = $8.25 × 22 × 1 = $181.50. - # 7% cap = $2_996.25 × 0.07 = $209.74; cap does not bind. + # 7% cap = $2_895.67 × 0.07 = $202.70; cap does not bind. wv_ccap_copay: 181.5 - name: Case 19, large family with three children triggers 7 percent cap. @@ -856,7 +857,7 @@ state_code: WV output: # Foster child -> copay = $0 regardless of income - # FPL ratio would be ~1.42 -> normally 3.5% bracket + # FPL ratio would be ~1.47 -> normally 3.5% bracket # But foster child exemption overrides wv_ccap_copay: 0 @@ -1509,7 +1510,7 @@ # daily benefit = min(45, 13.64) = 13.64 wv_ccap_daily_benefit: [0, 13.64] - # 2-person family, FPL ratio = 2_000 / 1_762.50 = 1.1348. + # 2-person family, FPL ratio = 2_000 / 1_703.33 = 1.1742. # Appendix A 2-person "120%" row daily fee = $5.75/child; 22 days. # copay = $5.75 × 22 = $126.50. # 22 days > 20 → per-day billing; per_child = min($45 × 22, $300) = $300. diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/integration.yaml index e2f4a607820..ca9ffdf6021 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/integration.yaml @@ -1,8 +1,8 @@ # WV CCAP Integration Tests -# 2025 FPG (Contiguous US): -# first_person = 15_650, additional = 5_500 -# Family of 2: 21_150 -# Family of 3: 26_650 +# Appendix A uses the 2024 FPG (Contiguous US): +# first_person = 15_060, additional = 5_380 +# Family of 2: 20_440 +# Family of 3: 25_820 - name: Case 1, basic eligible family with center care. period: 2025-01 @@ -37,7 +37,7 @@ # === Eligibility === wv_ccap_eligible_child: [false, true] - # 185% FPL family of 2 = $39,127.50/yr; $24,000/yr → eligible. + # The family of 2 cap = $37,812/yr; $24,000/yr → eligible. wv_ccap_income_eligible: true is_ccdf_asset_eligible: true wv_ccap_eligible: true @@ -51,7 +51,7 @@ wv_ccap_daily_rate: [0, 37] # === Copay === - # 2-person family, FPL ratio = 2_000 / 1_762.50 = 1.1348. + # 2-person family, FPL ratio = 2_000 / 1_703.33 = 1.1742. # Appendix A 2-person "120%" row daily fee = $5.75/child. # 1 eligible child × 22 monthly days. # copay = $5.75 × 22 × 1 = $126.50. @@ -107,7 +107,7 @@ # Family Home Tier I Infant = $30/day wv_ccap_daily_rate: [0, 30] - # FPL ratio = 500 / 1_762.50 = 0.2837 < 0.40 -> 0% copay + # FPL ratio = 500 / 1_703.33 = 0.2935 < 0.40 -> 0% copay wv_ccap_copay: 0 # daily charge = 500 / 22 = 22.73 @@ -124,7 +124,7 @@ people: person1: age: 35 - # Above 185% FPL family of 2 ($39,127.50/yr). + # Above the family of 2 cap ($37,812/yr). employment_income: 60_000 immigration_status: CITIZEN weekly_hours_worked: 40 @@ -148,7 +148,7 @@ members: [person1, person2] state_code: WV output: - # $60,000/yr > 185% FPL family of 2 ($39,127.50/yr). + # $60,000/yr > the family of 2 cap ($37,812/yr). wv_ccap_income_eligible: false wv_ccap_eligible: false wv_ccap: 0 @@ -200,7 +200,7 @@ # daily charge = (10_000/12) / 22 = 37.88; daily benefit = min(35+3, 37.88) = 37.88. wv_ccap_daily_benefit: [0, 37.88] - # Copay: same 2-person FPL 1.1348 → Appendix A "120%" row $5.75/day × 22 = $126.50. + # Copay: same 2-person FPL 1.1742 → Appendix A "120%" row $5.75/day × 22 = $126.50. wv_ccap_copay: 126.5 # 22 days/month > 20 → per-day billing for base. @@ -272,7 +272,7 @@ wv_ccap_daily_rate: [0, 37] # 17 days/month is in the 13-20 monthly-rate range. # Base reimbursement (monthly rate): $37 × 20 = $740. - # Copay: 2-person FPL 1.1348 → Appendix A "120%" row $5.75/day × 17 = $97.75. + # Copay: 2-person FPL 1.1742 → Appendix A "120%" row $5.75/day × 17 = $97.75. wv_ccap_copay: 97.75 # benefit = max($740 - $97.75, 0) = $642.25. wv_ccap: 642.25 @@ -357,7 +357,7 @@ # 9 days/month is below the 13-day monthly-rate threshold. # Center Tier I Toddler = $37/day; daily charge = $1_000 / 9 = $111.11. wv_ccap_daily_benefit: [0, 37] - # Copay: 2-person FPL 1.1348 → Appendix A "120%" row $5.75/day × 9 = $51.75. + # Copay: 2-person FPL 1.1742 → Appendix A "120%" row $5.75/day × 9 = $51.75. wv_ccap_copay: 51.75 # Per-child reimbursement is capped before copay: # max(min($1_000 expense, $37 × 9 max rate) - $51.75, 0) = $281.25. diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_copay.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_copay.yaml index 0192752bd40..4c4c3f34b77 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_copay.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_copay.yaml @@ -3,7 +3,7 @@ # Manual §6.4.3.2: fees are daily, charged for each child in care. # Manual §6.4.3.4: capped at the three youngest children. # CCDF Plan §3.1.1: total family fee capped at 7% of gross income. -# 2025 FPG family of 2 monthly: $1_762.50. +# Appendix A's 2024 FPG for a family of 2: $1_703.33 a month. - name: Case 1, income below 40% FPL pays zero copay. period: 2025-01 @@ -27,7 +27,7 @@ members: [person1, person2] state_code: WV output: - # FPL ratio = 500 / 1_762.50 = 0.2837 < 0.40 -> fee = $0/day. + # FPL ratio = 500 / 1_703.33 = 0.2935 < 0.40 -> fee = $0/day. wv_ccap_copay: 0 - name: Case 2, mid-range income copay from Appendix A daily fee. @@ -52,7 +52,7 @@ members: [person1, person2] state_code: WV output: - # Monthly income $1_500; FPL ratio = 1_500 / 1_762.50 = 0.8511. + # Monthly income $1_500; FPL ratio = 1_500 / 1_703.33 = 0.8806. # Appendix A 2-person "90%" row daily fee = $4.25/child. # 1 eligible child × 22 monthly days. # copay = $4.25 × 22 × 1 = $93.50. @@ -80,7 +80,7 @@ members: [person1, person2] state_code: WV output: - # Monthly income $3_000; FPL ratio = 3_000 / 1_762.50 = 1.7021. + # Monthly income $3_000; FPL ratio = 3_000 / 1_703.33 = 1.7613. # Appendix A 2-person "180%" row daily fee = $8.75/child. # uncapped copay = $8.75 × 22 = $192.50. # 7% cap = $3_000 × 0.07 = $210. Cap does not bind for 2-person, 1-child. @@ -156,7 +156,7 @@ state_code: WV output: # Family size 12 defaults to the 11-person column. - # FPL ratio = 5_400 / 6_345.83 = 0.8511, so Appendix A 11-person "90%" row = $4.50/day. + # FPL ratio = 5_400 / 6_186.67 = 0.8729, so Appendix A 11-person "90%" row = $4.50/day. # 1 eligible child × 22 monthly days. # copay = $4.50 × 22 = $99. wv_ccap_copay: 99 @@ -192,9 +192,34 @@ members: [person1, person2, person3, person4, person5] state_code: WV output: - # Family size 5, FPL ratio = 2_500 / 3_137.50 = 0.7968. - # Appendix A 5-person "80%" row daily fee = $2.25/child. + # Family size 5, FPL ratio = 2_500 / 3_048.33 = 0.8201. + # Appendix A 5-person "90%" row daily fee = $2.50/child. # 4 eligible children × 22 monthly days = 88 monthly days. # Three-child cap scales billed days by 3/4: 88 × 3/4 = 66. - # copay = $2.25 × 66 = $148.50. - wv_ccap_copay: 148.5 + # copay = $2.50 × 66 = $165. + wv_ccap_copay: 165 + +- name: A family of three at 3,000 dollars a month pays the 140 percent row in 2026. + period: 2026-01 + absolute_error_margin: 0.01 + # FPL ratio = 3,000 / 2,151.67 = 1.394, Appendix A's row from $2,797.01 to $3,012, + # at $4.25 a day. 4.25 x 22 days = 93.50; the 7% cap of $210 doesn't bind. + input: + people: + person1: + age: 30 + person2: + age: 4 + childcare_attending_days_per_month: 22 + person3: + age: 12 + spm_units: + spm_unit: + members: [person1, person2, person3] + wv_ccap_countable_income: 3_000 + households: + household: + members: [person1, person2, person3] + state_code: WV + output: + wv_ccap_copay: 93.5 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_fpg.yaml new file mode 100644 index 00000000000..3c8756f1524 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_fpg.yaml @@ -0,0 +1,67 @@ +# Tests for wv_ccap_fpg (SPMUnit, MONTH). Appendix A prints the 2024 guideline, and the +# Bureau still linked that scale on November 5, 2026. +- name: 2024-11 uses the 2024 guideline. + period: 2024-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2024: WV + output: + wv_ccap_fpg: 2_151.67 + +- name: 2025-06 uses the 2024 guideline. + period: 2025-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2025: WV + output: + wv_ccap_fpg: 2_151.67 + +- name: 2026-11 uses the 2024 guideline. + period: 2026-11 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: + 2026: WV + output: + wv_ccap_fpg: 2_151.67 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_income_eligible.yaml index 0c1b030eda2..d7e14f14bdd 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_income_eligible.yaml @@ -1,6 +1,6 @@ # WV CCAP Income Eligibility Tests # Initial intake cap: 185% FPL (Manual §3.2.1, Appendix A) -# 185% FPL for a 2-person family (2025) = $39,127.50/yr +# Appendix A prints the 185% cap for a 2-person family at $3,151/mo, or $37,812/yr, on the 2024 FPG - name: Case 1, income below 185% FPL eligible. period: 2025-01 @@ -54,8 +54,8 @@ people: person1: age: 30 - # 2-person family: 185% FPL ≈ $39,127.50 - employment_income: 39_000 + # 2-person family: cap = $37,812/yr + employment_income: 37_800 person2: age: 5 tax_units: @@ -97,3 +97,1011 @@ # NOTE: we don't model "TANF children-only" cases (§3.2.1.4) that must # still meet the income test at the moment. wv_ccap_income_eligible: true + +# Appendix A's intake caps on the 2024 guideline, which the Bureau still linked on +# November 5, 2026. + +- name: New applicant of 3 at 3,981 dollars qualifies in 2024-11. + period: 2024-11 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + wv_ccap_countable_income: 3_981 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 3 at 3,982 dollars doesn't qualify in 2024-11. + period: 2024-11 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + wv_ccap_countable_income: 3_982 + households: + household: + members: [person1, person2, person3] + state_code: + 2024: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 3 at 3,981 dollars qualifies in 2025-06. + period: 2025-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + wv_ccap_countable_income: 3_981 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 3 at 3,982 dollars doesn't qualify in 2025-06. + period: 2025-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + wv_ccap_countable_income: 3_982 + households: + household: + members: [person1, person2, person3] + state_code: + 2025: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 1 at 2,322 dollars qualifies in 2026-01. + period: 2026-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + wv_ccap_countable_income: 2_322 + households: + household: + members: [person1] + state_code: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 1 at 2,323 dollars doesn't qualify in 2026-01. + period: 2026-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + wv_ccap_countable_income: 2_323 + households: + household: + members: [person1] + state_code: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 2 at 3,151 dollars qualifies in 2026-01. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_countable_income: 3_151 + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 2 at 3,152 dollars doesn't qualify in 2026-01. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_countable_income: 3_152 + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 3 at 3,981 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + wv_ccap_countable_income: 3_981 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 3 at 3,982 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + wv_ccap_countable_income: 3_982 + households: + household: + members: [person1, person2, person3] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 4 at 4,810 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + wv_ccap_countable_income: 4_810 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 4 at 4,811 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + wv_ccap_countable_income: 4_811 + households: + household: + members: [person1, person2, person3, person4] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 5 at 5,639 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + wv_ccap_countable_income: 5_639 + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 5 at 5,640 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + wv_ccap_countable_income: 5_640 + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 6 at 6,469 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + wv_ccap_countable_income: 6_469 + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 6 at 6,470 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + wv_ccap_countable_income: 6_470 + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 7 at 7,298 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + wv_ccap_countable_income: 7_298 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 7 at 7,299 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7] + wv_ccap_countable_income: 7_299 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 8 at 8,128 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + wv_ccap_countable_income: 8_128 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 8 at 8,129 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + wv_ccap_countable_income: 8_129 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: false + +- name: New applicant of 9 at 8,957 dollars qualifies in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + person9: + age: 17 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + wv_ccap_countable_income: 8_957 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: true + +- name: New applicant of 9 at 8,958 dollars doesn't qualify in 2026-06. + period: 2026-06 + input: + people: + person1: + age: 30 + person2: + age: 4 + person3: + age: 7 + person4: + age: 9 + person5: + age: 11 + person6: + age: 13 + person7: + age: 15 + person8: + age: 16 + person9: + age: 17 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + wv_ccap_countable_income: 8_958 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: + 2026: WV + output: + wv_ccap_income_eligible: false + +# Posted charts: each printed family size at its top passes and a dollar more +# fails. Each case sets the unit's size directly and lists the outcomes in size +# order, the top first. + +- name: Appendix A's FY 2024 scale holds at every family size in January 2026. + period: 2026-01 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + p5: + age: + 2026: 30 + p6: + age: + 2026: 30 + p7: + age: + 2026: 30 + p8: + age: + 2026: 30 + p9: + age: + 2026: 30 + p10: + age: + 2026: 30 + p11: + age: + 2026: 30 + p12: + age: + 2026: 30 + p13: + age: + 2026: 30 + p14: + age: + 2026: 30 + p15: + age: + 2026: 30 + p16: + age: + 2026: 30 + p17: + age: + 2026: 30 + p18: + age: + 2026: 30 + p19: + age: + 2026: 30 + p20: + age: + 2026: 30 + p21: + age: + 2026: 30 + p22: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 1 + wv_ccap_countable_income: 2_322 + u2: + members: [p2] + spm_unit_size: + 2026: 1 + wv_ccap_countable_income: 2_323 + u3: + members: [p3] + spm_unit_size: + 2026: 2 + wv_ccap_countable_income: 3_151 + u4: + members: [p4] + spm_unit_size: + 2026: 2 + wv_ccap_countable_income: 3_152 + u5: + members: [p5] + spm_unit_size: + 2026: 3 + wv_ccap_countable_income: 3_981 + u6: + members: [p6] + spm_unit_size: + 2026: 3 + wv_ccap_countable_income: 3_982 + u7: + members: [p7] + spm_unit_size: + 2026: 4 + wv_ccap_countable_income: 4_810 + u8: + members: [p8] + spm_unit_size: + 2026: 4 + wv_ccap_countable_income: 4_811 + u9: + members: [p9] + spm_unit_size: + 2026: 5 + wv_ccap_countable_income: 5_639 + u10: + members: [p10] + spm_unit_size: + 2026: 5 + wv_ccap_countable_income: 5_640 + u11: + members: [p11] + spm_unit_size: + 2026: 6 + wv_ccap_countable_income: 6_469 + u12: + members: [p12] + spm_unit_size: + 2026: 6 + wv_ccap_countable_income: 6_470 + u13: + members: [p13] + spm_unit_size: + 2026: 7 + wv_ccap_countable_income: 7_298 + u14: + members: [p14] + spm_unit_size: + 2026: 7 + wv_ccap_countable_income: 7_299 + u15: + members: [p15] + spm_unit_size: + 2026: 8 + wv_ccap_countable_income: 8_128 + u16: + members: [p16] + spm_unit_size: + 2026: 8 + wv_ccap_countable_income: 8_129 + u17: + members: [p17] + spm_unit_size: + 2026: 9 + wv_ccap_countable_income: 8_957 + u18: + members: [p18] + spm_unit_size: + 2026: 9 + wv_ccap_countable_income: 8_958 + u19: + members: [p19] + spm_unit_size: + 2026: 10 + wv_ccap_countable_income: 9_247 + u20: + members: [p20] + spm_unit_size: + 2026: 10 + wv_ccap_countable_income: 9_248 + u21: + members: [p21] + spm_unit_size: + 2026: 11 + wv_ccap_countable_income: 9_440 + u22: + members: [p22] + spm_unit_size: + 2026: 11 + wv_ccap_countable_income: 9_441 + households: + h1: + members: [p1] + state_code: + 2026: WV + h2: + members: [p2] + state_code: + 2026: WV + h3: + members: [p3] + state_code: + 2026: WV + h4: + members: [p4] + state_code: + 2026: WV + h5: + members: [p5] + state_code: + 2026: WV + h6: + members: [p6] + state_code: + 2026: WV + h7: + members: [p7] + state_code: + 2026: WV + h8: + members: [p8] + state_code: + 2026: WV + h9: + members: [p9] + state_code: + 2026: WV + h10: + members: [p10] + state_code: + 2026: WV + h11: + members: [p11] + state_code: + 2026: WV + h12: + members: [p12] + state_code: + 2026: WV + h13: + members: [p13] + state_code: + 2026: WV + h14: + members: [p14] + state_code: + 2026: WV + h15: + members: [p15] + state_code: + 2026: WV + h16: + members: [p16] + state_code: + 2026: WV + h17: + members: [p17] + state_code: + 2026: WV + h18: + members: [p18] + state_code: + 2026: WV + h19: + members: [p19] + state_code: + 2026: WV + h20: + members: [p20] + state_code: + 2026: WV + h21: + members: [p21] + state_code: + 2026: WV + h22: + members: [p22] + state_code: + 2026: WV + output: + # 185% of the 2024 guideline, sizes 1 to 9. For ten and eleven people the + # scale stops at 85% of the October 2024 state median income. + wv_ccap_income_eligible: [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false] + +- name: Appendix A caps ten and eleven people at 85% of the October 2024 state median income in October 2024, when the scale starts. + period: 2024-10 + input: + people: + p1: + age: + 2024: 30 + p2: + age: + 2024: 30 + p3: + age: + 2024: 30 + p4: + age: + 2024: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2024: 10 + wv_ccap_countable_income: 9_247 + u2: + members: [p2] + spm_unit_size: + 2024: 10 + wv_ccap_countable_income: 9_248 + u3: + members: [p3] + spm_unit_size: + 2024: 11 + wv_ccap_countable_income: 9_440 + u4: + members: [p4] + spm_unit_size: + 2024: 11 + wv_ccap_countable_income: 9_441 + households: + h1: + members: [p1] + state_code: + 2024: WV + h2: + members: [p2] + state_code: + 2024: WV + h3: + members: [p3] + state_code: + 2024: WV + h4: + members: [p4] + state_code: + 2024: WV + output: + # $9,247 for ten people and $9,440 for eleven. + wv_ccap_income_eligible: [true, false, true, false] + +- name: Appendix A caps ten and eleven people at 85% of the October 2024 state median income in October 2025, after the next table starts. + period: 2025-10 + input: + people: + p1: + age: + 2025: 30 + p2: + age: + 2025: 30 + p3: + age: + 2025: 30 + p4: + age: + 2025: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2025: 10 + wv_ccap_countable_income: 9_247 + u2: + members: [p2] + spm_unit_size: + 2025: 10 + wv_ccap_countable_income: 9_248 + u3: + members: [p3] + spm_unit_size: + 2025: 11 + wv_ccap_countable_income: 9_440 + u4: + members: [p4] + spm_unit_size: + 2025: 11 + wv_ccap_countable_income: 9_441 + households: + h1: + members: [p1] + state_code: + 2025: WV + h2: + members: [p2] + state_code: + 2025: WV + h3: + members: [p3] + state_code: + 2025: WV + h4: + members: [p4] + state_code: + 2025: WV + output: + # $9,247 for ten people and $9,440 for eleven. + wv_ccap_income_eligible: [true, false, true, false] + +- name: Appendix A caps ten and eleven people at 85% of the October 2024 state median income in October 2026, after two more tables start. + period: 2026-10 + input: + people: + p1: + age: + 2026: 30 + p2: + age: + 2026: 30 + p3: + age: + 2026: 30 + p4: + age: + 2026: 30 + spm_units: + u1: + members: [p1] + spm_unit_size: + 2026: 10 + wv_ccap_countable_income: 9_247 + u2: + members: [p2] + spm_unit_size: + 2026: 10 + wv_ccap_countable_income: 9_248 + u3: + members: [p3] + spm_unit_size: + 2026: 11 + wv_ccap_countable_income: 9_440 + u4: + members: [p4] + spm_unit_size: + 2026: 11 + wv_ccap_countable_income: 9_441 + households: + h1: + members: [p1] + state_code: + 2026: WV + h2: + members: [p2] + state_code: + 2026: WV + h3: + members: [p3] + state_code: + 2026: WV + h4: + members: [p4] + state_code: + 2026: WV + output: + # $9,247 for ten people and $9,440 for eleven. + wv_ccap_income_eligible: [true, false, true, false] diff --git a/policyengine_us/tests/test_child_care_posted_income_limits.py b/policyengine_us/tests/test_child_care_posted_income_limits.py new file mode 100644 index 00000000000..24409821ab1 --- /dev/null +++ b/policyengine_us/tests/test_child_care_posted_income_limits.py @@ -0,0 +1,823 @@ +"""Invariants of the child care income limits that states post. + +The state YAML files pin each posted chart: every printed family size at its top +passes and a dollar more fails. These tests check properties across many incomes and +families, one simulation per case, which single YAML households can't draw: + +1. Rules: for every date in RULES and NEVADA_RULES and for any income, a family passes + exactly when its income is at or below the rate times that date's guideline or + median income, rounded as the state's chart rounds. In Indiana and West Virginia + the limit stops at 85% of the state median income, which binds only for large + families, so those rules draw families of up to 20 and 11 people. This also makes + each income test monotonic in income. Each rule states the limit apart from the + formulas, so it acts as a second implementation. +2. Enrolled families: a family that passes as a new applicant passes as an enrolled + family at the same income, in every state with separate limits. +3. Ohio: the voucher pays only families over the Publicly Funded Child Care limit, + never pays more than the charge, and leaves the two programs exclusive, including + for homeless families, whom Publicly Funded Child Care serves without its income + test. Together the two income tests stay monotonic. The voucher's own test breaks + monotonicity on purpose, since a family under the intake limit belongs to + Publicly Funded Child Care. +4. Nevada: while the April to September 2024 percent-of-income schedule applied, no + family owed more than 7% of income, and sizes above 14 use the 14-person column. +5. Georgia: the program test equals its conjuncts, a priority group never removes + eligibility, and enrollment replaces the priority group. + +Hypothesis draws families from a fixed seed, so every run checks the same ones. The +properties also check fixed families: each size at its limit, and a grid of Georgia +families, some failing only one test. +""" + +import itertools +import math +from dataclasses import dataclass +from typing import Callable, Optional + +import numpy as np +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from policyengine_us import Simulation + + +def simulate( + state, month, families, income_variable, spm=None, person=None, household=None +): + """Build one simulation with a separate household per (size, monthly income).""" + year = int(month[:4]) + people, tax_units, spm_units, family_units, households = {}, {}, {}, {}, {} + marital_units = {} + for index, (size, income) in enumerate(families): + members = [f"person_{index}_{slot}" for slot in range(size)] + for slot, member in enumerate(members): + people[member] = { + "age": {year: 30 if slot == 0 else 5}, + "immigration_status": {year: "CITIZEN"}, + "weekly_hours_worked_before_lsr": {year: 40 if slot == 0 else 0}, + } + people[member].update(person(index, slot) if person else {}) + # Without explicit marital units, every person would share one. + marital_units[f"marital_{index}_{slot}"] = {"members": [member]} + income_input = ( + {year: income * 12} + if income_variable == "nv_ccdp_countable_income" + else {month: income} + ) + spm_units[f"spm_{index}"] = { + "members": members, + income_variable: income_input, + **(spm(index) if spm else {}), + } + tax_units[f"tax_{index}"] = {"members": members} + family_units[f"family_{index}"] = {"members": members} + households[f"household_{index}"] = { + "members": members, + "state_code": {year: state}, + **(household(index) if household else {}), + } + return Simulation( + situation={ + "people": people, + "tax_units": tax_units, + "spm_units": spm_units, + "families": family_units, + "marital_units": marital_units, + "households": households, + } + ) + + +def passes(test, month, families): + """Run an income test for (size, monthly income) families.""" + + def enrolled(_): + return {test.enrolled_variable: {month: True}} + + spm = enrolled if test.enrolled_variable and test.enrolled else None + simulation = simulate(test.state, month, families, test.income, spm=spm) + return simulation.calculate(test.eligible, month).astype(bool) + + +@dataclass(frozen=True) +class Program: + state: str + eligible: str + income: str + enrolled_variable: Optional[str] = None + enrolled: bool = False + + +AL = Program( + "AL", "al_ccsp_income_eligible", "al_ccsp_countable_income", "al_ccsp_enrolled" +) +AL_ENROLLED = Program( + "AL", + "al_ccsp_income_eligible", + "al_ccsp_countable_income", + "al_ccsp_enrolled", + True, +) +ID = Program( + "ID", "id_iccp_income_eligible", "id_iccp_countable_income", "id_iccp_enrolled" +) +IN = Program( + "IN", "in_ccdf_income_eligible", "in_ccdf_countable_income", "is_in_ccdf_enrolled" +) +IN_ENROLLED = Program( + "IN", + "in_ccdf_income_eligible", + "in_ccdf_countable_income", + "is_in_ccdf_enrolled", + True, +) +MO = Program( + "MO", "mo_ccs_income_eligible", "mo_ccs_adjusted_income", "mo_ccs_enrolled" +) +MO_ENROLLED = Program( + "MO", "mo_ccs_income_eligible", "mo_ccs_adjusted_income", "mo_ccs_enrolled", True +) +WV = Program("WV", "wv_ccap_income_eligible", "wv_ccap_countable_income") +MT = Program( + "MT", "mt_ccap_income_eligible", "mt_ccap_countable_income", "mt_ccap_enrolled" +) +MT_ENROLLED = Program( + "MT", + "mt_ccap_income_eligible", + "mt_ccap_countable_income", + "mt_ccap_enrolled", + True, +) +NV = Program( + "NV", "nv_ccdp_income_eligible", "nv_ccdp_countable_income", "nv_ccdp_enrolled" +) +NV_ENROLLED = Program( + "NV", + "nv_ccdp_income_eligible", + "nv_ccdp_countable_income", + "nv_ccdp_enrolled", + True, +) +OH = Program( + "OH", "oh_ccap_income_eligible", "oh_ccap_countable_income", "oh_ccap_enrolled" +) +GA = Program( + "GA", "ga_caps_income_eligible", "ga_caps_countable_income", "ga_caps_enrolled" +) +GA_ENROLLED = Program( + "GA", + "ga_caps_income_eligible", + "ga_caps_countable_income", + "ga_caps_enrolled", + True, +) +MD = Program( + "MD", "md_ccs_income_eligible", "md_ccs_countable_income", "md_ccs_enrolled" +) +MD_ENROLLED = Program( + "MD", + "md_ccs_income_eligible", + "md_ccs_countable_income", + "md_ccs_enrolled", + True, +) + + +# HHS poverty guidelines for the contiguous states, as (first person, each additional). +GUIDELINES = { + 2018: (12_140, 4_320), + 2019: (12_490, 4_420), + 2020: (12_760, 4_480), + 2021: (12_880, 4_540), + 2022: (13_590, 4_720), + 2023: (14_580, 5_140), + 2024: (15_060, 5_380), + 2025: (15_650, 5_500), + 2026: (15_960, 5_680), +} + + +def guideline(year, size): + first, additional = GUIDELINES[year] + return first + additional * (size - 1) + + +def nearest_dollar(amount): + """Half a dollar goes up, as Alabama, Indiana, Missouri, West Virginia, Montana and + Nevada print.""" + return math.floor(round(amount, 2) + 0.5) + + +def next_dollar(amount): + """Any cents go up, as Idaho, Ohio and Indiana's 85% limits print.""" + return math.ceil(round(amount, 2)) + + +def median_share(size): + """A family's share of the four-person state median income (45 CFR 96.85(b)): + 52% for one person, 16 points more for each person through six, and 3 points for + each person after that.""" + return 0.52 + 0.16 * (min(size, 6) - 1) + 0.03 * max(size - 6, 0) + + +@dataclass(frozen=True) +class Rule: + program: Program + month: str + # A rule without a guideline year tests the median income limit alone. + guideline_year: Optional[int] + rate: Optional[float] = None + rounding: Optional[Callable] = None + # Indiana's and West Virginia's charts stop at 85% of a four-person state median + # income table, adjusted for family size and rounded as each chart prints. + median: Optional[int] = None + median_rounding: Callable = nearest_dollar + max_size: int = 6 + + def top(self, size): + limits = [] + if self.guideline_year is not None: + limits.append( + self.rounding(guideline(self.guideline_year, size) * self.rate / 12) + ) + if self.median is not None: + limits.append( + self.median_rounding(self.median * median_share(size) * 0.85 / 12) + ) + return min(limits) + + +RULES = [ + # Alabama's fact sheets apply the prior year's guideline. + Rule(AL, "2026-01", 2025, 1.8, nearest_dollar), + Rule(AL, "2026-05", 2025, 1.8, nearest_dollar), + Rule(AL, "2026-06", 2025, 1.5, nearest_dollar), + Rule(AL_ENROLLED, "2026-01", 2025, 2, nearest_dollar), + Rule(AL_ENROLLED, "2026-06", 2025, 1.7, nearest_dollar), + # Idaho's rule set 130% until April 6, 2023, and 175% from then. The department + # reopened at 130% on January 13, 2025, and kept the 2024 guideline until its + # October 2025 table. + Rule(ID, "2022-06", 2022, 1.3, next_dollar), + Rule(ID, "2023-06", 2023, 1.75, next_dollar), + Rule(ID, "2025-02", 2024, 1.3, next_dollar), + Rule(ID, "2025-09", 2024, 1.3, next_dollar), + Rule(ID, "2025-10", 2025, 1.3, next_dollar), + Rule(ID, "2026-06", 2025, 1.3, next_dollar), + # Indiana's charts move partway through each year. Each caps families at 85% of + # the four-person median that starts the October before its guideline year, + # rounded up. + Rule(IN, "2024-06", 2024, 1.5, nearest_dollar, 95_373, next_dollar, 20), + Rule(IN, "2025-03", 2024, 1.5, nearest_dollar, 95_373, next_dollar, 20), + Rule(IN, "2025-06", 2025, 1.5, nearest_dollar, 103_324, next_dollar, 20), + Rule(IN, "2026-01", 2025, 1.5, nearest_dollar, 103_324, next_dollar, 20), + Rule(IN, "2026-04", 2025, 1.5, nearest_dollar, 103_324, next_dollar, 20), + Rule(IN, "2026-05", 2026, 1.35, nearest_dollar, 107_555, next_dollar, 20), + Rule( + IN_ENROLLED, + "2026-01", + None, + median=103_324, + median_rounding=next_dollar, + max_size=20, + ), + Rule( + IN_ENROLLED, + "2026-05", + None, + median=107_555, + median_rounding=next_dollar, + max_size=20, + ), + # Missouri holds the 2025 guideline through 2026. + Rule(MO, "2025-11", 2025, 1.5, nearest_dollar), + Rule(MO, "2026-01", 2025, 1.5, nearest_dollar), + Rule(MO, "2026-07", 2025, 1.5, nearest_dollar), + Rule(MO_ENROLLED, "2026-06", 2025, 2.42, nearest_dollar), + Rule(MO_ENROLLED, "2026-07", 2025, 2.15, nearest_dollar), + # West Virginia's Appendix A still prints the 2024 guideline, and from October 2024 + # stops at 85% of that October's four-person median. + Rule(WV, "2024-06", 2024, 1.85, nearest_dollar), + Rule(WV, "2024-10", 2024, 1.85, nearest_dollar, 90_661, max_size=11), + Rule(WV, "2025-03", 2024, 1.85, nearest_dollar, 90_661, max_size=11), + Rule(WV, "2026-03", 2024, 1.85, nearest_dollar, 90_661, max_size=11), + Rule(WV, "2026-10", 2024, 1.85, nearest_dollar, 90_661, max_size=11), + # Montana's scale moves each July. + Rule(MT, "2024-03", 2024, 1.85, nearest_dollar), + Rule(MT, "2025-03", 2024, 1.85, nearest_dollar), + Rule(MT, "2025-07", 2025, 1.85, nearest_dollar), + Rule(MT, "2026-03", 2025, 1.85, nearest_dollar), + Rule(MT_ENROLLED, "2025-07", 2025, 2, nearest_dollar), + Rule(MT_ENROLLED, "2026-03", 2025, 2, nearest_dollar), + # Ohio moves each October. + Rule(OH, "2026-01", 2025, 1.45, next_dollar), + Rule(OH, "2026-09", 2025, 1.45, next_dollar), + Rule(OH, "2026-10", 2026, 1.45, next_dollar), + # From October 2018 through June 2022 most new applicants in Nevada faced 130% of + # the guideline, which Nevada took up each October. + Rule(NV, "2018-10", 2018, 1.3, nearest_dollar), + Rule(NV, "2019-09", 2018, 1.3, nearest_dollar), + Rule(NV, "2019-10", 2019, 1.3, nearest_dollar), + Rule(NV, "2020-10", 2020, 1.3, nearest_dollar), + Rule(NV, "2022-06", 2021, 1.3, nearest_dollar), +] + + +def families_up_to(max_size, max_income): + """Twenty (size, monthly income) families.""" + return st.lists( + st.tuples( + st.integers(min_value=1, max_value=max_size), + st.integers(min_value=0, max_value=max_income), + ), + min_size=20, + max_size=20, + ) + + +SMALL_FAMILIES = families_up_to(6, 12_000) + + +@pytest.mark.parametrize( + "rule", + RULES, + ids=lambda rule: ( + f"{rule.program.state}-{rule.month}" + + ("-enrolled" if rule.program.enrolled else "") + ), +) +def test_limit_equals_rate_times_dated_guideline(rule): + families_drawn = ( + SMALL_FAMILIES if rule.max_size == 6 else families_up_to(rule.max_size, 16_000) + ) + + @settings(max_examples=2, deadline=None, derandomize=True) + @given(families=families_drawn) + def check(families): + # Each family also sits at its top and one dollar over, the two cases a + # random income almost never lands on, and so does the largest size, where + # a median income cap binds. + sizes = sorted({size for size, _ in families} | {rule.max_size}) + edges = [ + (size, income) + for size in sizes + for income in (rule.top(size), rule.top(size) + 1) + ] + cases = families + edges + result = passes(rule.program, rule.month, cases) + expected = [income <= rule.top(size) for size, income in cases] + assert result.tolist() == expected + + check() + + +# Nevada's four-person state median income, by the October that starts each table. +NEVADA_SMI = { + "2017-10": 69_361, + "2018-10": 71_593, + "2022-10": 85_150, + "2023-10": 89_325, + "2024-10": 96_026, + "2026-10": 105_027, +} +SMI_SIZE_FACTOR = {1: 0.52, 2: 0.68, 3: 0.84, 4: 1.0, 5: 1.16, 6: 1.32} + +NEVADA_RULES = [ + (NV, "2018-09", "2017-10", 0.85), + # From October 2018 through June 2022 enrolled families kept 85% of the median, + # while most new applicants faced the guideline (RULES). + (NV_ENROLLED, "2019-06", "2018-10", 0.85), + # The FFY 2022-2024 plan dates its 85% limits to July 1, 2022, on the table that + # starts October 1, 2022. + (NV, "2022-07", "2022-10", 0.85), + (NV, "2022-09", "2022-10", 0.85), + (NV, "2022-10", "2022-10", 0.85), + (NV, "2024-09", "2023-10", 0.85), + (NV_ENROLLED, "2024-09", "2023-10", 0.85), + (NV, "2024-10", "2024-10", 0.41), + (NV_ENROLLED, "2024-10", "2024-10", 0.49), + (NV, "2026-10", "2026-10", 0.41), + (NV_ENROLLED, "2026-10", "2026-10", 0.49), +] + + +def nevada_top(table, size, rate, month): + """The highest whole-dollar monthly income that passes. + + From October 2024 the charts print each limit as the nearest dollar. Earlier + limits keep their cents, and MS 316 rounds income to the nearest dollar, so the + highest passing income is the limit rounded down. + """ + limit = NEVADA_SMI[table] * SMI_SIZE_FACTOR[size] * rate / 12 + if month >= "2024-10": + return nearest_dollar(limit) + return math.floor(round(limit, 2)) + + +@pytest.mark.parametrize( + "program, month, table, rate", + NEVADA_RULES, + ids=lambda value: value.eligible if isinstance(value, Program) else str(value), +) +def test_nevada_limit_equals_rate_times_dated_median_income( + program, month, table, rate +): + sizes = list(SMI_SIZE_FACTOR) + families = [] + for size in sizes: + top = nevada_top(table, size, rate, month) + families += [(size, top), (size, top + 1)] + result = passes(program, month, families) + assert result.tolist() == [True, False] * len(sizes) + + +ENROLLMENT_PAIRS = [ + (AL, AL_ENROLLED, "2026-06"), + (AL, AL_ENROLLED, "2026-01"), + ( + ID, + Program( + "ID", + "id_iccp_income_eligible", + "id_iccp_countable_income", + "id_iccp_enrolled", + True, + ), + "2026-01", + ), + (IN, IN_ENROLLED, "2026-05"), + (MO, MO_ENROLLED, "2026-07"), + (MT, MT_ENROLLED, "2026-03"), + (NV, NV_ENROLLED, "2024-10"), + (NV, NV_ENROLLED, "2022-07"), + (NV, NV_ENROLLED, "2019-06"), + ( + OH, + Program( + "OH", + "oh_ccap_income_eligible", + "oh_ccap_countable_income", + "oh_ccap_enrolled", + True, + ), + "2026-10", + ), + (GA, GA_ENROLLED, "2026-01"), + (GA, GA_ENROLLED, "2026-10"), + # Maryland's continuation scale moved to the federal fiscal 2025 median eight + # months before the initial scale did. + (MD, MD_ENROLLED, "2024-05"), + (MD, MD_ENROLLED, "2024-11"), + (MD, MD_ENROLLED, "2026-03"), +] + + +def highest_passing_incomes(program, month, high=15_000): + """The highest monthly income at which a family of each size from 1 to 6 passes. + + Scans $100 steps up to `high`, then each dollar after the last step that passes. + """ + sizes = range(1, 7) + steps = range(0, high + 1, 100) + coarse = passes( + program, month, [(size, income) for size in sizes for income in steps] + ).reshape(len(sizes), len(steps)) + starts = { + size: steps[np.flatnonzero(row)[-1]] + for size, row in zip(sizes, coarse) + if row.any() + } + if not starts: + return {} + fine = passes( + program, + month, + [ + (size, start + extra) + for size, start in starts.items() + for extra in range(100) + ], + ).reshape(len(starts), 100) + return { + size: start + int(np.flatnonzero(row)[-1]) + for (size, start), row in zip(starts.items(), fine) + } + + +@pytest.mark.parametrize( + "new, enrolled, month", + ENROLLMENT_PAIRS, + ids=lambda value: value.state if isinstance(value, Program) else str(value), +) +def test_new_applicant_who_passes_also_passes_when_enrolled(new, enrolled, month): + # A family at the highest income that passes as a new applicant must pass when + # enrolled. If the enrolled test is monotonic in income, passing there means + # passing at every lower income too. + tops = highest_passing_incomes(new, month) + assert sorted(tops) == [1, 2, 3, 4, 5, 6] + assert passes(enrolled, month, list(tops.items())).all(), tops + + @settings(max_examples=2, deadline=None, derandomize=True) + @given(families=SMALL_FAMILIES) + def check(families): + passes_new = passes(new, month, families) + passes_enrolled = passes(enrolled, month, families) + assert not (passes_new & ~passes_enrolled).any() + + check() + + +OHIO_MONTHS = ["2025-11", "2026-01", "2026-10", "2026-11"] + + +def ohio_family_results(month, cases, charges=None, homeless=None): + """Run Ohio for families whose children are 2 and in center care. + + Each child's provider charges charges[index] a year ($24,000 unless given), and + homeless[index] marks a homeless household. + """ + year = int(month[:4]) + + def person(index, slot): + if slot == 0: + return {} + return { + "age": {year: 2}, + "childcare_hours_per_week": {year: 40}, + "oh_ccap_provider_type": {month: "CENTER"}, + "pre_subsidy_childcare_expenses": { + year: charges[index] if charges else 24_000 + }, + } + + def household(index): + return {"is_homeless": {year: homeless[index]}} if homeless else {} + + simulation = simulate( + "OH", + month, + cases, + "oh_ccap_countable_income", + person=person, + household=household, + ) + return { + variable: simulation.calculate(variable, month) + for variable in [ + "oh_ccap", + "oh_ccvp", + "oh_ccap_income_eligible", + "oh_ccvp_eligible", + ] + } + + +@pytest.mark.parametrize("month", OHIO_MONTHS) +def test_ohio_voucher_stays_apart_from_publicly_funded_child_care(month): + # Each child's provider charges $300 a month, under every voucher rate, or + # $2,000, over them. Homeless families qualify for Publicly Funded Child Care + # without its income test. + families = [ + (size, income, annual_charge, homeless) + for size in (2, 3, 4) + for income in range(1_500, 9_500, 250) + for annual_charge in (3_600, 24_000) + for homeless in (False, True) + ] + results = ohio_family_results( + month, + [(size, income) for size, income, _, _ in families], + charges=[annual_charge for _, _, annual_charge, _ in families], + homeless=[homeless for _, _, _, homeless in families], + ) + voucher = results["oh_ccvp"] + publicly_funded = results["oh_ccap"] + charge = np.array( + [(size - 1) * annual_charge / 12 for size, _, annual_charge, _ in families] + ) + homeless = np.array([homeless for _, _, _, homeless in families]) + # Exclusive: a family drawing the voucher draws nothing from the other program. + assert not ((voucher > 0) & (publicly_funded > 0)).any() + # The voucher never pays more than the family's charge... + assert (voucher <= charge + 0.01).all() + # ...and the charge sets the payment for some families, so the bound binds. + assert ((voucher > 0) & (np.abs(voucher - charge) < 0.01)).any() + # Homeless families draw Publicly Funded Child Care at any income, so none draws + # the voucher, and some over that program's intake limit draw it. + assert not (voucher[homeless] > 0).any() + over_intake_limit = ~results["oh_ccap_income_eligible"].astype(bool) + assert ((publicly_funded > 0) & homeless & over_intake_limit).any() + # The voucher pays in some months of this range, so the checks above bind. + assert (voucher > 0).any() + # Only families over the intake limit qualify. + assert not ( + results["oh_ccvp_eligible"].astype(bool) + & results["oh_ccap_income_eligible"].astype(bool) + ).any() + + +@pytest.mark.parametrize("month", ["2026-01", "2026-10"]) +def test_ohio_income_tests_together_are_monotonic(month): + incomes = list(range(0, 12_000, 150)) + cases = [(3, income) for income in incomes] + results = ohio_family_results(month, cases) + either = results["oh_ccap_income_eligible"].astype(bool) | results[ + "oh_ccvp_eligible" + ].astype(bool) + # Once a family fails both tests, every higher income fails both. + assert (np.diff(either.astype(int)) <= 0).all() + + +def test_ohio_voucher_test_alone_is_not_monotonic_by_design(): + # Intended violation, minimized: the same family fails the voucher at $3,221 (it + # belongs to Publicly Funded Child Care) and passes at $3,222. + results = ohio_family_results("2026-01", [(3, 3_221), (3, 3_222)]) + assert results["oh_ccvp_eligible"].astype(bool).tolist() == [False, True] + + +def test_nevada_copay_stays_within_seven_percent_of_income(): + month = "2024-06" + cases = [ + (size, income) + for size in (1, 2, 3, 4, 5, 8, 14) + for income in range(0, 9_000, 300) + ] + simulation = simulate("NV", month, cases, "nv_ccdp_countable_income") + copay = simulation.calculate("nv_ccdp_copay", month) + income = np.array([income for _, income in cases], dtype=float) + assert (copay <= income * 0.07 + 0.01).all() + # The schedule charges something in this range, so the bound binds. + assert (copay > 0).any() + + +def test_nevada_copay_uses_the_fourteen_person_column_above_fourteen(): + month = "2024-06" + cases = [ + (size, income) for income in range(0, 12_000, 400) for size in (14, 15, 18) + ] + simulation = simulate("NV", month, cases, "nv_ccdp_countable_income") + copay = simulation.calculate("nv_ccdp_copay", month).reshape(-1, 3) + # The copay depends on income and the column, so equal incomes give equal copays. + assert (copay[:, 1] == copay[:, 0]).all() + assert (copay[:, 2] == copay[:, 0]).all() + + +GEORGIA_FLAGS = st.fixed_dictionaries( + { + "size": st.integers(min_value=2, max_value=5), + "income": st.integers(min_value=0, max_value=8_000), + "hours": st.sampled_from([0, 20, 40]), + "enrolled": st.booleans(), + "pre_k": st.booleans(), + "domestic_violence": st.booleans(), + } +) + + +def georgia_results(month, families, **overrides): + year = int(month[:4]) + enrolled = overrides.get("enrolled") + pre_k = overrides.get("pre_k") + + def spm(index): + family = families[index] + return { + "ga_caps_enrolled": { + month: family["enrolled"] if enrolled is None else enrolled + }, + "ga_caps_domestic_violence": {month: family["domestic_violence"]}, + } + + def person(index, slot): + family = families[index] + if slot == 0: + return {"weekly_hours_worked_before_lsr": {year: family["hours"]}} + return { + "ga_caps_pre_k_enrolled": { + month: family["pre_k"] if pre_k is None else pre_k + } + } + + simulation = simulate( + "GA", + month, + [(family["size"], family["income"]) for family in families], + "ga_caps_countable_income", + spm=spm, + person=person, + ) + return { + variable: simulation.calculate(variable, month).astype(bool) + for variable in [ + "ga_caps_eligible", + "ga_caps_income_eligible", + "ga_caps_activity_eligible", + "ga_caps_priority_group_eligible", + "ga_caps_enrolled", + ] + } + + +# Every combination of the drawn flags at seven incomes. The tests below check that +# the grid holds families on each side of every test they cover. +GEORGIA_GRID = [ + { + "size": size, + "income": income, + "hours": hours, + "enrolled": enrolled, + "pre_k": pre_k, + "domestic_violence": domestic_violence, + } + for size, income, hours, enrolled, pre_k, domestic_violence in itertools.product( + [2, 3, 5], + [100, 1_000, 2_000, 3_000, 4_500, 6_000, 7_500], + [0, 20, 40], + [False, True], + [False, True], + [False, True], + ) +] + + +def check_georgia_product(month, families): + results = georgia_results(month, families) + # Every family has a citizen child under 13 and assets under the limit, so + # those two conjuncts hold for all of them. + expected = ( + results["ga_caps_income_eligible"] + & results["ga_caps_activity_eligible"] + & (results["ga_caps_priority_group_eligible"] | results["ga_caps_enrolled"]) + ) + assert (results["ga_caps_eligible"] == expected).all() + return results + + +@pytest.mark.parametrize( + "month", ["2015-06", "2022-11", "2024-08", "2026-01", "2026-10"] +) +def test_georgia_eligibility_is_the_product_of_its_tests(month): + results = check_georgia_product(month, GEORGIA_GRID) + income = results["ga_caps_income_eligible"] + activity = results["ga_caps_activity_eligible"] + group = results["ga_caps_priority_group_eligible"] + enrolled = results["ga_caps_enrolled"] + # Some grid family fails each test while passing the others, and some enrolled + # family passes outside every priority group, so dropping any term changes a + # result. Georgia has required new applicants to belong to a priority group since + # August 2016. + assert (~income & activity & (group | enrolled)).any() + assert (income & ~activity & (group | enrolled)).any() + if month >= "2016-08": + assert (income & activity & ~group & ~enrolled).any() + assert (income & activity & ~group & enrolled).any() + + @settings(max_examples=2, deadline=None, derandomize=True) + @given(families=st.lists(GEORGIA_FLAGS, min_size=20, max_size=20)) + def check(families): + check_georgia_product(month, families) + + check() + + +def check_priority_group_never_removes_eligibility(families): + without = georgia_results("2026-10", families, enrolled=False, pre_k=False) + with_group = georgia_results("2026-10", families, enrolled=False, pre_k=True) + assert not (without["ga_caps_eligible"] & ~with_group["ga_caps_eligible"]).any() + assert with_group["ga_caps_priority_group_eligible"].all() + return without, with_group + + +def test_georgia_priority_group_never_removes_eligibility(): + without, with_group = check_priority_group_never_removes_eligibility(GEORGIA_GRID) + # Pre-K admits some grid families that no other group admits. + assert (~without["ga_caps_eligible"] & with_group["ga_caps_eligible"]).any() + + @settings(max_examples=2, deadline=None, derandomize=True) + @given(families=st.lists(GEORGIA_FLAGS, min_size=20, max_size=20)) + def check(families): + check_priority_group_never_removes_eligibility(families) + + check() + + +def check_enrollment_replaces_the_priority_group(families): + results = georgia_results("2026-10", families, enrolled=True, pre_k=False) + expected = results["ga_caps_income_eligible"] & results["ga_caps_activity_eligible"] + assert (results["ga_caps_eligible"] == expected).all() + return results + + +def test_georgia_enrollment_replaces_the_priority_group(): + results = check_enrollment_replaces_the_priority_group(GEORGIA_GRID) + # Some enrolled grid families pass outside every priority group. + assert ( + results["ga_caps_eligible"] & ~results["ga_caps_priority_group_eligible"] + ).any() + + @settings(max_examples=2, deadline=None, derandomize=True) + @given(families=st.lists(GEORGIA_FLAGS, min_size=20, max_size=20)) + def check(families): + check_enrollment_replaces_the_priority_group(families) + + check() 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 55f21e6be47..dcb0f8e5f24 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,10 +5,11 @@ 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.2(c)(iii)). Defaults to - # False, so every household is treated as a new applicant unless this - # input is explicitly set. + # Distinguishes new applicants, who face the initial limit, from continuing + # recipients, who face the higher continuing limit (§2.5.2(c)(iii)); both + # limits live in gov.states.al.dhr.ccsp.income.limit. Defaults to False, + # so the model treats every household as a new applicant unless the user + # sets this input. 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/al_ccsp_fpg.py b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_fpg.py new file mode 100644 index 00000000000..a181aeb0c48 --- /dev/null +++ b/policyengine_us/variables/gov/states/al/dhr/ccsp/al_ccsp_fpg.py @@ -0,0 +1,29 @@ +from policyengine_us.model_api import * + + +class al_ccsp_fpg(Variable): + value_type = float + entity = SPMUnit + label = "Alabama CCSP monthly federal poverty guideline" + definition_period = MONTH + unit = USD + defined_for = StateCode.AL + reference = ( + "https://dhr.alabama.gov/wp-content/uploads/2024/01/Child-Care-Fact-Sheet-2024.pdf#page=1", + "https://dhr.alabama.gov/wp-content/uploads/2026/06/CHILD-CARE-FACT-SHEET-Jun2026-1.pdf#page=1", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.al.dhr.ccsp.income + size = spm_unit("spm_unit_size", period.this_year) + # The fact sheets print one row for families of eight or more. + capped_size = min_(size, p.max_family_size) + state_group = spm_unit.household("state_group_str", period.this_year) + # Alabama's fact sheets use the prior calendar year's HHS poverty + # guidelines throughout the benefit year, since HHS publishes the new + # guidelines in mid-January. + p_fpg = parameters(period.last_year).gov.hhs.fpg + annual_fpg = p_fpg.first_person[state_group] + p_fpg.additional_person[ + state_group + ] * (capped_size - 1) + return annual_fpg / 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 6913e1b1f31..26596ec36fc 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,9 +15,7 @@ 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) - # Use the prior calendar year's HHS poverty guidelines to match - # Alabama's Child Care Fact Sheet operational thresholds. - monthly_fpg = spm_unit("spm_unit_fpg", period.last_year) / MONTHS_IN_YEAR + monthly_fpg = spm_unit("al_ccsp_fpg", period) 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 6aa3bd959dc..06aab57366d 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,24 +7,27 @@ class al_ccsp_income_eligible(Variable): label = "Eligible for Alabama CCSP based on income" 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=24" + reference = ( + "https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=24", + "https://dhr.alabama.gov/wp-content/uploads/2026/06/CHILD-CARE-FACT-SHEET-Jun2026-1.pdf#page=1", + ) 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) - # 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. - annual_fpg = spm_unit("spm_unit_fpg", period.last_year) - monthly_fpg = annual_fpg / MONTHS_IN_YEAR + monthly_fpg = spm_unit("al_ccsp_fpg", period) enrolled = spm_unit("al_ccsp_enrolled", period) fpl_limit_ratio = where( enrolled, p.fpl_continuing, p.fpl_initial, ) - fpl_eligible = monthly_income <= monthly_fpg * fpl_limit_ratio + # The fact sheet prints each limit to the nearest dollar, with half a + # dollar going up ($3,172.50 prints as $3,173). Round to cents first so + # floating-point noise can't move a tie. + fpl_limit = np.floor(np.round(monthly_fpg * fpl_limit_ratio, 2) + 0.5) + fpl_eligible = monthly_income <= fpl_limit monthly_smi = spm_unit("hhs_smi", period) smi_eligible = monthly_income <= monthly_smi * p.smi_cap diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/copay/ga_caps_family_fee.py b/policyengine_us/variables/gov/states/ga/decal/caps/copay/ga_caps_family_fee.py index 874681a02a9..4e5d59e8e24 100644 --- a/policyengine_us/variables/gov/states/ga/decal/caps/copay/ga_caps_family_fee.py +++ b/policyengine_us/variables/gov/states/ga/decal/caps/copay/ga_caps_family_fee.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg class ga_caps_family_fee(Variable): @@ -21,16 +22,19 @@ def formula(spm_unit, period, parameters): is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) age = person("age", period.this_year) has_minor_parent = spm_unit.any(is_head_or_spouse & (age <= p.minor_parent_age)) - # DFCS custody fee waiver: any child in DFCS custody waives the fee. - has_dfcs_custody_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 - fee_waived = has_minor_parent | has_dfcs_custody_child - # Compute fee from FPL-ratio scale bracket. + # Each child in DFCS custody forms a family unit of one that owes no fee + # (CAPS/00-5, 5.4.1; CAPS/00-7, 7.5), which ga_caps pays apart from this + # fee. The family's own unit leaves those children out of its size. countable_income = spm_unit("ga_caps_countable_income", period) - fpg = spm_unit("spm_unit_fpg", period) - mask = fpg > 0 + size = spm_unit("ga_caps_family_size", period) + state_group = spm_unit.household("state_group_str", period.this_year) + monthly_fpg = fpg(size, state_group, period.this_year, parameters) / ( + MONTHS_IN_YEAR + ) + mask = monthly_fpg > 0 fpl_ratio = np.divide( countable_income, - fpg, + monthly_fpg, out=np.zeros_like(countable_income), where=mask, ) @@ -39,4 +43,4 @@ def formula(spm_unit, period, parameters): annual_income = countable_income * MONTHS_IN_YEAR weekly_fee = np.floor(annual_income * fee_rate / WEEKS_IN_YEAR) monthly_fee = weekly_fee * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) - return where(fee_waived, 0, monthly_fee) + return where(has_minor_parent, 0, monthly_fee) diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_activity_eligible.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_activity_eligible.py index 3f8b4e4f790..4849f8a6e43 100644 --- a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_activity_eligible.py +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_activity_eligible.py @@ -7,7 +7,11 @@ class ga_caps_activity_eligible(Variable): label = "Eligible for Georgia CAPS based on activity requirements" definition_period = MONTH defined_for = StateCode.GA - reference = "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=33" + reference = ( + "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=33", + # PDF pages 2, 8 + "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=2", + ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states.ga.decal.caps.activity_requirements @@ -33,4 +37,13 @@ def formula(spm_unit, period, parameters): individually_eligible = meets_work_requirement | is_student | is_disabled all_heads_meet = ~spm_unit.any(is_head_or_spouse & ~individually_eligible) meets_ccdf = spm_unit("meets_ccdf_activity_test", period.this_year) - return all_heads_meet | meets_ccdf + # CAPS/00-7, 7.13 waives the requirement for parents in Grandparents Raising + # Grandchildren. Foster parents of children in DFCS custody need not meet it + # either (7.5), but those children form family units of one, which + # ga_caps_eligible serves apart from this test. The Child Protective + # Services waiver in 7.4 is discretionary ("may be waived"), so + # meets_ccdf_activity_test carries it as an input. + grandparents_raising_grandchildren = spm_unit( + "ga_caps_grandparents_raising_grandchildren", period + ) + return all_heads_meet | meets_ccdf | grandparents_raising_grandchildren diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_dfcs_custody_child.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_dfcs_custody_child.py new file mode 100644 index 00000000000..bfefeb77823 --- /dev/null +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_dfcs_custody_child.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class ga_caps_dfcs_custody_child(Variable): + value_type = bool + entity = Person + label = "Child in DFCS custody, served by Georgia CAPS as a family unit of one" + definition_period = MONTH + defined_for = StateCode.GA + reference = ( + "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=27", + "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=2", + ) + + def formula(person, period, parameters): + # CAPS/00-5, 5.4.1: the State stands as the parent of each child in DFCS + # custody, and the child forms a family unit of one. CAPS/00-7, 7.5: foster + # parents need not meet the income or activity requirements, and the child + # owes no family fee. + eligible_child = person("ga_caps_eligible_child", period) + return eligible_child & person("is_in_foster_care", period) diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_eligible.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_eligible.py index 113bc8e6911..57544d66ab9 100644 --- a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_eligible.py +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_eligible.py @@ -7,11 +7,17 @@ class ga_caps_eligible(Variable): label = "Eligible for Georgia CAPS" definition_period = MONTH defined_for = StateCode.GA - reference = "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=29" + reference = ( + # PDF pages 27, 29 + "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=27", + "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=2", + ) def formula(spm_unit, period, parameters): - has_eligible_child = add(spm_unit, period, ["ga_caps_eligible_child"]) > 0 - income_eligible = spm_unit("ga_caps_income_eligible", period) - asset_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) - activity_eligible = spm_unit("ga_caps_activity_eligible", period) - return has_eligible_child & income_eligible & asset_eligible & activity_eligible + # CAPS serves each child in DFCS custody as a family unit of one (CAPS/00-5, + # 5.4.1; CAPS/00-7, 7.5) and the family's other children when the family + # qualifies on its own. + has_dfcs_custody_child = ( + add(spm_unit, period, ["ga_caps_dfcs_custody_child"]) > 0 + ) + return spm_unit("ga_caps_family_eligible", period) | has_dfcs_custody_child diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_family_eligible.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_family_eligible.py new file mode 100644 index 00000000000..a01ee97c9bc --- /dev/null +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_family_eligible.py @@ -0,0 +1,51 @@ +from policyengine_us.model_api import * + + +class ga_caps_family_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Georgia CAPS as a family, apart from children in DFCS custody" + definition_period = MONTH + defined_for = StateCode.GA + reference = ( + # PDF pages 27, 29 + "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=27", + "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=1", + "https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_from_Elisabetta_Kasfir_Families_07.01.2024.pdf#page=1", + "https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_to_Families_Policy_Revisions_10.06.25.pdf#page=1", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ga.decal.caps.priority_groups + person = spm_unit.members + # CAPS/00-5, 5.4.1: a child in DFCS custody forms a family unit of one, so + # the family's own case covers its other children. + family_child = person("ga_caps_eligible_child", period) & ~person( + "is_in_foster_care", period + ) + has_eligible_child = spm_unit.any(family_child) + income_eligible = spm_unit("ga_caps_income_eligible", period) + asset_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) + activity_eligible = spm_unit("ga_caps_activity_eligible", period) + # CAPS/00-7, 7.3.1: new applicants outside a priority group are denied even + # when they meet every other requirement. 7.3.1.3 drops the requirement at + # annual redetermination. From July 1, 2024 to October 6, 2025, a family whose + # child attended Georgia's Pre-K at the initial application or the previous + # determination had to belong to a group at redetermination. + pre_k_family = spm_unit.any( + person("ga_caps_pre_k_at_previous_determination", period) + ) + exempt_at_redetermination = spm_unit("ga_caps_enrolled", period) & ~( + pre_k_family & p.pre_k_redetermination_in_effect + ) + priority_group_met = ( + spm_unit("ga_caps_priority_group_eligible", period) + | exempt_at_redetermination + ) + return ( + has_eligible_child + & income_eligible + & asset_eligible + & activity_eligible + & priority_group_met + ) diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_family_size.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_family_size.py new file mode 100644 index 00000000000..18c5abd1a79 --- /dev/null +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_family_size.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class ga_caps_family_size(Variable): + value_type = int + entity = SPMUnit + label = "Georgia CAPS family unit size" + definition_period = MONTH + defined_for = StateCode.GA + reference = "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=27" + + def formula(spm_unit, period, parameters): + # CAPS/00-5, 5.4.1: each child in DFCS custody forms a family unit of one, so + # the foster family's own unit leaves those children out. + size = spm_unit("spm_unit_size", period.this_year) + return size - add(spm_unit, period, ["is_in_foster_care"]) diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible.py index c3e8213fc7a..bf40ce17559 100644 --- a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible.py +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/ga_caps_income_eligible.py @@ -1,4 +1,6 @@ +from policyengine_core.periods import instant from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import smi class ga_caps_income_eligible(Variable): @@ -8,16 +10,28 @@ class ga_caps_income_eligible(Variable): definition_period = MONTH defined_for = StateCode.GA reference = ( - "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=49", - "https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf", + # PDF pages 27, 49, 52 + "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=27", + "https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1", ) def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.ga.decal.caps.income.smi_rate - countable_income = spm_unit("ga_caps_countable_income", period) - smi = spm_unit("hhs_smi", period) + p = parameters(period).gov.states.ga.decal.caps.income + # Each Appendix A chart dates the state median income table it takes up, + # which smi_year_lag carries. The chart prints annual limits rounded up to + # the next dollar, and Manual 8.8.4 multiplies monthly income by 12 to + # compare with it. Round to cents first so floating-point noise can't push + # a whole-dollar limit up by one or move a family at the limit. + size = spm_unit("ga_caps_family_size", period) + state = spm_unit.household("state_code_str", period.this_year) + table_date = instant(period).offset(-int(p.smi_year_lag), "year") + annual_smi = smi(size, state, table_date, parameters) enrolled = spm_unit("ga_caps_enrolled", period) - initial_limit = smi * p.initial_eligibility - ongoing_limit = smi * p.ongoing_eligibility - income_limit = where(enrolled, ongoing_limit, initial_limit) - return countable_income <= income_limit + rate = where( + enrolled, p.smi_rate.ongoing_eligibility, p.smi_rate.initial_eligibility + ) + income_limit = np.ceil(np.round(annual_smi * rate, 2)) + annual_income = np.round( + spm_unit("ga_caps_countable_income", period) * MONTHS_IN_YEAR, 2 + ) + return annual_income <= income_limit diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_domestic_violence.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_domestic_violence.py new file mode 100644 index 00000000000..0f2a26dc845 --- /dev/null +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_domestic_violence.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class ga_caps_domestic_violence(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Family experiences domestic violence, for the Georgia CAPS priority group" + defined_for = StateCode.GA + reference = "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=3" diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_grandparents_raising_grandchildren.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_grandparents_raising_grandchildren.py new file mode 100644 index 00000000000..de7d12110cf --- /dev/null +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_grandparents_raising_grandchildren.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class ga_caps_grandparents_raising_grandchildren(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Family participates in the Georgia Grandparents Raising Grandchildren program, for the Georgia CAPS priority group" + defined_for = StateCode.GA + reference = "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=8" diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_natural_disaster.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_natural_disaster.py new file mode 100644 index 00000000000..b8b16fdfcc4 --- /dev/null +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_natural_disaster.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class ga_caps_natural_disaster(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Family was harmed by a declared natural disaster in the previous 24 months, for the Georgia CAPS priority group" + defined_for = StateCode.GA + reference = "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=6" diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_pre_k_at_previous_determination.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_pre_k_at_previous_determination.py new file mode 100644 index 00000000000..7440c91062f --- /dev/null +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_pre_k_at_previous_determination.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class ga_caps_pre_k_at_previous_determination(Variable): + value_type = bool + entity = Person + definition_period = MONTH + label = "Child attended Georgia's Pre-K Program at the family's initial Georgia CAPS application or previous eligibility determination" + defined_for = StateCode.GA + reference = "https://caps.decal.ga.gov/Assets/downloads/CAPS_Letter_from_Elisabetta_Kasfir_Families_07.01.2024.pdf#page=1" diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_pre_k_enrolled.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_pre_k_enrolled.py new file mode 100644 index 00000000000..7fa1c77087d --- /dev/null +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_pre_k_enrolled.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class ga_caps_pre_k_enrolled(Variable): + value_type = bool + entity = Person + definition_period = MONTH + label = "Child attends Georgia's Pre-K Program, for the Georgia CAPS priority group" + defined_for = StateCode.GA + reference = "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=5" diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_priority_group_eligible.py b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_priority_group_eligible.py new file mode 100644 index 00000000000..b31841239ec --- /dev/null +++ b/policyengine_us/variables/gov/states/ga/decal/caps/eligibility/priority_groups/ga_caps_priority_group_eligible.py @@ -0,0 +1,94 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class ga_caps_priority_group_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Belongs to a Georgia CAPS priority group" + definition_period = MONTH + defined_for = StateCode.GA + reference = ( + "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=1", + "https://www.decal.ga.gov/documents/attachments/fundingrestrictionsqa.pdf#page=1", + "https://www.decal.ga.gov/documents/attachments/CCDFStatePlan25-27.pdf#page=25", + "https://caps.decal.ga.gov/assets/downloads/CAPS/AppendixA-CAPS%20Maximum%20Income%20Limits%20by%20Family%20Size.pdf#page=1", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ga.decal.caps.priority_groups + if not p.in_effect: + return np.ones_like(spm_unit("spm_unit_size", period.this_year), dtype=bool) + person = spm_unit.members + # Groups that turn on one of the family's own children: Child Protective + # Services and court-ordered supervision (CAPS/00-7, 7.4), need to protect + # (7.15), disabilities (7.7) and Georgia's Pre-K (7.8). A child in DFCS + # custody (7.5) forms a family unit of one (CAPS/00-5, 5.4.1), which + # ga_caps_dfcs_custody_child serves, so that child doesn't place the rest of + # the family in a group. + family_child = person("ga_caps_eligible_child", period) & ~person( + "is_in_foster_care", period + ) + protective_care = person( + "receives_or_needs_protective_services", period.this_year + ) | person("is_under_court_supervision", period.this_year) + disability = person("is_disabled", period.this_year) | person( + "has_developmental_delay", period.this_year + ) + pre_k = person("ga_caps_pre_k_enrolled", period) + child_group = spm_unit.any( + family_child & (protective_care | disability | pre_k) + ) + # Groups that turn on a parent: minor parents (7.14) and student parents + # (7.16). is_full_time_student stands in for enrollment in the listed + # programs, as it does in ga_caps_activity_eligible. + minor_parent = person("age", period.this_year) <= p.minor_parent_age + student_parent = ( + person("is_full_time_student", period.this_year) + & p.student_parent_in_effect + ) + parent_group = spm_unit.any( + person("is_tax_unit_head_or_spouse", period.this_year) + & (minor_parent | student_parent) + ) + # 7.12 and Appendix A: gross applicable income against an annual chart built + # on the guideline year very_low_income_fpg_year_lag carries. Round to cents + # so floating-point noise can't move a family at the limit. + annual_income = np.round( + spm_unit("ga_caps_countable_income", period) * MONTHS_IN_YEAR, 2 + ) + size = spm_unit("ga_caps_family_size", period) + state_group = spm_unit.household("state_group_str", period.this_year) + guideline = fpg( + size, + state_group, + period, + parameters, + year_lag=p.very_low_income_fpg_year_lag, + ) + very_low_income_limit = np.round(guideline * p.very_low_income_fpg_rate, 2) + very_low_income = ( + annual_income <= very_low_income_limit + ) & p.very_low_income_in_effect + # The funding Q&A adds the homeless, domestic violence and very low income + # groups on October 1, 2016, two months after the other groups. + homeless = ( + spm_unit.household("is_homeless", period.this_year) & p.homeless_in_effect + ) + domestic_violence = ( + spm_unit("ga_caps_domestic_violence", period) + & p.domestic_violence_in_effect + ) + # is_tanf_enrolled stands in for families in TANF employment services + # (7.9); the group excludes payees outside those services, and the model + # can't tell them apart. + return ( + child_group + | parent_group + | very_low_income + | spm_unit("is_tanf_enrolled", period) + | homeless + | domestic_violence + | spm_unit("ga_caps_natural_disaster", period) + | spm_unit("ga_caps_grandparents_raising_grandchildren", period) + ) diff --git a/policyengine_us/variables/gov/states/ga/decal/caps/ga_caps.py b/policyengine_us/variables/gov/states/ga/decal/caps/ga_caps.py index d58782d2c87..7fa945c2fa4 100644 --- a/policyengine_us/variables/gov/states/ga/decal/caps/ga_caps.py +++ b/policyengine_us/variables/gov/states/ga/decal/caps/ga_caps.py @@ -12,28 +12,19 @@ class ga_caps(Variable): definition_period = MONTH defined_for = "ga_caps_eligible" reference = ( - "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=55", + # PDF pages 27, 55 + "https://caps.decal.ga.gov/assets/downloads/CAPS/0-CAPS_Policy-Manual.pdf#page=27", "https://www.decal.ga.gov/documents/attachments/CCDFStatePlan25-27.pdf#page=69", + "https://caps.decal.ga.gov/assets/downloads/CAPS/07-CAPS_Policy-Priority%20Groups.pdf#page=2", ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states.ga.decal.caps person = spm_unit.members - - max_weekly = person("ga_caps_maximum_weekly_benefit", period) - sum_max_weekly = spm_unit.sum(max_weekly) - sum_max_monthly = sum_max_weekly * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) - - expenses_monthly = spm_unit("spm_unit_pre_subsidy_childcare_expenses", period) - base_monthly = min_(expenses_monthly, sum_max_monthly) - - family_fee = spm_unit("ga_caps_family_fee", period) - net_base = max_(base_monthly - family_fee, 0) + weekly_to_monthly = WEEKS_IN_YEAR / MONTHS_IN_YEAR # CCDF Plan §4.3.3 phrases the Quality Rated bonus as a per-provider - # add-on. We don't distinguish provider rating per child at the moment, - # so we collapse to one family-level effective bonus rate weighted by - # each child's maximum weekly benefit. + # add-on. quality_rating = person("ga_caps_quality_rating", period) star_count = select( [ @@ -45,11 +36,43 @@ def formula(spm_unit, period, parameters): default=0, ) bonus_rate = p.quality_rated.bonus_rate.calc(star_count) - weighted_bonus = spm_unit.sum(max_weekly * bonus_rate) + max_weekly = person("ga_caps_maximum_weekly_benefit", period) + + # CAPS/00-5, 5.4.1 and CAPS/00-7, 7.5: each child in DFCS custody forms a + # family unit of one and owes no family fee. The SPM unit's expenses split + # evenly across its children in pre_subsidy_childcare_expenses, which sets + # each such child's share. + dfcs_child = person("ga_caps_dfcs_custody_child", period) + child_expense = person("pre_subsidy_childcare_expenses", period) + dfcs_payment = spm_unit.sum( + min_(child_expense, max_weekly * weekly_to_monthly) + * (1 + bonus_rate) + * dfcs_child + ) + dfcs_expenses = spm_unit.sum(child_expense * dfcs_child) + + # The family's own case covers its other eligible children against the rest + # of the SPM unit's expenses, less the family fee. + family_eligible = spm_unit("ga_caps_family_eligible", period) + family_child = ( + person("ga_caps_eligible_child", period) + & ~person("is_in_foster_care", period) + & spm_unit.project(family_eligible) + ) + family_max_weekly = spm_unit.sum(max_weekly * family_child) + expenses = spm_unit("spm_unit_pre_subsidy_childcare_expenses", period) + family_expenses = max_(expenses - dfcs_expenses, 0) + family_base = min_(family_expenses, family_max_weekly * weekly_to_monthly) + family_fee = spm_unit("ga_caps_family_fee", period) + family_net = max_(family_base - family_fee, 0) + # We don't distinguish provider rating per child within the family's case at + # the moment, so we collapse to one effective bonus rate weighted by each + # child's maximum weekly benefit. + weighted_bonus = spm_unit.sum(max_weekly * bonus_rate * family_child) effective_bonus_rate = np.divide( weighted_bonus, - sum_max_weekly, + family_max_weekly, out=np.zeros_like(weighted_bonus), - where=sum_max_weekly > 0, + where=family_max_weekly > 0, ) - return net_base * (1 + effective_bonus_rate) + return family_net * (1 + effective_bonus_rate) + dfcs_payment diff --git a/policyengine_us/variables/gov/states/id/dhw/iccp/copay/id_iccp_copay_per_child.py b/policyengine_us/variables/gov/states/id/dhw/iccp/copay/id_iccp_copay_per_child.py index dc390581cd9..0cd3bd98477 100644 --- a/policyengine_us/variables/gov/states/id/dhw/iccp/copay/id_iccp_copay_per_child.py +++ b/policyengine_us/variables/gov/states/id/dhw/iccp/copay/id_iccp_copay_per_child.py @@ -77,6 +77,8 @@ def formula(person, period, parameters): # families below 100% FPG; the 503 sub-condition limiting it to TAFI # families in non-employment activities is not tracked at the moment. tafi = person.spm_unit("is_tanf_enrolled", period) + # This test reads the current year's guideline, while the income limits + # read the guideline year of the department's posted table (id_iccp_fpg). fpg = person.spm_unit("spm_unit_fpg", period) below_tafi_fpl = income < fpg * p.tafi_exemption_fpl_rate tafi_exempt = tafi & below_tafi_fpl diff --git a/policyengine_us/variables/gov/states/id/dhw/iccp/eligibility/id_iccp_fpg.py b/policyengine_us/variables/gov/states/id/dhw/iccp/eligibility/id_iccp_fpg.py new file mode 100644 index 00000000000..f2a7f57bb51 --- /dev/null +++ b/policyengine_us/variables/gov/states/id/dhw/iccp/eligibility/id_iccp_fpg.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class id_iccp_fpg(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "Idaho Child Care Program monthly federal poverty guideline" + defined_for = StateCode.ID + reference = "https://healthandwelfare.idaho.gov/services-programs/children-families/apply-child-care" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.id.dhw.iccp.income + size = spm_unit("spm_unit_size", period.this_year) + state_group = spm_unit.household("state_group_str", period.this_year) + annual_fpg = fpg(size, state_group, period, parameters, year_lag=p.fpg_year_lag) + return annual_fpg / MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/id/dhw/iccp/eligibility/id_iccp_income_eligible.py b/policyengine_us/variables/gov/states/id/dhw/iccp/eligibility/id_iccp_income_eligible.py index 1ef7402618b..910558f4753 100644 --- a/policyengine_us/variables/gov/states/id/dhw/iccp/eligibility/id_iccp_income_eligible.py +++ b/policyengine_us/variables/gov/states/id/dhw/iccp/eligibility/id_iccp_income_eligible.py @@ -7,14 +7,22 @@ class id_iccp_income_eligible(Variable): definition_period = MONTH label = "Income eligible for the Idaho Child Care Program" defined_for = StateCode.ID - reference = "https://adminrules.idaho.gov/rules/current/16/160612.pdf#page=7" + reference = ( + "https://adminrules.idaho.gov/rules/current/16/160612.pdf#page=7", + "https://healthandwelfare.idaho.gov/services-programs/children-families/apply-child-care", + ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states.id.dhw.iccp.income countable_income = spm_unit("id_iccp_countable_income", period) enrolled = spm_unit("id_iccp_enrolled", period) - initial_limit = ( - spm_unit("spm_unit_fpg", period) * p.fpl_rate.initial_eligibility + # The department's table rounds each limit up to a whole dollar. Round + # to cents first so floating-point noise can't push a whole-dollar limit + # up by one. + initial_limit = np.ceil( + np.round( + spm_unit("id_iccp_fpg", period) * p.fpl_rate.initial_eligibility, 2 + ) ) continuing_limit = spm_unit("hhs_smi", period) * p.smi_rate.continuing return countable_income <= where(enrolled, continuing_limit, initial_limit) diff --git a/policyengine_us/variables/gov/states/in/fssa/ccdf/copay/in_ccdf_copay.py b/policyengine_us/variables/gov/states/in/fssa/ccdf/copay/in_ccdf_copay.py index 1a14cf6e753..b7a0be5bfe9 100644 --- a/policyengine_us/variables/gov/states/in/fssa/ccdf/copay/in_ccdf_copay.py +++ b/policyengine_us/variables/gov/states/in/fssa/ccdf/copay/in_ccdf_copay.py @@ -18,7 +18,7 @@ def formula(spm_unit, period, parameters): # Income is floored at zero so a self-employment loss cannot produce a # negative copay. countable_income = max_(spm_unit("in_ccdf_countable_income", period), 0) - fpg = spm_unit("spm_unit_fpg", period) + fpg = spm_unit("in_ccdf_fpg", period) fpg_ratio = where(fpg > 0, countable_income / fpg, 0) # The sliding fee schedule also varies by years on the program (Year # 1-3 through Year 10+); we don't track program tenure at the moment, diff --git a/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_fpg.py b/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_fpg.py new file mode 100644 index 00000000000..fa91749dfb0 --- /dev/null +++ b/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_fpg.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class in_ccdf_fpg(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "Indiana CCDF monthly federal poverty guideline" + defined_for = StateCode.IN + reference = "https://www.in.gov/dA/3271c7180e/Income-Get-on-CCDF.pdf" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states["in"].fssa.ccdf.income + size = spm_unit("spm_unit_size", period.this_year) + state_group = spm_unit.household("state_group_str", period.this_year) + annual_fpg = fpg(size, state_group, period, parameters, year_lag=p.fpg_year_lag) + return annual_fpg / MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_income_eligible.py b/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_income_eligible.py index 55ee7ee1917..30a9af30ce9 100644 --- a/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_income_eligible.py +++ b/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_income_eligible.py @@ -7,7 +7,13 @@ class in_ccdf_income_eligible(Variable): label = "Indiana CCDF income eligible" definition_period = MONTH defined_for = StateCode.IN - reference = "https://www.in.gov/fssa/carefinder/files/CCDF-Policy-Manual.pdf#page=5" + reference = ( + "https://www.in.gov/fssa/carefinder/files/CCDF-Policy-Manual.pdf#page=5", + "https://www.in.gov/dA/3271c7180e/Income-Get-on-CCDF.pdf", + # PDF pages 1-2 + "https://www.in.gov/dA/7fc32972de/CCDFSlidingFeeSchedule_withCopays_2026.pdf#page=1", + "https://www.in.gov/dA/6307709ae5/ACF-118CCDFFFY2025-2027IndianaAmendment.pdf?language_id=1#page=22", + ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states["in"].fssa.ccdf.income @@ -16,8 +22,18 @@ def formula(spm_unit, period, parameters): # Initial applicants are tested against the get-on share of the # federal poverty guideline (127% through Jul 2023, 150% from Aug # 2023, 135% from Apr 2026); enrolled recipients are tested at 85% - # of the state median income. - initial_limit = spm_unit("spm_unit_fpg", period) * p.get_on_fpg_rate - continuing_limit = spm_unit("hhs_smi", period) * p.stay_on_smi_rate - income_limit = where(enrolled, continuing_limit, initial_limit) + # of the state median income. The plan allows no limit above 85% of + # the state median income, and FSSA's charts cap the get-on limit there + # for the largest families ($13,028 a month for 19 people from April + # 2026). The charts print the get-on limit to the nearest dollar, with + # half a dollar going up ($3,073.50 prints as $3,074), and round the 85% + # limit up to the next dollar ($7,618.48 prints as $7,619 for four). + # Round to cents first so floating-point noise can't move a tie. + fpg_limit = np.floor( + np.round(spm_unit("in_ccdf_fpg", period) * p.get_on_fpg_rate, 2) + 0.5 + ) + smi_limit = np.ceil( + np.round(spm_unit("in_ccdf_smi", period) * p.stay_on_smi_rate, 2) + ) + income_limit = where(enrolled, smi_limit, min_(fpg_limit, smi_limit)) return countable_income <= income_limit diff --git a/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_smi.py b/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_smi.py new file mode 100644 index 00000000000..fb5b235f974 --- /dev/null +++ b/policyengine_us/variables/gov/states/in/fssa/ccdf/eligibility/in_ccdf_smi.py @@ -0,0 +1,29 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import smi + + +class in_ccdf_smi(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "Indiana CCDF monthly state median income" + defined_for = StateCode.IN + reference = ( + # PDF pages 1-2 + "https://www.in.gov/dA/7fc32972de/CCDFSlidingFeeSchedule_withCopays_2026.pdf#page=1", + ) + + def formula(spm_unit, period, parameters): + # Each FSSA schedule pairs the guideline year it adopts with the federal + # state median income table that starts the October before. The April 5, + # 2026 schedule caps a family of four at $7,619 a month, 85% of the + # October 2025 table rounded up, and the March 2023, 2024 and 2025 + # schedules follow the same pattern. The guideline year lag therefore + # also selects the table. + p = parameters(period).gov.states["in"].fssa.ccdf.income + guideline_year = period.start.year - int(p.fpg_year_lag) + size = spm_unit("spm_unit_size", period.this_year) + state = spm_unit.household("state_code_str", period.this_year) + annual_smi = smi(size, state, f"{guideline_year - 1}-10-01", parameters) + return annual_smi / MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py index f24aa0123fc..f2c9e844339 100644 --- a/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py +++ b/policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py @@ -11,27 +11,37 @@ class md_ccs_income_eligible(Variable): reference = ( "https://regs.maryland.gov/us/md/exec/comar/13A.14.06.03", "https://mgaleg.maryland.gov/2022RS/Chapters_noln/CH_525_hb0995E.pdf#page=1", + "https://web.archive.org/web/20261009215322/https://earlychildhood.marylandpublicschools.org/child-care-providers/child-care-scholarship-program", ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states.md.msde.ccs.income countable_income = spm_unit("md_ccs_countable_income", period) - # Maryland freezes the SMI base year on a fiscal-year schedule (MSDE - # Feb 4, 2026 W&M briefing slide 21): FY2019-2022 used 2018 SMI, - # FY2023-2024 used 2021 SMI, FY2025+ uses current SMI. - if p.smi_freeze_in_effect: - size = spm_unit("spm_unit_size", period.this_year) - state = spm_unit.household("state_code_str", period.this_year) - smi_value = ( - smi(size, state, f"{p.smi_frozen_year}-10-01", parameters) - / MONTHS_IN_YEAR - ) - else: - smi_value = spm_unit("hhs_smi", period) + size = spm_unit("spm_unit_size", period.this_year) + state = spm_unit.household("state_code_str", period.this_year) + current_smi = spm_unit("hhs_smi", period) + + # Maryland holds the SMI base year on its own schedule (MSDE Feb 4, 2026 + # W&M briefing slide 21): FY2019-2022 used 2018 SMI and FY2023-2024 used + # 2021 SMI. The scales MSDE posts moved continuing families to the + # federal fiscal 2025 median on April 22, 2024 and new applicants on + # December 15, 2024, and MSDE still posts both scales in October 2026. + def monthly_smi(freeze_in_effect, frozen_year): + if freeze_in_effect: + return ( + smi(size, state, f"{frozen_year}-10-01", parameters) + / MONTHS_IN_YEAR + ) + return current_smi + + initial_smi = monthly_smi(p.smi_freeze_in_effect, p.smi_frozen_year) + continuation_smi = monthly_smi( + p.continuation_smi_freeze_in_effect, p.continuation_smi_frozen_year + ) enrolled = spm_unit("md_ccs_enrolled", period) income_limit = where( enrolled, - smi_value * p.smi_rate.continuation, - smi_value * p.smi_rate.initial, + continuation_smi * p.smi_rate.continuation, + initial_smi * p.smi_rate.initial, ) return countable_income <= income_limit diff --git a/policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_fpg.py b/policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_fpg.py new file mode 100644 index 00000000000..5210c819b13 --- /dev/null +++ b/policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_fpg.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class mo_ccs_fpg(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "Missouri Child Care Subsidy monthly federal poverty guideline" + defined_for = StateCode.MO + reference = "https://dese.mo.gov/sites/g/files/zuston521/files/media/pdf/2026/07/Income%20Elig%20_Updated%206.29.26.pdf#page=1" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.mo.dese.ccs.income + size = spm_unit("spm_unit_size", period.this_year) + state_group = spm_unit.household("state_group_str", period.this_year) + annual_fpg = fpg(size, state_group, period, parameters, year_lag=p.fpg_year_lag) + return annual_fpg / MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.py b/policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.py index dbf13b948a6..892124dc03c 100644 --- a/policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.py +++ b/policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_income_eligible.py @@ -10,25 +10,24 @@ class mo_ccs_income_eligible(Variable): reference = ( "https://web.archive.org/web/20250831220820id_/https://dese.mo.gov/childhood/quality-programs/child-care-subsidy/child-care-manual/2010/045/00", "https://www.law.cornell.edu/regulations/missouri/5-CSR-25-200-060", + "https://dese.mo.gov/sites/g/files/zuston521/files/media/pdf/2026/07/Income%20Elig%20_Updated%206.29.26.pdf#page=1", ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states.mo.dese.ccs.income.fpl_rate p_ccdf = parameters(period).gov.hhs.ccdf adjusted_income = spm_unit("mo_ccs_adjusted_income", period) - monthly_fpg = spm_unit("spm_unit_fpg", period) + monthly_fpg = spm_unit("mo_ccs_fpg", period) # New applicants use the traditional FPG limit; existing families may # qualify up to the higher transitional limit. enrolled = spm_unit("mo_ccs_enrolled", period) - fpg_limit = where( - enrolled, - monthly_fpg * p.transitional, - monthly_fpg * p.initial_eligibility, - ) + fpg_rate = where(enrolled, p.transitional, p.initial_eligibility) + # DESE's chart prints each limit to the nearest dollar. Round to cents + # first so floating-point noise can't move a tie. + fpg_limit = np.floor(np.round(monthly_fpg * fpg_rate, 2) + 0.5) # Adjusted gross income may also not exceed 85% of the state median - # income at application (Manual sec. 4.7). In practice the FPG limit is - # the binding ceiling at all realistic household sizes; the 85% SMI cap - # is a non-binding federal backstop kept for CCDF compliance and - # robustness to future FPG/SMI ratio shifts. + # income (Manual sec. 4.7), and the July 2026 chart applies the lower of + # its maximum and that amount. On that chart 85% of the median binds for + # enrolled families from ten people and for new applicants from 17. smi_limit = spm_unit("hhs_smi", period) * p_ccdf.income_limit_smi return adjusted_income <= min_(fpg_limit, smi_limit) diff --git a/policyengine_us/variables/gov/states/mo/dese/ccs/mo_ccs.py b/policyengine_us/variables/gov/states/mo/dese/ccs/mo_ccs.py index e535d7f52ac..ee5f4ac49b8 100644 --- a/policyengine_us/variables/gov/states/mo/dese/ccs/mo_ccs.py +++ b/policyengine_us/variables/gov/states/mo/dese/ccs/mo_ccs.py @@ -11,7 +11,6 @@ class mo_ccs(Variable): reference = "https://www.law.cornell.edu/regulations/missouri/5-CSR-25-200-060" def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.mo.dese.ccs # Reimbursement is paid per child at a daily rate for each day of care, # capped at the family's child care charges. person = spm_unit.members @@ -28,8 +27,5 @@ def formula(spm_unit, period, parameters): # funds the percentage "of the remaining state base rate"). Traditional # families are funded at the full rate, so the multiplier is 1 and the # order has no effect. - adjusted_income = spm_unit("mo_ccs_adjusted_income", period) - monthly_fpg = spm_unit("spm_unit_fpg", period) - fpl_ratio = where(monthly_fpg > 0, adjusted_income / monthly_fpg, 0) - funding_rate = p.transitional.funding_rate.calc(fpl_ratio) + funding_rate = spm_unit("mo_ccs_funding_rate", period) return funding_rate * max_(total_reimbursement - copay, 0) diff --git a/policyengine_us/variables/gov/states/mo/dese/ccs/mo_ccs_funding_rate.py b/policyengine_us/variables/gov/states/mo/dese/ccs/mo_ccs_funding_rate.py new file mode 100644 index 00000000000..0e700ab6868 --- /dev/null +++ b/policyengine_us/variables/gov/states/mo/dese/ccs/mo_ccs_funding_rate.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * + + +class mo_ccs_funding_rate(Variable): + value_type = float + entity = SPMUnit + unit = "/1" + label = "Missouri Child Care Subsidy share of the remaining base rate funded" + definition_period = MONTH + defined_for = StateCode.MO + reference = ( + "https://web.archive.org/web/20250831220820id_/https://dese.mo.gov/childhood/quality-programs/child-care-subsidy/child-care-manual/2010/045/00", + "https://www.law.cornell.edu/regulations/missouri/5-CSR-25-200-060", + "https://dese.mo.gov/sites/g/files/zuston521/files/media/pdf/2026/07/Income%20Elig%20_Updated%206.29.26.pdf#page=1", + ) + + def formula(spm_unit, period, parameters): + # Manual 2010.045.00 funds traditional families at the full base rate and + # each Transitional Child Care level at a reduced share. DESE's chart prints + # each level's top as the nearest dollar of a multiple of the guideline, and + # income above a top falls in the next level. Round to cents first so + # floating-point noise can't move a tie. + scale = parameters(period).gov.states.mo.dese.ccs.transitional.funding_rate + adjusted_income = spm_unit("mo_ccs_adjusted_income", period) + monthly_fpg = spm_unit("mo_ccs_fpg", period) + funding_rate = np.full_like(adjusted_income, scale.amounts[0]) + for threshold, amount in zip(scale.thresholds[1:], scale.amounts[1:]): + level_top = np.floor(np.round(monthly_fpg * threshold, 2) + 0.5) + funding_rate = where(adjusted_income > level_top, amount, funding_rate) + return funding_rate diff --git a/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_enrolled.py b/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_enrolled.py index 87bc4fa548d..bf4ed8d6d00 100644 --- a/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_enrolled.py +++ b/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_enrolled.py @@ -8,6 +8,6 @@ class mt_ccap_enrolled(Variable): definition_period = MONTH defined_for = StateCode.MT reference = "https://www.law.cornell.edu/regulations/montana/Mont-Admin-r-37.80.202" - # Distinguishes a continuing recipient (at annual redetermination, eligible - # under the ARM 37.80.202(2) graduated 185% FPG limit) from a first-time - # applicant (the default, held to the 150% initial limit in 37.80.202(1)). + # Distinguishes a continuing recipient at annual redetermination, who faces + # the graduated limit, from a first-time applicant (the default), who faces + # the initial limit; gov.states.mt.dphhs.ccap.income.fpg_limit holds both. diff --git a/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_fpg.py b/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_fpg.py new file mode 100644 index 00000000000..c930ebc8f9c --- /dev/null +++ b/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_fpg.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class mt_ccap_fpg(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "Montana CCAP monthly federal poverty guideline" + defined_for = StateCode.MT + reference = "https://dphhs.mt.gov/assets/ecfsd/childcare/policymanual/SlidingFeeScale07012023.pdf#page=1" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.mt.dphhs.ccap.income + size = spm_unit("spm_unit_size", period.this_year) + state_group = spm_unit.household("state_group_str", period.this_year) + annual_fpg = fpg(size, state_group, period, parameters, year_lag=p.fpg_year_lag) + return annual_fpg / MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_income_eligible.py b/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_income_eligible.py index d5730918738..ded6470b9a7 100644 --- a/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_income_eligible.py +++ b/policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_income_eligible.py @@ -9,39 +9,31 @@ class mt_ccap_income_eligible(Variable): defined_for = StateCode.MT reference = ( "https://www.law.cornell.edu/regulations/montana/Mont-Admin-r-37.80.202", + "https://archive.legmt.gov/bills/MCA/title_0520/chapter_0020/part_0070/section_0150/0520-0020-0070-0150.html", "https://dphhs.mt.gov/assets/ecfsd/childcare/policymanual/SlidingFeeScale07012023.pdf#page=1", ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states.mt.dphhs.ccap.income countable_income = spm_unit("mt_ccap_countable_income", period) - fpg = spm_unit("spm_unit_fpg", period) - # ARM 37.80.202(1): initial eligibility for income below 150% FPG (first- - # time applicant). ARM 37.80.202(2): graduated eligibility for non-TANF - # households at annual redetermination, income below 185% FPG. We proxy "at - # redetermination / continuing recipient" with the mt_ccap_enrolled input; - # first-time applicants (the default) use the 150% initial limit. + fpg = spm_unit("mt_ccap_fpg", period) + # MCA 52-2-715(1) sets the threshold for applicants at no less than 185% + # FPG, and the Sliding Fee Scale ends Standard Eligibility at that row. + # ARM 37.80.202 still prints 150% and 185%; the statute and the scale + # govern. The scale's Graduated Eligibility runs to 200% FPG for families + # already on the program at annual redetermination. We proxy "at + # redetermination / continuing recipient" with the mt_ccap_enrolled input. # - # NOTE on the ARM (185%) vs operational Sliding Fee Scale (200% "EXIT") - # ceiling: the published scale runs its graduated tier to 200% FPG, but - # ARM 37.80.202(2)'s rule text caps graduated eligibility at 185% FPG. We - # follow the ARM rule text (gov.states.mt.dphhs.ccap.income.fpg_limit. - # graduated = 1.85). Raising it to 2.0 to match the operational scale is a - # policy question pending DPHHS confirmation, so it is documented, not - # changed. The copay scale retains its 190/195/200% brackets to mirror the - # published table even though they are unreachable at the 185% ceiling. - # - # FPG uses an exclusive `<` ("below" in the ARM text); the 85% SMI overlay - # below uses `<=` because 45 CFR 98.20(a)(2) frames it as remaining "at or - # below" 85% SMI. The two comparators intentionally differ. (The exact-cent - # FPG boundary is float32-precision sensitive since monthly income and - # monthly FPG are each annual/12; unit tests pin the +/- $1 behavior.) + # The scale prints the top income of each row to the nearest dollar, and a + # family at that income belongs to the row, so the test is at or below the + # rounded limit. Round to cents first so floating-point noise can't move a tie. enrolled = spm_unit("mt_ccap_enrolled", period) fpg_rate = where(enrolled, p.fpg_limit.graduated, p.fpg_limit.initial) - fpg_eligible = countable_income < fpg * fpg_rate + fpg_limit = np.floor(np.round(fpg * fpg_rate, 2) + 0.5) + fpg_eligible = countable_income <= fpg_limit # 85% SMI ineligibility overlay (45 CFR 98.20(a)(2) / Sliding Fee Scale). - # With the 185% FPG ceiling the FPG limit binds first for all but the - # largest households, so this rarely controls eligibility. + # The FPG limit binds first for all but the largest households, so this + # rarely controls eligibility. smi = spm_unit("hhs_smi", period) smi_eligible = countable_income <= smi * p.income_limit_smi_rate income_eligible = fpg_eligible & smi_eligible diff --git a/policyengine_us/variables/gov/states/mt/dphhs/ccap/mt_ccap_copay.py b/policyengine_us/variables/gov/states/mt/dphhs/ccap/mt_ccap_copay.py index a5b665264bd..00616891007 100644 --- a/policyengine_us/variables/gov/states/mt/dphhs/ccap/mt_ccap_copay.py +++ b/policyengine_us/variables/gov/states/mt/dphhs/ccap/mt_ccap_copay.py @@ -16,7 +16,7 @@ class mt_ccap_copay(Variable): def formula(spm_unit, period, parameters): p = parameters(period).gov.states.mt.dphhs.ccap.copayment gmi = spm_unit("mt_ccap_countable_income", period) - fpg = spm_unit("spm_unit_fpg", period) + fpg = spm_unit("mt_ccap_fpg", period) fpg_ratio = where(fpg > 0, gmi / fpg, 0) # Non-TANF families pay the greater of GMI times the sliding-scale diff --git a/policyengine_us/variables/gov/states/nv/dwss/ccdp/copay/nv_ccdp_copay.py b/policyengine_us/variables/gov/states/nv/dwss/ccdp/copay/nv_ccdp_copay.py index f7e9b80b51a..300b5659a93 100644 --- a/policyengine_us/variables/gov/states/nv/dwss/ccdp/copay/nv_ccdp_copay.py +++ b/policyengine_us/variables/gov/states/nv/dwss/ccdp/copay/nv_ccdp_copay.py @@ -8,22 +8,55 @@ class nv_ccdp_copay(Variable): label = "Nevada CCDP monthly family co-payment" definition_period = MONTH defined_for = StateCode.NV - reference = "https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/CC_PT_06-25_ANNUAL_INCOME_CHANGES_10.02.2025.pdf#page=1" + reference = ( + "https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/CC_PT_06-25_ANNUAL_INCOME_CHANGES_10.02.2025.pdf#page=1", + "https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=2", + "https://nevadachildcare.netlify.app/static/200a0b5ae99f788e8c99d6f7824dc92b/Child-Care-Updates-Parents-.pdf#page=1", + "https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=75", + ) def formula(spm_unit, period, parameters): - # Flat monthly copay keyed by income as a share of SMI, effective - # Oct 1, 2024 (State Plan Section 2.4.v); CC PT 06-25 is the Oct 1, 2025 - # annual refresh. <= 32.99% SMI -> $0; 33%-42% SMI -> $90; >42% -> $150. - p = parameters(period).gov.states.nv.dwss.ccdp.copay - # Floor income at 0 before taking the ratio: negative self-employment - # income would otherwise produce a negative ratio and the wrong band. - monthly_income = max_( - spm_unit("nv_ccdp_countable_income", period.this_year) / MONTHS_IN_YEAR, - 0, - ) - monthly_smi = spm_unit("nv_ccdp_smi", period) - smi_ratio = where(monthly_smi > 0, monthly_income / monthly_smi, 0) - copay = p.amount.calc(smi_ratio) + # Nevada's copayment has followed three dated rules: + # - July 1, 2022 through March 31, 2024: American Rescue Plan funds covered + # every family's copayment. + # - April 1 through September 30, 2024: a percent of gross income, 0% to 7%, + # from the chart effective October 1, 2023, by household size and income. + # Households above fourteen people use the fourteen-person column. + # - From October 1, 2024: a flat monthly amount by income as a share of SMI + # (State Plan Section 2.4.v): up to 33% SMI -> $0; up to 42% SMI -> $90; + # above 42% -> $150, with each band top rounded to the nearest dollar as the + # charts print it. The flat schedule also stands in for dates before July + # 2022. + ccdp = parameters(period).gov.states.nv.dwss.ccdp + p = ccdp.copay + if p.reimbursed: + return spm_unit.empty_array() + # MS 316 rounds monthly income to the nearest dollar before reading the + # chart. Countable income floors at zero, so negative self-employment + # income can't produce a negative copayment. + monthly_income = spm_unit("nv_ccdp_monthly_countable_income", period) + if p.percent_of_income.in_effect: + size = spm_unit("spm_unit_size", period.this_year) + scales = p.percent_of_income + sizes = range(1, 14) + share = select( + [size == n for n in sizes], + [scales[f"size_{n}"].calc(monthly_income) for n in sizes], + default=scales.size_14.calc(monthly_income), + ) + copay = share * monthly_income + else: + # Each threshold of the flat schedule gives, as a share of SMI, the top + # of the band below it. The charts from October 2024 print each top as + # the nearest dollar, and income above a top pays the next band. + monthly_smi = spm_unit("nv_ccdp_smi", period) + scale = p.amount + copay = np.full_like(monthly_income, scale.amounts[0]) + for threshold, amount in zip(scale.thresholds[1:], scale.amounts[1:]): + band_top = monthly_smi * threshold + if ccdp.chart_rounds_to_nearest_dollar: + band_top = np.floor(np.round(band_top, 2) + 0.5) + copay = where(monthly_income > band_top, amount, copay) # Manual MS 180/181 (Co-Payments) waives the copay for exactly three # categories: TANF/NEON referrals, CPS/foster placements, and homeless # households (plus a discretionary case-by-case waiver by the CCDP diff --git a/policyengine_us/variables/gov/states/nv/dwss/ccdp/eligibility/nv_ccdp_income_eligible.py b/policyengine_us/variables/gov/states/nv/dwss/ccdp/eligibility/nv_ccdp_income_eligible.py index e51d6f70e3a..4e7c5309a2d 100644 --- a/policyengine_us/variables/gov/states/nv/dwss/ccdp/eligibility/nv_ccdp_income_eligible.py +++ b/policyengine_us/variables/gov/states/nv/dwss/ccdp/eligibility/nv_ccdp_income_eligible.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg class nv_ccdp_income_eligible(Variable): @@ -7,24 +8,33 @@ class nv_ccdp_income_eligible(Variable): label = "Eligible for Nevada CCDP based on income" definition_period = MONTH defined_for = StateCode.NV - reference = "https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/CC_PT_06-25_ANNUAL_INCOME_CHANGES_10.02.2025.pdf#page=1" + reference = ( + "https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/CC_PT_06-25_ANNUAL_INCOME_CHANGES_10.02.2025.pdf#page=1", + "https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/CC%20PT%2007-23%20Annual%20Income%20Ceiling%20Increase%20(Public%20Distribution).pdf#page=1", + # PDF pages 50-51 + "https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/Amended%20State%20Plan.pdf#page=50", + "https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=75", + "https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Home/Features/2022-2024%20Child%20Care%20PrePrint%20Draft(1).pdf#page=45", + # PDF pages 1-2 + "https://nwlc.org/wp-content/uploads/2020/02/nevada-childcare-subsidy2019_v1.pdf#page=1", + ) def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.nv.dwss.ccdp.income - # Countable income is YEAR-defined; convert to a monthly figure to - # compare against the monthly SMI accessor. - countable_income = ( - spm_unit("nv_ccdp_countable_income", period.this_year) / MONTHS_IN_YEAR - ) + p = parameters(period).gov.states.nv.dwss.ccdp + # MS 316 compares monthly income, rounded to the nearest dollar, with the + # chart for the household's size. + countable_income = spm_unit("nv_ccdp_monthly_countable_income", period) monthly_smi = spm_unit("nv_ccdp_smi", period) enrolled = spm_unit("nv_ccdp_enrolled", period) - # New applicants must be at or below 41% SMI (intake). Enrolled families - # are redetermined at or below 49% SMI (renewal); this matches the - # published renewal income/copay chart (CC PT 06-25), whose copay bands - # top out at 49% SMI. A separate federal protection (45 CFR - # 98.21(a)(1)(ii)) bars terminating a family mid-certification until - # income exceeds 85% SMI, but we don't track certification periods at - # the moment, so the 85% mid-period ceiling is not modeled. + # New applicants face smi_intake and enrolled families face smi_renewal, both + # dated. From October 1, 2024 they are 41% and 49% of SMI, which match the + # published charts (CC PT 06-25 and the October 2026 transmittal). From July 1, + # 2022 through September 2024 both were 85%: the FFY 2022-2024 plan builds the + # July 2022 limits on the fiscal year 2023 table (smi_year_lag), and CC PT + # 07-23 prints the October 2023 ceiling. Since October 2024 a separate federal protection + # (45 CFR 98.21(a)(1)(ii)) bars terminating a family mid-certification until + # income exceeds 85% SMI, but we don't track certification periods at the + # moment, so the 85% mid-period ceiling is not modeled. # MS 216.4.3.1 (Foster) and MS 216.4.4.1 (CPS) treat a foster or CPS # child as a household of one and do NOT count the traditional # household's income ("Income received by the traditional household is @@ -34,5 +44,35 @@ def formula(spm_unit, period, parameters): # by this income test even though the program would serve them at 100% # subsidy. Their copay is still waived and their need-for-care is met via # the protective-care pathway in nv_ccdp_copay / nv_ccdp_activity_eligible. - income_limit = monthly_smi * where(enrolled, p.smi_renewal, p.smi_intake) + share = where(enrolled, p.income.smi_renewal, p.income.smi_intake) + income_limit = monthly_smi * share + # The charts from October 2024 print each limit as the nearest dollar. + if p.chart_rounds_to_nearest_dollar: + income_limit = np.floor(np.round(income_limit, 2) + 0.5) + fpg_intake = p.income.fpg_intake + if fpg_intake.in_effect: + # From October 2018 through June 2022 most new applicants faced 130% of + # the poverty guideline. Nevada took up each year's guideline on October 1, + # and the draft FFY 2022-2024 plan prints the October 2020 limits as the + # nearest dollar ($1,868 a month for two, from $1,867.67). NWLC reports that families + # with a child in foster care or protective services and homeless + # families still qualified at 85% of SMI. Families in contracted slots + # or wrap-around care did too, but we don't track those at the moment. + year = period.start.year + program_year = year if period.start.month >= 10 else year - 1 + size = spm_unit("spm_unit_size", period.this_year) + state_group = spm_unit.household("state_group_str", period.this_year) + monthly_fpg = ( + fpg(size, state_group, f"{program_year}-10-01", parameters) + / MONTHS_IN_YEAR + ) + fpg_limit = np.floor(np.round(monthly_fpg * fpg_intake.rate, 2) + 0.5) + person = spm_unit.members + in_protective_care = person("nv_ccdp_eligible_child", period) & ( + person("is_in_foster_care", period) + | person("receives_or_needs_protective_services", period.this_year) + ) + is_homeless = spm_unit.household("is_homeless", period.this_year) + keeps_smi_limit = enrolled | spm_unit.any(in_protective_care) | is_homeless + income_limit = where(keeps_smi_limit, income_limit, fpg_limit) return countable_income <= income_limit diff --git a/policyengine_us/variables/gov/states/nv/dwss/ccdp/income/nv_ccdp_monthly_countable_income.py b/policyengine_us/variables/gov/states/nv/dwss/ccdp/income/nv_ccdp_monthly_countable_income.py new file mode 100644 index 00000000000..2305b950788 --- /dev/null +++ b/policyengine_us/variables/gov/states/nv/dwss/ccdp/income/nv_ccdp_monthly_countable_income.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class nv_ccdp_monthly_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Nevada CCDP monthly countable income, rounded to the nearest dollar" + definition_period = MONTH + unit = USD + defined_for = StateCode.NV + reference = "https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/Child_Care_Manual_July_2024.pdf#page=75" + + def formula(spm_unit, period, parameters): + # MS 316, second step: round gross monthly income to the nearest dollar, + # with 50 cents and up rounding up. Round to cents first so floating-point + # noise from dividing the annual amount can't move a half dollar. + monthly_income = ( + spm_unit("nv_ccdp_countable_income", period.this_year) / MONTHS_IN_YEAR + ) + return np.floor(np.round(monthly_income, 2) + 0.5) diff --git a/policyengine_us/variables/gov/states/nv/dwss/ccdp/nv_ccdp_smi.py b/policyengine_us/variables/gov/states/nv/dwss/ccdp/nv_ccdp_smi.py index 2cbf74545ee..341359dd78d 100644 --- a/policyengine_us/variables/gov/states/nv/dwss/ccdp/nv_ccdp_smi.py +++ b/policyengine_us/variables/gov/states/nv/dwss/ccdp/nv_ccdp_smi.py @@ -9,19 +9,22 @@ class nv_ccdp_smi(Variable): unit = USD definition_period = MONTH defined_for = StateCode.NV - reference = "https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/ACF-118_CCDF_FFY_2025-2027_For_Nevada__3.pdf#page=36" + reference = ( + "https://www.dss.nv.gov/siteassets/dwss.nv.gov/content/care/ACF-118_CCDF_FFY_2025-2027_For_Nevada__3.pdf#page=36", + # PDF pages 50-51 + "https://dwss.nv.gov/uploadedFiles/dwssnvgov/content/Care/Amended%20State%20Plan.pdf#page=50", + ) def formula(spm_unit, period, parameters): # Nevada keys income eligibility and copays to State Median Income (not # the federal poverty guideline). The income chart updates annually on - # October 1, so select the SMI table in effect for that program year. + # October 1, so select the SMI table in effect for that program year, + # shifted by smi_year_lag where a chart takes up a table early. + p = parameters(period).gov.states.nv.dwss.ccdp.income year = period.start.year - month = period.start.month - if month >= 10: - instant_str = f"{year}-10-01" - else: - instant_str = f"{year - 1}-10-01" + program_year = year if period.start.month >= 10 else year - 1 + table_year = program_year - int(p.smi_year_lag) size = spm_unit("spm_unit_size", period.this_year) state = spm_unit.household("state_code_str", period.this_year) - annual_smi = smi(size, state, instant_str, parameters) + annual_smi = smi(size, state, f"{table_year}-10-01", parameters) return annual_smi / MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp.py b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp.py new file mode 100644 index 00000000000..67146f49ffd --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class oh_ccvp(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "Ohio Child Care Choice Voucher Program monthly payment" + definition_period = MONTH + defined_for = "oh_ccvp_eligible" + reference = ( + # PDF pages 2, 4 + "https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_36.pdf#page=2", + ) + + def formula(spm_unit, period, parameters): + # Procedure Letter 36: the voucher pays one program per child each + # month, and that payment plus the family's portion may not exceed the + # provider's private rate, so the charge caps the payment. The voucher + # has no Publicly Funded Child Care copayment; the letter encourages + # programs to hold the family's portion to 9% of income without + # requiring it. The model leaves out the letter's initial enrollment + # payment, which programs receive on authorization on top of the + # monthly payments. + person = spm_unit.members + rate = person("oh_ccvp_rate", period) + charge = person("pre_subsidy_childcare_expenses", period) + return spm_unit.sum(min_(rate, charge)) diff --git a/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_child_age_group.py b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_child_age_group.py new file mode 100644 index 00000000000..90debf99328 --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_child_age_group.py @@ -0,0 +1,42 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.oh.dcy.ccap.oh_ccap_child_age_group import ( + OHCCAPAgeGroup, +) + + +class oh_ccvp_child_age_group(Variable): + value_type = Enum + entity = Person + possible_values = OHCCAPAgeGroup + default_value = OHCCAPAgeGroup.PRESCHOOL + definition_period = MONTH + label = "Ohio Child Care Choice Voucher Program child age group" + defined_for = StateCode.OH + reference = "https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_36.pdf#page=3" + + def formula(person, period, parameters): + # Procedure Letter 36 prices a child enrolled in, or eligible to enroll in, + # kindergarten at its school-age row, so a child past the five-year boundary + # that oh_ccap_child_age_group uses takes that row whether or not the child + # attends school, and so does a younger child already in school. The chart + # has no summer row. + p = parameters(period).gov.states.oh.dcy.ccap.age_group + age_in_months = person("age", period.this_year) * MONTHS_IN_YEAR + base_group = p.months.calc(age_in_months) + in_school = person("is_in_k12_school", period.this_year) + school_age = (base_group == OHCCAPAgeGroup.SCHOOL_AGE.index) | ( + (base_group == OHCCAPAgeGroup.PRESCHOOL.index) & in_school + ) + return select( + [ + school_age, + base_group == OHCCAPAgeGroup.INFANT.index, + base_group == OHCCAPAgeGroup.TODDLER.index, + ], + [ + OHCCAPAgeGroup.SCHOOL_AGE, + OHCCAPAgeGroup.INFANT, + OHCCAPAgeGroup.TODDLER, + ], + default=OHCCAPAgeGroup.PRESCHOOL, + ) diff --git a/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible.py b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible.py new file mode 100644 index 00000000000..f3d7f3d9bc3 --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible.py @@ -0,0 +1,53 @@ +from policyengine_us.model_api import * + + +class oh_ccvp_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for the Ohio Child Care Choice Voucher Program" + definition_period = MONTH + defined_for = StateCode.OH + reference = ( + # PDF pages 3-4 + "https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_36.pdf#page=3", + "https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners%20and%20Providers/Rules%20and%20Resources/2026/PL_45.pdf#page=2", + "https://www.lsc.ohio.gov/assets/legislation/136/hb96/en0/files/hb96-kid-bill-analysis-as-enacted-136th-general-assembly.pdf#page=10", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.oh.dcy.ccap.ccvp + if not p.in_effect: + return np.zeros_like( + spm_unit("spm_unit_size", period.this_year), dtype=bool + ) + has_eligible_child = add(spm_unit, period, ["oh_ccvp_eligible_child"]) > 0 + # H.B. 96, Section 423.190: the family fails the income conditions for + # Publicly Funded Child Care and income does not exceed 200% of the + # poverty line. Procedure Letters 21 and 45 print this limit rounded up + # to the next whole dollar, as they print the other limits. + # Round to cents first so floating-point noise can't push an exact + # dollar up. + income_limit = np.ceil( + np.round(spm_unit("oh_ccap_fpg", period) * p.fpl_rate, 2) + ) + within_limit = spm_unit("oh_ccap_countable_income", period) <= income_limit + fails_pfcc_income_test = ~spm_unit("oh_ccap_income_eligible", period) + # Procedure Letter 36: families meet every other Publicly Funded Child + # Care requirement. + activity_eligible = spm_unit("oh_ccap_activity_eligible", period) + asset_limit = parameters(period).gov.hhs.ccdf.asset_limit + asset_eligible = ( + add(spm_unit, period.this_year, ["bank_account_assets"]) <= asset_limit + ) + # Procedure Letter 36: families eligible for Publicly Funded Child Care + # cannot use the voucher. Protective care and homeless families qualify + # for that program without its income test. + pfcc_eligible = spm_unit("oh_ccap_eligible", period) + return ( + has_eligible_child + & within_limit + & fails_pfcc_income_test + & activity_eligible + & asset_eligible + & ~pfcc_eligible + ) diff --git a/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible_child.py b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible_child.py new file mode 100644 index 00000000000..2a3490f93bb --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_eligible_child.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class oh_ccvp_eligible_child(Variable): + value_type = bool + entity = Person + label = "Eligible child for the Ohio Child Care Choice Voucher Program" + definition_period = MONTH + defined_for = StateCode.OH + reference = "https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_36.pdf#page=3" + + def formula(person, period, parameters): + # Procedure Letter 36 prices school-age children under 15, or under 18 + # with special needs, and requires families to meet the other Publicly + # Funded Child Care conditions, which include the child's immigration + # status. + p = parameters(period).gov.states.oh.dcy.ccap + age = person("age", period.this_year) + age_eligible = where( + person("oh_ccap_special_needs", period), + age < p.eligibility.special_needs_child_age_limit, + age < p.ccvp.child_age_limit, + ) + immigration_eligible = person( + "is_ccdf_immigration_eligible_child", period.this_year + ) + return age_eligible & immigration_eligible diff --git a/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_rate.py b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_rate.py new file mode 100644 index 00000000000..be10a08ca2c --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/dcy/ccap/ccvp/oh_ccvp_rate.py @@ -0,0 +1,33 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.oh.dcy.ccap.oh_ccap_rate_with_addons import ( + ohio_rate_with_addons, +) + + +class oh_ccvp_rate(Variable): + value_type = float + entity = Person + unit = USD + label = "Ohio Child Care Choice Voucher Program monthly payment rate" + definition_period = MONTH + defined_for = "oh_ccvp_eligible_child" + reference = ( + # PDF pages 2-3 + "https://dam.assets.ohio.gov/image/upload/childrenandyouth.ohio.gov/For%20Partners/Rules%20and%20Resources/2025/PL_36.pdf#page=2", + "https://www.lsc.ohio.gov/assets/legislation/136/hb96/en0/files/hb96-kid-bill-analysis-as-enacted-136th-general-assembly.pdf#page=10", + "https://codes.ohio.gov/ohio-administrative-code/rule-5180:6-1-10", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.oh.dcy.ccap.ccvp + # H.B. 96, Section 423.190, moves the voucher to the Publicly Funded + # Child Care payment rates by November 1, 2026, without the Step Up to + # Quality enhancement. The accreditation, non-traditional hours and + # special needs add-ons of 5180:6-1-10(D), (F) and (G) still apply. + if p.pfcc_rates_in_effect: + return ohio_rate_with_addons( + person, period, parameters, step_up_to_quality=False + ) + provider_type = person("oh_ccap_provider_type", period) + age_group = person("oh_ccvp_child_age_group", period) + return p.payment[provider_type][age_group] diff --git a/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_ccap_base_rate.py b/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_ccap_base_rate.py index e23d55b60fa..75e9cea2a46 100644 --- a/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_ccap_base_rate.py +++ b/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_ccap_base_rate.py @@ -13,7 +13,10 @@ class oh_ccap_base_rate(Variable): unit = USD label = "Ohio CCAP monthly maximum reimbursement rate before add-ons" definition_period = MONTH - defined_for = "oh_ccap_eligible_child" + # Both readers apply their own child test: oh_ccap_rate_with_addons for + # Publicly Funded Child Care and oh_ccvp_rate for the voucher, which also + # covers 13- and 14-year-olds. + defined_for = StateCode.OH reference = "https://codes.ohio.gov/assets/laws/administrative-code/pdfs/5180/6/1/5180$6-1-10_PH_FF_N_APP1_20251020_1028.pdf#page=1" def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_ccap_rate_with_addons.py b/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_ccap_rate_with_addons.py index d848d547033..9025054d2fd 100644 --- a/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_ccap_rate_with_addons.py +++ b/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_ccap_rate_with_addons.py @@ -1,6 +1,69 @@ from policyengine_us.model_api import * +def ohio_rate_with_addons(person, period, parameters, step_up_to_quality): + """The 5180:6-1-10 payment rate after its add-ons. + + The Child Care Choice Voucher passes step_up_to_quality=False: H.B. 96, + Section 423.190, pays it the Publicly Funded Child Care rates without the + Step Up To Quality enhancement, so paragraph (C) drops out and every rate + that builds on "(B)(1) or (C)" builds on (B)(1). + """ + # 5180:6-1-10(B)(1)-(2): the base rate for all add-ons is the lower + # of the Appendix A county rate and the provider's customary charge. + p = parameters(period).gov.states.oh.dcy.ccap.addons + base_rate = person("oh_ccap_base_rate", period) + customary_charge = person("pre_subsidy_childcare_expenses", period) + capped_base = min_(base_rate, customary_charge) + + # (C)/(D): the higher of the Step Up To Quality bonus and the + # accredited bonus is added on top of the (B)(1) base; this quality + # payment may exceed the customary charge. + quality_tier = person("oh_ccap_quality_tier", period) + is_sutq = (quality_tier != quality_tier.possible_values.NONE) & step_up_to_quality + sutq_pct = where(is_sutq, p.quality.sutq[quality_tier], 0) + sutq_rate = capped_base * (1 + sutq_pct) + is_accredited = person("oh_ccap_is_accredited", period) + accredited_pct = where(is_accredited, p.accredited, 0) + accredited_rate = capped_base * (1 + accredited_pct) + rate_after_quality = max_(sutq_rate, accredited_rate) + + # (F)/(G) refer only to the rate established under (B)(1) or (C). + # Accreditation under (D) is a separate payment and therefore is not + # compounded by the non-traditional-hours or special-needs percentage. + enhancement_base = where(is_sutq, sutq_rate, capped_base) + + non_traditional = person("oh_ccap_non_traditional_hours", period) + non_traditional_pct = where(non_traditional, p.non_traditional_hours, 0) + has_special_needs = person("oh_ccap_special_needs", period) + has_accommodations = person("oh_ccap_has_special_accommodations", period) + accommodations = has_special_needs & has_accommodations + + # (F)(1)/(G)(1): the non-traditional-hours and special-needs + # percentages are computed on the (B)(1)-or-(C) rate; per (F)(3) and + # (G)(1) these payments may not exceed the customary charge, and they + # never reduce the (C) rate already established. + percentage_add = non_traditional_pct + where( + has_special_needs & ~accommodations, p.special_needs, 0 + ) + percentage_payment = rate_after_quality + enhancement_base * percentage_add + capped_percentage_payment = max_( + rate_after_quality, + min_(percentage_payment, customary_charge), + ) + # (G)(2): approved special accommodations double the (B)(1)-or-(C) + # rate with no customary-charge cap (5180:2-16-09 approval). Any + # accreditation payment remains separate, and any non-traditional + # share stays additive. + separate_accreditation_payment = rate_after_quality - enhancement_base + accommodations_payment = ( + enhancement_base + * (p.special_needs_accommodations_multiplier + non_traditional_pct) + + separate_accreditation_payment + ) + return where(accommodations, accommodations_payment, capped_percentage_payment) + + class oh_ccap_rate_with_addons(Variable): value_type = float entity = Person @@ -14,56 +77,6 @@ class oh_ccap_rate_with_addons(Variable): ) def formula(person, period, parameters): - # 5180:6-1-10(B)(1)-(2): the base rate for all add-ons is the lower - # of the Appendix A county rate and the provider's customary charge. - p = parameters(period).gov.states.oh.dcy.ccap.addons - base_rate = person("oh_ccap_base_rate", period) - customary_charge = person("pre_subsidy_childcare_expenses", period) - capped_base = min_(base_rate, customary_charge) - - # (C)/(D): the higher of the Step Up To Quality bonus and the - # accredited bonus is added on top of the (B)(1) base; this quality - # payment may exceed the customary charge. - quality_tier = person("oh_ccap_quality_tier", period) - sutq_pct = p.quality.sutq[quality_tier] - sutq_rate = capped_base * (1 + sutq_pct) - is_accredited = person("oh_ccap_is_accredited", period) - accredited_pct = where(is_accredited, p.accredited, 0) - accredited_rate = capped_base * (1 + accredited_pct) - rate_after_quality = max_(sutq_rate, accredited_rate) - - # (F)/(G) refer only to the rate established under (B)(1) or (C). - # Accreditation under (D) is a separate payment and therefore is not - # compounded by the non-traditional-hours or special-needs percentage. - is_sutq = quality_tier != quality_tier.possible_values.NONE - enhancement_base = where(is_sutq, sutq_rate, capped_base) - - non_traditional = person("oh_ccap_non_traditional_hours", period) - non_traditional_pct = where(non_traditional, p.non_traditional_hours, 0) - has_special_needs = person("oh_ccap_special_needs", period) - has_accommodations = person("oh_ccap_has_special_accommodations", period) - accommodations = has_special_needs & has_accommodations - - # (F)(1)/(G)(1): the non-traditional-hours and special-needs - # percentages are computed on the (B)(1)-or-(C) rate; per (F)(3) and - # (G)(1) these payments may not exceed the customary charge, and they - # never reduce the (C) rate already established. - percentage_add = non_traditional_pct + where( - has_special_needs & ~accommodations, p.special_needs, 0 - ) - percentage_payment = rate_after_quality + enhancement_base * percentage_add - capped_percentage_payment = max_( - rate_after_quality, - min_(percentage_payment, customary_charge), - ) - # (G)(2): approved special accommodations double the (B)(1)-or-(C) - # rate with no customary-charge cap (5180:2-16-09 approval). Any - # accreditation payment remains separate, and any non-traditional - # share stays additive. - separate_accreditation_payment = rate_after_quality - enhancement_base - accommodations_payment = ( - enhancement_base - * (p.special_needs_accommodations_multiplier + non_traditional_pct) - + separate_accreditation_payment + return ohio_rate_with_addons( + person, period, parameters, step_up_to_quality=True ) - return where(accommodations, accommodations_payment, capped_percentage_payment) diff --git a/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_child_care_subsidies.py b/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_child_care_subsidies.py index 7715fdcaa36..b3b8f090ca5 100644 --- a/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_child_care_subsidies.py +++ b/policyengine_us/variables/gov/states/oh/dcy/ccap/oh_child_care_subsidies.py @@ -8,4 +8,4 @@ class oh_child_care_subsidies(Variable): unit = USD definition_period = YEAR defined_for = StateCode.OH - adds = ["oh_ccap"] + adds = ["oh_ccap", "oh_ccvp"] diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_fpg.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_fpg.py new file mode 100644 index 00000000000..f3f95efdfa0 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_fpg.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class wv_ccap_fpg(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "West Virginia CCAP monthly federal poverty guideline" + defined_for = StateCode.WV + reference = "https://bfa.wv.gov/media/6826/download?inline#page=1" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.wv.dhhr.ccap.income + size = spm_unit("spm_unit_size", period.this_year) + state_group = spm_unit.household("state_group_str", period.this_year) + annual_fpg = fpg(size, state_group, period, parameters, year_lag=p.fpg_year_lag) + return annual_fpg / MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_income_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_income_eligible.py index 2ff825bb907..9a0437d3558 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_income_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_income_eligible.py @@ -9,18 +9,28 @@ class wv_ccap_income_eligible(Variable): defined_for = StateCode.WV reference = ( "https://bfa.wv.gov/media/6766/download?inline#page=25", + # PDF pages 1 and 5-6 "https://bfa.wv.gov/media/6826/download?inline#page=1", ) def formula(spm_unit, period, parameters): - # NOTE: We model the Appendix A intake cap (~185% FPL). The 85% SMI - # "Over-Income Policy Exception" for enrolled recipients (Manual §4.7.1) - # is not modeled at the moment. We also don't distinguish child-only - # TANF cases (Manual §3.2.1.4 requires them to pass the FPL test) from - # full TANF — is_tanf_enrolled treats both as categorically eligible. + # NOTE: The 85% SMI "Over-Income Policy Exception" for enrolled recipients + # (Manual §4.7.1) is not modeled at the moment. We also don't distinguish + # child-only TANF cases (Manual §3.2.1.4 requires them to pass the FPL + # test) from full TANF — is_tanf_enrolled treats both as categorically + # eligible. p = parameters(period).gov.states.wv.dhhr.ccap.income countable_income = spm_unit("wv_ccap_countable_income", period) - fpg = spm_unit("spm_unit_fpg", period) - fpl_eligible = countable_income <= fpg * p.fpl_limit + # Appendix A caps intake at 185% of the guideline, and each scale stops at + # 85% of the state median income, which binds from ten people ($9,247 a + # month). Appendix A prints each limit to the nearest dollar. Round to + # cents first so floating-point noise can't move a tie. + fpl_limit = np.floor( + np.round(spm_unit("wv_ccap_fpg", period) * p.fpl_limit, 2) + 0.5 + ) + smi_limit = np.floor( + np.round(spm_unit("wv_ccap_smi", period) * p.smi_limit, 2) + 0.5 + ) + income_eligible = countable_income <= min_(fpl_limit, smi_limit) is_tanf = spm_unit("is_tanf_enrolled", period) - return is_tanf | fpl_eligible + return is_tanf | income_eligible diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_smi.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_smi.py new file mode 100644 index 00000000000..ad6025b6715 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_smi.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import smi + + +class wv_ccap_smi(Variable): + value_type = float + entity = SPMUnit + unit = USD + definition_period = MONTH + label = "West Virginia CCAP monthly state median income" + defined_for = StateCode.WV + reference = ( + # PDF pages 5-6 + "https://bfa.wv.gov/media/6826/download?inline#page=5", + ) + + def formula(spm_unit, period, parameters): + # Each federal state median income table starts on October 1. Select the + # table for the program year, shifted back by smi_year_lag while Appendix A + # keeps the October 2024 table. + p = parameters(period).gov.states.wv.dhhr.ccap.income + year = period.start.year + program_year = year if period.start.month >= 10 else year - 1 + table_year = program_year - int(p.smi_year_lag) + size = spm_unit("spm_unit_size", period.this_year) + state = spm_unit.household("state_code_str", period.this_year) + annual_smi = smi(size, state, f"{table_year}-10-01", parameters) + return annual_smi / MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_copay.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_copay.py index 5899b1d011b..79cf7a03e81 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_copay.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_copay.py @@ -20,7 +20,7 @@ def formula(spm_unit, period, parameters): # in care. Manual §6.4.3.4: capped at three youngest children. p = parameters(period).gov.states.wv.dhhr.ccap.copayment countable_income = spm_unit("wv_ccap_countable_income", period) - fpg = spm_unit("spm_unit_fpg", period) + fpg = spm_unit("wv_ccap_fpg", period) fpl_ratio = where(fpg > 0, countable_income / fpg, 0) family_size = spm_unit("spm_unit_size", period.this_year) # Look up daily fee per child from Appendix A by family size column. diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 12772c7bdde..f576529c1bc 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -300,6 +300,44 @@ candidates: and that no authority for a statewide delay before Alaska''s November 1, 2025 good-faith exemption was found (hr1_in_effect.yaml, is_snap_abawd_hr1_in_effect.py). The good-faith window is modeled separately, through the waived areas and the retained pre-HR1 exceptions.' +- id: us-al:ccdf-new-applicant-limit-june-2026 + program: child-care-assistance + years: + from: 2026 + type: calendar + question: From June 1, 2026, does a new Alabama Child Care Subsidy applicant face 180% of the poverty guideline + and a family at recertification 200%, as the FFY 2025-2027 CCDF State Plan says, or the 150% and 170% that DHR's + June 1, 2026 fact sheet prints? + sources: + - kind: plan + citation: Alabama CCDF State Plan FFY 2025-2027, 2.2.4 (initial eligibility) + url: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=26 + - kind: plan + citation: Alabama CCDF State Plan FFY 2025-2027, 2.5.2(c)(iii) (second tier) + url: https://dhr.alabama.gov/wp-content/uploads/2023/04/2025-2027-CCDF-State-Plan-with-Approval-Letter.pdf#page=39 + - kind: guidance + citation: Alabama Department of Human Resources, Child Care Fact Sheet (June 1, 2026) + url: https://dhr.alabama.gov/wp-content/uploads/2026/06/CHILD-CARE-FACT-SHEET-Jun2026-1.pdf#page=1 + readings: + statute: PolicyEngine found no statute or rule that sets either limit. Plan 2.2.4 states "The income eligibility + limit is 180% of Federal Poverty Line (FPL)", effective January 1, 2024, and 2.5.2(c)(iii) describes a second + tier that "caps at 200% FPL". + other: The June 1, 2026 fact sheet ends its initial scale at the 141-150% column, $3,331 a month for a family + of three, and its continuing scale at the 161-170% column, $3,775. + example: A family of three that applies in July 2026 with $3,500 a month qualifies at 180% (the January 2026 fact + sheet tops out at $3,998) but not under the June 2026 scale ($3,331). + pe_us: + follows: gap-fill + code: + - policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_initial.yaml + - policyengine_us/parameters/gov/states/al/dhr/ccsp/income/limit/fpl_continuing.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10670 + state: ruled + note: On 2026-11-06, PolicyEngine took the June 2026 fact sheet's limits from June 1, 2026. The fact sheet holds + the scales DHR posts for families, and it says "All new applicants must enter under the Initial Eligibility + Monthly Income Scale." The plan's limits carry an effective date of January 1, 2024, and DHR's January 2026 + fact sheet still printed them. - id: us-al:federal-tax-deduction-credit-list program: income-tax years: @@ -3450,6 +3488,52 @@ candidates: state: ruled note: 'Ruled statute-first in October 2026; confirm line 12(c)''s scope against the per-person statute and worksheet. Code not yet on main: id_grocery_credit.' +- id: us-id:iccp-initial-income-limit + program: child-care-assistance + years: + from: 2025 + type: calendar + question: Does a new Idaho Child Care Program applicant face the 175% of poverty limit in IDAPA 16.06.12.070.01, + or the 130% limit that the Department of Health and Welfare has applied since it reopened applications on January + 13, 2025? + sources: + - kind: regulation + citation: IDAPA 16.06.12.070.01, Income at Application (effective April 6, 2023) + url: https://adminrules.idaho.gov/rules/current/16/160612.pdf#page=7 + - kind: regulation + citation: IDAPA 16.06.12.705, Funding Restrictions + url: https://adminrules.idaho.gov/rules/current/16/160612.pdf#page=18 + - kind: agency-practice + citation: Idaho Department of Health and Welfare, DHW will resume applications to Idaho Child Care Program in + January (November 14, 2024) + url: https://healthandwelfare.idaho.gov/news/dhw-will-resume-applications-idaho-child-care-program-january + - kind: guidance + citation: Idaho Department of Health and Welfare, Apply for Child Care, maximum monthly income limits effective + October 2025 + url: https://healthandwelfare.idaho.gov/services-programs/children-families/apply-child-care + readings: + statute: No statute supplied. Under IDAPA 16.06.12.070.01, "When applying, a family's income cannot exceed one + hundred seventy-five percent (175%) of FPG for a family of the same size." + other: The department applies 130% to new applicants from January 13, 2025, to stay within its appropriation, + and posts $2,888 a month for a family of three from October 2025. IDAPA 16.06.12.705 lets it reduce child + care benefits when it projects a funding shortfall. + example: A family of three that applies in June 2026 with $3,000 a month of countable income qualifies under the + rule's 175% (limit $3,887) but not under the department's 130% (limit $2,888). + pe_us: + follows: gap-fill + code: + - policyengine_us/parameters/gov/states/id/dhw/iccp/income/fpl_rate/initial_eligibility.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10670 + state: ruled + note: On 2026-11-06, PolicyEngine took the department's 130%. Rule 070 lists conditions a family must meet to + be eligible, and rule 705 lets the department reduce child care benefits when it projects a funding shortfall; + the department tied the change to its appropriation. The rules' text doesn't settle whether 705 reaches the + intake limit, so the agency's reading breaks the tie. PolicyEngine has not settled whether a state rule binds + like a Treasury regulation; if it does and 070.01 reads as clear text, new applicants return to 175%. The 2026 + Legislature enacted none of S1374 (155% at application), S1419 (135%) and H0958 (175%). The department also + applies 130% at recertification, with a phase-out; the model keeps enrolled families on the 85% of state median + income limit. - id: us-id:liheap-heat-in-rent-fy2026 program: liheap years: @@ -4634,6 +4718,48 @@ candidates: state: ruled note: PR 9898 computes the base as max(0, min(Schedule D line 15, line 16)) and pins both readings' witnesses in md_capital_gains_surtax.yaml. Statute-first rule of 2026-10-19; register it once PR 9898 is on main. +- id: us-md:ccdf-new-applicant-limit-sources-differ + program: child-care-assistance + years: + from: 2026 + type: federal-fiscal + question: From October 2025, does a new Maryland Child Care Scholarship applicant face 75% of the federal fiscal + 2025 state median income, $94,026 a year for a family of three, as MSDE's scholarship page posts, or 75% of + the fiscal 2026 median, $97,094, as page 4 of MSDE's February 2026 briefing applies? + sources: + - kind: guidance + citation: MSDE, Child Care Scholarship Program, Initial Income Scale effective December 15, 2024 and Continuation + Income Scale effective April 22, 2024 (captured October 9, 2026) + url: https://web.archive.org/web/20261009215322/https://earlychildhood.marylandpublicschools.org/child-care-providers/child-care-scholarship-program + - kind: guidance + citation: MSDE, Child Care Scholarship Program briefing to the House Ways and Means Committee (February 4, 2026), + pages 4, 20 and 21 + url: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf#page=4 + readings: + statute: PolicyEngine found no statute or rule that names the median income year. COMAR 13A.14.06.03(H) prints + a dollar scale, which us-md:ccs-income-scale-regulation covers. + other: 'MSDE''s scholarship page posts the Initial Income Scale effective December 15, 2024 as the "Table used + for new applications": $94,026 a year for a family of three, 75% of the federal fiscal 2025 median. Page 20 + of the briefing says the program uses the fiscal 2025 estimates ($149,249 for four); page 4 gives $115,587 + for four, 75% of the fiscal 2026 median of $154,117.' + example: A family of three that applies in March 2026 with $95,000 a year qualifies at 75% of the fiscal 2026 + median ($97,094) but not under the posted scale ($94,026). + pe_us: + follows: gap-fill + code: + - policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_freeze_in_effect.yaml + - policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_frozen_year.yaml + - policyengine_us/parameters/gov/states/md/msde/ccs/income/continuation_smi_freeze_in_effect.yaml + - policyengine_us/parameters/gov/states/md/msde/ccs/income/continuation_smi_frozen_year.yaml + - policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10670 + state: ruled + note: On 2026-11-07, PolicyEngine took the posted scales, which MSDE applies to applications and page 20 of its + briefing describes. The model holds the fiscal 2025 median for new applicants from October 1, 2025, and for + continuing families from April 22, 2024, when the posted Continuation Income Scale ($106,563 for three) took + effect. Before this change, the model moved new applicants to the fiscal 2026 median in January 2026 and kept + continuing families on the median MSDE froze at its 2021 level until January 2025. - id: us-md:ccs-copay-flat-schedule program: child-care-assistance years: @@ -4675,6 +4801,47 @@ candidates: 2022 to May 2024 no statute is supplied. The bulletin''s amounts are maximums and some families pay $0, while the model charges the maximum, subject to the 7 percent federal cap. The parameter starts 2022-05-01; the bulletin dates the change May 23, 2022.' +- id: us-md:ccs-income-scale-regulation + program: child-care-assistance + years: + from: 2023 + type: state-fiscal + question: Does a new Maryland Child Care Scholarship applicant face the income eligibility scale in COMAR 13A.14.06.03(H), + which tops out at $60,081 a year for a family of three, or the 75% of state median income that MSDE has applied + since July 2022? + sources: + - kind: statute + citation: Md. Code, Educ. §9.5-111(d)(2) (Chapter 732 of 2023) + url: https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=ged§ion=9.5-111&enactments=false + - kind: regulation + citation: COMAR 13A.14.06.03(F)(1) and (H) + url: https://regs.maryland.gov/us/md/exec/comar/13A.14.06.03 + - kind: guidance + citation: MSDE, Child Care Scholarship Program briefing to the House Ways and Means Committee (February 4, 2026), + page 21 + url: https://mgaleg.maryland.gov/meeting_material/2026/w&m%20-%20134146885147130127%20-%20Briefing%20materials.pdf#page=21 + readings: + statute: From July 1, 2023, the Department "may not" alter the Program in effect as of January 1, 2023 to "Reduce + the income eligibility requirements", unless it first notifies four legislative committees or the Board of + Public Works approves budget reductions. + other: COMAR 13A.14.06.03(F)(1) has an applicant meet the scale in §H, which tops out at $60,081 a year for + a family of three, 65% of the federal fiscal 2018 median. Page 21 of MSDE's briefing lists 75% of the median + it froze at its 2021 level for new applicants in fiscal 2023 and 2024. + example: A family of three that applies in March 2026 with $70,000 a year qualifies under MSDE's posted scale + ($94,026) but not under COMAR's ($60,081). + pe_us: + follows: statute + code: + - policyengine_us/parameters/gov/states/md/msde/ccs/income/smi_rate/initial.yaml + - policyengine_us/variables/gov/states/md/msde/ccs/md_ccs_income_eligible.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10670 + state: ruled + note: On 2026-11-07, PolicyEngine kept MSDE's limits. On January 1, 2023, MSDE applied 75% of the median it froze + at its 2021 level, $78,628 a year for three, and a move to COMAR's scale would reduce that limit, which the + statute bars. If the Program in effect on that date means the regulation's scale, the statute doesn't reach + MSDE's higher limit, and the question turns on whether a state rule binds like a Treasury regulation, which + PolicyEngine has not settled. The model also follows MSDE from July 2022, before the statute took effect. - id: us-md:dependent-exemption-chart-10a program: income-tax years: @@ -5530,6 +5697,51 @@ candidates: prs: [] state: unreviewed note: Establish the guidance's statutory basis and reconcile M1SA with M1REF. +- id: us-mo:ccs-chart-guideline-year-2026 + program: child-care-assistance + years: + from: 2026 + type: calendar + question: Does a new Missouri Child Care Subsidy applicant in 2026 face 150% of the 2026 poverty guideline, or + 150% of the 2025 guideline, which DESE's income chart prints through 2026? + sources: + - kind: regulation + citation: 5 CSR 25-200.060(1), incorporating the Child Care Subsidy Eligibility Policy Manual revised November + 2022 + url: https://www.law.cornell.edu/regulations/missouri/5-CSR-25-200-060 + - kind: manual + citation: DESE, Child Care Subsidy Eligibility Policy Manual (revised August 2022), 4.7 (p. 7) and 11.1 (p. + 21), the copy DESE lists among its incorporated reference materials + url: https://web.archive.org/web/20250901014258/https://dese.mo.gov/sites/dese/files/media/pdf/2022/10/Manual%20CCSEPM%20FINAL_POST.pdf#page=7 + - kind: manual + citation: DESE, Child Care Manual 2010.045.00, Income Eligibility Guidelines (archived August 31, 2025) + url: https://web.archive.org/web/20250831220820id_/https://dese.mo.gov/childhood/quality-programs/child-care-subsidy/child-care-manual/2010/045/00 + - kind: guidance + citation: DESE, November 2025 Child Care Eligibility Income Guidelines and Sliding Fee Chart, updated July 1, + 2026 + url: https://dese.mo.gov/sites/g/files/zuston521/files/media/pdf/2026/07/Income%20Elig%20_Updated%206.29.26.pdf#page=1 + readings: + statute: The entry cites no statute. 5 CSR 25-200.060(1) incorporates the manual revised November 2022 and no + later amendment. In the copy DESE lists, 4.7 caps adjusted gross income at 85% of state median income at application + and says the income maximums "are listed on the Child Care Income Eligibility Guidelines and Sliding Fee Chart", + and 11.1 starts Transitional Child Care at 151% of poverty. Neither section names a guideline year. + other: Manual 2010.045.00 caps a new applicant's adjusted gross income at "150% of the federal poverty level", + and DESE's chart, headed November 2025 and updated July 1, 2026, tops the traditional scale at $3,331 a month + for a family of three, 150% of the 2025 guideline. + example: A family of three that applies in August 2026 with $3,400 a month of adjusted gross income qualifies + at 150% of the 2026 guideline ($3,415) but not under the chart ($3,331). + pe_us: + follows: gap-fill + code: + - policyengine_us/parameters/gov/states/mo/dese/ccs/income/fpg_year_lag.yaml + - policyengine_us/variables/gov/states/mo/dese/ccs/eligibility/mo_ccs_fpg.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10670 + state: ruled + note: On 2026-11-06, PolicyEngine took the chart's 2025 guideline through 2026. The incorporated manual leaves + the maximums to the chart, and neither manual names a guideline year, so the agency's chart fills the gap. The + model also keeps 4.7's 85% of state median income as an outer limit, which the July 2026 chart restates. From + 2027 a lag of one year extrapolates until DESE posts a new chart. - id: us-mo:claim-of-right-federal-tax-deduction program: income-tax years: @@ -6066,6 +6278,115 @@ candidates: state: unreviewed note: PE-US follows the manual from October 1, 2025; verify the checklist's meaning and the manual's administrative-code status. +- id: us-mt:best-beginnings-graduated-income-limit + program: child-care-assistance + years: + from: 2025 + type: calendar + question: Does a Best Beginnings family at annual redetermination keep graduated eligibility only with income + below 185% of poverty, as ARM 37.80.202(2) says, or up to 200%, as the department's sliding fee scale effective + July 1, 2025 prints? + sources: + - kind: statute + citation: MCA 52-2-715(2) (En. Sec. 2, Ch. 773, L. 2023) + url: https://archive.legmt.gov/bills/MCA/title_0520/chapter_0020/part_0070/section_0150/0520-0020-0070-0150.html + - kind: regulation + citation: ARM 37.80.202(2) + url: https://rules.mt.gov/gateway/ruleno.asp?RN=37.80.202 + - kind: guidance + citation: DPHHS, Best Beginnings Child Care Sliding Fee Scale, effective July 1, 2025 + url: https://dphhs.mt.gov/assets/ecfsd/childcare/policymanual/SlidingFeeScale07012023.pdf#page=1 + readings: + statute: MCA 52-2-715(2) has the department set a maximum qualifying income level no higher than the federal + child care and development block grant allows, and sets no graduated level. ARM 37.80.202(2) gives graduated + eligibility at redetermination to a non-TANF household with income above 150% and below 185% of the poverty + guideline. + other: The department's scale runs Graduated Eligibility from 185% to 200% of the poverty guideline for families + already on the program. + example: A family of three at redetermination in March 2026 with $4,300 a month keeps graduated eligibility under + the scale (limit $4,442) but has income above the rule's 185% (limit $4,109). + pe_us: + follows: gap-fill + code: + - policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/graduated.yaml + - policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_income_eligible.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10670 + state: ruled + note: On 2026-11-06, PolicyEngine took the department's 200% from July 1, 2025, the date of the earliest scale + it found that prints it. Once the statute moved initial eligibility to 185%, the rule's graduated band, 150% + to 185%, covers no one above the initial limit; the statute leaves the maximum qualifying income level to the + department within the federal limit, and its scale sets it. If PolicyEngine decides that a state rule binds + like a Treasury regulation, enrolled families could return to 185%. +- id: us-mt:best-beginnings-initial-income-limit + program: child-care-assistance + years: + from: 2023 + type: calendar + question: From July 1, 2023, does a new Best Beginnings applicant face ARM 37.80.202(1)'s limit of income below + 150% of poverty, or the threshold of no less than 185% that MCA 52-2-715(1) requires and the department's sliding + fee scale applies? + sources: + - kind: statute + citation: MCA 52-2-715(1) (En. Sec. 2, Ch. 773, L. 2023) + url: https://archive.legmt.gov/bills/MCA/title_0520/chapter_0020/part_0070/section_0150/0520-0020-0070-0150.html + - kind: regulation + citation: ARM 37.80.202(1) + url: https://rules.mt.gov/gateway/ruleno.asp?RN=37.80.202 + - kind: guidance + citation: DPHHS, Best Beginnings Child Care Sliding Fee Scale, effective July 1, 2025 + url: https://dphhs.mt.gov/assets/ecfsd/childcare/policymanual/SlidingFeeScale07012023.pdf#page=1 + readings: + statute: Under MCA 52-2-715(1), the department shall "set a qualifying income threshold at no less than 185% + of the federal poverty level for each family size". + other: ARM 37.80.202(1) still makes a household with income below 150% of the poverty guideline eligible. + example: A family of three that applies in March 2026 with $3,500 a month qualifies at 185% (limit $4,109) but + not under the rule's 150% (limit $3,331). + pe_us: + follows: statute + code: + - policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/initial.yaml + - policyengine_us/variables/gov/states/mt/dphhs/ccap/eligibility/mt_ccap_income_eligible.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10670 + state: ruled + note: 'On 2026-11-06, PolicyEngine took the statute''s floor, which the department''s scale applies: its Standard + Eligibility ends at 185%. The rule''s 150% predates the 2023 statute. If PolicyEngine decides that a state rule + binds like a Treasury regulation, a rule that contradicts its statute goes to the project lead case by case.' +- id: us-mt:best-beginnings-pandemic-income-limit + program: child-care-assistance + years: + from: 2021 + to: 2022 + type: calendar + question: From July 2021 through December 2022, did a new Best Beginnings applicant face ARM 37.80.202(1)'s limit + of income below 150% of poverty, or the 185% the department applied under its pandemic CCDF policies? + sources: + - kind: regulation + citation: ARM 37.80.202(1) + url: https://rules.mt.gov/gateway/ruleno.asp?RN=37.80.202 + - kind: agency-practice + citation: Montana Legislative Fiscal Division, Child Care Overview (June 2024), Policy Timeline, adapted from + DPHHS communications + url: https://leg.mt.gov/content/Publications/fiscal/2025-Biennium/Special-Topics/Childcare/Childcare-Overview-LEG-Days-June2024.pdf#page=13 + readings: + statute: No statute supplied; ARM 37.80.202(1) makes a household with income below 150% of the poverty guideline + eligible. + other: The timeline lists 185% under the department's pandemic CCDF policies from July 2021 to December 2022, + then 150% from January to June 2023. + example: A family of three that applied in June 2022 with $3,300 a month qualified at 185% (limit $3,550) but + not under the rule's 150% ($2,878.75). + pe_us: + follows: statute + code: + - policyengine_us/parameters/gov/states/mt/dphhs/ccap/income/fpg_limit/initial.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10670 + state: unreviewed + note: 'PE-US keeps the rule''s 150% for these months, and the PR leaves them unchanged. The question turns on + whether a state rule binds like a Treasury regulation, which PolicyEngine has not settled. With no statute in + the entry, the rule fills the statute slot, as in us-ak:hap-general-relief-assistance, so follows: statute means + the model follows ARM 37.80.202(1).' - id: us-mt:elderly-credit-homestead-costs program: income-tax years: @@ -11515,6 +11836,45 @@ candidates: note: 'PE-US follows the handbook: only liquid assets are tested against the limit, and the comment says the statutory home-value and vehicle-equity limits are not part of the operational test (wi_shares_asset_eligible.py). The statute-first rule requires implementing the omitted home-value and vehicle-equity limits.' +- id: us-wv:ccap-initial-income-limit + program: child-care-assistance + years: + from: 2025 + to: 2027 + type: federal-fiscal + question: Does a new West Virginia Child Care Assistance applicant face 85% of state median income, which the + FFY 2025-2027 CCDF State Plan lists as its maximum initial eligibility limit, or 185% of the poverty guideline, + which the Child Care Subsidy Policy manual and Appendix A's sliding fee scale print? + sources: + - kind: plan + citation: West Virginia CCDF State Plan FFY 2025-2027, 2.2.4(a)(i) (p. 20) + url: https://bfa.wv.gov/media/39915/download?inline#page=20 + - kind: manual + citation: West Virginia Child Care Subsidy Policy and Procedures Manual, 3.2.1, Eligibility Guidelines + url: https://bfa.wv.gov/media/6766/download?inline#page=25 + - kind: guidance + citation: West Virginia Child Care Subsidy Appendix A, Sliding Fee Scale (October 1, 2024) + url: https://bfa.wv.gov/media/6826/download?inline#page=1 + readings: + statute: No statute or rule supplied. The plan's table lists a maximum initial eligibility limit of 85% of state + median income, $5,394 a month for a family of three. + other: The manual's eligibility guidelines point to Appendix A, whose scale ends at 185% of the 2024 poverty + guideline, $3,981 a month for a family of three. + example: A family of three that applies in January 2026 with $4,500 a month qualifies under the plan's 85% of + state median income ($5,394) but not under Appendix A's 185% ($3,981). + pe_us: + follows: gap-fill + code: + - policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit.yaml + - policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_limit.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10670 + state: unreviewed + note: PE-US follows the manual and Appendix A, which the Bureau for Family Assistance links from its Child Care + Policy page. The PR changes the guideline year and adds Appendix A's own stop at 85% of state median income, + which binds from ten people ($9,247 a month), so the code takes the lower of the two limits at every size. + Check whether the plan's 85% states a limit the Bureau applies or the federal ceiling. With no statute or rule + in the entry, gap-fill means the code follows the manual and Appendix A, not the plan. - id: us-wv:claim-of-right-subtraction-authority program: income-tax years: