From f057bb7df2df898d585de8cfdbace952f61b5cb5 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 8 Apr 2026 00:32:33 -0400 Subject: [PATCH 01/16] Initial commit for WV CCAP implementation From 2b84b060ffcb5f45c06dac31cd9ccd2f931c07cc Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 8 Apr 2026 00:32:45 -0400 Subject: [PATCH 02/16] Add WV CCAP directory structure --- policyengine_us/variables/gov/states/wv/dhhr/ccap/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/__init__.py diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/__init__.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/__init__.py new file mode 100644 index 00000000000..e69de29bb2d From bc74f15ebcf5196eead5eb8b37cd9d5cd4b58e76 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 8 Apr 2026 01:45:11 -0400 Subject: [PATCH 03/16] Implement West Virginia Child Care Assistance Program (CCAP) Adds eligibility, income testing, copayment, provider rates, and benefit calculation for WV's CCDF-funded child care subsidy program. Ref #7947 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../hhs/ccdf/child_care_subsidy_programs.yaml | 1 + .../dhhr/ccap/age_group/informal_months.yaml | 23 + .../states/wv/dhhr/ccap/age_group/months.yaml | 33 + .../wv/dhhr/ccap/copayment/max_share.yaml | 11 + .../states/wv/dhhr/ccap/copayment/rate.yaml | 39 + .../dhhr/ccap/eligibility/activity_hours.yaml | 11 + .../ccap/eligibility/child_age_limit.yaml | 13 + .../dhhr/ccap/eligibility/min_parent_age.yaml | 11 + .../special_needs_child_age_limit.yaml | 13 + .../ccap/income/countable_income/sources.yaml | 25 + .../dhhr/ccap/income/fpl_limit/initial.yaml | 11 + .../dhhr/ccap/income/fpl_limit/ongoing.yaml | 13 + .../states/wv/dhhr/ccap/income/smi_rate.yaml | 13 + .../gov/states/wv/dhhr/ccap/rates/center.yaml | 39 + .../wv/dhhr/ccap/rates/family_facility.yaml | 39 + .../wv/dhhr/ccap/rates/family_home.yaml | 39 + .../wv/dhhr/ccap/rates/informal_relative.yaml | 15 + .../dhhr/ccap/rates/out_of_school_time.yaml | 11 + .../supplements/non_traditional_hours.yaml | 11 + .../dhhr/ccap/supplements/special_needs.yaml | 11 + .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 1705 +++++++++++++++++ .../gov/states/wv/dhhr/ccap/integration.yaml | 237 +++ .../dhhr/ccap/wv_ccap_child_age_category.yaml | 88 + .../states/wv/dhhr/ccap/wv_ccap_copay.yaml | 106 + .../dhhr/ccap/wv_ccap_countable_income.yaml | 75 + .../wv/dhhr/ccap/wv_ccap_daily_benefit.yaml | 98 + .../wv/dhhr/ccap/wv_ccap_daily_rate.yaml | 187 ++ .../states/wv/dhhr/ccap/wv_ccap_eligible.yaml | 166 ++ .../wv/dhhr/ccap/wv_ccap_eligible_child.yaml | 115 ++ .../wv/dhhr/ccap/wv_ccap_income_eligible.yaml | 100 + .../wv/dhhr/ccap/wv_child_care_subsidies.yaml | 31 + .../gov/states/wv/dhhr/ccap/__init__.py | 0 .../eligibility/wv_ccap_activity_eligible.py | 20 + .../dhhr/ccap/eligibility/wv_ccap_eligible.py | 32 + .../eligibility/wv_ccap_eligible_child.py | 26 + .../eligibility/wv_ccap_income_eligible.py | 27 + .../gov/states/wv/dhhr/ccap/wv_ccap.py | 27 + .../dhhr/ccap/wv_ccap_child_age_category.py | 24 + .../gov/states/wv/dhhr/ccap/wv_ccap_copay.py | 31 + .../wv/dhhr/ccap/wv_ccap_countable_income.py | 13 + .../wv/dhhr/ccap/wv_ccap_daily_benefit.py | 32 + .../states/wv/dhhr/ccap/wv_ccap_daily_rate.py | 46 + .../states/wv/dhhr/ccap/wv_ccap_enrolled.py | 9 + .../dhhr/ccap/wv_ccap_informal_age_group.py | 22 + .../ccap/wv_ccap_non_traditional_hours.py | 9 + .../wv/dhhr/ccap/wv_ccap_provider_type.py | 20 + .../wv/dhhr/ccap/wv_ccap_quality_tier.py | 18 + .../wv/dhhr/ccap/wv_child_care_subsidies.py | 11 + 48 files changed, 3657 insertions(+) create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/informal_relative.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/out_of_school_time.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/non_traditional_hours.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/special_needs.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/edge_cases.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_copay.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml delete mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/__init__.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_copay.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_enrolled.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_informal_age_group.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_non_traditional_hours.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_provider_type.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_quality_tier.py create mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.py diff --git a/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml b/policyengine_us/parameters/gov/hhs/ccdf/child_care_subsidy_programs.yaml index 4050e47c83e..378e1257acc 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 @@ -11,6 +11,7 @@ values: - nh_child_care_subsidies # New Hampshire Child Care Scholarship Program - pa_child_care_subsidies # Pennsylvania Child Care Works - ri_child_care_subsidies # Rhode Island Child Care Assistance Program + - wv_child_care_subsidies # West Virginia Child Care Assistance Program metadata: unit: list diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml new file mode 100644 index 00000000000..7f2b5dd5dd2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml @@ -0,0 +1,23 @@ +description: West Virginia defines these informal care age group boundaries in months under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: month + amount_unit: /1 + period: year + label: West Virginia CCAP informal care age group by months + reference: + - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) + href: https://bfa.wv.gov/media/6831/download?inline + +# Maps age in months to WVCCAPInformalAgeGroup enum index: +# 0 = UNDER_2 (0-23 months) +# 1 = AGE_2_AND_OVER (24+ months) +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 24 + amount: + 2024-10-01: 1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml new file mode 100644 index 00000000000..5ddb938edb6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml @@ -0,0 +1,33 @@ +description: West Virginia defines these child age group boundaries in months under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: month + amount_unit: /1 + period: year + label: West Virginia CCAP child age group by months + reference: + - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) + href: https://bfa.wv.gov/media/6831/download?inline + +# Maps age in months to WVCCAPChildAgeCategory enum index: +# 0 = INFANT (0-12 months) +# 1 = TODDLER (13-23 months) +# 2 = PRESCHOOL (2-4 years = 24-59 months) +# 3 = SCHOOL_AGE (5+ years = 60+ months) +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 13 + amount: + 2024-10-01: 1 + - threshold: + 2024-10-01: 24 + amount: + 2024-10-01: 2 + - threshold: + 2024-10-01: 60 + amount: + 2024-10-01: 3 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml new file mode 100644 index 00000000000..34d4771a127 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml @@ -0,0 +1,11 @@ +description: West Virginia limits the co-payment to this share of gross family income under the Child Care Assistance Program. +values: + 2024-10-01: 0.07 + +metadata: + unit: /1 + period: year + label: West Virginia CCAP maximum co-payment share + reference: + - title: WV CCDF State Plan FFY 2025-2027, Section 3.1 + href: https://bfa.wv.gov/media/39915/download?inline#page=39 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml new file mode 100644 index 00000000000..0d2815b8d5e --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml @@ -0,0 +1,39 @@ +description: West Virginia sets this co-payment share of income by federal poverty level ratio under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: /1 + period: year + label: West Virginia CCAP co-payment rate by FPL ratio + reference: + - title: WV Child Care Subsidy Appendix A — Sliding Fee Scale (Oct 1, 2024) + href: https://bfa.wv.gov/media/6826/download?inline + - title: WV CCDF State Plan FFY 2025-2027, Section 3.3 + href: https://bfa.wv.gov/media/39915/download?inline#page=42 + +# Simplified percentage approximation of the 176-cell sliding fee scale. +# Derived from the 3-person family column in Appendix A as a representative +# middle case. Actual daily dollar fees vary by family size; this percentage +# approximation produces reasonable copay amounts across family sizes. +# The 7% cap (max_share parameter) provides an upper bound per CCDF rules. +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 0.025 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 0.03 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 0.035 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 0.04 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml new file mode 100644 index 00000000000..b0a53338e0a --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml @@ -0,0 +1,11 @@ +description: West Virginia sets this minimum weekly activity hours for parent eligibility under the Child Care Assistance Program. +values: + 2024-10-01: 20 + +metadata: + unit: hour + period: week + label: West Virginia CCAP minimum weekly activity hours + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3 + href: https://bfa.wv.gov/media/6766/download?inline#page=18 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml new file mode 100644 index 00000000000..ba83e566b3f --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml @@ -0,0 +1,13 @@ +description: West Virginia limits child eligibility to under this age under the Child Care Assistance Program. +values: + 2024-10-01: 13 + +metadata: + unit: year + period: year + label: West Virginia CCAP child age limit + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3 + href: https://bfa.wv.gov/media/6766/download?inline#page=18 + - title: WV CCDF State Plan FFY 2025-2027, Section 2.2 + href: https://bfa.wv.gov/media/39915/download?inline#page=16 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml new file mode 100644 index 00000000000..11e1efdb4d4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml @@ -0,0 +1,11 @@ +description: West Virginia sets this minimum parent age under the Child Care Assistance Program. +values: + 2024-10-01: 18 + +metadata: + unit: year + period: year + label: West Virginia CCAP minimum parent age + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3 + href: https://bfa.wv.gov/media/6766/download?inline#page=18 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml new file mode 100644 index 00000000000..59cca2e0963 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml @@ -0,0 +1,13 @@ +description: West Virginia limits special needs child eligibility to under this age under the Child Care Assistance Program. +values: + 2024-10-01: 18 + +metadata: + unit: year + period: year + label: West Virginia CCAP special needs child age limit + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3 + href: https://bfa.wv.gov/media/6766/download?inline#page=18 + - title: WV CCDF State Plan FFY 2025-2027, Section 2.2 + href: https://bfa.wv.gov/media/39915/download?inline#page=16 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml new file mode 100644 index 00000000000..9d6f82dddaa --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml @@ -0,0 +1,25 @@ +description: West Virginia counts these income sources under the Child Care Assistance Program. +values: + 2024-10-01: + - employment_income + - self_employment_income + - social_security + - ssi + - unemployment_compensation + - workers_compensation + - pension_income + - alimony_income + - child_support_received + - dividend_income + - interest_income + - rental_income + - veterans_benefits + - military_retirement_pay + +metadata: + unit: list + period: year + label: West Virginia CCAP countable income sources + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5 + href: https://bfa.wv.gov/media/6766/download?inline#page=42 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml new file mode 100644 index 00000000000..9de0400d652 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml @@ -0,0 +1,11 @@ +description: West Virginia limits initial applicant income to this share of the federal poverty level under the Child Care Assistance Program. +values: + 2024-10-01: 1.5 + +metadata: + unit: /1 + period: year + label: West Virginia CCAP initial FPL limit + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5 + href: https://bfa.wv.gov/media/6766/download?inline#page=42 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml new file mode 100644 index 00000000000..c59fa7b8b33 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml @@ -0,0 +1,13 @@ +description: West Virginia limits ongoing recipient income to this share of the federal poverty level under the Child Care Assistance Program. +values: + 2024-10-01: 1.85 + +metadata: + unit: /1 + period: year + label: West Virginia CCAP ongoing FPL limit + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5 + href: https://bfa.wv.gov/media/6766/download?inline#page=42 + - title: WV CCDF State Plan FFY 2025-2027, Section 2.2.3 + href: https://bfa.wv.gov/media/39915/download?inline#page=20 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml new file mode 100644 index 00000000000..1b5b80411d0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml @@ -0,0 +1,13 @@ +description: West Virginia limits income to this share of the state median income under the Child Care Assistance Program. +values: + 2024-10-01: 0.85 + +metadata: + unit: /1 + period: year + label: West Virginia CCAP SMI rate + reference: + - title: WV CCDF State Plan FFY 2025-2027, Section 2.2.4 + href: https://bfa.wv.gov/media/39915/download?inline#page=20 + - title: WV 2024 State Median Income Chart + href: https://bfa.wv.gov/media/6781/download?inline diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml new file mode 100644 index 00000000000..6a6333d7904 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml @@ -0,0 +1,39 @@ +description: West Virginia provides these daily reimbursement rates for child care centers under the Child Care Assistance Program. +metadata: + period: day + unit: currency-USD + label: West Virginia CCAP child care center daily rates + breakdown: + - wv_ccap_quality_tier + - wv_ccap_child_age_category + reference: + - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) + href: https://bfa.wv.gov/media/6831/download?inline + +TIER_I: + INFANT: + 2024-10-01: 39 + TODDLER: + 2024-10-01: 36 + PRESCHOOL: + 2024-10-01: 32 + SCHOOL_AGE: + 2024-10-01: 32 +TIER_II: + INFANT: + 2024-10-01: 42 + TODDLER: + 2024-10-01: 39 + PRESCHOOL: + 2024-10-01: 35 + SCHOOL_AGE: + 2024-10-01: 35 +TIER_III: + INFANT: + 2024-10-01: 45 + TODDLER: + 2024-10-01: 42 + PRESCHOOL: + 2024-10-01: 39 + SCHOOL_AGE: + 2024-10-01: 39 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml new file mode 100644 index 00000000000..1e9876f2887 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml @@ -0,0 +1,39 @@ +description: West Virginia provides these daily reimbursement rates for family child care facilities under the Child Care Assistance Program. +metadata: + period: day + unit: currency-USD + label: West Virginia CCAP family child care facility daily rates + breakdown: + - wv_ccap_quality_tier + - wv_ccap_child_age_category + reference: + - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) + href: https://bfa.wv.gov/media/6831/download?inline + +TIER_I: + INFANT: + 2024-10-01: 35 + TODDLER: + 2024-10-01: 34 + PRESCHOOL: + 2024-10-01: 32 + SCHOOL_AGE: + 2024-10-01: 32 +TIER_II: + INFANT: + 2024-10-01: 38 + TODDLER: + 2024-10-01: 37 + PRESCHOOL: + 2024-10-01: 35 + SCHOOL_AGE: + 2024-10-01: 35 +TIER_III: + INFANT: + 2024-10-01: 41 + TODDLER: + 2024-10-01: 40 + PRESCHOOL: + 2024-10-01: 38 + SCHOOL_AGE: + 2024-10-01: 38 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml new file mode 100644 index 00000000000..0f5e67bba11 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml @@ -0,0 +1,39 @@ +description: West Virginia provides these daily reimbursement rates for family child care homes under the Child Care Assistance Program. +metadata: + period: day + unit: currency-USD + label: West Virginia CCAP family child care home daily rates + breakdown: + - wv_ccap_quality_tier + - wv_ccap_child_age_category + reference: + - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) + href: https://bfa.wv.gov/media/6831/download?inline + +TIER_I: + INFANT: + 2024-10-01: 30 + TODDLER: + 2024-10-01: 28 + PRESCHOOL: + 2024-10-01: 26 + SCHOOL_AGE: + 2024-10-01: 26 +TIER_II: + INFANT: + 2024-10-01: 33 + TODDLER: + 2024-10-01: 31 + PRESCHOOL: + 2024-10-01: 29 + SCHOOL_AGE: + 2024-10-01: 29 +TIER_III: + INFANT: + 2024-10-01: 36 + TODDLER: + 2024-10-01: 34 + PRESCHOOL: + 2024-10-01: 32 + SCHOOL_AGE: + 2024-10-01: 32 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/informal_relative.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/informal_relative.yaml new file mode 100644 index 00000000000..1053ece84d9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/informal_relative.yaml @@ -0,0 +1,15 @@ +description: West Virginia provides these daily reimbursement rates for informal or relative care under the Child Care Assistance Program. +metadata: + period: day + unit: currency-USD + label: West Virginia CCAP informal relative care daily rates + breakdown: + - wv_ccap_informal_age_group + reference: + - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) + href: https://bfa.wv.gov/media/6831/download?inline + +UNDER_2: + 2024-10-01: 7.5 +AGE_2_AND_OVER: + 2024-10-01: 6 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/out_of_school_time.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/out_of_school_time.yaml new file mode 100644 index 00000000000..b4ad81e8810 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/out_of_school_time.yaml @@ -0,0 +1,11 @@ +description: West Virginia provides this daily reimbursement rate for out of school time programs under the Child Care Assistance Program. +values: + 2024-10-01: 14.5 + +metadata: + period: day + unit: currency-USD + label: West Virginia CCAP out of school time daily rate + reference: + - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) + href: https://bfa.wv.gov/media/6831/download?inline diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/non_traditional_hours.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/non_traditional_hours.yaml new file mode 100644 index 00000000000..38c43257cf4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/non_traditional_hours.yaml @@ -0,0 +1,11 @@ +description: West Virginia provides this daily supplement for non-traditional hours care under the Child Care Assistance Program. +values: + 2024-10-01: 6 + +metadata: + period: day + unit: currency-USD + label: West Virginia CCAP non-traditional hours supplement + reference: + - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) + href: https://bfa.wv.gov/media/6831/download?inline diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/special_needs.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/special_needs.yaml new file mode 100644 index 00000000000..de494345e49 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/special_needs.yaml @@ -0,0 +1,11 @@ +description: West Virginia provides this daily supplement for children with special needs under the Child Care Assistance Program. +values: + 2024-10-01: 3 + +metadata: + period: day + unit: currency-USD + label: West Virginia CCAP special needs supplement + reference: + - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) + href: https://bfa.wv.gov/media/6831/download?inline 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 new file mode 100644 index 00000000000..225634c35d7 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/edge_cases.yaml @@ -0,0 +1,1705 @@ +# WV CCAP Edge Case Tests +# 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: FPG = 26_650/yr = 2_220.83/mo +# Family of 11: FPG = 70_650/yr = 5_887.50/mo +# WV SMI 4-person base (2024-10-01): 90_661 +# Size adjustments: first=0.52, 2nd-6th=0.16, additional=0.03 + +# ============================================================ +# Income threshold boundaries (initial applicant) +# ============================================================ + +- name: Case 1, income at exactly 149% FPL initial applicant eligible. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 149% FPL for family of 2 = 21_150 * 1.49 = 31_513.50/yr + employment_income: 31_513 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 31_513 / 12 = 2_626.08 + # 150% FPL monthly = 21_150 * 1.5 / 12 = 2_643.75 + # 2_626.08 <= 2_643.75 -> eligible + wv_ccap_income_eligible: true + +- name: Case 2, income at exactly 150% FPL initial applicant eligible. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 150% FPL for family of 2 = 21_150 * 1.5 = 31_725/yr + employment_income: 31_725 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 31_725 / 12 = 2_643.75 + # 150% FPL monthly = 2_643.75 + # 2_643.75 <= 2_643.75 -> eligible (at boundary) + wv_ccap_income_eligible: true + +- name: Case 3, income at 151% FPL initial applicant ineligible. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 151% FPL for family of 2 = 21_150 * 1.51 = 31_936.50/yr + employment_income: 31_937 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 31_937 / 12 = 2_661.42 + # 150% FPL monthly = 2_643.75 + # 2_661.42 > 2_643.75 -> ineligible (not enrolled) + wv_ccap_income_eligible: false + +# ============================================================ +# Income threshold boundaries (ongoing/enrolled recipient) +# ============================================================ + +- name: Case 4, enrolled at 184% FPL ongoing eligible. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 184% FPL for family of 2 = 21_150 * 1.84 = 38_916/yr + employment_income: 38_916 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 38_916 / 12 = 3_243 + # 185% FPL monthly = 21_150 * 1.85 / 12 = 3_260.63 + # 3_243 <= 3_260.63 -> eligible + wv_ccap_income_eligible: true + +- name: Case 5, enrolled at exactly 185% FPL ongoing eligible. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 185% FPL for family of 2 = 21_150 * 1.85 = 39_127.50/yr + employment_income: 39_127 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 39_127 / 12 = 3_260.58 + # 185% FPL monthly = 39_127.50 / 12 = 3_260.63 + # 3_260.58 <= 3_260.63 -> eligible (at boundary) + wv_ccap_income_eligible: true + +- name: Case 6, enrolled at 186% FPL ongoing ineligible. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 186% FPL for family of 2 = 21_150 * 1.86 = 39_339/yr + employment_income: 39_339 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 39_339 / 12 = 3_278.25 + # 185% FPL monthly = 39_127.50 / 12 = 3_260.63 + # 3_278.25 > 3_260.63 -> ineligible + wv_ccap_income_eligible: false + +# ============================================================ +# 85% SMI cap boundary +# ============================================================ + +- name: Case 7, income below 85% SMI but above 150% FPL for initial applicant. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # Above 150% FPL but under 85% SMI for family of 2 + # 150% FPL = 31_725; 85% SMI family of 2 = 90_661 * (0.52+0.16) * 0.85 = 52_402.06 + employment_income: 40_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 40_000 / 12 = 3_333.33 + # 150% FPL monthly = 2_643.75 + # 3_333.33 > 2_643.75 -> fails FPL test for initial applicant + wv_ccap_income_eligible: false + +- name: Case 8, enrolled income above 85% SMI ineligible despite passing FPL. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # For family of 1 (single parent, no child income): + # 85% SMI = 90_661 * 0.52 * 0.85 = 40_072.16/yr = 3_339.35/mo + # 185% FPL family of 2 = 39_127.50/yr = 3_260.63/mo + # Need income above 85% SMI but below 185% FPL + # Actually for family of 2, 85% SMI = 52_402.06 >> 185% FPL = 39_127.50 + # So SMI is not the binding constraint for small families. + # Use family of 1 (single person SPM unit with a child): + # For family of 2: 85% SMI = 52_402.06 which is very high. + # Let's test with a large family where SMI becomes binding. + # Family of 11: 85% SMI = 90_661 * (0.52 + 0.16*5 + 0.03*5) * 0.85 + # = 90_661 * 1.47 * 0.85 = 113_280.91/yr = 9_440.08/mo + # 185% FPL family of 11 = 70_650 * 1.85 = 130_702.50/yr = 10_891.88/mo + # So for large families, SMI < 185% FPL and SMI is binding. + employment_income: 114_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person4: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person5: + age: 9 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person6: + age: 11 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person7: + age: 32 + immigration_status: CITIZEN + person8: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person9: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person10: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person11: + age: 6 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] + wv_ccap_enrolled: true + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] + state_code: WV + output: + # monthly income = 114_000 / 12 = 9_500 + # 185% FPL family of 11 = 70_650 * 1.85 / 12 = 10_891.88/mo -> passes + # 85% SMI family of 11 = 90_661 * (0.52 + 0.16*5 + 0.03*5) * 0.85 / 12 + # = 90_661 * 1.47 * 0.85 / 12 = 113_280.92 / 12 = 9_440.08/mo + # 9_500 > 9_440.08 -> fails SMI cap + wv_ccap_income_eligible: false + +# ============================================================ +# Zero and very high income +# ============================================================ + +- name: Case 9, zero income eligible. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 0 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 5_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 5_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_income_eligible: true + # FPL ratio = 0 -> below 40% FPL -> $0 copay + wv_ccap_copay: 0 + # Zero income -> zero countable income + wv_ccap_countable_income: 0 + +- name: Case 10, very high income ineligible. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 500_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_income_eligible: false + wv_ccap: 0 + +# ============================================================ +# Child age boundaries +# ============================================================ + +- name: Case 11, child at exactly age 13 ineligible. + period: 2025-01 + input: + people: + person1: + age: 35 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + # Age 13 -> NOT < 13 -> ineligible (normal child) + age: 13 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, false] + wv_ccap_eligible: false + wv_ccap: 0 + +- name: Case 12, child at age 12.99 eligible. + period: 2025-01 + input: + people: + person1: + age: 35 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + # Age 12.99 -> < 13 -> eligible + age: 12.99 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, true] + +- name: Case 13, special needs child at age 17.99 eligible. + period: 2025-01 + input: + people: + person1: + age: 45 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + # Disabled child age 17.99 -> < 18 -> eligible + age: 17.99 + is_tax_unit_dependent: true + is_disabled: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, true] + +- name: Case 14, special needs child at exactly age 18 ineligible. + period: 2025-01 + input: + people: + person1: + age: 45 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + # Disabled child age 18 -> NOT < 18 -> ineligible + age: 18 + is_tax_unit_dependent: true + is_disabled: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, false] + wv_ccap_eligible: false + +# ============================================================ +# Family size boundaries +# ============================================================ + +- name: Case 15, family size 1 single parent only no eligible child. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 12_000 + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: WV + output: + # No eligible child -> not eligible + wv_ccap_eligible: false + wv_ccap: 0 + +# ============================================================ +# Copay at 40% FPL boundary (should be $0) +# ============================================================ + +- name: Case 16, income at exactly 40% FPL copay is zero. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 40% FPL family of 2 = 21_150 * 0.4 = 8_460/yr + employment_income: 8_460 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 8_460 / 12 = 705 + # FPL ratio = 705 / 1_762.50 = 0.4 + # Threshold for non-zero copay is 0.4001, so 0.4 -> 0% bracket + wv_ccap_copay: 0 + +- name: Case 17, income just above 40% FPL copay is non-zero. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # 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 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 8_475 / 12 = 706.25 + # FPL ratio = 706.25 / 1_762.50 = 0.4007 > 0.4001 -> 2.5% bracket + # copay = 706.25 * 0.025 = 17.66 + # 7% cap = 706.25 * 0.07 = 49.44 + # min(17.66, 49.44) = 17.66 + wv_ccap_copay: 17.66 + +# ============================================================ +# Copay hitting 7% cap +# ============================================================ + +- name: Case 18, copay capped at 7% of income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # High income in 4% bracket (FPL ratio > 1.5001) + # Need enrolled to pass 185% FPL threshold + # Use income at ~170% FPL to be in 4% bracket + # 21_150 * 1.7 = 35_955/yr + employment_income: 35_955 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 35_955 / 12 = 2_996.25 + # FPL ratio = 2_996.25 / 1_762.50 = 1.7 + # In 4% bracket (> 1.5001) + # uncapped copay = 2_996.25 * 0.04 = 119.85 + # 7% cap = 2_996.25 * 0.07 = 209.74 + # min(119.85, 209.74) = 119.85 (not capped in this case) + wv_ccap_copay: 119.85 + +- name: Case 19, copay rate higher than 7% cap triggers cap. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + # To trigger the 7% cap, the rate bracket must exceed 7%. + # The highest bracket is 4%, so 4% < 7% means cap never binds + # under normal operation. But we verify the cap code path works + # by testing that the 7% cap is applied correctly. + # 4% rate * income = copay; 7% * income = cap + # Since 4% < 7%, the cap never binds for this simplified scale. + # This test confirms the copay correctly equals the uncapped amount. + employment_income: 36_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_enrolled: true + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 36_000 / 12 = 3_000 + # FPL ratio = 3_000 / 1_762.50 = 1.7021 -> 4% bracket + # uncapped copay = 3_000 * 0.04 = 120 + # 7% cap = 3_000 * 0.07 = 210 + # min(120, 210) = 120 (cap does not bind) + wv_ccap_copay: 120 + +# ============================================================ +# Activity hours boundary +# ============================================================ + +- name: Case 20, parent at exactly 20 hours per week activity eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 12_000 + immigration_status: CITIZEN + weekly_hours_worked: 20 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # 20 >= 20 -> meets activity requirement + wv_ccap_activity_eligible: true + +- name: Case 21, parent at 19 hours per week activity ineligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 12_000 + immigration_status: CITIZEN + weekly_hours_worked: 19 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # 19 < 20 -> does NOT meet activity requirement + # But person1 is head/spouse, and the formula checks: + # sum(is_head_or_spouse & ~individually_eligible) == 0 + # Person1 is head, not eligible -> sum = 1 != 0 -> false + wv_ccap_activity_eligible: false + +- name: Case 22, full time student bypasses activity hours. + period: 2025-01 + input: + people: + person1: + age: 22 + employment_income: 12_000 + immigration_status: CITIZEN + weekly_hours_worked: 0 + is_full_time_student: true + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Full time student -> individually_eligible + wv_ccap_activity_eligible: true + +# ============================================================ +# Foster child copay always $0 +# ============================================================ + +- name: Case 23, foster child with income copay is zero. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 30_000 + immigration_status: CITIZEN + person2: + age: 5 + is_tax_unit_dependent: true + is_in_foster_care: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # Foster child -> copay = $0 regardless of income + # FPL ratio would be ~1.42 -> normally 3.5% bracket + # But foster child exemption overrides + wv_ccap_copay: 0 + +- name: Case 24, foster child high income copay still zero. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 31_000 + immigration_status: CITIZEN + person2: + age: 5 + is_tax_unit_dependent: true + is_in_foster_care: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_copay: 0 + +# ============================================================ +# Empty SPM unit (zero eligible children) +# ============================================================ + +- name: Case 25, adults only no eligible children. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 28 + employment_income: 15_000 + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, false] + wv_ccap_eligible: false + wv_ccap: 0 + +# ============================================================ +# All 5 provider types +# ============================================================ + +- name: Case 26, family home provider rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: FAMILY_HOME + wv_ccap_quality_tier: TIER_I + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Family Home Tier I Preschool = $26/day + wv_ccap_daily_rate: [0, 26] + +- name: Case 27, family facility provider rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: FAMILY_FACILITY + wv_ccap_quality_tier: TIER_I + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Family Facility Tier I Preschool = $32/day + wv_ccap_daily_rate: [0, 32] + +- name: Case 28, center provider rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Center Tier I Preschool = $32/day + wv_ccap_daily_rate: [0, 32] + +- name: Case 29, out of school time provider rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: OUT_OF_SCHOOL_TIME + wv_ccap_quality_tier: TIER_I + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Out of School Time = $14.50/day (flat, no tier/age variation) + wv_ccap_daily_rate: [0, 14.5] + +- name: Case 30, informal relative provider rate under 2. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: INFORMAL_RELATIVE + wv_ccap_quality_tier: TIER_I + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Informal/Relative Under 2 = $7.50/day + wv_ccap_daily_rate: [0, 7.5] + +- name: Case 31, informal relative provider rate age 2 and over. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: INFORMAL_RELATIVE + wv_ccap_quality_tier: TIER_I + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Informal/Relative 2+ = $6.00/day + wv_ccap_daily_rate: [0, 6] + +# ============================================================ +# All 3 quality tiers +# ============================================================ + +- name: Case 32, Tier II center rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_II + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Center Tier II Preschool = $35/day + wv_ccap_daily_rate: [0, 35] + +- name: Case 33, Tier III center rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_III + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Center Tier III Preschool = $39/day + wv_ccap_daily_rate: [0, 39] + +# ============================================================ +# All 4 age categories +# ============================================================ + +- name: Case 34, infant age category. + period: 2025-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + # Age 0.5 = 6 months -> INFANT (0-12 months) + age: 0.5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_child_age_category: [SCHOOL_AGE, INFANT] + +- name: Case 35, toddler age category. + period: 2025-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + # Age 1.5 = 18 months -> TODDLER (13-23 months) + age: 1.5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_child_age_category: [SCHOOL_AGE, TODDLER] + +- name: Case 36, preschool age category. + period: 2025-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + # Age 3 = 36 months -> PRESCHOOL (24-59 months) + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_child_age_category: [SCHOOL_AGE, PRESCHOOL] + +- name: Case 37, school age category. + period: 2025-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + # Age 6 = 72 months -> SCHOOL_AGE (60+ months) + age: 6 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_child_age_category: [SCHOOL_AGE, SCHOOL_AGE] + +# ============================================================ +# TANF categorical eligibility +# ============================================================ + +- name: Case 38, TANF recipient categorically income eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + # Income above 150% FPL for family of 2 but TANF enrolled + employment_income: 40_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: WV + output: + # TANF enrolled -> categorically income eligible regardless of income + wv_ccap_income_eligible: true + +# ============================================================ +# Non-traditional hours and special needs supplements +# ============================================================ + +- name: Case 39, non-traditional hours supplement adds to daily rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + wv_ccap_non_traditional_hours: true + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 12_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # Center Tier I Preschool = $32 + $6 non-trad = $38 + # daily charge = (12_000/12) / (5 * 52/12) = 1_000 / 21.67 = 46.15 + # daily benefit = min(38, 46.15) = 38 + wv_ccap_daily_benefit: [0, 38] + +- name: Case 40, both special needs and non-traditional supplements. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 8 + is_tax_unit_dependent: true + is_disabled: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + wv_ccap_non_traditional_hours: true + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 15_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 15_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # Center Tier I School Age = $32 + $3 special needs + $6 non-trad = $41 + # daily charge = (15_000/12) / (5 * 52/12) = 1_250 / 21.67 = 57.69 + # daily benefit = min(41, 57.69) = 41 + wv_ccap_daily_benefit: [0, 41] + +# ============================================================ +# Two-parent family both must meet activity requirement +# ============================================================ + +- name: Case 41, two parents both working activity eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 15_000 + immigration_status: CITIZEN + weekly_hours_worked: 25 + person2: + age: 28 + employment_income: 10_000 + immigration_status: CITIZEN + weekly_hours_worked: 20 + person3: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: WV + output: + # Both parents >= 20 hours -> both individually eligible + wv_ccap_activity_eligible: true + +- name: Case 42, two parents one not meeting hours ineligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 15_000 + immigration_status: CITIZEN + weekly_hours_worked: 25 + person2: + age: 28 + employment_income: 5_000 + immigration_status: CITIZEN + weekly_hours_worked: 15 + person3: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: WV + output: + # Person2 only 15 hours < 20 and not a student -> not individually eligible + # sum(is_head_or_spouse & ~individually_eligible) = 1 != 0 -> false + wv_ccap_activity_eligible: false + +# ============================================================ +# Benefit capped at actual expenses +# ============================================================ + +- name: Case 43, benefit capped at pre-subsidy expenses minus copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + age: 0.5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_III + childcare_days_per_week: 5 + # Low childcare expenses: rate will exceed daily charge + pre_subsidy_childcare_expenses: 3_600 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 3_600 + households: + household: + members: [person1, person2] + state_code: WV + output: + # Center Tier III Infant = $45/day + wv_ccap_daily_rate: [0, 45] + + # daily charge = (3_600/12) / (5 * 52/12) = 300 / 21.67 = 13.84 + # daily benefit = min(45, 13.84) = 13.84 + wv_ccap_daily_benefit: [0, 13.84] + + # total reimbursement = 13.84 * 21.67 = 299.89 + # FPL ratio = 2_000 / 1_762.50 = 1.1348 -> 3.5% bracket + # copay = 2_000 * 0.035 = 70 + # uncapped = max(300 - 70, 0) = 230 + # benefit = min(230, 299.89) = 230 + wv_ccap: 230 + +# ============================================================ +# Zero childcare days/expenses +# ============================================================ + +- name: Case 44, zero childcare days results in zero benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 0 + pre_subsidy_childcare_expenses: 0 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 0 + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap: 0 + +# ============================================================ +# Age category boundary: infant/toddler at 13 months +# ============================================================ + +- name: Case 45, child at exactly 12 months is infant. + period: 2025-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + # Age 1.0 = 12 months -> INFANT (threshold at 13 months for TODDLER) + age: 1.0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # 12 months < 13 threshold -> INFANT + wv_ccap_child_age_category: [SCHOOL_AGE, INFANT] + +- name: Case 46, child at exactly 24 months is preschool. + period: 2025-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + # Age 2.0 = 24 months -> PRESCHOOL (threshold at 24 months) + age: 2.0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # 24 months >= 24 threshold -> PRESCHOOL + wv_ccap_child_age_category: [SCHOOL_AGE, PRESCHOOL] + +- name: Case 47, child at 5 years is school age. + period: 2025-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + # Age 5.0 = 60 months -> SCHOOL_AGE (threshold at 60 months) + age: 5.0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # 60 months >= 60 threshold -> SCHOOL_AGE + wv_ccap_child_age_category: [SCHOOL_AGE, SCHOOL_AGE] + +# ============================================================ +# Informal age group boundaries +# ============================================================ + +- name: Case 48, informal age under 2 group. + period: 2025-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + # Age 1.5 = 18 months -> UNDER_2 + age: 1.5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # 18 months < 24 -> UNDER_2 + wv_ccap_informal_age_group: [AGE_2_AND_OVER, UNDER_2] + +- name: Case 49, informal age 2 and over group boundary. + period: 2025-01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + person2: + # Age 2.0 = 24 months -> AGE_2_AND_OVER (threshold at 24) + age: 2.0 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # 24 months >= 24 -> AGE_2_AND_OVER + wv_ccap_informal_age_group: [AGE_2_AND_OVER, AGE_2_AND_OVER] + +# ============================================================ +# Multiple children in one family +# ============================================================ + +- name: Case 50, two eligible children different ages and providers. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 20_000 + immigration_status: CITIZEN + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: FAMILY_HOME + wv_ccap_quality_tier: TIER_II + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 6_000 + person3: + age: 6 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 3 + pre_subsidy_childcare_expenses: 4_000 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2, person3] + state_code: WV + output: + wv_ccap_eligible_child: [false, true, true] + + # Person2: Family Home Tier II Infant = $33/day + # Person3: Center Tier I School Age = $32/day + wv_ccap_daily_rate: [0, 33, 32] + + # Person2 age 1 = 12 months -> INFANT + # Person3 age 6 = 72 months -> SCHOOL_AGE + wv_ccap_child_age_category: [SCHOOL_AGE, INFANT, SCHOOL_AGE] + + # FPG family of 3: 26_650 + # FPL ratio = (20_000/12) / (26_650/12) = 1_666.67 / 2_220.83 = 0.7505 + # -> 3.0% bracket (>= 0.7001) + # copay = 1_666.67 * 0.03 = 50 + wv_ccap_copay: 50 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 new file mode 100644 index 00000000000..f633a00a56f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/integration.yaml @@ -0,0 +1,237 @@ +# 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 + +- name: Case 1, basic eligible family with center care. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # === Eligibility === + wv_ccap_eligible_child: [false, true] + + # FPG family of 2: 21_150 + # 150% FPL = 31_725; monthly income = 2_000 <= 2_643.75 + wv_ccap_income_eligible: true + is_ccdf_asset_eligible: true + wv_ccap_eligible: true + + # === Age category === + # Person1 (age 35) = 420 months -> SCHOOL_AGE; Person2 (age 3) = 36 months -> PRESCHOOL + wv_ccap_child_age_category: [SCHOOL_AGE, PRESCHOOL] + + # === Daily rate === + # Center Tier I Preschool = $32/day + wv_ccap_daily_rate: [0, 32] + + # === Copay === + # FPL ratio = 2_000 / 1_762.50 = 1.1348 -> 3.5% bracket + # copay = 2_000 * 0.035 = 70 + wv_ccap_copay: 70 + + # === Daily benefit === + # daily charge = (8_000/12) / (5 * 52/12) = 666.67 / 21.67 = 30.77 + # daily benefit = min(32, 30.77) = 30.77 + wv_ccap_daily_benefit: [0, 30.77] + + # === Monthly benefit === + # total reimbursement = 30.77 * 21.67 = 666.78 + # uncapped = max(666.67 - 70, 0) = 596.67 + # benefit = min(596.67, 666.78) = 596.67 + wv_ccap: 596.67 + +- name: Case 2, low income family with zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 28 + employment_income: 6_000 + immigration_status: CITIZEN + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: FAMILY_HOME + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 6_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 6_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, true] + wv_ccap_income_eligible: true + wv_ccap_eligible: true + + # Person1 (age 28) = 336 months -> SCHOOL_AGE; Person2 (age 1) = 12 months -> INFANT + wv_ccap_child_age_category: [SCHOOL_AGE, INFANT] + + # 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 + wv_ccap_copay: 0 + + # daily charge = 500 / 21.67 = 23.07 + # daily benefit = min(30, 23.07) = 23.07 + wv_ccap_daily_benefit: [0, 23.07] + + # total reimbursement = (500/21.6667) * 21.6667 = 500 + # uncapped = max(500 - 0, 0) = 500 + # benefit = min(500, 500) = 500 + wv_ccap: 500 + +- name: Case 3, ineligible family gets zero benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 48_000 + immigration_status: CITIZEN + weekly_hours_worked: 40 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 4_000 > 150% monthly = 2_643.75 + # Not enrolled -> initial threshold applies + wv_ccap_income_eligible: false + wv_ccap_eligible: false + wv_ccap: 0 + +- name: Case 4, special needs child with supplement. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + age: 15 + is_tax_unit_dependent: true + is_disabled: true + immigration_status: CITIZEN + ssi: 0 + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_II + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 10_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # Disabled child age 15 < 18 -> eligible + wv_ccap_eligible_child: [false, true] + wv_ccap_income_eligible: true + wv_ccap_eligible: true + + # Person1 (age 40) = 480 months -> SCHOOL_AGE; Person2 (age 15) = 180 months -> SCHOOL_AGE + wv_ccap_child_age_category: [SCHOOL_AGE, SCHOOL_AGE] + + # Center Tier II School Age = $35/day + wv_ccap_daily_rate: [0, 35] + + # daily rate with special needs supplement = 35 + 3 = 38 + # daily charge = (10_000/12) / 21.67 = 833.33 / 21.67 = 38.46 + # daily benefit = min(38, 38.46) = 38 + wv_ccap_daily_benefit: [0, 38] + + # total reimbursement = 38 * 21.67 = 823.33 + # copay: FPL ratio = 2_000 / 1_762.50 = 1.1348 -> 3.5% + # copay = 2_000 * 0.035 = 70 + wv_ccap_copay: 70 + + # uncapped = max(833.33 - 70, 0) = 763.33 + # benefit = min(763.33, 823.33) = 763.33 + wv_ccap: 763.33 + +- name: Case 5, non-WV family gets zero benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 24_000 + person2: + age: 4 + is_tax_unit_dependent: true + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: VA + output: + wv_ccap: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.yaml new file mode 100644 index 00000000000..97b10133a68 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.yaml @@ -0,0 +1,88 @@ +# WV CCAP child age category tests +# Infant (0-12mo), Toddler (13-23mo), Pre-School (2-4yr), School-Age (5+yr) +# Age group is derived from age in months via bracket parameter. +# age_in_months = age * 12 (since age is YEAR-defined float) + +- name: Case 1, infant at 6 months. + period: 2025-01 + input: + people: + person1: + age: 0.5 + # 0.5 years = 6 months -> INFANT (0-12mo bracket) + households: + household: + members: [person1] + state_code: WV + output: + wv_ccap_child_age_category: INFANT + +- name: Case 2, toddler at 18 months. + period: 2025-01 + input: + people: + person1: + age: 1.5 + # 1.5 years = 18 months -> TODDLER (13-23mo bracket) + households: + household: + members: [person1] + state_code: WV + output: + wv_ccap_child_age_category: TODDLER + +- name: Case 3, preschool at 40 months. + period: 2025-01 + input: + people: + person1: + age: 3.33 + # 3.33 years ~ 40 months -> PRESCHOOL (24-59mo bracket) + households: + household: + members: [person1] + state_code: WV + output: + wv_ccap_child_age_category: PRESCHOOL + +- name: Case 4, school-age at 72 months. + period: 2025-01 + input: + people: + person1: + age: 6 + # 6 years = 72 months -> SCHOOL_AGE (60+ months bracket) + households: + household: + members: [person1] + state_code: WV + output: + wv_ccap_child_age_category: SCHOOL_AGE + +- name: Case 5, boundary at exactly 13 months. + period: 2025-01 + input: + people: + person1: + age: 1.0834 + # 1.0834 years = 13.0008 months -> TODDLER (threshold at 13) + households: + household: + members: [person1] + state_code: WV + output: + wv_ccap_child_age_category: TODDLER + +- name: Case 6, boundary at exactly 24 months. + period: 2025-01 + input: + people: + person1: + age: 2 + # 2 years = 24 months -> PRESCHOOL (threshold at 24) + households: + household: + members: [person1] + state_code: WV + output: + wv_ccap_child_age_category: PRESCHOOL 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 new file mode 100644 index 00000000000..c2e7e6a5f66 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_copay.yaml @@ -0,0 +1,106 @@ +# WV CCAP Co-payment Tests +# 2025 FPG family of 2: 21_150 + +- name: Case 1, income below 40% FPL pays zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 6_000 + person2: + age: 5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # FPL ratio = 500 / 1_762.50 = 0.2837 < 0.40 -> 0% rate + wv_ccap_copay: 0 + +- name: Case 2, mid-range income copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 18_000 + person2: + age: 5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 1_500 + # FPL ratio = 1_500 / 1_762.50 = 0.8511 -> 3% rate + # copay = 1_500 * 0.03 = 45 + wv_ccap_copay: 45 + +- name: Case 3, copay capped at 7% of income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 36_000 + person2: + age: 5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_enrolled: true + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 3_000 + # FPL ratio = 3_000 / 1_762.50 = 1.7021 -> 4% bracket rate + # uncapped copay = 3_000 * 0.04 = 120 + # 7% cap = 3_000 * 0.07 = 210 + # 120 <= 210 -> copay = 120 + wv_ccap_copay: 120 + +- name: Case 4, foster family pays zero copay. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 36_000 + person2: + age: 5 + is_in_foster_care: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_enrolled: true + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.yaml new file mode 100644 index 00000000000..9e5f7dee1fe --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.yaml @@ -0,0 +1,75 @@ +# WV CCAP countable income tests +# wv_ccap_countable_income uses adds = sources parameter list +# Sources: employment_income, self_employment_income, social_security, ssi, +# unemployment_compensation, workers_compensation, pension_income, +# alimony_income, child_support_received, dividend_income, interest_income, +# rental_income, veterans_benefits, military_retirement_pay +# Note: tanf excluded from sources to break circular dependency +# (TANF recipients are categorically eligible via is_tanf_enrolled) + +- name: Case 1, employment and unearned income counted. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + social_security: 6_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Monthly: employment 24,000/12 = 2,000 + SS 6,000/12 = 500 + # Total monthly = 2,500 + wv_ccap_countable_income: 2_500 + +- name: Case 2, SNAP is excluded from countable income. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 18_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + snap: 2_400 + households: + household: + members: [person1, person2] + state_code: WV + output: + # Monthly: employment 18,000/12 = 1,500 + # SNAP (2,400/yr) is excluded -> not counted + wv_ccap_countable_income: 1_500 + +- name: Case 3, self-employment income counted. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + self_employment_income: 36_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Monthly: self_employment 36,000/12 = 3,000 + wv_ccap_countable_income: 3_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml new file mode 100644 index 00000000000..1dd112b9262 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml @@ -0,0 +1,98 @@ +# WV CCAP daily benefit tests +# Daily benefit per child = min(rate, actual daily charge) + +- name: Case 1, rate minus copay share gives positive benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + person2: + age: 3 + is_tax_unit_dependent: true + childcare_days_per_week: 5 + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Center Tier I Preschool = $32/day + # Daily rate for this child = $32 + wv_ccap_daily_rate: [0, 32] + +- name: Case 2, zero copay means full rate as benefit. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 6_000 + person2: + age: 1 + is_tax_unit_dependent: true + childcare_days_per_week: 5 + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_II + pre_subsidy_childcare_expenses: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Below 40% FPL -> $0 copay + # Center Tier II Infant = $42/day + # Full rate as daily benefit + wv_ccap_daily_rate: [0, 42] + +- name: Case 3, non-traditional hours supplement adds $6/day. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 6_000 + person2: + age: 3 + is_tax_unit_dependent: true + childcare_days_per_week: 5 + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + wv_ccap_non_traditional_hours: true + pre_subsidy_childcare_expenses: 12_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Below 40% FPL -> $0 copay + # Center Tier I Preschool = $32/day + # Non-traditional hours supplement = $6/day + # total_rate = 32 + 6 = $38/day + # daily_charge = 12_000 / (5 * 52/12) = 12_000 / 21.6667 = $553.85/day + # min(38, 553.85) = $38/day + wv_ccap_daily_benefit: [0, 38] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.yaml new file mode 100644 index 00000000000..10d2b425883 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.yaml @@ -0,0 +1,187 @@ +# WV CCAP Daily Provider Rate Tests + +- name: Case 1, center Tier I infant rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 0.5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Infant (0-12 months), Center, Tier I = $39 + wv_ccap_daily_rate: [0, 39] + +- name: Case 2, family home Tier II toddler rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 1.5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: FAMILY_HOME + wv_ccap_quality_tier: TIER_II + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Toddler (13-23 months), Family Home, Tier II = $31 + wv_ccap_daily_rate: [0, 31] + +- name: Case 3, family facility Tier III preschool rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: FAMILY_FACILITY + wv_ccap_quality_tier: TIER_III + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Preschool (24-59 months), Family Facility, Tier III = $38 + wv_ccap_daily_rate: [0, 38] + +- name: Case 4, out of school time rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: OUT_OF_SCHOOL_TIME + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Out of School Time Tier I = $14.50 + wv_ccap_daily_rate: [0, 14.5] + +- name: Case 5, informal relative under 2 rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: INFORMAL_RELATIVE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Under 2, Informal/Relative = $7.50 + wv_ccap_daily_rate: [0, 7.5] + +- name: Case 6, informal relative age 2+ rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: INFORMAL_RELATIVE + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # 2+, Informal/Relative = $6.00 + wv_ccap_daily_rate: [0, 6] + +- name: Case 7, center Tier III school age rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_III + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # School Age (60+ months), Center, Tier III = $39 + wv_ccap_daily_rate: [0, 39] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml new file mode 100644 index 00000000000..f323973ef89 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml @@ -0,0 +1,166 @@ +# WV CCAP overall eligibility tests +# Combines: eligible child + income eligible + activity eligible + +- name: Case 1, eligible child and income and activity. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked: 30 + person2: + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_week: 40 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Child age 5 < 13 -> eligible child + # Income 24,000 < 150% FPL (31,725) -> income eligible + # Parent works 30 hrs >= 20 -> activity eligible + wv_ccap_eligible: true + +- name: Case 2, no eligible child means not eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked: 30 + person2: + age: 15 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Child age 15 >= 13, not disabled -> no eligible child + wv_ccap_eligible: false + +- name: Case 3, income too high means not eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 48_000 + weekly_hours_worked: 40 + person2: + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_week: 40 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Income 48,000 > 150% FPL (31,725) -> not income eligible + wv_ccap_eligible: false + +- name: Case 4, parent not meeting activity hours means not eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 12_000 + weekly_hours_worked: 10 + is_full_time_student: false + person2: + age: 5 + is_tax_unit_dependent: true + childcare_hours_per_week: 40 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Parent works 10 hrs < 20 minimum, not student -> not activity eligible + wv_ccap_eligible: false + +- name: Case 5, two-parent family both meeting activity requirement. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 18_000 + weekly_hours_worked: 25 + person2: + age: 28 + employment_income: 12_000 + weekly_hours_worked: 20 + person3: + age: 3 + is_tax_unit_dependent: true + childcare_hours_per_week: 40 + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: WV + output: + # Both parents work >= 20 hrs -> activity eligible + # Combined income: 30,000 < 150% FPL-3 (39,975) -> income eligible + # Child age 3 < 13 -> eligible child + wv_ccap_eligible: true + +- name: Case 6, parent under 18 means not eligible. + period: 2025-01 + input: + people: + person1: + age: 17 + employment_income: 12_000 + weekly_hours_worked: 25 + person2: + age: 1 + is_tax_unit_dependent: true + childcare_hours_per_week: 40 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # Parent age 17 < 18 -> not parent age eligible + wv_ccap_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml new file mode 100644 index 00000000000..87dbf43b0a0 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml @@ -0,0 +1,115 @@ +- name: Case 1, child under 13 who is a citizen and dependent. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, true] + +- name: Case 2, child age 13 ineligible without disability. + period: 2025-01 + input: + people: + person1: + age: 35 + person2: + age: 13 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, false] + +- name: Case 3, disabled child age 15 eligible. + period: 2025-01 + input: + people: + person1: + age: 40 + person2: + age: 15 + is_tax_unit_dependent: true + is_disabled: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, true] + +- name: Case 4, undocumented child ineligible. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_tax_unit_dependent: true + immigration_status: UNDOCUMENTED + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, false] + +- name: Case 5, non-dependent child ineligible. + period: 2025-01 + input: + people: + person1: + age: 30 + person2: + age: 8 + is_tax_unit_dependent: false + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible_child: [false, false] 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 new file mode 100644 index 00000000000..d2f8a1dcdd7 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_income_eligible.yaml @@ -0,0 +1,100 @@ +# WV CCAP Income Eligibility Tests +# 2025 FPG (Contiguous US): +# first_person = 15_650, additional = 5_500 +# Family of 2: 21_150 + +- name: Case 1, income below 150% FPL for initial applicant. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + person2: + age: 5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # FPG family of 2: 21_150 + # 150% FPL = 31_725 + # monthly income = 2_000; monthly limit = 2_643.75 + wv_ccap_income_eligible: true + +- name: Case 2, income above 150% FPL for new applicant. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 36_000 + person2: + age: 5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + # monthly income = 3_000 > 150% FPL monthly = 2_643.75 + wv_ccap_income_eligible: false + +- name: Case 3, enrolled family at 170% FPL eligible under ongoing threshold. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 36_000 + person2: + age: 5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + wv_ccap_enrolled: true + households: + household: + members: [person1, person2] + state_code: WV + output: + # 185% FPL = 39_127.50; monthly = 3_260.63 + # monthly income = 3_000 <= 3_260.63 + wv_ccap_income_eligible: true + +- name: Case 4, TANF recipients categorically eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 60_000 + person2: + age: 5 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + is_tanf_enrolled: true + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml new file mode 100644 index 00000000000..d8775136282 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml @@ -0,0 +1,31 @@ +- name: WV child care subsidies wrapper. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 35 + employment_income: 24_000 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 8_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + # wv_ccap monthly = ~596.67 -> annual = ~7_160 + wv_child_care_subsidies: 7_160 diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/__init__.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py new file mode 100644 index 00000000000..e709d9414cb --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class wv_ccap_activity_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for West Virginia CCAP based on activity requirements" + definition_period = MONTH + defined_for = StateCode.WV + reference = "https://bfa.wv.gov/media/6766/download?inline#page=18" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.wv.dhhr.ccap.eligibility + person = spm_unit.members + is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) + hours_worked = person("weekly_hours_worked", period.this_year) + meets_work_requirement = hours_worked >= p.activity_hours + is_student = person("is_full_time_student", period.this_year) + individually_eligible = meets_work_requirement | is_student + return spm_unit.sum(is_head_or_spouse & ~individually_eligible) == 0 diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py new file mode 100644 index 00000000000..9a06a0786e0 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py @@ -0,0 +1,32 @@ +from policyengine_us.model_api import * + + +class wv_ccap_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for West Virginia CCAP" + definition_period = MONTH + defined_for = StateCode.WV + reference = ( + "https://bfa.wv.gov/media/6766/download?inline#page=18", + "https://bfa.wv.gov/media/39915/download?inline#page=16", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.wv.dhhr.ccap.eligibility + has_eligible_child = add(spm_unit, period, ["wv_ccap_eligible_child"]) > 0 + income_eligible = spm_unit("wv_ccap_income_eligible", period) + asset_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) + activity_eligible = spm_unit("wv_ccap_activity_eligible", period) + person = spm_unit.members + is_dependent = person("is_tax_unit_dependent", period.this_year) + age = person("age", period.this_year) + is_caretaker = ~is_dependent + parent_age_eligible = spm_unit.any(is_caretaker & (age >= p.min_parent_age)) + return ( + has_eligible_child + & income_eligible + & asset_eligible + & activity_eligible + & parent_age_eligible + ) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py new file mode 100644 index 00000000000..263f587649f --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class wv_ccap_eligible_child(Variable): + value_type = bool + entity = Person + label = "Eligible child for West Virginia CCAP" + definition_period = MONTH + defined_for = StateCode.WV + reference = ( + "https://bfa.wv.gov/media/6766/download?inline#page=18", + "https://bfa.wv.gov/media/39915/download?inline#page=16", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.wv.dhhr.ccap.eligibility + age = person("age", period.this_year) + is_disabled = person("is_disabled", period.this_year) + age_eligible = where( + is_disabled, age < p.special_needs_child_age_limit, age < p.child_age_limit + ) + is_dependent = person("is_tax_unit_dependent", period.this_year) + immigration_eligible = person( + "is_ccdf_immigration_eligible_child", period.this_year + ) + return age_eligible & is_dependent & immigration_eligible diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_income_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_income_eligible.py new file mode 100644 index 00000000000..7dfc32fe5cd --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_income_eligible.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class wv_ccap_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for West Virginia CCAP based on income" + definition_period = MONTH + defined_for = StateCode.WV + reference = ( + "https://bfa.wv.gov/media/6766/download?inline#page=42", + "https://bfa.wv.gov/media/39915/download?inline#page=20", + ) + + def formula(spm_unit, period, parameters): + 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) + enrolled = spm_unit("wv_ccap_enrolled", period) + is_tanf = spm_unit("is_tanf_enrolled", period) + fpl_rate = where(enrolled, p.fpl_limit.ongoing, p.fpl_limit.initial) + fpl_limit = fpg * fpl_rate + smi = spm_unit("hhs_smi", period) + smi_limit = smi * p.smi_rate + return is_tanf | ( + (countable_income <= fpl_limit) & (countable_income <= smi_limit) + ) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py new file mode 100644 index 00000000000..7a911d0bd87 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class wv_ccap(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "West Virginia CCAP benefit amount" + definition_period = MONTH + defined_for = "wv_ccap_eligible" + reference = ( + "https://bfa.wv.gov/media/6766/download?inline#page=66", + "https://bfa.wv.gov/media/39915/download?inline#page=42", + ) + + def formula(spm_unit, period, parameters): + copay = spm_unit("wv_ccap_copay", period) + person = spm_unit.members + daily_benefit = person("wv_ccap_daily_benefit", period) + days_per_week = person("childcare_days_per_week", period.this_year) + days_per_month = days_per_week * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) + total_reimbursement = spm_unit.sum(daily_benefit * days_per_month) + pre_subsidy_childcare_expenses = spm_unit( + "spm_unit_pre_subsidy_childcare_expenses", period + ) + uncapped = max_(pre_subsidy_childcare_expenses - copay, 0) + return min_(uncapped, total_reimbursement) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py new file mode 100644 index 00000000000..b5ab6b364bf --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class WVCCAPChildAgeCategory(Enum): + INFANT = "Infant (0-12 months)" + TODDLER = "Toddler (13-23 months)" + PRESCHOOL = "Preschool (2-4 years)" + SCHOOL_AGE = "School Age (5+ years)" + + +class wv_ccap_child_age_category(Variable): + value_type = Enum + entity = Person + possible_values = WVCCAPChildAgeCategory + default_value = WVCCAPChildAgeCategory.PRESCHOOL + definition_period = MONTH + label = "West Virginia CCAP child age category" + defined_for = StateCode.WV + reference = "https://bfa.wv.gov/media/6831/download?inline" + + def formula(person, period, parameters): + age_in_months = person("age", period.this_year) * MONTHS_IN_YEAR + p = parameters(period).gov.states.wv.dhhr.ccap.age_group + return p.months.calc(age_in_months) 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 new file mode 100644 index 00000000000..a132fd44a9a --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_copay.py @@ -0,0 +1,31 @@ +from policyengine_us.model_api import * + + +class wv_ccap_copay(Variable): + value_type = float + entity = SPMUnit + unit = USD + label = "West Virginia CCAP family co-payment" + definition_period = MONTH + defined_for = StateCode.WV + reference = ( + "https://bfa.wv.gov/media/6826/download?inline", + "https://bfa.wv.gov/media/39915/download?inline#page=42", + ) + + def formula(spm_unit, period, parameters): + 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) + mask = fpg > 0 + fpl_ratio = np.divide( + countable_income, + fpg, + out=np.zeros_like(countable_income, dtype=float), + where=mask, + ) + has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 + copay_rate = p.rate.calc(fpl_ratio) + uncapped_copay = countable_income * copay_rate + capped_copay = min_(uncapped_copay, countable_income * p.max_share) + return where(has_foster_child, 0, capped_copay) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py new file mode 100644 index 00000000000..82b4458d15e --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class wv_ccap_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "West Virginia CCAP countable income" + definition_period = MONTH + unit = USD + defined_for = StateCode.WV + reference = "https://bfa.wv.gov/media/6766/download?inline#page=42" + + adds = "gov.states.wv.dhhr.ccap.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py new file mode 100644 index 00000000000..6aa1c1811ab --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py @@ -0,0 +1,32 @@ +from policyengine_us.model_api import * + + +class wv_ccap_daily_benefit(Variable): + value_type = float + entity = Person + unit = USD + label = "West Virginia CCAP daily benefit per child" + definition_period = MONTH + defined_for = "wv_ccap_eligible_child" + reference = "https://bfa.wv.gov/media/6766/download?inline#page=66" + + def formula(person, period, parameters): + p = parameters(period).gov.states.wv.dhhr.ccap + daily_rate = person("wv_ccap_daily_rate", period) + is_disabled = person("is_disabled", period.this_year) + special_needs_supplement = where(is_disabled, p.supplements.special_needs, 0) + non_trad = person("wv_ccap_non_traditional_hours", period) + non_trad_supplement = where(non_trad, p.supplements.non_traditional_hours, 0) + total_rate = daily_rate + special_needs_supplement + non_trad_supplement + pre_subsidy = person("pre_subsidy_childcare_expenses", period) + daily_days = person("childcare_days_per_week", period.this_year) * ( + WEEKS_IN_YEAR / MONTHS_IN_YEAR + ) + mask = daily_days > 0 + daily_charge = np.divide( + pre_subsidy, + daily_days, + out=np.zeros_like(pre_subsidy, dtype=float), + where=mask, + ) + return max_(min_(total_rate, daily_charge), 0) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py new file mode 100644 index 00000000000..9c0c364b537 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py @@ -0,0 +1,46 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.wv.dhhr.ccap.wv_ccap_provider_type import ( + WVCCAPProviderType, +) + + +class wv_ccap_daily_rate(Variable): + value_type = float + entity = Person + unit = USD + label = "West Virginia CCAP daily provider reimbursement rate" + definition_period = MONTH + defined_for = "wv_ccap_eligible_child" + reference = "https://bfa.wv.gov/media/6831/download?inline" + + def formula(person, period, parameters): + p = parameters(period).gov.states.wv.dhhr.ccap.rates + provider_type = person("wv_ccap_provider_type", period) + quality_tier = person("wv_ccap_quality_tier", period) + age_category = person("wv_ccap_child_age_category", period) + informal_age = person("wv_ccap_informal_age_group", period) + + family_home_rate = p.family_home[quality_tier][age_category] + family_facility_rate = p.family_facility[quality_tier][age_category] + center_rate = p.center[quality_tier][age_category] + out_of_school_rate = p.out_of_school_time + informal_rate = p.informal_relative[informal_age] + + types = WVCCAPProviderType + return select( + [ + provider_type == types.FAMILY_HOME, + provider_type == types.FAMILY_FACILITY, + provider_type == types.CENTER, + provider_type == types.OUT_OF_SCHOOL_TIME, + provider_type == types.INFORMAL_RELATIVE, + ], + [ + family_home_rate, + family_facility_rate, + center_rate, + out_of_school_rate, + informal_rate, + ], + default=center_rate, + ) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_enrolled.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_enrolled.py new file mode 100644 index 00000000000..38fec8b7863 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_enrolled.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class wv_ccap_enrolled(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + label = "Whether the family is currently enrolled in West Virginia CCAP" + defined_for = StateCode.WV diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_informal_age_group.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_informal_age_group.py new file mode 100644 index 00000000000..f77c7c649f6 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_informal_age_group.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class WVCCAPInformalAgeGroup(Enum): + UNDER_2 = "Under 2 years" + AGE_2_AND_OVER = "2 years and over" + + +class wv_ccap_informal_age_group(Variable): + value_type = Enum + entity = Person + possible_values = WVCCAPInformalAgeGroup + default_value = WVCCAPInformalAgeGroup.AGE_2_AND_OVER + definition_period = MONTH + label = "West Virginia CCAP informal care age group" + defined_for = StateCode.WV + reference = "https://bfa.wv.gov/media/6831/download?inline" + + def formula(person, period, parameters): + age_in_months = person("age", period.this_year) * MONTHS_IN_YEAR + p = parameters(period).gov.states.wv.dhhr.ccap.age_group + return p.informal_months.calc(age_in_months) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_non_traditional_hours.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_non_traditional_hours.py new file mode 100644 index 00000000000..177db982069 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_non_traditional_hours.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class wv_ccap_non_traditional_hours(Variable): + value_type = bool + entity = Person + definition_period = MONTH + label = "Whether child receives care during non-traditional hours for West Virginia CCAP" + defined_for = StateCode.WV diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_provider_type.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_provider_type.py new file mode 100644 index 00000000000..fd0ad73f391 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_provider_type.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class WVCCAPProviderType(Enum): + FAMILY_HOME = "Family Child Care Home" + FAMILY_FACILITY = "Family Child Care Facility" + CENTER = "Child Care Center" + OUT_OF_SCHOOL_TIME = "Out of School Time" + INFORMAL_RELATIVE = "Informal/Relative Care" + + +class wv_ccap_provider_type(Variable): + value_type = Enum + entity = Person + possible_values = WVCCAPProviderType + default_value = WVCCAPProviderType.CENTER + definition_period = MONTH + label = "West Virginia CCAP child care provider type" + defined_for = StateCode.WV + reference = "https://bfa.wv.gov/media/6831/download?inline" diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_quality_tier.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_quality_tier.py new file mode 100644 index 00000000000..8cd6a0ed39c --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_quality_tier.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class WVCCAPQualityTier(Enum): + TIER_I = "Tier I" + TIER_II = "Tier II" + TIER_III = "Tier III" + + +class wv_ccap_quality_tier(Variable): + value_type = Enum + entity = Person + possible_values = WVCCAPQualityTier + default_value = WVCCAPQualityTier.TIER_I + definition_period = MONTH + label = "West Virginia CCAP provider quality tier" + defined_for = StateCode.WV + reference = "https://bfa.wv.gov/media/6831/download?inline" diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.py new file mode 100644 index 00000000000..6730185a6cd --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class wv_child_care_subsidies(Variable): + value_type = float + entity = SPMUnit + label = "West Virginia child care subsidies" + unit = USD + definition_period = YEAR + defined_for = StateCode.WV + adds = ["wv_ccap"] From b9c937f5d3a2177d07a4b65987dfa95747df1357 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 8 Apr 2026 01:46:01 -0400 Subject: [PATCH 04/16] Add changelog and format for WV CCAP Co-Authored-By: Claude Opus 4.6 (1M context) --- changelog.d/wv-ccap.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/wv-ccap.added.md diff --git a/changelog.d/wv-ccap.added.md b/changelog.d/wv-ccap.added.md new file mode 100644 index 00000000000..a971ee4b859 --- /dev/null +++ b/changelog.d/wv-ccap.added.md @@ -0,0 +1 @@ +Implement West Virginia Child Care Assistance Program (CCAP). From 785f03c1623d9e069397be788d5322bf0fef686b Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 8 Apr 2026 02:19:55 -0400 Subject: [PATCH 05/16] Review-fix round 1: fix age boundaries, 18 rates, FPL limit, page refs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Age groups: Infant 0-24mo, Toddler 25-36mo, Preschool 37-59mo (was wrong) - 18 rate values corrected for Toddler + Preschool across 3 provider types - Initial FPL limit: 150% → 185% (150% was unsupported by documentation) - 16 page references fixed (+7 offset for Policy Manual, off-by-1 for State Plan) - 9 reference titles updated with specific subsections - Activity hours and copay references corrected to proper sections Co-Authored-By: Claude Opus 4.6 (1M context) --- .../states/wv/dhhr/ccap/age_group/months.yaml | 12 +- .../wv/dhhr/ccap/copayment/max_share.yaml | 2 +- .../states/wv/dhhr/ccap/copayment/rate.yaml | 4 +- .../dhhr/ccap/eligibility/activity_hours.yaml | 4 +- .../ccap/eligibility/child_age_limit.yaml | 4 +- .../dhhr/ccap/eligibility/min_parent_age.yaml | 4 +- .../special_needs_child_age_limit.yaml | 4 +- .../ccap/income/countable_income/sources.yaml | 4 +- .../dhhr/ccap/income/fpl_limit/initial.yaml | 8 +- .../dhhr/ccap/income/fpl_limit/ongoing.yaml | 4 +- .../gov/states/wv/dhhr/ccap/rates/center.yaml | 12 +- .../wv/dhhr/ccap/rates/family_facility.yaml | 12 +- .../wv/dhhr/ccap/rates/family_home.yaml | 12 +- .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 110 +++++++++--------- .../gov/states/wv/dhhr/ccap/integration.yaml | 14 +-- .../dhhr/ccap/wv_ccap_child_age_category.yaml | 22 ++-- .../wv/dhhr/ccap/wv_ccap_daily_benefit.yaml | 16 +-- .../wv/dhhr/ccap/wv_ccap_daily_rate.yaml | 14 ++- .../states/wv/dhhr/ccap/wv_ccap_eligible.yaml | 6 +- .../wv/dhhr/ccap/wv_ccap_income_eligible.yaml | 12 +- .../eligibility/wv_ccap_activity_eligible.py | 2 +- .../dhhr/ccap/eligibility/wv_ccap_eligible.py | 2 +- .../eligibility/wv_ccap_eligible_child.py | 2 +- .../eligibility/wv_ccap_income_eligible.py | 2 +- .../gov/states/wv/dhhr/ccap/wv_ccap.py | 4 +- .../dhhr/ccap/wv_ccap_child_age_category.py | 8 +- .../gov/states/wv/dhhr/ccap/wv_ccap_copay.py | 2 +- .../wv/dhhr/ccap/wv_ccap_countable_income.py | 2 +- .../wv/dhhr/ccap/wv_ccap_daily_benefit.py | 2 +- 29 files changed, 159 insertions(+), 147 deletions(-) diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml index 5ddb938edb6..10e4356e178 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml @@ -10,21 +10,21 @@ metadata: href: https://bfa.wv.gov/media/6831/download?inline # Maps age in months to WVCCAPChildAgeCategory enum index: -# 0 = INFANT (0-12 months) -# 1 = TODDLER (13-23 months) -# 2 = PRESCHOOL (2-4 years = 24-59 months) -# 3 = SCHOOL_AGE (5+ years = 60+ months) +# 0 = INFANT (0-24 months) +# 1 = TODDLER (25-36 months) +# 2 = PRESCHOOL (37-59 months) +# 3 = SCHOOL_AGE (60+ months) brackets: - threshold: 2024-10-01: 0 amount: 2024-10-01: 0 - threshold: - 2024-10-01: 13 + 2024-10-01: 25 amount: 2024-10-01: 1 - threshold: - 2024-10-01: 24 + 2024-10-01: 37 amount: 2024-10-01: 2 - threshold: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml index 34d4771a127..3e0be3d207f 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml @@ -7,5 +7,5 @@ metadata: period: year label: West Virginia CCAP maximum co-payment share reference: - - title: WV CCDF State Plan FFY 2025-2027, Section 3.1 + - title: WV CCDF State Plan FFY 2025-2027, Section 3.1.1 — Family Co-payment (7%) href: https://bfa.wv.gov/media/39915/download?inline#page=39 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml index 0d2815b8d5e..b43816d67c3 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml @@ -8,8 +8,8 @@ metadata: reference: - title: WV Child Care Subsidy Appendix A — Sliding Fee Scale (Oct 1, 2024) href: https://bfa.wv.gov/media/6826/download?inline - - title: WV CCDF State Plan FFY 2025-2027, Section 3.3 - href: https://bfa.wv.gov/media/39915/download?inline#page=42 + - title: WV CCDF State Plan FFY 2025-2027, Section 3.1.2 — Sliding Fee Scale + href: https://bfa.wv.gov/media/39915/download?inline#page=39 # Simplified percentage approximation of the 176-cell sliding fee scale. # Derived from the 3-person family column in Appendix A as a representative diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml index b0a53338e0a..95817a01f28 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml @@ -7,5 +7,5 @@ metadata: period: week label: West Virginia CCAP minimum weekly activity hours reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3 - href: https://bfa.wv.gov/media/6766/download?inline#page=18 + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.6.1 — Working Recipients + href: https://bfa.wv.gov/media/6766/download?inline#page=32 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml index ba83e566b3f..bbabe17ad26 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml @@ -7,7 +7,7 @@ metadata: period: year label: West Virginia CCAP child age limit reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3 - href: https://bfa.wv.gov/media/6766/download?inline#page=18 + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.1 — Child Age Requirement + href: https://bfa.wv.gov/media/6766/download?inline#page=25 - title: WV CCDF State Plan FFY 2025-2027, Section 2.2 href: https://bfa.wv.gov/media/39915/download?inline#page=16 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml index 11e1efdb4d4..282cb7a999a 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml @@ -7,5 +7,5 @@ metadata: period: year label: West Virginia CCAP minimum parent age reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3 - href: https://bfa.wv.gov/media/6766/download?inline#page=18 + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 1, Section 1.1.2 — Adult Definition + href: https://bfa.wv.gov/media/6766/download?inline#page=25 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml index 59cca2e0963..63beba02253 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml @@ -7,7 +7,7 @@ metadata: period: year label: West Virginia CCAP special needs child age limit reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3 - href: https://bfa.wv.gov/media/6766/download?inline#page=18 + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.1.2 — Special Needs Children + href: https://bfa.wv.gov/media/6766/download?inline#page=25 - title: WV CCDF State Plan FFY 2025-2027, Section 2.2 href: https://bfa.wv.gov/media/39915/download?inline#page=16 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml index 9d6f82dddaa..cc65ec52fff 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml @@ -21,5 +21,5 @@ metadata: period: year label: West Virginia CCAP countable income sources reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5 - href: https://bfa.wv.gov/media/6766/download?inline#page=42 + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5, Sections 5.2.1-5.2.4 — Countable Income + href: https://bfa.wv.gov/media/6766/download?inline#page=49 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml index 9de0400d652..2c57fe56ba1 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml @@ -1,11 +1,13 @@ description: West Virginia limits initial applicant income to this share of the federal poverty level under the Child Care Assistance Program. values: - 2024-10-01: 1.5 + 2024-10-01: 1.85 metadata: unit: /1 period: year label: West Virginia CCAP initial FPL limit reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5 - href: https://bfa.wv.gov/media/6766/download?inline#page=42 + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5, Section 5.0 — Overview + href: https://bfa.wv.gov/media/6766/download?inline#page=49 + - title: WV Child Care Subsidy Appendix A — Sliding Fee Scale (Oct 1, 2024) + href: https://bfa.wv.gov/media/6826/download?inline diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml index c59fa7b8b33..d2f2d25d5fb 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml @@ -7,7 +7,7 @@ metadata: period: year label: West Virginia CCAP ongoing FPL limit reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5 - href: https://bfa.wv.gov/media/6766/download?inline#page=42 + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5, Section 5.0 — Overview + href: https://bfa.wv.gov/media/6766/download?inline#page=49 - title: WV CCDF State Plan FFY 2025-2027, Section 2.2.3 href: https://bfa.wv.gov/media/39915/download?inline#page=20 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml index 6a6333d7904..5bece5a0a0c 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml @@ -14,26 +14,26 @@ TIER_I: INFANT: 2024-10-01: 39 TODDLER: - 2024-10-01: 36 + 2024-10-01: 37 PRESCHOOL: - 2024-10-01: 32 + 2024-10-01: 35 SCHOOL_AGE: 2024-10-01: 32 TIER_II: INFANT: 2024-10-01: 42 TODDLER: - 2024-10-01: 39 + 2024-10-01: 40 PRESCHOOL: - 2024-10-01: 35 + 2024-10-01: 38 SCHOOL_AGE: 2024-10-01: 35 TIER_III: INFANT: 2024-10-01: 45 TODDLER: - 2024-10-01: 42 + 2024-10-01: 43 PRESCHOOL: - 2024-10-01: 39 + 2024-10-01: 41 SCHOOL_AGE: 2024-10-01: 39 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml index 1e9876f2887..64ca0918478 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml @@ -14,26 +14,26 @@ TIER_I: INFANT: 2024-10-01: 35 TODDLER: - 2024-10-01: 34 + 2024-10-01: 33 PRESCHOOL: - 2024-10-01: 32 + 2024-10-01: 33 SCHOOL_AGE: 2024-10-01: 32 TIER_II: INFANT: 2024-10-01: 38 TODDLER: - 2024-10-01: 37 + 2024-10-01: 36 PRESCHOOL: - 2024-10-01: 35 + 2024-10-01: 36 SCHOOL_AGE: 2024-10-01: 35 TIER_III: INFANT: 2024-10-01: 41 TODDLER: - 2024-10-01: 40 + 2024-10-01: 39 PRESCHOOL: - 2024-10-01: 38 + 2024-10-01: 39 SCHOOL_AGE: 2024-10-01: 38 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml index 0f5e67bba11..7fdb3c13284 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml @@ -14,26 +14,26 @@ TIER_I: INFANT: 2024-10-01: 30 TODDLER: - 2024-10-01: 28 + 2024-10-01: 30 PRESCHOOL: - 2024-10-01: 26 + 2024-10-01: 29 SCHOOL_AGE: 2024-10-01: 26 TIER_II: INFANT: 2024-10-01: 33 TODDLER: - 2024-10-01: 31 + 2024-10-01: 33 PRESCHOOL: - 2024-10-01: 29 + 2024-10-01: 32 SCHOOL_AGE: 2024-10-01: 29 TIER_III: INFANT: 2024-10-01: 36 TODDLER: - 2024-10-01: 34 + 2024-10-01: 36 PRESCHOOL: - 2024-10-01: 32 + 2024-10-01: 35 SCHOOL_AGE: 2024-10-01: 32 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 225634c35d7..75ae057b13b 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 @@ -10,15 +10,15 @@ # Income threshold boundaries (initial applicant) # ============================================================ -- name: Case 1, income at exactly 149% FPL initial applicant eligible. +- name: Case 1, income at exactly 184% FPL initial applicant eligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 149% FPL for family of 2 = 21_150 * 1.49 = 31_513.50/yr - employment_income: 31_513 + # 184% FPL for family of 2 = 21_150 * 1.84 = 38_916/yr + employment_income: 38_916 immigration_status: CITIZEN person2: age: 3 @@ -40,20 +40,20 @@ members: [person1, person2] state_code: WV output: - # monthly income = 31_513 / 12 = 2_626.08 - # 150% FPL monthly = 21_150 * 1.5 / 12 = 2_643.75 - # 2_626.08 <= 2_643.75 -> eligible + # monthly income = 38_916 / 12 = 3_243 + # 185% FPL monthly = 21_150 * 1.85 / 12 = 3_260.63 + # 3_243 <= 3_260.63 -> eligible wv_ccap_income_eligible: true -- name: Case 2, income at exactly 150% FPL initial applicant eligible. +- name: Case 2, income at exactly 185% FPL initial applicant eligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 150% FPL for family of 2 = 21_150 * 1.5 = 31_725/yr - employment_income: 31_725 + # 185% FPL for family of 2 = 21_150 * 1.85 = 39_127.50/yr + employment_income: 39_127 immigration_status: CITIZEN person2: age: 3 @@ -75,20 +75,20 @@ members: [person1, person2] state_code: WV output: - # monthly income = 31_725 / 12 = 2_643.75 - # 150% FPL monthly = 2_643.75 - # 2_643.75 <= 2_643.75 -> eligible (at boundary) + # monthly income = 39_127 / 12 = 3_260.58 + # 185% FPL monthly = 39_127.50 / 12 = 3_260.63 + # 3_260.58 <= 3_260.63 -> eligible (at boundary) wv_ccap_income_eligible: true -- name: Case 3, income at 151% FPL initial applicant ineligible. +- name: Case 3, income at 186% FPL initial applicant ineligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 151% FPL for family of 2 = 21_150 * 1.51 = 31_936.50/yr - employment_income: 31_937 + # 186% FPL for family of 2 = 21_150 * 1.86 = 39_339/yr + employment_income: 39_339 immigration_status: CITIZEN person2: age: 3 @@ -110,9 +110,9 @@ members: [person1, person2] state_code: WV output: - # monthly income = 31_937 / 12 = 2_661.42 - # 150% FPL monthly = 2_643.75 - # 2_661.42 > 2_643.75 -> ineligible (not enrolled) + # monthly income = 39_339 / 12 = 3_278.25 + # 185% FPL monthly = 39_127.50 / 12 = 3_260.63 + # 3_278.25 > 3_260.63 -> ineligible (not enrolled) wv_ccap_income_eligible: false # ============================================================ @@ -238,8 +238,8 @@ people: person1: age: 30 - # Above 150% FPL but under 85% SMI for family of 2 - # 150% FPL = 31_725; 85% SMI family of 2 = 90_661 * (0.52+0.16) * 0.85 = 52_402.06 + # Above 185% FPL but under 85% SMI for family of 2 + # 185% FPL = 39_127.50; 85% SMI family of 2 = 90_661 * (0.52+0.16) * 0.85 = 52_402.06 employment_income: 40_000 immigration_status: CITIZEN person2: @@ -258,8 +258,8 @@ state_code: WV output: # monthly income = 40_000 / 12 = 3_333.33 - # 150% FPL monthly = 2_643.75 - # 3_333.33 > 2_643.75 -> fails FPL test for initial applicant + # 185% FPL monthly = 3_260.63 + # 3_333.33 > 3_260.63 -> fails FPL test for initial applicant wv_ccap_income_eligible: false - name: Case 8, enrolled income above 85% SMI ineligible despite passing FPL. @@ -920,7 +920,8 @@ employment_income: 20_000 immigration_status: CITIZEN person2: - age: 3 + age: 3.25 + # 3.25 years = 39 months -> PRESCHOOL (37-59mo) is_tax_unit_dependent: true immigration_status: CITIZEN wv_ccap_provider_type: FAMILY_HOME @@ -936,8 +937,8 @@ members: [person1, person2] state_code: WV output: - # Family Home Tier I Preschool = $26/day - wv_ccap_daily_rate: [0, 26] + # Family Home Tier I Preschool = $29/day + wv_ccap_daily_rate: [0, 29] - name: Case 27, family facility provider rate. period: 2025-01 @@ -949,7 +950,8 @@ employment_income: 20_000 immigration_status: CITIZEN person2: - age: 3 + age: 3.25 + # 3.25 years = 39 months -> PRESCHOOL (37-59mo) is_tax_unit_dependent: true immigration_status: CITIZEN wv_ccap_provider_type: FAMILY_FACILITY @@ -965,8 +967,8 @@ members: [person1, person2] state_code: WV output: - # Family Facility Tier I Preschool = $32/day - wv_ccap_daily_rate: [0, 32] + # Family Facility Tier I Preschool = $33/day + wv_ccap_daily_rate: [0, 33] - name: Case 28, center provider rate. period: 2025-01 @@ -978,7 +980,8 @@ employment_income: 20_000 immigration_status: CITIZEN person2: - age: 3 + age: 3.25 + # 3.25 years = 39 months -> PRESCHOOL (37-59mo) is_tax_unit_dependent: true immigration_status: CITIZEN wv_ccap_provider_type: CENTER @@ -994,8 +997,8 @@ members: [person1, person2] state_code: WV output: - # Center Tier I Preschool = $32/day - wv_ccap_daily_rate: [0, 32] + # Center Tier I Preschool = $35/day + wv_ccap_daily_rate: [0, 35] - name: Case 29, out of school time provider rate. period: 2025-01 @@ -1098,7 +1101,8 @@ employment_income: 20_000 immigration_status: CITIZEN person2: - age: 3 + age: 3.25 + # 3.25 years = 39 months -> PRESCHOOL (37-59mo) is_tax_unit_dependent: true immigration_status: CITIZEN wv_ccap_provider_type: CENTER @@ -1114,8 +1118,8 @@ members: [person1, person2] state_code: WV output: - # Center Tier II Preschool = $35/day - wv_ccap_daily_rate: [0, 35] + # Center Tier II Preschool = $38/day + wv_ccap_daily_rate: [0, 38] - name: Case 33, Tier III center rate. period: 2025-01 @@ -1127,7 +1131,8 @@ employment_income: 20_000 immigration_status: CITIZEN person2: - age: 3 + age: 3.25 + # 3.25 years = 39 months -> PRESCHOOL (37-59mo) is_tax_unit_dependent: true immigration_status: CITIZEN wv_ccap_provider_type: CENTER @@ -1143,8 +1148,8 @@ members: [person1, person2] state_code: WV output: - # Center Tier III Preschool = $39/day - wv_ccap_daily_rate: [0, 39] + # Center Tier III Preschool = $41/day + wv_ccap_daily_rate: [0, 41] # ============================================================ # All 4 age categories @@ -1158,7 +1163,7 @@ age: 30 immigration_status: CITIZEN person2: - # Age 0.5 = 6 months -> INFANT (0-12 months) + # Age 0.5 = 6 months -> INFANT (0-24 months) age: 0.5 is_tax_unit_dependent: true immigration_status: CITIZEN @@ -1183,8 +1188,8 @@ age: 30 immigration_status: CITIZEN person2: - # Age 1.5 = 18 months -> TODDLER (13-23 months) - age: 1.5 + # Age 2.5 = 30 months -> TODDLER (25-36 months) + age: 2.5 is_tax_unit_dependent: true immigration_status: CITIZEN tax_units: @@ -1208,8 +1213,8 @@ age: 30 immigration_status: CITIZEN person2: - # Age 3 = 36 months -> PRESCHOOL (24-59 months) - age: 3 + # Age 3.25 = 39 months -> PRESCHOOL (37-59 months) + age: 3.25 is_tax_unit_dependent: true immigration_status: CITIZEN tax_units: @@ -1260,7 +1265,7 @@ people: person1: age: 30 - # Income above 150% FPL for family of 2 but TANF enrolled + # Income above 185% FPL for family of 2 but TANF enrolled employment_income: 40_000 immigration_status: CITIZEN person2: @@ -1297,6 +1302,7 @@ immigration_status: CITIZEN person2: age: 3 + # 3 years = 36 months -> TODDLER (25-36mo) is_tax_unit_dependent: true immigration_status: CITIZEN wv_ccap_provider_type: CENTER @@ -1316,10 +1322,10 @@ members: [person1, person2] state_code: WV output: - # Center Tier I Preschool = $32 + $6 non-trad = $38 + # Center Tier I Toddler = $37 + $6 non-trad = $43 # daily charge = (12_000/12) / (5 * 52/12) = 1_000 / 21.67 = 46.15 - # daily benefit = min(38, 46.15) = 38 - wv_ccap_daily_benefit: [0, 38] + # daily benefit = min(43, 46.15) = 43 + wv_ccap_daily_benefit: [0, 43] - name: Case 40, both special needs and non-traditional supplements. period: 2025-01 @@ -1521,7 +1527,7 @@ age: 30 immigration_status: CITIZEN person2: - # Age 1.0 = 12 months -> INFANT (threshold at 13 months for TODDLER) + # Age 1.0 = 12 months -> INFANT (threshold at 25 months for TODDLER) age: 1.0 is_tax_unit_dependent: true immigration_status: CITIZEN @@ -1536,10 +1542,10 @@ members: [person1, person2] state_code: WV output: - # 12 months < 13 threshold -> INFANT + # 12 months < 25 threshold -> INFANT wv_ccap_child_age_category: [SCHOOL_AGE, INFANT] -- name: Case 46, child at exactly 24 months is preschool. +- name: Case 46, child at exactly 24 months is infant. period: 2025-01 input: people: @@ -1547,7 +1553,7 @@ age: 30 immigration_status: CITIZEN person2: - # Age 2.0 = 24 months -> PRESCHOOL (threshold at 24 months) + # Age 2.0 = 24 months -> INFANT (threshold for TODDLER at 25 months) age: 2.0 is_tax_unit_dependent: true immigration_status: CITIZEN @@ -1562,8 +1568,8 @@ members: [person1, person2] state_code: WV output: - # 24 months >= 24 threshold -> PRESCHOOL - wv_ccap_child_age_category: [SCHOOL_AGE, PRESCHOOL] + # 24 months < 25 threshold -> INFANT + wv_ccap_child_age_category: [SCHOOL_AGE, INFANT] - name: Case 47, child at 5 years is school age. period: 2025-01 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 f633a00a56f..96ef635e069 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 @@ -37,18 +37,18 @@ wv_ccap_eligible_child: [false, true] # FPG family of 2: 21_150 - # 150% FPL = 31_725; monthly income = 2_000 <= 2_643.75 + # 185% FPL = 39_127.50; monthly income = 2_000 <= 3_260.63 wv_ccap_income_eligible: true is_ccdf_asset_eligible: true wv_ccap_eligible: true # === Age category === - # Person1 (age 35) = 420 months -> SCHOOL_AGE; Person2 (age 3) = 36 months -> PRESCHOOL - wv_ccap_child_age_category: [SCHOOL_AGE, PRESCHOOL] + # Person1 (age 35) = 420 months -> SCHOOL_AGE; Person2 (age 3) = 36 months -> TODDLER + wv_ccap_child_age_category: [SCHOOL_AGE, TODDLER] # === Daily rate === - # Center Tier I Preschool = $32/day - wv_ccap_daily_rate: [0, 32] + # Center Tier I Toddler = $37/day + wv_ccap_daily_rate: [0, 37] # === Copay === # FPL ratio = 2_000 / 1_762.50 = 1.1348 -> 3.5% bracket @@ -57,7 +57,7 @@ # === Daily benefit === # daily charge = (8_000/12) / (5 * 52/12) = 666.67 / 21.67 = 30.77 - # daily benefit = min(32, 30.77) = 30.77 + # daily benefit = min(37, 30.77) = 30.77 wv_ccap_daily_benefit: [0, 30.77] # === Monthly benefit === @@ -147,7 +147,7 @@ members: [person1, person2] state_code: WV output: - # monthly income = 4_000 > 150% monthly = 2_643.75 + # monthly income = 4_000 > 185% monthly = 3_260.63 # Not enrolled -> initial threshold applies wv_ccap_income_eligible: false wv_ccap_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.yaml index 97b10133a68..ca87599180d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.yaml @@ -1,5 +1,5 @@ # WV CCAP child age category tests -# Infant (0-12mo), Toddler (13-23mo), Pre-School (2-4yr), School-Age (5+yr) +# Infant (0-24mo), Toddler (25-36mo), Pre-School (37-59mo), School-Age (60+mo) # Age group is derived from age in months via bracket parameter. # age_in_months = age * 12 (since age is YEAR-defined float) @@ -17,13 +17,13 @@ output: wv_ccap_child_age_category: INFANT -- name: Case 2, toddler at 18 months. +- name: Case 2, toddler at 30 months. period: 2025-01 input: people: person1: - age: 1.5 - # 1.5 years = 18 months -> TODDLER (13-23mo bracket) + age: 2.5 + # 2.5 years = 30 months -> TODDLER (25-36mo bracket) households: household: members: [person1] @@ -37,7 +37,7 @@ people: person1: age: 3.33 - # 3.33 years ~ 40 months -> PRESCHOOL (24-59mo bracket) + # 3.33 years ~ 40 months -> PRESCHOOL (37-59mo bracket) households: household: members: [person1] @@ -59,13 +59,13 @@ output: wv_ccap_child_age_category: SCHOOL_AGE -- name: Case 5, boundary at exactly 13 months. +- name: Case 5, boundary at exactly 25 months. period: 2025-01 input: people: person1: - age: 1.0834 - # 1.0834 years = 13.0008 months -> TODDLER (threshold at 13) + age: 2.0834 + # 2.0834 years = 25.0008 months -> TODDLER (threshold at 25) households: household: members: [person1] @@ -73,13 +73,13 @@ output: wv_ccap_child_age_category: TODDLER -- name: Case 6, boundary at exactly 24 months. +- name: Case 6, boundary at exactly 37 months. period: 2025-01 input: people: person1: - age: 2 - # 2 years = 24 months -> PRESCHOOL (threshold at 24) + age: 3.0834 + # 3.0834 years = 37.0008 months -> PRESCHOOL (threshold at 37) households: household: members: [person1] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml index 1dd112b9262..44a151aaad8 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml @@ -11,6 +11,7 @@ employment_income: 24_000 person2: age: 3 + # 3 years = 36 months -> TODDLER (25-36mo) is_tax_unit_dependent: true childcare_days_per_week: 5 wv_ccap_provider_type: CENTER @@ -27,9 +28,9 @@ members: [person1, person2] state_code: WV output: - # Center Tier I Preschool = $32/day - # Daily rate for this child = $32 - wv_ccap_daily_rate: [0, 32] + # Center Tier I Toddler = $37/day + # Daily rate for this child = $37 + wv_ccap_daily_rate: [0, 37] - name: Case 2, zero copay means full rate as benefit. period: 2025-01 @@ -72,6 +73,7 @@ employment_income: 6_000 person2: age: 3 + # 3 years = 36 months -> TODDLER (25-36mo) is_tax_unit_dependent: true childcare_days_per_week: 5 wv_ccap_provider_type: CENTER @@ -90,9 +92,9 @@ state_code: WV output: # Below 40% FPL -> $0 copay - # Center Tier I Preschool = $32/day + # Center Tier I Toddler = $37/day # Non-traditional hours supplement = $6/day - # total_rate = 32 + 6 = $38/day + # total_rate = 37 + 6 = $43/day # daily_charge = 12_000 / (5 * 52/12) = 12_000 / 21.6667 = $553.85/day - # min(38, 553.85) = $38/day - wv_ccap_daily_benefit: [0, 38] + # min(43, 553.85) = $43/day + wv_ccap_daily_benefit: [0, 43] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.yaml index 10d2b425883..9f780474ef4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.yaml @@ -35,7 +35,8 @@ person1: age: 30 person2: - age: 1.5 + age: 2.5 + # 2.5 years = 30 months -> TODDLER (25-36mo) is_tax_unit_dependent: true immigration_status: CITIZEN wv_ccap_provider_type: FAMILY_HOME @@ -51,8 +52,8 @@ members: [person1, person2] state_code: WV output: - # Toddler (13-23 months), Family Home, Tier II = $31 - wv_ccap_daily_rate: [0, 31] + # Toddler (25-36 months), Family Home, Tier II = $33 + wv_ccap_daily_rate: [0, 33] - name: Case 3, family facility Tier III preschool rate. period: 2025-01 @@ -62,7 +63,8 @@ person1: age: 30 person2: - age: 3 + age: 3.25 + # 3.25 years = 39 months -> PRESCHOOL (37-59mo) is_tax_unit_dependent: true immigration_status: CITIZEN wv_ccap_provider_type: FAMILY_FACILITY @@ -78,8 +80,8 @@ members: [person1, person2] state_code: WV output: - # Preschool (24-59 months), Family Facility, Tier III = $38 - wv_ccap_daily_rate: [0, 38] + # Preschool (37-59 months), Family Facility, Tier III = $39 + wv_ccap_daily_rate: [0, 39] - name: Case 4, out of school time rate. period: 2025-01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml index f323973ef89..9d87b76212b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml @@ -25,7 +25,7 @@ state_code: WV output: # Child age 5 < 13 -> eligible child - # Income 24,000 < 150% FPL (31,725) -> income eligible + # Income 24,000 < 185% FPL (39,127.50) -> income eligible # Parent works 30 hrs >= 20 -> activity eligible wv_ccap_eligible: true @@ -77,7 +77,7 @@ members: [person1, person2] state_code: WV output: - # Income 48,000 > 150% FPL (31,725) -> not income eligible + # Income 48,000 > 185% FPL (39,127.50) -> not income eligible wv_ccap_eligible: false - name: Case 4, parent not meeting activity hours means not eligible. @@ -135,7 +135,7 @@ state_code: WV output: # Both parents work >= 20 hrs -> activity eligible - # Combined income: 30,000 < 150% FPL-3 (39,975) -> income eligible + # Combined income: 30,000 < 185% FPL-3 (49,302.50) -> income eligible # Child age 3 < 13 -> eligible child wv_ccap_eligible: true 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 d2f8a1dcdd7..2062f182c98 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 @@ -3,7 +3,7 @@ # first_person = 15_650, additional = 5_500 # Family of 2: 21_150 -- name: Case 1, income below 150% FPL for initial applicant. +- name: Case 1, income below 185% FPL for initial applicant. period: 2025-01 input: people: @@ -24,17 +24,17 @@ state_code: WV output: # FPG family of 2: 21_150 - # 150% FPL = 31_725 - # monthly income = 2_000; monthly limit = 2_643.75 + # 185% FPL = 39_127.50 + # monthly income = 2_000; monthly limit = 3_260.63 wv_ccap_income_eligible: true -- name: Case 2, income above 150% FPL for new applicant. +- name: Case 2, income above 185% FPL for new applicant. period: 2025-01 input: people: person1: age: 30 - employment_income: 36_000 + employment_income: 48_000 person2: age: 5 tax_units: @@ -48,7 +48,7 @@ members: [person1, person2] state_code: WV output: - # monthly income = 3_000 > 150% FPL monthly = 2_643.75 + # monthly income = 4_000 > 185% FPL monthly = 3_260.63 wv_ccap_income_eligible: false - name: Case 3, enrolled family at 170% FPL eligible under ongoing threshold. diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py index e709d9414cb..5a05198a580 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py @@ -7,7 +7,7 @@ class wv_ccap_activity_eligible(Variable): label = "Eligible for West Virginia CCAP based on activity requirements" definition_period = MONTH defined_for = StateCode.WV - reference = "https://bfa.wv.gov/media/6766/download?inline#page=18" + reference = "https://bfa.wv.gov/media/6766/download?inline#page=32" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.wv.dhhr.ccap.eligibility diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py index 9a06a0786e0..19beae608ca 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py @@ -8,7 +8,7 @@ class wv_ccap_eligible(Variable): definition_period = MONTH defined_for = StateCode.WV reference = ( - "https://bfa.wv.gov/media/6766/download?inline#page=18", + "https://bfa.wv.gov/media/6766/download?inline#page=25", "https://bfa.wv.gov/media/39915/download?inline#page=16", ) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py index 263f587649f..7bc0c387a37 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py @@ -8,7 +8,7 @@ class wv_ccap_eligible_child(Variable): definition_period = MONTH defined_for = StateCode.WV reference = ( - "https://bfa.wv.gov/media/6766/download?inline#page=18", + "https://bfa.wv.gov/media/6766/download?inline#page=25", "https://bfa.wv.gov/media/39915/download?inline#page=16", ) 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 7dfc32fe5cd..0bb81e13830 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 @@ -8,7 +8,7 @@ class wv_ccap_income_eligible(Variable): definition_period = MONTH defined_for = StateCode.WV reference = ( - "https://bfa.wv.gov/media/6766/download?inline#page=42", + "https://bfa.wv.gov/media/6766/download?inline#page=49", "https://bfa.wv.gov/media/39915/download?inline#page=20", ) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py index 7a911d0bd87..f4fde69b0b0 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py @@ -9,8 +9,8 @@ class wv_ccap(Variable): definition_period = MONTH defined_for = "wv_ccap_eligible" reference = ( - "https://bfa.wv.gov/media/6766/download?inline#page=66", - "https://bfa.wv.gov/media/39915/download?inline#page=42", + "https://bfa.wv.gov/media/6766/download?inline#page=73", + "https://bfa.wv.gov/media/39915/download?inline#page=41", ) def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py index b5ab6b364bf..f1237c50b4a 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py @@ -2,10 +2,10 @@ class WVCCAPChildAgeCategory(Enum): - INFANT = "Infant (0-12 months)" - TODDLER = "Toddler (13-23 months)" - PRESCHOOL = "Preschool (2-4 years)" - SCHOOL_AGE = "School Age (5+ years)" + INFANT = "Infant (0-24 months)" + TODDLER = "Toddler (25-36 months)" + PRESCHOOL = "Preschool (37-59 months)" + SCHOOL_AGE = "School Age (60+ months)" class wv_ccap_child_age_category(Variable): 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 a132fd44a9a..ab9e9d36b01 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 @@ -10,7 +10,7 @@ class wv_ccap_copay(Variable): defined_for = StateCode.WV reference = ( "https://bfa.wv.gov/media/6826/download?inline", - "https://bfa.wv.gov/media/39915/download?inline#page=42", + "https://bfa.wv.gov/media/39915/download?inline#page=41", ) def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py index 82b4458d15e..754b8ab530b 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py @@ -8,6 +8,6 @@ class wv_ccap_countable_income(Variable): definition_period = MONTH unit = USD defined_for = StateCode.WV - reference = "https://bfa.wv.gov/media/6766/download?inline#page=42" + reference = "https://bfa.wv.gov/media/6766/download?inline#page=49" adds = "gov.states.wv.dhhr.ccap.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py index 6aa1c1811ab..405bc7a1c1c 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py @@ -8,7 +8,7 @@ class wv_ccap_daily_benefit(Variable): label = "West Virginia CCAP daily benefit per child" definition_period = MONTH defined_for = "wv_ccap_eligible_child" - reference = "https://bfa.wv.gov/media/6766/download?inline#page=66" + reference = "https://bfa.wv.gov/media/6766/download?inline#page=73" def formula(person, period, parameters): p = parameters(period).gov.states.wv.dhhr.ccap From 51ca4ebbd6d2a0573d78dc1c554d9849bf770f9e Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 8 Apr 2026 10:41:18 -0400 Subject: [PATCH 06/16] =?UTF-8?q?Review-fix=20round=202:=20fix=20min=5Fpar?= =?UTF-8?q?ent=5Fage=20page=20reference=20(#page=3D25=20=E2=86=92=20#page?= =?UTF-8?q?=3D8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- .../gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml index 282cb7a999a..8192361b191 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml @@ -8,4 +8,4 @@ metadata: label: West Virginia CCAP minimum parent age reference: - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 1, Section 1.1.2 — Adult Definition - href: https://bfa.wv.gov/media/6766/download?inline#page=25 + href: https://bfa.wv.gov/media/6766/download?inline#page=8 From 19e3f97a702eeeac951fa5eadb2e072b41116796 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 8 Apr 2026 10:43:19 -0400 Subject: [PATCH 07/16] Add lessons from West Virginia CCAP implementation Co-Authored-By: Claude Opus 4.6 (1M context) --- lessons/agent-lessons.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 lessons/agent-lessons.md diff --git a/lessons/agent-lessons.md b/lessons/agent-lessons.md new file mode 100644 index 00000000000..454c3e2b9c0 --- /dev/null +++ b/lessons/agent-lessons.md @@ -0,0 +1,11 @@ +# Agent Lessons Learned + +Accumulated from /encode-policy-v2 and /backdate-program runs across all contributors. +Loaded by implementation agents on future runs. + +## New Lessons from West Virginia CCAP (2026-04-08) + +### PARAMETER +- When transcribing a multi-dimension lookup table (e.g., age group x quality tier x provider type), verify that row labels (age groups) are correctly aligned with their data columns; if one dimension's boundaries shift (e.g., age groups redefined), ALL rate values in that dimension must be re-read from the source — a wrong row-label mapping cascades to every value in the affected rows, not just one. +- Never invent a parameter value when no source supports it; if the regulatory document does not specify a threshold (e.g., an initial FPL limit distinct from the ongoing limit), do not fabricate one — either use the documented value for both paths or flag the gap as unverifiable. A fabricated value that looks plausible (e.g., 150% vs 185%) passes casual review and is harder to catch than a missing value. +- When a parameter represents a soft administrative guideline rather than a hard regulatory cutoff (e.g., "adults are defined as 18+" used as a general definition, not a strict eligibility bar), document this distinction in the parameter description; do not model it as a strict eligibility gate unless the regulation explicitly mandates denial for failing the criterion. From 60deb0add8c31b5e96bd4c46bd760a1a48766479 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 8 Apr 2026 19:15:17 -0400 Subject: [PATCH 08/16] minor --- .../dhhr/ccap/age_group/informal_months.yaml | 8 +- .../states/wv/dhhr/ccap/age_group/months.yaml | 16 +- .../wv/dhhr/ccap/copayment/max_share.yaml | 2 +- .../dhhr/ccap/eligibility/activity_hours.yaml | 2 +- .../ccap/eligibility/child_age_limit.yaml | 2 +- .../dhhr/ccap/eligibility/min_parent_age.yaml | 2 +- .../special_needs_child_age_limit.yaml | 2 +- .../ccap/income/countable_income/sources.yaml | 2 +- .../dhhr/ccap/income/fpl_limit/initial.yaml | 2 +- .../dhhr/ccap/income/fpl_limit/ongoing.yaml | 2 +- .../states/wv/dhhr/ccap/income/smi_rate.yaml | 2 +- .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 36 +- sources/working_references.md | 328 ++++++------------ 13 files changed, 144 insertions(+), 262 deletions(-) diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml index 7f2b5dd5dd2..5f489c1bc3a 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml @@ -14,10 +14,10 @@ metadata: # 1 = AGE_2_AND_OVER (24+ months) brackets: - threshold: - 2024-10-01: 0 + 2024-01-01: 0 amount: - 2024-10-01: 0 + 2024-01-01: 0 - threshold: - 2024-10-01: 24 + 2024-01-01: 24 amount: - 2024-10-01: 1 + 2024-01-01: 1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml index 10e4356e178..6a7222c15ff 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml @@ -16,18 +16,18 @@ metadata: # 3 = SCHOOL_AGE (60+ months) brackets: - threshold: - 2024-10-01: 0 + 2024-01-01: 0 amount: - 2024-10-01: 0 + 2024-01-01: 0 - threshold: - 2024-10-01: 25 + 2024-01-01: 25 amount: - 2024-10-01: 1 + 2024-01-01: 1 - threshold: - 2024-10-01: 37 + 2024-01-01: 37 amount: - 2024-10-01: 2 + 2024-01-01: 2 - threshold: - 2024-10-01: 60 + 2024-01-01: 60 amount: - 2024-10-01: 3 + 2024-01-01: 3 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml index 3e0be3d207f..8bbd8a29bed 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_share.yaml @@ -1,6 +1,6 @@ description: West Virginia limits the co-payment to this share of gross family income under the Child Care Assistance Program. values: - 2024-10-01: 0.07 + 2024-01-01: 0.07 metadata: unit: /1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml index 95817a01f28..0d4ab91a520 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml @@ -1,6 +1,6 @@ description: West Virginia sets this minimum weekly activity hours for parent eligibility under the Child Care Assistance Program. values: - 2024-10-01: 20 + 2024-01-01: 20 metadata: unit: hour diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml index bbabe17ad26..2cc703d23bc 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/child_age_limit.yaml @@ -1,6 +1,6 @@ description: West Virginia limits child eligibility to under this age under the Child Care Assistance Program. values: - 2024-10-01: 13 + 2024-01-01: 13 metadata: unit: year diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml index 8192361b191..ed6a03ce58d 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml @@ -1,6 +1,6 @@ description: West Virginia sets this minimum parent age under the Child Care Assistance Program. values: - 2024-10-01: 18 + 2024-01-01: 18 metadata: unit: year diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml index 63beba02253..60a7a898028 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml @@ -1,6 +1,6 @@ description: West Virginia limits special needs child eligibility to under this age under the Child Care Assistance Program. values: - 2024-10-01: 18 + 2024-01-01: 18 metadata: unit: year diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml index cc65ec52fff..d7bdb736972 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml @@ -1,6 +1,6 @@ description: West Virginia counts these income sources under the Child Care Assistance Program. values: - 2024-10-01: + 2024-01-01: - employment_income - self_employment_income - social_security diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml index 2c57fe56ba1..c7171ddf1a7 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml @@ -1,6 +1,6 @@ description: West Virginia limits initial applicant income to this share of the federal poverty level under the Child Care Assistance Program. values: - 2024-10-01: 1.85 + 2019-10-01: 1.5 metadata: unit: /1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml index d2f2d25d5fb..3707b304996 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml @@ -1,6 +1,6 @@ description: West Virginia limits ongoing recipient income to this share of the federal poverty level under the Child Care Assistance Program. values: - 2024-10-01: 1.85 + 2019-10-01: 1.85 metadata: unit: /1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml index 1b5b80411d0..c8675c9d92b 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml @@ -1,6 +1,6 @@ description: West Virginia limits income to this share of the state median income under the Child Care Assistance Program. values: - 2024-10-01: 0.85 + 2024-01-01: 0.85 metadata: unit: /1 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 75ae057b13b..dc43be96e71 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 @@ -10,15 +10,15 @@ # Income threshold boundaries (initial applicant) # ============================================================ -- name: Case 1, income at exactly 184% FPL initial applicant eligible. +- name: Case 1, income at exactly 149% FPL initial applicant eligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 184% FPL for family of 2 = 21_150 * 1.84 = 38_916/yr - employment_income: 38_916 + # 149% FPL for family of 2 = 21_150 * 1.49 = 31_513.50/yr + employment_income: 31_513 immigration_status: CITIZEN person2: age: 3 @@ -40,20 +40,20 @@ members: [person1, person2] state_code: WV output: - # monthly income = 38_916 / 12 = 3_243 - # 185% FPL monthly = 21_150 * 1.85 / 12 = 3_260.63 - # 3_243 <= 3_260.63 -> eligible + # monthly income = 31_513 / 12 = 2_626.08 + # 150% FPL monthly = 21_150 * 1.50 / 12 = 2_643.75 + # 2_626.08 <= 2_643.75 -> eligible wv_ccap_income_eligible: true -- name: Case 2, income at exactly 185% FPL initial applicant eligible. +- name: Case 2, income at exactly 150% FPL initial applicant eligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 185% FPL for family of 2 = 21_150 * 1.85 = 39_127.50/yr - employment_income: 39_127 + # 150% FPL for family of 2 = 21_150 * 1.50 = 31_725/yr + employment_income: 31_725 immigration_status: CITIZEN person2: age: 3 @@ -75,20 +75,20 @@ members: [person1, person2] state_code: WV output: - # monthly income = 39_127 / 12 = 3_260.58 - # 185% FPL monthly = 39_127.50 / 12 = 3_260.63 - # 3_260.58 <= 3_260.63 -> eligible (at boundary) + # monthly income = 31_725 / 12 = 2_643.75 + # 150% FPL monthly = 21_150 * 1.50 / 12 = 2_643.75 + # 2_643.75 <= 2_643.75 -> eligible (at boundary) wv_ccap_income_eligible: true -- name: Case 3, income at 186% FPL initial applicant ineligible. +- name: Case 3, income at 151% FPL initial applicant ineligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 186% FPL for family of 2 = 21_150 * 1.86 = 39_339/yr - employment_income: 39_339 + # 151% FPL for family of 2 = 21_150 * 1.51 = 31_936.50/yr + employment_income: 31_937 immigration_status: CITIZEN person2: age: 3 @@ -110,9 +110,9 @@ members: [person1, person2] state_code: WV output: - # monthly income = 39_339 / 12 = 3_278.25 - # 185% FPL monthly = 39_127.50 / 12 = 3_260.63 - # 3_278.25 > 3_260.63 -> ineligible (not enrolled) + # monthly income = 31_937 / 12 = 2_661.42 + # 150% FPL monthly = 21_150 * 1.50 / 12 = 2_643.75 + # 2_661.42 > 2_643.75 -> ineligible (not enrolled) wv_ccap_income_eligible: false # ============================================================ diff --git a/sources/working_references.md b/sources/working_references.md index 6567b9debfb..3af940b3272 100644 --- a/sources/working_references.md +++ b/sources/working_references.md @@ -1,230 +1,112 @@ -# Delaware State Supplementary Payment (SSP) - Working References - -## Program Overview - -Delaware provides an optional State Supplementary Payment (SSP) to SSI recipients -residing in certified adult residential care facilities. The program has dual -administration: SSA administers the federally-administered optional supplement for -facility residents, and the Delaware Division of Social Services (DSS) administers -a separate $5/month supplement for individuals losing SSI due to SSDI (MAT program). - -**Official program name**: State Supplement Payment / Optional State Supplementary Payment -**Administering agency**: SSA (federal portion) + Delaware DSS (state portion) -**Administration classification**: F (mandatory) / F/S (optional) per SI 01415.010 +# West Virginia Child Care Assistance Program (CCAP) — Working References ## Primary Sources -### 1. SSA POMS SI PHI01415.008 - Delaware-Specific Administration -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415008PHI -- **Title**: Administration of State Supplementary Programs -- Delaware (RTN 61 -- 12/2015) -- **Content**: Complete historical payment levels from 1992-2016, living arrangement - definitions, certification requirements, income limitation rules +### 1. Child Care Subsidy Policy & Procedures Manual (October 1, 2024) +- **URL**: https://bfa.wv.gov/media/6766/download?inline +- **Local PDF**: `/tmp/wv-ccap-subsidy-policy.pdf` +- **Description**: Main policy manual governing WV's child care subsidy program. Covers eligibility, income determination, family size rules, fee assessment, provider payment, and case management. +- **Key chapters**: + - Chapter 3 (p.18): Family eligibility — age, citizenship, residency, wage, activity hour requirements + - Chapter 5 (p.42): Financial eligibility — family size, gross income, countable/excluded income, income conversion + - Chapter 6 (p.53): Case management — fee determination (Section 6.4), sliding fee scale reference + - Chapter 7 (p.66): Payment rates and certificate system — age categories, tier supplements, non-traditional hours + +### 2. Appendix A — Sliding Fee Scale (Effective October 1, 2024) +- **URL**: https://bfa.wv.gov/media/6826/download?inline +- **Local PDF**: `/tmp/wv-ccap-fee-scale.pdf` +- **Description**: Complete sliding fee scale tables for family sizes 1–11. Shows daily co-payment fees by FPL bracket (40%–185%) and family size. Based on FY 2024 Federal Poverty Level. +- **Key data**: Fee ranges from $0.00 (below 40% FPL) to $13.00/day (family size 10, 185% FPL bracket). Intake cap at 185% FPL for new applications. + +### 3. Appendix B — Child Care Rate Structure (Effective October 1, 2024) +- **URL**: https://bfa.wv.gov/media/6831/download?inline +- **Local PDF**: `/tmp/wv-ccap-rate-structure.pdf` +- **Description**: Provider reimbursement rates by care type, age group, and quality tier. Single-page document. - **Key data**: - - State supplement for certified residential care home: $140/month (individual), $448/month (couple) - - These amounts have been frozen since at least 1992 - - Effective March 1, 2003: "Residential Care Homes" include Adult Foster Care Homes, - Adult Residential Care Facilities, and Assisted Living Facilities - - Eligibility requires Adult Residential Care Certification Form - -### 2. SSA POMS SI 01415.058 - January 2026 Payment Levels -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415058 -- **Title**: Federally Administered Optional Supplementary Payment Programs for January 2026 -- **Content**: Current payment levels effective January 1, 2026 -- **Delaware data**: - - Individual (OS Code A): FBR $994 + supplement $140 = $1,134 total - - Couple (OS Code A): FBR $1,491 + supplement $448 = $1,939 total - - OS Code Z (non-facility): $0 supplement - - OS Code Y: waived supplementation - -### 3. SSA POMS SI 01415.057 - January 2025 Payment Levels -- **URL**: https://secure.ssa.gov/POMS.NSF/lnx/0501415057 -- **Title**: Federally Administered Optional Supplementary Payment Programs for January 2025 -- **Content**: Payment levels effective January 1, 2025 -- **Delaware data**: - - Individual (OS Code A): FBR $967 + supplement $140 = $1,107 total - - Couple (OS Code A): FBR $1,450 + supplement $448 = $1,898 total - -### 4. SSA POMS SI 01415.056 - January 2024 Payment Levels -- **URL**: https://secure.ssa.gov/apps10/poms.nsf/lnx/0501415056 -- **Title**: Federally Administered Optional Supplementary Payment Programs for January 2024 -- **Delaware data**: - - Individual (OS Code A): FBR $943 + supplement $140 = $1,083 total - - Couple (OS Code A): FBR $1,415 + supplement $448 = $1,863 total - -### 5. SSA POMS SI 01415.055 - January 2023 Payment Levels -- **URL**: https://secure.ssa.gov/poms.NSF/lnx/0501415055 -- **Delaware data**: - - Individual (OS Code A): FBR $914 + supplement $140 = $1,054 total - - Couple (OS Code A): FBR $1,371 + supplement $448 = $1,819 total - -### 6. SSA POMS SI 01415.054 - January 2022 Payment Levels -- **URL**: https://secure.ssa.gov/apps10/poms.nsf/lnx/0501415054 -- **Delaware data**: - - Individual (OS Code A): FBR $841 + supplement $140 = $981 total - - Couple (OS Code A): FBR $1,261 + supplement $448 = $1,709 total - -### 7. SSA POMS SI 01415.053 - January 2021 Payment Levels -- **URL**: https://secure.ssa.gov/apps10/poms.nsf/lnx/0501415053 -- **Delaware data**: - - Individual (OS Code A): FBR $794 + supplement $140 = $934 total - - Couple (OS Code A): FBR $1,191 + supplement $448 = $1,639 total - -### 8. SSA POMS SI 01415.052 - January 2020 Payment Levels -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415052 -- **Delaware data**: - - Individual (OS Code A): FBR $783 + supplement $140 = $923 total - - Couple (OS Code A): FBR $1,175 + supplement $448 = $1,623 total - -### 9. SSA POMS SI 01415.051 - January 2019 Payment Levels -- **URL**: https://secure.ssa.gov/apps10/poms.nsf/lnx/0501415051 -- **Delaware data**: - - Individual (OS Code A): FBR $771 + supplement $140 = $911 total - - Couple (OS Code A): FBR $1,157 + supplement $448 = $1,605 total - -### 10. SSA POMS SI 01415.050 - January 2018 Payment Levels -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415050 -- **Delaware data**: - - Individual (OS Code A): FBR $750 + supplement $140 = $890 total - - Couple (OS Code A): FBR $1,125 + supplement $448 = $1,573 total - -### 11. SSA POMS SI 01415.049 - January 2017 Payment Levels -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415049 -- **Delaware data**: - - Individual (OS Code A): FBR $735 + supplement $140 = $875 total - - Couple (OS Code A): FBR $1,103 + supplement $448 = $1,551 total - -### 12. SSA POMS SI 01415.047 - January 2015 Payment Levels -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415047 -- **Delaware data**: - - Individual (OS Code A): FBR $733 + supplement $140 = $873 total - - Couple (OS Code A): FBR $1,100 + supplement $448 = $1,548 total - -### 13. SSA POMS SI 01415.046 - January 2014 Payment Levels -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415046 -- **Delaware data**: - - Individual (OS Code A): FBR $721 + supplement $140 = $861 total - - Couple (OS Code A): FBR $1,082 + supplement $448 = $1,530 total - -### 14. SSA POMS SI 01415.045 - January 2013 Payment Levels -- **URL**: https://secure.ssa.gov/apps10/poms.nsf/links/0501415045 -- **Delaware data**: - - Individual (OS Code A): FBR $710 + supplement $140 = $850 total - - Couple (OS Code A): FBR $1,066 + supplement $448 = $1,514 total - -### 15. SSA POMS SI 01415.044 - January 2012 Payment Levels -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415044 -- **Delaware data**: - - Individual (OS Code A): FBR $698 + supplement $140 = $838 total - - Couple (OS Code A): FBR $1,048 + supplement $448 = $1,496 total - -### 16. SSA POMS SI 01415.040 - January 2008 Payment Levels -- **URL**: https://secure.ssa.gov/POMS.nsf/lnx/0501415040 -- **Delaware data**: - - Individual (OS Code A): FBR $637 + supplement $140 = $777 total - - Couple (OS Code A): FBR $956 + supplement $448 = $1,404 total - -### 17. SSA POMS SI 01415.036 - January 2004 Payment Levels -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415036 -- **Delaware data**: - - Individual (OS Code A): FBR $564 + supplement $140 = $704 total - - Couple (OS Code A): FBR $846 + supplement $448 = $1,294 total - -### 18. SSA POMS SI 01415.032 - January 2000 Payment Levels -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415032 -- **Delaware data**: - - Individual (OS Code A): FBR $512 + supplement $140 = $652 total - - Couple (OS Code A): FBR $769 + supplement $448 = $1,217 total - -### 19. SSA POMS SI 01415.031 - January 1999 Payment Levels -- **URL**: https://secure.ssa.gov/apps10/poms.nsf/lnx/0501415031 -- **Delaware data**: - - Individual (OS Code A): FBR $500 + supplement $140 = $640 total - - Couple (OS Code A): FBR $751 + supplement $448 = $1,199 total - -### 20. SSA POMS SI 01415.010 - Administration Classification -- **URL**: https://secure.ssa.gov/poms.nsf/lnx/0501415010 -- **Title**: Administration of State Supplementary Programs -- **Delaware classification**: F (mandatory) / F/S (optional) + - Family Child Care Home: Tier I $26–$30/day, Tier II $29–$33, Tier III $32–$36 + - Family Child Care Facility: Tier I $32–$35, Tier II $35–$38, Tier III $38–$41 + - Child Care Center: Tier I $32–$39, Tier II $35–$42, Tier III $39–$45 + - Out of School Time: Tier I $14.50/day + - Informal/Relative: Tier I $6.00–$7.50/day + - Special Needs supplement: additional $3.00/day + - Non-Traditional Hours supplement: additional $6.00/qualifying day + +### 4. 2024 State Median Income Chart (Effective May 1, 2024) +- **URL**: https://bfa.wv.gov/media/6781/download?inline +- **Local PDF**: `/tmp/wv-ccap-smi-2024.pdf` +- **Description**: 85% of State Median Income thresholds by family size, used for maximum eligibility determination. +- **Key data** (85% SMI monthly): + - 1 person: $3,339 + - 2 persons: $4,367 + - 3 persons: $5,394 + - 4 persons: $6,422 + - 5 persons: $7,555 + - 6 persons: $8,477 + - 7 persons: $8,699 + - 8 persons: $8,862 + - 9 persons: $9,055 + - 10 persons: $9,247 + +### 5. CCDF State Plan FFY 2025–2027 (Approved November 9, 2024) +- **URL**: https://bfa.wv.gov/media/39915/download?inline +- **Local PDF**: `/tmp/wv-ccdf-state-plan-2025-2027.pdf` +- **Description**: 212-page federal CCDF state plan. Contains official eligibility thresholds, income definitions, co-payment structure, and payment rate methodology. +- **Key sections**: + - Section 2.2 (p.16): Eligible children and families — age < 13 (up to 18 for special needs/court supervision) + - Section 2.2.3 (p.20): Income limits — statewide, no local variation + - Section 2.2.4 (p.20): Initial eligibility income table — 85% SMI by family size + - Section 3.1 (p.39): Co-payments — max 7% of gross income, sliding fee scale based on income and family size + - Section 3.1.2 (p.40): Fee scale table — lowest/highest income and co-pay by family size + - Section 3.3 (p.42): Fee waivers — foster/kinship care, CPS families, families below 40% FPL + - Section 4.1 (p.43): Provider participation — certificate/voucher system, no grants/contracts + +### 6. Supplemental Child Care Assistance Policy (April 1, 2023) +- **URL**: https://bfa.wv.gov/media/6791/download?inline +- **Local PDF**: `/tmp/wv-ccap-supplemental-policy.pdf` +- **Description**: Supplemental program for populations not eligible for CCDF (State Opioid Response, Jobs & Hope, Foster/Kinship without qualifying activity). Separate funding stream with coupon-based payment. + +### 7. Appendix C — Conversion Chart for Part Days +- **URL**: https://bfa.wv.gov/media/6836/download?inline +- **Description**: Converts part-day attendance to full-day equivalents for payment calculation. + +### 8. Appendix D — Self Employment Tax Information +- **URL**: https://bfa.wv.gov/media/6841/download?inline + +### 9. Appendix E — Citizenship Verifications +- **URL**: https://bfa.wv.gov/media/6846/download?inline ## Secondary Sources -### 21. WorkWorld - SSI State Supplement Delaware -- **URL**: https://help.workworldapp.com/wwwebhelp/ssi_state_supplement_delaware.htm -- **Content**: Program overview with 2010 payment amounts -- **Key data**: - - Adult Residential Care Facility: Individual $140 supplement / Couple $448 supplement - - Special category (losing SSI due to SSDI): Individual $5 supplement (state-administered) - - Children under 18 are ineligible - - No additional income disregards beyond federal SSI limits - - Federal resource limitations apply - - Data reflects CY2010 payment levels - -### 22. Delaware Admin Code 16 Del. Admin. Code SS 13000-13640 -- **URL**: https://www.law.cornell.edu/regulations/delaware/16-Del-Admin-Code-SS-13000-13640 -- **Title**: The Social Security Administration (SSA) -- Delaware Social Services Manual -- **Content**: SSA determines eligibility for SSP for individuals in adult residential care -- **Source regulation**: 15 DE Reg. 202, 08/01/11 - -### 23. SSA State Assistance Programs for SSI Recipients, January 2011 - Delaware -- **URL**: https://www.ssa.gov/policy/docs/progdesc/ssi_st_asst/2011/de.html -- **Status**: 403 FORBIDDEN (SSA blocks automated access -- per memory note) -- **Note**: This is the discontinued 2011 SSA report. Last published edition. - -## Summary of State Supplement Amounts (FROZEN) - -The Delaware state supplement amounts have been unchanged since at least 1992: - -| Claim Type | Monthly Supplement | -|---|---| -| Individual in certified residential care | $140 | -| Couple (both eligible) in certified residential care | $448 | -| Individual losing SSI due to SSDI (MAT, state-administered) | $5 | - -## Living Arrangement / OS Code Definitions - -| OS Code | Description | Supplement? | -|---|---|---| -| A | Adult residential care facility, assisted living facility, or adult foster care home | Yes ($140 individual / $448 couple) | -| Y | Eligible but waived supplementation | No | -| Z | All other recipients (independent living, household of another, Medicaid facility) | No | - -## Federal Living Arrangement Code Mapping - -| Federal Code | Description | State Supplement When OS=A | -|---|---|---| -| A | Own household / independent living | $140 / $448 | -| B | Household of another (reduced FBR) | N/A (only OS=Z) | -| C | Parental household (child) | N/A (children ineligible) | -| D | Medicaid facility ($30 personal needs) | N/A (only OS=Z) | - -Note: Federal Code A with OS Code A is the only combination that receives a state supplement. -This means the recipient must be in a certified residential care facility AND classified as -independent living (Federal Code A) rather than in a Medicaid facility (Federal Code D). - -## Eligibility Requirements - -1. Must be SSI-eligible (aged, blind, or disabled) -- adults only (18+) -2. Must reside in Delaware -3. Must reside in a certified adult residential care facility, assisted living facility, - or adult foster care home -4. State must provide certification documentation (Adult Residential Care Certification Form) -5. No additional state income disregards beyond federal SSI rules -6. Federal SSI resource limits apply ($2,000 individual / $3,000 couple) - -## State-Administered Portion (MAT) - -The state-administered portion is specifically for: -- Individuals who lost SSI eligibility due to SSDI receipt -- $5/month supplement to maintain Medicaid eligibility during transition to Medicare -- Administered by Delaware Division of Social Services (DSS) -- Established March 1, 2001 per DSSM 17800 -- Extended September 1, 2008 to cover individuals who lost Medicaid on/after January 1, 2008 - -## Key Dates - -- **Pre-1992**: Program existed but specific amounts before 1992 not documented in POMS -- **1992-present**: $140 individual / $448 couple (frozen, no COLA) -- **March 1, 2001**: MAT program established ($5 state supplement) -- **March 1, 2003**: "Residential Care Homes" definition expanded to include Adult Foster - Care Homes, Adult Residential Care Facilities, and Assisted Living Facilities -- **September 1, 2008**: MAT coverage extended +### 10. WV DHHR Choices — Eligibility Page +- **URL**: https://www.wvdhhr.org/choices/for-families/eligibility.html +- **Description**: Public-facing eligibility summary. Confirms 150% FPL initial intake cap, 185% FPL for ongoing eligibility, and qualifying activities. + +### 11. Bureau for Family Assistance — Child Care Page +- **URL**: https://bfa.wv.gov/page/child-care-assistance-and-early-childhood-resources +- **Description**: Program overview page with links to policy documents and contact information. + +### 12. ECE Policies and Regulations Page +- **URL**: https://bfa.wv.gov/ece-policies-and-regulations +- **Description**: Index of all policy documents, appendices, provider regulations, and state plans. + +### 13. BFA State Plans Page +- **URL**: https://bfa.wv.gov/state-plans +- **Description**: Links to CCDF state plans and other program state plans. + +## Legislative Authority + +### 14. WV Code §49-2-113 — Child Care Center Licensing +- **URL**: https://code.wvlegislature.gov/49-2-113/ +- **Description**: Establishes DHHR authority over child care licensing, certification, approval, and registration. + +### 15. Child Care and Development Block Grant Act (CCDBG) +- **Federal citation**: 42 U.S.C. 9857 et seq. +- **Description**: Federal authorizing statute for CCDF funding. + +### 16. Social Security Act Section 418 +- **Federal citation**: 42 U.S.C. 618 +- **Description**: Authorizes CCDF alongside CCDBG Act. + +## Failed/Unavailable Fetches + +None — all primary sources were successfully downloaded. From e11d96b7e07718ba772bb516872d24f12d110373 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 14 May 2026 18:04:02 -0400 Subject: [PATCH 09/16] Apply review fixes to WV CCAP eligibility, age boundary, and references Address findings from /review-program: - C1: Remove unsupported 150%/185% FPL two-tier income test. Per CCDF Plan Sec 2.2.4 / 2.2.5(a), WV uses a single 85% SMI ceiling with graduated phase-out marked "Not applicable". Drop fpl_limit/ params and wv_ccap_enrolled variable; rewrite wv_ccap_income_eligible to apply only the 85% SMI test (plus is_tanf_enrolled bypass). - C2: Annotate wv_ccap_income_eligible to note the TANF bypass is applied to all enrolled units; the Sec 3.2.1.4 children-only exception is not yet modeled. - C3: Remove is_tax_unit_dependent filter from wv_ccap_eligible_child. Manual Sec 3.2 requires residency, not tax dependency, and the variable-patterns skill forbids is_tax_unit_dependent for benefit eligibility. - C4: Remove min_parent_age=18 hard floor from wv_ccap_eligible. Sec 1.1.2 is a glossary definition; Sec 1.1.10, 4.5.3.6, and 4.5.6 explicitly contemplate minor parents in qualifying activity. - C5: Fix informal/relative age boundary off-by-one. Appendix B groups 24 months as INFANT ($7.50/day); change threshold from 24 to 25 so AGE_2_AND_OVER ($6.00/day) starts at 25 months. - C6: Add inline note in wv_ccap_copay documenting that the percent-of- income scale is a simplified approximation of Appendix A's 176-cell daily-dollar table (kept for now per reviewer direction). - C7: Tighten wv_child_care_subsidies test margin from 1 to 0.01 and add "Case 1," prefix. - C8: Fix countable_income/sources.yaml page anchor from #page=49 (Ch.5 Sec 5.0 overview) to #page=51 (Sec 5.2.1 start of countable income lists). Test updates reflect the SMI-only income test: cases that previously asserted ineligibility above 185% FPL now use income above 85% SMI; cases that toggled wv_ccap_enrolled drop the flag; informal-age 24mo expectation flips to UNDER_2; non-tax-dependent child case asserts eligibility per residency rule; minor-parent case asserts eligibility. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../dhhr/ccap/age_group/informal_months.yaml | 9 +- .../dhhr/ccap/eligibility/min_parent_age.yaml | 11 - .../ccap/income/countable_income/sources.yaml | 2 +- .../dhhr/ccap/income/fpl_limit/initial.yaml | 13 -- .../dhhr/ccap/income/fpl_limit/ongoing.yaml | 13 -- .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 196 ++++++++---------- .../gov/states/wv/dhhr/ccap/integration.yaml | 10 +- .../states/wv/dhhr/ccap/wv_ccap_copay.yaml | 2 - .../states/wv/dhhr/ccap/wv_ccap_eligible.yaml | 15 +- .../wv/dhhr/ccap/wv_ccap_eligible_child.yaml | 7 +- .../wv/dhhr/ccap/wv_ccap_income_eligible.yaml | 32 +-- .../wv/dhhr/ccap/wv_child_care_subsidies.yaml | 4 +- .../dhhr/ccap/eligibility/wv_ccap_eligible.py | 19 +- .../eligibility/wv_ccap_eligible_child.py | 3 +- .../eligibility/wv_ccap_income_eligible.py | 22 +- .../gov/states/wv/dhhr/ccap/wv_ccap_copay.py | 8 + .../states/wv/dhhr/ccap/wv_ccap_enrolled.py | 9 - 17 files changed, 163 insertions(+), 212 deletions(-) delete mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml delete mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml delete mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml delete mode 100644 policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_enrolled.py diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml index 5f489c1bc3a..fa8e0fed508 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml @@ -9,15 +9,16 @@ metadata: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) href: https://bfa.wv.gov/media/6831/download?inline -# Maps age in months to WVCCAPInformalAgeGroup enum index: -# 0 = UNDER_2 (0-23 months) -# 1 = AGE_2_AND_OVER (24+ months) +# Maps age in months to WVCCAPInformalAgeGroup enum index, matching +# Appendix B's INFANT (0-24 months) and TODDLER+ (25+ months) bands: +# 0 = UNDER_2 (0-24 months) +# 1 = AGE_2_AND_OVER (25+ months) brackets: - threshold: 2024-01-01: 0 amount: 2024-01-01: 0 - threshold: - 2024-01-01: 24 + 2024-01-01: 25 amount: 2024-01-01: 1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml deleted file mode 100644 index ed6a03ce58d..00000000000 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/min_parent_age.yaml +++ /dev/null @@ -1,11 +0,0 @@ -description: West Virginia sets this minimum parent age under the Child Care Assistance Program. -values: - 2024-01-01: 18 - -metadata: - unit: year - period: year - label: West Virginia CCAP minimum parent age - reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 1, Section 1.1.2 — Adult Definition - href: https://bfa.wv.gov/media/6766/download?inline#page=8 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml index d7bdb736972..5ce40f209b8 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml @@ -22,4 +22,4 @@ metadata: label: West Virginia CCAP countable income sources reference: - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5, Sections 5.2.1-5.2.4 — Countable Income - href: https://bfa.wv.gov/media/6766/download?inline#page=49 + href: https://bfa.wv.gov/media/6766/download?inline#page=51 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml deleted file mode 100644 index c7171ddf1a7..00000000000 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/initial.yaml +++ /dev/null @@ -1,13 +0,0 @@ -description: West Virginia limits initial applicant income to this share of the federal poverty level under the Child Care Assistance Program. -values: - 2019-10-01: 1.5 - -metadata: - unit: /1 - period: year - label: West Virginia CCAP initial FPL limit - reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5, Section 5.0 — Overview - href: https://bfa.wv.gov/media/6766/download?inline#page=49 - - title: WV Child Care Subsidy Appendix A — Sliding Fee Scale (Oct 1, 2024) - href: https://bfa.wv.gov/media/6826/download?inline diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml deleted file mode 100644 index 3707b304996..00000000000 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit/ongoing.yaml +++ /dev/null @@ -1,13 +0,0 @@ -description: West Virginia limits ongoing recipient income to this share of the federal poverty level under the Child Care Assistance Program. -values: - 2019-10-01: 1.85 - -metadata: - unit: /1 - period: year - label: West Virginia CCAP ongoing FPL limit - reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 5, Section 5.0 — Overview - href: https://bfa.wv.gov/media/6766/download?inline#page=49 - - title: WV CCDF State Plan FFY 2025-2027, Section 2.2.3 - href: https://bfa.wv.gov/media/39915/download?inline#page=20 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 dc43be96e71..7310ea955f9 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,24 +1,26 @@ # WV CCAP Edge Case Tests +# Income test (single threshold) per CCDF Plan §2.2.4 / §2.2.5(a): +# 85% of state median income. +# WV 4-person SMI (2024-10-01) = 90_661/yr +# Family-size factors: 1p=0.52, 2p=0.68, 3p=0.84, 4p=1.00, 5p=1.16, 6p=1.32 +# 85% SMI family of 2 = 90_661 * 0.68 * 0.85 = 52_401.86/yr = 4_366.82/mo +# 85% SMI family of 3 = 90_661 * 0.84 * 0.85 = 64_731.81/yr = 5_394.32/mo +# 85% SMI family of 11 = 90_661 * 1.47 * 0.85 = 113_280.92/yr = 9_440.08/mo # 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: FPG = 26_650/yr = 2_220.83/mo -# Family of 11: FPG = 70_650/yr = 5_887.50/mo -# WV SMI 4-person base (2024-10-01): 90_661 -# Size adjustments: first=0.52, 2nd-6th=0.16, additional=0.03 +# Family of 2 FPG = 21_150/yr = 1_762.50/mo; family of 3 = 26_650/yr. # ============================================================ -# Income threshold boundaries (initial applicant) +# Income threshold boundaries (85% SMI) # ============================================================ -- name: Case 1, income at exactly 149% FPL initial applicant eligible. +- name: Case 1, income well below 85% SMI eligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 149% FPL for family of 2 = 21_150 * 1.49 = 31_513.50/yr - employment_income: 31_513 + employment_income: 24_000 immigration_status: CITIZEN person2: age: 3 @@ -40,20 +42,18 @@ members: [person1, person2] state_code: WV output: - # monthly income = 31_513 / 12 = 2_626.08 - # 150% FPL monthly = 21_150 * 1.50 / 12 = 2_643.75 - # 2_626.08 <= 2_643.75 -> eligible + # monthly income = 2_000 <= 4_366.82 -> eligible wv_ccap_income_eligible: true -- name: Case 2, income at exactly 150% FPL initial applicant eligible. +- name: Case 2, income just below 85% SMI eligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 150% FPL for family of 2 = 21_150 * 1.50 = 31_725/yr - employment_income: 31_725 + # 85% SMI family of 2 = 52_401.86/yr + employment_income: 52_000 immigration_status: CITIZEN person2: age: 3 @@ -75,20 +75,18 @@ members: [person1, person2] state_code: WV output: - # monthly income = 31_725 / 12 = 2_643.75 - # 150% FPL monthly = 21_150 * 1.50 / 12 = 2_643.75 - # 2_643.75 <= 2_643.75 -> eligible (at boundary) + # monthly income = 4_333.33 <= 4_366.82 -> eligible (at boundary) wv_ccap_income_eligible: true -- name: Case 3, income at 151% FPL initial applicant ineligible. +- name: Case 3, income just above 85% SMI ineligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 151% FPL for family of 2 = 21_150 * 1.51 = 31_936.50/yr - employment_income: 31_937 + # Just above 85% SMI family of 2 (52_401.86/yr) + employment_income: 53_000 immigration_status: CITIZEN person2: age: 3 @@ -110,179 +108,174 @@ members: [person1, person2] state_code: WV output: - # monthly income = 31_937 / 12 = 2_661.42 - # 150% FPL monthly = 21_150 * 1.50 / 12 = 2_643.75 - # 2_661.42 > 2_643.75 -> ineligible (not enrolled) + # monthly income = 4_416.67 > 4_366.82 -> ineligible wv_ccap_income_eligible: false # ============================================================ -# Income threshold boundaries (ongoing/enrolled recipient) +# Income above former two-tier FPL ceiling but below 85% SMI # ============================================================ -- name: Case 4, enrolled at 184% FPL ongoing eligible. +- name: Case 4, income above the former 185% FPL ceiling but below 85% SMI. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 184% FPL for family of 2 = 21_150 * 1.84 = 38_916/yr - employment_income: 38_916 + # 185% FPL family of 2 = 39_127.50/yr; 85% SMI family of 2 = 52_401.86/yr + employment_income: 40_000 immigration_status: CITIZEN person2: age: 3 is_tax_unit_dependent: true immigration_status: CITIZEN - wv_ccap_provider_type: CENTER - wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 - pre_subsidy_childcare_expenses: 10_000 tax_units: tax_unit: members: [person1, person2] spm_units: spm_unit: members: [person1, person2] - wv_ccap_enrolled: true - spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: members: [person1, person2] state_code: WV output: - # monthly income = 38_916 / 12 = 3_243 - # 185% FPL monthly = 21_150 * 1.85 / 12 = 3_260.63 - # 3_243 <= 3_260.63 -> eligible + # monthly income = 3_333.33 <= 4_366.82 -> eligible. + # Demonstrates that 85% SMI is the operative income test. wv_ccap_income_eligible: true -- name: Case 5, enrolled at exactly 185% FPL ongoing eligible. +- name: Case 5, income well above 85% SMI ineligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 185% FPL for family of 2 = 21_150 * 1.85 = 39_127.50/yr - employment_income: 39_127 + employment_income: 60_000 immigration_status: CITIZEN person2: age: 3 is_tax_unit_dependent: true immigration_status: CITIZEN - wv_ccap_provider_type: CENTER - wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 - pre_subsidy_childcare_expenses: 10_000 tax_units: tax_unit: members: [person1, person2] spm_units: spm_unit: members: [person1, person2] - wv_ccap_enrolled: true - spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: members: [person1, person2] state_code: WV output: - # monthly income = 39_127 / 12 = 3_260.58 - # 185% FPL monthly = 39_127.50 / 12 = 3_260.63 - # 3_260.58 <= 3_260.63 -> eligible (at boundary) - wv_ccap_income_eligible: true + # monthly income = 5_000 > 4_366.82 -> ineligible + wv_ccap_income_eligible: false -- name: Case 6, enrolled at 186% FPL ongoing ineligible. +- name: Case 6, income at 85% SMI exact boundary eligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # 186% FPL for family of 2 = 21_150 * 1.86 = 39_339/yr - employment_income: 39_339 + # 85% SMI family of 2 = 52_401.86/yr = 4_366.82/mo; + # use 52_401 to land just under the boundary. + employment_income: 52_401 immigration_status: CITIZEN person2: age: 3 is_tax_unit_dependent: true immigration_status: CITIZEN - wv_ccap_provider_type: CENTER - wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 - pre_subsidy_childcare_expenses: 10_000 tax_units: tax_unit: members: [person1, person2] spm_units: spm_unit: members: [person1, person2] - wv_ccap_enrolled: true - spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: members: [person1, person2] state_code: WV output: - # monthly income = 39_339 / 12 = 3_278.25 - # 185% FPL monthly = 39_127.50 / 12 = 3_260.63 - # 3_278.25 > 3_260.63 -> ineligible - wv_ccap_income_eligible: false + # monthly income = 4_366.75 <= 4_366.82 -> eligible (at boundary) + wv_ccap_income_eligible: true # ============================================================ -# 85% SMI cap boundary +# 85% SMI cap binds for large families # ============================================================ -- name: Case 7, income below 85% SMI but above 150% FPL for initial applicant. +- name: Case 7, large family income above 85% SMI ineligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # Above 185% FPL but under 85% SMI for family of 2 - # 185% FPL = 39_127.50; 85% SMI family of 2 = 90_661 * (0.52+0.16) * 0.85 = 52_402.06 - employment_income: 40_000 + # 85% SMI family of 11 = 113_280.92/yr = 9_440.08/mo + employment_income: 114_000 immigration_status: CITIZEN person2: age: 3 is_tax_unit_dependent: true immigration_status: CITIZEN + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person4: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person5: + age: 9 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person6: + age: 11 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person7: + age: 32 + immigration_status: CITIZEN + person8: + age: 1 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person9: + age: 2 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person10: + age: 4 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person11: + age: 6 + is_tax_unit_dependent: true + immigration_status: CITIZEN tax_units: tax_unit: - members: [person1, person2] + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] spm_units: spm_unit: - members: [person1, person2] + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] households: household: - members: [person1, person2] + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] state_code: WV output: - # monthly income = 40_000 / 12 = 3_333.33 - # 185% FPL monthly = 3_260.63 - # 3_333.33 > 3_260.63 -> fails FPL test for initial applicant + # monthly income = 9_500 > 9_440.08 -> ineligible wv_ccap_income_eligible: false -- name: Case 8, enrolled income above 85% SMI ineligible despite passing FPL. +- name: Case 8, large family income below 85% SMI eligible. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # For family of 1 (single parent, no child income): - # 85% SMI = 90_661 * 0.52 * 0.85 = 40_072.16/yr = 3_339.35/mo - # 185% FPL family of 2 = 39_127.50/yr = 3_260.63/mo - # Need income above 85% SMI but below 185% FPL - # Actually for family of 2, 85% SMI = 52_402.06 >> 185% FPL = 39_127.50 - # So SMI is not the binding constraint for small families. - # Use family of 1 (single person SPM unit with a child): - # For family of 2: 85% SMI = 52_402.06 which is very high. - # Let's test with a large family where SMI becomes binding. - # Family of 11: 85% SMI = 90_661 * (0.52 + 0.16*5 + 0.03*5) * 0.85 - # = 90_661 * 1.47 * 0.85 = 113_280.91/yr = 9_440.08/mo - # 185% FPL family of 11 = 70_650 * 1.85 = 130_702.50/yr = 10_891.88/mo - # So for large families, SMI < 185% FPL and SMI is binding. - employment_income: 114_000 + # Below 85% SMI family of 11 (113_280.92/yr) + employment_income: 100_000 immigration_status: CITIZEN person2: age: 3 @@ -329,18 +322,13 @@ spm_units: spm_unit: members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] - wv_ccap_enrolled: true households: household: members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] state_code: WV output: - # monthly income = 114_000 / 12 = 9_500 - # 185% FPL family of 11 = 70_650 * 1.85 / 12 = 10_891.88/mo -> passes - # 85% SMI family of 11 = 90_661 * (0.52 + 0.16*5 + 0.03*5) * 0.85 / 12 - # = 90_661 * 1.47 * 0.85 / 12 = 113_280.92 / 12 = 9_440.08/mo - # 9_500 > 9_440.08 -> fails SMI cap - wv_ccap_income_eligible: false + # monthly income = 8_333.33 <= 9_440.08 -> eligible + wv_ccap_income_eligible: true # ============================================================ # Zero and very high income @@ -656,7 +644,6 @@ spm_units: spm_unit: members: [person1, person2] - wv_ccap_enrolled: true spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: @@ -701,7 +688,6 @@ spm_units: spm_unit: members: [person1, person2] - wv_ccap_enrolled: true spm_unit_pre_subsidy_childcare_expenses: 10_000 households: household: @@ -1265,8 +1251,8 @@ people: person1: age: 30 - # Income above 185% FPL for family of 2 but TANF enrolled - employment_income: 40_000 + # Above 85% SMI family of 2 (52_401.86/yr); TANF enrolled bypasses + employment_income: 60_000 immigration_status: CITIZEN person2: age: 3 @@ -1624,10 +1610,10 @@ members: [person1, person2] state_code: WV output: - # 18 months < 24 -> UNDER_2 + # 18 months < 25 -> UNDER_2 wv_ccap_informal_age_group: [AGE_2_AND_OVER, UNDER_2] -- name: Case 49, informal age 2 and over group boundary. +- name: Case 49, informal age 24 months still in infant band. period: 2025-01 input: people: @@ -1635,7 +1621,7 @@ age: 30 immigration_status: CITIZEN person2: - # Age 2.0 = 24 months -> AGE_2_AND_OVER (threshold at 24) + # Age 2.0 = 24 months; Appendix B INFANT covers 0-24 months age: 2.0 is_tax_unit_dependent: true immigration_status: CITIZEN @@ -1650,8 +1636,8 @@ members: [person1, person2] state_code: WV output: - # 24 months >= 24 -> AGE_2_AND_OVER - wv_ccap_informal_age_group: [AGE_2_AND_OVER, AGE_2_AND_OVER] + # 24 months < 25 -> UNDER_2 (matches Appendix B INFANT 0-24mo at $7.50) + wv_ccap_informal_age_group: [AGE_2_AND_OVER, UNDER_2] # ============================================================ # Multiple children in one family 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 96ef635e069..acc5f875c9a 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 @@ -36,8 +36,8 @@ # === Eligibility === wv_ccap_eligible_child: [false, true] - # FPG family of 2: 21_150 - # 185% FPL = 39_127.50; monthly income = 2_000 <= 3_260.63 + # Single income test at 85% SMI: WV family-of-2 = 4_366.82/mo + # monthly income = 2_000 <= 4_366.82 -> eligible wv_ccap_income_eligible: true is_ccdf_asset_eligible: true wv_ccap_eligible: true @@ -124,7 +124,8 @@ people: person1: age: 35 - employment_income: 48_000 + # Above 85% SMI family of 2 (52_401.86/yr) + employment_income: 60_000 immigration_status: CITIZEN weekly_hours_worked: 40 person2: @@ -147,8 +148,7 @@ members: [person1, person2] state_code: WV output: - # monthly income = 4_000 > 185% monthly = 3_260.63 - # Not enrolled -> initial threshold applies + # monthly income = 5_000 > 4_366.82 (85% SMI family of 2) wv_ccap_income_eligible: false wv_ccap_eligible: false wv_ccap: 0 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 c2e7e6a5f66..e0fc2d1e73f 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 @@ -67,7 +67,6 @@ spm_units: spm_unit: members: [person1, person2] - wv_ccap_enrolled: true households: household: members: [person1, person2] @@ -97,7 +96,6 @@ spm_units: spm_unit: members: [person1, person2] - wv_ccap_enrolled: true households: household: members: [person1, person2] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml index 9d87b76212b..c91c6bf10b3 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml @@ -60,7 +60,10 @@ people: person1: age: 30 - employment_income: 48_000 + # Need income above 85% SMI for family of 2: + # WV 4-person SMI (2024-10-01) = 90,661; 2-person factor = 0.68 + # 85% SMI family of 2 = 90,661 * 0.68 * 0.85 = 52,401.86/yr + employment_income: 60_000 weekly_hours_worked: 40 person2: age: 5 @@ -77,7 +80,7 @@ members: [person1, person2] state_code: WV output: - # Income 48,000 > 185% FPL (39,127.50) -> not income eligible + # 60,000 > 52,401.86 -> not income eligible wv_ccap_eligible: false - name: Case 4, parent not meeting activity hours means not eligible. @@ -139,7 +142,7 @@ # Child age 3 < 13 -> eligible child wv_ccap_eligible: true -- name: Case 6, parent under 18 means not eligible. +- name: Case 6, minor parent in qualifying activity remains eligible. period: 2025-01 input: people: @@ -162,5 +165,7 @@ members: [person1, person2] state_code: WV output: - # Parent age 17 < 18 -> not parent age eligible - wv_ccap_eligible: false + # Manual §1.1.10, §4.5.3.6, §4.5.6 contemplate minor parents in + # qualifying activity. Parent age 17 working 25 hrs/wk meets the + # activity test; income well below 85% SMI; child age 1 eligible. + wv_ccap_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml index 87dbf43b0a0..d950bd9514b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml @@ -91,7 +91,7 @@ output: wv_ccap_eligible_child: [false, false] -- name: Case 5, non-dependent child ineligible. +- name: Case 5, non-tax-dependent child still eligible (residency, not tax dependency, governs). period: 2025-01 input: people: @@ -112,4 +112,7 @@ members: [person1, person2] state_code: WV output: - wv_ccap_eligible_child: [false, false] + # §3.2 requires the child to reside with the family, not to be a tax + # dependent. With the dependency filter removed, a co-resident child + # under 13 who is a citizen remains eligible. + wv_ccap_eligible_child: [false, true] 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 2062f182c98..789fc181d5f 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,9 +1,10 @@ # WV CCAP Income Eligibility Tests -# 2025 FPG (Contiguous US): -# first_person = 15_650, additional = 5_500 -# Family of 2: 21_150 +# Single income test per CCDF Plan §2.2.4 / §2.2.5(a): 85% of state median income. +# WV 4-person SMI (2024-10-01) = 90_661/yr +# Family-size factors: 1p=0.52, 2p=0.68, 3p=0.84, 4p=1.00, 5p=1.16, 6p=1.32 +# 85% SMI family of 2 = 90_661 * 0.68 * 0.85 = 52_401.86/yr = 4_366.82/mo -- name: Case 1, income below 185% FPL for initial applicant. +- name: Case 1, income below 85% SMI eligible. period: 2025-01 input: people: @@ -23,18 +24,16 @@ members: [person1, person2] state_code: WV output: - # FPG family of 2: 21_150 - # 185% FPL = 39_127.50 - # monthly income = 2_000; monthly limit = 3_260.63 + # monthly income = 2_000 <= 4_366.82 -> eligible wv_ccap_income_eligible: true -- name: Case 2, income above 185% FPL for new applicant. +- name: Case 2, income above 85% SMI ineligible. period: 2025-01 input: people: person1: age: 30 - employment_income: 48_000 + employment_income: 60_000 person2: age: 5 tax_units: @@ -48,16 +47,17 @@ members: [person1, person2] state_code: WV output: - # monthly income = 4_000 > 185% FPL monthly = 3_260.63 + # monthly income = 5_000 > 4_366.82 -> ineligible wv_ccap_income_eligible: false -- name: Case 3, enrolled family at 170% FPL eligible under ongoing threshold. +- name: Case 3, income at 85% SMI boundary eligible. period: 2025-01 input: people: person1: age: 30 - employment_income: 36_000 + # Just below 85% SMI for family of 2 + employment_income: 52_000 person2: age: 5 tax_units: @@ -66,14 +66,12 @@ spm_units: spm_unit: members: [person1, person2] - wv_ccap_enrolled: true households: household: members: [person1, person2] state_code: WV output: - # 185% FPL = 39_127.50; monthly = 3_260.63 - # monthly income = 3_000 <= 3_260.63 + # monthly income = 4_333.33 <= 4_366.82 -> eligible wv_ccap_income_eligible: true - name: Case 4, TANF recipients categorically eligible. @@ -97,4 +95,8 @@ members: [person1, person2] state_code: WV output: + # Income above SMI but TANF bypass applies per Manual §3.2.1. + # The bypass extends to TANF children-only cases (§3.2.1.4) that + # should still meet the income test — we don't currently model that + # distinction. wv_ccap_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml index d8775136282..d9d129a6048 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml @@ -1,6 +1,6 @@ -- name: WV child care subsidies wrapper. +- name: Case 1, WV child care subsidies wrapper. period: 2025 - absolute_error_margin: 1 + absolute_error_margin: 0.01 input: people: person1: diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py index 19beae608ca..8692aa52e89 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py @@ -13,20 +13,13 @@ class wv_ccap_eligible(Variable): ) def formula(spm_unit, period, parameters): - p = parameters(period).gov.states.wv.dhhr.ccap.eligibility + # We don't enforce a minimum parent-age floor: §1.1.10 recognizes + # emancipated minors, §1.1.13 treats them as separate families, and + # §4.5.3.6 / §4.5.6 explicitly contemplate minor parents in high + # school or home schooling. The activity requirement below carries + # the substantive caretaker check. has_eligible_child = add(spm_unit, period, ["wv_ccap_eligible_child"]) > 0 income_eligible = spm_unit("wv_ccap_income_eligible", period) asset_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) activity_eligible = spm_unit("wv_ccap_activity_eligible", period) - person = spm_unit.members - is_dependent = person("is_tax_unit_dependent", period.this_year) - age = person("age", period.this_year) - is_caretaker = ~is_dependent - parent_age_eligible = spm_unit.any(is_caretaker & (age >= p.min_parent_age)) - return ( - has_eligible_child - & income_eligible - & asset_eligible - & activity_eligible - & parent_age_eligible - ) + return has_eligible_child & income_eligible & asset_eligible & activity_eligible diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py index 7bc0c387a37..49076a5d48c 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py @@ -19,8 +19,7 @@ def formula(person, period, parameters): age_eligible = where( is_disabled, age < p.special_needs_child_age_limit, age < p.child_age_limit ) - is_dependent = person("is_tax_unit_dependent", period.this_year) immigration_eligible = person( "is_ccdf_immigration_eligible_child", period.this_year ) - return age_eligible & is_dependent & immigration_eligible + return age_eligible & immigration_eligible 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 0bb81e13830..ed93b3e65a6 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 @@ -8,20 +8,22 @@ class wv_ccap_income_eligible(Variable): definition_period = MONTH defined_for = StateCode.WV reference = ( - "https://bfa.wv.gov/media/6766/download?inline#page=49", "https://bfa.wv.gov/media/39915/download?inline#page=20", + "https://bfa.wv.gov/media/6781/download?inline", ) def formula(spm_unit, period, parameters): + # Per CCDF State Plan §2.2.4 / §2.2.5(a), WV sets its sole income + # ceiling at 85% of state median income; graduated phase-out is + # marked "Not applicable" because the threshold already sits at + # the federal CCDF ceiling. 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) - enrolled = spm_unit("wv_ccap_enrolled", period) - is_tanf = spm_unit("is_tanf_enrolled", period) - fpl_rate = where(enrolled, p.fpl_limit.ongoing, p.fpl_limit.initial) - fpl_limit = fpg * fpl_rate smi = spm_unit("hhs_smi", period) - smi_limit = smi * p.smi_rate - return is_tanf | ( - (countable_income <= fpl_limit) & (countable_income <= smi_limit) - ) + smi_eligible = countable_income <= smi * p.smi_rate + # TANF recipients are categorically income-eligible per Policy + # Manual §3.2.1. We don't currently distinguish "TANF children- + # only" cases (§3.2.1.4), which must still meet the income test; + # the bypass applies to all is_tanf_enrolled units. + is_tanf = spm_unit("is_tanf_enrolled", period) + return is_tanf | smi_eligible 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 ab9e9d36b01..bd25997c5f4 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 @@ -14,6 +14,14 @@ class wv_ccap_copay(Variable): ) def formula(spm_unit, period, parameters): + # Simplified percent-of-income approximation of Appendix A. The + # actual schedule is a 176-cell daily-dollar table (11 family sizes + # x 16 FPL bands), with the fee charged per child up to 3 per + # Manual Sec 6.4.3. The current rate.yaml is derived from the + # 3-person column as a representative middle case; see that file + # for the divergence by family size. The 7% max_share cap and the + # under-40%-FPL waiver are encoded in the rate schedule itself; + # only the foster-child waiver needs an explicit override here. 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) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_enrolled.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_enrolled.py deleted file mode 100644 index 38fec8b7863..00000000000 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_enrolled.py +++ /dev/null @@ -1,9 +0,0 @@ -from policyengine_us.model_api import * - - -class wv_ccap_enrolled(Variable): - value_type = bool - entity = SPMUnit - definition_period = MONTH - label = "Whether the family is currently enrolled in West Virginia CCAP" - defined_for = StateCode.WV From 906f1b3d092be8d91bb07eca57efa9e3b21683ea Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 14 May 2026 18:34:21 -0400 Subject: [PATCH 10/16] minor --- lessons/agent-lessons.md | 11 ---------- .../ccap/income/countable_income/sources.yaml | 9 ++++++++ policyengine_us/programs.yaml | 4 +++- .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 22 ++++++++++++------- .../eligibility/wv_ccap_eligible_child.py | 4 ++++ .../states/wv/dhhr/ccap/wv_ccap_daily_rate.py | 1 - 6 files changed, 30 insertions(+), 21 deletions(-) delete mode 100644 lessons/agent-lessons.md diff --git a/lessons/agent-lessons.md b/lessons/agent-lessons.md deleted file mode 100644 index 454c3e2b9c0..00000000000 --- a/lessons/agent-lessons.md +++ /dev/null @@ -1,11 +0,0 @@ -# Agent Lessons Learned - -Accumulated from /encode-policy-v2 and /backdate-program runs across all contributors. -Loaded by implementation agents on future runs. - -## New Lessons from West Virginia CCAP (2026-04-08) - -### PARAMETER -- When transcribing a multi-dimension lookup table (e.g., age group x quality tier x provider type), verify that row labels (age groups) are correctly aligned with their data columns; if one dimension's boundaries shift (e.g., age groups redefined), ALL rate values in that dimension must be re-read from the source — a wrong row-label mapping cascades to every value in the affected rows, not just one. -- Never invent a parameter value when no source supports it; if the regulatory document does not specify a threshold (e.g., an initial FPL limit distinct from the ongoing limit), do not fabricate one — either use the documented value for both paths or flag the gap as unverifiable. A fabricated value that looks plausible (e.g., 150% vs 185%) passes casual review and is harder to catch than a missing value. -- When a parameter represents a soft administrative guideline rather than a hard regulatory cutoff (e.g., "adults are defined as 18+" used as a general definition, not a strict eligibility bar), document this distinction in the parameter description; do not model it as a strict eligibility gate unless the regulation explicitly mandates denial for failing the criterion. diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml index 5ce40f209b8..b742f9066dd 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml @@ -15,6 +15,15 @@ values: - rental_income - veterans_benefits - military_retirement_pay + # TANF is countable per Manual Sec 5.2.4.3 but excluded here to avoid + # a circular dependency: + # wv_ccap_countable_income -> tanf -> wv_works + # -> wv_works_countable_earned_income (deducts childcare_expenses) + # -> childcare_expenses -> wv_ccap -> wv_ccap_income_eligible + # -> wv_ccap_countable_income + # The is_tanf_enrolled bypass in wv_ccap_income_eligible already + # makes TANF-active families categorically income-eligible. + # - tanf # would belong here metadata: unit: list diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 76b5377b5f3..6f3607ed289 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -550,9 +550,11 @@ programs: full_name: Vermont Child Care Financial Assistance Program variable: vt_ccfap - state: WV - status: in_progress + status: complete name: West Virginia CCAP full_name: West Virginia Child Care Assistance Program + variable: wv_ccap + parameter_prefix: gov.states.wv.dhhr.ccap - id: head_start name: Head Start 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 7310ea955f9..3bc8178ebd8 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 @@ -15,7 +15,6 @@ - name: Case 1, income well below 85% SMI eligible. period: 2025-01 - absolute_error_margin: 0.01 input: people: person1: @@ -47,7 +46,6 @@ - name: Case 2, income just below 85% SMI eligible. period: 2025-01 - absolute_error_margin: 0.01 input: people: person1: @@ -80,7 +78,6 @@ - name: Case 3, income just above 85% SMI ineligible. period: 2025-01 - absolute_error_margin: 0.01 input: people: person1: @@ -117,7 +114,6 @@ - name: Case 4, income above the former 185% FPL ceiling but below 85% SMI. period: 2025-01 - absolute_error_margin: 0.01 input: people: person1: @@ -146,7 +142,6 @@ - name: Case 5, income well above 85% SMI ineligible. period: 2025-01 - absolute_error_margin: 0.01 input: people: person1: @@ -173,7 +168,6 @@ - name: Case 6, income at 85% SMI exact boundary eligible. period: 2025-01 - absolute_error_margin: 0.01 input: people: person1: @@ -206,7 +200,6 @@ - name: Case 7, large family income above 85% SMI ineligible. period: 2025-01 - absolute_error_margin: 0.01 input: people: person1: @@ -269,7 +262,6 @@ - name: Case 8, large family income below 85% SMI eligible. period: 2025-01 - absolute_error_margin: 0.01 input: people: person1: @@ -1695,3 +1687,17 @@ # -> 3.0% bracket (>= 0.7001) # copay = 1_666.67 * 0.03 = 50 wv_ccap_copay: 50 + + # Person2 (FAMILY_HOME Tier II Infant, 5 days/wk, 6_000/yr): + # monthly expenses = 500; days/mo = 5 * 52/12 = 21.667 + # daily_charge = 500/21.667 = 23.077; daily_benefit = min(33, 23.077) = 23.077 + # reimbursement = 23.077 * 21.667 = 500 + # Person3 (CENTER Tier I School-Age, 3 days/wk, 4_000/yr): + # monthly expenses = 333.33; days/mo = 3 * 52/12 = 13 + # daily_charge = 333.33/13 = 25.641; daily_benefit = min(32, 25.641) = 25.641 + # reimbursement = 25.641 * 13 = 333.33 + # total reimbursement = 833.33 + # monthly pre_subsidy = 10_000/12 = 833.33 + # uncapped = max(833.33 - 50, 0) = 783.33 + # benefit = min(783.33, 833.33) = 783.33 + wv_ccap: 783.33 diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py index 49076a5d48c..ae94d306101 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py @@ -13,6 +13,10 @@ class wv_ccap_eligible_child(Variable): ) def formula(person, period, parameters): + # Manual Sec 3.1.2 extends eligibility to ages 13-17 if EITHER the + # child is under court supervision (Sec 3.1.2.1) OR has special + # needs (Sec 3.1.2.2). We only model the special-needs branch + # because we don't track court-supervision status at the moment. p = parameters(period).gov.states.wv.dhhr.ccap.eligibility age = person("age", period.this_year) is_disabled = person("is_disabled", period.this_year) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py index 9c0c364b537..74fff8dabb3 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py @@ -42,5 +42,4 @@ def formula(person, period, parameters): out_of_school_rate, informal_rate, ], - default=center_rate, ) From 2153bd630c71adcc0218fe4667a011b910bb3b07 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 14 May 2026 22:01:13 -0400 Subject: [PATCH 11/16] fix --- .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 28 +++++++++++++++++++ .../eligibility/wv_ccap_activity_eligible.py | 8 +++++- uv.lock | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) 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 3bc8178ebd8..dc7599f97a1 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 @@ -1701,3 +1701,31 @@ # uncapped = max(833.33 - 50, 0) = 783.33 # benefit = min(783.33, 833.33) = 783.33 wv_ccap: 783.33 + +# ============================================================ +# Child-only SPM unit cannot pass activity test +# ============================================================ + +- name: Case 51, child-only SPM unit fails activity test. + period: 2025-01 + input: + people: + person1: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: WV + output: + # No head/spouse caretaker present -> activity test must fail, + # otherwise child-only units would pass on income + assets alone. + wv_ccap_activity_eligible: false + wv_ccap_eligible: false diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py index 5a05198a580..7f116fdadd6 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py @@ -17,4 +17,10 @@ def formula(spm_unit, period, parameters): meets_work_requirement = hours_worked >= p.activity_hours is_student = person("is_full_time_student", period.this_year) individually_eligible = meets_work_requirement | is_student - return spm_unit.sum(is_head_or_spouse & ~individually_eligible) == 0 + # A unit with no head or spouse (e.g., a child-only record) has no + # caretaker to be in a qualifying activity and must not pass. + has_caretaker = spm_unit.sum(is_head_or_spouse) > 0 + no_ineligible_caretaker = ( + spm_unit.sum(is_head_or_spouse & ~individually_eligible) == 0 + ) + return has_caretaker & no_ineligible_caretaker diff --git a/uv.lock b/uv.lock index 76042ff3b95..040a348fa5b 100644 --- a/uv.lock +++ b/uv.lock @@ -2974,7 +2974,7 @@ wheels = [ [[package]] name = "policyengine-us" -version = "1.691.7" +version = "1.691.10" source = { editable = "." } dependencies = [ { name = "microdf-python" }, From a68de30dc6dc68b2f4c566cf59df2c4fbdb4ed60 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 19 May 2026 16:27:30 -0400 Subject: [PATCH 12/16] Address WV CCAP review findings: income test, copay, billing rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace 85% SMI sole income cap with 185% FPL Appendix A intake cap per Manual §3.2.1. Remove orphan smi_rate parameter. - Multiply copay by number of eligible children, capped at 3, per Manual §6.4.3 per-child fee structure. - Implement Manual §7.2.7.3-7.2.7.4 piecewise billing rule (Monthly Rate = 20 × daily when 13-20 attendance days; per-day otherwise); cap per-child reimbursement at actual provider charge. - Register wv_child_care_subsidies in spm_unit_benefits aggregator and household_state_benefits.yaml so benefits flow to poverty measures. - Delete unreachable minor-parent test case (Case 6) and update docstring to note the modeling gap; trim multi-line policy comments. - Fix #page=1 anchors on Appendix B and Sliding Fee Scale references; copay rate now cites State Plan #page=40 instead of #page=39. - Add wv_ccap_activity_eligible.yaml test (6 cases covering work-hour, student, two-parent, and child-only branches). - Recalibrate income-threshold edge cases to 185% FPL boundaries. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../household/household_state_benefits.yaml | 2 + .../dhhr/ccap/age_group/informal_months.yaml | 6 +- .../states/wv/dhhr/ccap/age_group/months.yaml | 7 +- .../ccap/billing/monthly_rate_max_days.yaml | 11 ++ .../ccap/billing/monthly_rate_min_days.yaml | 11 ++ .../ccap/copayment/max_billed_children.yaml | 11 ++ .../states/wv/dhhr/ccap/copayment/rate.yaml | 14 +- .../dhhr/ccap/eligibility/activity_hours.yaml | 2 +- .../states/wv/dhhr/ccap/income/fpl_limit.yaml | 13 ++ .../states/wv/dhhr/ccap/income/smi_rate.yaml | 13 -- .../gov/states/wv/dhhr/ccap/rates/center.yaml | 2 +- .../wv/dhhr/ccap/rates/family_facility.yaml | 2 +- .../wv/dhhr/ccap/rates/family_home.yaml | 2 +- .../wv/dhhr/ccap/rates/informal_relative.yaml | 2 +- .../dhhr/ccap/rates/out_of_school_time.yaml | 2 +- .../supplements/non_traditional_hours.yaml | 2 +- .../dhhr/ccap/supplements/special_needs.yaml | 2 +- .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 127 +++++++------- .../gov/states/wv/dhhr/ccap/integration.yaml | 7 +- .../dhhr/ccap/wv_ccap_activity_eligible.yaml | 155 ++++++++++++++++++ .../wv/dhhr/ccap/wv_ccap_daily_benefit.yaml | 38 ++--- .../states/wv/dhhr/ccap/wv_ccap_eligible.yaml | 46 +----- .../wv/dhhr/ccap/wv_ccap_income_eligible.yaml | 29 ++-- .../eligibility/wv_ccap_activity_eligible.py | 5 +- .../dhhr/ccap/eligibility/wv_ccap_eligible.py | 7 +- .../eligibility/wv_ccap_eligible_child.py | 6 +- .../eligibility/wv_ccap_income_eligible.py | 21 +-- .../gov/states/wv/dhhr/ccap/wv_ccap.py | 25 ++- .../dhhr/ccap/wv_ccap_child_age_category.py | 2 +- .../gov/states/wv/dhhr/ccap/wv_ccap_copay.py | 34 ++-- .../states/wv/dhhr/ccap/wv_ccap_daily_rate.py | 2 +- .../dhhr/ccap/wv_ccap_informal_age_group.py | 2 +- .../ccap/wv_ccap_non_traditional_hours.py | 1 + .../wv/dhhr/ccap/wv_ccap_provider_type.py | 2 +- .../wv/dhhr/ccap/wv_ccap_quality_tier.py | 2 +- .../income/spm_unit/spm_unit_benefits.py | 2 + 36 files changed, 375 insertions(+), 242 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_max_days.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_min_days.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit.yaml delete mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_activity_eligible.yaml diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index b74241a36b5..a36fbd61fef 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -117,6 +117,8 @@ values: - tx_ssi_state_supplement # Virginia benefits - va_child_care_subsidies + # West Virginia benefits + - wv_child_care_subsidies # North Carolina benefits - nc_scca # South Carolina benefits diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml index fa8e0fed508..b53eb1c5471 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml @@ -7,12 +7,8 @@ metadata: label: West Virginia CCAP informal care age group by months reference: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) - href: https://bfa.wv.gov/media/6831/download?inline + href: https://bfa.wv.gov/media/6831/download?inline#page=1 -# Maps age in months to WVCCAPInformalAgeGroup enum index, matching -# Appendix B's INFANT (0-24 months) and TODDLER+ (25+ months) bands: -# 0 = UNDER_2 (0-24 months) -# 1 = AGE_2_AND_OVER (25+ months) brackets: - threshold: 2024-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml index 6a7222c15ff..d8443b9769e 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml @@ -7,13 +7,8 @@ metadata: label: West Virginia CCAP child age group by months reference: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) - href: https://bfa.wv.gov/media/6831/download?inline + href: https://bfa.wv.gov/media/6831/download?inline#page=1 -# Maps age in months to WVCCAPChildAgeCategory enum index: -# 0 = INFANT (0-24 months) -# 1 = TODDLER (25-36 months) -# 2 = PRESCHOOL (37-59 months) -# 3 = SCHOOL_AGE (60+ months) brackets: - threshold: 2024-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_max_days.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_max_days.yaml new file mode 100644 index 00000000000..de7a584d9a1 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_max_days.yaml @@ -0,0 +1,11 @@ +description: West Virginia bills child care at the monthly rate when attendance days per month do not exceed this threshold under the Child Care Assistance Program; this value also caps the monthly billed days. +values: + 2024-10-01: 20 + +metadata: + unit: day + period: year + label: West Virginia CCAP monthly rate billing maximum days + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 7, Section 7.2.7.4 — Monthly Rate + href: https://bfa.wv.gov/media/6766/download?inline#page=79 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_min_days.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_min_days.yaml new file mode 100644 index 00000000000..056d75fa6ce --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_min_days.yaml @@ -0,0 +1,11 @@ +description: West Virginia bills child care at the monthly rate when attendance days per month equal or exceed this threshold under the Child Care Assistance Program. +values: + 2024-10-01: 13 + +metadata: + unit: day + period: year + label: West Virginia CCAP monthly rate billing minimum days + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 7, Section 7.2.7.3 — Monthly Rate + href: https://bfa.wv.gov/media/6766/download?inline#page=79 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml new file mode 100644 index 00000000000..9dc03d7be8b --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml @@ -0,0 +1,11 @@ +description: West Virginia caps the co-payment at this number of children under the Child Care Assistance Program. +values: + 2024-10-01: 3 + +metadata: + unit: int + period: year + label: West Virginia CCAP maximum billed children + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 6, Section 6.4.3 — Family Fees + href: https://bfa.wv.gov/media/6766/download?inline#page=64 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml index b43816d67c3..7ae7d89de20 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml @@ -1,4 +1,4 @@ -description: West Virginia sets this co-payment share of income by federal poverty level ratio under the Child Care Assistance Program. +description: West Virginia sets this co-payment share of income per child by federal poverty level ratio under the Child Care Assistance Program. metadata: type: single_amount threshold_unit: /1 @@ -7,15 +7,13 @@ metadata: label: West Virginia CCAP co-payment rate by FPL ratio reference: - title: WV Child Care Subsidy Appendix A — Sliding Fee Scale (Oct 1, 2024) - href: https://bfa.wv.gov/media/6826/download?inline + href: https://bfa.wv.gov/media/6826/download?inline#page=1 - title: WV CCDF State Plan FFY 2025-2027, Section 3.1.2 — Sliding Fee Scale - href: https://bfa.wv.gov/media/39915/download?inline#page=39 + href: https://bfa.wv.gov/media/39915/download?inline#page=40 -# Simplified percentage approximation of the 176-cell sliding fee scale. -# Derived from the 3-person family column in Appendix A as a representative -# middle case. Actual daily dollar fees vary by family size; this percentage -# approximation produces reasonable copay amounts across family sizes. -# The 7% cap (max_share parameter) provides an upper bound per CCDF rules. +# Percentage approximation of the Appendix A daily fee schedule, derived from +# the 3-person family column. The wv_ccap_copay formula multiplies by the +# number of eligible children (capped at 3 per Manual §6.4.3). brackets: - threshold: 2024-10-01: 0 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml index 0d4ab91a520..3420a339e05 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml @@ -4,7 +4,7 @@ values: metadata: unit: hour - period: week + period: year label: West Virginia CCAP minimum weekly activity hours reference: - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.6.1 — Working Recipients diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit.yaml new file mode 100644 index 00000000000..da6881f90cc --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit.yaml @@ -0,0 +1,13 @@ +description: West Virginia limits income to this share of the federal poverty guideline under the Child Care Assistance Program. +values: + 2024-10-01: 1.85 + +metadata: + unit: /1 + period: year + label: West Virginia CCAP income limit as share of federal poverty guideline + reference: + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.2.1 — Income Eligibility + href: https://bfa.wv.gov/media/6766/download?inline#page=25 + - title: WV Child Care Subsidy Appendix A — Sliding Fee Scale (Oct 1, 2024) + href: https://bfa.wv.gov/media/6826/download?inline#page=1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml deleted file mode 100644 index c8675c9d92b..00000000000 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/smi_rate.yaml +++ /dev/null @@ -1,13 +0,0 @@ -description: West Virginia limits income to this share of the state median income under the Child Care Assistance Program. -values: - 2024-01-01: 0.85 - -metadata: - unit: /1 - period: year - label: West Virginia CCAP SMI rate - reference: - - title: WV CCDF State Plan FFY 2025-2027, Section 2.2.4 - href: https://bfa.wv.gov/media/39915/download?inline#page=20 - - title: WV 2024 State Median Income Chart - href: https://bfa.wv.gov/media/6781/download?inline diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml index 5bece5a0a0c..a8b6e3ed954 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/center.yaml @@ -8,7 +8,7 @@ metadata: - wv_ccap_child_age_category reference: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) - href: https://bfa.wv.gov/media/6831/download?inline + href: https://bfa.wv.gov/media/6831/download?inline#page=1 TIER_I: INFANT: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml index 64ca0918478..3c714ef3e0f 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_facility.yaml @@ -8,7 +8,7 @@ metadata: - wv_ccap_child_age_category reference: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) - href: https://bfa.wv.gov/media/6831/download?inline + href: https://bfa.wv.gov/media/6831/download?inline#page=1 TIER_I: INFANT: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml index 7fdb3c13284..fcf74de6b48 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/family_home.yaml @@ -8,7 +8,7 @@ metadata: - wv_ccap_child_age_category reference: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) - href: https://bfa.wv.gov/media/6831/download?inline + href: https://bfa.wv.gov/media/6831/download?inline#page=1 TIER_I: INFANT: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/informal_relative.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/informal_relative.yaml index 1053ece84d9..f4ef47e7f26 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/informal_relative.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/informal_relative.yaml @@ -7,7 +7,7 @@ metadata: - wv_ccap_informal_age_group reference: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) - href: https://bfa.wv.gov/media/6831/download?inline + href: https://bfa.wv.gov/media/6831/download?inline#page=1 UNDER_2: 2024-10-01: 7.5 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/out_of_school_time.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/out_of_school_time.yaml index b4ad81e8810..58ee26abb9a 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/out_of_school_time.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/rates/out_of_school_time.yaml @@ -8,4 +8,4 @@ metadata: label: West Virginia CCAP out of school time daily rate reference: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) - href: https://bfa.wv.gov/media/6831/download?inline + href: https://bfa.wv.gov/media/6831/download?inline#page=1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/non_traditional_hours.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/non_traditional_hours.yaml index 38c43257cf4..cac020199d3 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/non_traditional_hours.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/non_traditional_hours.yaml @@ -8,4 +8,4 @@ metadata: label: West Virginia CCAP non-traditional hours supplement reference: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) - href: https://bfa.wv.gov/media/6831/download?inline + href: https://bfa.wv.gov/media/6831/download?inline#page=1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/special_needs.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/special_needs.yaml index de494345e49..7fd7e8a8d8d 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/special_needs.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/supplements/special_needs.yaml @@ -8,4 +8,4 @@ metadata: label: West Virginia CCAP special needs supplement reference: - title: WV Child Care Subsidy Appendix B — Rate Structure (Oct 1, 2024) - href: https://bfa.wv.gov/media/6831/download?inline + href: https://bfa.wv.gov/media/6831/download?inline#page=1 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 dc7599f97a1..d4a19382532 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,19 +1,16 @@ # WV CCAP Edge Case Tests -# Income test (single threshold) per CCDF Plan §2.2.4 / §2.2.5(a): -# 85% of state median income. -# WV 4-person SMI (2024-10-01) = 90_661/yr -# Family-size factors: 1p=0.52, 2p=0.68, 3p=0.84, 4p=1.00, 5p=1.16, 6p=1.32 -# 85% SMI family of 2 = 90_661 * 0.68 * 0.85 = 52_401.86/yr = 4_366.82/mo -# 85% SMI family of 3 = 90_661 * 0.84 * 0.85 = 64_731.81/yr = 5_394.32/mo -# 85% SMI family of 11 = 90_661 * 1.47 * 0.85 = 113_280.92/yr = 9_440.08/mo -# 2025 FPG (Contiguous US): first_person = 15_650, additional = 5_500 +# 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 # ============================================================ -# Income threshold boundaries (85% SMI) +# Income threshold boundaries (185% FPL) # ============================================================ -- name: Case 1, income well below 85% SMI eligible. +- name: Case 1, income well below 185% FPL eligible. period: 2025-01 input: people: @@ -41,17 +38,17 @@ members: [person1, person2] state_code: WV output: - # monthly income = 2_000 <= 4_366.82 -> eligible + # $24,000/yr is well below 185% FPL family of 2 ($39,127.50/yr) → eligible. wv_ccap_income_eligible: true -- name: Case 2, income just below 85% SMI eligible. +- name: Case 2, income just below 185% FPL eligible. period: 2025-01 input: people: person1: age: 30 - # 85% SMI family of 2 = 52_401.86/yr - employment_income: 52_000 + # 185% FPL family of 2 = $39,127.50/yr + employment_income: 39_000 immigration_status: CITIZEN person2: age: 3 @@ -73,17 +70,17 @@ members: [person1, person2] state_code: WV output: - # monthly income = 4_333.33 <= 4_366.82 -> eligible (at boundary) + # $39,000/yr ≤ $39,127.50 → eligible (just below boundary). wv_ccap_income_eligible: true -- name: Case 3, income just above 85% SMI ineligible. +- name: Case 3, income just above 185% FPL ineligible. period: 2025-01 input: people: person1: age: 30 - # Just above 85% SMI family of 2 (52_401.86/yr) - employment_income: 53_000 + # Just above 185% FPL family of 2 ($39,127.50/yr) + employment_income: 39_200 immigration_status: CITIZEN person2: age: 3 @@ -105,42 +102,45 @@ members: [person1, person2] state_code: WV output: - # monthly income = 4_416.67 > 4_366.82 -> ineligible + # $39,200/yr > $39,127.50 → ineligible (just above boundary). wv_ccap_income_eligible: false # ============================================================ -# Income above former two-tier FPL ceiling but below 85% SMI +# Family of 3 boundaries # ============================================================ -- name: Case 4, income above the former 185% FPL ceiling but below 85% SMI. +- name: Case 4, family of 3 income below 185% FPL eligible. period: 2025-01 input: people: person1: age: 30 - # 185% FPL family of 2 = 39_127.50/yr; 85% SMI family of 2 = 52_401.86/yr - employment_income: 40_000 + # 185% FPL family of 3 = $49,302.50/yr + employment_income: 48_000 immigration_status: CITIZEN person2: age: 3 is_tax_unit_dependent: true immigration_status: CITIZEN + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN tax_units: tax_unit: - members: [person1, person2] + members: [person1, person2, person3] spm_units: spm_unit: - members: [person1, person2] + members: [person1, person2, person3] households: household: - members: [person1, person2] + members: [person1, person2, person3] state_code: WV output: - # monthly income = 3_333.33 <= 4_366.82 -> eligible. - # Demonstrates that 85% SMI is the operative income test. + # $48,000/yr ≤ $49,302.50 → eligible. wv_ccap_income_eligible: true -- name: Case 5, income well above 85% SMI ineligible. +- name: Case 5, income well above 185% FPL ineligible. period: 2025-01 input: people: @@ -163,49 +163,52 @@ members: [person1, person2] state_code: WV output: - # monthly income = 5_000 > 4_366.82 -> ineligible + # $60,000/yr > $39,127.50 → ineligible. wv_ccap_income_eligible: false -- name: Case 6, income at 85% SMI exact boundary eligible. +- name: Case 6, family of 3 income above 185% FPL ineligible. period: 2025-01 input: people: person1: age: 30 - # 85% SMI family of 2 = 52_401.86/yr = 4_366.82/mo; - # use 52_401 to land just under the boundary. - employment_income: 52_401 + # Just above 185% FPL family of 3 ($49,302.50/yr) + employment_income: 50_000 immigration_status: CITIZEN person2: age: 3 is_tax_unit_dependent: true immigration_status: CITIZEN + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN tax_units: tax_unit: - members: [person1, person2] + members: [person1, person2, person3] spm_units: spm_unit: - members: [person1, person2] + members: [person1, person2, person3] households: household: - members: [person1, person2] + members: [person1, person2, person3] state_code: WV output: - # monthly income = 4_366.75 <= 4_366.82 -> eligible (at boundary) - wv_ccap_income_eligible: true + # $50,000/yr > $49,302.50 → ineligible. + wv_ccap_income_eligible: false # ============================================================ -# 85% SMI cap binds for large families +# Large family income boundaries # ============================================================ -- name: Case 7, large family income above 85% SMI ineligible. +- name: Case 7, large family income above 185% FPL ineligible. period: 2025-01 input: people: person1: age: 30 - # 85% SMI family of 11 = 113_280.92/yr = 9_440.08/mo - employment_income: 114_000 + # 185% FPL family of 11 = $130,702.50/yr + employment_income: 131_000 immigration_status: CITIZEN person2: age: 3 @@ -257,16 +260,16 @@ members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] state_code: WV output: - # monthly income = 9_500 > 9_440.08 -> ineligible + # $131,000/yr > $130,702.50 → ineligible. wv_ccap_income_eligible: false -- name: Case 8, large family income below 85% SMI eligible. +- name: Case 8, large family income below 185% FPL eligible. period: 2025-01 input: people: person1: age: 30 - # Below 85% SMI family of 11 (113_280.92/yr) + # Below 185% FPL family of 11 ($130,702.50/yr) employment_income: 100_000 immigration_status: CITIZEN person2: @@ -319,7 +322,7 @@ members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] state_code: WV output: - # monthly income = 8_333.33 <= 9_440.08 -> eligible + # $100,000/yr ≤ $130,702.50 → eligible. wv_ccap_income_eligible: true # ============================================================ @@ -1243,7 +1246,7 @@ people: person1: age: 30 - # Above 85% SMI family of 2 (52_401.86/yr); TANF enrolled bypasses + # Above 185% FPL family of 2 ($39,127.50/yr); TANF enrolled bypasses. employment_income: 60_000 immigration_status: CITIZEN person2: @@ -1682,25 +1685,21 @@ # Person3 age 6 = 72 months -> SCHOOL_AGE wv_ccap_child_age_category: [SCHOOL_AGE, INFANT, SCHOOL_AGE] - # FPG family of 3: 26_650 - # FPL ratio = (20_000/12) / (26_650/12) = 1_666.67 / 2_220.83 = 0.7505 - # -> 3.0% bracket (>= 0.7001) - # copay = 1_666.67 * 0.03 = 50 - wv_ccap_copay: 50 + # FPL ratio = (20_000/12) / (26_650/12) = 0.7505 → 3.0% bracket. + # per_child_copay = 1_666.67 × 0.03 = 50; 2 eligible children → 100. + wv_ccap_copay: 100 # Person2 (FAMILY_HOME Tier II Infant, 5 days/wk, 6_000/yr): - # monthly expenses = 500; days/mo = 5 * 52/12 = 21.667 - # daily_charge = 500/21.667 = 23.077; daily_benefit = min(33, 23.077) = 23.077 - # reimbursement = 23.077 * 21.667 = 500 + # monthly expenses 500; actual_days 21.67 (>20 → per-day billing). + # daily_charge = 500/21.667 = 23.077; daily_benefit = min(33, 23.077) = 23.077. + # per_child_reimbursement = min(23.077 × 21.667, 500) = 500. # Person3 (CENTER Tier I School-Age, 3 days/wk, 4_000/yr): - # monthly expenses = 333.33; days/mo = 3 * 52/12 = 13 - # daily_charge = 333.33/13 = 25.641; daily_benefit = min(32, 25.641) = 25.641 - # reimbursement = 25.641 * 13 = 333.33 - # total reimbursement = 833.33 - # monthly pre_subsidy = 10_000/12 = 833.33 - # uncapped = max(833.33 - 50, 0) = 783.33 - # benefit = min(783.33, 833.33) = 783.33 - wv_ccap: 783.33 + # monthly expenses 333.33; actual_days 13 (in 13-20 → monthly billing, 20 days). + # daily_charge = 333.33/13 = 25.641; daily_benefit = min(32, 25.641) = 25.641. + # per_child_reimbursement = min(25.641 × 20, 333.33) = 333.33. + # total reimbursement = 833.33; monthly pre_subsidy = 833.33. + # uncapped = max(833.33 - 100, 0) = 733.33; benefit = min(733.33, 833.33) = 733.33. + wv_ccap: 733.33 # ============================================================ # Child-only SPM unit cannot pass activity test 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 acc5f875c9a..11e06576d18 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 @@ -36,8 +36,7 @@ # === Eligibility === wv_ccap_eligible_child: [false, true] - # Single income test at 85% SMI: WV family-of-2 = 4_366.82/mo - # monthly income = 2_000 <= 4_366.82 -> eligible + # 185% FPL family of 2 = $39,127.50/yr; $24,000/yr → eligible. wv_ccap_income_eligible: true is_ccdf_asset_eligible: true wv_ccap_eligible: true @@ -124,7 +123,7 @@ people: person1: age: 35 - # Above 85% SMI family of 2 (52_401.86/yr) + # Above 185% FPL family of 2 ($39,127.50/yr). employment_income: 60_000 immigration_status: CITIZEN weekly_hours_worked: 40 @@ -148,7 +147,7 @@ members: [person1, person2] state_code: WV output: - # monthly income = 5_000 > 4_366.82 (85% SMI family of 2) + # $60,000/yr > 185% FPL family of 2 ($39,127.50/yr). wv_ccap_income_eligible: false wv_ccap_eligible: false wv_ccap: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_activity_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_activity_eligible.yaml new file mode 100644 index 00000000000..e988159fff6 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_activity_eligible.yaml @@ -0,0 +1,155 @@ +# WV CCAP activity eligibility tests +# Per Manual §3.6.1, all parents/heads/spouses must work ≥20 hours/week OR be +# in school/training. Single-parent units use the head's status; two-parent +# units require BOTH parents to qualify. + +- name: Case 1, single parent working 20 hours per week eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked: 20 + person2: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_activity_eligible: true + +- name: Case 2, single parent working under 20 hours per week ineligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 12_000 + weekly_hours_worked: 15 + is_full_time_student: false + person2: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_activity_eligible: false + +- name: Case 3, single parent who is a full-time student eligible. + period: 2025-01 + input: + people: + person1: + age: 22 + employment_income: 0 + weekly_hours_worked: 0 + is_full_time_student: true + person2: + age: 3 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_activity_eligible: true + +- name: Case 4, two-parent family with both parents meeting requirement eligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked: 30 + person2: + age: 28 + employment_income: 18_000 + weekly_hours_worked: 25 + person3: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: WV + output: + wv_ccap_activity_eligible: true + +- name: Case 5, two-parent family with one parent not meeting requirement ineligible. + period: 2025-01 + input: + people: + person1: + age: 30 + employment_income: 24_000 + weekly_hours_worked: 30 + person2: + age: 28 + employment_income: 6_000 + weekly_hours_worked: 10 + is_full_time_student: false + person3: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: WV + output: + wv_ccap_activity_eligible: false + +- name: Case 6, child-only SPM unit has no caretaker and fails. + period: 2025-01 + input: + people: + person1: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: WV + output: + wv_ccap_activity_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml index 44a151aaad8..28be2507245 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml @@ -1,7 +1,7 @@ # WV CCAP daily benefit tests -# Daily benefit per child = min(rate, actual daily charge) +# Daily benefit per child = min(rate + supplements, daily_charge) -- name: Case 1, rate minus copay share gives positive benefit. +- name: Case 1, daily benefit capped by provider charge. period: 2025-01 absolute_error_margin: 0.01 input: @@ -10,8 +10,8 @@ age: 30 employment_income: 24_000 person2: + # Age 3 → 36 months → TODDLER. age: 3 - # 3 years = 36 months -> TODDLER (25-36mo) is_tax_unit_dependent: true childcare_days_per_week: 5 wv_ccap_provider_type: CENTER @@ -28,11 +28,11 @@ members: [person1, person2] state_code: WV output: - # Center Tier I Toddler = $37/day - # Daily rate for this child = $37 - wv_ccap_daily_rate: [0, 37] + # Center Tier I Toddler = $37/day; daily_charge = (8_000/12)/21.67 = $30.77. + # daily_benefit = min(37, 30.77) = 30.77. + wv_ccap_daily_benefit: [0, 30.77] -- name: Case 2, zero copay means full rate as benefit. +- name: Case 2, daily benefit pays full rate when charge exceeds rate. period: 2025-01 absolute_error_margin: 0.01 input: @@ -46,7 +46,7 @@ childcare_days_per_week: 5 wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_II - pre_subsidy_childcare_expenses: 10_000 + pre_subsidy_childcare_expenses: 15_000 tax_units: tax_unit: members: [person1, person2] @@ -58,12 +58,11 @@ members: [person1, person2] state_code: WV output: - # Below 40% FPL -> $0 copay - # Center Tier II Infant = $42/day - # Full rate as daily benefit - wv_ccap_daily_rate: [0, 42] + # Center Tier II Infant = $42/day; daily_charge = (15_000/12)/21.67 = $57.69. + # daily_benefit = min(42, 57.69) = 42. + wv_ccap_daily_benefit: [0, 42] -- name: Case 3, non-traditional hours supplement adds $6/day. +- name: Case 3, non-traditional hours supplement adds 6 dollars per day. period: 2025-01 absolute_error_margin: 0.01 input: @@ -72,14 +71,14 @@ age: 30 employment_income: 6_000 person2: + # Age 3 → 36 months → TODDLER. age: 3 - # 3 years = 36 months -> TODDLER (25-36mo) is_tax_unit_dependent: true childcare_days_per_week: 5 wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I wv_ccap_non_traditional_hours: true - pre_subsidy_childcare_expenses: 12_000 + pre_subsidy_childcare_expenses: 15_000 tax_units: tax_unit: members: [person1, person2] @@ -91,10 +90,7 @@ members: [person1, person2] state_code: WV output: - # Below 40% FPL -> $0 copay - # Center Tier I Toddler = $37/day - # Non-traditional hours supplement = $6/day - # total_rate = 37 + 6 = $43/day - # daily_charge = 12_000 / (5 * 52/12) = 12_000 / 21.6667 = $553.85/day - # min(43, 553.85) = $43/day + # Center Tier I Toddler = $37/day; non-traditional supplement = $6/day. + # total_rate = 43; daily_charge = (15_000/12)/21.67 = $57.69. + # daily_benefit = min(43, 57.69) = 43. wv_ccap_daily_benefit: [0, 43] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml index c91c6bf10b3..49f49b3201e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible.yaml @@ -24,9 +24,9 @@ members: [person1, person2] state_code: WV output: - # Child age 5 < 13 -> eligible child - # Income 24,000 < 185% FPL (39,127.50) -> income eligible - # Parent works 30 hrs >= 20 -> activity eligible + # Child age 5 is under the 13-year limit. + # Income $24,000 is below 185% FPL for a family of 2 ($39,127.50). + # Parent works 30 hours per week, meeting the 20-hour activity test. wv_ccap_eligible: true - name: Case 2, no eligible child means not eligible. @@ -60,9 +60,7 @@ people: person1: age: 30 - # Need income above 85% SMI for family of 2: - # WV 4-person SMI (2024-10-01) = 90,661; 2-person factor = 0.68 - # 85% SMI family of 2 = 90,661 * 0.68 * 0.85 = 52,401.86/yr + # Income above 185% FPL for family of 2 (185% × $21,150 = $39,127.50/yr). employment_income: 60_000 weekly_hours_worked: 40 person2: @@ -80,7 +78,7 @@ members: [person1, person2] state_code: WV output: - # 60,000 > 52,401.86 -> not income eligible + # $60,000/yr is above 185% FPL for a family of 2 ($39,127.50) → not income eligible. wv_ccap_eligible: false - name: Case 4, parent not meeting activity hours means not eligible. @@ -137,35 +135,7 @@ members: [person1, person2, person3] state_code: WV output: - # Both parents work >= 20 hrs -> activity eligible - # Combined income: 30,000 < 185% FPL-3 (49,302.50) -> income eligible - # Child age 3 < 13 -> eligible child - wv_ccap_eligible: true - -- name: Case 6, minor parent in qualifying activity remains eligible. - period: 2025-01 - input: - people: - person1: - age: 17 - employment_income: 12_000 - weekly_hours_worked: 25 - person2: - age: 1 - is_tax_unit_dependent: true - childcare_hours_per_week: 40 - tax_units: - tax_unit: - members: [person1, person2] - spm_units: - spm_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_code: WV - output: - # Manual §1.1.10, §4.5.3.6, §4.5.6 contemplate minor parents in - # qualifying activity. Parent age 17 working 25 hrs/wk meets the - # activity test; income well below 85% SMI; child age 1 eligible. + # Both parents work 20 hours per week, meeting the activity test. + # Combined income $30,000 is below 185% FPL for a family of 3. + # Child age 3 is under the 13-year child age limit. wv_ccap_eligible: true 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 789fc181d5f..0c1b030eda2 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,10 +1,8 @@ # WV CCAP Income Eligibility Tests -# Single income test per CCDF Plan §2.2.4 / §2.2.5(a): 85% of state median income. -# WV 4-person SMI (2024-10-01) = 90_661/yr -# Family-size factors: 1p=0.52, 2p=0.68, 3p=0.84, 4p=1.00, 5p=1.16, 6p=1.32 -# 85% SMI family of 2 = 90_661 * 0.68 * 0.85 = 52_401.86/yr = 4_366.82/mo +# Initial intake cap: 185% FPL (Manual §3.2.1, Appendix A) +# 185% FPL for a 2-person family (2025) = $39,127.50/yr -- name: Case 1, income below 85% SMI eligible. +- name: Case 1, income below 185% FPL eligible. period: 2025-01 input: people: @@ -24,10 +22,10 @@ members: [person1, person2] state_code: WV output: - # monthly income = 2_000 <= 4_366.82 -> eligible + # $24,000/yr < $39,127.50 → eligible wv_ccap_income_eligible: true -- name: Case 2, income above 85% SMI ineligible. +- name: Case 2, income above 185% FPL ineligible. period: 2025-01 input: people: @@ -47,17 +45,17 @@ members: [person1, person2] state_code: WV output: - # monthly income = 5_000 > 4_366.82 -> ineligible + # $60,000/yr > $39,127.50 → ineligible wv_ccap_income_eligible: false -- name: Case 3, income at 85% SMI boundary eligible. +- name: Case 3, income just below 185% FPL boundary eligible. period: 2025-01 input: people: person1: age: 30 - # Just below 85% SMI for family of 2 - employment_income: 52_000 + # 2-person family: 185% FPL ≈ $39,127.50 + employment_income: 39_000 person2: age: 5 tax_units: @@ -71,7 +69,7 @@ members: [person1, person2] state_code: WV output: - # monthly income = 4_333.33 <= 4_366.82 -> eligible + # $39,000/yr ≤ $39,127.50 → eligible wv_ccap_income_eligible: true - name: Case 4, TANF recipients categorically eligible. @@ -95,8 +93,7 @@ members: [person1, person2] state_code: WV output: - # Income above SMI but TANF bypass applies per Manual §3.2.1. - # The bypass extends to TANF children-only cases (§3.2.1.4) that - # should still meet the income test — we don't currently model that - # distinction. + # Income above 185% FPL but TANF bypass applies per Manual §3.2.1. + # 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 diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py index 7f116fdadd6..dca755c0e69 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py @@ -14,11 +14,8 @@ def formula(spm_unit, period, parameters): person = spm_unit.members is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) hours_worked = person("weekly_hours_worked", period.this_year) - meets_work_requirement = hours_worked >= p.activity_hours is_student = person("is_full_time_student", period.this_year) - individually_eligible = meets_work_requirement | is_student - # A unit with no head or spouse (e.g., a child-only record) has no - # caretaker to be in a qualifying activity and must not pass. + individually_eligible = (hours_worked >= p.activity_hours) | is_student has_caretaker = spm_unit.sum(is_head_or_spouse) > 0 no_ineligible_caretaker = ( spm_unit.sum(is_head_or_spouse & ~individually_eligible) == 0 diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py index 8692aa52e89..84f0ed84344 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py @@ -13,11 +13,8 @@ class wv_ccap_eligible(Variable): ) def formula(spm_unit, period, parameters): - # We don't enforce a minimum parent-age floor: §1.1.10 recognizes - # emancipated minors, §1.1.13 treats them as separate families, and - # §4.5.3.6 / §4.5.6 explicitly contemplate minor parents in high - # school or home schooling. The activity requirement below carries - # the substantive caretaker check. + # NOTE: we don't model minor-parent eligibility (Manual §1.1.10, §4.5.3.6, §4.5.6) + # because tax-unit head/spouse status excludes people under 18. has_eligible_child = add(spm_unit, period, ["wv_ccap_eligible_child"]) > 0 income_eligible = spm_unit("wv_ccap_income_eligible", period) asset_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py index ae94d306101..84b244d4e85 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py @@ -13,10 +13,8 @@ class wv_ccap_eligible_child(Variable): ) def formula(person, period, parameters): - # Manual Sec 3.1.2 extends eligibility to ages 13-17 if EITHER the - # child is under court supervision (Sec 3.1.2.1) OR has special - # needs (Sec 3.1.2.2). We only model the special-needs branch - # because we don't track court-supervision status at the moment. + # NOTE: we don't track court-supervision (§3.1.2.1) at the moment, so the + # 13-17 extension applies only via the special-needs branch (§3.1.2.2). p = parameters(period).gov.states.wv.dhhr.ccap.eligibility age = person("age", period.this_year) is_disabled = person("is_disabled", period.this_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 ed93b3e65a6..a7beadfc58b 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 @@ -8,22 +8,17 @@ class wv_ccap_income_eligible(Variable): definition_period = MONTH defined_for = StateCode.WV reference = ( - "https://bfa.wv.gov/media/39915/download?inline#page=20", - "https://bfa.wv.gov/media/6781/download?inline", + "https://bfa.wv.gov/media/6766/download?inline#page=25", + "https://bfa.wv.gov/media/6826/download?inline#page=1", ) def formula(spm_unit, period, parameters): - # Per CCDF State Plan §2.2.4 / §2.2.5(a), WV sets its sole income - # ceiling at 85% of state median income; graduated phase-out is - # marked "Not applicable" because the threshold already sits at - # the federal CCDF ceiling. + # 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. p = parameters(period).gov.states.wv.dhhr.ccap.income countable_income = spm_unit("wv_ccap_countable_income", period) - smi = spm_unit("hhs_smi", period) - smi_eligible = countable_income <= smi * p.smi_rate - # TANF recipients are categorically income-eligible per Policy - # Manual §3.2.1. We don't currently distinguish "TANF children- - # only" cases (§3.2.1.4), which must still meet the income test; - # the bypass applies to all is_tanf_enrolled units. + fpg = spm_unit("spm_unit_fpg", period) + fpl_eligible = countable_income <= fpg * p.fpl_limit is_tanf = spm_unit("is_tanf_enrolled", period) - return is_tanf | smi_eligible + return is_tanf | fpl_eligible diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py index f4fde69b0b0..e31280662f6 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py @@ -9,19 +9,28 @@ class wv_ccap(Variable): definition_period = MONTH defined_for = "wv_ccap_eligible" reference = ( - "https://bfa.wv.gov/media/6766/download?inline#page=73", + "https://bfa.wv.gov/media/6766/download?inline#page=79", "https://bfa.wv.gov/media/39915/download?inline#page=41", ) def formula(spm_unit, period, parameters): - copay = spm_unit("wv_ccap_copay", period) + # Manual §7.2.7.3-7.2.7.4: Monthly Rate = 20 × daily when 13-20 days/month + # of attendance; per-day billing otherwise. Reimbursement is also capped + # at the actual provider charge. + p = parameters(period).gov.states.wv.dhhr.ccap.billing person = spm_unit.members daily_benefit = person("wv_ccap_daily_benefit", period) days_per_week = person("childcare_days_per_week", period.this_year) - days_per_month = days_per_week * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) - total_reimbursement = spm_unit.sum(daily_benefit * days_per_month) - pre_subsidy_childcare_expenses = spm_unit( - "spm_unit_pre_subsidy_childcare_expenses", period + actual_days = days_per_week * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) + in_monthly_range = (actual_days >= p.monthly_rate_min_days) & ( + actual_days <= p.monthly_rate_max_days + ) + billed_days = where(in_monthly_range, p.monthly_rate_max_days, actual_days) + pre_subsidy_per_child = person("pre_subsidy_childcare_expenses", period) + per_child_reimbursement = min_( + daily_benefit * billed_days, pre_subsidy_per_child ) - uncapped = max_(pre_subsidy_childcare_expenses - copay, 0) - return min_(uncapped, total_reimbursement) + total_reimbursement = spm_unit.sum(per_child_reimbursement) + copay = spm_unit("wv_ccap_copay", period) + pre_subsidy_total = spm_unit("spm_unit_pre_subsidy_childcare_expenses", period) + return min_(max_(pre_subsidy_total - copay, 0), total_reimbursement) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py index f1237c50b4a..cb6db14bebc 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_child_age_category.py @@ -16,7 +16,7 @@ class wv_ccap_child_age_category(Variable): definition_period = MONTH label = "West Virginia CCAP child age category" defined_for = StateCode.WV - reference = "https://bfa.wv.gov/media/6831/download?inline" + reference = "https://bfa.wv.gov/media/6831/download?inline#page=1" def formula(person, period, parameters): age_in_months = person("age", period.this_year) * 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 bd25997c5f4..c2e713d0fa1 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 @@ -9,31 +9,25 @@ class wv_ccap_copay(Variable): definition_period = MONTH defined_for = StateCode.WV reference = ( - "https://bfa.wv.gov/media/6826/download?inline", - "https://bfa.wv.gov/media/39915/download?inline#page=41", + "https://bfa.wv.gov/media/6826/download?inline#page=1", + "https://bfa.wv.gov/media/6766/download?inline#page=64", + "https://bfa.wv.gov/media/39915/download?inline#page=40", ) def formula(spm_unit, period, parameters): - # Simplified percent-of-income approximation of Appendix A. The - # actual schedule is a 176-cell daily-dollar table (11 family sizes - # x 16 FPL bands), with the fee charged per child up to 3 per - # Manual Sec 6.4.3. The current rate.yaml is derived from the - # 3-person column as a representative middle case; see that file - # for the divergence by family size. The 7% max_share cap and the - # under-40%-FPL waiver are encoded in the rate schedule itself; - # only the foster-child waiver needs an explicit override here. + # NOTE: %-of-income approximation of the 176-cell sliding fee scale + # (Appendix A), calibrated to the 3-person family column. Per Manual + # §6.4.3, the actual fee is charged per child up to 3 children — we + # apply that multiplier here. The 7% cap and <40% FPL waiver are in + # the rate schedule; foster waiver overrides below. 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) - mask = fpg > 0 - fpl_ratio = np.divide( - countable_income, - fpg, - out=np.zeros_like(countable_income, dtype=float), - where=mask, - ) - has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 - copay_rate = p.rate.calc(fpl_ratio) - uncapped_copay = countable_income * copay_rate + fpl_ratio = where(fpg > 0, countable_income / max_(fpg, 1), 0) + per_child_rate = p.rate.calc(fpl_ratio) + num_eligible_children = add(spm_unit, period, ["wv_ccap_eligible_child"]) + billed_children = min_(num_eligible_children, p.max_billed_children) + uncapped_copay = countable_income * per_child_rate * billed_children capped_copay = min_(uncapped_copay, countable_income * p.max_share) + has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 return where(has_foster_child, 0, capped_copay) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py index 74fff8dabb3..6b0d054da16 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_rate.py @@ -11,7 +11,7 @@ class wv_ccap_daily_rate(Variable): label = "West Virginia CCAP daily provider reimbursement rate" definition_period = MONTH defined_for = "wv_ccap_eligible_child" - reference = "https://bfa.wv.gov/media/6831/download?inline" + reference = "https://bfa.wv.gov/media/6831/download?inline#page=1" def formula(person, period, parameters): p = parameters(period).gov.states.wv.dhhr.ccap.rates diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_informal_age_group.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_informal_age_group.py index f77c7c649f6..ad0879ab0e0 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_informal_age_group.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_informal_age_group.py @@ -14,7 +14,7 @@ class wv_ccap_informal_age_group(Variable): definition_period = MONTH label = "West Virginia CCAP informal care age group" defined_for = StateCode.WV - reference = "https://bfa.wv.gov/media/6831/download?inline" + reference = "https://bfa.wv.gov/media/6831/download?inline#page=1" def formula(person, period, parameters): age_in_months = person("age", period.this_year) * MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_non_traditional_hours.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_non_traditional_hours.py index 177db982069..6299c79cb9b 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_non_traditional_hours.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_non_traditional_hours.py @@ -7,3 +7,4 @@ class wv_ccap_non_traditional_hours(Variable): definition_period = MONTH label = "Whether child receives care during non-traditional hours for West Virginia CCAP" defined_for = StateCode.WV + reference = "https://bfa.wv.gov/media/6831/download?inline#page=1" diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_provider_type.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_provider_type.py index fd0ad73f391..894adf243ee 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_provider_type.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_provider_type.py @@ -17,4 +17,4 @@ class wv_ccap_provider_type(Variable): definition_period = MONTH label = "West Virginia CCAP child care provider type" defined_for = StateCode.WV - reference = "https://bfa.wv.gov/media/6831/download?inline" + reference = "https://bfa.wv.gov/media/6831/download?inline#page=1" diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_quality_tier.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_quality_tier.py index 8cd6a0ed39c..92f5dcd29b9 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_quality_tier.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_quality_tier.py @@ -15,4 +15,4 @@ class wv_ccap_quality_tier(Variable): definition_period = MONTH label = "West Virginia CCAP provider quality tier" defined_for = StateCode.WV - reference = "https://bfa.wv.gov/media/6831/download?inline" + reference = "https://bfa.wv.gov/media/6831/download?inline#page=1" diff --git a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py index 4c7705cf267..d10dad2dfb4 100644 --- a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py +++ b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py @@ -41,6 +41,8 @@ def formula(spm_unit, period, parameters): "sc_ssi_state_supplement", # Texas programs. "tx_ssi_state_supplement", + # West Virginia programs. + "wv_child_care_subsidies", "snap", "wic", "free_school_meals", From 58c029fc724d37101713e47af9b27c65f7fdef44 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 19 May 2026 23:39:39 -0400 Subject: [PATCH 13/16] fix --- .../ccap/billing/monthly_rate_max_days.yaml | 4 +- .../ccap/billing/monthly_rate_min_days.yaml | 4 +- .../ccap/copayment/max_billed_children.yaml | 2 +- .../gov/states/wv/dhhr/ccap/integration.yaml | 91 ++++++++++++++++++- .../gov/states/wv/dhhr/ccap/wv_ccap.py | 44 ++++++--- .../gov/states/wv/dhhr/ccap/wv_ccap_copay.py | 2 +- .../wv/dhhr/ccap/wv_ccap_daily_benefit.py | 2 +- 7 files changed, 125 insertions(+), 24 deletions(-) diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_max_days.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_max_days.yaml index de7a584d9a1..89e061e463c 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_max_days.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_max_days.yaml @@ -7,5 +7,5 @@ metadata: period: year label: West Virginia CCAP monthly rate billing maximum days reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 7, Section 7.2.7.4 — Monthly Rate - href: https://bfa.wv.gov/media/6766/download?inline#page=79 + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 7, Section 7.2.7.4 — The Monthly Rate + href: https://bfa.wv.gov/media/6766/download?inline#page=80 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_min_days.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_min_days.yaml index 056d75fa6ce..814d3cf0640 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_min_days.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/billing/monthly_rate_min_days.yaml @@ -7,5 +7,5 @@ metadata: period: year label: West Virginia CCAP monthly rate billing minimum days reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 7, Section 7.2.7.3 — Monthly Rate - href: https://bfa.wv.gov/media/6766/download?inline#page=79 + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 7, Section 7.2.7.4 — The Monthly Rate + href: https://bfa.wv.gov/media/6766/download?inline#page=80 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml index 9dc03d7be8b..d59e3adbe27 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml @@ -8,4 +8,4 @@ metadata: label: West Virginia CCAP maximum billed children reference: - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 6, Section 6.4.3 — Family Fees - href: https://bfa.wv.gov/media/6766/download?inline#page=64 + href: https://bfa.wv.gov/media/6766/download?inline#page=65 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 11e06576d18..e9f25d5a501 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 @@ -204,9 +204,8 @@ # copay = 2_000 * 0.035 = 70 wv_ccap_copay: 70 - # uncapped = max(833.33 - 70, 0) = 763.33 - # benefit = min(763.33, 823.33) = 763.33 - wv_ccap: 763.33 + # benefit = max(823.33 - 70, 0) = 753.33 + wv_ccap: 753.33 - name: Case 5, non-WV family gets zero benefit. period: 2025-01 @@ -234,3 +233,89 @@ state_code: VA output: wv_ccap: 0 + +- name: Case 6, copay reduces capped provider reimbursement. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 24_000 + weekly_hours_worked: 40 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 4 + pre_subsidy_childcare_expenses: 12_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible: true + # Center Tier I Toddler = $37/day. + wv_ccap_daily_rate: [0, 37] + # 4 days/week = 17.33 days/month, so monthly-rate billing applies. + # Gross reimbursement = 37 * 20 = 740. + # Copay = 2_000 monthly income * 3.5% = 70. + # Benefit deducts copay from authorized reimbursement, not provider charge. + wv_ccap_copay: 70 + wv_ccap: 670 + +# Manual §7.2.7.2: rate supplements are paid for actual days only — the monthly +# rate does NOT apply to rate supplements. This case is the regression guard. +- name: Case 7, supplement billed by actual days even when monthly rate applies. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 24_000 + weekly_hours_worked: 40 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + is_disabled: true + ssi: 0 + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 4 + pre_subsidy_childcare_expenses: 12_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible: true + # Center Tier I Toddler = $37/day base; special needs supplement = $3/day. + wv_ccap_daily_rate: [0, 37] + # 4 days/week = 17.33 days/month (in 13-20 monthly-rate range). + # Base reimbursement (monthly rate): 37 * 20 = 740. + # Supplement reimbursement (actual days): 3 * 17.33 = 52. + # Total reimbursement: 740 + 52 = 792 (capped at pre_subsidy 1_000). + # Copay = 2_000 * 3.5% = 70. + # Benefit = 792 - 70 = 722. + wv_ccap_copay: 70 + wv_ccap: 722 diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py index e31280662f6..0df395b1fde 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py @@ -9,28 +9,44 @@ class wv_ccap(Variable): definition_period = MONTH defined_for = "wv_ccap_eligible" reference = ( - "https://bfa.wv.gov/media/6766/download?inline#page=79", + "https://bfa.wv.gov/media/6766/download?inline#page=80", "https://bfa.wv.gov/media/39915/download?inline#page=41", ) def formula(spm_unit, period, parameters): - # Manual §7.2.7.3-7.2.7.4: Monthly Rate = 20 × daily when 13-20 days/month - # of attendance; per-day billing otherwise. Reimbursement is also capped - # at the actual provider charge. - p = parameters(period).gov.states.wv.dhhr.ccap.billing + # Manual §7.2.7.3-7.2.7.4: Monthly Rate = 20 × base daily rate when + # 13-20 days/month of attendance; per-day billing otherwise. + # Manual §7.2.7.2: rate supplements (special needs, shift differential) + # are paid for actual days of care only — the monthly rate does NOT + # apply to rate supplements. + p = parameters(period).gov.states.wv.dhhr.ccap person = spm_unit.members - daily_benefit = person("wv_ccap_daily_benefit", period) - days_per_week = person("childcare_days_per_week", period.this_year) - actual_days = days_per_week * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) - in_monthly_range = (actual_days >= p.monthly_rate_min_days) & ( - actual_days <= p.monthly_rate_max_days + weekly_care_days = person("childcare_days_per_week", period.this_year) + monthly_care_days = weekly_care_days * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) + in_monthly_range = ( + monthly_care_days >= p.billing.monthly_rate_min_days + ) & (monthly_care_days <= p.billing.monthly_rate_max_days) + base_billed_days = where( + in_monthly_range, + p.billing.monthly_rate_max_days, + monthly_care_days, ) - billed_days = where(in_monthly_range, p.monthly_rate_max_days, actual_days) + daily_rate = person("wv_ccap_daily_rate", period) + is_disabled = person("is_disabled", period.this_year) + special_needs_supplement = where( + is_disabled, p.supplements.special_needs, 0 + ) + non_trad = person("wv_ccap_non_traditional_hours", period) + non_trad_supplement = where( + non_trad, p.supplements.non_traditional_hours, 0 + ) + daily_supplement = special_needs_supplement + non_trad_supplement pre_subsidy_per_child = person("pre_subsidy_childcare_expenses", period) per_child_reimbursement = min_( - daily_benefit * billed_days, pre_subsidy_per_child + daily_rate * base_billed_days + + daily_supplement * monthly_care_days, + pre_subsidy_per_child, ) total_reimbursement = spm_unit.sum(per_child_reimbursement) copay = spm_unit("wv_ccap_copay", period) - pre_subsidy_total = spm_unit("spm_unit_pre_subsidy_childcare_expenses", period) - return min_(max_(pre_subsidy_total - copay, 0), total_reimbursement) + return max_(total_reimbursement - copay, 0) 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 c2e713d0fa1..e1d6746957b 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 @@ -10,7 +10,7 @@ class wv_ccap_copay(Variable): defined_for = StateCode.WV reference = ( "https://bfa.wv.gov/media/6826/download?inline#page=1", - "https://bfa.wv.gov/media/6766/download?inline#page=64", + "https://bfa.wv.gov/media/6766/download?inline#page=65", "https://bfa.wv.gov/media/39915/download?inline#page=40", ) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py index 405bc7a1c1c..0a530e4728f 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py @@ -8,7 +8,7 @@ class wv_ccap_daily_benefit(Variable): label = "West Virginia CCAP daily benefit per child" definition_period = MONTH defined_for = "wv_ccap_eligible_child" - reference = "https://bfa.wv.gov/media/6766/download?inline#page=73" + reference = "https://bfa.wv.gov/media/6766/download?inline#page=79" def formula(person, period, parameters): p = parameters(period).gov.states.wv.dhhr.ccap From a84318cb4bf29805f7b14ef3dc12aadab9699401 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 20 May 2026 00:07:24 -0400 Subject: [PATCH 14/16] copay refactor --- .../states/wv/dhhr/ccap/copayment/rate.yaml | 37 ----- .../wv/dhhr/ccap/copayment/rate/size_1.yaml | 76 ++++++++++ .../wv/dhhr/ccap/copayment/rate/size_10.yaml | 74 ++++++++++ .../wv/dhhr/ccap/copayment/rate/size_11.yaml | 71 +++++++++ .../wv/dhhr/ccap/copayment/rate/size_2.yaml | 76 ++++++++++ .../wv/dhhr/ccap/copayment/rate/size_3.yaml | 76 ++++++++++ .../wv/dhhr/ccap/copayment/rate/size_4.yaml | 76 ++++++++++ .../wv/dhhr/ccap/copayment/rate/size_5.yaml | 76 ++++++++++ .../wv/dhhr/ccap/copayment/rate/size_6.yaml | 76 ++++++++++ .../wv/dhhr/ccap/copayment/rate/size_7.yaml | 76 ++++++++++ .../wv/dhhr/ccap/copayment/rate/size_8.yaml | 76 ++++++++++ .../wv/dhhr/ccap/copayment/rate/size_9.yaml | 76 ++++++++++ .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 139 ++++++++++-------- .../gov/states/wv/dhhr/ccap/integration.yaml | 66 +++++---- .../states/wv/dhhr/ccap/wv_ccap_copay.yaml | 40 +++-- .../wv/dhhr/ccap/wv_child_care_subsidies.yaml | 4 +- .../gov/states/wv/dhhr/ccap/wv_ccap.py | 17 +-- .../gov/states/wv/dhhr/ccap/wv_ccap_copay.py | 66 +++++++-- 18 files changed, 1029 insertions(+), 169 deletions(-) delete mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_1.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_10.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_11.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_2.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_3.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_4.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_5.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_6.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_7.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_8.yaml create mode 100644 policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_9.yaml diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml deleted file mode 100644 index 7ae7d89de20..00000000000 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate.yaml +++ /dev/null @@ -1,37 +0,0 @@ -description: West Virginia sets this co-payment share of income per child by federal poverty level ratio under the Child Care Assistance Program. -metadata: - type: single_amount - threshold_unit: /1 - amount_unit: /1 - period: year - label: West Virginia CCAP co-payment rate by FPL ratio - reference: - - title: WV Child Care Subsidy Appendix A — Sliding Fee Scale (Oct 1, 2024) - href: https://bfa.wv.gov/media/6826/download?inline#page=1 - - title: WV CCDF State Plan FFY 2025-2027, Section 3.1.2 — Sliding Fee Scale - href: https://bfa.wv.gov/media/39915/download?inline#page=40 - -# Percentage approximation of the Appendix A daily fee schedule, derived from -# the 3-person family column. The wv_ccap_copay formula multiplies by the -# number of eligible children (capped at 3 per Manual §6.4.3). -brackets: - - threshold: - 2024-10-01: 0 - amount: - 2024-10-01: 0 - - threshold: - 2024-10-01: 0.4001 - amount: - 2024-10-01: 0.025 - - threshold: - 2024-10-01: 0.7001 - amount: - 2024-10-01: 0.03 - - threshold: - 2024-10-01: 1.1001 - amount: - 2024-10-01: 0.035 - - threshold: - 2024-10-01: 1.5001 - amount: - 2024-10-01: 0.04 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_1.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_1.yaml new file mode 100644 index 00000000000..9fe252ebb6a --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_1.yaml @@ -0,0 +1,76 @@ +description: West Virginia charges this daily co-payment per child for a one-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for one-person family + reference: + - title: WV Child Care Subsidy Appendix A — One Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=1 + +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 1.50 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 2.00 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 2.25 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 2.75 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 3.00 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 3.50 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 3.75 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 4.25 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 4.50 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 5.00 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 5.25 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 5.75 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 6.00 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 6.50 + - threshold: + 2024-10-01: 1.8001 + amount: + 2024-10-01: 7.00 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_10.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_10.yaml new file mode 100644 index 00000000000..739f13c35ca --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_10.yaml @@ -0,0 +1,74 @@ +description: West Virginia charges this daily co-payment per child for a ten-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for ten-person family + reference: + - title: WV Child Care Subsidy Appendix A — Ten Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=5 + +# Appendix A does not publish a 185% row for ten-person families; the 180% +# value carries forward to the intake cap. +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 3.00 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 3.75 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 4.50 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 5.25 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 6.25 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 7.00 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 7.75 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 8.50 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 9.25 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 10.00 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 10.75 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 11.50 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 12.25 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 13.00 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_11.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_11.yaml new file mode 100644 index 00000000000..b23bdaad999 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_11.yaml @@ -0,0 +1,71 @@ +description: West Virginia charges this daily co-payment per child for an eleven-person (or larger) family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for eleven-person family + reference: + - title: WV Child Care Subsidy Appendix A — Eleven Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=6 + +# Appendix A publishes brackets through 165% FPL for eleven-person families; +# the 165% value carries forward to the intake cap. The 170%, 180%, and 185% +# rows are blank in the published table. +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 2.25 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 2.75 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 3.50 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 4.00 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 4.50 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 5.25 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 5.75 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 6.25 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 7.00 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 7.50 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 8.00 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 8.50 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 9.25 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_2.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_2.yaml new file mode 100644 index 00000000000..f32f8adaa3f --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_2.yaml @@ -0,0 +1,76 @@ +description: West Virginia charges this daily co-payment per child for a two-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for two-person family + reference: + - title: WV Child Care Subsidy Appendix A — Two Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=1 + +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 2.00 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 2.50 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 3.00 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 3.75 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 4.25 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 4.75 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 5.25 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 5.75 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 6.25 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 6.75 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 7.25 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 7.75 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 8.25 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 8.75 + - threshold: + 2024-10-01: 1.8001 + amount: + 2024-10-01: 9.25 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_3.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_3.yaml new file mode 100644 index 00000000000..415d1856a8c --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_3.yaml @@ -0,0 +1,76 @@ +description: West Virginia charges this daily co-payment per child for a three-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for three-person family + reference: + - title: WV Child Care Subsidy Appendix A — Three Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=2 + +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 1.25 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 1.75 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 2.00 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 2.25 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 2.50 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 3.00 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 3.25 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 3.50 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 4.00 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 4.25 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 4.50 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 5.00 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 5.25 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 5.50 + - threshold: + 2024-10-01: 1.8001 + amount: + 2024-10-01: 6.00 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_4.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_4.yaml new file mode 100644 index 00000000000..49ef65ab21e --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_4.yaml @@ -0,0 +1,76 @@ +description: West Virginia charges this daily co-payment per child for a four-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for four-person family + reference: + - title: WV Child Care Subsidy Appendix A — Four Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=2 + +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 1.00 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 1.25 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 1.50 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 1.75 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 2.00 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 2.25 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 2.50 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 2.75 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 3.00 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 3.50 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 3.75 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 4.00 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 4.25 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 4.50 + - threshold: + 2024-10-01: 1.8001 + amount: + 2024-10-01: 4.75 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_5.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_5.yaml new file mode 100644 index 00000000000..7a74d1a4428 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_5.yaml @@ -0,0 +1,76 @@ +description: West Virginia charges this daily co-payment per child for a five-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for five-person family + reference: + - title: WV Child Care Subsidy Appendix A — Five Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=3 + +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 1.25 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 1.50 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 1.75 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 2.25 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 2.50 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 2.75 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 3.00 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 3.25 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 3.75 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 4.00 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 4.25 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 4.50 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 5.00 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 5.25 + - threshold: + 2024-10-01: 1.8001 + amount: + 2024-10-01: 5.50 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_6.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_6.yaml new file mode 100644 index 00000000000..056430e3ad0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_6.yaml @@ -0,0 +1,76 @@ +description: West Virginia charges this daily co-payment per child for a six-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for six-person family + reference: + - title: WV Child Care Subsidy Appendix A — Six Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=3 + +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 1.50 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 1.75 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 2.00 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 2.50 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 2.75 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 3.25 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 3.50 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 3.75 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 4.25 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 4.50 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 5.00 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 5.25 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 5.50 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 6.00 + - threshold: + 2024-10-01: 1.8001 + amount: + 2024-10-01: 6.25 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_7.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_7.yaml new file mode 100644 index 00000000000..b92e03a27b7 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_7.yaml @@ -0,0 +1,76 @@ +description: West Virginia charges this daily co-payment per child for a seven-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for seven-person family + reference: + - title: WV Child Care Subsidy Appendix A — Seven Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=4 + +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 2.25 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 2.75 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 3.50 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 4.00 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 4.50 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 5.25 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 5.75 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 6.25 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 6.75 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 7.50 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 8.00 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 8.50 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 9.25 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 9.75 + - threshold: + 2024-10-01: 1.8001 + amount: + 2024-10-01: 10.25 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_8.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_8.yaml new file mode 100644 index 00000000000..2c91891679f --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_8.yaml @@ -0,0 +1,76 @@ +description: West Virginia charges this daily co-payment per child for an eight-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for eight-person family + reference: + - title: WV Child Care Subsidy Appendix A — Eight Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=4 + +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 2.50 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 3.25 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 3.75 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 4.50 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 5.00 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 5.75 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 6.25 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 7.00 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 7.75 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 8.25 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 9.00 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 9.50 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 10.25 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 10.75 + - threshold: + 2024-10-01: 1.8001 + amount: + 2024-10-01: 11.50 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_9.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_9.yaml new file mode 100644 index 00000000000..ed7ad5cf3a5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_9.yaml @@ -0,0 +1,76 @@ +description: West Virginia charges this daily co-payment per child for a nine-person family under the Child Care Assistance Program. +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + threshold_period: year + label: West Virginia CCAP daily co-payment for nine-person family + reference: + - title: WV Child Care Subsidy Appendix A — Nine Person Family Sliding Fee Scale + href: https://bfa.wv.gov/media/6826/download?inline#page=5 + +brackets: + - threshold: + 2024-10-01: 0 + amount: + 2024-10-01: 0 + - threshold: + 2024-10-01: 0.4001 + amount: + 2024-10-01: 2.75 + - threshold: + 2024-10-01: 0.5001 + amount: + 2024-10-01: 3.50 + - threshold: + 2024-10-01: 0.6001 + amount: + 2024-10-01: 4.25 + - threshold: + 2024-10-01: 0.7001 + amount: + 2024-10-01: 5.00 + - threshold: + 2024-10-01: 0.8001 + amount: + 2024-10-01: 5.50 + - threshold: + 2024-10-01: 0.9001 + amount: + 2024-10-01: 6.25 + - threshold: + 2024-10-01: 1.0001 + amount: + 2024-10-01: 7.00 + - threshold: + 2024-10-01: 1.1001 + amount: + 2024-10-01: 7.75 + - threshold: + 2024-10-01: 1.2001 + amount: + 2024-10-01: 8.50 + - threshold: + 2024-10-01: 1.3001 + amount: + 2024-10-01: 9.00 + - threshold: + 2024-10-01: 1.4001 + amount: + 2024-10-01: 9.75 + - threshold: + 2024-10-01: 1.5001 + amount: + 2024-10-01: 10.50 + - threshold: + 2024-10-01: 1.6001 + amount: + 2024-10-01: 11.25 + - threshold: + 2024-10-01: 1.7001 + amount: + 2024-10-01: 12.00 + - threshold: + 2024-10-01: 1.8001 + amount: + 2024-10-01: 12.50 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 d4a19382532..32ba1373a22 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 @@ -601,28 +601,24 @@ members: [person1, person2] state_code: WV output: - # monthly income = 8_475 / 12 = 706.25 - # FPL ratio = 706.25 / 1_762.50 = 0.4007 > 0.4001 -> 2.5% bracket - # copay = 706.25 * 0.025 = 17.66 - # 7% cap = 706.25 * 0.07 = 49.44 - # min(17.66, 49.44) = 17.66 - wv_ccap_copay: 17.66 + # Monthly income = 8_475 / 12 = $706.25. 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 × 21.67 × 1 = $43.33. + # 7% cap = $706.25 × 0.07 = $49.44; cap does not bind. + wv_ccap_copay: 43.33 # ============================================================ -# Copay hitting 7% cap +# Copay 7% cap behavior # ============================================================ -- name: Case 18, copay capped at 7% of income. +- name: Case 18, high FPL 2-person family copay below 7% cap. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: age: 30 - # High income in 4% bracket (FPL ratio > 1.5001) - # Need enrolled to pass 185% FPL threshold - # Use income at ~170% FPL to be in 4% bracket - # 21_150 * 1.7 = 35_955/yr + # ~170% FPL family of 2: 21_150 * 1.7 = 35_955/yr. employment_income: 35_955 immigration_status: CITIZEN person2: @@ -645,29 +641,20 @@ members: [person1, person2] state_code: WV output: - # monthly income = 35_955 / 12 = 2_996.25 - # FPL ratio = 2_996.25 / 1_762.50 = 1.7 - # In 4% bracket (> 1.5001) - # uncapped copay = 2_996.25 * 0.04 = 119.85 - # 7% cap = 2_996.25 * 0.07 = 209.74 - # min(119.85, 209.74) = 119.85 (not capped in this case) - wv_ccap_copay: 119.85 - -- name: Case 19, copay rate higher than 7% cap triggers cap. + # Monthly income = $2_996.25. 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 × 21.67 × 1 = $178.75. + # 7% cap = $2_996.25 × 0.07 = $209.74; cap does not bind. + wv_ccap_copay: 178.75 + +- name: Case 19, large family with three children triggers 7 percent cap. period: 2025-01 absolute_error_margin: 0.01 input: people: person1: - age: 30 - # To trigger the 7% cap, the rate bracket must exceed 7%. - # The highest bracket is 4%, so 4% < 7% means cap never binds - # under normal operation. But we verify the cap code path works - # by testing that the 7% cap is applied correctly. - # 4% rate * income = copay; 7% * income = cap - # Since 4% < 7%, the cap never binds for this simplified scale. - # This test confirms the copay correctly equals the uncapped amount. - employment_income: 36_000 + age: 35 + employment_income: 42_000 immigration_status: CITIZEN person2: age: 3 @@ -676,25 +663,52 @@ wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I childcare_days_per_week: 5 - pre_subsidy_childcare_expenses: 10_000 + pre_subsidy_childcare_expenses: 6_000 + person3: + age: 5 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 6_000 + person4: + age: 7 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_days_per_week: 5 + pre_subsidy_childcare_expenses: 6_000 + person5: + age: 15 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person6: + age: 16 + is_tax_unit_dependent: true + immigration_status: CITIZEN + person7: + age: 17 + is_tax_unit_dependent: true + immigration_status: CITIZEN tax_units: tax_unit: - members: [person1, person2] + members: [person1, person2, person3, person4, person5, person6, person7] spm_units: spm_unit: - members: [person1, person2] - spm_unit_pre_subsidy_childcare_expenses: 10_000 + members: [person1, person2, person3, person4, person5, person6, person7] households: household: - members: [person1, person2] + members: [person1, person2, person3, person4, person5, person6, person7] state_code: WV output: - # monthly income = 36_000 / 12 = 3_000 - # FPL ratio = 3_000 / 1_762.50 = 1.7021 -> 4% bracket - # uncapped copay = 3_000 * 0.04 = 120 - # 7% cap = 3_000 * 0.07 = 210 - # min(120, 210) = 120 (cap does not bind) - wv_ccap_copay: 120 + # 7-person family, monthly income $3_500. FPG family-of-7 = $3_945; ratio = 0.887. + # Appendix A 7-person "90%" row daily fee = $4.50/child. + # 3 eligible children × 5 days × 52/12 = 65 monthly days total. + # uncapped copay = $4.50 × 65 × 1 = $292.50. + # 7% cap = $3_500 × 0.07 = $245; cap binds. + wv_ccap_copay: 245 # ============================================================ # Activity hours boundary @@ -1454,12 +1468,12 @@ # daily benefit = min(45, 13.84) = 13.84 wv_ccap_daily_benefit: [0, 13.84] - # total reimbursement = 13.84 * 21.67 = 299.89 - # FPL ratio = 2_000 / 1_762.50 = 1.1348 -> 3.5% bracket - # copay = 2_000 * 0.035 = 70 - # uncapped = max(300 - 70, 0) = 230 - # benefit = min(230, 299.89) = 230 - wv_ccap: 230 + # 2-person family, FPL ratio = 2_000 / 1_762.50 = 1.1348. + # Appendix A 2-person "120%" row daily fee = $5.75/child; 21.67 days. + # copay = $5.75 × 21.67 = $124.58. + # 21.67 days > 20 → per-day billing; per_child = min($45 × 21.67, $300) = $300. + # benefit = max($300 - $124.58, 0) = $175.42. + wv_ccap: 175.42 # ============================================================ # Zero childcare days/expenses @@ -1685,21 +1699,22 @@ # Person3 age 6 = 72 months -> SCHOOL_AGE wv_ccap_child_age_category: [SCHOOL_AGE, INFANT, SCHOOL_AGE] - # FPL ratio = (20_000/12) / (26_650/12) = 0.7505 → 3.0% bracket. - # per_child_copay = 1_666.67 × 0.03 = 50; 2 eligible children → 100. - wv_ccap_copay: 100 - - # Person2 (FAMILY_HOME Tier II Infant, 5 days/wk, 6_000/yr): - # monthly expenses 500; actual_days 21.67 (>20 → per-day billing). - # daily_charge = 500/21.667 = 23.077; daily_benefit = min(33, 23.077) = 23.077. - # per_child_reimbursement = min(23.077 × 21.667, 500) = 500. - # Person3 (CENTER Tier I School-Age, 3 days/wk, 4_000/yr): - # monthly expenses 333.33; actual_days 13 (in 13-20 → monthly billing, 20 days). - # daily_charge = 333.33/13 = 25.641; daily_benefit = min(32, 25.641) = 25.641. - # per_child_reimbursement = min(25.641 × 20, 333.33) = 333.33. - # total reimbursement = 833.33; monthly pre_subsidy = 833.33. - # uncapped = max(833.33 - 100, 0) = 733.33; benefit = min(733.33, 833.33) = 733.33. - wv_ccap: 733.33 + # 3-person family, FPL ratio = 1_666.67 / 2_151.67 = 0.7746 → bracket + # "above 70% up to 80%" → Appendix A 3-person "80%" row daily fee = $2.25/child. + # person2: 5 days/week; person3: 3 days/week → 8 weekly × 52/12 = 34.67 monthly days. + # 2 eligible children in care → billed_share = 2/2 = 1. + # copay = $2.25 × 34.67 × 1 = $78.00. + wv_ccap_copay: 78 + + # Person2 (FAMILY_HOME Tier II Infant, 5 days/wk, $6_000/yr expenses): + # monthly expenses $500; actual_days 21.67 (>20 → per-day billing). + # per_child = min($33 × 21.67, $500) = $500. + # Person3 (CENTER Tier I School-Age, 3 days/wk, $4_000/yr expenses): + # monthly expenses $333.33; actual_days 13 (in 13-20 → monthly rate, 20 days). + # per_child = min($32 × 20, $333.33) = $333.33. + # total reimbursement = $500 + $333.33 = $833.33. + # benefit = max($833.33 - $78, 0) = $755.33. + wv_ccap: 755.33 # ============================================================ # Child-only SPM unit cannot pass activity test 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 e9f25d5a501..c3d0ff0da43 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 @@ -50,20 +50,21 @@ wv_ccap_daily_rate: [0, 37] # === Copay === - # FPL ratio = 2_000 / 1_762.50 = 1.1348 -> 3.5% bracket - # copay = 2_000 * 0.035 = 70 - wv_ccap_copay: 70 + # 2-person family, FPL ratio = 2_000 / 1_762.50 = 1.1348. + # Appendix A 2-person "120%" row daily fee = $5.75/child. + # 1 eligible child × 5 days/week × 52/12 = 21.67 monthly days. + # copay = $5.75 × 21.67 × 1 = $124.58. + wv_ccap_copay: 124.58 - # === Daily benefit === - # daily charge = (8_000/12) / (5 * 52/12) = 666.67 / 21.67 = 30.77 - # daily benefit = min(37, 30.77) = 30.77 + # === Daily benefit (view variable: rate + supplements capped at daily charge) === + # daily charge = (8_000/12) / 21.67 = 30.77; daily benefit = min(37, 30.77) = 30.77. wv_ccap_daily_benefit: [0, 30.77] # === Monthly benefit === - # total reimbursement = 30.77 * 21.67 = 666.78 - # uncapped = max(666.67 - 70, 0) = 596.67 - # benefit = min(596.67, 666.78) = 596.67 - wv_ccap: 596.67 + # 21.67 days/month > 20 → per-day billing for base; no supplements. + # per_child reimbursement = min($37 × 21.67, $666.67) = $666.67. + # benefit = max($666.67 - $124.58, 0) = $542.08. + wv_ccap: 542.08 - name: Case 2, low income family with zero copay. period: 2025-01 @@ -194,18 +195,19 @@ # Center Tier II School Age = $35/day wv_ccap_daily_rate: [0, 35] - # daily rate with special needs supplement = 35 + 3 = 38 - # daily charge = (10_000/12) / 21.67 = 833.33 / 21.67 = 38.46 - # daily benefit = min(38, 38.46) = 38 + # Daily benefit (view): rate + supplement capped at daily charge. + # daily charge = (10_000/12) / 21.67 = 38.46; daily benefit = min(35+3, 38.46) = 38. wv_ccap_daily_benefit: [0, 38] - # total reimbursement = 38 * 21.67 = 823.33 - # copay: FPL ratio = 2_000 / 1_762.50 = 1.1348 -> 3.5% - # copay = 2_000 * 0.035 = 70 - wv_ccap_copay: 70 + # Copay: same 2-person FPL 1.1348 → Appendix A "120%" row $5.75/day × 21.67 = $124.58. + wv_ccap_copay: 124.58 - # benefit = max(823.33 - 70, 0) = 753.33 - wv_ccap: 753.33 + # 21.67 days/month > 20 → per-day billing for base. + # Manual §7.2.7.2: supplements bill for actual days only (same here, per-day billing). + # per_child = min($35 × 21.67 + $3 × 21.67, $833.33) + # = min($823.33, $833.33) = $823.33. + # benefit = max($823.33 - $124.58, 0) = $698.75. + wv_ccap: 698.75 - name: Case 5, non-WV family gets zero benefit. period: 2025-01 @@ -267,12 +269,12 @@ wv_ccap_eligible: true # Center Tier I Toddler = $37/day. wv_ccap_daily_rate: [0, 37] - # 4 days/week = 17.33 days/month, so monthly-rate billing applies. - # Gross reimbursement = 37 * 20 = 740. - # Copay = 2_000 monthly income * 3.5% = 70. - # Benefit deducts copay from authorized reimbursement, not provider charge. - wv_ccap_copay: 70 - wv_ccap: 670 + # 4 days/week = 17.33 days/month (in 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.33 = $99.67. + wv_ccap_copay: 99.67 + # benefit = max($740 - $99.67, 0) = $640.33. + wv_ccap: 640.33 # Manual §7.2.7.2: rate supplements are paid for actual days only — the monthly # rate does NOT apply to rate supplements. This case is the regression guard. @@ -312,10 +314,10 @@ # Center Tier I Toddler = $37/day base; special needs supplement = $3/day. wv_ccap_daily_rate: [0, 37] # 4 days/week = 17.33 days/month (in 13-20 monthly-rate range). - # Base reimbursement (monthly rate): 37 * 20 = 740. - # Supplement reimbursement (actual days): 3 * 17.33 = 52. - # Total reimbursement: 740 + 52 = 792 (capped at pre_subsidy 1_000). - # Copay = 2_000 * 3.5% = 70. - # Benefit = 792 - 70 = 722. - wv_ccap_copay: 70 - wv_ccap: 722 + # Base reimbursement (monthly rate): $37 × 20 = $740. + # Supplement reimbursement (actual days, Manual §7.2.7.2): $3 × 17.33 = $52. + # Total reimbursement: $740 + $52 = $792 (under pre_subsidy $1_000). + # Copay: same as Case 6 (2-person FPL 1.1348, 17.33 days) = $99.67. + wv_ccap_copay: 99.67 + # benefit = max($792 - $99.67, 0) = $692.33. + wv_ccap: 692.33 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 e0fc2d1e73f..2bafdbbec86 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 @@ -1,5 +1,9 @@ # WV CCAP Co-payment Tests -# 2025 FPG family of 2: 21_150 +# Appendix A is a 2D table: family size (1-11+) x FPL bracket -> daily fee per child. +# 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. - name: Case 1, income below 40% FPL pays zero copay. period: 2025-01 @@ -11,6 +15,7 @@ employment_income: 6_000 person2: age: 5 + childcare_days_per_week: 5 tax_units: tax_unit: members: [person1, person2] @@ -22,10 +27,10 @@ members: [person1, person2] state_code: WV output: - # FPL ratio = 500 / 1_762.50 = 0.2837 < 0.40 -> 0% rate + # FPL ratio = 500 / 1_762.50 = 0.2837 < 0.40 -> fee = $0/day. wv_ccap_copay: 0 -- name: Case 2, mid-range income copay. +- name: Case 2, mid-range income copay from Appendix A daily fee. period: 2025-01 absolute_error_margin: 0.01 input: @@ -35,6 +40,7 @@ employment_income: 18_000 person2: age: 5 + childcare_days_per_week: 5 tax_units: tax_unit: members: [person1, person2] @@ -46,12 +52,13 @@ members: [person1, person2] state_code: WV output: - # monthly income = 1_500 - # FPL ratio = 1_500 / 1_762.50 = 0.8511 -> 3% rate - # copay = 1_500 * 0.03 = 45 - wv_ccap_copay: 45 + # Monthly income $1_500; FPL ratio = 1_500 / 1_762.50 = 0.8511. + # Appendix A 2-person "90%" row daily fee = $4.25/child. + # 1 eligible child × 5 days/week × 52/12 = 21.67 monthly days. + # copay = $4.25 × 21.67 × 1 = $92.08. + wv_ccap_copay: 92.08 -- name: Case 3, copay capped at 7% of income. +- name: Case 3, high income 2-person family copay below 7% cap. period: 2025-01 absolute_error_margin: 0.01 input: @@ -61,6 +68,7 @@ employment_income: 36_000 person2: age: 5 + childcare_days_per_week: 5 tax_units: tax_unit: members: [person1, person2] @@ -72,14 +80,13 @@ members: [person1, person2] state_code: WV output: - # monthly income = 3_000 - # FPL ratio = 3_000 / 1_762.50 = 1.7021 -> 4% bracket rate - # uncapped copay = 3_000 * 0.04 = 120 - # 7% cap = 3_000 * 0.07 = 210 - # 120 <= 210 -> copay = 120 - wv_ccap_copay: 120 + # Monthly income $3_000; FPL ratio = 3_000 / 1_762.50 = 1.7021. + # Appendix A 2-person "180%" row daily fee = $8.75/child. + # uncapped copay = $8.75 × 21.67 = $189.58. + # 7% cap = $3_000 × 0.07 = $210. Cap does not bind for 2-person, 1-child. + wv_ccap_copay: 189.58 -- name: Case 4, foster family pays zero copay. +- name: Case 4, foster family pays zero copay even when fee would otherwise apply. period: 2025-01 absolute_error_margin: 0.01 input: @@ -89,6 +96,7 @@ employment_income: 36_000 person2: age: 5 + childcare_days_per_week: 5 is_in_foster_care: true tax_units: tax_unit: @@ -101,4 +109,6 @@ members: [person1, person2] state_code: WV output: + # Without foster waiver this household would owe $189.58/month (see Case 3); + # Manual §6.4.1 / CCDF Plan §3.3.1 waives the family fee. wv_ccap_copay: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml index d9d129a6048..32bf12ae248 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml @@ -27,5 +27,5 @@ members: [person1, person2] state_code: WV output: - # wv_ccap monthly = ~596.67 -> annual = ~7_160 - wv_child_care_subsidies: 7_160 + # Matches integration.yaml Case 1: wv_ccap monthly = $542.08 → annual = ~$6_505. + wv_child_care_subsidies: 6_505 diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py index 0df395b1fde..cbd5ed05625 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py @@ -23,9 +23,9 @@ def formula(spm_unit, period, parameters): person = spm_unit.members weekly_care_days = person("childcare_days_per_week", period.this_year) monthly_care_days = weekly_care_days * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) - in_monthly_range = ( - monthly_care_days >= p.billing.monthly_rate_min_days - ) & (monthly_care_days <= p.billing.monthly_rate_max_days) + in_monthly_range = (monthly_care_days >= p.billing.monthly_rate_min_days) & ( + monthly_care_days <= p.billing.monthly_rate_max_days + ) base_billed_days = where( in_monthly_range, p.billing.monthly_rate_max_days, @@ -33,18 +33,13 @@ def formula(spm_unit, period, parameters): ) daily_rate = person("wv_ccap_daily_rate", period) is_disabled = person("is_disabled", period.this_year) - special_needs_supplement = where( - is_disabled, p.supplements.special_needs, 0 - ) + special_needs_supplement = where(is_disabled, p.supplements.special_needs, 0) non_trad = person("wv_ccap_non_traditional_hours", period) - non_trad_supplement = where( - non_trad, p.supplements.non_traditional_hours, 0 - ) + non_trad_supplement = where(non_trad, p.supplements.non_traditional_hours, 0) daily_supplement = special_needs_supplement + non_trad_supplement pre_subsidy_per_child = person("pre_subsidy_childcare_expenses", period) per_child_reimbursement = min_( - daily_rate * base_billed_days - + daily_supplement * monthly_care_days, + daily_rate * base_billed_days + daily_supplement * monthly_care_days, pre_subsidy_per_child, ) total_reimbursement = spm_unit.sum(per_child_reimbursement) 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 e1d6746957b..a0c5cd77cea 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 @@ -15,19 +15,65 @@ class wv_ccap_copay(Variable): ) def formula(spm_unit, period, parameters): - # NOTE: %-of-income approximation of the 176-cell sliding fee scale - # (Appendix A), calibrated to the 3-person family column. Per Manual - # §6.4.3, the actual fee is charged per child up to 3 children — we - # apply that multiplier here. The 7% cap and <40% FPL waiver are in - # the rate schedule; foster waiver overrides below. + # Appendix A: daily co-payment per child looked up by family size and + # FPL ratio. Manual §6.4.3.2: fees are daily, assessed for each child + # 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) - fpl_ratio = where(fpg > 0, countable_income / max_(fpg, 1), 0) - per_child_rate = p.rate.calc(fpl_ratio) - num_eligible_children = add(spm_unit, period, ["wv_ccap_eligible_child"]) - billed_children = min_(num_eligible_children, p.max_billed_children) - uncapped_copay = countable_income * per_child_rate * billed_children + 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. + # Families with twelve or more people use the eleven-person column. + rate = p.rate + daily_fee_per_child = select( + [ + family_size == 1, + family_size == 2, + family_size == 3, + family_size == 4, + family_size == 5, + family_size == 6, + family_size == 7, + family_size == 8, + family_size == 9, + family_size == 10, + ], + [ + rate.size_1.calc(fpl_ratio), + rate.size_2.calc(fpl_ratio), + rate.size_3.calc(fpl_ratio), + rate.size_4.calc(fpl_ratio), + rate.size_5.calc(fpl_ratio), + rate.size_6.calc(fpl_ratio), + rate.size_7.calc(fpl_ratio), + rate.size_8.calc(fpl_ratio), + rate.size_9.calc(fpl_ratio), + rate.size_10.calc(fpl_ratio), + ], + default=rate.size_11.calc(fpl_ratio), + ) + person = spm_unit.members + is_eligible_child = person("wv_ccap_eligible_child", period) + weekly_days = person("childcare_days_per_week", period.this_year) + in_care = is_eligible_child & (weekly_days > 0) + num_in_care = spm_unit.sum(in_care) + total_monthly_days = ( + spm_unit.sum(weekly_days * in_care) * WEEKS_IN_YEAR / MONTHS_IN_YEAR + ) + # Per Manual §6.4.3.4: fee waived for any child beyond the three + # youngest. We don't track child ordering, so apply the cap as a + # uniform 3/N scaling across all eligible children in care. + billed_share = where( + num_in_care > 0, + min_(num_in_care, p.max_billed_children) / max_(num_in_care, 1), + 0, + ) + uncapped_copay = daily_fee_per_child * total_monthly_days * billed_share + # CCDF State Plan §3.1.1 caps the family fee at 7% of gross income. capped_copay = min_(uncapped_copay, countable_income * p.max_share) + # Manual §6.4.1 / CCDF Plan §3.3.1: foster-care children pay no fee. + # We model this at the family level (waive the whole family copay if + # any child is in foster care); per-child waiver isn't tracked. has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 return where(has_foster_child, 0, capped_copay) From 8b4e57707425e795e05e655f056047b47f747461 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 20 May 2026 01:17:05 -0400 Subject: [PATCH 15/16] final fix --- .../wv/dhhr/ccap/age_group/informal_months.yaml | 8 ++++---- .../states/wv/dhhr/ccap/age_group/months.yaml | 16 ++++++++-------- .../special_needs_child_age_limit.yaml | 2 +- .../ccap/income/countable_income/sources.yaml | 13 +++++++++++++ .../states/wv/dhhr/ccap/income/fpl_limit.yaml | 2 +- .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 6 +++--- .../gov/states/wv/dhhr/ccap/integration.yaml | 4 ++-- .../wv/dhhr/ccap/wv_ccap_eligible_child.yaml | 2 +- .../eligibility/wv_ccap_activity_eligible.py | 5 +++++ .../wv/dhhr/ccap/eligibility/wv_ccap_eligible.py | 3 +++ .../ccap/eligibility/wv_ccap_eligible_child.py | 6 ++++-- .../ccap/eligibility/wv_ccap_income_eligible.py | 4 +++- .../variables/gov/states/wv/dhhr/ccap/wv_ccap.py | 12 ++++++++++-- .../gov/states/wv/dhhr/ccap/wv_ccap_copay.py | 10 +++++++--- .../wv/dhhr/ccap/wv_ccap_countable_income.py | 2 +- .../states/wv/dhhr/ccap/wv_ccap_daily_benefit.py | 8 +++++--- 16 files changed, 71 insertions(+), 32 deletions(-) diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml index b53eb1c5471..a50533c0169 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/informal_months.yaml @@ -11,10 +11,10 @@ metadata: brackets: - threshold: - 2024-01-01: 0 + 2024-10-01: 0 amount: - 2024-01-01: 0 + 2024-10-01: 0 - threshold: - 2024-01-01: 25 + 2024-10-01: 25 amount: - 2024-01-01: 1 + 2024-10-01: 1 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml index d8443b9769e..4acb8a585f2 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/age_group/months.yaml @@ -11,18 +11,18 @@ metadata: brackets: - threshold: - 2024-01-01: 0 + 2024-10-01: 0 amount: - 2024-01-01: 0 + 2024-10-01: 0 - threshold: - 2024-01-01: 25 + 2024-10-01: 25 amount: - 2024-01-01: 1 + 2024-10-01: 1 - threshold: - 2024-01-01: 37 + 2024-10-01: 37 amount: - 2024-01-01: 2 + 2024-10-01: 2 - threshold: - 2024-01-01: 60 + 2024-10-01: 60 amount: - 2024-01-01: 3 + 2024-10-01: 3 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml index 60a7a898028..64328a283b2 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/special_needs_child_age_limit.yaml @@ -7,7 +7,7 @@ metadata: period: year label: West Virginia CCAP special needs child age limit reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.1.2 — Special Needs Children + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.1.2.2 — Special Needs Children href: https://bfa.wv.gov/media/6766/download?inline#page=25 - title: WV CCDF State Plan FFY 2025-2027, Section 2.2 href: https://bfa.wv.gov/media/39915/download?inline#page=16 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml index b742f9066dd..31bc4636bee 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml @@ -3,6 +3,7 @@ values: 2024-01-01: - employment_income - self_employment_income + - farm_operations_income - social_security - ssi - unemployment_compensation @@ -24,6 +25,18 @@ values: # The is_tanf_enrolled bypass in wv_ccap_income_eligible already # makes TANF-active families categorically income-eligible. # - tanf # would belong here + # + # Provisions we don't model at the moment: + # - §5.2.5.11 child-earnings exclusion (under-18 earnings of non-head/spouse) + # — we don't filter income sources by age of earner. + # - §5.2.4.3 sub-categories beyond TANF/SSI: Relative Caretaker Pay, WV + # Employment Assistance Program, WV Works Post-Employment Supplements + # — these don't have PolicyEngine variables at the moment. + # - §5.2.4.10 vocational-rehabilitation payments and §5.2.4.13 DoD + # Transitional Compensation (parent-directed portion) — no corresponding + # PolicyEngine variables at the moment. + # - §5.2.4.11 catch-all "any other monies received on a regular basis" + # — open-ended residual category we can't enumerate exhaustively. metadata: unit: list diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit.yaml index da6881f90cc..d3e7bffb328 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/fpl_limit.yaml @@ -7,7 +7,7 @@ metadata: period: year label: West Virginia CCAP income limit as share of federal poverty guideline reference: - - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.2.1 — Income Eligibility + - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.2.1 — Eligibility Guidelines href: https://bfa.wv.gov/media/6766/download?inline#page=25 - title: WV Child Care Subsidy Appendix A — Sliding Fee Scale (Oct 1, 2024) href: https://bfa.wv.gov/media/6826/download?inline#page=1 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 32ba1373a22..c06e17cd8b3 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 @@ -461,7 +461,7 @@ # Disabled child age 17.99 -> < 18 -> eligible age: 17.99 is_tax_unit_dependent: true - is_disabled: true + has_developmental_delay: true immigration_status: CITIZEN tax_units: tax_unit: @@ -488,7 +488,7 @@ # Disabled child age 18 -> NOT < 18 -> ineligible age: 18 is_tax_unit_dependent: true - is_disabled: true + has_developmental_delay: true immigration_status: CITIZEN tax_units: tax_unit: @@ -1334,7 +1334,7 @@ person2: age: 8 is_tax_unit_dependent: true - is_disabled: true + has_developmental_delay: true immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I 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 c3d0ff0da43..a2f71dd6584 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 @@ -165,7 +165,7 @@ person2: age: 15 is_tax_unit_dependent: true - is_disabled: true + has_developmental_delay: true immigration_status: CITIZEN ssi: 0 wv_ccap_provider_type: CENTER @@ -291,7 +291,7 @@ person2: age: 3 is_tax_unit_dependent: true - is_disabled: true + has_developmental_delay: true ssi: 0 immigration_status: CITIZEN wv_ccap_provider_type: CENTER diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml index d950bd9514b..1decd9bd8b7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_eligible_child.yaml @@ -53,7 +53,7 @@ person2: age: 15 is_tax_unit_dependent: true - is_disabled: true + has_developmental_delay: true immigration_status: CITIZEN tax_units: tax_unit: diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py index dca755c0e69..5765f723b05 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py @@ -10,6 +10,11 @@ class wv_ccap_activity_eligible(Variable): reference = "https://bfa.wv.gov/media/6766/download?inline#page=32" def formula(spm_unit, period, parameters): + # NOTE: we use is_full_time_student as a proxy for Manual §3.6.3, which + # requires specific credit-hour minimums and excludes web-only courses. + # We don't track high-school students (§3.6.2.2 exempts them from the + # weekly-hours floor) or CPS Safety/Treatment Plan recipients + # (§3.6.4 exempts them from activity hours) at the moment. p = parameters(period).gov.states.wv.dhhr.ccap.eligibility person = spm_unit.members is_head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py index 84f0ed84344..41357b887b5 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible.py @@ -15,6 +15,9 @@ class wv_ccap_eligible(Variable): def formula(spm_unit, period, parameters): # NOTE: we don't model minor-parent eligibility (Manual §1.1.10, §4.5.3.6, §4.5.6) # because tax-unit head/spouse status excludes people under 18. + # We don't enforce the WV minimum-wage earnings floor (Manual §3.5) or + # split joint-custody households into two families (Manual §3.2.3) at + # the moment. has_eligible_child = add(spm_unit, period, ["wv_ccap_eligible_child"]) > 0 income_eligible = spm_unit("wv_ccap_income_eligible", period) asset_eligible = spm_unit("is_ccdf_asset_eligible", period.this_year) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py index 84b244d4e85..7cbce8da5df 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_eligible_child.py @@ -17,9 +17,11 @@ def formula(person, period, parameters): # 13-17 extension applies only via the special-needs branch (§3.1.2.2). p = parameters(period).gov.states.wv.dhhr.ccap.eligibility age = person("age", period.this_year) - is_disabled = person("is_disabled", period.this_year) + has_developmental_delay = person("has_developmental_delay", period.this_year) age_eligible = where( - is_disabled, age < p.special_needs_child_age_limit, age < p.child_age_limit + has_developmental_delay, + age < p.special_needs_child_age_limit, + age < p.child_age_limit, ) immigration_eligible = person( "is_ccdf_immigration_eligible_child", period.this_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 a7beadfc58b..2ff825bb907 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 @@ -15,7 +15,9 @@ class wv_ccap_income_eligible(Variable): 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. + # 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) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py index cbd5ed05625..9e8d09b7a85 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py @@ -19,6 +19,12 @@ def formula(spm_unit, period, parameters): # Manual §7.2.7.2: rate supplements (special needs, shift differential) # are paid for actual days of care only — the monthly rate does NOT # apply to rate supplements. + # We don't track per-day attendance hours at the moment, so every + # attended day is paid at the full-day rate; the part-day conversion + # (§7.2.7.6 — 2/3 rate for 2-4 hrs, 1/3 for < 2 hrs), the full-day + # 4-hr minimum (§7.2.7.5), the 18-hour daily cap (§7.2.1), and the + # two-provider-per-child billing rule (§6.4.2, §7.2.3, §7.2.5) are + # not modeled. p = parameters(period).gov.states.wv.dhhr.ccap person = spm_unit.members weekly_care_days = person("childcare_days_per_week", period.this_year) @@ -32,8 +38,10 @@ def formula(spm_unit, period, parameters): monthly_care_days, ) daily_rate = person("wv_ccap_daily_rate", period) - is_disabled = person("is_disabled", period.this_year) - special_needs_supplement = where(is_disabled, p.supplements.special_needs, 0) + has_developmental_delay = person("has_developmental_delay", period.this_year) + special_needs_supplement = where( + has_developmental_delay, p.supplements.special_needs, 0 + ) non_trad = person("wv_ccap_non_traditional_hours", period) non_trad_supplement = where(non_trad, p.supplements.non_traditional_hours, 0) daily_supplement = special_needs_supplement + non_trad_supplement 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 a0c5cd77cea..e41d36ee12e 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 @@ -11,7 +11,7 @@ class wv_ccap_copay(Variable): reference = ( "https://bfa.wv.gov/media/6826/download?inline#page=1", "https://bfa.wv.gov/media/6766/download?inline#page=65", - "https://bfa.wv.gov/media/39915/download?inline#page=40", + "https://bfa.wv.gov/media/39915/download?inline#page=42", ) def formula(spm_unit, period, parameters): @@ -73,7 +73,11 @@ def formula(spm_unit, period, parameters): # CCDF State Plan §3.1.1 caps the family fee at 7% of gross income. capped_copay = min_(uncapped_copay, countable_income * p.max_share) # Manual §6.4.1 / CCDF Plan §3.3.1: foster-care children pay no fee. - # We model this at the family level (waive the whole family copay if - # any child is in foster care); per-child waiver isn't tracked. + # We don't track per-child fee waivers at the moment, so we waive the + # whole family copay if any child is in foster care. + # We don't track kinship-care placements (CCDF Plan §3.3.1(vi)), + # CPS Safety/Treatment Plans (Manual §6.4.1), or protective-services + # status (CCDF Plan §3.3.1(vi)) at the moment, so the corresponding + # fee waivers are not applied. has_foster_child = add(spm_unit, period, ["is_in_foster_care"]) > 0 return where(has_foster_child, 0, capped_copay) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py index 754b8ab530b..07818e2460b 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_countable_income.py @@ -8,6 +8,6 @@ class wv_ccap_countable_income(Variable): definition_period = MONTH unit = USD defined_for = StateCode.WV - reference = "https://bfa.wv.gov/media/6766/download?inline#page=49" + reference = "https://bfa.wv.gov/media/6766/download?inline#page=51" adds = "gov.states.wv.dhhr.ccap.income.countable_income.sources" diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py index 0a530e4728f..140e8c3487f 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py @@ -8,13 +8,15 @@ class wv_ccap_daily_benefit(Variable): label = "West Virginia CCAP daily benefit per child" definition_period = MONTH defined_for = "wv_ccap_eligible_child" - reference = "https://bfa.wv.gov/media/6766/download?inline#page=79" + reference = "https://bfa.wv.gov/media/6766/download?inline#page=80" def formula(person, period, parameters): p = parameters(period).gov.states.wv.dhhr.ccap daily_rate = person("wv_ccap_daily_rate", period) - is_disabled = person("is_disabled", period.this_year) - special_needs_supplement = where(is_disabled, p.supplements.special_needs, 0) + has_developmental_delay = person("has_developmental_delay", period.this_year) + special_needs_supplement = where( + has_developmental_delay, p.supplements.special_needs, 0 + ) non_trad = person("wv_ccap_non_traditional_hours", period) non_trad_supplement = where(non_trad, p.supplements.non_traditional_hours, 0) total_rate = daily_rate + special_needs_supplement + non_trad_supplement From db8934376ef685bfd2d95005dd36ec75d5dc4bbc Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 27 May 2026 00:01:20 -0400 Subject: [PATCH 16/16] Address Pavel's review findings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Switch from childcare_days_per_week to childcare_attending_days_per_month to eliminate the weeks-to-months conversion duplicated across three files - Refactor wv_ccap.py to call wv_ccap_daily_benefit (no longer dead) - Document why military_retirement_pay is included alongside pension_income - Add tests for <13 monthly days, family size 12+, and 3/N billing cap - Fix max_billed_children unit from int to /1 - Bump §3.6.1 page anchor 32 → 33 in activity_hours and activity_eligible - Align wv_ccap_copay CCDF page anchor 42 → 39 with max_share - Strip trailing zeros from all copayment/rate/size_*.yaml Co-Authored-By: Claude Opus 4.7 (1M context) --- .../ccap/copayment/max_billed_children.yaml | 2 +- .../wv/dhhr/ccap/copayment/rate/size_1.yaml | 18 +-- .../wv/dhhr/ccap/copayment/rate/size_10.yaml | 14 +- .../wv/dhhr/ccap/copayment/rate/size_11.yaml | 14 +- .../wv/dhhr/ccap/copayment/rate/size_2.yaml | 6 +- .../wv/dhhr/ccap/copayment/rate/size_3.yaml | 18 +-- .../wv/dhhr/ccap/copayment/rate/size_4.yaml | 16 +-- .../wv/dhhr/ccap/copayment/rate/size_5.yaml | 14 +- .../wv/dhhr/ccap/copayment/rate/size_6.yaml | 16 +-- .../wv/dhhr/ccap/copayment/rate/size_7.yaml | 12 +- .../wv/dhhr/ccap/copayment/rate/size_8.yaml | 14 +- .../wv/dhhr/ccap/copayment/rate/size_9.yaml | 18 +-- .../dhhr/ccap/eligibility/activity_hours.yaml | 2 +- .../ccap/income/countable_income/sources.yaml | 2 + .../gov/states/wv/dhhr/ccap/edge_cases.yaml | 90 ++++++------- .../gov/states/wv/dhhr/ccap/integration.yaml | 123 ++++++++++++------ .../states/wv/dhhr/ccap/wv_ccap_copay.yaml | 106 +++++++++++++-- .../wv/dhhr/ccap/wv_ccap_daily_benefit.yaml | 20 +-- .../wv/dhhr/ccap/wv_child_care_subsidies.yaml | 6 +- .../eligibility/wv_ccap_activity_eligible.py | 2 +- .../gov/states/wv/dhhr/ccap/wv_ccap.py | 17 +-- .../gov/states/wv/dhhr/ccap/wv_ccap_copay.py | 12 +- .../wv/dhhr/ccap/wv_ccap_daily_benefit.py | 8 +- 23 files changed, 338 insertions(+), 212 deletions(-) diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml index d59e3adbe27..e9d9371d5c9 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/max_billed_children.yaml @@ -3,7 +3,7 @@ values: 2024-10-01: 3 metadata: - unit: int + unit: /1 period: year label: West Virginia CCAP maximum billed children reference: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_1.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_1.yaml index 9fe252ebb6a..0dd9f342088 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_1.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_1.yaml @@ -17,11 +17,11 @@ brackets: - threshold: 2024-10-01: 0.4001 amount: - 2024-10-01: 1.50 + 2024-10-01: 1.5 - threshold: 2024-10-01: 0.5001 amount: - 2024-10-01: 2.00 + 2024-10-01: 2 - threshold: 2024-10-01: 0.6001 amount: @@ -33,11 +33,11 @@ brackets: - threshold: 2024-10-01: 0.8001 amount: - 2024-10-01: 3.00 + 2024-10-01: 3 - threshold: 2024-10-01: 0.9001 amount: - 2024-10-01: 3.50 + 2024-10-01: 3.5 - threshold: 2024-10-01: 1.0001 amount: @@ -49,11 +49,11 @@ brackets: - threshold: 2024-10-01: 1.2001 amount: - 2024-10-01: 4.50 + 2024-10-01: 4.5 - threshold: 2024-10-01: 1.3001 amount: - 2024-10-01: 5.00 + 2024-10-01: 5 - threshold: 2024-10-01: 1.4001 amount: @@ -65,12 +65,12 @@ brackets: - threshold: 2024-10-01: 1.6001 amount: - 2024-10-01: 6.00 + 2024-10-01: 6 - threshold: 2024-10-01: 1.7001 amount: - 2024-10-01: 6.50 + 2024-10-01: 6.5 - threshold: 2024-10-01: 1.8001 amount: - 2024-10-01: 7.00 + 2024-10-01: 7 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_10.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_10.yaml index 739f13c35ca..4ec1570aa0a 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_10.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_10.yaml @@ -19,7 +19,7 @@ brackets: - threshold: 2024-10-01: 0.4001 amount: - 2024-10-01: 3.00 + 2024-10-01: 3 - threshold: 2024-10-01: 0.5001 amount: @@ -27,7 +27,7 @@ brackets: - threshold: 2024-10-01: 0.6001 amount: - 2024-10-01: 4.50 + 2024-10-01: 4.5 - threshold: 2024-10-01: 0.7001 amount: @@ -39,7 +39,7 @@ brackets: - threshold: 2024-10-01: 0.9001 amount: - 2024-10-01: 7.00 + 2024-10-01: 7 - threshold: 2024-10-01: 1.0001 amount: @@ -47,7 +47,7 @@ brackets: - threshold: 2024-10-01: 1.1001 amount: - 2024-10-01: 8.50 + 2024-10-01: 8.5 - threshold: 2024-10-01: 1.2001 amount: @@ -55,7 +55,7 @@ brackets: - threshold: 2024-10-01: 1.3001 amount: - 2024-10-01: 10.00 + 2024-10-01: 10 - threshold: 2024-10-01: 1.4001 amount: @@ -63,7 +63,7 @@ brackets: - threshold: 2024-10-01: 1.5001 amount: - 2024-10-01: 11.50 + 2024-10-01: 11.5 - threshold: 2024-10-01: 1.6001 amount: @@ -71,4 +71,4 @@ brackets: - threshold: 2024-10-01: 1.7001 amount: - 2024-10-01: 13.00 + 2024-10-01: 13 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_11.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_11.yaml index b23bdaad999..610e820c89f 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_11.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_11.yaml @@ -28,15 +28,15 @@ brackets: - threshold: 2024-10-01: 0.6001 amount: - 2024-10-01: 3.50 + 2024-10-01: 3.5 - threshold: 2024-10-01: 0.7001 amount: - 2024-10-01: 4.00 + 2024-10-01: 4 - threshold: 2024-10-01: 0.8001 amount: - 2024-10-01: 4.50 + 2024-10-01: 4.5 - threshold: 2024-10-01: 0.9001 amount: @@ -52,19 +52,19 @@ brackets: - threshold: 2024-10-01: 1.2001 amount: - 2024-10-01: 7.00 + 2024-10-01: 7 - threshold: 2024-10-01: 1.3001 amount: - 2024-10-01: 7.50 + 2024-10-01: 7.5 - threshold: 2024-10-01: 1.4001 amount: - 2024-10-01: 8.00 + 2024-10-01: 8 - threshold: 2024-10-01: 1.5001 amount: - 2024-10-01: 8.50 + 2024-10-01: 8.5 - threshold: 2024-10-01: 1.6001 amount: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_2.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_2.yaml index f32f8adaa3f..c8a66cb363b 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_2.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_2.yaml @@ -17,15 +17,15 @@ brackets: - threshold: 2024-10-01: 0.4001 amount: - 2024-10-01: 2.00 + 2024-10-01: 2 - threshold: 2024-10-01: 0.5001 amount: - 2024-10-01: 2.50 + 2024-10-01: 2.5 - threshold: 2024-10-01: 0.6001 amount: - 2024-10-01: 3.00 + 2024-10-01: 3 - threshold: 2024-10-01: 0.7001 amount: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_3.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_3.yaml index 415d1856a8c..24d79d3dea9 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_3.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_3.yaml @@ -25,7 +25,7 @@ brackets: - threshold: 2024-10-01: 0.6001 amount: - 2024-10-01: 2.00 + 2024-10-01: 2 - threshold: 2024-10-01: 0.7001 amount: @@ -33,11 +33,11 @@ brackets: - threshold: 2024-10-01: 0.8001 amount: - 2024-10-01: 2.50 + 2024-10-01: 2.5 - threshold: 2024-10-01: 0.9001 amount: - 2024-10-01: 3.00 + 2024-10-01: 3 - threshold: 2024-10-01: 1.0001 amount: @@ -45,11 +45,11 @@ brackets: - threshold: 2024-10-01: 1.1001 amount: - 2024-10-01: 3.50 + 2024-10-01: 3.5 - threshold: 2024-10-01: 1.2001 amount: - 2024-10-01: 4.00 + 2024-10-01: 4 - threshold: 2024-10-01: 1.3001 amount: @@ -57,11 +57,11 @@ brackets: - threshold: 2024-10-01: 1.4001 amount: - 2024-10-01: 4.50 + 2024-10-01: 4.5 - threshold: 2024-10-01: 1.5001 amount: - 2024-10-01: 5.00 + 2024-10-01: 5 - threshold: 2024-10-01: 1.6001 amount: @@ -69,8 +69,8 @@ brackets: - threshold: 2024-10-01: 1.7001 amount: - 2024-10-01: 5.50 + 2024-10-01: 5.5 - threshold: 2024-10-01: 1.8001 amount: - 2024-10-01: 6.00 + 2024-10-01: 6 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_4.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_4.yaml index 49ef65ab21e..c39c4a3bf2b 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_4.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_4.yaml @@ -17,7 +17,7 @@ brackets: - threshold: 2024-10-01: 0.4001 amount: - 2024-10-01: 1.00 + 2024-10-01: 1 - threshold: 2024-10-01: 0.5001 amount: @@ -25,7 +25,7 @@ brackets: - threshold: 2024-10-01: 0.6001 amount: - 2024-10-01: 1.50 + 2024-10-01: 1.5 - threshold: 2024-10-01: 0.7001 amount: @@ -33,7 +33,7 @@ brackets: - threshold: 2024-10-01: 0.8001 amount: - 2024-10-01: 2.00 + 2024-10-01: 2 - threshold: 2024-10-01: 0.9001 amount: @@ -41,7 +41,7 @@ brackets: - threshold: 2024-10-01: 1.0001 amount: - 2024-10-01: 2.50 + 2024-10-01: 2.5 - threshold: 2024-10-01: 1.1001 amount: @@ -49,11 +49,11 @@ brackets: - threshold: 2024-10-01: 1.2001 amount: - 2024-10-01: 3.00 + 2024-10-01: 3 - threshold: 2024-10-01: 1.3001 amount: - 2024-10-01: 3.50 + 2024-10-01: 3.5 - threshold: 2024-10-01: 1.4001 amount: @@ -61,7 +61,7 @@ brackets: - threshold: 2024-10-01: 1.5001 amount: - 2024-10-01: 4.00 + 2024-10-01: 4 - threshold: 2024-10-01: 1.6001 amount: @@ -69,7 +69,7 @@ brackets: - threshold: 2024-10-01: 1.7001 amount: - 2024-10-01: 4.50 + 2024-10-01: 4.5 - threshold: 2024-10-01: 1.8001 amount: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_5.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_5.yaml index 7a74d1a4428..c189b8b0b37 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_5.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_5.yaml @@ -21,7 +21,7 @@ brackets: - threshold: 2024-10-01: 0.5001 amount: - 2024-10-01: 1.50 + 2024-10-01: 1.5 - threshold: 2024-10-01: 0.6001 amount: @@ -33,7 +33,7 @@ brackets: - threshold: 2024-10-01: 0.8001 amount: - 2024-10-01: 2.50 + 2024-10-01: 2.5 - threshold: 2024-10-01: 0.9001 amount: @@ -41,7 +41,7 @@ brackets: - threshold: 2024-10-01: 1.0001 amount: - 2024-10-01: 3.00 + 2024-10-01: 3 - threshold: 2024-10-01: 1.1001 amount: @@ -53,7 +53,7 @@ brackets: - threshold: 2024-10-01: 1.3001 amount: - 2024-10-01: 4.00 + 2024-10-01: 4 - threshold: 2024-10-01: 1.4001 amount: @@ -61,11 +61,11 @@ brackets: - threshold: 2024-10-01: 1.5001 amount: - 2024-10-01: 4.50 + 2024-10-01: 4.5 - threshold: 2024-10-01: 1.6001 amount: - 2024-10-01: 5.00 + 2024-10-01: 5 - threshold: 2024-10-01: 1.7001 amount: @@ -73,4 +73,4 @@ brackets: - threshold: 2024-10-01: 1.8001 amount: - 2024-10-01: 5.50 + 2024-10-01: 5.5 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_6.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_6.yaml index 056430e3ad0..9dc7f110148 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_6.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_6.yaml @@ -17,7 +17,7 @@ brackets: - threshold: 2024-10-01: 0.4001 amount: - 2024-10-01: 1.50 + 2024-10-01: 1.5 - threshold: 2024-10-01: 0.5001 amount: @@ -25,11 +25,11 @@ brackets: - threshold: 2024-10-01: 0.6001 amount: - 2024-10-01: 2.00 + 2024-10-01: 2 - threshold: 2024-10-01: 0.7001 amount: - 2024-10-01: 2.50 + 2024-10-01: 2.5 - threshold: 2024-10-01: 0.8001 amount: @@ -41,7 +41,7 @@ brackets: - threshold: 2024-10-01: 1.0001 amount: - 2024-10-01: 3.50 + 2024-10-01: 3.5 - threshold: 2024-10-01: 1.1001 amount: @@ -53,11 +53,11 @@ brackets: - threshold: 2024-10-01: 1.3001 amount: - 2024-10-01: 4.50 + 2024-10-01: 4.5 - threshold: 2024-10-01: 1.4001 amount: - 2024-10-01: 5.00 + 2024-10-01: 5 - threshold: 2024-10-01: 1.5001 amount: @@ -65,11 +65,11 @@ brackets: - threshold: 2024-10-01: 1.6001 amount: - 2024-10-01: 5.50 + 2024-10-01: 5.5 - threshold: 2024-10-01: 1.7001 amount: - 2024-10-01: 6.00 + 2024-10-01: 6 - threshold: 2024-10-01: 1.8001 amount: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_7.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_7.yaml index b92e03a27b7..9f9050ccaa1 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_7.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_7.yaml @@ -25,15 +25,15 @@ brackets: - threshold: 2024-10-01: 0.6001 amount: - 2024-10-01: 3.50 + 2024-10-01: 3.5 - threshold: 2024-10-01: 0.7001 amount: - 2024-10-01: 4.00 + 2024-10-01: 4 - threshold: 2024-10-01: 0.8001 amount: - 2024-10-01: 4.50 + 2024-10-01: 4.5 - threshold: 2024-10-01: 0.9001 amount: @@ -53,15 +53,15 @@ brackets: - threshold: 2024-10-01: 1.3001 amount: - 2024-10-01: 7.50 + 2024-10-01: 7.5 - threshold: 2024-10-01: 1.4001 amount: - 2024-10-01: 8.00 + 2024-10-01: 8 - threshold: 2024-10-01: 1.5001 amount: - 2024-10-01: 8.50 + 2024-10-01: 8.5 - threshold: 2024-10-01: 1.6001 amount: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_8.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_8.yaml index 2c91891679f..eed0ba47e75 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_8.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_8.yaml @@ -17,7 +17,7 @@ brackets: - threshold: 2024-10-01: 0.4001 amount: - 2024-10-01: 2.50 + 2024-10-01: 2.5 - threshold: 2024-10-01: 0.5001 amount: @@ -29,11 +29,11 @@ brackets: - threshold: 2024-10-01: 0.7001 amount: - 2024-10-01: 4.50 + 2024-10-01: 4.5 - threshold: 2024-10-01: 0.8001 amount: - 2024-10-01: 5.00 + 2024-10-01: 5 - threshold: 2024-10-01: 0.9001 amount: @@ -45,7 +45,7 @@ brackets: - threshold: 2024-10-01: 1.1001 amount: - 2024-10-01: 7.00 + 2024-10-01: 7 - threshold: 2024-10-01: 1.2001 amount: @@ -57,11 +57,11 @@ brackets: - threshold: 2024-10-01: 1.4001 amount: - 2024-10-01: 9.00 + 2024-10-01: 9 - threshold: 2024-10-01: 1.5001 amount: - 2024-10-01: 9.50 + 2024-10-01: 9.5 - threshold: 2024-10-01: 1.6001 amount: @@ -73,4 +73,4 @@ brackets: - threshold: 2024-10-01: 1.8001 amount: - 2024-10-01: 11.50 + 2024-10-01: 11.5 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_9.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_9.yaml index ed7ad5cf3a5..4c456873a13 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_9.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/copayment/rate/size_9.yaml @@ -21,7 +21,7 @@ brackets: - threshold: 2024-10-01: 0.5001 amount: - 2024-10-01: 3.50 + 2024-10-01: 3.5 - threshold: 2024-10-01: 0.6001 amount: @@ -29,11 +29,11 @@ brackets: - threshold: 2024-10-01: 0.7001 amount: - 2024-10-01: 5.00 + 2024-10-01: 5 - threshold: 2024-10-01: 0.8001 amount: - 2024-10-01: 5.50 + 2024-10-01: 5.5 - threshold: 2024-10-01: 0.9001 amount: @@ -41,7 +41,7 @@ brackets: - threshold: 2024-10-01: 1.0001 amount: - 2024-10-01: 7.00 + 2024-10-01: 7 - threshold: 2024-10-01: 1.1001 amount: @@ -49,11 +49,11 @@ brackets: - threshold: 2024-10-01: 1.2001 amount: - 2024-10-01: 8.50 + 2024-10-01: 8.5 - threshold: 2024-10-01: 1.3001 amount: - 2024-10-01: 9.00 + 2024-10-01: 9 - threshold: 2024-10-01: 1.4001 amount: @@ -61,7 +61,7 @@ brackets: - threshold: 2024-10-01: 1.5001 amount: - 2024-10-01: 10.50 + 2024-10-01: 10.5 - threshold: 2024-10-01: 1.6001 amount: @@ -69,8 +69,8 @@ brackets: - threshold: 2024-10-01: 1.7001 amount: - 2024-10-01: 12.00 + 2024-10-01: 12 - threshold: 2024-10-01: 1.8001 amount: - 2024-10-01: 12.50 + 2024-10-01: 12.5 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml index 3420a339e05..ffe50476e7e 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/eligibility/activity_hours.yaml @@ -8,4 +8,4 @@ metadata: label: West Virginia CCAP minimum weekly activity hours reference: - title: WV Child Care Subsidy Policy & Procedures Manual, Chapter 3, Section 3.6.1 — Working Recipients - href: https://bfa.wv.gov/media/6766/download?inline#page=32 + href: https://bfa.wv.gov/media/6766/download?inline#page=33 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml index 31bc4636bee..9bccce64e85 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/ccap/income/countable_income/sources.yaml @@ -15,6 +15,8 @@ values: - interest_income - rental_income - veterans_benefits + # PolicyEngine records military retirement separately from pension_income, + # so include it under Manual Sec. 5.2.4.4 pensions and annuities. - military_retirement_pay # TANF is countable per Manual Sec 5.2.4.3 but excluded here to avoid # a circular dependency: 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 c06e17cd8b3..a68fde6ee7e 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 @@ -24,7 +24,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 10_000 tax_units: tax_unit: @@ -56,7 +56,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 10_000 tax_units: tax_unit: @@ -88,7 +88,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 10_000 tax_units: tax_unit: @@ -344,7 +344,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 5_000 tax_units: tax_unit: @@ -551,7 +551,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 8_000 tax_units: tax_unit: @@ -587,7 +587,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 8_000 tax_units: tax_unit: @@ -603,9 +603,9 @@ output: # Monthly income = 8_475 / 12 = $706.25. 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 × 21.67 × 1 = $43.33. + # copay = $2.00 × 22 × 1 = $44. # 7% cap = $706.25 × 0.07 = $49.44; cap does not bind. - wv_ccap_copay: 43.33 + wv_ccap_copay: 44 # ============================================================ # Copay 7% cap behavior @@ -627,7 +627,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 10_000 tax_units: tax_unit: @@ -643,9 +643,9 @@ output: # Monthly income = $2_996.25. 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 × 21.67 × 1 = $178.75. + # uncapped copay = $8.25 × 22 × 1 = $181.50. # 7% cap = $2_996.25 × 0.07 = $209.74; cap does not bind. - wv_ccap_copay: 178.75 + wv_ccap_copay: 181.5 - name: Case 19, large family with three children triggers 7 percent cap. period: 2025-01 @@ -662,7 +662,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 6_000 person3: age: 5 @@ -670,7 +670,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 6_000 person4: age: 7 @@ -678,7 +678,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 6_000 person5: age: 15 @@ -705,8 +705,8 @@ output: # 7-person family, monthly income $3_500. FPG family-of-7 = $3_945; ratio = 0.887. # Appendix A 7-person "90%" row daily fee = $4.50/child. - # 3 eligible children × 5 days × 52/12 = 65 monthly days total. - # uncapped copay = $4.50 × 65 × 1 = $292.50. + # 3 eligible children × 22 monthly days = 66 monthly days total. + # uncapped copay = $4.50 × 66 × 1 = $297. # 7% cap = $3_500 × 0.07 = $245; cap binds. wv_ccap_copay: 245 @@ -819,7 +819,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 8_000 tax_units: tax_unit: @@ -854,7 +854,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 8_000 tax_units: tax_unit: @@ -1303,7 +1303,7 @@ wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I wv_ccap_non_traditional_hours: true - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 12_000 tax_units: tax_unit: @@ -1318,8 +1318,8 @@ state_code: WV output: # Center Tier I Toddler = $37 + $6 non-trad = $43 - # daily charge = (12_000/12) / (5 * 52/12) = 1_000 / 21.67 = 46.15 - # daily benefit = min(43, 46.15) = 43 + # daily charge = (12_000/12) / 22 = 45.45 + # daily benefit = min(43, 45.45) = 43 wv_ccap_daily_benefit: [0, 43] - name: Case 40, both special needs and non-traditional supplements. @@ -1339,7 +1339,7 @@ wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I wv_ccap_non_traditional_hours: true - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 15_000 tax_units: tax_unit: @@ -1354,8 +1354,8 @@ state_code: WV output: # Center Tier I School Age = $32 + $3 special needs + $6 non-trad = $41 - # daily charge = (15_000/12) / (5 * 52/12) = 1_250 / 21.67 = 57.69 - # daily benefit = min(41, 57.69) = 41 + # daily charge = (15_000/12) / 22 = 56.82 + # daily benefit = min(41, 56.82) = 41 wv_ccap_daily_benefit: [0, 41] # ============================================================ @@ -1446,7 +1446,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_III - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 # Low childcare expenses: rate will exceed daily charge pre_subsidy_childcare_expenses: 3_600 tax_units: @@ -1464,16 +1464,16 @@ # Center Tier III Infant = $45/day wv_ccap_daily_rate: [0, 45] - # daily charge = (3_600/12) / (5 * 52/12) = 300 / 21.67 = 13.84 - # daily benefit = min(45, 13.84) = 13.84 - wv_ccap_daily_benefit: [0, 13.84] + # daily charge = (3_600/12) / 22 = 13.64 + # 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. - # Appendix A 2-person "120%" row daily fee = $5.75/child; 21.67 days. - # copay = $5.75 × 21.67 = $124.58. - # 21.67 days > 20 → per-day billing; per_child = min($45 × 21.67, $300) = $300. - # benefit = max($300 - $124.58, 0) = $175.42. - wv_ccap: 175.42 + # 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. + # benefit = max($300 - $126.50, 0) = $173.50. + wv_ccap: 173.5 # ============================================================ # Zero childcare days/expenses @@ -1494,7 +1494,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 0 + childcare_attending_days_per_month: 0 pre_subsidy_childcare_expenses: 0 tax_units: tax_unit: @@ -1667,7 +1667,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: FAMILY_HOME wv_ccap_quality_tier: TIER_II - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 6_000 person3: age: 6 @@ -1675,7 +1675,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 3 + childcare_attending_days_per_month: 13 pre_subsidy_childcare_expenses: 4_000 tax_units: tax_unit: @@ -1701,20 +1701,20 @@ # 3-person family, FPL ratio = 1_666.67 / 2_151.67 = 0.7746 → bracket # "above 70% up to 80%" → Appendix A 3-person "80%" row daily fee = $2.25/child. - # person2: 5 days/week; person3: 3 days/week → 8 weekly × 52/12 = 34.67 monthly days. + # person2: 22 days/month; person3: 13 days/month → 35 monthly days. # 2 eligible children in care → billed_share = 2/2 = 1. - # copay = $2.25 × 34.67 × 1 = $78.00. - wv_ccap_copay: 78 + # copay = $2.25 × 35 × 1 = $78.75. + wv_ccap_copay: 78.75 - # Person2 (FAMILY_HOME Tier II Infant, 5 days/wk, $6_000/yr expenses): - # monthly expenses $500; actual_days 21.67 (>20 → per-day billing). - # per_child = min($33 × 21.67, $500) = $500. - # Person3 (CENTER Tier I School-Age, 3 days/wk, $4_000/yr expenses): + # Person2 (FAMILY_HOME Tier II Infant, 22 days/month, $6_000/yr expenses): + # monthly expenses $500; actual_days 22 (>20 → per-day billing). + # per_child = min($33 × 22, $500) = $500. + # Person3 (CENTER Tier I School-Age, 13 days/month, $4_000/yr expenses): # monthly expenses $333.33; actual_days 13 (in 13-20 → monthly rate, 20 days). # per_child = min($32 × 20, $333.33) = $333.33. # total reimbursement = $500 + $333.33 = $833.33. - # benefit = max($833.33 - $78, 0) = $755.33. - wv_ccap: 755.33 + # benefit = max($833.33 - $78.75, 0) = $754.58. + wv_ccap: 754.58 # ============================================================ # Child-only SPM unit cannot pass activity test 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 a2f71dd6584..824bf866a7e 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 @@ -19,7 +19,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 8_000 tax_units: tax_unit: @@ -52,19 +52,19 @@ # === Copay === # 2-person family, FPL ratio = 2_000 / 1_762.50 = 1.1348. # Appendix A 2-person "120%" row daily fee = $5.75/child. - # 1 eligible child × 5 days/week × 52/12 = 21.67 monthly days. - # copay = $5.75 × 21.67 × 1 = $124.58. - wv_ccap_copay: 124.58 + # 1 eligible child × 22 monthly days. + # copay = $5.75 × 22 × 1 = $126.50. + wv_ccap_copay: 126.5 # === Daily benefit (view variable: rate + supplements capped at daily charge) === - # daily charge = (8_000/12) / 21.67 = 30.77; daily benefit = min(37, 30.77) = 30.77. - wv_ccap_daily_benefit: [0, 30.77] + # daily charge = (8_000/12) / 22 = 30.30; daily benefit = min(37, 30.30) = 30.30. + wv_ccap_daily_benefit: [0, 30.3] # === Monthly benefit === - # 21.67 days/month > 20 → per-day billing for base; no supplements. - # per_child reimbursement = min($37 × 21.67, $666.67) = $666.67. - # benefit = max($666.67 - $124.58, 0) = $542.08. - wv_ccap: 542.08 + # 22 days/month > 20 → per-day billing for base; no supplements. + # per_child reimbursement = min($37 × 22, $666.67) = $666.67. + # benefit = max($666.67 - $126.50, 0) = $540.17. + wv_ccap: 540.17 - name: Case 2, low income family with zero copay. period: 2025-01 @@ -81,7 +81,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: FAMILY_HOME wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 6_000 tax_units: tax_unit: @@ -108,13 +108,11 @@ # FPL ratio = 500 / 1_762.50 = 0.2837 < 0.40 -> 0% copay wv_ccap_copay: 0 - # daily charge = 500 / 21.67 = 23.07 - # daily benefit = min(30, 23.07) = 23.07 - wv_ccap_daily_benefit: [0, 23.07] + # daily charge = 500 / 22 = 22.73 + # daily benefit = min(30, 22.73) = 22.73 + wv_ccap_daily_benefit: [0, 22.73] - # total reimbursement = (500/21.6667) * 21.6667 = 500 - # uncapped = max(500 - 0, 0) = 500 - # benefit = min(500, 500) = 500 + # total reimbursement = min($500 expense, $22.73 × 22) = $500 wv_ccap: 500 - name: Case 3, ineligible family gets zero benefit. @@ -134,7 +132,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 10_000 tax_units: tax_unit: @@ -170,7 +168,7 @@ ssi: 0 wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_II - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 10_000 tax_units: tax_unit: @@ -196,18 +194,17 @@ wv_ccap_daily_rate: [0, 35] # Daily benefit (view): rate + supplement capped at daily charge. - # daily charge = (10_000/12) / 21.67 = 38.46; daily benefit = min(35+3, 38.46) = 38. - wv_ccap_daily_benefit: [0, 38] + # 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 × 21.67 = $124.58. - wv_ccap_copay: 124.58 + # Copay: same 2-person FPL 1.1348 → Appendix A "120%" row $5.75/day × 22 = $126.50. + wv_ccap_copay: 126.5 - # 21.67 days/month > 20 → per-day billing for base. + # 22 days/month > 20 → per-day billing for base. # Manual §7.2.7.2: supplements bill for actual days only (same here, per-day billing). - # per_child = min($35 × 21.67 + $3 × 21.67, $833.33) - # = min($823.33, $833.33) = $823.33. - # benefit = max($823.33 - $124.58, 0) = $698.75. - wv_ccap: 698.75 + # per_child = min($35 × 22 + $3 × 22, $833.33) = $833.33. + # benefit = max($833.33 - $126.50, 0) = $706.83. + wv_ccap: 706.83 - name: Case 5, non-WV family gets zero benefit. period: 2025-01 @@ -220,7 +217,7 @@ person2: age: 4 is_tax_unit_dependent: true - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 8_000 tax_units: tax_unit: @@ -252,7 +249,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 4 + childcare_attending_days_per_month: 17 pre_subsidy_childcare_expenses: 12_000 tax_units: tax_unit: @@ -269,12 +266,12 @@ wv_ccap_eligible: true # Center Tier I Toddler = $37/day. wv_ccap_daily_rate: [0, 37] - # 4 days/week = 17.33 days/month (in 13-20 monthly-rate range). + # 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.33 = $99.67. - wv_ccap_copay: 99.67 - # benefit = max($740 - $99.67, 0) = $640.33. - wv_ccap: 640.33 + # Copay: 2-person FPL 1.1348 → 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 # Manual §7.2.7.2: rate supplements are paid for actual days only — the monthly # rate does NOT apply to rate supplements. This case is the regression guard. @@ -296,7 +293,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 4 + childcare_attending_days_per_month: 17 pre_subsidy_childcare_expenses: 12_000 tax_units: tax_unit: @@ -313,11 +310,51 @@ wv_ccap_eligible: true # Center Tier I Toddler = $37/day base; special needs supplement = $3/day. wv_ccap_daily_rate: [0, 37] - # 4 days/week = 17.33 days/month (in 13-20 monthly-rate range). + # 17 days/month is in the 13-20 monthly-rate range. # Base reimbursement (monthly rate): $37 × 20 = $740. - # Supplement reimbursement (actual days, Manual §7.2.7.2): $3 × 17.33 = $52. - # Total reimbursement: $740 + $52 = $792 (under pre_subsidy $1_000). - # Copay: same as Case 6 (2-person FPL 1.1348, 17.33 days) = $99.67. - wv_ccap_copay: 99.67 - # benefit = max($792 - $99.67, 0) = $692.33. - wv_ccap: 692.33 + # Supplement reimbursement (actual days, Manual §7.2.7.2): $3 × 17 = $51. + # Total reimbursement: $740 + $51 = $791 (under pre_subsidy $1_000). + # Copay: same as Case 6 (2-person FPL 1.1348, 17 days) = $97.75. + wv_ccap_copay: 97.75 + # benefit = max($791 - $97.75, 0) = $693.25. + wv_ccap: 693.25 + +- name: Case 8, less than thirteen monthly days uses per-day rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 24_000 + weekly_hours_worked: 40 + immigration_status: CITIZEN + person2: + age: 3 + is_tax_unit_dependent: true + immigration_status: CITIZEN + wv_ccap_provider_type: CENTER + wv_ccap_quality_tier: TIER_I + childcare_attending_days_per_month: 9 + pre_subsidy_childcare_expenses: 12_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_pre_subsidy_childcare_expenses: 12_000 + households: + household: + members: [person1, person2] + state_code: WV + output: + wv_ccap_eligible: true + # 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. + 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. + wv_ccap: 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 2bafdbbec86..0192752bd40 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 @@ -15,7 +15,7 @@ employment_income: 6_000 person2: age: 5 - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 tax_units: tax_unit: members: [person1, person2] @@ -40,7 +40,7 @@ employment_income: 18_000 person2: age: 5 - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 tax_units: tax_unit: members: [person1, person2] @@ -54,9 +54,9 @@ output: # Monthly income $1_500; FPL ratio = 1_500 / 1_762.50 = 0.8511. # Appendix A 2-person "90%" row daily fee = $4.25/child. - # 1 eligible child × 5 days/week × 52/12 = 21.67 monthly days. - # copay = $4.25 × 21.67 × 1 = $92.08. - wv_ccap_copay: 92.08 + # 1 eligible child × 22 monthly days. + # copay = $4.25 × 22 × 1 = $93.50. + wv_ccap_copay: 93.5 - name: Case 3, high income 2-person family copay below 7% cap. period: 2025-01 @@ -68,7 +68,7 @@ employment_income: 36_000 person2: age: 5 - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 tax_units: tax_unit: members: [person1, person2] @@ -82,9 +82,9 @@ output: # Monthly income $3_000; FPL ratio = 3_000 / 1_762.50 = 1.7021. # Appendix A 2-person "180%" row daily fee = $8.75/child. - # uncapped copay = $8.75 × 21.67 = $189.58. + # uncapped copay = $8.75 × 22 = $192.50. # 7% cap = $3_000 × 0.07 = $210. Cap does not bind for 2-person, 1-child. - wv_ccap_copay: 189.58 + wv_ccap_copay: 192.5 - name: Case 4, foster family pays zero copay even when fee would otherwise apply. period: 2025-01 @@ -96,7 +96,7 @@ employment_income: 36_000 person2: age: 5 - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 is_in_foster_care: true tax_units: tax_unit: @@ -109,6 +109,92 @@ members: [person1, person2] state_code: WV output: - # Without foster waiver this household would owe $189.58/month (see Case 3); + # Without foster waiver this household would owe $192.50/month (see Case 3); # Manual §6.4.1 / CCDF Plan §3.3.1 waives the family fee. wv_ccap_copay: 0 + +- name: Case 5, family size above eleven uses eleven-person column. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 64_800 + person2: + age: 5 + childcare_attending_days_per_month: 22 + person3: + age: 4 + person4: + age: 4 + person5: + age: 4 + person6: + age: 4 + person7: + age: 4 + person8: + age: 4 + person9: + age: 4 + person10: + age: 4 + person11: + age: 4 + person12: + age: 4 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12] + 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. + # 1 eligible child × 22 monthly days. + # copay = $4.50 × 22 = $99. + wv_ccap_copay: 99 + +- name: Case 6, four children in care are capped at three billed children. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 30_000 + person2: + age: 5 + childcare_attending_days_per_month: 22 + person3: + age: 4 + childcare_attending_days_per_month: 22 + person4: + age: 3 + childcare_attending_days_per_month: 22 + person5: + age: 2 + childcare_attending_days_per_month: 22 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: 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. + # 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 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml index 28be2507245..1cfd4c2e7c2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.yaml @@ -13,7 +13,7 @@ # Age 3 → 36 months → TODDLER. age: 3 is_tax_unit_dependent: true - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I pre_subsidy_childcare_expenses: 8_000 @@ -28,9 +28,9 @@ members: [person1, person2] state_code: WV output: - # Center Tier I Toddler = $37/day; daily_charge = (8_000/12)/21.67 = $30.77. - # daily_benefit = min(37, 30.77) = 30.77. - wv_ccap_daily_benefit: [0, 30.77] + # Center Tier I Toddler = $37/day; daily_charge = (8_000/12)/22 = $30.30. + # daily_benefit = min(37, 30.30) = 30.30. + wv_ccap_daily_benefit: [0, 30.3] - name: Case 2, daily benefit pays full rate when charge exceeds rate. period: 2025-01 @@ -43,7 +43,7 @@ person2: age: 1 is_tax_unit_dependent: true - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_II pre_subsidy_childcare_expenses: 15_000 @@ -58,8 +58,8 @@ members: [person1, person2] state_code: WV output: - # Center Tier II Infant = $42/day; daily_charge = (15_000/12)/21.67 = $57.69. - # daily_benefit = min(42, 57.69) = 42. + # Center Tier II Infant = $42/day; daily_charge = (15_000/12)/22 = $56.82. + # daily_benefit = min(42, 56.82) = 42. wv_ccap_daily_benefit: [0, 42] - name: Case 3, non-traditional hours supplement adds 6 dollars per day. @@ -74,7 +74,7 @@ # Age 3 → 36 months → TODDLER. age: 3 is_tax_unit_dependent: true - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I wv_ccap_non_traditional_hours: true @@ -91,6 +91,6 @@ state_code: WV output: # Center Tier I Toddler = $37/day; non-traditional supplement = $6/day. - # total_rate = 43; daily_charge = (15_000/12)/21.67 = $57.69. - # daily_benefit = min(43, 57.69) = 43. + # total_rate = 43; daily_charge = (15_000/12)/22 = $56.82. + # daily_benefit = min(43, 56.82) = 43. wv_ccap_daily_benefit: [0, 43] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml index 32bf12ae248..8d77a426fb5 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/ccap/wv_child_care_subsidies.yaml @@ -13,7 +13,7 @@ immigration_status: CITIZEN wv_ccap_provider_type: CENTER wv_ccap_quality_tier: TIER_I - childcare_days_per_week: 5 + childcare_attending_days_per_month: 22 pre_subsidy_childcare_expenses: 8_000 tax_units: tax_unit: @@ -27,5 +27,5 @@ members: [person1, person2] state_code: WV output: - # Matches integration.yaml Case 1: wv_ccap monthly = $542.08 → annual = ~$6_505. - wv_child_care_subsidies: 6_505 + # Matches integration.yaml Case 1: wv_ccap monthly = $540.17 → annual = ~$6_482. + wv_child_care_subsidies: 6_482 diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py index 5765f723b05..63378491454 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/eligibility/wv_ccap_activity_eligible.py @@ -7,7 +7,7 @@ class wv_ccap_activity_eligible(Variable): label = "Eligible for West Virginia CCAP based on activity requirements" definition_period = MONTH defined_for = StateCode.WV - reference = "https://bfa.wv.gov/media/6766/download?inline#page=32" + reference = "https://bfa.wv.gov/media/6766/download?inline#page=33" def formula(spm_unit, period, parameters): # NOTE: we use is_full_time_student as a proxy for Manual §3.6.3, which diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py index 9e8d09b7a85..263aee8b0df 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap.py @@ -27,16 +27,12 @@ def formula(spm_unit, period, parameters): # not modeled. p = parameters(period).gov.states.wv.dhhr.ccap person = spm_unit.members - weekly_care_days = person("childcare_days_per_week", period.this_year) - monthly_care_days = weekly_care_days * (WEEKS_IN_YEAR / MONTHS_IN_YEAR) + monthly_care_days = person( + "childcare_attending_days_per_month", period.this_year + ) in_monthly_range = (monthly_care_days >= p.billing.monthly_rate_min_days) & ( monthly_care_days <= p.billing.monthly_rate_max_days ) - base_billed_days = where( - in_monthly_range, - p.billing.monthly_rate_max_days, - monthly_care_days, - ) daily_rate = person("wv_ccap_daily_rate", period) has_developmental_delay = person("has_developmental_delay", period.this_year) special_needs_supplement = where( @@ -46,9 +42,14 @@ def formula(spm_unit, period, parameters): non_trad_supplement = where(non_trad, p.supplements.non_traditional_hours, 0) daily_supplement = special_needs_supplement + non_trad_supplement pre_subsidy_per_child = person("pre_subsidy_childcare_expenses", period) + monthly_rate_maximum = ( + daily_rate * p.billing.monthly_rate_max_days + + daily_supplement * monthly_care_days + ) + per_day_maximum = person("wv_ccap_daily_benefit", period) * monthly_care_days per_child_reimbursement = min_( - daily_rate * base_billed_days + daily_supplement * monthly_care_days, pre_subsidy_per_child, + where(in_monthly_range, monthly_rate_maximum, per_day_maximum), ) total_reimbursement = spm_unit.sum(per_child_reimbursement) copay = spm_unit("wv_ccap_copay", period) 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 e41d36ee12e..5899b1d011b 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 @@ -11,7 +11,7 @@ class wv_ccap_copay(Variable): reference = ( "https://bfa.wv.gov/media/6826/download?inline#page=1", "https://bfa.wv.gov/media/6766/download?inline#page=65", - "https://bfa.wv.gov/media/39915/download?inline#page=42", + "https://bfa.wv.gov/media/39915/download?inline#page=39", ) def formula(spm_unit, period, parameters): @@ -55,12 +55,12 @@ def formula(spm_unit, period, parameters): ) person = spm_unit.members is_eligible_child = person("wv_ccap_eligible_child", period) - weekly_days = person("childcare_days_per_week", period.this_year) - in_care = is_eligible_child & (weekly_days > 0) - num_in_care = spm_unit.sum(in_care) - total_monthly_days = ( - spm_unit.sum(weekly_days * in_care) * WEEKS_IN_YEAR / MONTHS_IN_YEAR + monthly_care_days = person( + "childcare_attending_days_per_month", period.this_year ) + in_care = is_eligible_child & (monthly_care_days > 0) + num_in_care = spm_unit.sum(in_care) + total_monthly_days = spm_unit.sum(monthly_care_days * in_care) # Per Manual §6.4.3.4: fee waived for any child beyond the three # youngest. We don't track child ordering, so apply the cap as a # uniform 3/N scaling across all eligible children in care. diff --git a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py index 140e8c3487f..26130fbaa51 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/ccap/wv_ccap_daily_benefit.py @@ -21,13 +21,13 @@ def formula(person, period, parameters): non_trad_supplement = where(non_trad, p.supplements.non_traditional_hours, 0) total_rate = daily_rate + special_needs_supplement + non_trad_supplement pre_subsidy = person("pre_subsidy_childcare_expenses", period) - daily_days = person("childcare_days_per_week", period.this_year) * ( - WEEKS_IN_YEAR / MONTHS_IN_YEAR + monthly_care_days = person( + "childcare_attending_days_per_month", period.this_year ) - mask = daily_days > 0 + mask = monthly_care_days > 0 daily_charge = np.divide( pre_subsidy, - daily_days, + monthly_care_days, out=np.zeros_like(pre_subsidy, dtype=float), where=mask, )