diff --git a/changelog.d/id-liheap-wave2c.added.md b/changelog.d/id-liheap-wave2c.added.md new file mode 100644 index 00000000000..d16ab73d290 --- /dev/null +++ b/changelog.d/id-liheap-wave2c.added.md @@ -0,0 +1 @@ +Add Idaho LIHEAP regular heating assistance for FY2026. diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/fpg_rate.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/fpg_rate.yaml new file mode 100644 index 00000000000..2b110f55bb0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/fpg_rate.yaml @@ -0,0 +1,11 @@ +description: Idaho limits household income to this multiple of federal poverty guidelines for larger households under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 1.5 + +metadata: + unit: /1 + period: year + label: Idaho LIHEAP FPG rate + reference: + - title: Idaho FY2026 LIHEAP State Plan + href: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/fpg_year_lag.yaml new file mode 100644 index 00000000000..cc6e6cadd72 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/fpg_year_lag.yaml @@ -0,0 +1,13 @@ +description: Idaho uses federal poverty guidelines from this many years before the benefit fiscal year under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 1 + +metadata: + unit: year + period: year + label: Idaho LIHEAP FPG year lag + reference: + - title: Idaho FY2026 LIHEAP State Plan, section 2.1 + href: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=8 + - title: Idaho Department of Health and Welfare, monthly limits effective October 1, 2025 + href: https://healthandwelfare.idaho.gov/services-programs/financial-assistance/home-heating-and-utility-assistance/apply-heating-assistance diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/program_year_start_month.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/program_year_start_month.yaml new file mode 100644 index 00000000000..8f3c766e948 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/program_year_start_month.yaml @@ -0,0 +1,10 @@ +description: Idaho starts the program year, used to test SNAP receipt, in this month of the preceding calendar year under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 10 +metadata: + unit: month + period: year + label: Idaho LIHEAP program year start month + reference: + - title: Idaho FY2026 LIHEAP State Plan, categorical eligibility + href: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=5 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/smi_max_household_size.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/smi_max_household_size.yaml new file mode 100644 index 00000000000..83501dcb915 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/smi_max_household_size.yaml @@ -0,0 +1,11 @@ +description: Idaho uses state median income limits for households up to this size under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 7 + +metadata: + unit: person + period: year + label: Idaho LIHEAP maximum household size for SMI limits + reference: + - title: Idaho FY2026 LIHEAP State Plan + href: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/smi_rate.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/smi_rate.yaml new file mode 100644 index 00000000000..bd0f65e6a8e --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/eligibility/smi_rate.yaml @@ -0,0 +1,11 @@ +description: Idaho limits household income to this share of state median income for smaller households under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 0.6 + +metadata: + unit: /1 + period: year + label: Idaho LIHEAP SMI rate + reference: + - title: Idaho FY2026 LIHEAP State Plan + href: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/income/sources/earned.yaml new file mode 100644 index 00000000000..12b33bbcc40 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/income/sources/earned.yaml @@ -0,0 +1,24 @@ +description: Idaho counts these earned income sources under the Low Income Home Energy Assistance Program. +# Every member's earnings count: IDAPA 16.04.14.010.06 counts moneys "from all +# sources" and 151.02 does not exclude a minor's, although plan 1.9 leaves them +# unchecked. +values: + 2025-10-01: + - employment_income + # Plan 1.9 checks "Wages". Basic pay is an input 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: Idaho LIHEAP countable earned income sources + reference: + - title: "Idaho FY2026 LIHEAP State Plan #page 5-7" + href: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=5 + - title: IDAPA 16.04.14.010.06 as of September 10, 2025 + href: https://web.archive.org/web/20250910171431id_/https://adminrules.idaho.gov/rules/current/16/160414.pdf#page=3 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/income/sources/unearned.yaml new file mode 100644 index 00000000000..aa98119cf35 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/income/sources/unearned.yaml @@ -0,0 +1,43 @@ +description: Idaho counts these unearned income sources under the Low Income Home Energy Assistance Program. +# Social Security is counted net of Part B separately; TANF enters once per household. +values: + 2025-10-01: + - ssi + - pension_income + # Military retirement includes Survivor Benefit Plan annuities. + - military_retirement_income + - railroad_benefits + # Ongoing IRA/401k distributions are separate from pension_income. + # Existing annual inputs do not identify an excluded one-time lump sum. + - retirement_distributions + - survivor_benefits + - total_unemployment_compensation + - strike_benefits + - rental_income + - farm_rent_income + - alimony_income + - interest_income + - ordinary_dividend_income + - estate_income + - disability_benefits + - workers_compensation + # IDAPA 16.04.14.010.06 counts moneys "from all sources", and 151.02 excludes + # none of these, although plan 1.9 leaves VA and general assistance unchecked. + - veterans_benefits + - general_assistance + - id_aabd + # Plan 1.9's checked Other line and IDAPA 16.04.14.151.02.f count gifts and + # lottery winnings over $30, although its lump-sum line is unchecked. The + # specific line is followed. The $30 test has no input: annual amounts count. + - gambling_winnings + - financial_assistance + +metadata: + unit: list + period: year + label: Idaho LIHEAP countable unearned income sources + reference: + - title: "Idaho FY2026 LIHEAP State Plan #page 5-7" + href: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=5 + - title: "IDAPA 16.04.14.010.06 and 151.02 as of September 10, 2025 #page 3,5" + href: https://web.archive.org/web/20250910171431id_/https://adminrules.idaho.gov/rules/current/16/160414.pdf#page=3 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/energy_burden/high_rate.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/energy_burden/high_rate.yaml new file mode 100644 index 00000000000..8bcfd4b36fe --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/energy_burden/high_rate.yaml @@ -0,0 +1,13 @@ +description: Idaho places households in the high energy-burden group when estimated annual heating costs reach this share of annual income under the Low Income Home Energy Assistance Program. + +# Modeling convention: exactly 11% is high; the published chart omits that boundary. +values: + 2025-10-01: 0.11 + +metadata: + unit: /1 + period: year + label: Idaho LIHEAP high energy-burden rate + reference: + - title: Idaho PY26 LIHEAP Benefit Determination Chart PDF, PY23 LIHEAP Benefit Matrix Summary + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/energy_burden/medium_rate.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/energy_burden/medium_rate.yaml new file mode 100644 index 00000000000..ee528f29786 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/energy_burden/medium_rate.yaml @@ -0,0 +1,11 @@ +description: Idaho places households in the medium energy-burden group when estimated annual heating costs reach this share of annual income under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 0.06 + +metadata: + unit: /1 + period: year + label: Idaho LIHEAP medium energy-burden rate + reference: + - title: Idaho PY26 LIHEAP Benefit Determination Chart PDF, PY23 LIHEAP Benefit Matrix Summary + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/estimated_heating_costs.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/estimated_heating_costs.yaml new file mode 100644 index 00000000000..e27544cf740 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/estimated_heating_costs.yaml @@ -0,0 +1,48 @@ +description: Idaho uses these estimated heating-season costs by fuel and heating area under the Low Income Home Energy Assistance Program. + +# Modeling assumption: the PY2007 estimated nine-month heating costs continue. +# This table is not confirmed as current for FY2026. +# The FY2026 anchor records this modeling assumption, not a verified update. +# Preserve the published amounts without inflation or a twelve-month uplift. +# Provider groups are not distinguished. Electricity uses Idaho Power & +# Southern Utilities; natural gas uses the complete Intermountain Gas column. +# The old rent-cost column and old benefit percentages are not used. +oil_or_propane: + 1: + 2025-10-01: 1_625 + 2: + 2025-10-01: 1_845 + 3: + 2025-10-01: 2_145 +natural_gas: + 1: + 2025-10-01: 977 + 2: + 2025-10-01: 1_100 + 3: + 2025-10-01: 1_207 +electricity: + 1: + 2025-10-01: 1_335 + 2: + 2025-10-01: 1_455 + 3: + 2025-10-01: 1_605 +coal_or_wood: + 1: + 2025-10-01: 1_200 + 2: + 2025-10-01: 1_600 + 3: + 2025-10-01: 1_800 + +metadata: + propagate_metadata_to_children: true + unit: currency-USD + period: year + label: Idaho LIHEAP estimated nine-month heating costs + reference: + - title: Historical Idaho LIHEAP Intake Manual, Appendix C, average heating-cost matrix + href: https://web.archive.org/web/20170127123014id_/http://www.healthandwelfare.idaho.gov/Portals/_Rainbow/Manuals/LIHEAP/Appendices/c_htgcost_matrix_PY07.pdf#page=1 + - title: Historical Idaho LIHEAP Intake Manual, Heating Cost Estimation, PY2007 nine-month matrix + href: https://web.archive.org/web/20080512165351id_/http://www.healthandwelfare.idaho.gov:80/Portals/_Rainbow/Manuals/LIHEAP/Benefit_Calculation/Heating_Cost_Estimation.htm diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/heating_areas.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/heating_areas.yaml new file mode 100644 index 00000000000..dd69c03a048 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/heating_areas.yaml @@ -0,0 +1,65 @@ +description: Idaho groups counties into these heating areas under the Low Income Home Energy Assistance Program. + +# The recovered historical county map continues as a modeling assumption. +# The FY2026 anchor is not a verified effective date. +# Use the complete left-hand county table on page 2; the right-hand table +# duplicates Power County and omits Elmore County. +area_1: + 2025-10-01: + - ADA_COUNTY_ID + - CANYON_COUNTY_ID + - ELMORE_COUNTY_ID + - GEM_COUNTY_ID + - GOODING_COUNTY_ID + - LATAH_COUNTY_ID + - NEZ_PERCE_COUNTY_ID + - OWYHEE_COUNTY_ID + - PAYETTE_COUNTY_ID + - WASHINGTON_COUNTY_ID +area_2: + 2025-10-01: + - ADAMS_COUNTY_ID + - BANNOCK_COUNTY_ID + - BENEWAH_COUNTY_ID + - BINGHAM_COUNTY_ID + - BOISE_COUNTY_ID + - BONNER_COUNTY_ID + - BOUNDARY_COUNTY_ID + - CASSIA_COUNTY_ID + - CLEARWATER_COUNTY_ID + - FRANKLIN_COUNTY_ID + - IDAHO_COUNTY_ID + - JEROME_COUNTY_ID + - KOOTENAI_COUNTY_ID + - LEWIS_COUNTY_ID + - LINCOLN_COUNTY_ID + - MINIDOKA_COUNTY_ID + - ONEIDA_COUNTY_ID + - POWER_COUNTY_ID + - SHOSHONE_COUNTY_ID + - TWIN_FALLS_COUNTY_ID +area_3: + 2025-10-01: + - BEAR_LAKE_COUNTY_ID + - BLAINE_COUNTY_ID + - BONNEVILLE_COUNTY_ID + - BUTTE_COUNTY_ID + - CAMAS_COUNTY_ID + - CARIBOU_COUNTY_ID + - CLARK_COUNTY_ID + - CUSTER_COUNTY_ID + - FREMONT_COUNTY_ID + - JEFFERSON_COUNTY_ID + - LEMHI_COUNTY_ID + - MADISON_COUNTY_ID + - TETON_COUNTY_ID + - VALLEY_COUNTY_ID + +metadata: + propagate_metadata_to_children: true + unit: list + period: year + label: Idaho LIHEAP heating-area counties + reference: + - title: Historical Idaho LIHEAP Intake Manual, Appendix A, county codes + href: https://web.archive.org/web/20170124204651id_/http://healthandwelfare.idaho.gov/portals/_rainbow/manuals/liheap/Appendices/a_codes_all.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/coal_or_wood.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/coal_or_wood.yaml new file mode 100644 index 00000000000..799a66ed79c --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/coal_or_wood.yaml @@ -0,0 +1,40 @@ +description: Idaho provides this base coal or wood heating benefit by heating area and energy-burden group under the Low Income Home Energy Assistance Program. + +# Heating areas 1-3 correspond to Areas I-III in the published chart. +# Energy-burden groups: 1 = low, 2 = medium, 3 = high. +1: + 1: + 2025-10-01: 467 + 2: + 2025-10-01: 486 + 3: + 2025-10-01: 505 +2: + 1: + 2025-10-01: 544 + 2: + 2025-10-01: 567 + 3: + 2025-10-01: 590 +3: + 1: + 2025-10-01: 622 + 2: + 2025-10-01: 648 + 3: + 2025-10-01: 674 + +metadata: + propagate_metadata_to_children: true + unit: currency-USD + period: year + label: Idaho LIHEAP base coal or wood heating benefit + breakdown: + - range(1, 4) + - range(1, 4) + breakdown_labels: + - Heating area + - Energy-burden group + reference: + - title: Idaho PY26 LIHEAP Benefit Determination Chart + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/electricity.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/electricity.yaml new file mode 100644 index 00000000000..bb42cb0876e --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/electricity.yaml @@ -0,0 +1,43 @@ +description: Idaho provides this base electric-heating benefit by heating area and energy-burden group under the Low Income Home Energy Assistance Program. + +# Electric utility-provider groups are not distinguished in the model for now. +# Use only the Idaho Power & Southern Utilities column; omit the Avista & +# Northern Utilities and Rocky Mountain Power columns. +# Heating areas 1-3 correspond to Areas I-III in the published chart. +# Energy-burden groups: 1 = low, 2 = medium, 3 = high. +1: + 1: + 2025-10-01: 328 + 2: + 2025-10-01: 342 + 3: + 2025-10-01: 355 +2: + 1: + 2025-10-01: 378 + 2: + 2025-10-01: 394 + 3: + 2025-10-01: 410 +3: + 1: + 2025-10-01: 429 + 2: + 2025-10-01: 447 + 3: + 2025-10-01: 464 + +metadata: + propagate_metadata_to_children: true + unit: currency-USD + period: year + label: Idaho LIHEAP base electric-heating benefit + breakdown: + - range(1, 4) + - range(1, 4) + breakdown_labels: + - Heating area + - Energy-burden group + reference: + - title: Idaho PY26 LIHEAP Benefit Determination Chart + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/natural_gas.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/natural_gas.yaml new file mode 100644 index 00000000000..616f0b94cde --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/natural_gas.yaml @@ -0,0 +1,43 @@ +description: Idaho provides this base natural gas heating benefit by heating area and energy-burden group under the Low Income Home Energy Assistance Program. + +# Natural gas provider groups are not distinguished in the model for now. +# Use the Intermountain Gas column, the only one filled in all three areas; +# omit the Avista column. Matches estimated_heating_costs. +# Heating areas 1-3 correspond to Areas I-III in the published chart. +# Energy-burden groups: 1 = low, 2 = medium, 3 = high. +1: + 1: + 2025-10-01: 122 + 2: + 2025-10-01: 127 + 3: + 2025-10-01: 132 +2: + 1: + 2025-10-01: 141 + 2: + 2025-10-01: 147 + 3: + 2025-10-01: 152 +3: + 1: + 2025-10-01: 159 + 2: + 2025-10-01: 166 + 3: + 2025-10-01: 173 + +metadata: + propagate_metadata_to_children: true + unit: currency-USD + period: year + label: Idaho LIHEAP base natural gas heating benefit + breakdown: + - range(1, 4) + - range(1, 4) + breakdown_labels: + - Heating area + - Energy-burden group + reference: + - title: Idaho PY26 LIHEAP Benefit Determination Chart + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/oil_or_propane.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/oil_or_propane.yaml new file mode 100644 index 00000000000..209c7a4e556 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/matrix/oil_or_propane.yaml @@ -0,0 +1,40 @@ +description: Idaho provides this base oil or propane heating benefit by heating area and energy-burden group under the Low Income Home Energy Assistance Program. + +# Heating areas 1-3 correspond to Areas I-III in the published chart. +# Energy-burden groups: 1 = low, 2 = medium, 3 = high. +1: + 1: + 2025-10-01: 776 + 2: + 2025-10-01: 808 + 3: + 2025-10-01: 840 +2: + 1: + 2025-10-01: 970 + 2: + 2025-10-01: 1_010 + 3: + 2025-10-01: 1_050 +3: + 1: + 2025-10-01: 1_164 + 2: + 2025-10-01: 1_212 + 3: + 2025-10-01: 1_260 + +metadata: + propagate_metadata_to_children: true + unit: currency-USD + period: year + label: Idaho LIHEAP base oil or propane heating benefit + breakdown: + - range(1, 4) + - range(1, 4) + breakdown_labels: + - Heating area + - Energy-burden group + reference: + - title: Idaho PY26 LIHEAP Benefit Determination Chart + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/rent.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/rent.yaml new file mode 100644 index 00000000000..3eae0a98b74 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/rent.yaml @@ -0,0 +1,20 @@ +description: Idaho provides this base benefit to households without a specific heating-cost obligation under the Low Income Home Energy Assistance Program. + +# FY2025 paid the minimum rent benefit before any target supplement. +# This category became ineligible in FY2026; zero is not an unknown amount. +# This rule does not exclude all renters or all subsidized households. +values: + 2024-10-01: 75 + 2025-10-01: 0 + +metadata: + unit: currency-USD + period: year + label: Idaho LIHEAP base benefit without a specific heating-cost obligation + reference: + - title: FY2025 Idaho LIHEAP State Plan, sections 2.5 and 2.6 + href: https://liheapch.acf.gov/docs/2025/state-plans/ID_Plan_2025.pdf#page=9 + - title: Idaho PY25 Benefit Determination Chart + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/ID_BenefitMatrix_2025.pdf#page=1 + - title: FY2026 Idaho LIHEAP State Plan, sections 2.5 and 2.6 + href: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=9 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/target_bonus/amount.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/target_bonus/amount.yaml new file mode 100644 index 00000000000..d2ef920d5f0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/target_bonus/amount.yaml @@ -0,0 +1,13 @@ +description: Idaho adds this target benefit for households with a vulnerable member under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 25 + +metadata: + unit: currency-USD + period: year + label: Idaho LIHEAP target bonus amount + reference: + - title: Idaho FY2026 LIHEAP State Plan, section 2.4 + href: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=9 + - title: Idaho PY26 LIHEAP Benefit Determination Chart PDF, PY23 LIHEAP Benefit Matrix Summary + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/target_bonus/child_age_limit.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/target_bonus/child_age_limit.yaml new file mode 100644 index 00000000000..c011b400cca --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/target_bonus/child_age_limit.yaml @@ -0,0 +1,11 @@ +description: Idaho treats children younger than this age as vulnerable under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 6 + +metadata: + unit: year + period: year + label: Idaho LIHEAP target bonus child age limit + reference: + - title: Idaho PY26 LIHEAP Benefit Determination Chart PDF, PY23 LIHEAP Benefit Matrix Summary + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/target_bonus/elderly_age.yaml b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/target_bonus/elderly_age.yaml new file mode 100644 index 00000000000..4e4f4503ae8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/id/dhw/liheap/payment/target_bonus/elderly_age.yaml @@ -0,0 +1,11 @@ +description: Idaho treats adults reaching this age before the program year ends as vulnerable under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 60 + +metadata: + unit: year + period: year + label: Idaho LIHEAP target bonus elderly age + reference: + - title: Idaho PY26 LIHEAP Benefit Determination Chart PDF, PY23 LIHEAP Benefit Matrix Summary + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=2 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 362bdca4f4b..f654dcc4120 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, CA, CO, CT, 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 + coverage: AK, AR, AL, AZ, CA, CO, CT, DC, DE, GA, HI, Riverside County, MA, FL, IL, IA, ID, 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 @@ -1361,6 +1361,13 @@ programs: parameter_prefix: gov.states.wy.dfs.lieap verified_years: "2026" notes: FY2026 regular heating from the published fuel cost standards. Crisis, cooling, weatherization and equipment assistance are out of scope. + - state: ID + status: partial + name: Idaho LIHEAP + full_name: Idaho Low Income Home Energy Assistance Program + variable: id_liheap + parameter_prefix: gov.states.id.dhw.liheap + notes: FY2026 regular heating; burden bands use the PY2007 heating-cost table, whose FY2026 currency is unconfirmed, so no year is verified. Crisis, cooling, weatherization and equipment assistance are out of scope. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_eligible.yaml new file mode 100644 index 00000000000..91b65eafc16 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_eligible.yaml @@ -0,0 +1,58 @@ +# Accepted FY2026 plan, sections 2.3 and 2.5 (pages 8-9); FY2025 plan, section 2.5 (page 9). +# https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=8 +# https://liheapch.acf.gov/docs/2025/state-plans/ID_Plan_2025.pdf#page=9 +# IDAPA 16.03.08.200.07: costs incurred directly or as a designated portion of rent. +# https://adminrules.idaho.gov/rules/current/16/160308.pdf#page=5 + +- name: Case 1, income eligibility and a modeled heating cost are both required. + period: 2026 + # Ada County is Area I. OTHER, NONE and UNSPECIFIED have no chart column. No Idaho + # source names solar or kerosene; solar reads as electric and kerosene as oil. + input: + state_code: [ID, ID, ID, ID, ID, ID, ID, ID, OR] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, + ADA_COUNTY_ID, ADA_COUNTY_ID, UNKNOWN, BAKER_COUNTY_OR] + heating_type: [NATURAL_GAS, NATURAL_GAS, SOLAR, KEROSENE, OTHER, NONE, UNSPECIFIED, + NATURAL_GAS, NATURAL_GAS] + has_heating_expense: [true, true, true, true, true, true, true, true, true] + id_liheap_income_eligible: [true, false, true, true, true, true, true, true, true] + output: + id_liheap_eligible: [true, false, true, true, false, false, false, false, false] + +- name: Case 2, heat in rent has no specific obligation from FY2026 while subsidized tenants paying directly qualify. + period: 2026 + input: + state_code: [ID, ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + heat_expense_included_in_rent: [true, true, false] + receives_housing_assistance: [false, true, true] + gas_expense: [0, 0, 900] + id_liheap_income_eligible: [true, true, true] + output: + id_liheap_eligible: [false, false, true] + +- name: Case 3, FY2025 paid households with heat in rent, whatever the fuel. + period: 2025 + input: + state_code: [ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID] + heating_type: [NATURAL_GAS, OTHER] + heat_expense_included_in_rent: [true, true] + id_liheap_income_eligible: [true, true] + output: + id_liheap_eligible: [true, true] + +- name: Case 4, a direct fuel household needs a heating cost obligation. + period: 2026 + # Plan 2.3: "The household must pay for home heating costs". Free gathered wood and a + # subsidized tenant with no gas bill have none; a wood bill establishes one. + input: + state_code: [ID, ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID] + heating_type: [WOOD, NATURAL_GAS, WOOD] + wood_expense: [0, 0, 300] + receives_housing_assistance: [false, true, false] + id_liheap_income_eligible: [true, true, true] + output: + id_liheap_eligible: [false, false, true] diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_household_size.yaml new file mode 100644 index 00000000000..7ea7f75fcfb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_household_size.yaml @@ -0,0 +1,63 @@ +# Idaho FY2026 LIHEAP plan, qualified household membership (page 9). +# https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=9 +# IDAPA 16.03.08 sections 201-202, shared economic household (pages 5-6). +# https://adminrules.idaho.gov/rules/current/16/160308.pdf#page=5 + +- name: Case 1, citizen child counts while nonqualified parent does not. + period: 2026 + # One qualified child; the adult status cannot erase the child. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: false, employment_income: 20_000, ssi: 0} + person2: {age: 8, is_citizen_or_legal_immigrant: true, ssi: 0} + spm_units: + spm_unit: {members: [person1, person2], heating_type: NATURAL_GAS} + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_household_size: 1 + +- name: Case 2, all nonqualified members give zero eligible size. + period: 2026 + # Neither member satisfies the citizenship or qualified-status rule. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: false, ssi: 0} + person2: {age: 8, is_citizen_or_legal_immigrant: false, ssi: 0} + spm_units: + spm_unit: {members: [person1, person2], heating_type: NATURAL_GAS} + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_household_size: 0 + +- name: Case 3, qualified foster child remains a household member. + period: 2026 + # No Idaho source excludes a qualified foster member from size. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: true, ssi: 0} + person2: {age: 8, is_citizen_or_legal_immigrant: true, ssi: 0, is_in_foster_care: {2026-01: true}} + spm_units: + spm_unit: {members: [person1, person2], heating_type: NATURAL_GAS} + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_household_size: 2 + +- name: Case 4, mixed states keep Idaho size separate. + period: 2026 + # The qualified Idaho pair counts; Colorado is outside this component. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: true, ssi: 0} + person2: {age: 8, is_citizen_or_legal_immigrant: true, ssi: 0} + person3: {age: 40, is_citizen_or_legal_immigrant: true, ssi: 0} + spm_units: + spm_unit1: {members: [person1, person2], heating_type: NATURAL_GAS} + spm_unit2: {members: [person3], heating_type: NATURAL_GAS} + households: + household1: {members: [person1, person2], state_code: ID} + household2: {members: [person3], state_code: CO} + output: + id_liheap_household_size: [2, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_income_eligible.yaml new file mode 100644 index 00000000000..baf729024f6 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_income_eligible.yaml @@ -0,0 +1,1797 @@ +# Source-derived financial eligibility tests. +# Accepted FY2026 plan, categorical rules and income thresholds (pages 5, 8). +# https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=5 +# Pre-consolidation IDAPA 16.04.14 section 151.01 (physical pages 4-5). +# https://web.archive.org/web/20250910171431id_/https://adminrules.idaho.gov/rules/current/16/160414.pdf#page=4 +# DHW monthly limits effective October 1, 2025. +# https://healthandwelfare.idaho.gov/services-programs/financial-assistance/home-heating-and-utility-assistance/apply-heating-assistance +# Means-tested VA and discretionary medical determinations are unobserved routes. +# False means no modeled route is established, not exhaustive legal denial. + +- name: Case 1, ordinary income qualifies through the inclusive published ceiling. + # DHW one-person monthly limit 2_736.25 * 12 = 32_835. + # No SNAP or SSI; one cent below, exactly at, and one cent above. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 32834.99 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 32835 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 32835.01 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit2: + members: + - person2 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit3: + members: + - person3 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + households: + household1: + members: + - person1 + state_code: ID + household2: + members: + - person2 + state_code: ID + household3: + members: + - person3 + state_code: ID + output: + id_liheap_income_eligible: + - true + - true + - false + id_liheap_household_size: + - 1 + - 1 + - 1 + id_liheap_countable_income: + - 32834.99 + - 32835 + - 32835.01 + id_liheap_income_limit: + - 32835 + - 32835 + - 32835 + +- name: Case 2, SNAP receipt follows the October through September program year. + # Plan section 1.4a specifies October 1-September 30. + # First/last included months qualify; adjacent outside months do not. + # All other months September 2025-December 2026 are explicitly zero. + # SNAP establishes a route without erasing 40_000 of countable earnings. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 40000 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 40000 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 40000 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person4: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 40000 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 1 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit2: + members: + - person2 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 1 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit3: + members: + - person3 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 1 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit4: + members: + - person4 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 1 + 2026-11: 0 + 2026-12: 0 + households: + household1: + members: + - person1 + state_code: ID + household2: + members: + - person2 + state_code: ID + household3: + members: + - person3 + state_code: ID + household4: + members: + - person4 + state_code: ID + output: + id_liheap_income_eligible: + - true + - true + - false + - false + id_liheap_household_size: + - 1 + - 1 + - 1 + - 1 + id_liheap_countable_income: + - 40000 + - 40000 + - 40000 + - 40000 + +- name: Case 3, one member receiving SSI establishes the modeled categorical route. + # Positive requested-year SSI is the documented stable-receipt approximation. + # Income: 40_000 + 1 * 12; 60_000 + 6_000 + 100 * 12; 40_000 + 100 * 12. + # Child earnings count; SSI is counted once. + # The third unit has a nonqualified SSI recipient and a qualified child. + # The parent income counts; SSI is not restricted to qualified members. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 40000 + ssi: + 2026-01: 1 + 2026-02: 1 + 2026-03: 1 + 2026-04: 1 + 2026-05: 1 + 2026-06: 1 + 2026-07: 1 + 2026-08: 1 + 2026-09: 1 + 2026-10: 1 + 2026-11: 1 + 2026-12: 1 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 60000 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person3: + age: 10 + is_citizen_or_legal_immigrant: true + employment_income: 6000 + ssi: + 2026-01: 100 + 2026-02: 100 + 2026-03: 100 + 2026-04: 100 + 2026-05: 100 + 2026-06: 100 + 2026-07: 100 + 2026-08: 100 + 2026-09: 100 + 2026-10: 100 + 2026-11: 100 + 2026-12: 100 + person4: + age: 40 + is_citizen_or_legal_immigrant: false + employment_income: 40000 + ssi: + 2026-01: 100 + 2026-02: 100 + 2026-03: 100 + 2026-04: 100 + 2026-05: 100 + 2026-06: 100 + 2026-07: 100 + 2026-08: 100 + 2026-09: 100 + 2026-10: 100 + 2026-11: 100 + 2026-12: 100 + person5: + age: 10 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit2: + members: + - person2 + - person3 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit3: + members: + - person4 + - person5 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + households: + household1: + members: + - person1 + state_code: ID + household2: + members: + - person2 + - person3 + state_code: ID + household3: + members: + - person4 + - person5 + state_code: ID + output: + id_liheap_income_eligible: + - true + - true + - true + id_liheap_household_size: + - 1 + - 2 + - 1 + id_liheap_countable_income: + - 40012 + - 67200 + - 41200 + id_liheap_income_limit: + - 32835 + - 42938 + - 32835 + +- name: Case 4, qualified size is required with zero income or categorical receipt. + # All-nonqualified units fail without benefits, with SNAP, and with SSI. + # Mixed status retains parent income one cent above the one-person ceiling. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: false + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person2: + age: 40 + is_citizen_or_legal_immigrant: false + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person3: + age: 40 + is_citizen_or_legal_immigrant: false + employment_income: 0 + ssi: + 2026-01: 100 + 2026-02: 100 + 2026-03: 100 + 2026-04: 100 + 2026-05: 100 + 2026-06: 100 + 2026-07: 100 + 2026-08: 100 + 2026-09: 100 + 2026-10: 100 + 2026-11: 100 + 2026-12: 100 + person4: + age: 40 + is_citizen_or_legal_immigrant: false + employment_income: 32835.01 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person5: + age: 10 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit2: + members: + - person2 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 1 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit3: + members: + - person3 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit4: + members: + - person4 + - person5 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + households: + household1: + members: + - person1 + state_code: ID + household2: + members: + - person2 + state_code: ID + household3: + members: + - person3 + state_code: ID + household4: + members: + - person4 + - person5 + state_code: ID + output: + id_liheap_income_eligible: + - false + - false + - false + - false + id_liheap_household_size: + - 0 + - 0 + - 0 + - 1 + id_liheap_countable_income: + - 0 + - 0 + - 1200 + - 32835.01 + +- name: Case 5, TANF alone is not categorical and SNAP retains actual income. + # Plan page 5 marks TANF no and SNAP yes for heating categorical eligibility. + # TAFI 100 monthly = 1_200 annual countable income, without a categorical route. + # SNAP opens the modeled route without imputing or erasing other income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 40000 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 40000 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 100 + 2026-02: 100 + 2026-03: 100 + 2026-04: 100 + 2026-05: 100 + 2026-06: 100 + 2026-07: 100 + 2026-08: 100 + 2026-09: 100 + 2026-10: 100 + 2026-11: 100 + 2026-12: 100 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit2: + members: + - person2 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 1 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + households: + household1: + members: + - person1 + state_code: ID + household2: + members: + - person2 + state_code: ID + output: + id_liheap_income_eligible: + - false + - true + id_liheap_household_size: + - 1 + - 1 + id_liheap_countable_income: + - 41200 + - 40000 + +- name: Case 6, the seven to eight member switch affects ordinary eligibility. + # Published size-7 monthly 7_103.75 * 12 = 85_245. + # Published size-8 monthly 6_768.75 * 12 = 81_225. + # The explicit SMI/FPG switch does not take the larger guideline. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 84000 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person4: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person5: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person6: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person7: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person8: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 84000 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person9: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person10: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person11: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person12: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person13: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person14: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person15: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_units: + spm_unit1: + members: + - person1 + - person2 + - person3 + - person4 + - person5 + - person6 + - person7 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit2: + members: + - person8 + - person9 + - person10 + - person11 + - person12 + - person13 + - person14 + - person15 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + households: + household1: + members: + - person1 + - person2 + - person3 + - person4 + - person5 + - person6 + - person7 + state_code: ID + household2: + members: + - person8 + - person9 + - person10 + - person11 + - person12 + - person13 + - person14 + - person15 + state_code: ID + output: + id_liheap_income_eligible: + - true + - false + id_liheap_household_size: + - 7 + - 8 + id_liheap_countable_income: + - 84000 + - 84000 + id_liheap_income_limit: + - 85245 + - 81225 + +- name: Case 7, financial eligibility does not decide heating responsibility. + # Zero income meets this financial component despite no heat bill. + # This is not a finding of full program eligibility or a heating award. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NONE + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + households: + household1: + members: + - person1 + state_code: ID + output: + id_liheap_income_eligible: + - true + id_liheap_household_size: + - 1 + id_liheap_countable_income: + - 0 + +- name: Case 8, mixed states isolate ordinary and categorical financial routes. + # Idaho meets ordinary income; Washington cannot use this state component. + # The last unit receives SSI, testing the state guard on that route. + # Existing Idaho size/income helpers are zero outside Idaho. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 0 + ssi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 40000 + ssi: + 2026-01: 1 + 2026-02: 1 + 2026-03: 1 + 2026-04: 1 + 2026-05: 1 + 2026-06: 1 + 2026-07: 1 + 2026-08: 1 + 2026-09: 1 + 2026-10: 1 + 2026-11: 1 + 2026-12: 1 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit2: + members: + - person2 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit3: + members: + - person3 + heating_type: NATURAL_GAS + id_tafi: + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + households: + household1: + members: + - person1 + state_code: ID + household2: + members: + - person2 + state_code: WA + household3: + members: + - person3 + state_code: WA + output: + id_liheap_income_eligible: + - true + - false + - false + id_liheap_household_size: + - 1 + - 0 + - 0 + id_liheap_countable_income: + - 0 + - 0 + - 0 + +- name: Case 9, reported SSI receipt establishes the categorical route. + # Modeled SSI is zero, but the member reports receiving SSI. Income of 100,000 + # is far above the size-one ceiling and SNAP is zero across the program year, + # so only the SSI route qualifies. + period: 2026 + input: + people: + person1: + age: 70 + is_citizen_or_legal_immigrant: true + employment_income: 100_000 + ssi: 0 + receives_ssi: + 2026-01: true + spm_units: + spm_unit: + members: [person1] + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + households: + household: + members: [person1] + state_code: ID + output: + id_liheap_income_eligible: true + +- name: Case 10, two cents over the federal maximum for two fails. + # HHS's mandatory FY2026 amount for two people is 42,938. DHW's monthly $3,578.17 would annualize to 42,938.04. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, ssi: 0} + person2: {age: 40, is_citizen_or_legal_immigrant: true, ssi: 0} + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + id_liheap_countable_income: 42_938.02 + snap: + 2025-09: 0 + 2025-10: 0 + 2025-11: 0 + 2025-12: 0 + 2026-01: 0 + 2026-02: 0 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_income_limit: 42_938 + id_liheap_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_income_limit.yaml new file mode 100644 index 00000000000..5ebb4e499dc --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/eligibility/id_liheap_income_limit.yaml @@ -0,0 +1,158 @@ +# Idaho FY2026 LIHEAP plan, 60% of SMI for sizes 1-7 and 150% of the guideline for 8 and up (page 8). +# https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=8 +# DHW published monthly limits effective 2025-10-01; retrieved 2026-10-03. +# 42 U.S.C. 8624(b)(2)(B) and HHS Attachment 4 set the federal maximum. +# https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf#page=1 +# https://healthandwelfare.idaho.gov/services-programs/financial-assistance/home-heating-and-utility-assistance/apply-heating-assistance + +- name: Case 1, published monthly limits annualize under the federal maximum. + period: 2026 + absolute_error_margin: 0.01 + # Sizes 1-10 use published monthly [2736.25,3578.17,4420.08,5262.08, + # 6104,6945.92,7103.75,6768.75,7456.25,8143.75] times 12. + # Sizes 2 and 6 would be 42,938.04 and 83,351.04, so they cap at HHS's 42,938 and 83,351. + # Sizes 3 and 4 stay at DHW's lower 53,040.96 and 63,144.96. + # Size 11 = (8,143.75 + 687.50) x 12 = 105,975; size 15 = (8,143.75 + 5 x 687.50) x 12 = 138,975. + # Size 7 annual 85,245 exceeds size 8 annual 81,225: the explicit SMI-to-FPG switch is not max(). + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + person3: {age: 38, is_citizen_or_legal_immigrant: true} + person4: {age: 40, is_citizen_or_legal_immigrant: true} + person5: {age: 38, is_citizen_or_legal_immigrant: true} + person6: {age: 17, is_citizen_or_legal_immigrant: true} + person7: {age: 40, is_citizen_or_legal_immigrant: true} + person8: {age: 38, is_citizen_or_legal_immigrant: true} + person9: {age: 17, is_citizen_or_legal_immigrant: true} + person10: {age: 16, is_citizen_or_legal_immigrant: true} + person11: {age: 40, is_citizen_or_legal_immigrant: true} + person12: {age: 38, is_citizen_or_legal_immigrant: true} + person13: {age: 17, is_citizen_or_legal_immigrant: true} + person14: {age: 16, is_citizen_or_legal_immigrant: true} + person15: {age: 15, is_citizen_or_legal_immigrant: true} + person16: {age: 40, is_citizen_or_legal_immigrant: true} + person17: {age: 38, is_citizen_or_legal_immigrant: true} + person18: {age: 17, is_citizen_or_legal_immigrant: true} + person19: {age: 16, is_citizen_or_legal_immigrant: true} + person20: {age: 15, is_citizen_or_legal_immigrant: true} + person21: {age: 14, is_citizen_or_legal_immigrant: true} + person22: {age: 40, is_citizen_or_legal_immigrant: true} + person23: {age: 38, is_citizen_or_legal_immigrant: true} + person24: {age: 17, is_citizen_or_legal_immigrant: true} + person25: {age: 16, is_citizen_or_legal_immigrant: true} + person26: {age: 15, is_citizen_or_legal_immigrant: true} + person27: {age: 14, is_citizen_or_legal_immigrant: true} + person28: {age: 13, is_citizen_or_legal_immigrant: true} + person29: {age: 40, is_citizen_or_legal_immigrant: true} + person30: {age: 38, is_citizen_or_legal_immigrant: true} + person31: {age: 17, is_citizen_or_legal_immigrant: true} + person32: {age: 16, is_citizen_or_legal_immigrant: true} + person33: {age: 15, is_citizen_or_legal_immigrant: true} + person34: {age: 14, is_citizen_or_legal_immigrant: true} + person35: {age: 13, is_citizen_or_legal_immigrant: true} + person36: {age: 12, is_citizen_or_legal_immigrant: true} + person37: {age: 40, is_citizen_or_legal_immigrant: true} + person38: {age: 38, is_citizen_or_legal_immigrant: true} + person39: {age: 17, is_citizen_or_legal_immigrant: true} + person40: {age: 16, is_citizen_or_legal_immigrant: true} + person41: {age: 15, is_citizen_or_legal_immigrant: true} + person42: {age: 14, is_citizen_or_legal_immigrant: true} + person43: {age: 13, is_citizen_or_legal_immigrant: true} + person44: {age: 12, is_citizen_or_legal_immigrant: true} + person45: {age: 11, is_citizen_or_legal_immigrant: true} + person46: {age: 40, is_citizen_or_legal_immigrant: true} + person47: {age: 38, is_citizen_or_legal_immigrant: true} + person48: {age: 17, is_citizen_or_legal_immigrant: true} + person49: {age: 16, is_citizen_or_legal_immigrant: true} + person50: {age: 15, is_citizen_or_legal_immigrant: true} + person51: {age: 14, is_citizen_or_legal_immigrant: true} + person52: {age: 13, is_citizen_or_legal_immigrant: true} + person53: {age: 12, is_citizen_or_legal_immigrant: true} + person54: {age: 11, is_citizen_or_legal_immigrant: true} + person55: {age: 10, is_citizen_or_legal_immigrant: true} + person56: {age: 40, is_citizen_or_legal_immigrant: true} + person57: {age: 38, is_citizen_or_legal_immigrant: true} + person58: {age: 17, is_citizen_or_legal_immigrant: true} + person59: {age: 16, is_citizen_or_legal_immigrant: true} + person60: {age: 15, is_citizen_or_legal_immigrant: true} + person61: {age: 14, is_citizen_or_legal_immigrant: true} + person62: {age: 13, is_citizen_or_legal_immigrant: true} + person63: {age: 12, is_citizen_or_legal_immigrant: true} + person64: {age: 11, is_citizen_or_legal_immigrant: true} + person65: {age: 10, is_citizen_or_legal_immigrant: true} + person66: {age: 9, is_citizen_or_legal_immigrant: true} + person67: {age: 40, is_citizen_or_legal_immigrant: true} + person68: {age: 38, is_citizen_or_legal_immigrant: true} + person69: {age: 17, is_citizen_or_legal_immigrant: true} + person70: {age: 16, is_citizen_or_legal_immigrant: true} + person71: {age: 15, is_citizen_or_legal_immigrant: true} + person72: {age: 14, is_citizen_or_legal_immigrant: true} + person73: {age: 13, is_citizen_or_legal_immigrant: true} + person74: {age: 12, is_citizen_or_legal_immigrant: true} + person75: {age: 11, is_citizen_or_legal_immigrant: true} + person76: {age: 10, is_citizen_or_legal_immigrant: true} + person77: {age: 9, is_citizen_or_legal_immigrant: true} + person78: {age: 8, is_citizen_or_legal_immigrant: true} + person79: {age: 7, is_citizen_or_legal_immigrant: true} + person80: {age: 6, is_citizen_or_legal_immigrant: true} + person81: {age: 5, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: {members: [person1], heating_type: NATURAL_GAS} + spm_unit2: {members: [person2, person3], heating_type: NATURAL_GAS} + spm_unit3: {members: [person4, person5, person6], heating_type: NATURAL_GAS} + spm_unit4: {members: [person7, person8, person9, person10], heating_type: NATURAL_GAS} + spm_unit5: {members: [person11, person12, person13, person14, person15], heating_type: NATURAL_GAS} + spm_unit6: {members: [person16, person17, person18, person19, person20, person21], heating_type: NATURAL_GAS} + spm_unit7: {members: [person22, person23, person24, person25, person26, person27, person28], heating_type: NATURAL_GAS} + spm_unit8: {members: [person29, person30, person31, person32, person33, person34, person35, person36], heating_type: NATURAL_GAS} + spm_unit9: {members: [person37, person38, person39, person40, person41, person42, person43, person44, person45], heating_type: NATURAL_GAS} + spm_unit10: {members: [person46, person47, person48, person49, person50, person51, person52, person53, person54, person55], heating_type: NATURAL_GAS} + spm_unit11: {members: [person56, person57, person58, person59, person60, person61, person62, person63, person64, person65, person66], heating_type: NATURAL_GAS} + spm_unit12: {members: [person67, person68, person69, person70, person71, person72, person73, person74, person75, person76, person77, person78, person79, person80, person81], heating_type: NATURAL_GAS} + households: + household1: {members: [person1], state_code: ID} + household2: {members: [person2, person3], state_code: ID} + household3: {members: [person4, person5, person6], state_code: ID} + household4: {members: [person7, person8, person9, person10], state_code: ID} + household5: {members: [person11, person12, person13, person14, person15], state_code: ID} + household6: {members: [person16, person17, person18, person19, person20, person21], state_code: ID} + household7: {members: [person22, person23, person24, person25, person26, person27, person28], state_code: ID} + household8: {members: [person29, person30, person31, person32, person33, person34, person35, person36], state_code: ID} + household9: {members: [person37, person38, person39, person40, person41, person42, person43, person44, person45], state_code: ID} + household10: {members: [person46, person47, person48, person49, person50, person51, person52, person53, person54, person55], state_code: ID} + household11: {members: [person56, person57, person58, person59, person60, person61, person62, person63, person64, person65, person66], state_code: ID} + household12: {members: [person67, person68, person69, person70, person71, person72, person73, person74, person75, person76, person77, person78, person79, person80, person81], state_code: ID} + output: + id_liheap_income_limit: [32_835.0, 42_938.0, 53_040.96, 63_144.96, 73_248.0, 83_351.0, 85_245.0, 81_225.0, 89_475.0, 97_725.0, 105_975.0, 138_975.0] + +- name: Case 2, no qualified member has zero income limit. + period: 2026 + absolute_error_margin: 0.01 + # No eligible household member means no applicable income ceiling. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: false} + spm_units: + spm_unit: {members: [person1], heating_type: NATURAL_GAS} + households: + household: {members: [person1], state_code: ID} + output: + id_liheap_income_limit: 0 + +- name: Case 3, mixed state vector preserves the Idaho limit and masks another state. + period: 2026 + absolute_error_margin: 0.01 + # Idaho one-person monthly 2,736.25 x 12 = 32,835; California 0. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: {members: [person1], heating_type: NATURAL_GAS} + spm_unit2: {members: [person2], heating_type: NATURAL_GAS} + households: + household1: {members: [person1], state_code: ID} + household2: {members: [person2], state_code: CA} + output: + id_liheap_income_limit: [32_835, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/id_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/id_liheap.yaml new file mode 100644 index 00000000000..122e2536bc4 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/id_liheap.yaml @@ -0,0 +1,325 @@ +# Expected amounts come from the PY26 Benefit Determination Chart and its summary (pages 1-2). +# https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=1 +# Burden = estimated annual heating cost / annual income, with the PY2007 costs: +# electricity 1_335, 1_455, 1_605; natural gas 977, 1_100, 1_207; +# oil or propane 1_625, 1_845, 2_145; coal or wood 1_200, 1_600, 1_800 (Areas I, II, III). +# Ada County is Area I, Bannock County Area II, Bear Lake County Area III. +# Low burden is under 6%, medium 6% to under 11%, high 11% or more. +# Income 40_000 is low and 8_000 high for every fuel and area. +# Cases 1 to 8 set has_heating_expense directly; a bill would not change the amount. + +- name: Case 1, electric heat pays the Idaho Power and Southern Utilities column in every cell. + period: 2026 + absolute_error_margin: 0.01 + # Income 16_000 is medium: 8.34%, 9.09%, 10.03%. + input: + state_code: [ID, ID, ID, ID, ID, ID, ID, ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, + BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, + BEAR_LAKE_COUNTY_ID, BEAR_LAKE_COUNTY_ID, BEAR_LAKE_COUNTY_ID] + heating_type: [ELECTRICITY, ELECTRICITY, ELECTRICITY, + ELECTRICITY, ELECTRICITY, ELECTRICITY, + ELECTRICITY, ELECTRICITY, ELECTRICITY] + id_liheap_countable_income: [40_000, 16_000, 8_000, + 40_000, 16_000, 8_000, + 40_000, 16_000, 8_000] + id_liheap_income_eligible: [true, true, true, true, true, true, true, true, true] + has_heating_expense: [true, true, true, true, true, true, true, true, true] + output: + id_liheap: [328, 342, 355, + 378, 394, 410, + 429, 447, 464] + +- name: Case 2, natural gas pays the Intermountain Gas column in every cell. + period: 2026 + absolute_error_margin: 0.01 + # Income 12_000 is medium: 8.14%, 9.17%, 10.06%. + input: + state_code: [ID, ID, ID, ID, ID, ID, ID, ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, + BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, + BEAR_LAKE_COUNTY_ID, BEAR_LAKE_COUNTY_ID, BEAR_LAKE_COUNTY_ID] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + id_liheap_countable_income: [40_000, 12_000, 8_000, + 40_000, 12_000, 8_000, + 40_000, 12_000, 8_000] + id_liheap_income_eligible: [true, true, true, true, true, true, true, true, true] + has_heating_expense: [true, true, true, true, true, true, true, true, true] + output: + id_liheap: [122, 127, 132, + 141, 147, 152, + 159, 166, 173] + +- name: Case 3, fuel oil and propane share the oil or propane column in every cell. + period: 2026 + absolute_error_margin: 0.01 + # Income 20_000 is medium: 8.13%, 9.23%, 10.73%. + input: + state_code: [ID, ID, ID, ID, ID, ID, ID, ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, + BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, + BEAR_LAKE_COUNTY_ID, BEAR_LAKE_COUNTY_ID, BEAR_LAKE_COUNTY_ID] + heating_type: [FUEL_OIL, FUEL_OIL, FUEL_OIL, + PROPANE, PROPANE, PROPANE, + FUEL_OIL, FUEL_OIL, FUEL_OIL] + id_liheap_countable_income: [40_000, 20_000, 8_000, + 40_000, 20_000, 8_000, + 40_000, 20_000, 8_000] + id_liheap_income_eligible: [true, true, true, true, true, true, true, true, true] + has_heating_expense: [true, true, true, true, true, true, true, true, true] + output: + id_liheap: [776, 808, 840, + 970, 1_010, 1_050, + 1_164, 1_212, 1_260] + +- name: Case 4, coal and wood share the coal or wood column in every cell. + period: 2026 + absolute_error_margin: 0.01 + # Income 18_000 is medium: 6.67%, 8.89%, 10%. + input: + state_code: [ID, ID, ID, ID, ID, ID, ID, ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, + BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, + BEAR_LAKE_COUNTY_ID, BEAR_LAKE_COUNTY_ID, BEAR_LAKE_COUNTY_ID] + heating_type: [WOOD, WOOD, WOOD, + COAL, COAL, COAL, + WOOD, WOOD, WOOD] + id_liheap_countable_income: [40_000, 18_000, 8_000, + 40_000, 18_000, 8_000, + 40_000, 18_000, 8_000] + id_liheap_income_eligible: [true, true, true, true, true, true, true, true, true] + has_heating_expense: [true, true, true, true, true, true, true, true, true] + output: + id_liheap: [467, 486, 505, + 544, 567, 590, + 622, 648, 674] + +- name: Case 5, burden bands turn at exactly 6 percent and 11 percent, and zero income is high. + period: 2026 + absolute_error_margin: 0.01 + # Bannock electricity 1_455: 1_455 / 24_250 = 6% is medium; 24_251 is low. + # Bannock gas 1_100: 1_100 / 10_000 = 11% is high; 10_001 is medium; zero income is high. + input: + state_code: [ID, ID, ID, ID, ID] + county: [BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID, + BANNOCK_COUNTY_ID, BANNOCK_COUNTY_ID] + heating_type: [ELECTRICITY, ELECTRICITY, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + id_liheap_countable_income: [24_250, 24_251, 10_000, 10_001, 0] + id_liheap_income_eligible: [true, true, true, true, true] + has_heating_expense: [true, true, true, true, true] + output: + id_liheap: [394, 378, 152, 147, 152] + +- name: Case 6, a child under six, an adult of 60 and a disabled adult add the target bonus. + period: 2026 + absolute_error_margin: 0.01 + # Ada gas at low burden is 122, and 122 + 25 = 147, the chart's lowest bonus amount. + # The last row is Bear Lake oil at high burden: 1_260 + 25 = 1_285, the chart's highest. + input: + state_code: [ID, ID, ID, ID, ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID, + BEAR_LAKE_COUNTY_ID] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, FUEL_OIL] + age: [5, 6, 59, 60, 40, 60] + is_disabled: [false, false, false, false, true, false] + id_liheap_countable_income: [40_000, 40_000, 40_000, 40_000, 40_000, 8_000] + id_liheap_income_eligible: [true, true, true, true, true, true] + has_heating_expense: [true, true, true, true, true, true] + output: + id_liheap: [147, 122, 122, 147, 147, 1_285] + +- name: Case 7, several vulnerable members earn one target bonus. + period: 2026 + absolute_error_margin: 0.01 + # Ada gas at low burden: 122 + 25 = 147. + input: + people: + person1: + age: 65 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + id_liheap_countable_income: 40_000 + id_liheap_income_eligible: true + has_heating_expense: true + households: + household: + members: [person1, person2] + state_code: ID + county: ADA_COUNTY_ID + output: + id_liheap: 147 + +- name: Case 8, a vulnerable member who is not a qualified member earns no target bonus. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + person2: + age: 65 + is_citizen_or_legal_immigrant: false + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + id_liheap_countable_income: 40_000 + id_liheap_income_eligible: true + has_heating_expense: true + households: + household: + members: [person1, person2] + state_code: ID + county: ADA_COUNTY_ID + output: + id_liheap: 122 + +- name: Case 9, heat in rent paid 75 in FY2025 with the target bonus on top. + period: 2025 + absolute_error_margin: 0.01 + # PY25 chart Rent column and its 75 and 100 low amounts. + input: + state_code: [ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID] + heating_type: [NATURAL_GAS, NATURAL_GAS] + heat_expense_included_in_rent: [true, true] + age: [40, 60] + id_liheap_income_eligible: [true, true] + output: + id_liheap: [75, 100] + +- name: Case 10, ineligible households, fuels with no chart column and heat in rent from FY2026 receive nothing. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [ID, ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID] + heating_type: [NATURAL_GAS, OTHER, NATURAL_GAS] + heat_expense_included_in_rent: [false, false, true] + has_heating_expense: [true, true, false] + age: [60, 60, 60] + id_liheap_income_eligible: [false, true, true] + output: + id_liheap: [0, 0, 0] + +- name: Case 11, a parent and child in Bannock County at the medium burden. + period: 2026 + absolute_error_margin: 0.01 + # Wages 18_000 and no other income; 1_100 / 18_000 = 6.11% is medium; the child is eight. + # The 900 gas bill shows the obligation; the PY2007 table sets the burden. + input: + people: + person1: + age: 35 + employment_income_before_lsr: 18_000 + person2: + age: 8 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 900 + takes_up_tanf_if_eligible: false + households: + household: + members: [person1, person2] + state_code: ID + county: BANNOCK_COUNTY_ID + output: + id_liheap_countable_income: 18_000 + id_liheap_estimated_heating_cost: 1_100 + id_liheap_eligible: true + id_liheap: 147 + +- name: Case 12, solar with an electric bill pays the electric column and kerosene with a bill the oil column. + period: 2026 + absolute_error_margin: 0.01 + # Ada County. Solar: 1_335 / 16_000 = 8.34% is medium, 342. + # Kerosene: 1_625 / 20_000 = 8.13% is medium, 808. + input: + state_code: [ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID] + heating_type: [SOLAR, KEROSENE] + pre_subsidy_electricity_expense: [1_000, 0] + fuel_oil_expense: [0, 800] + id_liheap_countable_income: [16_000, 20_000] + id_liheap_income_eligible: [true, true] + output: + id_liheap: [342, 808] + +- name: Case 13, VA benefits and a minor's earnings can put a household over the limit. + period: 2026 + absolute_error_margin: 0.01 + # IDAPA 16.04.14.010.06 counts them. Ada County, gas with a bill, SNAP zero over the program year. + # VA 35_000 is over the one-person 32_835. Wages 36_000 + 8_000 = 44_000 are over the two-person 42_938. + input: + people: + person1: + age: 45 + veterans_benefits: 35_000 + person2: + age: 40 + employment_income_before_lsr: 36_000 + person3: + age: 17 + employment_income_before_lsr: 8_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 900 + takes_up_tanf_if_eligible: false + snap: {2025-10: 0, 2025-11: 0, 2025-12: 0, 2026-01: 0, 2026-02: 0, 2026-03: 0, 2026-04: 0, 2026-05: 0, 2026-06: 0, 2026-07: 0, 2026-08: 0, 2026-09: 0} + spm_unit2: + members: [person2, person3] + heating_type: NATURAL_GAS + gas_expense: 900 + takes_up_tanf_if_eligible: false + snap: {2025-10: 0, 2025-11: 0, 2025-12: 0, 2026-01: 0, 2026-02: 0, 2026-03: 0, 2026-04: 0, 2026-05: 0, 2026-06: 0, 2026-07: 0, 2026-08: 0, 2026-09: 0} + households: + household1: + members: [person1] + state_code: ID + county: ADA_COUNTY_ID + household2: + members: [person2, person3] + state_code: ID + county: ADA_COUNTY_ID + output: + id_liheap_countable_income: [35_000, 44_000] + id_liheap_income_limit: [32_835, 42_938] + id_liheap_eligible: [false, false] + id_liheap: [0, 0] + +- name: Case 14, the Idaho AABD supplement counts and can move the burden band. + period: 2026 + absolute_error_margin: 0.01 + # SSI (994 a month x 12) 11_928 + AABD (53 a month x 12) 636 = 12_564. Ada County electric 1_335 / 12_564 + # = 10.63% is medium, 342, plus the 25 bonus at age 65. Without AABD, 1_335 / 11_928 = 11.19% would be high. + input: + people: + person1: + age: 65 + ssi: 11_928 + id_aabd_living_arrangement: SINGLE + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + takes_up_tanf_if_eligible: false + households: + household: + members: [person1] + state_code: ID + county: ADA_COUNTY_ID + output: + id_aabd: 636 + id_liheap_countable_income: 12_564 + id_liheap: 367 diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/id_liheap_estimated_heating_cost.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/id_liheap_estimated_heating_cost.yaml new file mode 100644 index 00000000000..a71cdf164e0 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/id_liheap_estimated_heating_cost.yaml @@ -0,0 +1,74 @@ +# Historical Idaho LIHEAP Intake Manual, Appendix C, physical page 1. +# https://web.archive.org/web/20170127123014id_/http://www.healthandwelfare.idaho.gov/Portals/_Rainbow/Manuals/LIHEAP/Appendices/c_htgcost_matrix_PY07.pdf#page=1 +# PY2007 estimated nine-month costs are used as a modeling assumption; +# their current FY2026 applicability is unconfirmed. No inflation or 12/9 scaling. +# Electricity uses Idaho Power & Southern Utilities. Natural gas uses the +# Intermountain column as a modeling simplification, without a provider input. + +- name: Case 1, six supported fuels use the historical costs in all three areas. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [ID, ID, ID, ID, ID, ID, ID, ID, ID, + ID, ID, ID, ID, ID, ID, ID, ID, ID] + county: [ADA_COUNTY_ID, BANNOCK_COUNTY_ID, BEAR_LAKE_COUNTY_ID, + ADA_COUNTY_ID, BANNOCK_COUNTY_ID, BEAR_LAKE_COUNTY_ID, + ADA_COUNTY_ID, BANNOCK_COUNTY_ID, BEAR_LAKE_COUNTY_ID, + ADA_COUNTY_ID, BANNOCK_COUNTY_ID, BEAR_LAKE_COUNTY_ID, + ADA_COUNTY_ID, BANNOCK_COUNTY_ID, BEAR_LAKE_COUNTY_ID, + ADA_COUNTY_ID, BANNOCK_COUNTY_ID, BEAR_LAKE_COUNTY_ID] + heating_type: [ELECTRICITY, ELECTRICITY, ELECTRICITY, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + FUEL_OIL, FUEL_OIL, FUEL_OIL, + PROPANE, PROPANE, PROPANE, + WOOD, WOOD, WOOD, + COAL, COAL, COAL] + output: + id_liheap_estimated_heating_cost: [1_335, 1_455, 1_605, + 977, 1_100, 1_207, + 1_625, 1_845, 2_145, + 1_625, 1_845, 2_145, + 1_200, 1_600, 1_800, + 1_200, 1_600, 1_800] + +- name: Case 2, unknown areas and unsupported fuels have no modeled cost. + period: 2026 + absolute_error_margin: 0.01 + # Zero denotes an unmodeled cost, not a legal eligibility determination. + input: + state_code: [ID, ID, ID, ID, ID] + county: [UNKNOWN, BAKER_COUNTY_OR, ADA_COUNTY_ID, ADA_COUNTY_ID, ADA_COUNTY_ID] + heating_type: [ELECTRICITY, ELECTRICITY, UNSPECIFIED, NONE, OTHER] + output: + id_liheap_estimated_heating_cost: [0, 0, 0, 0, 0] + +- name: Case 3, omitted county uses the shared Ada fallback and its electric cost. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: ID + heating_type: ELECTRICITY + output: + county_str: ADA_COUNTY_ID + id_liheap_estimated_heating_cost: 1_335 + +- name: Case 4, mixed-state households isolate Idaho estimated heating costs. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [ID, OR, ID, OR] + county: [BEAR_LAKE_COUNTY_ID, BEAR_LAKE_COUNTY_ID, + ADA_COUNTY_ID, BAKER_COUNTY_OR] + heating_type: [NATURAL_GAS, NATURAL_GAS, COAL, ELECTRICITY] + output: + id_liheap_estimated_heating_cost: [1_207, 0, 1_200, 0] + +- name: Case 5, solar uses the electric cost and kerosene the oil cost. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [ID, ID] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID] + heating_type: [SOLAR, KEROSENE] + output: + id_liheap_estimated_heating_cost: [1_335, 1_625] diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/id_liheap_heating_area.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/id_liheap_heating_area.yaml new file mode 100644 index 00000000000..504edb4660b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/id_liheap_heating_area.yaml @@ -0,0 +1,87 @@ +# Historical Idaho LIHEAP Intake Manual, Appendix A, physical page 2. +# https://web.archive.org/web/20170124204651id_/http://healthandwelfare.idaho.gov/portals/_rainbow/manuals/liheap/Appendices/a_codes_all.pdf#page=2 +# This undated map continues as a modeling assumption. +# Expected areas follow the complete left table in county-code order 1-44. +# The right table duplicates Power and omits Elmore; Elmore is in Area I. + +- name: Case 1, all forty-four counties follow the recovered county table. + period: 2026 + input: + state_code: [ID, ID, ID, ID, ID, ID, ID, ID, ID, ID, ID, + ID, ID, ID, ID, ID, ID, ID, ID, ID, ID, ID, + ID, ID, ID, ID, ID, ID, ID, ID, ID, ID, ID, + ID, ID, ID, ID, ID, ID, ID, ID, ID, ID, ID] + county: + - ADA_COUNTY_ID + - ADAMS_COUNTY_ID + - BANNOCK_COUNTY_ID + - BEAR_LAKE_COUNTY_ID + - BENEWAH_COUNTY_ID + - BINGHAM_COUNTY_ID + - BLAINE_COUNTY_ID + - BOISE_COUNTY_ID + - BONNER_COUNTY_ID + - BONNEVILLE_COUNTY_ID + - BOUNDARY_COUNTY_ID + - BUTTE_COUNTY_ID + - CAMAS_COUNTY_ID + - CANYON_COUNTY_ID + - CARIBOU_COUNTY_ID + - CASSIA_COUNTY_ID + - CLARK_COUNTY_ID + - CLEARWATER_COUNTY_ID + - CUSTER_COUNTY_ID + - ELMORE_COUNTY_ID + - FRANKLIN_COUNTY_ID + - FREMONT_COUNTY_ID + - GEM_COUNTY_ID + - GOODING_COUNTY_ID + - IDAHO_COUNTY_ID + - JEFFERSON_COUNTY_ID + - JEROME_COUNTY_ID + - KOOTENAI_COUNTY_ID + - LATAH_COUNTY_ID + - LEMHI_COUNTY_ID + - LEWIS_COUNTY_ID + - LINCOLN_COUNTY_ID + - MADISON_COUNTY_ID + - MINIDOKA_COUNTY_ID + - NEZ_PERCE_COUNTY_ID + - ONEIDA_COUNTY_ID + - OWYHEE_COUNTY_ID + - PAYETTE_COUNTY_ID + - POWER_COUNTY_ID + - SHOSHONE_COUNTY_ID + - TETON_COUNTY_ID + - TWIN_FALLS_COUNTY_ID + - VALLEY_COUNTY_ID + - WASHINGTON_COUNTY_ID + output: + id_liheap_heating_area: [1, 2, 2, 3, 2, 2, 3, 2, 2, 3, 2, + 3, 3, 1, 3, 2, 3, 2, 3, 1, 2, 3, + 1, 1, 2, 3, 2, 2, 1, 3, 2, 2, 3, + 2, 1, 2, 1, 1, 2, 2, 3, 2, 3, 1] + +- name: Case 2, unknown and out-of-state county strings remain unassigned. + period: 2026 + input: + state_code: [ID, ID] + county: [UNKNOWN, BAKER_COUNTY_OR] + output: + id_liheap_heating_area: [0, 0] + +- name: Case 3, omitted county inherits the shared Ada County fallback. + period: 2026 + input: + state_code: ID + output: + county_str: ADA_COUNTY_ID + id_liheap_heating_area: 1 + +- name: Case 4, mixed-state households only assign an Idaho heating area. + period: 2026 + input: + state_code: [ID, OR, OR] + county: [ADA_COUNTY_ID, ADA_COUNTY_ID, BAKER_COUNTY_OR] + output: + id_liheap_heating_area: [1, 0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/income/id_liheap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/income/id_liheap_countable_income.yaml new file mode 100644 index 00000000000..75172af05ee --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/id/dhw/liheap/income/id_liheap_countable_income.yaml @@ -0,0 +1,499 @@ +# Idaho FY2026 LIHEAP plan, gross income checkboxes and other-income text (pages 5-7). +# https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=5 +# IDAPA 16.03.08 section 202 includes income of nonqualified household members (page 6). +# https://adminrules.idaho.gov/rules/current/16/160308.pdf#page=6 +# IDAPA 16.04.14.010.06 and 151.02 define income for FY2026 heating (pages 3, 5). +# https://web.archive.org/web/20250910171431id_/https://adminrules.idaho.gov/rules/current/16/160414.pdf#page=3 + +- name: Case 1, a minor's earnings, VA benefits and general assistance count and child support does not. + period: 2026 + absolute_error_margin: 0.01 + # Adult 12,000 + child wages 6,000 + SSI (100 a month x 12) 1,200 + VA 3,000 + GA 900 = 23,100. + # IDAPA 16.04.14.151.02.t excludes the child support. + # The SSI input of 1,200 is the annual amount for a MONTH variable in a YEAR test. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: true, ssi: 0, employment_income: 12_000} + person2: {age: 17, is_citizen_or_legal_immigrant: true, employment_income: 6_000, ssi: 1_200, child_support_received: 6_000, veterans_benefits: 3_000, general_assistance: 900} + spm_units: + spm_unit: {members: [person1, person2], heating_type: NATURAL_GAS, id_tafi: 0} + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_countable_income: 23_100 + +- name: Case 2, an eighteen-year-old's earnings count. + period: 2026 + absolute_error_margin: 0.01 + # The 12,000 of adult wages and the 18-year-old's 6,000 of earnings both count. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: true, ssi: 0, employment_income: 12_000} + person2: {age: 18, is_citizen_or_legal_immigrant: true, ssi: 0, employment_income: 6_000} + spm_units: + spm_unit: {members: [person1, person2], heating_type: NATURAL_GAS, id_tafi: 0} + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_countable_income: 18_000 + +- name: Case 3, nonqualified parent income still counts for citizen child. + period: 2026 + absolute_error_margin: 0.01 + # The parent is excluded from eligible size but their 20,000 of wages remain countable. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: false, employment_income: 20_000, ssi: 0} + person2: {age: 8, is_citizen_or_legal_immigrant: true, ssi: 0} + spm_units: + spm_unit: {members: [person1, person2], heating_type: NATURAL_GAS, id_tafi: 0} + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_countable_income: 20_000 + +- name: Case 4, all represented unearned sources count without pension double counting. + period: 2026 + absolute_error_margin: 0.01 + # Social Security 12,000 + SSI 1,200 + pension (1,000 + 2,000 + 300 + 400) 3,700 + survivor 500 + # + unemployment 2,400 + strike 300 + rent 600 + farm rent 700 + alimony 400 + # + interest 200 + dividends 250 + estate 800 + disability 900 + workers' compensation 1,000 = 24,950. + # Pension and SSA subcomponents each enter their aggregates exactly once. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, ssi: 0, social_security_disability: 12_000, taxable_public_pension_income: 1_000, taxable_private_pension_income: 2_000, tax_exempt_public_pension_income: 300, tax_exempt_private_pension_income: 400, survivor_benefits: 500, unemployment_compensation: 2_400, strike_benefits: 300, rental_income: 600, farm_rent_income: 700, alimony_income: 400, interest_income: 200, ordinary_dividend_income: 250, estate_income: 800, disability_benefits: 900, workers_compensation: 1_000} + person2: {age: 8, is_citizen_or_legal_immigrant: true, ssi: 1_200} + spm_units: + spm_unit: {members: [person1, person2], heating_type: NATURAL_GAS, id_tafi: 0} + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_countable_income: 24_950 + +- name: Case 5, all supported earned business streams count. + period: 2026 + absolute_error_margin: 0.01 + # Gross wages 10,000 + basic pay 500 + net business streams 2,000 + 3,000 + 4,000 + 5,000 = 24,500. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, ssi: 0, employment_income: 10_000, military_basic_pay: 500, self_employment_income: 2_000, sstb_self_employment_income: 3_000, farm_operations_income: 4_000, partnership_s_corp_income: 5_000} + spm_units: + spm_unit: {members: [person1], heating_type: NATURAL_GAS, id_tafi: 0} + households: + household: {members: [person1], state_code: ID} + output: + id_liheap_countable_income: 24_500 + +- name: Case 6, negative business sources do not offset positive earnings. + period: 2026 + absolute_error_margin: 0.01 + # Net-business approximation: 10,000 + max(-9,000, 0) + 2,000 + max(-7,000, 0) + 3,000 = 15,000. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, ssi: 0, employment_income: 10_000, self_employment_income: -9_000, sstb_self_employment_income: 2_000, farm_operations_income: -7_000, partnership_s_corp_income: 3_000} + spm_units: + spm_unit: {members: [person1], heating_type: NATURAL_GAS, id_tafi: 0} + households: + household: {members: [person1], state_code: ID} + output: + id_liheap_countable_income: 15_000 + +- name: Case 7, monthly SSI and TAFI aggregate once over the year. + period: 2026 + absolute_error_margin: 0.01 + # Child SSI 100 + 200 = 300; SPM TAFI 300 + 200 + 100 = 600; total 900. + # All other months are explicitly 0, and TAFI must not be multiplied by household size. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: true, ssi: {2026-01: 0, 2026-02: 0, 2026-03: 0, 2026-04: 0, 2026-05: 0, 2026-06: 0, 2026-07: 0, 2026-08: 0, 2026-09: 0, 2026-10: 0, 2026-11: 0, 2026-12: 0}} + person2: {age: 8, is_citizen_or_legal_immigrant: true, ssi: {2026-01: 100, 2026-02: 200, 2026-03: 0, 2026-04: 0, 2026-05: 0, 2026-06: 0, 2026-07: 0, 2026-08: 0, 2026-09: 0, 2026-10: 0, 2026-11: 0, 2026-12: 0}} + spm_units: + spm_unit: {members: [person1, person2], heating_type: NATURAL_GAS, id_tafi: {2026-01: 300, 2026-02: 200, 2026-03: 100, 2026-04: 0, 2026-05: 0, 2026-06: 0, 2026-07: 0, 2026-08: 0, 2026-09: 0, 2026-10: 0, 2026-11: 0, 2026-12: 0}} + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_countable_income: 900 + +- name: Case 8, child support is excluded and VA benefits and general assistance count. + period: 2026 + absolute_error_margin: 0.01 + # IDAPA 16.04.14.151.02.t excludes child support 9,000; VA 5,000 + GA 2,000 = 7,000 count. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: true, ssi: 0, child_support_received: 9_000, veterans_benefits: 5_000, general_assistance: 2_000} + person2: {age: 8, is_citizen_or_legal_immigrant: true, ssi: 0} + spm_units: + spm_unit: {members: [person1, person2], heating_type: NATURAL_GAS, id_tafi: 0} + households: + household: {members: [person1, person2], state_code: ID} + output: + id_liheap_countable_income: 7_000 + +- name: Case 9, mixed states and unequal memberships retain separate income totals. + period: 2026 + absolute_error_margin: 0.01 + # First Idaho unit 6,000 + 6,000 = 12,000; Colorado 0; + # second Idaho unit adult 1,800 + minor wages 10,000 + child SSI 1,800 = 13,600. + input: + people: + person1: {age: 35, is_citizen_or_legal_immigrant: true, ssi: 0, employment_income: 6_000} + person2: {age: 34, is_citizen_or_legal_immigrant: false, employment_income: 6_000, ssi: 0} + person3: {age: 40, is_citizen_or_legal_immigrant: true, ssi: 0, employment_income: 12_000} + person4: {age: 35, is_citizen_or_legal_immigrant: true, ssi: 0, employment_income: 1_800} + person5: {age: 12, is_citizen_or_legal_immigrant: true, employment_income: 10_000, ssi: 1_800} + spm_units: + spm_unit1: {members: [person1, person2], heating_type: NATURAL_GAS, id_tafi: 0} + spm_unit2: {members: [person3], heating_type: NATURAL_GAS, id_tafi: 0} + spm_unit3: {members: [person4, person5], heating_type: NATURAL_GAS, id_tafi: 0} + households: + household1: {members: [person1, person2], state_code: ID} + household2: {members: [person3], state_code: CO} + household3: {members: [person4, person5], state_code: ID} + output: + id_liheap_countable_income: [12_000, 0, 13_600] + +# Ongoing retirement receipts: pension 1,000 + taxable IRA 12,000 + exempt IRA 3,000. +# Count the two aggregates once; one-time lump sums are not represented here. +- name: Case 10, recurring taxable and exempt retirement distributions count beside pensions. + 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: NATURAL_GAS + id_tafi: 0 + households: + household: + members: [person] + state_code: ID + output: + id_liheap_countable_income: 16_000 + +# FY2026 one-person limit 32,835. Gross Social Security 34,000 minus actual Part B 2,400 = 31,600. +# Military 40,000 and pension 34,000 exceed the limit. Rental losses are not deductions. +# UI 36,000 fails; reported UI gives 31,200; a negative receipt leaves 30,000. +# TANF receipt controls use the two-person limit 42,938, with no TANF categorical bypass. +- name: Case 11, military retirement net Social Security and rental loss affect financial + eligibility. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + military_retirement_pay: 40_000 + person2: + age: 68 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 34_000 + medicare_part_b_premium: 2_400 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + pension_income: 34_000 + rental_income: -10_000 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NATURAL_GAS + id_tafi: 0 + snap: + 2025: 0 + 2026: 0 + spm_unit2: + members: + - person2 + heating_type: NATURAL_GAS + id_tafi: 0 + snap: + 2025: 0 + 2026: 0 + spm_unit3: + members: + - person3 + heating_type: NATURAL_GAS + id_tafi: 0 + snap: + 2025: 0 + 2026: 0 + households: + household1: + members: + - person1 + state_code: ID + household2: + members: + - person2 + state_code: ID + household3: + members: + - person3 + state_code: ID + output: + id_liheap_countable_income: + - 40_000 + - 31_600 + - 34_000 + id_liheap_income_limit: + - 32_835 + - 32_835 + - 32_835 + id_liheap_income_eligible: + - false + - true + - false +- name: Case 12, excess Medicare premiums cannot reduce another income source. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 68 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 1_000 + medicare_part_b_premium: 2_400 + pension_income: 34_000 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NATURAL_GAS + id_tafi: 0 + snap: + 2025: 0 + 2026: 0 + households: + household1: + members: + - person1 + state_code: ID + output: + id_liheap_countable_income: 34_000 + id_liheap_income_eligible: false +- name: Case 13, UI uses the receipt helper and cannot offset positive wages. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + employment_income: 30_000 + unemployment_compensation: 0 + modeled_state_unemployment_compensation: 6_000 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + employment_income: 30_000 + unemployment_compensation: 1_200 + modeled_state_unemployment_compensation: 6_000 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + employment_income: 30_000 + unemployment_compensation: -100 + modeled_state_unemployment_compensation: 6_000 + spm_units: + spm_unit1: + members: + - person1 + heating_type: NATURAL_GAS + id_tafi: 0 + snap: + 2025: 0 + 2026: 0 + spm_unit2: + members: + - person2 + heating_type: NATURAL_GAS + id_tafi: 0 + snap: + 2025: 0 + 2026: 0 + spm_unit3: + members: + - person3 + heating_type: NATURAL_GAS + id_tafi: 0 + snap: + 2025: 0 + 2026: 0 + households: + household1: + members: + - person1 + state_code: ID + household2: + members: + - person2 + state_code: ID + household3: + members: + - person3 + state_code: ID + output: + total_unemployment_compensation: + - 6_000 + - 1_200 + - -100 + id_liheap_countable_income: + - 36_000 + - 31_200 + - 30_000 + id_liheap_income_eligible: + - false + - true + - true +- name: Case 14, received TANF counts once without creating a categorical route. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + employment_income: 40_000 + person2: + age: 8 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + employment_income: 40_000 + person4: + age: 8 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + spm_units: + spm_unit1: + members: + - person1 + - person2 + heating_type: NATURAL_GAS + id_tafi: 6_000 + snap: + 2025: 0 + 2026: 0 + takes_up_tanf_if_eligible: true + spm_unit2: + members: + - person3 + - person4 + heating_type: NATURAL_GAS + id_tafi: 6_000 + snap: + 2025: 0 + 2026: 0 + takes_up_tanf_if_eligible: false + households: + household1: + members: + - person1 + - person2 + state_code: ID + household2: + members: + - person3 + - person4 + state_code: ID + output: + tanf: + - 6_000 + - 0 + id_liheap_countable_income: + - 46_000 + - 40_000 + id_liheap_income_eligible: + - false + - true + +# Plan item 1.9 counts retirement and pension benefits: railroad retirement 6,000. +- name: Case 15, railroad retirement counts as a retirement benefit. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + medicare_part_b_premium: 0 + railroad_benefits: 6_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + id_tafi: 0 + households: + household: + members: [person1] + state_code: ID + output: + id_liheap_countable_income: 6_000 + +# Plan 1.9's Other line and IDAPA 16.04.14.151.02.f count gifts and lottery winnings +# over $30. The $30 test has no input, so annual amounts count in full: +# wages 25,000 + winnings 1,000 + gifts 500. +- name: Case 16, gifts and lottery winnings count. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 25_000 + gambling_winnings: 1_000 + financial_assistance: 500 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + id_tafi: 0 + households: + household: + members: [person1] + state_code: ID + output: + id_liheap_countable_income: 26_500 diff --git a/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_eligible.py b/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_eligible.py new file mode 100644 index 00000000000..580521fea16 --- /dev/null +++ b/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_eligible.py @@ -0,0 +1,34 @@ +from policyengine_us.model_api import * + + +class id_liheap_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Eligible for Idaho LIHEAP regular heating assistance" + definition_period = YEAR + defined_for = StateCode.ID + reference = ( + # PDF pages 8-9 + "https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=8", + "https://adminrules.idaho.gov/rules/current/16/160308.pdf#page=5", + # IDAPA 16.04.14.001.02 and 152.02, in force for all of FY2026 heating. + # PDF pages 3, 6 + "https://web.archive.org/web/20250910171431id_/https://adminrules.idaho.gov/rules/current/16/160414.pdf#page=3", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.id.dhw.liheap.payment + income_eligible = spm_unit("id_liheap_income_eligible", period) + cost = spm_unit("id_liheap_estimated_heating_cost", period) + heat_in_rent = spm_unit("heat_expense_included_in_rent", period) + # Plan 2.3 requires the household to pay for heat. has_heating_expense + # reads the primary fuel's bill, or can be set directly; the bill does + # not set the amount. + pays_for_heat = spm_unit("has_heating_expense", period) + # Heat in rent stands for no specific heating-cost obligation; a + # designated heat charge within the rent has no input. That base is + # zero from FY2026, when plan 2.5 makes these households ineligible. + # Other subsidized tenants paying for heat follow the general chart. + return income_eligible & where( + heat_in_rent, p.rent > 0, (cost > 0) & pays_for_heat + ) diff --git a/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_household_size.py b/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_household_size.py new file mode 100644 index 00000000000..8389296e807 --- /dev/null +++ b/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_household_size.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class id_liheap_household_size(Variable): + value_type = int + entity = SPMUnit + label = "Idaho LIHEAP eligible household size" + definition_period = YEAR + defined_for = StateCode.ID + reference = "https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=9" + # The SPM unit approximates the economic unit sharing heating costs. + adds = ["is_citizen_or_legal_immigrant"] diff --git a/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_income_eligible.py b/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_income_eligible.py new file mode 100644 index 00000000000..10ac696b5c2 --- /dev/null +++ b/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_income_eligible.py @@ -0,0 +1,33 @@ +from policyengine_us.model_api import * + + +class id_liheap_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Idaho LIHEAP modeled income eligibility" + definition_period = YEAR + defined_for = StateCode.ID + reference = ( + "https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=5", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.id.dhw.liheap.eligibility + size = spm_unit("id_liheap_household_size", period) + income = spm_unit("id_liheap_countable_income", period) + limit = spm_unit("id_liheap_income_limit", period) + # SNAP receipt can occur anywhere in the October-September program year. + snap_period = period.offset( + p.program_year_start_month - 1 - MONTHS_IN_YEAR, "month" + ) + receives_snap = spm_unit("snap", snap_period, options=[ADD]) > 0 + # Annual SSI is a stable-current-receipt proxy because the application + # month is not an input. Any member may establish categorical eligibility. + person = spm_unit.members + receives_ssi = spm_unit.any( + (person("ssi", period, options=[ADD]) > 0) + | (add(person, period, ["receives_ssi"]) > 0) + ) + # Means-tested VA receipt also qualifies, but veterans_benefits does not + # identify that category. This unmodeled route is not a legal exclusion. + return (size > 0) & ((income <= limit) | receives_snap | receives_ssi) diff --git a/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_income_limit.py b/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_income_limit.py new file mode 100644 index 00000000000..0e813b1b196 --- /dev/null +++ b/policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_income_limit.py @@ -0,0 +1,47 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import liheap_smi_limit +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class id_liheap_income_limit(Variable): + value_type = float + entity = SPMUnit + label = "Idaho LIHEAP annual income limit" + unit = USD + definition_period = YEAR + defined_for = StateCode.ID + reference = ( + "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", + "https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=8", + "https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf#page=1", + "https://healthandwelfare.idaho.gov/services-programs/financial-assistance/home-heating-and-utility-assistance/apply-heating-assistance", + ) + + def formula(spm_unit, period, parameters): + size = spm_unit("id_liheap_household_size", period) + state = spm_unit.household("state_code_str", period) + group = spm_unit.household("state_group_str", period) + p = parameters(period) + eligibility = p.gov.states.id.dhw.liheap.eligibility + # The shared helper's flooring order matches all seven HHS FY2026 amounts. + # DHW prints monthly limits in cents. At sizes 2 and 6 they annualize 4 cents + # above those amounts, the federal maximum, so the cap applies there. + annual_smi = liheap_smi_limit( + size, state, eligibility.smi_rate, period, parameters + ) + monthly_smi = np.round(annual_smi / MONTHS_IN_YEAR, 2) + annual_fpg = eligibility.fpg_rate * fpg( + size, + group, + period, + parameters, + year_lag=eligibility.fpg_year_lag, + ) + # The plan explicitly switches to FPG at size eight, even though this + # lowers the limit; using max(SMI, FPG) would contradict its table. + annual_limit = where( + size <= eligibility.smi_max_household_size, + min_(monthly_smi * MONTHS_IN_YEAR, annual_smi), + annual_fpg, + ) + return where(size > 0, annual_limit, 0) diff --git a/policyengine_us/variables/gov/states/id/dhw/liheap/id_liheap.py b/policyengine_us/variables/gov/states/id/dhw/liheap/id_liheap.py new file mode 100644 index 00000000000..06e83a89f2c --- /dev/null +++ b/policyengine_us/variables/gov/states/id/dhw/liheap/id_liheap.py @@ -0,0 +1,64 @@ +from policyengine_us.model_api import * + + +class id_liheap(Variable): + value_type = float + entity = SPMUnit + label = "Idaho LIHEAP regular heating assistance" + unit = USD + definition_period = YEAR + defined_for = "id_liheap_eligible" + reference = ( + # PDF pages 1-2 + "https://liheapch.acf.gov/docs/2026/benefits-matricies/ID_BenefitMatrix_Heating_2026.pdf#page=1", + "https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=9", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.id.dhw.liheap.payment + cost = spm_unit("id_liheap_estimated_heating_cost", period) + income = spm_unit("id_liheap_countable_income", period) + # Zero income has the highest burden. + burden_group = select( + [ + cost >= income * p.energy_burden.high_rate, + cost >= income * p.energy_burden.medium_rate, + ], + [3, 2], + default=1, + ) + # Safe lookup; eligibility already requires a known area. + area = clip(spm_unit("id_liheap_heating_area", period), 1, 3) + heating = spm_unit("heating_type", period) + types = heating.possible_values + chart_amount = select( + [ + (heating == types.ELECTRICITY) | (heating == types.SOLAR), + heating == types.NATURAL_GAS, + (heating == types.FUEL_OIL) + | (heating == types.KEROSENE) + | (heating == types.PROPANE), + (heating == types.COAL) | (heating == types.WOOD), + ], + [ + p.matrix.electricity[area][burden_group], + p.matrix.natural_gas[area][burden_group], + p.matrix.oil_or_propane[area][burden_group], + p.matrix.coal_or_wood[area][burden_group], + ], + default=0, + ) + heat_in_rent = spm_unit("heat_expense_included_in_rent", period) + person = spm_unit.members + # Annual age stands in for age by the end of the program year. + age = person("age", period) + vulnerable = ( + (age < p.target_bonus.child_age_limit) + | (age >= p.target_bonus.elderly_age) + | person("is_disabled", period) + ) + qualified = person("is_citizen_or_legal_immigrant", period) + target_bonus = spm_unit.any(vulnerable & qualified) * p.target_bonus.amount + # The chart's $122 minimum and $1,285 maximum are its own lowest and + # highest amounts, so no separate limits apply. + return where(heat_in_rent, p.rent, chart_amount) + target_bonus diff --git a/policyengine_us/variables/gov/states/id/dhw/liheap/id_liheap_estimated_heating_cost.py b/policyengine_us/variables/gov/states/id/dhw/liheap/id_liheap_estimated_heating_cost.py new file mode 100644 index 00000000000..5e3443a285a --- /dev/null +++ b/policyengine_us/variables/gov/states/id/dhw/liheap/id_liheap_estimated_heating_cost.py @@ -0,0 +1,42 @@ +from policyengine_us.model_api import * + + +class id_liheap_estimated_heating_cost(Variable): + value_type = float + entity = SPMUnit + label = "Idaho LIHEAP estimated heating cost" + unit = USD + definition_period = YEAR + defined_for = StateCode.ID + reference = "https://web.archive.org/web/20170127123014id_/http://www.healthandwelfare.idaho.gov/Portals/_Rainbow/Manuals/LIHEAP/Appendices/c_htgcost_matrix_PY07.pdf#page=1" + + def formula(spm_unit, period, parameters): + area = spm_unit("id_liheap_heating_area", period) + heating = spm_unit("heating_type", period) + types = heating.possible_values + p = parameters(period).gov.states.id.dhw.liheap.payment.estimated_heating_costs + # PY2007 nine-month cost proxy; FY2026 applicability is unconfirmed. + # Safe lookup leaves unknown areas unassigned after fuel selection. + # No Idaho source names solar or kerosene. As in heating_expense, solar + # reads as electric and kerosene as the chart's oil. + lookup_area = clip(area, 1, 3) + cost = select( + [ + (heating == types.ELECTRICITY) | (heating == types.SOLAR), + heating == types.NATURAL_GAS, + (heating == types.FUEL_OIL) + | (heating == types.KEROSENE) + | (heating == types.PROPANE), + (heating == types.COAL) | (heating == types.WOOD), + ], + [ + p.electricity[lookup_area], + p.natural_gas[lookup_area], + p.oil_or_propane[lookup_area], + p.coal_or_wood[lookup_area], + ], + default=0, + ) + # Zero for unknown area or unsupported fuel is no modeled cost, + # not a determination of legal ineligibility or actual heating costs. + return where((area >= 1) & (area <= 3), cost, 0) diff --git a/policyengine_us/variables/gov/states/id/dhw/liheap/id_liheap_heating_area.py b/policyengine_us/variables/gov/states/id/dhw/liheap/id_liheap_heating_area.py new file mode 100644 index 00000000000..3edd6ee3225 --- /dev/null +++ b/policyengine_us/variables/gov/states/id/dhw/liheap/id_liheap_heating_area.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class id_liheap_heating_area(Variable): + value_type = int + entity = SPMUnit + label = "Idaho LIHEAP heating area" + definition_period = YEAR + defined_for = StateCode.ID + reference = "https://web.archive.org/web/20170124204651id_/http://healthandwelfare.idaho.gov/portals/_rainbow/manuals/liheap/Appendices/a_codes_all.pdf#page=2" + + def formula(spm_unit, period, parameters): + county = spm_unit.household("county_str", period) + p = parameters(period).gov.states.id.dhw.liheap.payment.heating_areas + # Area codes match the benefit matrix; zero leaves unmatched counties + # unassigned. The recovered map continues as a modeling assumption. + return select( + [ + np.isin(county, p.area_1), + np.isin(county, p.area_2), + np.isin(county, p.area_3), + ], + [1, 2, 3], + default=0, + ) diff --git a/policyengine_us/variables/gov/states/id/dhw/liheap/income/id_liheap_countable_income.py b/policyengine_us/variables/gov/states/id/dhw/liheap/income/id_liheap_countable_income.py new file mode 100644 index 00000000000..5d693f0e49e --- /dev/null +++ b/policyengine_us/variables/gov/states/id/dhw/liheap/income/id_liheap_countable_income.py @@ -0,0 +1,38 @@ +from policyengine_us.model_api import * + + +class id_liheap_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Idaho LIHEAP countable annual income" + unit = USD + definition_period = YEAR + defined_for = StateCode.ID + reference = ( + # PDF pages 5-7 + "https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=5", + # IDAPA 16.04.14.010.06 and 151.02. PDF pages 3, 5 + "https://web.archive.org/web/20250910171431id_/https://adminrules.idaho.gov/rules/current/16/160414.pdf#page=3", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.id.dhw.liheap.income + person = spm_unit.members + # Annual flows approximate prior-month receipts. Source losses do not + # offset other receipts; existing net business inputs need no deduction. + earned = 0 + for source in p.sources.earned: + earned = earned + max_(add(person, period, [source]), 0) + unearned = 0 + for source in p.sources.unearned: + unearned = unearned + max_(add(person, period, [source]), 0) + social_security = max_( + person("social_security", period) + - person("medicare_part_b_premium", period), + 0, + ) + # Every member's income counts, nonqualified members' and minors' included. + # IDAPA 16.04.14.151.02.t leaves out child support, which is in neither list. + return spm_unit.sum(earned + unearned + social_security) + spm_unit( + "tanf", period + ) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 10770cf9257..15835a001d7 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -3398,6 +3398,119 @@ candidates: state: ruled note: 'Ruled statute-first in October 2026; confirm line 12(c)''s scope against the per-person statute and worksheet. Code not yet on main: id_grocery_credit.' +- id: us-id:liheap-heat-in-rent-fy2026 + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Is an Idaho household that pays for heat through its rent eligible for FY2026 regular heating, as the rule in + force until June 2026 provides, or ineligible, as the FY2026 plan provides? + sources: + - kind: regulation + citation: IDAPA 16.04.14.152.02 and 16.04.14.010.08.b, effective April 6, 2023 + url: https://www.law.cornell.edu/regulations/idaho/IDAPA-16.04.14.152 + - kind: plan + citation: Idaho FY2026 LIHEAP State Plan, items 2.3 and 2.5, PDF pages 8-9 + url: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=8 + - kind: regulation + citation: IDAPA 16.03.08.200.07, effective July 1, 2026 + url: https://adminrules.idaho.gov/rules/current/16/160308.pdf#page=5 + readings: + statute: No statute is supplied; 16.04.14.152.02 covers households that incur home energy costs "either directly or as + an undesignated portion of their rent". From July 1, 2026, 16.03.08.200.07 says "designated portion". + other: Plan 2.5 says "Household with no specific heat cost obligation (included in rent, rent subsidized) will not be + eligible to a LIHEAP benefit", and the PY26 chart has no rent amount. + example: One person aged 65 with $15,000 of Social Security and natural gas heat included in rent in Ada County receives + $0 under the plan. Under 16.04.14.152.02 the household is eligible, and no FY2026 amount is printed for it. + pe_us: + follows: conflicting-source + code: + - policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_eligible.py + - policyengine_us/parameters/gov/states/id/dhw/liheap/payment/rent.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10613 + state: ruled + note: 'Ruled 2026-11-02 and confirmed 2026-11-03: heat in rent is read as no specific obligation and is ineligible from + FY2026, although plan 1.1 runs heating assistance from October 2025 to March 2026, all under 16.04.14. Basis: 16.04.14 + sets no amount (001.02: "does not entitle any household to a certain amount or form of assistance"), and the PY26 + chart, the only FY2026 amount instrument, drops the Rent column PY25 had. A designated heat charge within rent has no + input.' +- id: us-id:liheap-monthly-limit-above-federal-ceiling + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Can Idaho's monthly income limits in cents pay a household whose annual income exceeds HHS's 60% state median + income amount? + 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: guidance + citation: HHS LIHEAP IM 2025-02 Attachment 4, Mandatory Use in LIHEAP for FY26, Idaho, pages 1 and 4 + url: https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf#page=1 + - kind: guidance + citation: Idaho DHW Apply for Heating Assistance, monthly income limits effective October 1, 2025 + url: https://healthandwelfare.idaho.gov/services-programs/financial-assistance/home-heating-and-utility-assistance/apply-heating-assistance + readings: + statute: Payments go only to households whose income does not exceed the greater of 150% of the poverty guideline and + 60% of the state median income, which HHS publishes as $42,938 for two people and $83,351 for six. + other: DHW prints $3,578.17 and $6,945.92 a month, which annualize to $42,938.04 and $83,351.04. + example: Two adults with $42,938.02 of wages and natural gas heat in Ada County exceed the $42,938 federal maximum and + receive $0. The annualized monthly limit would pay $122. + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/states/id/dhw/liheap/eligibility/id_liheap_income_limit.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10613 + state: unreviewed + note: The PR caps the annualized monthly limit at HHS's amount. DHW's lower annualized figures at sizes 3 and 4 ($53,040.96 + and $63,144.96) stay, since a lower limit is allowed. +- id: us-id:liheap-plan-income-checklist + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Do VA benefits, general assistance and minors' earnings count for Idaho LIHEAP in FY2026, as IDAPA 16.04.14 + provides, or stay out under the FY2026 plan checklist? + sources: + - kind: regulation + citation: IDAPA 16.04.14.010.06 and 16.04.14.151.02, effective April 6, 2023 + url: https://www.law.cornell.edu/regulations/idaho/IDAPA-16.04.14.010 + - kind: plan + citation: Idaho FY2026 LIHEAP State Plan, section 1.9, PDF pages 5-7 + url: https://liheapch.acf.gov/docs/2026/state-plans/ID_Plan_2026.pdf#page=5 + - kind: regulation + citation: IDAPA 16.03.08.202, effective July 1, 2026 + url: https://adminrules.idaho.gov/rules/current/16/160308.pdf#page=6 + readings: + statute: No statute is supplied; 16.04.14.010.06 counts moneys "from all sources", and the closed exclusion list at + 151.02 names only GI Bill education money among VA payments and no general assistance or minors' earnings. + other: Plan 1.9 leaves "General Assistance benefits", "Veterans Administration (VA) benefits" and "Earned income of a + child under the age of 18" unchecked. From July 1, 2026, 16.03.08.202 counts gross income as the Department determines. + example: A veteran aged 45 with $35,000 of VA disability compensation and natural gas heat in Ada County counts $35,000 + under the rule, above the $32,835 limit, and receives $0. Under the plan the household counts $0 and receives $132. + pe_us: + follows: statute + code: + - policyengine_us/parameters/gov/states/id/dhw/liheap/income/sources/earned.yaml + - policyengine_us/parameters/gov/states/id/dhw/liheap/income/sources/unearned.yaml + - policyengine_us/variables/gov/states/id/dhw/liheap/income/id_liheap_countable_income.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10613 + state: ruled + note: 'Ruled 2026-11-05 for the regulation by the project lead; the ruling record is + https://github.com/PolicyEngine/policyengine-us/pull/10613#issuecomment-6665844738. 16.04.14.010.06 defines income as moneys "from all sources", the + 151.02 exclusion list is closed, and 16.04.14 does not delegate countable income to the department or adopt the state + plan. The rule was in force April 6, 2023 to June 30, 2026, and plan 1.1 runs FY2026 heating October 1, 2025 to March + 31, 2026, so it governed every heating determination. us-nm:liheap-plan-income-checklist followed its regulation over + the same checklist. The ruling covers VA benefits, general assistance, minors'' earnings and id_aabd; Part B netting + under plan 1.9 and miscellaneous_income, pfml_benefits, life_insurance_benefits, gi_cash_assistance and capital_gains, + which stay uncounted, are unchanged and outside it.' - id: us-il:2022-rebate-claimed-vs-claimable program: income-tax years: