diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..a8be794573c 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Rhode Island LIHEAP eligibility determination diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/deliverable/amount.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/deliverable/amount.yaml new file mode 100644 index 00000000000..c785bc6f343 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/deliverable/amount.yaml @@ -0,0 +1,35 @@ +description: Rhode Island provides this amount as the heating assistance benefit for deliverable fuels under the Low Income Home Energy Assistance Program. + +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: year + label: Rhode Island LIHEAP deliverable fuel benefit + reference: + - title: Rhode Island LIHEAP FFY 2026 Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 + +brackets: + - threshold: + 2025-10-01: 0 + amount: + 2025-10-01: 861 + - threshold: + 2025-10-01: 0.76 + amount: + 2025-10-01: 805 + - threshold: + 2025-10-01: 1.01 + amount: + 2025-10-01: 752 + - threshold: + 2025-10-01: 1.26 + amount: + 2025-10-01: 704 + - threshold: + 2025-10-01: 1.51 + amount: + 2025-10-01: 657 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/electric/amount.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/electric/amount.yaml new file mode 100644 index 00000000000..03fa3f3a28c --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/electric/amount.yaml @@ -0,0 +1,35 @@ +description: Rhode Island provides this amount as the heating assistance benefit for electric heat under the Low Income Home Energy Assistance Program. + +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: year + label: Rhode Island LIHEAP electric heat benefit + reference: + - title: Rhode Island LIHEAP FFY 2026 Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 + +brackets: + - threshold: + 2025-10-01: 0 + amount: + 2025-10-01: 393 + - threshold: + 2025-10-01: 0.76 + amount: + 2025-10-01: 357 + - threshold: + 2025-10-01: 1.01 + amount: + 2025-10-01: 324 + - threshold: + 2025-10-01: 1.26 + amount: + 2025-10-01: 295 + - threshold: + 2025-10-01: 1.51 + amount: + 2025-10-01: 268 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/heat_in_rent/direct_pay.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/heat_in_rent/direct_pay.yaml new file mode 100644 index 00000000000..2c28b157ae3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/heat_in_rent/direct_pay.yaml @@ -0,0 +1,13 @@ +description: Rhode Island provides this amount as a direct payment to households with heat included in rent under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 400 + +metadata: + unit: currency-USD + period: year + label: Rhode Island LIHEAP heat in rent direct payment + reference: + - title: Rhode Island LIHEAP FFY 2026 Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/heat_in_rent/secondary_electric.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/heat_in_rent/secondary_electric.yaml new file mode 100644 index 00000000000..01776957060 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/heat_in_rent/secondary_electric.yaml @@ -0,0 +1,13 @@ +description: Rhode Island provides this amount for secondary electric costs to households with heat included in rent under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 80 + +metadata: + unit: currency-USD + period: year + label: Rhode Island LIHEAP heat in rent secondary electric benefit + reference: + - title: Rhode Island LIHEAP FFY 2026 Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/natural_gas/amount.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/natural_gas/amount.yaml new file mode 100644 index 00000000000..8fa2bb3167c --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/natural_gas/amount.yaml @@ -0,0 +1,35 @@ +description: Rhode Island provides this amount as the heating assistance benefit for natural gas under the Low Income Home Energy Assistance Program. + +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: year + label: Rhode Island LIHEAP natural gas benefit + reference: + - title: Rhode Island LIHEAP FFY 2026 Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 + +brackets: + - threshold: + 2025-10-01: 0 + amount: + 2025-10-01: 232 + - threshold: + 2025-10-01: 0.76 + amount: + 2025-10-01: 211 + - threshold: + 2025-10-01: 1.01 + amount: + 2025-10-01: 192 + - threshold: + 2025-10-01: 1.26 + amount: + 2025-10-01: 175 + - threshold: + 2025-10-01: 1.51 + amount: + 2025-10-01: 159 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/subsidized_housing/secondary_electric.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/subsidized_housing/secondary_electric.yaml new file mode 100644 index 00000000000..008e3e928a8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/benefit/subsidized_housing/secondary_electric.yaml @@ -0,0 +1,13 @@ +description: Rhode Island provides this amount for secondary electric costs to subsidized housing residents under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 50 + +metadata: + unit: currency-USD + period: year + label: Rhode Island LIHEAP subsidized housing secondary electric benefit + reference: + - title: Rhode Island LIHEAP FFY 2026 Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/crisis/maximum.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/crisis/maximum.yaml new file mode 100644 index 00000000000..b551f9e391c --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/crisis/maximum.yaml @@ -0,0 +1,13 @@ +description: This amount limits the maximum crisis assistance under the Rhode Island Low Income Home Energy Assistance Program. +values: + 2024-10-01: 1_500 + +metadata: + unit: currency-USD + period: year + label: Rhode Island LIHEAP maximum crisis assistance + reference: + - title: RI DHS FFY 2025 Low Income Home Energy Assistance Program + href: https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-1 + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/heating/maximum.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/heating/maximum.yaml new file mode 100644 index 00000000000..f2994bd7944 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/heating/maximum.yaml @@ -0,0 +1,14 @@ +description: Rhode Island limits the maximum heating assistance benefit to this amount under the Low Income Home Energy Assistance Program. +values: + 2024-10-01: 1_285 + 2025-10-01: 861 + +metadata: + unit: currency-USD + period: year + label: Rhode Island LIHEAP maximum heating benefit + reference: + - title: Rhode Island LIHEAP FFY 2026 Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/heating/minimum.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/heating/minimum.yaml new file mode 100644 index 00000000000..bae497ca019 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/heating/minimum.yaml @@ -0,0 +1,14 @@ +description: Rhode Island provides this amount as the minimum heating assistance benefit under the Low Income Home Energy Assistance Program. +values: + 2024-10-01: 75 + 2025-10-01: 50 + +metadata: + unit: currency-USD + period: year + label: Rhode Island LIHEAP minimum heating benefit + reference: + - title: Rhode Island LIHEAP FFY 2026 Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/priority/elderly_age.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/priority/elderly_age.yaml new file mode 100644 index 00000000000..a053d2d8647 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/priority/elderly_age.yaml @@ -0,0 +1,13 @@ +description: This age sets the elderly threshold for priority household status under the Rhode Island Low Income Home Energy Assistance Program. +values: + 2024-10-01: 60 + +metadata: + unit: year + period: year + label: Rhode Island LIHEAP elderly priority age threshold + reference: + - title: RI DHS FFY 2026 State Plan Summary + href: https://dhs.ri.gov/media/9371/download?language=en + - title: 42 U.S.C. Section 8624(b)(5) - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/priority/young_child_age.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/priority/young_child_age.yaml new file mode 100644 index 00000000000..d1d29ff999a --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/priority/young_child_age.yaml @@ -0,0 +1,13 @@ +description: This age sets the young child threshold for priority household status under the Rhode Island Low Income Home Energy Assistance Program. +values: + 2024-10-01: 6 + +metadata: + unit: year + period: year + label: Rhode Island LIHEAP young child priority age threshold + reference: + - title: RI DHS FFY 2026 State Plan Summary + href: https://dhs.ri.gov/media/9371/download?language=en + - title: 42 U.S.C. Section 8624(b)(5) - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/parameters/gov/states/ri/dhs/liheap/snap_nominal_payment.yaml b/policyengine_us/parameters/gov/states/ri/dhs/liheap/snap_nominal_payment.yaml new file mode 100644 index 00000000000..44487de7631 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ri/dhs/liheap/snap_nominal_payment.yaml @@ -0,0 +1,13 @@ +description: This amount provides the nominal payment for Supplemental Nutrition Assistance Program households under the Rhode Island Low Income Home Energy Assistance Program. +values: + 2024-10-01: 20.01 + +metadata: + unit: currency-USD + period: year + label: Rhode Island LIHEAP SNAP nominal payment + reference: + - title: RI DHS FFY 2026 State Plan Summary + href: https://dhs.ri.gov/media/9371/download?language=en + - title: 42 U.S.C. Section 8624 - Applications and requirements + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/edge_cases.yaml new file mode 100644 index 00000000000..7f8ddc3dc19 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/edge_cases.yaml @@ -0,0 +1,933 @@ +# Edge case tests for Rhode Island LIHEAP +# Tests boundary conditions, extreme values, and corner cases +# Generated to prevent "what about X?" review comments +# +# Income eligibility: Gross income <= 60% of State Median Income (SMI) +# SMI calculation uses HHS parameters based on state and household size +# +# Priority thresholds: +# - Elderly: age >= 60 +# - Young child: age < 6 +# - Disabled: is_disabled = true + +# ============================================================================= +# INCOME ELIGIBILITY EDGE CASES +# ============================================================================= + +# --- Zero Income Test --- + +- name: Edge 1, zero income single person household. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 25 + employment_income: 0 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Zero income always below any threshold + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +- name: Edge 2, zero income household with multiple members. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + person2: + age: 28 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: RI + output: + # Zero income always below any threshold + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +# --- Clearly Over/Under Income Limits --- + +- name: Edge 3, income clearly below 1-person limit. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 35 + employment_income: 35_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # $35,000 is well below any reasonable 1-person 60% SMI limit + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +- name: Edge 4, income clearly above 1-person limit. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 35 + employment_income: 50_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # $50,000 is above any reasonable 1-person 60% SMI limit + ri_liheap_income_eligible: false + ri_liheap_priority_household: false + ri_liheap_eligible: false + +# --- Large Household Size Test --- + +- name: Edge 5, 8-person household income well below limit. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 45 + employment_income: 80_000 + person2: + age: 43 + person3: + age: 18 + person4: + age: 16 + person5: + age: 14 + person6: + age: 12 + person7: + age: 10 + person8: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: RI + output: + # 8-person household has high 60% SMI limit + # $80,000 should be below the limit + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +- name: Edge 6, 8-person household income well above limit. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 45 + employment_income: 150_000 + person2: + age: 43 + person3: + age: 18 + person4: + age: 16 + person5: + age: 14 + person6: + age: 12 + person7: + age: 10 + person8: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: RI + output: + # $150,000 is above any reasonable 8-person 60% SMI limit + ri_liheap_income_eligible: false + ri_liheap_priority_household: false + ri_liheap_eligible: false + +- name: Edge 7, 10-person household very large family. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 50 + employment_income: 90_000 + person2: + age: 48 + person3: + age: 22 + person4: + age: 20 + person5: + age: 18 + person6: + age: 16 + person7: + age: 14 + person8: + age: 12 + person9: + age: 10 + person10: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + state_code: RI + output: + # Tests very large household size adjustment formula + # 10-person adjustment: 0.52 + 0.16*5 + 0.03*4 = 1.44 + # Large household should have high income limit + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +# ============================================================================= +# PRIORITY HOUSEHOLD EDGE CASES - AGE BOUNDARIES +# ============================================================================= + +# --- Elderly Age Boundary (60) --- + +- name: Edge 8, person exactly age 60 at elderly threshold. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 60 + employment_income: 30_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Age 60 >= 60 = elderly, priority household + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 9, person age 59 just below elderly threshold. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 59 + employment_income: 30_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Age 59 < 60 = not elderly + # Not disabled, no young children = NOT priority + ri_liheap_priority_household: false + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 10, person age 61 just above elderly threshold. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 61 + employment_income: 30_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Age 61 >= 60 = elderly, priority household + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +# --- Young Child Age Boundary (under 6) --- + +- name: Edge 11, child exactly age 6 at young child threshold. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income: 35_000 + person2: + age: 6 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Child age 6 is NOT under 6 + # No elderly, not disabled = NOT priority + ri_liheap_priority_household: false + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 12, child age 5 just under young child threshold. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income: 35_000 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Child age 5 < 6 = young child, priority household + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 13, child age 7 above young child threshold. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 35 + employment_income: 35_000 + person2: + age: 7 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Child age 7 is NOT under 6 + # No elderly, not disabled = NOT priority + ri_liheap_priority_household: false + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 14, infant age 0 should be priority. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 25 + employment_income: 30_000 + person2: + age: 0 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Infant age 0 < 6 = young child = priority household + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 15, toddler age 1 should be priority. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 28 + employment_income: 30_000 + person2: + age: 1 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Toddler age 1 < 6 = young child = priority household + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +# ============================================================================= +# PRIORITY HOUSEHOLD EDGE CASES - DISABILITY +# ============================================================================= + +- name: Edge 16, person with is_disabled equals true. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 40 + is_disabled: true + employment_income: 25_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Disabled member = priority household + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 17, disabled child in household. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 35 + employment_income: 40_000 + person2: + age: 33 + person3: + age: 12 + is_disabled: true + person4: + age: 10 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # Child with disability = priority household + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 18, person NOT disabled explicit false. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 45 + is_disabled: false + employment_income: 30_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Not disabled, not elderly, no young children = NOT priority + ri_liheap_priority_household: false + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +# ============================================================================= +# PRIORITY HOUSEHOLD EDGE CASES - MULTIPLE FACTORS +# ============================================================================= + +- name: Edge 19, multiple priority factors elderly plus young child. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 68 + social_security: 20_000 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Elderly (68) AND young child (3) = priority household (multiple factors) + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 20, multiple priority factors elderly plus disabled. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 72 + is_disabled: true + social_security: 22_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Elderly (72) AND disabled = priority household (multiple factors) + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 21, multiple priority factors disabled plus young child. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 35 + is_disabled: true + ssi: 10_000 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Disabled AND young child (4) = priority household (multiple factors) + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +- name: Edge 22, all three priority factors elderly disabled with young child. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 70 + is_disabled: true + social_security: 18_000 + person2: + age: 35 + employment_income: 20_000 + person3: + age: 2 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: RI + output: + # Elderly (70), disabled, AND young child (2) = priority (all three factors) + ri_liheap_priority_household: true + ri_liheap_income_eligible: true + ri_liheap_eligible: true + +# ============================================================================= +# OVERALL ELIGIBILITY EDGE CASES +# ============================================================================= + +- name: Edge 23, income eligible but NOT priority plain eligible household. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 40 + employment_income: 35_000 + person2: + age: 38 + person3: + age: 15 + person4: + age: 12 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # Income eligible + # Ages 40, 38, 15, 12 - no elderly (under 60), no disabled, no young children (under 6) + # Eligible but NOT priority + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +- name: Edge 24, income ineligible regardless of priority factors. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 65 + employment_income: 70_000 + person2: + age: 2 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Elderly (65) AND young child (2) = would be priority + # BUT income $70,000 is above 2-person 60% SMI limit = income INELIGIBLE + # Priority factors don't override income requirement + ri_liheap_income_eligible: false + ri_liheap_priority_household: true + ri_liheap_eligible: false + +- name: Edge 25, high income with all priority factors still ineligible. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 70 + is_disabled: true + employment_income: 100_000 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Has ALL priority factors: elderly (70), disabled, young child (3) + # But income $100,000 far exceeds 2-person 60% SMI limit + # Income eligibility is strict requirement + ri_liheap_income_eligible: false + ri_liheap_priority_household: true + ri_liheap_eligible: false + +# ============================================================================= +# STATE RESIDENCY EDGE CASES +# ============================================================================= + +- name: Edge 26, non-RI resident ineligible regardless of income. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 35 + employment_income: 20_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MA + output: + # Massachusetts resident, NOT Rhode Island + # Would be income eligible in RI, but not RI resident + # ri_liheap_income_eligible has defined_for = StateCode.RI + ri_liheap_income_eligible: false + ri_liheap_priority_household: false + ri_liheap_eligible: false + +- name: Edge 27, non-RI resident with priority factors still ineligible. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 70 + is_disabled: true + social_security: 15_000 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CT + output: + # Connecticut resident, NOT Rhode Island + # Has elderly (70), disabled, and young child (3) = would be priority + # Income would be eligible + # But state residency requirement not met + ri_liheap_income_eligible: false + ri_liheap_priority_household: false + ri_liheap_eligible: false + +- name: Edge 28, neighboring state NY resident ineligible. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 65 + social_security: 20_000 + person2: + age: 63 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NY + output: + # New York resident - different state + # Would be elderly priority and income eligible in RI + # Not eligible for RI LIHEAP + ri_liheap_income_eligible: false + ri_liheap_priority_household: false + ri_liheap_eligible: false + +# ============================================================================= +# HOUSEHOLD COMPOSITION EDGE CASES +# ============================================================================= + +- name: Edge 29, single person household minimum size. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income: 25_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Minimum household size of 1 + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +- name: Edge 30, household with no one meeting any priority criteria. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 45 + employment_income: 40_000 + person2: + age: 43 + person3: + age: 17 + person4: + age: 15 + person5: + age: 12 + person6: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: RI + output: + # 6-person household + # Ages: 45, 43, 17, 15, 12, 8 - no one is 60+ (elderly) + # Youngest is 8, not under 6 (young child) + # No one disabled + # Income eligible but NOT priority + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +# ============================================================================= +# INCOME SOURCE EDGE CASES +# ============================================================================= + +- name: Edge 31, mixed income sources within limit. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 65 + social_security: 15_000 + employment_income: 10_000 + person2: + age: 63 + social_security: 10_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Income: $15,000 + $10,000 + $10,000 = $35,000 + # Should be below 2-person 60% SMI limit + # Age 65 = elderly = priority + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true + +- name: Edge 32, self-employment income only. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 40 + self_employment_income: 30_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Self-employment income counts toward gross income + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +- name: Edge 33, SSI income only disabled person. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 50 + is_disabled: true + ssi: 10_092 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # SSI income counts toward gross income + # $10,092 well below any 1-person 60% SMI limit + # Disabled = priority household + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true + +- name: Edge 34, social security disability income. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 55 + is_disabled: true + social_security_disability: 24_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # SSDI income counts toward gross income + # Disabled = priority household + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true + +- name: Edge 35, multiple income sources elderly couple. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 68 + social_security: 20_000 + employment_income: 5_000 + person2: + age: 66 + social_security: 15_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Total income: $20,000 + $5,000 + $15,000 = $40,000 + # Elderly (68 and 66) = priority + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/integration.yaml new file mode 100644 index 00000000000..e6ffda36176 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/integration.yaml @@ -0,0 +1,387 @@ +# Integration tests for Rhode Island LIHEAP (Low Income Home Energy Assistance Program) +# Full pipeline testing with realistic family scenarios +# +# Program Overview: +# - Administered by: Rhode Island Department of Human Services (DHS) +# - Income limit: 60% of State Median Income (SMI) +# - No categorical eligibility (SNAP/SSI/TANF do not auto-qualify) +# - Priority given to households with elderly (60+), disabled, or young children (under 6) +# +# Sources: +# - https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program +# - 42 U.S.C. Section 8624 +# - 45 CFR 96.85 +# +# FFY 2026 60% SMI limits by household size: +# 1-person: $42,252 | 2-person: $55,252 | 3-person: $68,253 +# 4-person: $81,254 | 5-person: $94,254 | 6-person: $107,255 + +- name: Scenario 1, single elderly person on Social Security, priority household. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 72 + social_security: 24_000 + spm_units: + spm_unit: + members: [person1] + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Income: $24,000 (Social Security) + # 60% SMI for 1-person: $42,252 + # $24,000 < $42,252 = income eligible + # Age 72 = elderly = priority household + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true + +- name: Scenario 2, single working adult, income just below 60% SMI. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 35 + employment_income: 42_000 + spm_units: + spm_unit: + members: [person1] + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Income: $42,000 + # 60% SMI for 1-person: $42,252 + # $42,000 < $42,252 = income eligible (just below threshold) + # Age 35 = not elderly, not disabled, no young children = not priority + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +- name: Scenario 3, high income single person, ineligible. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 40 + employment_income: 55_000 + spm_units: + spm_unit: + members: [person1] + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Income: $55,000 + # 60% SMI for 1-person: $42,252 + # $55,000 > $42,252 = income ineligible + ri_liheap_income_eligible: false + ri_liheap_priority_household: false + ri_liheap_eligible: false + +- name: Scenario 4, family with young child, priority household. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 28 + employment_income: 35_000 + person2: + age: 26 + employment_income: 15_000 + person3: + age: 4 + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: RI + output: + # Income: $35,000 + $15,000 = $50,000 + # 60% SMI for 3-person: $68,253 + # $50,000 < $68,253 = income eligible + # Child age 4 (under 6) = young child = priority household + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true + +- name: Scenario 5, disabled adult with child, priority household. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 45 + is_disabled: true + ssi: 10_092 + social_security_disability: 18_000 + person2: + age: 12 + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Income: $10,092 (SSI) + $18,000 (SSDI) = $28,092 + # 60% SMI for 2-person: $55,252 + # $28,092 < $55,252 = income eligible + # Disabled member = priority household + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true + +- name: Scenario 6, large family of 5, income eligible. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 40 + employment_income: 55_000 + person2: + age: 38 + employment_income: 25_000 + person3: + age: 16 + person4: + age: 13 + person5: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: RI + output: + # Income: $55,000 + $25,000 = $80,000 + # 60% SMI for 5-person: $94,254 + # $80,000 < $94,254 = income eligible + # No elderly (ages 40, 38), not disabled, no children under 6 = not priority + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +- name: Scenario 7, 4-person household exceeding 60% SMI, ineligible. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 45 + employment_income: 55_000 + person2: + age: 43 + employment_income: 35_000 + person3: + age: 15 + person4: + age: 12 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # Income: $55,000 + $35,000 = $90,000 + # 60% SMI for 4-person: $81,254 + # $90,000 > $81,254 = income ineligible + ri_liheap_income_eligible: false + ri_liheap_priority_household: false + ri_liheap_eligible: false + +- name: Scenario 8, multigenerational household with elderly grandparent, priority. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 35 + employment_income: 40_000 + person2: + age: 33 + person3: + age: 10 + person4: + age: 7 + person5: + age: 68 + social_security: 20_000 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: RI + output: + # Income: $40,000 + $20,000 = $60,000 + # 60% SMI for 5-person: $94,254 + # $60,000 < $94,254 = income eligible + # Grandparent age 68 = elderly = priority household + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true + +- name: Scenario 9, couple with infant, priority due to young child. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 30 + employment_income: 28_000 + person2: + age: 28 + employment_income: 18_000 + person3: + age: 1 + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: RI + output: + # Income: $28,000 + $18,000 = $46,000 + # 60% SMI for 3-person: $68,253 + # $46,000 < $68,253 = income eligible + # Child age 1 (under 6) = young child = priority household + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true + +- name: Scenario 10, household just at income boundary, 2-person. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 55 + employment_income: 55_000 + person2: + age: 53 + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Income: $55,000 + # 60% SMI for 2-person: $55,252 + # $55,000 < $55,252 = income eligible (just under threshold) + # Ages 55 and 53, not disabled, no children = not priority + ri_liheap_income_eligible: true + ri_liheap_priority_household: false + ri_liheap_eligible: true + +- name: Scenario 11, zero income household with young child. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 22 + person2: + age: 2 + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Income: $0 + # Zero income always below any SMI threshold = income eligible + # Child age 2 (under 6) = young child = priority household + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true + +- name: Scenario 12, household with disabled child, priority. + period: 2025 + absolute_error_margin: 1 + input: + people: + person1: + age: 38 + employment_income: 45_000 + person2: + age: 36 + person3: + age: 14 + is_disabled: true + person4: + age: 10 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # Income: $45,000 + # 60% SMI for 4-person: $81,254 + # $45,000 < $81,254 = income eligible + # Child age 14 is disabled = priority household + ri_liheap_income_eligible: true + ri_liheap_priority_household: true + ri_liheap_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap.yaml new file mode 100644 index 00000000000..ea9e1da7605 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap.yaml @@ -0,0 +1,415 @@ +# Unit tests for Rhode Island LIHEAP main benefit variable +# Tests the final benefit amount combining eligibility and heating benefit calculation +# +# The ri_liheap variable: +# - Returns heating_benefit if eligible +# - Returns $0 if not eligible +# +# Program overview: +# - Income eligibility: <= 60% State Median Income (SMI) +# - Benefit varies by heating type and FPG ratio bracket +# +# FFY 2026 Benefit Matrix (effective 2025-10-01): +# | FPG Range | Deliverable | Natural Gas | Electric | +# |-----------|-------------|-------------|----------| +# | 0-75% | $861 | $232 | $393 | +# | 76-100% | $805 | $211 | $357 | +# | 101-125% | $752 | $192 | $324 | +# | 126-150% | $704 | $175 | $295 | +# | 151%+ | $657 | $159 | $268 | +# +# Heat in Rent: $400 direct pay + $80 secondary electric (or $50 if subsidized) +# +# 2026 FPG values (CONTIGUOUS_US): +# - 1-person: $15,960 +# - 2-person: $21,640 +# - 3-person: $27,320 +# - 4-person: $33,000 +# - Additional person: $5,680 +# +# Source: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + +# ============================================================================= +# ELIGIBLE HOUSEHOLD BENEFIT TESTS +# ============================================================================= + +- name: Case 1, eligible single person deliverable fuel low income. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + # Income at ~63% FPG ($15,960 * 0.63 = $10,055) + employment_income: 10_055 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # Income $10,055 < 60% SMI for 1-person = eligible + # FPG ratio ~63%, Bracket 0-75%: Deliverable = $861 + ri_liheap_eligible: true + ri_liheap: 861 + +- name: Case 2, eligible single person natural gas moderate income. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # Income at ~133% FPG ($15,960 * 1.33 = $21,227) + employment_income: 21_227 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # Income $21,227 < 60% SMI for 1-person = eligible + # FPG ratio ~133%, Bracket 126-150%: Natural Gas = $175 + ri_liheap_eligible: true + ri_liheap: 175 + +- name: Case 3, eligible single person electric heat high FPG ratio. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 45 + # Income at ~160% FPG ($15,960 * 1.60 = $25,536) + employment_income: 25_536 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1] + state_code: RI + output: + # Income $25,536 < 60% SMI for 1-person = eligible + # FPG ratio ~160%, Bracket 151%+: Electric = $268 + ri_liheap_eligible: true + ri_liheap: 268 + +- name: Case 4, eligible heat in rent non-subsidized. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + employment_income: 15_000 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: HEAT_IN_RENT + receives_housing_assistance: false + households: + household: + members: [person1] + state_code: RI + output: + # Eligible, heat in rent: $400 + $80 = $480 + ri_liheap_eligible: true + ri_liheap: 480 + +- name: Case 5, eligible heat in rent subsidized housing. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + employment_income: 15_000 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: HEAT_IN_RENT + receives_housing_assistance: true + households: + household: + members: [person1] + state_code: RI + output: + # Eligible, heat in rent subsidized: $400 + $50 = $450 + ri_liheap_eligible: true + ri_liheap: 450 + +# ============================================================================= +# INELIGIBLE HOUSEHOLD TESTS +# ============================================================================= + +- name: Case 6, ineligible income over 60% SMI. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + employment_income: 50_000 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # Income $50,000 > 60% SMI for 1-person = ineligible + ri_liheap_eligible: false + ri_liheap: 0 + +- name: Case 7, ineligible non-RI resident. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + employment_income: 15_000 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: MA + output: + # Not RI resident = ineligible for RI LIHEAP + ri_liheap_eligible: false + ri_liheap: 0 + +# ============================================================================= +# FAMILY HOUSEHOLD TESTS +# ============================================================================= + +- name: Case 8, 4-person family low income deliverable fuel. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # 4-person FPG = $33,000, targeting 80% FPG = $26,400 + employment_income: 26_400 + person2: + age: 33 + person3: + age: 10 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # 4-person family, income $26,400 < 60% SMI = eligible + # FPG ratio = $26,400 / $33,000 = 80%, Bracket 76-100%: Deliverable = $805 + ri_liheap_eligible: true + ri_liheap: 805 + +- name: Case 9, 3-person family moderate income natural gas. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + # 3-person FPG = $27,320, targeting 160% FPG = $43,712 + employment_income: 43_712 + person2: + age: 38 + person3: + age: 12 + spm_units: + spm_unit: + members: [person1, person2, person3] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1, person2, person3] + state_code: RI + output: + # 3-person family, income $43,712 < 60% SMI = eligible + # FPG ratio = $43,712 / $27,320 = 160%, Bracket 151%+: Natural Gas = $159 + ri_liheap_eligible: true + ri_liheap: 159 + +- name: Case 10, 2-person elderly household electric heat. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 70 + # 2-person FPG = $21,640, targeting 130% FPG = $28,132 + # Using employment_income since irs_gross_income only counts taxable income + employment_income: 15_000 + person2: + age: 68 + employment_income: 13_132 + spm_units: + spm_unit: + members: [person1, person2] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1, person2] + state_code: RI + output: + # 2-person elderly, income $28,132 < 60% SMI = eligible + # FPG ratio = $28,132 / $21,640 = 130%, Bracket 126-150%: Electric = $295 + ri_liheap_eligible: true + ri_liheap: 295 + +# ============================================================================= +# PRIORITY HOUSEHOLD TESTS (eligible with priority status) +# ============================================================================= + +- name: Case 11, elderly priority household. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 65 + # Income at ~133% FPG ($15,960 * 1.33 = $21,227) + # Using employment_income since irs_gross_income only counts taxable income + employment_income: 21_227 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # Elderly (65+) = priority household, income eligible + # FPG ratio ~133%, Bracket 126-150%: Deliverable = $704 + ri_liheap_priority_household: true + ri_liheap_eligible: true + ri_liheap: 704 + +- name: Case 12, disabled priority household. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 45 + is_disabled: true + # Using employment_income since SSI is not counted in irs_gross_income + employment_income: 10_000 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # Disabled = priority household, income eligible + # FPG ratio = $10,000 / $15,960 = 62.7%, Bracket 0-75%: Natural Gas = $232 + ri_liheap_priority_household: true + ri_liheap_eligible: true + ri_liheap: 232 + +- name: Case 13, young child priority household. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + # 2-person FPG = $21,640, targeting 105% FPG = $22,722 + employment_income: 22_722 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1, person2] + state_code: RI + output: + # Child under 6 = priority household, income eligible + # FPG ratio = $22,722 / $21,640 = 105%, Bracket 101-125%: Electric = $324 + ri_liheap_priority_household: true + ri_liheap_eligible: true + ri_liheap: 324 + +# ============================================================================= +# ZERO INCOME TESTS +# ============================================================================= + +- name: Case 14, zero income household eligible. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 25 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1, person2] + state_code: RI + output: + # Zero income = FPG ratio 0%, always eligible + # Bracket 0-75%: Deliverable = $861 + ri_liheap_priority_household: true + ri_liheap_eligible: true + ri_liheap: 861 + +# ============================================================================= +# DEFAULT HEATING TYPE TEST +# ============================================================================= + +- name: Case 15, default heating type natural gas. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + # Income at ~94% FPG ($15,960 * 0.94 = $15,002) + employment_income: 15_002 + spm_units: + spm_unit: + members: [person1] + # No heating type specified - should default to NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # Default heating type is NATURAL_GAS per variable definition + # FPG ratio ~94%, Bracket 76-100%: Natural Gas = $211 + ri_liheap_eligible: true + ri_liheap: 211 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_eligible.yaml new file mode 100644 index 00000000000..992fc53f253 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_eligible.yaml @@ -0,0 +1,138 @@ +# Unit tests for Rhode Island LIHEAP overall eligibility +# Eligibility requires: +# 1. Rhode Island residency (state_code = RI) +# 2. Income <= 60% of State Median Income +# Source: https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program +# +# Note: Rhode Island does NOT use categorical eligibility - all households +# must meet the 60% SMI income test regardless of SNAP/SSI/TANF participation. +# +# FFY 2025 60% SMI limits by household size (used for period 2025): +# 1-person: $39,102 +# 2-person: $51,134 +# 4-person: $75,197 + +- name: Case 1, RI resident, income eligible, single person. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 30_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # RI resident, income $30,000 < 60% SMI $39,102 + ri_liheap_eligible: true + +- name: Case 2, RI resident, income ineligible. + period: 2025 + input: + people: + person1: + age: 40 + employment_income: 50_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # RI resident, but income $50,000 > 60% SMI $39,102 + ri_liheap_eligible: false + +- name: Case 3, non-RI resident, income would be eligible. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 20_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MA + output: + # Not RI resident - not eligible for RI LIHEAP + ri_liheap_eligible: false + +- name: Case 4, 4-person household, income eligible. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 50_000 + person2: + age: 33 + employment_income: 15_000 + person3: + age: 10 + person4: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # 60% SMI for 4-person: $75,197 + # $65,000 < $75,197 = eligible + ri_liheap_eligible: true + +- name: Case 5, 4-person household, income ineligible. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 50_000 + person2: + age: 33 + employment_income: 30_000 + person3: + age: 10 + person4: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # 60% SMI for 4-person: $75,197 + # $80,000 > $75,197 = ineligible + ri_liheap_eligible: false + +- name: Case 6, zero income household eligible. + period: 2025 + input: + people: + person1: + age: 28 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Zero income always below SMI threshold + ri_liheap_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_fpg_ratio.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_fpg_ratio.yaml new file mode 100644 index 00000000000..10da8604d81 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_fpg_ratio.yaml @@ -0,0 +1,338 @@ +# Unit tests for Rhode Island LIHEAP federal poverty guideline ratio +# Calculates income as a ratio of the federal poverty guideline (FPG) +# +# Formula: ri_liheap_fpg_ratio = irs_gross_income / spm_unit_fpg +# +# The FPG ratio determines which benefit bracket applies: +# - 0-75%: Highest benefit tier +# - 76-100%: Second tier +# - 101-125%: Third tier +# - 126-150%: Fourth tier +# - 151%+: Lowest benefit tier (but still eligible if under 60% SMI) +# +# Note: This uses FPG for benefit calculation, while eligibility uses SMI. +# +# 2026 FPG values (CONTIGUOUS_US): +# - 1-person: $15,960 +# - 2-person: $21,640 +# - 3-person: $27,320 +# - 4-person: $33,000 +# - Additional person: $5,680 +# +# Source: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + +# ============================================================================= +# SINGLE PERSON HOUSEHOLD TESTS +# ============================================================================= + +- name: Case 1, single person zero income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Zero income / any FPG = 0 + ri_liheap_fpg_ratio: 0 + +- name: Case 2, single person income at 50% FPG. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 35 + # 2026 FPG for 1-person = $15,960, 50% = $7,980 + employment_income: 7_980 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $7,980 / $15,960 = 0.50 + ri_liheap_fpg_ratio: 0.50 + +- name: Case 3, single person income at 75% FPG. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 40 + # 2026 FPG for 1-person = $15,960, 75% = $11,970 + employment_income: 11_970 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $11,970 / $15,960 = 0.75 + ri_liheap_fpg_ratio: 0.75 + +- name: Case 4, single person income at 100% FPG. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 45 + # 2026 FPG for 1-person = $15,960 + employment_income: 15_960 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $15,960 / $15,960 = 1.0 + ri_liheap_fpg_ratio: 1.0 + +- name: Case 5, single person income at 125% FPG. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 50 + # 2026 FPG for 1-person = $15,960, 125% = $19,950 + employment_income: 19_950 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $19,950 / $15,960 = 1.25 + ri_liheap_fpg_ratio: 1.25 + +- name: Case 6, single person income at 150% FPG. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 55 + # 2026 FPG for 1-person = $15,960, 150% = $23,940 + employment_income: 23_940 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $23,940 / $15,960 = 1.50 + ri_liheap_fpg_ratio: 1.50 + +- name: Case 7, single person income at 175% FPG. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 60 + # 2026 FPG for 1-person = $15,960, 175% = $27,930 + employment_income: 27_930 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $27,930 / $15,960 = 1.75 + ri_liheap_fpg_ratio: 1.75 + +# ============================================================================= +# MULTI-PERSON HOUSEHOLD TESTS +# ============================================================================= + +- name: Case 8, 2-person household at 100% FPG. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 40 + # 2026 FPG for 2-person = $21,640 + employment_income: 21_640 + person2: + age: 38 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # FPG ratio = $21,640 / $21,640 = 1.0 + ri_liheap_fpg_ratio: 1.0 + +- name: Case 9, 4-person household at 50% FPG. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 35 + # 2026 FPG for 4-person = $33,000, 50% = $16,500 + employment_income: 16_500 + person2: + age: 33 + person3: + age: 10 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # FPG ratio = $16,500 / $33,000 = 0.50 + ri_liheap_fpg_ratio: 0.50 + +- name: Case 10, 4-person household at 130% FPG. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 40 + # 2026 FPG for 4-person = $33,000, 130% = $42,900 + employment_income: 42_900 + person2: + age: 38 + person3: + age: 12 + person4: + age: 10 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # FPG ratio = $42,900 / $33,000 = 1.30 + ri_liheap_fpg_ratio: 1.30 + +# ============================================================================= +# MULTIPLE INCOME SOURCES TESTS +# Note: Using employment_income for these tests since irs_gross_income only +# includes taxable income (SSI is not taxable, social_security is only partially +# taxable as taxable_social_security). +# ============================================================================= + +- name: Case 11, elderly with employment income. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 70 + # Income targeting 120% FPG: $15,960 * 1.20 = $19,152 + employment_income: 19_152 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $19,152 / $15,960 = 1.20 + ri_liheap_fpg_ratio: 1.20 + +- name: Case 12, disabled with employment income. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 45 + is_disabled: true + # Income targeting 66% FPG: $15,960 * 0.66 = $10,534 + employment_income: 10_534 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $10,534 / $15,960 = 0.66 + ri_liheap_fpg_ratio: 0.66 + +- name: Case 13, 2-person household with mixed income. + period: 2026 + absolute_error_margin: 0.05 + input: + people: + person1: + age: 65 + # Using employment income for accurate FPG ratio testing + employment_income: 20_000 + person2: + age: 63 + employment_income: 11_801 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Total income = $20,000 + $11,801 = $31,801 + # 2-person FPG = $21,640 + # FPG ratio = $31,801 / $21,640 = 1.47 + ri_liheap_fpg_ratio: 1.47 + +# ============================================================================= +# NON-RI RESIDENT TEST +# ============================================================================= + +- name: Case 14, non-RI resident returns zero. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 15_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MA + output: + # Not RI resident - defined_for = StateCode.RI returns 0 + ri_liheap_fpg_ratio: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_heating_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_heating_benefit.yaml new file mode 100644 index 00000000000..95bbcb649b0 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_heating_benefit.yaml @@ -0,0 +1,659 @@ +# Unit tests for Rhode Island LIHEAP heating benefit calculation +# Tests benefit amounts based on fuel type and FPG bracket +# +# Benefit amounts vary by: +# 1. Heating type: Deliverable, Natural Gas, Electric, Heat in Rent +# 2. FPG ratio bracket: 0-75%, 76-100%, 101-125%, 126-150%, 151%+ +# +# FFY 2026 Benefit Matrix (effective 2025-10-01): +# | FPG Range | Deliverable | Natural Gas | Electric | +# |-----------|-------------|-------------|----------| +# | 0-75% | $861 | $232 | $393 | +# | 76-100% | $805 | $211 | $357 | +# | 101-125% | $752 | $192 | $324 | +# | 126-150% | $704 | $175 | $295 | +# | 151%+ | $657 | $159 | $268 | +# +# Heat in Rent: +# - Direct Pay: $400 +# - Secondary Electric (non-subsidized): $80 +# - Secondary Electric (subsidized housing): $50 +# +# 2026 FPG values (CONTIGUOUS_US): +# - 1-person: $15,960 +# - 2-person: $21,640 +# - 3-person: $27,320 +# - 4-person: $33,000 +# - Additional person: $5,680 +# +# Source: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + +# ============================================================================= +# DELIVERABLE FUEL TESTS (Oil, Propane, Kerosene, Wood, Coal) +# ============================================================================= + +- name: Case 1, deliverable fuel, FPG ratio 50% bracket 0-75%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + # 2026 FPG for 1-person = $15,960, 50% = $7,980 + employment_income: 7_980 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $7,980 / $15,960 = 0.50 (50%) + # Bracket 0-75%: Deliverable = $861 + ri_liheap_heating_benefit: 861 + +- name: Case 2, deliverable fuel, FPG ratio 90% bracket 76-100%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # 2026 FPG for 1-person = $15,960, 90% = $14,364 + employment_income: 14_364 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $14,364 / $15,960 = 0.90 (90%) + # Bracket 76-100%: Deliverable = $805 + ri_liheap_heating_benefit: 805 + +- name: Case 3, deliverable fuel, FPG ratio 110% bracket 101-125%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 45 + # 2026 FPG for 1-person = $15,960, 110% = $17,556 + employment_income: 17_556 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $17,556 / $15,960 = 1.10 (110%) + # Bracket 101-125%: Deliverable = $752 + ri_liheap_heating_benefit: 752 + +- name: Case 4, deliverable fuel, FPG ratio 140% bracket 126-150%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 50 + # 2026 FPG for 1-person = $15,960, 140% = $22,344 + employment_income: 22_344 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $22,344 / $15,960 = 1.40 (140%) + # Bracket 126-150%: Deliverable = $704 + ri_liheap_heating_benefit: 704 + +- name: Case 5, deliverable fuel, FPG ratio 160% bracket 151%+. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 55 + # 2026 FPG for 1-person = $15,960, 160% = $25,536 + employment_income: 25_536 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $25,536 / $15,960 = 1.60 (160%) + # Bracket 151%+: Deliverable = $657 + ri_liheap_heating_benefit: 657 + +# ============================================================================= +# NATURAL GAS TESTS +# ============================================================================= + +- name: Case 6, natural gas, FPG ratio 50% bracket 0-75%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + # 2026 FPG for 1-person = $15,960, 50% = $7,980 + employment_income: 7_980 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~50%, Bracket 0-75%: Natural Gas = $232 + ri_liheap_heating_benefit: 232 + +- name: Case 7, natural gas, FPG ratio 90% bracket 76-100%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # 2026 FPG for 1-person = $15,960, 90% = $14,364 + employment_income: 14_364 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~90%, Bracket 76-100%: Natural Gas = $211 + ri_liheap_heating_benefit: 211 + +- name: Case 8, natural gas, FPG ratio 110% bracket 101-125%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 45 + # 2026 FPG for 1-person = $15,960, 110% = $17,556 + employment_income: 17_556 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~110%, Bracket 101-125%: Natural Gas = $192 + ri_liheap_heating_benefit: 192 + +- name: Case 9, natural gas, FPG ratio 140% bracket 126-150%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 50 + # 2026 FPG for 1-person = $15,960, 140% = $22,344 + employment_income: 22_344 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~140%, Bracket 126-150%: Natural Gas = $175 + ri_liheap_heating_benefit: 175 + +- name: Case 10, natural gas, FPG ratio 160% bracket 151%+. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 55 + # 2026 FPG for 1-person = $15,960, 160% = $25,536 + employment_income: 25_536 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~160%, Bracket 151%+: Natural Gas = $159 + ri_liheap_heating_benefit: 159 + +# ============================================================================= +# ELECTRIC HEAT TESTS +# ============================================================================= + +- name: Case 11, electric heat, FPG ratio 50% bracket 0-75%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + # 2026 FPG for 1-person = $15,960, 50% = $7,980 + employment_income: 7_980 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~50%, Bracket 0-75%: Electric = $393 + ri_liheap_heating_benefit: 393 + +- name: Case 12, electric heat, FPG ratio 90% bracket 76-100%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # 2026 FPG for 1-person = $15,960, 90% = $14,364 + employment_income: 14_364 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~90%, Bracket 76-100%: Electric = $357 + ri_liheap_heating_benefit: 357 + +- name: Case 13, electric heat, FPG ratio 110% bracket 101-125%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 45 + # 2026 FPG for 1-person = $15,960, 110% = $17,556 + employment_income: 17_556 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~110%, Bracket 101-125%: Electric = $324 + ri_liheap_heating_benefit: 324 + +- name: Case 14, electric heat, FPG ratio 140% bracket 126-150%. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 50 + # 2026 FPG for 1-person = $15,960, 140% = $22,344 + employment_income: 22_344 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~140%, Bracket 126-150%: Electric = $295 + ri_liheap_heating_benefit: 295 + +- name: Case 15, electric heat, FPG ratio 160% bracket 151%+. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 55 + # 2026 FPG for 1-person = $15,960, 160% = $25,536 + employment_income: 25_536 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio ~160%, Bracket 151%+: Electric = $268 + ri_liheap_heating_benefit: 268 + +# ============================================================================= +# HEAT IN RENT TESTS +# ============================================================================= + +- name: Case 16, heat in rent non-subsidized housing. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + employment_income: 15_000 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: HEAT_IN_RENT + receives_housing_assistance: false + households: + household: + members: [person1] + state_code: RI + output: + # Heat in rent: $400 direct pay + $80 secondary electric = $480 + ri_liheap_heating_benefit: 480 + +- name: Case 17, heat in rent subsidized housing. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + employment_income: 15_000 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: HEAT_IN_RENT + receives_housing_assistance: true + households: + household: + members: [person1] + state_code: RI + output: + # Heat in rent subsidized: $400 direct pay + $50 secondary electric = $450 + ri_liheap_heating_benefit: 450 + +# ============================================================================= +# MULTI-PERSON HOUSEHOLD TESTS +# ============================================================================= + +- name: Case 18, 4-person household deliverable fuel low income. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # 4-person FPG = $33,000, targeting ~60% FPG = $19,800 + employment_income: 19_800 + person2: + age: 33 + person3: + age: 10 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # FPG for 4-person = $33,000, income $19,800 + # FPG ratio = $19,800 / $33,000 = 0.60 (60%) + # Bracket 0-75%: Deliverable = $861 + ri_liheap_heating_benefit: 861 + +- name: Case 19, 3-person household natural gas mid income. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + # 3-person FPG = $27,320, targeting 140% FPG = $38,248 + employment_income: 38_248 + person2: + age: 38 + person3: + age: 12 + spm_units: + spm_unit: + members: [person1, person2, person3] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1, person2, person3] + state_code: RI + output: + # FPG for 3-person = $27,320, income $38,248 + # FPG ratio = $38,248 / $27,320 = 1.40 (140%) + # Bracket 126-150%: Natural Gas = $175 + ri_liheap_heating_benefit: 175 + +- name: Case 20, 2-person household electric heat elderly. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 70 + # 2-person FPG = $21,640, targeting 160% FPG = $34,624 + # Using employment_income since irs_gross_income only counts taxable income + employment_income: 20_000 + person2: + age: 68 + employment_income: 14_624 + spm_units: + spm_unit: + members: [person1, person2] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1, person2] + state_code: RI + output: + # Income = $20,000 + $14,624 = $34,624 + # FPG for 2-person = $21,640 + # FPG ratio = $34,624 / $21,640 = 1.60 (160%) + # Bracket 151%+: Electric = $268 + ri_liheap_heating_benefit: 268 + +# ============================================================================= +# BOUNDARY CONDITION TESTS +# ============================================================================= + +- name: Case 21, FPG ratio exactly at 75% threshold. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # 2026 FPG for 1-person = $15,960, 75% = $11,970 + employment_income: 11_970 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $11,970 / $15,960 = 0.75 (75%) + # At 75% threshold - still in 0-75% bracket + ri_liheap_heating_benefit: 861 + +- name: Case 22, FPG ratio just above 75% threshold. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # 2026 FPG for 1-person = $15,960, 76% = $12,130 + employment_income: 12_130 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $12,130 / $15,960 = 0.76 (76%) + # Just above 76% threshold - in 76-100% bracket + ri_liheap_heating_benefit: 805 + +- name: Case 23, FPG ratio exactly at 100% threshold. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # 2026 FPG for 1-person = $15,960, 100% = $15,960 + employment_income: 15_960 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $15,960 / $15,960 = 1.0 (100%) + # At 100% threshold - still in 76-100% bracket + ri_liheap_heating_benefit: 211 + +- name: Case 24, FPG ratio just above 100% threshold. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 35 + # 2026 FPG for 1-person = $15,960, 101% = $16,120 + employment_income: 16_120 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # FPG ratio = $16,120 / $15,960 = 1.01 (101%) + # Just above 101% threshold - in 101-125% bracket + ri_liheap_heating_benefit: 192 + +# ============================================================================= +# INELIGIBLE HOUSEHOLD TESTS +# ============================================================================= + +- name: Case 25, income over 60% SMI ineligible household. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + employment_income: 60_000 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + # Income $60,000 exceeds 60% SMI for 1-person household + # Not eligible for LIHEAP - heating benefit should be $0 + # Note: ri_liheap_heating_benefit has defined_for="ri_liheap_eligible" + ri_liheap_heating_benefit: 0 + +- name: Case 26, non-RI resident ineligible. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 40 + employment_income: 15_000 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: MA + output: + # Not RI resident - ineligible for RI LIHEAP + ri_liheap_heating_benefit: 0 + +# ============================================================================= +# ZERO INCOME TESTS +# ============================================================================= + +- name: Case 27, zero income household lowest FPG bracket. + period: 2026 + absolute_error_margin: 0.1 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1, person2] + state_code: RI + output: + # Zero income = 0% FPG ratio + # Bracket 0-75%: Deliverable = $861 + ri_liheap_heating_benefit: 861 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_heating_type.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_heating_type.yaml new file mode 100644 index 00000000000..bd5188005eb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_heating_type.yaml @@ -0,0 +1,102 @@ +# Unit tests for Rhode Island LIHEAP heating type enum variable +# Tests the input variable for heating fuel type used by the household +# +# Available heating types: +# - DELIVERABLE: Oil, propane, kerosene, wood, coal +# - NATURAL_GAS: Natural gas +# - ELECTRIC: Electric heat +# - HEAT_IN_RENT: Heat included in rent +# +# Default value: NATURAL_GAS (if not specified) +# +# Source: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + +# ============================================================================= +# HEATING TYPE INPUT TESTS +# ============================================================================= + +- name: Case 1, deliverable fuel type. + period: 2026 + input: + people: + person1: + age: 40 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: DELIVERABLE + households: + household: + members: [person1] + state_code: RI + output: + ri_liheap_heating_type: DELIVERABLE + +- name: Case 2, natural gas type. + period: 2026 + input: + people: + person1: + age: 40 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + ri_liheap_heating_type: NATURAL_GAS + +- name: Case 3, electric heat type. + period: 2026 + input: + people: + person1: + age: 40 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: ELECTRIC + households: + household: + members: [person1] + state_code: RI + output: + ri_liheap_heating_type: ELECTRIC + +- name: Case 4, heat in rent type. + period: 2026 + input: + people: + person1: + age: 40 + spm_units: + spm_unit: + members: [person1] + ri_liheap_heating_type: HEAT_IN_RENT + households: + household: + members: [person1] + state_code: RI + output: + ri_liheap_heating_type: HEAT_IN_RENT + +- name: Case 5, default heating type is natural gas. + period: 2026 + input: + people: + person1: + age: 40 + spm_units: + spm_unit: + members: [person1] + # No heating type specified - should default to NATURAL_GAS + households: + household: + members: [person1] + state_code: RI + output: + # Default value is NATURAL_GAS per variable definition + ri_liheap_heating_type: NATURAL_GAS diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_income_eligible.yaml new file mode 100644 index 00000000000..b03a06bf781 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_income_eligible.yaml @@ -0,0 +1,208 @@ +# Unit tests for Rhode Island LIHEAP income eligibility +# Eligibility: Gross income <= 60% of State Median Income (SMI) +# Source: 42 U.S.C. Section 8624(b)(2)(B); 45 CFR 96.85 +# https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program +# +# FFY 2025 60% SMI limits by household size (used for period 2025): +# 1-person: $39,102 +# 2-person: $51,134 +# 3-person: $63,165 +# 4-person: $75,197 +# 5-person: $87,228 +# 6-person: $99,260 +# +# Note: Period 2025 uses parameters effective 2025-01-01, which falls within FFY 2025 +# (Oct 2024 - Sept 2025). RI 4-person SMI for FFY 2025 is $125,328. + +- name: Case 1, single person income well below 60% SMI. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 30_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # 60% SMI for 1-person in RI FFY 2025: $39,102 + # $30,000 < $39,102 = eligible + ri_liheap_income_eligible: true + +- name: Case 2, single person income above 60% SMI. + period: 2025 + input: + people: + person1: + age: 40 + employment_income: 50_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # 60% SMI for 1-person in RI FFY 2025: $39,102 + # $50,000 > $39,102 = ineligible + ri_liheap_income_eligible: false + +- name: Case 3, single person income at boundary just below limit. + period: 2025 + input: + people: + person1: + age: 45 + employment_income: 39_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # 60% SMI for 1-person: $39,102 + # $39,000 < $39,102 = eligible + ri_liheap_income_eligible: true + +- name: Case 4, single person income at boundary just above limit. + period: 2025 + input: + people: + person1: + age: 45 + employment_income: 39_500 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # 60% SMI for 1-person: $39,102 + # $39,500 > $39,102 = ineligible + ri_liheap_income_eligible: false + +- name: Case 5, 4-person household income below 60% SMI. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 60_000 + person2: + age: 33 + person3: + age: 10 + person4: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # 60% SMI for 4-person in RI FFY 2025: $75,197 + # $60,000 < $75,197 = eligible + ri_liheap_income_eligible: true + +- name: Case 6, 4-person household income above 60% SMI. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 50_000 + person2: + age: 33 + employment_income: 30_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # 60% SMI for 2-person: $51,134 + # $80,000 > $51,134 = ineligible + ri_liheap_income_eligible: false + +- name: Case 7, 2-person household at boundary. + period: 2025 + input: + people: + person1: + age: 50 + employment_income: 51_000 + person2: + age: 48 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # 60% SMI for 2-person: $51,134 + # $51,000 < $51,134 = eligible + ri_liheap_income_eligible: true + +- name: Case 8, 6-person large household eligible. + period: 2025 + input: + people: + person1: + age: 40 + employment_income: 80_000 + person2: + age: 38 + person3: + age: 15 + person4: + age: 12 + person5: + age: 8 + person6: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: RI + output: + # 60% SMI for 6-person: $99,260 + # $80,000 < $99,260 = eligible + ri_liheap_income_eligible: true + +- name: Case 9, household with zero income. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 0 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # $0 < any SMI threshold = eligible + ri_liheap_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_priority_household.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_priority_household.yaml new file mode 100644 index 00000000000..1695a5f4197 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/dhs/liheap/ri_liheap_priority_household.yaml @@ -0,0 +1,212 @@ +# Unit tests for Rhode Island LIHEAP priority household status +# Per 42 U.S.C. Section 8624, states must give priority to households with: +# - Elderly member (age 60+) +# - Disabled member +# - Young child (under 6) +# Source: https://dhs.ri.gov/media/9371/download?language=en (FFY 2026 State Plan Summary) + +- name: Case 1, household with elderly member (age 60). + period: 2025 + input: + people: + person1: + age: 60 + employment_income: 20_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Person age 60 = elderly, priority household + ri_liheap_priority_household: true + +- name: Case 2, household with elderly member (age 75). + period: 2025 + input: + people: + person1: + age: 75 + social_security: 18_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Person age 75 = elderly, priority household + ri_liheap_priority_household: true + +- name: Case 3, household with disabled member. + period: 2025 + input: + people: + person1: + age: 45 + is_disabled: true + ssi: 12_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Disabled member = priority household + ri_liheap_priority_household: true + +- name: Case 4, household with young child under 6. + period: 2025 + input: + people: + person1: + age: 28 + employment_income: 30_000 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Child age 4 (under 6) = young child, priority household + ri_liheap_priority_household: true + +- name: Case 5, household with infant. + period: 2025 + input: + people: + person1: + age: 30 + employment_income: 25_000 + person2: + age: 32 + person3: + age: 1 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: RI + output: + # Child age 1 (under 6) = young child, priority household + ri_liheap_priority_household: true + +- name: Case 6, household with child age 6 not priority. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 40_000 + person2: + age: 6 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Child age 6 is NOT under 6, not a priority factor + # No elderly or disabled either = not priority + ri_liheap_priority_household: false + +- name: Case 7, adult age 59 not elderly, not priority. + period: 2025 + input: + people: + person1: + age: 59 + employment_income: 35_000 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: RI + output: + # Age 59 is NOT 60+, not elderly + # Not disabled, no young children = not priority + ri_liheap_priority_household: false + +- name: Case 8, working-age adults with older children, not priority. + period: 2025 + input: + people: + person1: + age: 42 + employment_income: 50_000 + person2: + age: 40 + person3: + age: 14 + person4: + age: 10 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: RI + output: + # No elderly (ages 42, 40), not disabled + # No children under 6 (ages 14, 10) + # Not a priority household + ri_liheap_priority_household: false + +- name: Case 9, household with multiple priority factors. + period: 2025 + input: + people: + person1: + age: 65 + is_disabled: true + social_security: 15_000 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Elderly (65), disabled, AND young child (3) + # Multiple priority factors = priority household + ri_liheap_priority_household: true + +- name: Case 10, household with disabled child. + period: 2025 + input: + people: + person1: + age: 35 + employment_income: 30_000 + person2: + age: 10 + is_disabled: true + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: RI + output: + # Disabled child = priority household + ri_liheap_priority_household: true diff --git a/policyengine_us/variables/gov/states/ri/dhs/liheap/eligibility/ri_liheap_eligible.py b/policyengine_us/variables/gov/states/ri/dhs/liheap/eligibility/ri_liheap_eligible.py new file mode 100644 index 00000000000..0093e75665f --- /dev/null +++ b/policyengine_us/variables/gov/states/ri/dhs/liheap/eligibility/ri_liheap_eligible.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class ri_liheap_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Rhode Island LIHEAP" + definition_period = YEAR + reference = "https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program" + defined_for = StateCode.RI + + def formula(spm_unit, period, parameters): + return spm_unit("ri_liheap_income_eligible", period) diff --git a/policyengine_us/variables/gov/states/ri/dhs/liheap/eligibility/ri_liheap_income_eligible.py b/policyengine_us/variables/gov/states/ri/dhs/liheap/eligibility/ri_liheap_income_eligible.py new file mode 100644 index 00000000000..fd4b778bf81 --- /dev/null +++ b/policyengine_us/variables/gov/states/ri/dhs/liheap/eligibility/ri_liheap_income_eligible.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ri_liheap_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Rhode Island LIHEAP income eligibility" + definition_period = YEAR + defined_for = StateCode.RI + reference = ( + "https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program", + "https://www.law.cornell.edu/uscode/text/42/8624", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.hhs.liheap + income = add(spm_unit, period, ["irs_gross_income"]) + income_limit = spm_unit("hhs_smi", period) * p.smi_limit + return income <= income_limit diff --git a/policyengine_us/variables/gov/states/ri/dhs/liheap/eligibility/ri_liheap_priority_household.py b/policyengine_us/variables/gov/states/ri/dhs/liheap/eligibility/ri_liheap_priority_household.py new file mode 100644 index 00000000000..7aac05e3599 --- /dev/null +++ b/policyengine_us/variables/gov/states/ri/dhs/liheap/eligibility/ri_liheap_priority_household.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class ri_liheap_priority_household(Variable): + value_type = bool + entity = SPMUnit + label = "Rhode Island LIHEAP priority household" + definition_period = YEAR + defined_for = StateCode.RI + reference = ( + "https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program", + "https://www.law.cornell.edu/uscode/text/42/8624", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ri.dhs.liheap.priority + person = spm_unit.members + age = person("age", period) + + has_elderly = spm_unit.any(age >= p.elderly_age) + has_disabled = spm_unit.any(person("is_disabled", period)) + has_young_child = spm_unit.any(age < p.young_child_age) + + return has_elderly | has_disabled | has_young_child diff --git a/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap.py b/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap.py new file mode 100644 index 00000000000..6cf8f3139e9 --- /dev/null +++ b/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ri_liheap(Variable): + value_type = float + entity = SPMUnit + label = "Rhode Island LIHEAP benefit" + definition_period = YEAR + unit = USD + defined_for = StateCode.RI + reference = ( + "https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf", + "https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program", + ) + + def formula(spm_unit, period, parameters): + eligible = spm_unit("ri_liheap_eligible", period) + heating_benefit = spm_unit("ri_liheap_heating_benefit", period) + return where(eligible, heating_benefit, 0) diff --git a/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap_fpg_ratio.py b/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap_fpg_ratio.py new file mode 100644 index 00000000000..f2d4a4f6019 --- /dev/null +++ b/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap_fpg_ratio.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ri_liheap_fpg_ratio(Variable): + value_type = float + entity = SPMUnit + label = "Rhode Island LIHEAP federal poverty guideline ratio" + definition_period = YEAR + defined_for = StateCode.RI + unit = "/1" + reference = ( + "https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf", + "https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program", + ) + + def formula(spm_unit, period, parameters): + income = add(spm_unit, period, ["irs_gross_income"]) + fpg = spm_unit("spm_unit_fpg", period) + return income / fpg diff --git a/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap_heating_benefit.py b/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap_heating_benefit.py new file mode 100644 index 00000000000..8056887947d --- /dev/null +++ b/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap_heating_benefit.py @@ -0,0 +1,51 @@ +from policyengine_us.model_api import * + + +class ri_liheap_heating_benefit(Variable): + value_type = float + entity = SPMUnit + label = "Rhode Island LIHEAP heating benefit" + definition_period = YEAR + unit = USD + defined_for = "ri_liheap_eligible" + reference = ( + "https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf", + "https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ri.dhs.liheap.benefit + heating_type = spm_unit("ri_liheap_heating_type", period) + fpg_ratio = spm_unit("ri_liheap_fpg_ratio", period) + is_subsidized = spm_unit("receives_housing_assistance", period) + + # Heating type enum values + ht = heating_type.possible_values + is_deliverable = heating_type == ht.DELIVERABLE + is_natural_gas = heating_type == ht.NATURAL_GAS + is_electric = heating_type == ht.ELECTRIC + is_heat_in_rent = heating_type == ht.HEAT_IN_RENT + + # Calculate benefits by fuel type using bracketed parameters + deliverable_benefit = p.deliverable.amount.calc(fpg_ratio) + natural_gas_benefit = p.natural_gas.amount.calc(fpg_ratio) + electric_benefit = p.electric.amount.calc(fpg_ratio) + + # Heat in rent: flat payment plus potential secondary electric + heat_in_rent_payment = p.heat_in_rent.direct_pay + secondary_electric = where( + is_subsidized, + p.subsidized_housing.secondary_electric, + p.heat_in_rent.secondary_electric, + ) + + return select( + [is_deliverable, is_natural_gas, is_electric, is_heat_in_rent], + [ + deliverable_benefit, + natural_gas_benefit, + electric_benefit, + heat_in_rent_payment + secondary_electric, + ], + default=0, + ) diff --git a/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap_heating_type.py b/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap_heating_type.py new file mode 100644 index 00000000000..d151fd68e0b --- /dev/null +++ b/policyengine_us/variables/gov/states/ri/dhs/liheap/ri_liheap_heating_type.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class RILIHEAPHeatingType(Enum): + DELIVERABLE = "Deliverable" # Oil, propane, kerosene, wood, coal + NATURAL_GAS = "Natural Gas" + ELECTRIC = "Electric" + HEAT_IN_RENT = "Heat in Rent" # Heat included in rent + + +class ri_liheap_heating_type(Variable): + value_type = Enum + entity = SPMUnit + possible_values = RILIHEAPHeatingType + default_value = RILIHEAPHeatingType.NATURAL_GAS + label = "Rhode Island LIHEAP household heating type" + definition_period = YEAR + defined_for = StateCode.RI + reference = "https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf" diff --git a/sources/working_references.md b/sources/working_references.md index 27856ccebd3..badec6bfdcd 100644 --- a/sources/working_references.md +++ b/sources/working_references.md @@ -397,3 +397,640 @@ Several of these parameters have automatic uprating configured. However, the act - [x] Tier one retirement joint 2025 confirmed: $131,794 - [ ] Home heating credit 2025 standard allowances: PENDING (form not yet released) - [x] Tax rate 2025 confirmed: 4.25% + +--- +--- + +## Rhode Island LIHEAP Implementation +**Collected**: 2026-02-03 +**Implementation Task**: Rhode Island Low Income Home Energy Assistance Program (LIHEAP) eligibility and benefit calculation + +--- + +## Official Program Name + +**Federal Program**: Low Income Home Energy Assistance Program (LIHEAP) +**State's Official Name**: Low Income Home Energy Assistance Program (LIHEAP) +**Abbreviation**: LIHEAP +**Administering Agency**: Rhode Island Department of Human Services (DHS) +**Source**: R.I. Gen. Laws Section 39-1-27.12; DHS Program Page + +**Variable Prefix**: `ri_liheap` + +--- + +## Program Overview + +Rhode Island's LIHEAP is a federally-funded program administered by the Rhode Island Department of Human Services (DHS) through local Community Action Program (CAP) agencies. The program helps eligible low-income households pay their heating bills through federal grants. + +### Program Components + +1. **Heating Assistance**: A one-time supplemental grant to assist a household in meeting heating costs. The grant is paid directly to heating fuel vendors or utility companies, or in some cases, directly to the applicant. + +2. **Crisis Assistance**: A grant to help resolve a home heating crisis caused by: + - Heat shut-off due to failure to pay a regulated energy bill + - Inability to pay for deliverable fuel + - Failure of a heating system that is not repairable + +3. **Weatherization**: Services including home insulation, weather stripping, furnace cleaning/repair/replacement, and chimney inspection/cleaning. Households must first apply for heating assistance. + +### Source Information +- **Title**: Low Income Home Energy Assistance Program (LIHEAP) +- **URL**: https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-1 +- **Effective Date**: FFY 2026 (October 1, 2025 - September 30, 2026) + +--- + +## Income Eligibility + +### Income Limit Standard + +Rhode Island households are income-eligible for LIHEAP when the household's gross income is **equal to or less than 60 percent of the State Median Income (SMI)** for their household size. + +**Legal Authority**: +- Federal: 42 U.S.C. Section 8624(b)(2)(B) +- Regulation: 45 CFR 96.85 +- This became **mandatory** as of October 1, 2024 + +### 60% SMI Calculation Methodology (per 45 CFR 96.85) + +The income limits are calculated by taking 60% of the state's estimated median income for a 4-person family and multiplying by the following household size adjustments: + +| Household Size | Adjustment Factor | +|----------------|-------------------| +| 1 person | 52% | +| 2 persons | 68% | +| 3 persons | 84% | +| 4 persons | 100% | +| 5 persons | 116% | +| 6 persons | 132% | +| 7 persons | 135% | +| 8 persons | 138% | +| 9 persons | 141% | +| 10 persons | 144% | +| 11 persons | 147% | +| 12 persons | 150% | +| Each additional | +3% | + +### Rhode Island SMI for 4-Person Household (from HHS) + +| Federal Fiscal Year | 4-Person SMI | 60% of SMI | +|---------------------|--------------|------------| +| FFY 2025 (Oct 2024) | $125,328 | $75,197 | +| FFY 2026 (Oct 2025) | $135,424 | $81,254 | + +**Source**: HHS LIHEAP IM2025-02 State Median Income Tables +- https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf + +### FFY 2026 Income Limits by Household Size (60% SMI) + +| Household Size | Annual (12-Month) | Quarterly (3-Month) | Monthly (1-Month) | +|----------------|-------------------|---------------------|-------------------| +| 1 | $42,252 | $10,563 | $3,521 | +| 2 | $55,252 | $13,813 | $4,604 | +| 3 | $68,253 | $17,063 | $5,687 | +| 4 | $81,254 | $20,313 | $6,771 | +| 5 | $94,254 | $23,563 | $7,854 | +| 6 | $107,255 | $26,813 | $8,937 | +| 7 | $109,692 | $27,423 | $9,141 | +| 8 | $112,130 | $28,032 | $9,344 | +| 9 | $114,568 | $28,642 | $9,547 | +| 10 | $117,005 | $29,251 | $9,750 | +| 11 | $119,443 | $29,860 | $9,953 | +| 12 | $121,881 | $30,470 | $10,156 | +| 13 | $124,318 | $31,079 | $10,359 | +| 14 | $126,756 | $31,689 | $10,563 | + +**Source**: RI DHS FFY 2026 Low Income Guidelines +- https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/ffy-2025-low-income-guidelines + +### Income Definition + +- **Gross income** is used (not net income) +- Income documentation must represent gross income earned in the most recent 4 weeks, 3 months, or 12 months +- Self-employment income is verified by IRS tax forms +- Interest income in excess of $500 annually must be included +- Student income exemption: Full-time students ages 18-23 may have income excluded with proper documentation + +**Source**: Rhode Island LIHEAP Administration and Procedures Manual +- https://ripuc.ri.gov/sites/g/files/xkgbur841/files/eventsactions/docket/4290-DHS-DR-PUC-3-6-attachment-LIHEAP-Manual-2020---Final.pdf + +--- + +## Categorical Eligibility + +### Rhode Island Does NOT Use Categorical Eligibility + +Unlike some states, Rhode Island does **NOT** provide automatic/categorical eligibility for LIHEAP based on participation in: +- SNAP (Supplemental Nutrition Assistance Program) +- SSI (Supplemental Security Income) +- TANF (Temporary Assistance for Needy Families) + +All Rhode Island households must meet the 60% SMI income eligibility test regardless of participation in other programs. + +**Source**: LIHEAP Clearinghouse - Categorical Eligibility Tables +- https://liheapch.acf.gov/delivery/income_categorical.htm + +### SNAP Nominal Payment ("Heat and Eat") + +Rhode Island provides an annual **nominal LIHEAP payment of $20.01** to certain SNAP households. This allows eligible SNAP households to claim the Standard Utility Allowance (SUA) and receive higher SNAP benefits. + +**Eligibility for Nominal Payment**: +- Household has not received LIHEAP at their current residence for the past 12 months +- Household lives in subsidized housing with heat included in rent +- As of November 1, 2025: Limited to households with an elderly (60+) or disabled member + +**Source**: RI DHS FFY 2026 State Plan Summary +- https://dhs.ri.gov/media/9371/download?language=en + +--- + +## FFY 2026 Benefit Matrix (from PDF) + +**Source**: Rhode Island Department of Human Services - LIHEAP Grant Amounts Federal Fiscal Year 2026 +- URL: /Users/ziminghua/Downloads/RI_BenefitMatrix_2026.pdf (local file) +- Online: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf +- **Effective Date**: October 1, 2025 through September 30, 2026 + +**Important Note from Document**: "Moderate matrix dependent on funding levels at FFY 2025, to be input 9/30/2025" - This indicates values may be subject to adjustment based on federal funding. + +### Grant Amounts by Income Level and Heating Source + +Rhode Island uses **Federal Poverty Guidelines (FPG)** percentages to determine benefit tiers (NOT SMI - SMI is used for eligibility only). + +| Category | Income Level (% FPG) | Deliverables | Natural Gas | Electric | Other | +|----------|---------------------|--------------|-------------|----------|-------| +| A | Up to 75% | $861 | $232 | $393 | - | +| B | 76-100% | $805 | $211 | $357 | - | +| C | 101-125% | $752 | $192 | $324 | - | +| D | 126-150% | $704 | $175 | $295 | - | +| E | 151%+ | $657 | $159 | $268 | - | +| F | Subsidized Housing w/ Primary Heating Bill | $657 | $159 | $268 | - | +| G | Heat in Rent Direct Pay to Household | $400 | $400 | $400 | $400 | +| H | Heat in Rent Secondary Electric | - | - | - | $80 | +| I | Heat in Rent Subsidized Housing Secondary Electric | - | - | - | $50 | + +### Heating Source Definitions + +- **Deliverables**: Oil, propane, kerosene, wood, coal, or other delivered fuels +- **Natural Gas**: Utility-provided natural gas +- **Electric**: Electric heat (baseboard, heat pump, etc.) +- **Other**: Used for special categories (Heat in Rent) + +### Minimum and Maximum Benefit Amounts (FFY 2026) + +| Measure | Amount | Category | +|---------|--------|----------| +| **Maximum Benefit** | $861 | Deliverables, Up to 75% FPG (Category A) | +| **Minimum Regular Benefit** | $159 | Natural Gas, 151%+ FPG (Category E/F) | +| **Heat in Rent Flat Payment** | $400 | Direct Pay to Household (Category G) | +| **Secondary Electric** | $80 | Heat in Rent Secondary Electric (Category H) | +| **Minimum Benefit** | $50 | Subsidized Housing Secondary Electric (Category I) | + +### Comparison: FFY 2025 vs FFY 2026 + +| Measure | FFY 2025 | FFY 2026 | Change | +|---------|----------|----------|--------| +| Maximum Benefit | $1,285 | $861 | -$424 (-33%) | +| Minimum Benefit | $75 | $50 | -$25 (-33%) | + +**Significant reduction in benefits for FFY 2026** - This is consistent with the RI DHS FFY 2026 State Plan Summary which noted that "grant amounts are expected to be smaller than in prior years" due to anticipated changes in federal funding. + +### FFY 2026 Income Eligibility Thresholds by FPG (for Benefit Tier Assignment) + +The PDF also provides FPG-based income thresholds used to assign households to benefit tiers: + +| Household Size | 75% FPG (Annual) | 100% FPG (Annual) | 125% FPG (Annual) | 150% FPG (Annual) | +|----------------|------------------|-------------------|-------------------|-------------------| +| 1 | $11,738 | $15,650 | $19,563 | $23,475 | +| 2 | $15,863 | $21,150 | $31,725 | $31,725 | +| 3 | $19,988 | $26,650 | $33,313 | $39,975 | +| 4 | $24,113 | $32,150 | $40,188 | $48,225 | +| 5 | $28,238 | $37,650 | $47,063 | $56,475 | +| 6 | $32,363 | $43,150 | $53,938 | $64,725 | +| 7 | $36,488 | $48,650 | $60,813 | $72,975 | +| 8 | $40,613 | $54,150 | $67,688 | $81,225 | +| 9 | $44,738 | $59,650 | $74,563 | $89,475 | +| 10 | $48,863 | $65,150 | $81,438 | $97,725 | +| 11 | $52,988 | $70,650 | $88,313 | $105,975 | +| 12 | $57,113 | $76,150 | $95,188 | $114,225 | +| 13 | $61,238 | $81,650 | $102,063 | $122,475 | +| 14 | $65,363 | $87,150 | $108,938 | $130,725 | + +**Note**: The 100% FPG column shows monthly values as well ($1,304 for 1 person, etc.) which are used for income verification. + +### Benefit Calculation Logic + +1. **Determine Eligibility**: Household income must be at or below 60% SMI +2. **Determine Benefit Tier**: Compare household income to FPG thresholds + - Up to 75% FPG -> Category A (highest benefit) + - 76-100% FPG -> Category B + - 101-125% FPG -> Category C + - 126-150% FPG -> Category D + - 151%+ FPG (up to 60% SMI) -> Category E (lowest regular benefit) +3. **Determine Heating Source**: Deliverables, Natural Gas, or Electric +4. **Special Categories**: + - Subsidized housing with primary heating bill -> Category F + - Heat included in rent -> Category G (flat $400) + - Heat in rent with separate electric -> Category H ($80) + - Subsidized housing with heat in rent, secondary electric -> Category I ($50) + +### Parameters Needed for Implementation + +Based on the FFY 2026 Benefit Matrix, the following parameters are needed: + +```yaml +# Benefit amounts by income tier and fuel type +ri_liheap_benefit_deliverables: + 2025-10-01: + tier_a: 861 # Up to 75% FPG + tier_b: 805 # 76-100% FPG + tier_c: 752 # 101-125% FPG + tier_d: 704 # 126-150% FPG + tier_e: 657 # 151%+ FPG + +ri_liheap_benefit_natural_gas: + 2025-10-01: + tier_a: 232 + tier_b: 211 + tier_c: 192 + tier_d: 175 + tier_e: 159 + +ri_liheap_benefit_electric: + 2025-10-01: + tier_a: 393 + tier_b: 357 + tier_c: 324 + tier_d: 295 + tier_e: 268 + +# Special categories +ri_liheap_heat_in_rent_payment: + 2025-10-01: 400 + +ri_liheap_secondary_electric: + 2025-10-01: 80 + +ri_liheap_subsidized_secondary_electric: + 2025-10-01: 50 +``` + +### References for Parameters + +```yaml +reference: + - title: "Rhode Island LIHEAP Grant Amounts FFY 2026" + href: "https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf" + - title: "RI DHS LIHEAP Program" + href: "https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-1" +``` + +--- + +## Benefit Calculation + +### Benefit Determination Factors + +LIHEAP Primary Grant amounts are based on: +1. **Household income level** +2. **Household (family) size** +3. **Fuel type** (electric, gas, oil, propane) +4. **Minimum delivery requirements** + +### FFY 2025 Benefit Amounts (Previous Year - For Reference) + +| Component | Minimum | Maximum | +|-----------|---------|---------| +| Heating Assistance | $75 | $1,285 | +| Winter Crisis | N/A | $1,500 | + +**Alternative Source (LIHEAP Clearinghouse)**: +| Component | Minimum | Maximum | +|-----------|---------|---------| +| Heating Assistance | $64 | $1,148 | +| Winter Crisis | N/A | $1,500 | + +**Note**: Benefit amounts vary by source due to timing of updates and funding levels. + +### FFY 2026 Benefit Amounts (Current Year) + +| Component | Minimum | Maximum | +|-----------|---------|---------| +| Heating Assistance | $50 | $861 | +| Winter Crisis | N/A | TBD (likely $1,500) | + +Grant amounts for FFY 2026 are **dependent on funding levels** and are **smaller than in prior years** due to anticipated changes in federal funding and guidance. + +**Source**: RI DHS FFY 2026 State Plan Summary +- https://dhs.ri.gov/media/9371/download?language=en + +### Crisis Assistance Eligibility + +Crisis assistance may be issued if: +- Client has the utility shut off, OR +- Client has 1/4 tank or less of heating fuel + +**Additional Requirement**: Clients must have $300 or less remaining of their primary heating benefit before applying for crisis assistance. + +**Life-Threatening Crisis Definition**: A life-threatening crisis occurs when the client is unable to maintain heat in the home and the overnight temperature is **below 20 degrees Fahrenheit**. + +**Source**: RI DHS LIHEAP Program Information + +--- + +## Priority Groups (Vulnerable Populations) + +### Statutory Requirement + +Per 42 U.S.C. Section 8624, states must ensure "the highest level of assistance will be furnished to those households which have the lowest incomes and the highest energy costs or needs in relation to income, taking into account family size." + +### Rhode Island Priority Implementation + +Rhode Island gives priority to households with: +- **Elderly member** (age 60+) +- **Disabled member** +- **Young child** + +**How Priority is Applied**: +1. **Crisis Grants**: First round of crisis grants available to priority households for several weeks before opening to all eligible households +2. **Weatherization**: Work orders are prioritized in the software system by household composition +3. **Application Processing**: Grant renewal forms mailed in September to give vulnerable populations extra time + +**Source**: RI DHS FFY 2026 State Plan Summary; 42 U.S.C. Section 8624 +- https://www.law.cornell.edu/uscode/text/42/8624 + +--- + +## Program Dates and Seasons + +### FFY 2026 Program Dates + +| Component | Start Date | End Date | +|-----------|------------|----------| +| Heating Assistance | October 1, 2025 | April 15, 2026 | +| Winter Crisis | October 1, 2025 | May 1, 2026 | +| Weatherization | Year-round | Year-round | + +### Application Period + +- **New Applications**: Taken from September through May each year +- **Renewal Applications**: Mailed to prior year recipients in September +- **Vendor Notification**: December 1, 2025 (previously November 1) + +### Cooling Assistance + +Rhode Island DHS is **NOT planning to offer a cooling component** in FFY 2026. + +**Source**: RI DHS FFY 2026 State Plan Summary +- https://dhs.ri.gov/media/9371/download?language=en + +--- + +## Citizenship and Immigration Requirements + +### Eligible Applicants + +- U.S. Citizens +- Permanent legal residents +- Qualified aliens + +### Mixed Status Households + +"Mixed status households" (e.g., parent is undocumented and children are citizens/lawful immigrants) **may be eligible**. Family income is measured against the household size of the **eligible members only**. + +**Source**: RI DHS LIHEAP Eligibility Information +- https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program + +--- + +## LIHEAP Enhancement Plan (State Supplement) + +### Legal Authority + +R.I. Gen. Laws Section 39-1-27.12 established the Low-Income Home Energy Assistance Program Enhancement Plan to supplement federal LIHEAP funding. + +### Funding Mechanism + +A surcharge is applied to all electric and gas customer bills: +- **Electric customers**: Up to $10.00 per year +- **Natural gas customers**: Up to $10.00 per year + +### Total Revenue Cap + +- **Maximum**: $7,500,000 annually +- **Minimum**: $6,500,000 annually + +### Use of Enhancement Funds + +- Credits applied to accounts of customers receiving federal LIHEAP assistance +- Minimum 5% allocated for customers seeking LIHEAP certification for arrearage plans between April 15 and September 30 +- A portion set aside for homeless families/individuals transitioning from shelters into housing (for summer months) + +**Source**: R.I. Gen. Laws Section 39-1-27.12 +- http://webserver.rilin.state.ri.us/Statutes/title39/39-1/39-1-27.12.HTM +- https://law.justia.com/codes/rhode-island/2012/title-39/chapter-39-1/chapter-39-1-27.12/ + +--- + +## Additional Benefits for LIHEAP Recipients + +### Reduced Electric Rate + +Eligible LIHEAP clients also qualify for a **25% discount** on their electric and/or gas bill through Rhode Island Energy. + +**Source**: RI Energy Assistance Programs +- https://www.rienergy.com/site/ways-to-save/assistance-programs/grant-programs + +--- + +## Resource Test + +**Resources are NOT counted** for LIHEAP eligibility in Rhode Island. Only income is considered. + +**Source**: Economic Progress Institute - Low Income Home Energy & Water Assistance +- https://economicprogressri.org/resources/low-income-home-energy-water-assistance + +--- + +## Appeals Process + +Households determined ineligible are notified in writing by the agency regarding the reason for the denial along with documentation explaining the appeal process. + +**Appeal Deadline**: **15 business days** from receipt of the denial notice to request a hearing. + +**Source**: RI DHS LIHEAP Eligibility Information +- https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program + +--- + +## Non-Simulatable Rules (Architecture Limitation) + +The following rules CANNOT be fully simulated in PolicyEngine's single-period architecture: + +### Time-Based Requirements +- **12-Month Rule for Nominal Payment**: Household must not have received LIHEAP at current residence for past 12 months [CANNOT TRACK - requires history] +- **Crisis Assistance Waiting Period**: Must have $300 or less remaining of primary heating benefit [CANNOT TRACK - requires prior benefit tracking] + +### Historical Tracking Requirements +- **Prior Year Renewal Status**: Renewal applicants are those who received heating assistance the prior year [CANNOT TRACK] + +### What CAN Be Simulated + +- Current income eligibility (60% SMI test) +- Household size determination +- Priority group identification (elderly, disabled, young child) +- Citizenship/immigration eligibility +- **Benefit amount calculation** (based on income tier and fuel type) + +--- + +## References for Metadata + +### For Parameters + +```yaml +reference: + - title: "RI DHS FFY 2026 Low Income Guidelines" + href: "https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/ffy-2025-low-income-guidelines" + - title: "42 U.S.C. Section 8624 - Applications and requirements" + href: "https://www.law.cornell.edu/uscode/text/42/8624" + - title: "45 CFR 96.85 - Income Eligibility" + href: "https://www.ecfr.gov/current/title-45/section-96.85" + - title: "HHS LIHEAP IM2025-02 State Median Income Tables" + href: "https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf" + - title: "Rhode Island LIHEAP Grant Amounts FFY 2026" + href: "https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf" +``` + +### For Variables + +```python +reference = "https://dhs.ri.gov/programs-and-services/energy-assistance-programs-heating/low-income-home-energy-assistance-program" +``` + +--- + +## PDFs for Future Reference + +The following PDFs contain additional information but could not be extracted: + +1. **Rhode Island LIHEAP FFY 2026 State Plan (Full Document)** + - URL: https://liheapch.acf.gov/docs/2026/state-plans/RI_Plan_2026.pdf + - Expected content: Complete state plan with detailed program rules, benefit calculation methodology, outreach procedures, and administrative requirements + +2. **Rhode Island LIHEAP FFY 2026 Benefit Matrix** (NOW EXTRACTED - see above) + - URL: https://liheapch.acf.gov/docs/2026/benefits-matricies/RI_BenefitMatrix_2026.pdf + - Content: Specific benefit amounts by household size, income level, and fuel type combinations + +3. **Rhode Island LIHEAP FFY 2026 State Plan Summary** + - URL: https://dhs.ri.gov/media/9371/download?language=en + - Expected content: Summary of FFY 2026 state plan including benefit amounts, eligibility criteria, and program dates + +4. **Rhode Island LIHEAP FFY 2025 State Plan Summary** + - URL: https://dhs.ri.gov/media/7571/download?language=en + - Expected content: Prior year state plan for comparison + +5. **Rhode Island Low-Income Home Energy Assistance Program 2025-2026 Application** + - URL: https://dhs.ri.gov/media/9656/download?language=en + - Expected content: Application instructions, required documentation, and eligibility information + +6. **Rhode Island LIHEAP Administration and Procedures Manual (2020)** + - URL: https://ripuc.ri.gov/sites/g/files/xkgbur841/files/eventsactions/docket/4290-DHS-DR-PUC-3-6-attachment-LIHEAP-Manual-2020---Final.pdf + - Expected content: Detailed administrative procedures, income calculation methodology, and eligibility verification requirements + +7. **Rhode Island LIHEAP FFY 2025 Income Eligibility Chart** + - URL: https://www.ebcap.org/wp-content/uploads/2024/08/FFY2025-Eligibility-Chart-LIHEAP.pdf + - Expected content: Prior year income limits by household size + +8. **HHS LIHEAP IM2025-02 State Median Income Table (Attachment 4)** + - URL: https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf + - Expected content: Official SMI figures for all states for FFY 2026, including Rhode Island + +9. **Rhode Island Public Utilities Commission - Low-Income Ratepayers' Discount Overview** + - URL: https://ripuc.ri.gov/sites/g/files/xkgbur841/files/2025-08/Low-Income%20Ratepayers'%20Discount%20and%20Funding%20Sources%20-%20Regulatory%20Topic%20Overview%20(08-2025).pdf + - Expected content: Details on LIHEAP Enhancement Plan funding, rate discounts, and regulatory framework + +--- + +## Implementation Notes + +### Existing Federal Parameters + +PolicyEngine already has federal-level LIHEAP parameters that can be reused: + +1. **HHS State Median Income**: `parameters/gov/hhs/smi/amount.yaml` + - Contains Rhode Island SMI for 4-person household by year + - FFY 2026 (2025-10-01): $135,424 + +2. **SMI Household Size Adjustments**: `parameters/gov/hhs/smi/household_size_adjustment.yaml` + - First person: 0.52 + - Second to sixth person: +0.16 each + - Additional person: +0.03 each + +3. **LIHEAP SMI Limit**: `parameters/gov/hhs/liheap/smi_limit.yaml` + - Value: 0.6 (60% of SMI) + +### Variable to Calculate SMI Threshold + +The existing variable `hhs_smi` calculates the state median income for any SPM unit based on state and household size. The Massachusetts implementation shows how to use this: + +```python +# From ma_liheap_state_median_income_threshold.py +def formula(spm_unit, period, parameters): + p = parameters(period).gov.hhs.liheap + state_median_income = spm_unit("hhs_smi", period) + return state_median_income * p.smi_limit # 0.6 = 60% SMI +``` + +### State-Specific Parameters Needed + +Rhode Island LIHEAP implementation needs: + +1. **Benefit amounts by income level and fuel type** (from Benefit Matrix PDF - NOW DOCUMENTED) +2. **Crisis assistance maximum** ($1,500) +3. **Nominal SNAP payment amount** ($20.01) +4. **Program season dates** (if used in eligibility) +5. **Priority group definitions** (elderly age threshold: 60) + +--- + +## Key Contacts and Application Information + +- **Administering Agency**: RI Department of Human Services (DHS) +- **Application Phone**: 1-855-MY-RIDHS (1-855-697-4347) +- **TTY**: 7-1-1 +- **Mailing Address**: RI DHS, P.O. Box 8709, Cranston, RI 02920-8787 +- **Local CAP Agency Finder**: 401-921-4968 +- **Online Application**: Available through DHS portal + +### Community Action Program (CAP) Agencies + +Applications are taken at these local agencies: +- East Bay Community Action Program (EBCAP) +- Community Action Partnership of Providence (CAPP) +- Tri-County Community Action Agency +- Westbay Community Action +- Blackstone Valley Community Action Program (BVCAP) +- Community Care Alliance +- Comprehensive Community Action Program + +--- + +## Summary of Key Values for Implementation + +| Parameter | Value | Source | +|-----------|-------|--------| +| Income Limit | 60% of SMI | 42 U.S.C. 8624(b)(2)(B) | +| RI 4-Person SMI (FFY 2026) | $135,424 | HHS IM2025-02 | +| 60% SMI for 4-person (FFY 2026) | $81,254 | Calculated | +| Heating Benefit Min (FFY 2026) | $50 | RI Benefit Matrix | +| Heating Benefit Max (FFY 2026) | $861 | RI Benefit Matrix | +| Heating Benefit Min (FFY 2025) | $75 | RI DHS | +| Heating Benefit Max (FFY 2025) | $1,285 | RI DHS | +| Crisis Assistance Max (FFY 2025) | $1,500 | RI DHS | +| SNAP Nominal Payment | $20.01 | RI DHS State Plan | +| Elderly Age Threshold | 60 years | 42 U.S.C. 8624 | +| Heating Season Start | October 1 | RI DHS | +| Heating Season End | April 15 | RI DHS | +| Crisis Season End | May 1 | RI DHS | diff --git a/uv.lock b/uv.lock index 66293da3350..c34400be9b8 100644 --- a/uv.lock +++ b/uv.lock @@ -1664,7 +1664,7 @@ wheels = [ [[package]] name = "policyengine-us" -version = "1.549.0" +version = "1.550.0" source = { editable = "." } dependencies = [ { name = "microdf-python" },