diff --git a/changelog.d/sc-liheap-wave2c.added.md b/changelog.d/sc-liheap-wave2c.added.md new file mode 100644 index 00000000000..cf898f6f143 --- /dev/null +++ b/changelog.d/sc-liheap-wave2c.added.md @@ -0,0 +1 @@ +Add South Carolina LIHEAP regular heating assistance for FY2026, with countable income, the federal 110% poverty floor and statewide supplements. diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/eligibility/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/eligibility/fpg_year_lag.yaml new file mode 100644 index 00000000000..5a747148bbe --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/eligibility/fpg_year_lag.yaml @@ -0,0 +1,10 @@ +description: South Carolina uses federal poverty guidelines from this many years before the benefit year under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 1 +metadata: + unit: year + period: year + label: South Carolina LIHEAP poverty guideline year lag + reference: + - title: LIHEAP IM 2025-02, Attachment 2, poverty guidelines for mandatory use in FY26 + href: https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_FPGSte-Table_Att2.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/eligibility/smi_rate.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/eligibility/smi_rate.yaml new file mode 100644 index 00000000000..257297b9d61 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/eligibility/smi_rate.yaml @@ -0,0 +1,10 @@ +description: South Carolina limits income to this share of state median income under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 0.6 +metadata: + unit: /1 + period: year + label: South Carolina LIHEAP SMI limit rate + reference: + - title: South Carolina FY2026 LIHEAP Detailed Model Plan, item 2.1 + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/adult_min_age.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/adult_min_age.yaml new file mode 100644 index 00000000000..10e9c7543b9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/adult_min_age.yaml @@ -0,0 +1,12 @@ +description: South Carolina counts the earned and unearned income sources at or above this age, and only the minor unearned income sources below it, under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 18 +metadata: + unit: year + period: year + label: South Carolina LIHEAP adult income age + reference: + - title: South Carolina FY2026 LIHEAP Detailed Model Plan, item 1.9 + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=6 + - title: South Carolina 2024 Administrative Guide, income from minors + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=529 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/earned_sources.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/earned_sources.yaml new file mode 100644 index 00000000000..10a8b2447d6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/earned_sources.yaml @@ -0,0 +1,18 @@ +description: South Carolina counts these earned income sources under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: + - employment_income + # Active-duty basic pay, entered apart from employment_income; enter it in one + # of the two. + - military_basic_pay + - self_employment_income + - sstb_self_employment_income + - farm_operations_income + - partnership_s_corp_income +metadata: + unit: list + period: year + label: South Carolina LIHEAP earned income sources + reference: + - title: "South Carolina FY2026 LIHEAP Detailed Model Plan, items 1.8-1.9 #page 5-6" + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=5 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/minor_unearned_sources.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/minor_unearned_sources.yaml new file mode 100644 index 00000000000..9fa33582576 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/minor_unearned_sources.yaml @@ -0,0 +1,15 @@ +description: South Carolina counts these unearned income sources of household members younger than the adult income age under the Low Income Home Energy Assistance Program. +# The guide names "Social Security or Disability income". SSI is read as a child's +# disability income, and disability_benefits carries other disability income. +values: + 2025-10-01: + - social_security + - ssi + - disability_benefits +metadata: + unit: list + period: year + label: South Carolina LIHEAP minor unearned income sources + reference: + - title: South Carolina 2024 Administrative Guide, income from minors + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=529 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/unearned_sources.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/unearned_sources.yaml new file mode 100644 index 00000000000..b6d07a37219 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/income/unearned_sources.yaml @@ -0,0 +1,29 @@ +description: South Carolina counts these unearned income sources of adult household members under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: + - total_unemployment_compensation + - social_security + - ssi + # Optional State Supplementation, paid with SSI to care-facility residents. + - sc_ssi_state_supplement + - pension_income + # Military retirement includes Survivor Benefit Plan annuities. + - military_retirement_income + - railroad_benefits + # Ongoing IRA/401k receipts are separate from pension_income. + # Annual inputs cannot identify excluded one-time retirement lump sums. + - retirement_distributions + - survivor_benefits + - rental_income + - farm_rent_income + - alimony_income + - child_support_received + - veterans_benefits + - financial_assistance +metadata: + unit: list + period: year + label: South Carolina LIHEAP unearned income sources + reference: + - title: South Carolina FY2026 LIHEAP Detailed Model Plan, item 1.9 + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=6 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/ages.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/ages.yaml new file mode 100644 index 00000000000..fe03cbbf206 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/ages.yaml @@ -0,0 +1,13 @@ +description: South Carolina uses these age thresholds for regular heating supplements under the Low Income Home Energy Assistance Program. +elderly_min: + 2025-10-01: 60 +# The child maximum is completed age; five-year-olds remain covered until six. +child_max: + 2025-10-01: 5 +metadata: + unit: year + period: year + label: South Carolina LIHEAP supplement age thresholds + reference: + - title: "South Carolina FY2026 LIHEAP Detailed Model Plan, items 2.3-2.5 #page 8-9" + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/amounts.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/amounts.yaml new file mode 100644 index 00000000000..bff26ad685c --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/amounts.yaml @@ -0,0 +1,26 @@ +description: South Carolina provides these base and supplemental regular heating amounts under the Low Income Home Energy Assistance Program. +base: + 2025-10-01: 200 +elderly: + 2025-10-01: 75 +child: + 2025-10-01: 50 +disabled: + 2025-10-01: 50 +veteran: + 2025-10-01: 50 +low_income: + 2025-10-01: 175 +high_burden: + 2025-10-01: 175 +fuel: + 2025-10-01: 75 +maximum: + 2025-10-01: 850 +metadata: + unit: currency-USD + period: year + label: South Carolina LIHEAP regular heating amounts + reference: + - title: "South Carolina FY2026 LIHEAP Detailed Model Plan, items 2.3, 2.5 and 2.6 #page 8-9" + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/burden_rate.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/burden_rate.yaml new file mode 100644 index 00000000000..f4f10183689 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/burden_rate.yaml @@ -0,0 +1,10 @@ +description: South Carolina awards a high-burden supplement at or above this energy-cost share of income under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 0.2 +metadata: + unit: /1 + period: year + label: South Carolina LIHEAP high energy burden rate + reference: + - title: South Carolina FY2026 LIHEAP Detailed Model Plan, item 2.5 + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=9 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/energy_cost_sources.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/energy_cost_sources.yaml new file mode 100644 index 00000000000..a83e8bb3e8c --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/energy_cost_sources.yaml @@ -0,0 +1,19 @@ +description: South Carolina uses these represented home-energy bills for the energy-bill requirement and the energy-burden calculation under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: + - pre_subsidy_electricity_expense + - gas_expense + - bottled_gas_expense + - fuel_oil_expense + - wood_expense + - coal_expense + - other_heating_fuel_expense +metadata: + unit: list + period: year + label: South Carolina LIHEAP home energy cost sources + reference: + - title: South Carolina FY2026 LIHEAP Detailed Model Plan, item 2.5 + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=9 + - title: "South Carolina 2024 Administrative Guide, home energy bill #page 536-537" + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=536 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/low_income_limit_rate.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/low_income_limit_rate.yaml new file mode 100644 index 00000000000..7ee2326d89b --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/low_income_limit_rate.yaml @@ -0,0 +1,12 @@ +description: South Carolina awards a low-income supplement at or below this share of the household's income limit under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 0.3 +metadata: + unit: /1 + period: year + label: South Carolina LIHEAP low-income limit rate + reference: + - title: "South Carolina FY2026 LIHEAP Detailed Model Plan, items 2.3 and 2.5 #page 8-9" + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8 + - title: "South Carolina draft 2026 LIHEAP Administrative Guide, plan attachment #page 311-312,338" + href: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=311 diff --git a/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/supplement_fuels.yaml b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/supplement_fuels.yaml new file mode 100644 index 00000000000..2f592d03cc4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/supplement_fuels.yaml @@ -0,0 +1,14 @@ +description: South Carolina awards a supplement for these heating fuels under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: + - NATURAL_GAS + - FUEL_OIL + - KEROSENE + - PROPANE +metadata: + unit: list + period: year + label: South Carolina LIHEAP supplement heating fuels + reference: + - title: South Carolina 2026 Benefit Matrix, item 6 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/SC_BenefitMatrix_2026.pdf#page=2 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 13c55a3175a..1cf850d0e10 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -987,7 +987,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: AK, AR, AL, AZ, CO, DC, DE, GA, HI, Riverside County, MA, FL, IL, IA, IN, KS, KY, LA, MD, ME, MN, MO, MS, MT, NC, ND, NE, NH, NJ, NM, NV, NY, OH, OK, OR, PA, SD, RI, TN, TX, UT, VA, VT, WA, WI, WY + coverage: AK, AR, AL, AZ, CO, DC, DE, GA, HI, Riverside County, MA, FL, IL, IA, IN, KS, KY, LA, MD, ME, MN, MO, MS, MT, NC, ND, NE, NH, NJ, NM, NV, NY, OH, OK, OR, PA, SC, SD, RI, TN, TX, UT, VA, VT, WA, WI, WY state_implementations: - state: AL status: partial @@ -1267,6 +1267,14 @@ programs: parameter_prefix: gov.states.or.ohcs.liheap verified_years: "2025-2027" notes: PY2025-PY2027 regular heating only, with the two county regions, five fuel columns and the roomer half payment. Crisis, cooling, Fuel Payment, equipment and OEAP assistance are out of scope. + - state: SC + status: partial + name: South Carolina LIHEAP + full_name: South Carolina Low Income Home Energy Assistance Program + variable: sc_liheap + parameter_prefix: gov.states.sc.oeo.liheap + verified_years: "2026" + notes: FY2026 regular heating base amount with demographic, fuel, low-income and high-burden supplements. Crisis, cooling, weatherization and equipment assistance are out of scope. - state: SD status: partial name: South Dakota LIEAP diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap.yaml new file mode 100644 index 00000000000..d3937e003f6 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap.yaml @@ -0,0 +1,1474 @@ +# Accepted FY 2026 plan: regular heating base 200 and seven supplements, cap 850. +# https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8 +# Matrix used only for named fuels; its conflicting income/burden rules are not used. +# https://liheapch.acf.gov/docs/2026/benefits-matricies/SC_BenefitMatrix_2026.pdf#page=2 +# Agency's explicit LIHEAP household rule counts all income but qualified size. +# https://oeo.sc.gov/managedsites/prd/oeo/documents/WAP%202026%20State%20Plan.pdf#page=23 +# OEO's 2024 guide limits supplements to eligible members and prorates mixed-status awards. +# https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=537 +# Its draft 2026 guide measures the plan's 30% low-income tier against the 60% limit. +# These are annual state-schedule awards, before unmodeled local funding discretion. + +- name: Case 1, source base and combined low-income high-burden examples. + period: 2026 + # 40_000 income and 4_000 electric cost give only base 200. At 15_000 income, + # low-income 175 applies and 3_000/15_000=20% adds burden 175: total 550. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 40_000 + person2: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person3: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person4: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 15_000 + person6: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person7: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person8: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2, person3, person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 4_000 + spm_unit2: + members: [person5, person6, person7, person8] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 3_000 + households: + household1: + members: [person1, person2, person3, person4] + state_code: SC + household2: + members: [person5, person6, person7, person8] + state_code: SC + output: + sc_liheap_household_size: [4, 4] + sc_liheap_countable_income: [40_000, 15_000] + sc_liheap_income_limit: [61_525, 61_525] + sc_liheap_eligible: [true, true] + sc_liheap: [200, 550] + +- name: Case 2, thirty percent of the income limit is the supplement boundary. + period: 2026 + absolute_error_margin: 0.01 + # Four-person limit 61_525 x 30% = 18_457.50. At or below the boundary add 175 + # to base 200; a cent above receives only 200, which rejects both 30% of the full + # SMI (30_762.60) and the older matrix's 70% of the limit (43_067.50). + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 18_457.49 + person2: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person3: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person4: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 18_457.5 + person6: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person7: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person8: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person9: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 18_457.51 + person10: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person11: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person12: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2, person3, person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person5, person6, person7, person8] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit3: + members: [person9, person10, person11, person12] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2, person3, person4] + state_code: SC + household2: + members: [person5, person6, person7, person8] + state_code: SC + household3: + members: [person9, person10, person11, person12] + state_code: SC + output: + sc_liheap: [375, 375, 200] + +- name: Case 3, twenty-percent burden sums energy bills and includes equality. + period: 2026 + # Gas 500 + electric 3_499/3_500/3_501 gives costs 3_999/4_000/4_001. + # At income 20_000,20%=4_000. Base 200+gas-fuel 75 gains burden 175 at equality. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 500 + pre_subsidy_electricity_expense: 3_499 + spm_unit2: + members: [person2] + heating_type: NATURAL_GAS + gas_expense: 500 + pre_subsidy_electricity_expense: 3_500 + spm_unit3: + members: [person3] + heating_type: NATURAL_GAS + gas_expense: 500 + pre_subsidy_electricity_expense: 3_501 + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2] + state_code: SC + household3: + members: [person3] + state_code: SC + output: + sc_liheap: [275, 450, 450] + +- name: Case 4, nonenergy utility bills do not establish home-energy burden. + period: 2026 + # Home energy 1_000/20_000=5%. Water, trash and phone bills do not earn 175. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + water_expense: 5_000 + trash_expense: 2_000 + phone_expense: 2_000 + households: + household1: + members: [person1] + state_code: SC + output: + sc_liheap: 200 + +- name: Case 5, named supplement fuels and other heating fuels are distinguished. + period: 2026 + # Matrix page 2 names gas, oil/kerosene and propane for 75. Every scenario has + # its actual matching bill 1_000 and income 20_000, so no low-income/burden + # supplement applies. Other represented heating fuels receive the base 200. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person6: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person7: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person8: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person9: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + spm_unit2: + members: [person2] + heating_type: FUEL_OIL + fuel_oil_expense: 1_000 + spm_unit3: + members: [person3] + heating_type: KEROSENE + fuel_oil_expense: 1_000 + spm_unit4: + members: [person4] + heating_type: PROPANE + bottled_gas_expense: 1_000 + spm_unit5: + members: [person5] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit6: + members: [person6] + heating_type: WOOD + wood_expense: 1_000 + spm_unit7: + members: [person7] + heating_type: COAL + coal_expense: 1_000 + spm_unit8: + members: [person8] + heating_type: SOLAR + pre_subsidy_electricity_expense: 1_000 + spm_unit9: + members: [person9] + heating_type: OTHER + other_heating_fuel_expense: 1_000 + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2] + state_code: SC + household3: + members: [person3] + state_code: SC + household4: + members: [person4] + state_code: SC + household5: + members: [person5] + state_code: SC + household6: + members: [person6] + state_code: SC + household7: + members: [person7] + state_code: SC + household8: + members: [person8] + state_code: SC + household9: + members: [person9] + state_code: SC + output: + sc_liheap: [275, 275, 275, 275, 200, 200, 200, 200, 200] + +- name: Case 6, age disability and veteran supplements apply once per category. + period: 2026 + # Two-person income 30_000 exceeds its 12_551.10 low-income level and is below + # 41_837. + # Base 200 gains 75 at age 60; 50 for child <= 5, any disabled member, or any + # veteran. Two veterans still earn a single 50 supplement. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 30_000 + person2: + age: 59 + is_citizen_or_legal_immigrant: true + ssi: 0 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 30_000 + person4: + age: 60 + is_citizen_or_legal_immigrant: true + ssi: 0 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 30_000 + person6: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person7: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 30_000 + person8: + age: 6 + is_citizen_or_legal_immigrant: true + ssi: 0 + person9: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 30_000 + person10: + age: 8 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_disabled: true + person11: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 30_000 + person12: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_disabled: true + person13: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 30_000 + person14: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_veteran: true + person15: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 30_000 + is_veteran: true + person16: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_veteran: true + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person3, person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit3: + members: [person5, person6] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit4: + members: [person7, person8] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit5: + members: [person9, person10] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit6: + members: [person11, person12] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit7: + members: [person13, person14] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit8: + members: [person15, person16] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2] + state_code: SC + household2: + members: [person3, person4] + state_code: SC + household3: + members: [person5, person6] + state_code: SC + household4: + members: [person7, person8] + state_code: SC + household5: + members: [person9, person10] + state_code: SC + household6: + members: [person11, person12] + state_code: SC + household7: + members: [person13, person14] + state_code: SC + household8: + members: [person15, person16] + state_code: SC + output: + sc_liheap: [200, 275, 250, 200, 250, 250, 250, 250] + +- name: Case 7, all supplements total eight hundred fifty without multiplying people. + period: 2026 + # 200 base+75 elderly+50 disabled+50 young child+175 low income + # +175 high burden+75 propane+50 veteran=850. Repeated vulnerable members + # do not multiply categories. Negative net income cannot exceed the 850 cap. + input: + people: + person1: + age: 65 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 18_000 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_disabled: true + is_veteran: true + person3: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person4: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person5: + age: 65 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 18_000 + person6: + age: 60 + is_citizen_or_legal_immigrant: true + ssi: 0 + person7: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_disabled: true + is_veteran: true + person8: + age: 38 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_disabled: true + is_veteran: true + person9: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person10: + age: 4 + is_citizen_or_legal_immigrant: true + ssi: 0 + person11: + age: 65 + is_citizen_or_legal_immigrant: true + ssi: 0 + self_employment_income: -1_000_000 + person12: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_disabled: true + is_veteran: true + person13: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person14: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2, person3, person4] + heating_type: PROPANE + bottled_gas_expense: 6_000 + spm_unit2: + members: [person5, person6, person7, person8, person9, person10] + heating_type: PROPANE + bottled_gas_expense: 6_000 + spm_unit3: + members: [person11, person12, person13, person14] + heating_type: PROPANE + bottled_gas_expense: 6_000 + households: + household1: + members: [person1, person2, person3, person4] + state_code: SC + household2: + members: [person5, person6, person7, person8, person9, person10] + state_code: SC + household3: + members: [person11, person12, person13, person14] + state_code: SC + output: + sc_liheap: [850, 850, 850] + +- name: Case 8, nonqualified residents earn no supplement and the award is prorated. + period: 2026 + # Qualified size is one for each threshold. The 2024 guide counts only eligible + # members for the supplements, so the nonqualified elder, child, disabled person + # and veteran add nothing: base 200 / 2 members x 1 eligible member = 100. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person2: + age: 60 + is_citizen_or_legal_immigrant: false + ssi: 0 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person4: + age: 5 + is_citizen_or_legal_immigrant: false + ssi: 0 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person6: + age: 40 + is_citizen_or_legal_immigrant: false + ssi: 0 + is_disabled: true + person7: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person8: + age: 40 + is_citizen_or_legal_immigrant: false + ssi: 0 + is_veteran: true + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person3, person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit3: + members: [person5, person6] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit4: + members: [person7, person8] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2] + state_code: SC + household2: + members: [person3, person4] + state_code: SC + household3: + members: [person5, person6] + state_code: SC + household4: + members: [person7, person8] + state_code: SC + output: + sc_liheap_household_size: [1, 1, 1, 1] + sc_liheap_countable_income: [20_000, 20_000, 20_000, 20_000] + sc_liheap_income_limit: [31_993, 31_993, 31_993, 31_993] + sc_liheap: [100, 100, 100, 100] + +- name: Case 9, all resident income is compared with qualified-size limits. + period: 2026 + # Qualified child gives size one and ceiling 31_993. Parent income 30_000 + # qualifies: 200 base + 50 child + 75 gas = 325, / 2 members x 1 eligible = 162.50. + # Parent income 33_000 fails; an all-nonqualified household also receives zero. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + employment_income: 30_000 + person2: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person3: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + employment_income: 33_000 + person4: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person5: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + spm_unit2: + members: [person3, person4] + heating_type: NATURAL_GAS + gas_expense: 1_000 + spm_unit3: + members: [person5] + heating_type: NATURAL_GAS + gas_expense: 1_000 + households: + household1: + members: [person1, person2] + state_code: SC + household2: + members: [person3, person4] + state_code: SC + household3: + members: [person5] + state_code: SC + output: + sc_liheap_household_size: [1, 1, 0] + sc_liheap_countable_income: [30_000, 33_000, 0] + sc_liheap_eligible: [true, false, false] + sc_liheap: [162.5, 0, 0] + +- name: Case 10, housing treatment and low bills do not create an expense cap. + period: 2026 + # Base 200 can exceed the actual 100 bill; housing subsidy does not exclude. + # Heat in rent permits aid without a separately quantified bill; known gas + # still adds 75. Zero income with unmeasured rent heat gets low-income 175, + # but zero measured energy cost does not prove burden. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 100 + spm_unit2: + members: [person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 100 + receives_housing_assistance: true + spm_unit3: + members: [person3] + heating_type: UNSPECIFIED + heat_expense_included_in_rent: true + receives_housing_assistance: true + spm_unit4: + members: [person4] + heating_type: NATURAL_GAS + gas_expense: 0 + heat_expense_included_in_rent: true + spm_unit5: + members: [person5] + heating_type: UNSPECIFIED + heat_expense_included_in_rent: true + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2] + state_code: SC + household3: + members: [person3] + state_code: SC + household4: + members: [person4] + state_code: SC + household5: + members: [person5] + state_code: SC + output: + sc_liheap: [200, 200, 200, 275, 375] + +- name: Case 11, a home with no energy bill and other states receive zero. + period: 2026 + # Eligible SC gas heating earns 200+75; the same NC unit is state-guarded. + # NONE with no bill has no obligation to pay. An electric bill qualifies a gas-heated + # home with no gas bill: 200 + 175 low income + 175 burden on no income + 75 fuel = 625. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + spm_unit2: + members: [person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + spm_unit3: + members: [person3] + heating_type: NONE + spm_unit4: + members: [person4] + heating_type: NATURAL_GAS + gas_expense: 0 + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2] + state_code: NC + household3: + members: [person3] + state_code: SC + household4: + members: [person4] + state_code: SC + output: + sc_liheap: [275, 0, 0, 625] + +# Recurring payments are countable; this does not represent a one-time withdrawal. +# Income 40,000 exceeds the one-person 31,993 ceiling, so the award is 0. +- name: Case 12, recurring IRA payments above the income ceiling. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person: + age: 70 + immigration_status: CITIZEN + # Isolate recurring retirement receipts; no SSI is received. + ssi: 0 + taxable_ira_distributions: 40000 + spm_units: + spm_unit: + members: [person] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household: + members: [person] + state_code: SC + output: + sc_liheap_countable_income: 40000 + sc_liheap: 0 + +# Recurring payments are countable; this does not represent a one-time withdrawal. +# Income 12,000 exceeds the one-person 9,597.90 low-income level: 200 base + 75 +# elderly = 275. The 1,000 annual bill is below 20 percent, so no burden supplement +# applies. +- name: Case 13, recurring IRA payments without high energy burden. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person: + age: 70 + immigration_status: CITIZEN + # Isolate recurring retirement receipts; no SSI is received. + ssi: 0 + taxable_ira_distributions: 12000 + spm_units: + spm_unit: + members: [person] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household: + members: [person] + state_code: SC + output: + sc_liheap_countable_income: 12000 + sc_liheap: 275 + +# Military retirement is a separate receipt; a rental loss cannot cancel a 33,000 +# pension. The last two rows are existing-aggregate unemployment controls because +# there is no SC state unemployment model. Reported unemployment replaces the +# fallback, never adds to it. Every row exceeds the one-person 31,993 ceiling. +- name: Case 14, distinct received income prevents excess regular awards. + period: 2026 + input: + state_code: [SC, SC, SC, SC] + age: [55, 55, 35, 35] + is_citizen_or_legal_immigrant: [true, true, true, true] + ssi: [0, 0, 0, 0] + military_retirement_pay: [40_000, 0, 0, 0] + is_veteran: [true, false, false, false] + taxable_pension_income: [0, 33_000, 0, 0] + rental_income: [0, -10_000, 0, 0] + unemployment_compensation: [0, 0, 0, 45_000] + modeled_state_unemployment_compensation: [0, 0, 40_000, 40_000] + heating_type: [ELECTRICITY, ELECTRICITY, ELECTRICITY, ELECTRICITY] + pre_subsidy_electricity_expense: [1_000, 1_000, 1_000, 1_000] + output: + sc_liheap_countable_income: [40_000, 33_000, 40_000, 45_000] + sc_liheap_income_limit: [31_993, 31_993, 31_993, 31_993] + sc_liheap_eligible: [false, false, false, false] + sc_liheap: [0, 0, 0, 0] + +# Age five and under includes 5.5 until the sixth birthday. With two qualified +# members, 30,000 income is above the 12,551.10 low-income level but below the +# 41,837 ceiling. Electric 1,000 is below the 20% burden and has no fuel supplement: +# 200 base + 50 child = +# 250; the same household at age 6 receives 200. +- name: Case 15, the young-child supplement lasts until the sixth birthday. + period: 2026 + input: + people: + person1: {age: 35, employment_income: 30_000, is_citizen_or_legal_immigrant: true, ssi: 0} + person2: {age: 5.5, is_citizen_or_legal_immigrant: true, ssi: 0} + person3: {age: 35, employment_income: 30_000, is_citizen_or_legal_immigrant: true, ssi: 0} + person4: {age: 6, is_citizen_or_legal_immigrant: true, ssi: 0} + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person3, person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + tax_units: + tax_unit1: {members: [person1, person2]} + tax_unit2: {members: [person3, person4]} + households: + household1: {members: [person1, person2], state_code: SC} + household2: {members: [person3, person4], state_code: SC} + output: + sc_liheap_household_size: [2, 2] + sc_liheap_countable_income: [30_000, 30_000] + sc_liheap_income_limit: [41_837, 41_837] + sc_liheap_eligible: [true, true] + sc_liheap: [250, 200] + +# Qualified size 25 uses the 2025 FPG 15,650 + 24 x 5,500 = 147,650. The strict +# 110% floor of 162,415 protects 150,000 income above the ordinary SMI limit of +# 116,282. No vulnerable member, veteran, fuel or burden supplement applies, and +# income exceeds 34,884.60, 30% of the limit: base 200 is the award. Exactly 162,415 +# is unprotected. +- name: Case 16, large households retain strict federal income protection. + period: 2026 + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 150_000 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person6: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person7: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person8: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person9: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person10: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person11: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person12: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person13: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person14: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person15: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person16: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person17: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person18: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person19: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person20: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person21: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person22: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person23: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person24: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person25: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person26: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 162_415 + person27: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person28: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person29: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person30: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person31: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person32: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person33: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person34: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person35: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person36: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person37: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person38: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person39: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person40: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person41: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person42: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person43: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person44: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person45: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person46: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person47: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person48: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person49: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person50: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16, person17, person18, person19, person20, person21, person22, person23, person24, person25] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person26, person27, person28, person29, person30, person31, person32, person33, person34, person35, person36, person37, person38, person39, person40, person41, person42, person43, person44, person45, person46, person47, person48, person49, person50] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + tax_units: + tax_unit1: {members: [person1]} + tax_unit2: {members: [person2]} + tax_unit3: {members: [person3]} + tax_unit4: {members: [person4]} + tax_unit5: {members: [person5]} + tax_unit6: {members: [person6]} + tax_unit7: {members: [person7]} + tax_unit8: {members: [person8]} + tax_unit9: {members: [person9]} + tax_unit10: {members: [person10]} + tax_unit11: {members: [person11]} + tax_unit12: {members: [person12]} + tax_unit13: {members: [person13]} + tax_unit14: {members: [person14]} + tax_unit15: {members: [person15]} + tax_unit16: {members: [person16]} + tax_unit17: {members: [person17]} + tax_unit18: {members: [person18]} + tax_unit19: {members: [person19]} + tax_unit20: {members: [person20]} + tax_unit21: {members: [person21]} + tax_unit22: {members: [person22]} + tax_unit23: {members: [person23]} + tax_unit24: {members: [person24]} + tax_unit25: {members: [person25]} + tax_unit26: {members: [person26]} + tax_unit27: {members: [person27]} + tax_unit28: {members: [person28]} + tax_unit29: {members: [person29]} + tax_unit30: {members: [person30]} + tax_unit31: {members: [person31]} + tax_unit32: {members: [person32]} + tax_unit33: {members: [person33]} + tax_unit34: {members: [person34]} + tax_unit35: {members: [person35]} + tax_unit36: {members: [person36]} + tax_unit37: {members: [person37]} + tax_unit38: {members: [person38]} + tax_unit39: {members: [person39]} + tax_unit40: {members: [person40]} + tax_unit41: {members: [person41]} + tax_unit42: {members: [person42]} + tax_unit43: {members: [person43]} + tax_unit44: {members: [person44]} + tax_unit45: {members: [person45]} + tax_unit46: {members: [person46]} + tax_unit47: {members: [person47]} + tax_unit48: {members: [person48]} + tax_unit49: {members: [person49]} + tax_unit50: {members: [person50]} + households: + household1: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16, person17, person18, person19, person20, person21, person22, person23, person24, person25] + state_code: SC + household2: + members: [person26, person27, person28, person29, person30, person31, person32, person33, person34, person35, person36, person37, person38, person39, person40, person41, person42, person43, person44, person45, person46, person47, person48, person49, person50] + state_code: SC + output: + sc_liheap_household_size: [25, 25] + sc_liheap_countable_income: [150_000, 162_415] + sc_liheap_income_limit: [116_282, 116_282] + sc_liheap_eligible: [true, false] + sc_liheap: [200, 0] + +- name: Case 17, heating fuel bills reach the burden supplement and cooking fuel does not. + period: 2026 + # At income 20_000, 20% = 4_000 and the one-person low-income level is 9_597.90. + # Fuel oil: 200 + 75 fuel + 175 burden = 450. Wood, coal and other fuel: 200 + 175 + # = 375. Electric 3_000 plus cooking fuel 1_000 stays below 4_000: 200. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: FUEL_OIL + fuel_oil_expense: 4_000 + spm_unit2: + members: [person2] + heating_type: WOOD + wood_expense: 4_000 + spm_unit3: + members: [person3] + heating_type: COAL + coal_expense: 4_000 + spm_unit4: + members: [person4] + heating_type: OTHER + other_heating_fuel_expense: 4_000 + spm_unit5: + members: [person5] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 3_000 + cooking_fuel_expense: 1_000 + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2] + state_code: SC + household3: + members: [person3] + state_code: SC + household4: + members: [person4] + state_code: SC + household5: + members: [person5] + state_code: SC + output: + sc_liheap: [450, 375, 375, 375, 200] + +- name: Case 18, state-placed foster children are not household members. + period: 2026 + # Each foster child is left out of size, income and the supplements, so both + # adults are one-person households with the 31_993 ceiling. Wages 35_000 fail + # the ceiling. Wages 20_000 pass, the disabled child's 10_000 survivor benefits + # do not count, and neither child supplement applies: 200 + 75 gas = 275. The + # child also leaves the proration count, so one eligible of one member keeps 275. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 35_000 + person2: + age: 3 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_in_foster_care: + 2026-01: true + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person4: + age: 3 + is_citizen_or_legal_immigrant: true + ssi: 0 + is_disabled: true + social_security_survivors: 10_000 + is_in_foster_care: + 2026-01: true + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + spm_unit2: + members: [person3, person4] + heating_type: NATURAL_GAS + gas_expense: 1_000 + households: + household1: + members: [person1, person2] + state_code: SC + household2: + members: [person3, person4] + state_code: SC + output: + sc_liheap_household_size: [1, 1] + sc_liheap_countable_income: [35_000, 20_000] + sc_liheap_income_limit: [31_993, 31_993] + sc_liheap_eligible: [false, true] + sc_liheap: [0, 275] + +- name: Case 19, the 2024 guide's prorated example pays eligible members only. + period: 2026 + # Guide page 537: 425 / 4 members = 106.25, x 3 eligible = 318.75. Here 200 base + + # 50 child + 175 low income = 425. The nonqualified adult's 15_000 wages count and + # stay below the three-person low-income level of 15_504.30; 1_000 is under 20%. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + employment_income: 15_000 + person2: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person3: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person4: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2, person3, person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2, person3, person4] + state_code: SC + output: + sc_liheap_household_size: 3 + sc_liheap_countable_income: 15_000 + sc_liheap_income_limit: 51_681 + sc_liheap: 318.75 + +- name: Case 20, an electric bill pays a home without heating or with gathered wood. + period: 2026 + # OEO asks for an obligation to pay a home energy bill. 20_000 is above the low-income + # tier, 1_000 is under 20% of it, and neither fuel earns the supplement: base 200. + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: NONE + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person2] + heating_type: WOOD + wood_expense: 0 + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2] + state_code: SC + output: + sc_liheap: [200, 200] diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_countable_income.yaml new file mode 100644 index 00000000000..ba77d66d69c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_countable_income.yaml @@ -0,0 +1,356 @@ +# Accepted FY 2026 plan checks selected income streams and excludes minor earnings. +# https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=5 +# OEO's 2024 guide counts only Social Security or disability income under age 18. +# https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=529 +# Annual flows approximate application-month income; monthly SSI is summed once. + +- name: Case 1, earnings count at eighteen while a minor's Social Security still counts. + period: 2026 + absolute_error_margin: 0.01 + # Age 17 wages 12_000 are excluded but survivor Social Security 1_000 counts. + # At 18 the same wages count: 10_000+1_000=11_000 versus 23_000. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 10_000 + person2: + age: 17 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 12_000 + social_security_survivors: 1_000 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 10_000 + person4: + age: 18 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 12_000 + social_security_survivors: 1_000 + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person3, person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2] + state_code: SC + household2: + members: [person3, person4] + state_code: SC + output: + sc_liheap_countable_income: [11_000, 23_000] + +- name: Case 2, adult net business receipts and wages remain disjoint. + period: 2026 + absolute_error_margin: 0.01 + # 12_000 wages +500 military basic pay +2_000 net business +300 SSTB +700 farm + # +1_000 partnership =16_500. Existing business receipts are already net of expenses. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 12_000 + military_basic_pay: 500 + self_employment_income: 2_000 + sstb_self_employment_income: 300 + farm_operations_income: 700 + partnership_s_corp_income: 1_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1] + state_code: SC + output: + sc_liheap_countable_income: 16_500 + +- name: Case 3, pension Social Security survivor rental and gift receipts enter once. + period: 2026 + absolute_error_margin: 0.01 + # Pension 3_000 + Social Security 2_000 + other survivor 700 + rent 3_000 + # + unemployment 1_000 + alimony 400 + support 500 + VA 800 + gifts 600 + # + Optional State Supplementation 1_200 =13_200. + # Neither pension nor Social Security subcomponents are counted twice. + input: + people: + person1: + age: 65 + is_citizen_or_legal_immigrant: true + ssi: 0 + taxable_pension_income: 2_000 + tax_exempt_pension_income: 1_000 + social_security_retirement: 500 + social_security_disability: 300 + social_security_survivors: 1_000 + social_security_dependents: 200 + survivor_benefits: 700 + rental_income: 1_800 + farm_rent_income: 1_200 + unemployment_compensation: 1_000 + alimony_income: 400 + child_support_received: 500 + veterans_benefits: 800 + financial_assistance: 600 + sc_ssi_state_supplement: 1_200 + spm_units: + spm_unit1: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1] + state_code: SC + output: + sc_liheap_countable_income: 13_200 + +- name: Case 4, unchecked income types and assets do not inflate countable income. + period: 2026 + absolute_error_margin: 0.01 + # Only the 1_000 wages count. Plan page 6 leaves interest/dividends, GA, TANF, + # strike pay, lottery lump sums, direct insurance and asset balances unchecked. + # SNAP is not cash income. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 1_000 + interest_income: 5_000 + ordinary_dividend_income: 5_000 + general_assistance: 500 + strike_benefits: 600 + gambling_winnings: 700 + life_insurance_benefits: 800 + spm_units: + spm_unit1: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + sc_tanf: 3_600 + snap: 3_600 + spm_unit_assets: 500_000 + households: + household1: + members: [person1] + state_code: SC + output: + sc_liheap_countable_income: 1_000 + +- name: Case 5, nonuniform SSI for an adult and child is annualized once. + period: 2026 + absolute_error_margin: 0.01 + # Adult SSI=6*100+6*200=1_800; child SSI=6*50+6*100=900. + # Annual countable income=2_700, with matching explicit monthly keys. + input: + people: + person1: + age: 65 + is_citizen_or_legal_immigrant: true + ssi: + 2026-01: 100 + 2026-02: 100 + 2026-03: 100 + 2026-04: 100 + 2026-05: 100 + 2026-06: 100 + 2026-07: 200 + 2026-08: 200 + 2026-09: 200 + 2026-10: 200 + 2026-11: 200 + 2026-12: 200 + person2: + age: 8 + is_citizen_or_legal_immigrant: true + ssi: + 2026-01: 50 + 2026-02: 50 + 2026-03: 50 + 2026-04: 50 + 2026-05: 50 + 2026-06: 50 + 2026-07: 100 + 2026-08: 100 + 2026-09: 100 + 2026-10: 100 + 2026-11: 100 + 2026-12: 100 + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2] + state_code: SC + output: + sc_liheap_countable_income: 2_700 + +- name: Case 6, nonqualified adult income counts and other state components remain zero. + period: 2026 + absolute_error_margin: 0.01 + # Nonqualified adult earnings 20_000 remain in household income. Negative net + # resources alone do not produce negative countable income. NC has no SC amount. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + employment_income: 20_000 + person2: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + self_employment_income: -2_000 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person3] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit3: + members: [person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2] + state_code: SC + household2: + members: [person3] + state_code: SC + household3: + members: [person4] + state_code: NC + output: + sc_liheap_countable_income: [20_000, 0, 0] + +# Pension 1,000 + taxable recurring IRA 12,000 + exempt recurring IRA 3,000 = 16,000. +# These disjoint aggregates enter once; no one-time lump sum is supplied. +- name: Case 7, recurring retirement account subtypes count beside pension income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person: + age: 70 + immigration_status: CITIZEN + ssi: 0 + pension_income: 1_000 + taxable_ira_distributions: 12_000 + tax_exempt_ira_distributions: 3_000 + spm_units: + spm_unit: + members: [person] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household: + members: [person] + state_code: SC + output: + sc_liheap_countable_income: 16_000 + +# Plan item 1.9 counts retirement and pension benefits: railroad retirement 6,000. +- name: Case 8, railroad retirement counts as a retirement benefit. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person: + age: 60 + immigration_status: CITIZEN + ssi: 0 + railroad_benefits: 6_000 + spm_units: + spm_unit: + members: [person] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household: + members: [person] + state_code: SC + output: + sc_liheap_countable_income: 6_000 + +# 2024 guide: under 18, only Social Security or disability income counts. The child's +# 1,000 survivors + 1,200 SSI + 500 disability count with the adult's 10,000 wages: +# 12,700. The child's pension, child support and other survivor benefits do not. The +# adult's 500 of disability benefits has no plan 1.9 box, so that unit stays at 10,000. +- name: Case 9, a minor counts only Social Security SSI and disability income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 10_000 + person2: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 1_200 + social_security_survivors: 1_000 + disability_benefits: 500 + pension_income: 700 + child_support_received: 400 + survivor_benefits: 300 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 10_000 + disability_benefits: 500 + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person3] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2] + state_code: SC + household2: + members: [person3] + state_code: SC + output: + sc_liheap_countable_income: [12_700, 10_000] diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_eligible.yaml new file mode 100644 index 00000000000..0c26d04ece2 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_eligible.yaml @@ -0,0 +1,323 @@ +# Accepted plan has no categorical/asset or additional renter exclusions. +# https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=5 +# Current agency annual limits and demonstrated energy-need requirement. +# https://oeo.sc.gov/managedsites/prd/oeo/liheap.html +# OEO's 2024 guide asks for an obligation to pay a home energy bill. +# https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=536 +# These exact Boolean cases intentionally have no absolute_error_margin. + +- name: Case 1, annual published income ceiling is inclusive. + period: 2026 + # Four-person published ceiling is 61_525. That amount qualifies, but a cent + # above does not. This also distinguishes the floored ceiling from 61_525.20. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 61_524 + person2: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person3: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person4: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 61_525 + person6: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person7: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person8: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person9: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 61_525.01 + person10: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person11: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person12: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person13: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 61_526 + person14: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person15: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person16: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2, person3, person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person5, person6, person7, person8] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit3: + members: [person9, person10, person11, person12] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit4: + members: [person13, person14, person15, person16] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2, person3, person4] + state_code: SC + household2: + members: [person5, person6, person7, person8] + state_code: SC + household3: + members: [person9, person10, person11, person12] + state_code: SC + household4: + members: [person13, person14, person15, person16] + state_code: SC + output: + sc_liheap_eligible: [true, true, false, false] + +- name: Case 2, any counted energy bill or heat in rent shows the obligation to pay. + period: 2026 + # An electric bill qualifies a gas-heated home with no gas bill, a home without + # heating and a home heating with gathered wood. NONE with no bill has no obligation. + # Heat in rent qualifies without a separately measured bill; housing subsidy does not + # exclude. UNSPECIFIED with a bill and no heat in rent gets nothing: heating_type is + # a required input. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person5: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person6: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person7: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person8: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person9: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 0 + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + spm_unit3: + members: [person3] + heating_type: NONE + spm_unit4: + members: [person4] + heating_type: NONE + heat_expense_included_in_rent: true + spm_unit5: + members: [person5] + heating_type: UNSPECIFIED + heat_expense_included_in_rent: true + receives_housing_assistance: true + spm_unit6: + members: [person6] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + receives_housing_assistance: true + spm_unit7: + members: [person7] + heating_type: UNSPECIFIED + pre_subsidy_electricity_expense: 1_000 + spm_unit8: + members: [person8] + heating_type: NONE + pre_subsidy_electricity_expense: 1_000 + spm_unit9: + members: [person9] + heating_type: WOOD + wood_expense: 0 + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2] + state_code: SC + household3: + members: [person3] + state_code: SC + household4: + members: [person4] + state_code: SC + household5: + members: [person5] + state_code: SC + household6: + members: [person6] + state_code: SC + household7: + members: [person7] + state_code: SC + household8: + members: [person8] + state_code: SC + household9: + members: [person9] + state_code: SC + output: + sc_liheap_eligible: [true, true, false, true, true, true, false, true, true] + +- name: Case 3, cash program receipt does not override income and assets do not bar aid. + period: 2026 + # First income=106_000, above 31_993 even with SSI/SNAP/TANF receipt. + # The second has eligible income 20_000; no asset test applies. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 6_000 + employment_income: 100_000 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + sc_tanf: 3_600 + snap: 3_600 + spm_unit2: + members: [person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit_assets: 1_000_000 + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2] + state_code: SC + output: + sc_liheap_eligible: [false, true] + +- name: Case 4, zero qualified size and residence prevent eligibility. + period: 2026 + # A positive actual heating bill cannot qualify an all-nonqualified household + # or a nonresident. The comparable qualified SC resident qualifies. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + person3: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 20_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit3: + members: [person3] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2] + state_code: SC + household3: + members: [person3] + state_code: NC + output: + sc_liheap_eligible: [false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_household_size.yaml new file mode 100644 index 00000000000..9328c8979c1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_household_size.yaml @@ -0,0 +1,78 @@ +# Approved agency plan expressly attributes this household rule to LIHEAP. +# https://oeo.sc.gov/managedsites/prd/oeo/documents/WAP%202026%20State%20Plan.pdf#page=23 +# Only its LIHEAP attribution is used; no WAP income or benefit rules are borrowed. + +- name: Case 1, qualified members determine size independently of all resident income. + period: 2026 + # Three residents with two nonqualified adults leave one qualified child. + # All-qualified size is two; zero qualified residents and another state give zero. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + person2: + age: 32 + is_citizen_or_legal_immigrant: false + ssi: 0 + person3: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person5: + age: 32 + is_citizen_or_legal_immigrant: true + ssi: 0 + person6: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + person7: + age: 60 + is_citizen_or_legal_immigrant: false + ssi: 0 + person8: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + person9: + age: 32 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2, person3] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person4, person5] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit3: + members: [person6, person7] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit4: + members: [person8, person9] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2, person3] + state_code: SC + household2: + members: [person4, person5] + state_code: SC + household3: + members: [person6, person7] + state_code: SC + household4: + members: [person8, person9] + state_code: NC + output: + sc_liheap_household_size: [1, 2, 0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_income_limit.yaml new file mode 100644 index 00000000000..c77c6622d6f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/oeo/liheap/sc_liheap_income_limit.yaml @@ -0,0 +1,291 @@ +# Current agency table publishes all eight annual income ceilings below. +# https://oeo.sc.gov/managedsites/prd/oeo/liheap.html +# Annual figures govern; the inconsistent one-person monthly figure is not used. +# Tests verify the published values without treating inferred rounding as law. + +- name: Case 1, all eight agency annual ceilings use actual qualified household sizes. + period: 2026 + absolute_error_margin: 0.01 + # Agency annual rows for sizes one through eight are transcribed independently. + # The seventh and eighth rows distinguish the published schedule from rounding + # the unrounded federal SMI threshold only at the final step. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 0 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 0 + person3: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 0 + person5: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person6: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person7: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 0 + person8: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person9: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person10: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person11: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 0 + person12: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person13: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person14: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person15: + age: 14 + is_citizen_or_legal_immigrant: true + ssi: 0 + person16: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 0 + person17: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person18: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person19: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person20: + age: 14 + is_citizen_or_legal_immigrant: true + ssi: 0 + person21: + age: 16 + is_citizen_or_legal_immigrant: true + ssi: 0 + person22: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 0 + person23: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person24: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person25: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person26: + age: 14 + is_citizen_or_legal_immigrant: true + ssi: 0 + person27: + age: 16 + is_citizen_or_legal_immigrant: true + ssi: 0 + person28: + age: 18 + is_citizen_or_legal_immigrant: true + ssi: 0 + person29: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 0 + person30: + age: 33 + is_citizen_or_legal_immigrant: true + ssi: 0 + person31: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + person32: + age: 12 + is_citizen_or_legal_immigrant: true + ssi: 0 + person33: + age: 14 + is_citizen_or_legal_immigrant: true + ssi: 0 + person34: + age: 16 + is_citizen_or_legal_immigrant: true + ssi: 0 + person35: + age: 18 + is_citizen_or_legal_immigrant: true + ssi: 0 + person36: + age: 20 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person2, person3] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit3: + members: [person4, person5, person6] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit4: + members: [person7, person8, person9, person10] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit5: + members: [person11, person12, person13, person14, person15] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit6: + members: [person16, person17, person18, person19, person20, person21] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit7: + members: [person22, person23, person24, person25, person26, person27, person28] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit8: + members: + - person29 + - person30 + - person31 + - person32 + - person33 + - person34 + - person35 + - person36 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1] + state_code: SC + household2: + members: [person2, person3] + state_code: SC + household3: + members: [person4, person5, person6] + state_code: SC + household4: + members: [person7, person8, person9, person10] + state_code: SC + household5: + members: [person11, person12, person13, person14, person15] + state_code: SC + household6: + members: [person16, person17, person18, person19, person20, person21] + state_code: SC + household7: + members: [person22, person23, person24, person25, person26, person27, person28] + state_code: SC + household8: + members: + - person29 + - person30 + - person31 + - person32 + - person33 + - person34 + - person35 + - person36 + state_code: SC + output: + sc_liheap_income_limit: [31_993, 41_837, 51_681, 61_525, 71_369, 81_213, 83_058, 84_904] + +- name: Case 2, mixed status reduces the threshold and zero qualified size is guarded. + period: 2026 + absolute_error_margin: 0.01 + # One qualified child uses the one-person annual ceiling, without counting + # the nonqualified parent in size. No qualified residents gives zero. + input: + people: + person1: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + person2: + age: 5 + is_citizen_or_legal_immigrant: true + ssi: 0 + person3: + age: 35 + is_citizen_or_legal_immigrant: false + ssi: 0 + person4: + age: 35 + is_citizen_or_legal_immigrant: true + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit2: + members: [person3] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + spm_unit3: + members: [person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + households: + household1: + members: [person1, person2] + state_code: SC + household2: + members: [person3] + state_code: SC + household3: + members: [person4] + state_code: NC + output: + sc_liheap_household_size: [1, 0, 0] + sc_liheap_income_limit: [31_993, 0, 0] diff --git a/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap.py b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap.py new file mode 100644 index 00000000000..9b0490bab01 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap.py @@ -0,0 +1,64 @@ +from policyengine_us.model_api import * + + +class sc_liheap(Variable): + value_type = float + entity = SPMUnit + label = "South Carolina LIHEAP regular heating assistance" + unit = USD + definition_period = YEAR + defined_for = "sc_liheap_eligible" + reference = ( + # PDF pages 8-9 + "https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8", + "https://liheapch.acf.gov/docs/2026/benefits-matricies/SC_BenefitMatrix_2026.pdf#page=2", + # PDF pages 311-312,338,529,537,546 + "https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=311", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.sc.oeo.liheap.payment + income = spm_unit("sc_liheap_countable_income", period) + size = spm_unit("sc_liheap_household_size", period) + # The accepted plan's 30% governs over the older matrix's 70%. Both are shares + # of the income limit: OEO's draft guide writes "30 of 60 percent of the SMI" + # and "SMI is 60% of the State's Median Income". + limit = spm_unit("sc_liheap_income_limit", period) + low_income = income <= p.low_income_limit_rate * limit + person = spm_unit.members + age = person("age", period) + # OEO's 2024 guide leaves state-placed foster children out of the household + # and counts only eligible members for the itemized supplements. + member = ~person("is_in_foster_care", period.first_month) + eligible = member & person("is_citizen_or_legal_immigrant", period) + elderly = spm_unit.any(eligible & (age >= p.ages.elderly_min)) + child = spm_unit.any(eligible & (np.floor(age) <= p.ages.child_max)) + disabled = spm_unit.any(eligible & person("is_disabled", period)) + veteran = spm_unit.any(eligible & person("is_veteran", period)) + # The plan measures home-energy utilities; aggregate existing heating and + # electric bills, excluding water, sewer, trash, phone and separate cooking + # fuel. Annual expenses approximate current monthly bills, and rent-embedded + # charges are not available. + cost = add(spm_unit, period, p.energy_cost_sources) + high_burden = (cost > 0) & (cost >= income * p.burden_rate) + fuel = spm_unit("heating_type", period) + fuel_supplement = np.isin(fuel.decode_to_str(), p.supplement_fuels) + a = p.amounts + amount = ( + a.base + + a.elderly * elderly + + a.child * child + + a.disabled * disabled + + a.veteran * veteran + + a.low_income * low_income + + a.high_burden * high_burden + + a.fuel * fuel_supplement + ) + # Local funding and priority decisions are not represented. The state + # schedule does not impose a general benefit-to-bill cap. + # The plan states this maximum; the eight FY2026 amounts sum to exactly it. + award = min_(amount, a.maximum) + # A mixed-status award is the total benefit / all household members x + # eligible members; both counts leave out state-placed foster children. + # An eligible unit always has a member, so the floor only avoids dividing by zero. + return award * size / max_(spm_unit.sum(member), 1) diff --git a/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_countable_income.py b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_countable_income.py new file mode 100644 index 00000000000..45999e3f005 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_countable_income.py @@ -0,0 +1,37 @@ +from policyengine_us.model_api import * + + +class sc_liheap_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "South Carolina LIHEAP annual countable income" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + reference = ( + # PDF pages 5-6 + "https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=5", + "https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=529", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.sc.oeo.liheap.income + person = spm_unit.members + # Existing net business inputs approximate self-employment receipts + # without a second expense deduction. Annual flows approximate 30 days. + earned = 0 + for source in p.earned_sources: + earned = earned + max_(person(source, period), 0) + unearned = 0 + for source in p.unearned_sources: + unearned = unearned + max_(add(person, period, [source]), 0) + # OEO's 2024 guide calculates no income under age 18 apart from Social Security + # or disability income. Legal settlements and earmarked receipts lack inputs. + minor_income = 0 + for source in p.minor_unearned_sources: + minor_income = minor_income + max_(add(person, period, [source]), 0) + adult = person("age", period) >= p.adult_min_age + income = where(adult, earned + unearned, minor_income) + # State-placed foster children are not household members. + foster = person("is_in_foster_care", period.first_month) + return spm_unit.sum(where(foster, 0, income)) diff --git a/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_eligible.py b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_eligible.py new file mode 100644 index 00000000000..000ec310b1c --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_eligible.py @@ -0,0 +1,47 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class sc_liheap_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for South Carolina LIHEAP regular heating assistance" + definition_period = YEAR + defined_for = StateCode.SC + reference = ( + "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", + # PDF pages 8-9 + "https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8", + "https://oeo.sc.gov/managedsites/prd/oeo/liheap.html", + # PDF pages 526,536-537 + "https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=526", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.sc.oeo.liheap + size = spm_unit("sc_liheap_household_size", period) + income = spm_unit("sc_liheap_countable_income", period) + limit = spm_unit("sc_liheap_income_limit", period) + guideline = fpg( + size, + spm_unit.household("state_group_str", period), + period, + parameters, + year_lag=p.eligibility.fpg_year_lag, + ) + federal_floor = np.round( + guideline * parameters(period).gov.hhs.liheap.fpg_floor, 2 + ) + # OEO asks for an obligation to pay a home energy bill, and the one regular + # award pays heating or cooling costs, so any counted bill qualifies, including + # in a home without heating. heating_type is a required input, so an unspecified + # fuel qualifies only through heat in the rent. + has_energy_cost = add(spm_unit, period, p.payment.energy_cost_sources) > 0 + fuel = spm_unit("heating_type", period) + known_fuel = fuel != fuel.possible_values.UNSPECIFIED + heat_in_rent = spm_unit("heat_expense_included_in_rent", period) + return ( + (size > 0) + & ((income <= limit) | (income < federal_floor)) + & ((has_energy_cost & known_fuel) | heat_in_rent) + ) diff --git a/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_household_size.py b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_household_size.py new file mode 100644 index 00000000000..5369b6776d0 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_household_size.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class sc_liheap_household_size(Variable): + value_type = int + entity = SPMUnit + label = "South Carolina LIHEAP eligible household size" + definition_period = YEAR + defined_for = StateCode.SC + reference = ( + "https://oeo.sc.gov/managedsites/prd/oeo/documents/WAP%202026%20State%20Plan.pdf#page=23", + "https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=529", + ) + + def formula(spm_unit, period, parameters): + person = spm_unit.members + # This agency plan expressly attributes the size exclusion, while + # retaining all members' income, to South Carolina LIHEAP guidance. + qualified = person("is_citizen_or_legal_immigrant", period) + # OEO's 2024 guide leaves state-placed foster children out of the household. + # The input reads "qualifying foster care institution", the closest available. + foster = person("is_in_foster_care", period.first_month) + return spm_unit.sum(qualified & ~foster) diff --git a/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_income_limit.py b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_income_limit.py new file mode 100644 index 00000000000..7a697342c82 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_income_limit.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import liheap_smi_limit + + +class sc_liheap_income_limit(Variable): + value_type = float + entity = SPMUnit + label = "South Carolina LIHEAP annual income limit" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + reference = ( + "https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8", + "https://oeo.sc.gov/managedsites/prd/oeo/liheap.html", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.sc.oeo.liheap.eligibility + size = spm_unit("sc_liheap_household_size", period) + state = spm_unit.household("state_code_str", period) + # The HHS floor order reproduces all eight OEO annual limits. + limit = liheap_smi_limit(size, state, p.smi_rate, period, parameters) + return where(size > 0, limit, 0) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index ccd14853e8c..60fc010a078 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -9017,6 +9017,223 @@ candidates: - https://github.com/PolicyEngine/policyengine-us/pull/10398 state: ruled note: RR22-11 agrees with the statute. PR 10398 removes the 2021 reduction and the parameter that toggled it. + +- id: us-sc:liheap-energy-burden-test + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Is South Carolina's high energy burden supplement paid when energy costs equal 20% of income, as the FY2026 + plan reads, or only when the current bill is higher than 20% of income, as the 2024 guide and the matrix read? + sources: + - kind: plan + citation: South Carolina FY2026 LIHEAP State Plan, item 2.5, p.9 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=9 + - kind: manual + citation: South Carolina 2024 LIHEAP Administrative Guide, plan file PDF page 538 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=538 + - kind: manual + citation: South Carolina draft 2026 LIHEAP Administrative Guide (plan attachment), plan file PDF page 312 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=312 + - kind: guidance + citation: South Carolina 2026 Benefit Matrix, item 5, p.2 + url: https://liheapch.acf.gov/docs/2026/benefits-matricies/SC_BenefitMatrix_2026.pdf#page=2 + readings: + statute: No statute is supplied; plan item 2.5 pays the supplement at "20% or more of income used for utilities". + other: The 2024 and draft 2026 guides and the matrix test the current month's bill and demonstrate a burden when "the + current energy bill is higher than the PRODUCT". + example: One person with $20,000 of income and $4,000 of gas bills receives $450 under the plan and $275 under the + guide's "higher than". + pe_us: + follows: gap-fill + code: + - policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap.py + - policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/burden_rate.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10616 + state: unreviewed + note: PE-US follows the plan's inclusive test, with annual bills against annual income. + +- id: us-sc:liheap-income-floor-vs-smi-limit + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Can South Carolina's 60% SMI heating limit exclude a household of 15 or more whose income is below the + federal 110% poverty-guideline floor? + sources: + - kind: statute + citation: 42 U.S.C. 8624(b)(2)(B) + url: https://www.law.cornell.edu/uscode/text/42/8624#b_2_B + - kind: plan + citation: South Carolina FY2026 LIHEAP State Plan, income eligibility, p.8 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8 + readings: + statute: Income below 110% of the poverty guideline cannot by itself exclude the household. + other: The plan's 60% SMI limit falls below that floor from 15 members. + example: Twenty-five people with $150,000 exceed the $116,282 limit but are below the $162,415 floor (2025 guideline, + one-year lag), so they keep the $200 base award. + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_eligible.py + - policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml + - policyengine_us/parameters/gov/states/sc/oeo/liheap/eligibility/fpg_year_lag.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10616 + state: unreviewed + note: PE-US applies the floor, rounded to cents with the statute's strict "less than" (sc_liheap_eligible.py). +- id: us-sc:liheap-low-income-tier-base + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Is South Carolina's $175 low-income tier 30% of the full size-adjusted state median income, or 30% of the 60% + income limit that OEO's guides call the SMI? + sources: + - kind: plan + citation: South Carolina FY2026 LIHEAP State Plan, items 2.3 and 2.5, pp.8-9 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8 + - kind: manual + citation: South Carolina draft 2026 LIHEAP Administrative Guide (plan attachment), plan file PDF pages 311, 312 and 338 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=311 + - kind: manual + citation: South Carolina 2024 LIHEAP Administrative Guide, plan file PDF page 538 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=538 + - kind: guidance + citation: South Carolina 2026 Benefit Matrix, pp.1-2 + url: https://liheapch.acf.gov/docs/2026/benefits-matricies/SC_BenefitMatrix_2026.pdf#page=1 + readings: + statute: No statute is supplied; plan item 2.3 gives $175 "at or below 30% of the State's Median Income guidelines" and + item 2.5 "household income 30% of the SMI or less". + other: 'The draft guide says "must be at or below the 30% SMI. Note: SMI is 60% of the State''s Median Income" and "30 + of 60 percent of the SMI", which is 18% of the state median income. Its page 338 definition compares the tier "with + the same 30% variance when compared to the State''s 60% Median Income guidelines".' + example: A person aged 70 with $12,000 of income and a $1,000 electric bill receives $275 with the 60% limit as the base + (limit $9,597.90) and $450 with the full SMI as the base (limit $15,996.55). + pe_us: + follows: gap-fill + code: + - policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap.py + - policyengine_us/parameters/gov/states/sc/oeo/liheap/payment/low_income_limit_rate.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10616 + state: ruled + note: 'Ruled 2026-11-03: use 30% of the 60% limit. The plan''s words allow either base, and OEO''s own texts define + the SMI it means here, so the agency breaks the tie. The 2024 guide and the matrix use 70% of the same limit, a tier + the FY2026 plan replaced. The guide with the 30% text is a draft, and OEO has not been asked.' + +- id: us-sc:liheap-minor-income + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Does South Carolina LIHEAP count only a minor's Social Security or disability income, as the 2024 guide + provides, the unearned income plan item 1.9 checks, or no income of members under 18, as the OEO page reads? + sources: + - kind: manual + citation: South Carolina 2024 LIHEAP Administrative Guide, Income from Minors, plan file PDF page 529 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=529 + - kind: manual + citation: South Carolina draft 2026 LIHEAP Administrative Guide (plan attachment), plan file PDF page 304 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=304 + - kind: plan + citation: South Carolina FY2026 LIHEAP State Plan, item 1.9, pp.5-6 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=5 + - kind: guidance + citation: South Carolina OEO LIHEAP page + url: https://oeo.sc.gov/managedsites/prd/oeo/liheap.html + readings: + statute: No statute is supplied; the guide says "Income is not calculated for persons under age 18" but "If household + members under 18 receive Social Security or Disability income, the gross amount must be included". + other: Plan item 1.9 checks Social Security, SSI, pensions, child support and VA benefits and leaves only "Earned income + of a child under the age of 18" unchecked. The OEO page asks for "Gross 30-day income for all household members 18 + and older". + example: A parent aged 35 with $36,000 of wages and a 10-year-old with $8,000 of veterans benefits count $36,000 and + receive $200 with a $1,000 electric bill under the guide, and count $44,000 and receive $0 under plan item 1.9. + pe_us: + follows: gap-fill + code: + - policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_countable_income.py + - policyengine_us/parameters/gov/states/sc/oeo/liheap/income/adult_min_age.yaml + - policyengine_us/parameters/gov/states/sc/oeo/liheap/income/minor_unearned_sources.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10616 + state: ruled + note: 'Ruled 2026-11-02: follow the 2024 guide, the edition in force. Plan 1.9 is a checklist of income types, while + the guide''s "Income from Minors" section is the specific rule for members under 18. The draft 2026 guide repeats it, + and the OEO page asks for income only from members 18 and older. PE-US reads SSI as a child''s disability income and + uses disability_benefits for other disability income.' + +- id: us-sc:liheap-mixed-status-household + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Do South Carolina's itemized supplements look only at eligible members, with the award prorated, and are + state-placed foster children left out of the household, as the 2024 guide provides where the FY2026 plan is silent? + sources: + - kind: manual + citation: South Carolina 2024 LIHEAP Administrative Guide, plan file PDF pages 529, 537 and 546 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=529 + - kind: plan + citation: South Carolina FY2026 LIHEAP State Plan, items 2.3 and 2.5, pp.8-9 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=8 + readings: + statute: No statute is supplied; the guide says to "only consider eligible household members" for the itemized + benefits and then "apply the Direct Assistance Prorated Calculation". + other: The plan's supplements apply if "the household/a member of the household" qualifies, and it states no proration. + example: A nonqualified parent with $30,000 of income and a qualified child with gas heat receive (200 + 50 + 75) / 2 + members x 1 eligible = $162.50 under the guide, and $325 with no proration. + pe_us: + follows: gap-fill + code: + - policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap.py + - policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_household_size.py + - policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_countable_income.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10616 + state: ruled + note: 'Ruled 2026-11-02: follow the 2024 guide. The veteran supplement also looks only at eligible members, although + the guide''s list does not name veterans, and the prorated award keeps its cents.' + +- id: us-sc:liheap-plan-income-checklist + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Does South Carolina LIHEAP count all income, as the 2024 guide opens, or only the income forms plan item 1.9 + checks? + sources: + - kind: plan + citation: South Carolina FY2026 LIHEAP State Plan, item 1.9, pp.5-6 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20LIHEAP%20State%20Plan.pdf#page=5 + - kind: manual + citation: South Carolina 2024 LIHEAP Administrative Guide, How to Calculate Income, plan file PDF page 526 + url: https://oeo.sc.gov/managedsites/prd/oeo/documents/2026%20South%20Carolina%20LIHEAP%20Model%20Plan%20w%20Attachments.pdf#page=526 + readings: + statute: No statute is supplied; plan item 1.9 leaves interest and dividends unchecked, has no box for workers' + compensation or employment disability benefits, and leaves its Other box unchecked. + other: The guide says "When calculating total household income, include all income". + example: One person with a $1,000 electric bill, $20,000 of wages and $15,000 of interest counts $20,000 and receives + $200 under the plan, and counts $35,000 and receives $0 under the guide. + pe_us: + follows: gap-fill + code: + - policyengine_us/variables/gov/states/sc/oeo/liheap/sc_liheap_countable_income.py + - policyengine_us/parameters/gov/states/sc/oeo/liheap/income/earned_sources.yaml + - policyengine_us/parameters/gov/states/sc/oeo/liheap/income/unearned_sources.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10616 + state: ruled + note: 'Ruled 2026-11-02: income other than minors'' income follows the plan.' + - id: us-sd:liheap-2025-published-income-limit program: liheap years: