From 4491487fec9ea9090172c84bec3910e31dd1fa7f Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 30 Sep 2026 15:01:33 -0400 Subject: [PATCH 1/7] Add Nebraska LIHEAP regular heating assistance --- changelog.d/ne-liheap.added.md | 1 + .../dhhs/liheap/earned_income_disregard.yaml | 10 + .../states/ne/dhhs/liheap/fpg_year_lag.yaml | 10 + .../states/ne/dhhs/liheap/income_limit.yaml | 10 + .../states/ne/dhhs/liheap/payment/oil.yaml | 27 ++ .../ne/dhhs/liheap/payment/propane.yaml | 27 ++ .../ne/dhhs/liheap/payment/utility.yaml | 27 ++ .../states/ne/dhhs/liheap/payment/wood.yaml | 27 ++ .../ne/dhhs/liheap/payment_size_limit.yaml | 10 + policyengine_us/programs.yaml | 10 +- .../states/ne/dhhs/liheap/integration.yaml | 182 ++++++++++ .../gov/states/ne/dhhs/liheap/ne_liheap.yaml | 333 ++++++++++++++++++ .../ne/dhhs/liheap/ne_liheap_eligible.yaml | 40 +++ .../states/ne/dhhs/liheap/ne_liheap_fpg.yaml | 91 +++++ .../dhhs/liheap/ne_liheap_household_size.yaml | 69 ++++ .../liheap/ne_liheap_income_eligible.yaml | 41 +++ .../gov/states/ne/dhhs/liheap/ne_liheap.py | 52 +++ .../ne/dhhs/liheap/ne_liheap_earned_income.py | 27 ++ .../ne/dhhs/liheap/ne_liheap_eligible.py | 20 ++ .../states/ne/dhhs/liheap/ne_liheap_fpg.py | 24 ++ .../ne/dhhs/liheap/ne_liheap_gross_income.py | 27 ++ .../dhhs/liheap/ne_liheap_household_size.py | 19 + .../dhhs/liheap/ne_liheap_income_eligible.py | 16 + 23 files changed, 1099 insertions(+), 1 deletion(-) create mode 100644 changelog.d/ne-liheap.added.md create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_disregard.yaml create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/oil.yaml create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/propane.yaml create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/utility.yaml create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/wood.yaml create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment_size_limit.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.yaml create mode 100644 policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py create mode 100644 policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py create mode 100644 policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py create mode 100644 policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_fpg.py create mode 100644 policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py create mode 100644 policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py create mode 100644 policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py diff --git a/changelog.d/ne-liheap.added.md b/changelog.d/ne-liheap.added.md new file mode 100644 index 00000000000..b691f41d8f6 --- /dev/null +++ b/changelog.d/ne-liheap.added.md @@ -0,0 +1 @@ +Add partial FY2026 Nebraska LIHEAP regular heating assistance using existing inputs. diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_disregard.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_disregard.yaml new file mode 100644 index 00000000000..8f9350af5e0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_disregard.yaml @@ -0,0 +1,10 @@ +description: Nebraska disregards this share of gross countable earned income when determining regular heating payments after testing gross-income eligibility under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 0.2 +metadata: + unit: /1 + period: year + label: Nebraska LIHEAP earned income disregard + reference: + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025 + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml new file mode 100644 index 00000000000..fde423c25c8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml @@ -0,0 +1,10 @@ +description: Nebraska uses federal poverty guidelines from this many years before the modeled heating-season ending year under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 1 +metadata: + unit: year + period: year + label: Nebraska LIHEAP federal poverty guideline year lag + reference: + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025 + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml new file mode 100644 index 00000000000..e5bc1c8a07e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml @@ -0,0 +1,10 @@ +description: Nebraska limits gross countable income to this share of the federal poverty guidelines under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 1.5 +metadata: + unit: /1 + period: year + label: Nebraska LIHEAP income limit + reference: + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025 + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/oil.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/oil.yaml new file mode 100644 index 00000000000..b636a0b0db5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/oil.yaml @@ -0,0 +1,27 @@ +description: Nebraska provides these regular single-family heating payments for fuel oil and kerosene by countable income as a share of the federal poverty guideline under the Low Income Home Energy Assistance Program. +brackets: + - threshold: + 2025-10-01: -.inf + amount: + 2025-10-01: 1_050 + - threshold: + 2025-10-01: 0.7 + amount: + 2025-10-01: 650 + - threshold: + 2025-10-01: 1 + amount: + 2025-10-01: 350 + - threshold: + 2025-10-01: 1.3 + amount: + 2025-10-01: 175 +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: year + label: Nebraska LIHEAP fuel oil and kerosene heating payment + reference: + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025, Heating Payment Computation + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/propane.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/propane.yaml new file mode 100644 index 00000000000..8c3863a5dc5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/propane.yaml @@ -0,0 +1,27 @@ +description: Nebraska provides these regular single-family heating payments for propane by countable income as a share of the federal poverty guideline under the Low Income Home Energy Assistance Program. +brackets: + - threshold: + 2025-10-01: -.inf + amount: + 2025-10-01: 850 + - threshold: + 2025-10-01: 0.7 + amount: + 2025-10-01: 580 + - threshold: + 2025-10-01: 1 + amount: + 2025-10-01: 330 + - threshold: + 2025-10-01: 1.3 + amount: + 2025-10-01: 165 +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: year + label: Nebraska LIHEAP propane heating payment + reference: + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025, Heating Payment Computation + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/utility.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/utility.yaml new file mode 100644 index 00000000000..d96598d1d9e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/utility.yaml @@ -0,0 +1,27 @@ +description: Nebraska provides these regular single-family heating payments for natural gas, electricity, coal, and corn by countable income as a share of the federal poverty guideline under the Low Income Home Energy Assistance Program. +brackets: + - threshold: + 2025-10-01: -.inf + amount: + 2025-10-01: 700 + - threshold: + 2025-10-01: 0.7 + amount: + 2025-10-01: 550 + - threshold: + 2025-10-01: 1 + amount: + 2025-10-01: 400 + - threshold: + 2025-10-01: 1.3 + amount: + 2025-10-01: 280 +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: year + label: Nebraska LIHEAP natural gas, electricity, coal, and corn heating payment + reference: + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025, Heating Payment Computation + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/wood.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/wood.yaml new file mode 100644 index 00000000000..6641910bbc2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/wood.yaml @@ -0,0 +1,27 @@ +description: Nebraska provides these regular single-family heating payments for wood by countable income as a share of the federal poverty guideline under the Low Income Home Energy Assistance Program. +brackets: + - threshold: + 2025-10-01: -.inf + amount: + 2025-10-01: 800 + - threshold: + 2025-10-01: 0.7 + amount: + 2025-10-01: 600 + - threshold: + 2025-10-01: 1 + amount: + 2025-10-01: 350 + - threshold: + 2025-10-01: 1.3 + amount: + 2025-10-01: 175 +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: year + label: Nebraska LIHEAP wood heating payment + reference: + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025, Heating Payment Computation + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment_size_limit.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment_size_limit.yaml new file mode 100644 index 00000000000..965fd6df34f --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment_size_limit.yaml @@ -0,0 +1,10 @@ +description: Nebraska caps household size at this number when determining regular heating payment income bands under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 6 +metadata: + unit: person + period: year + label: Nebraska LIHEAP payment band household size limit + reference: + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025 + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 81c10bc47b6..df52c81153d 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -802,7 +802,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: OR, DC, Riverside County, MA, IL, TX + coverage: OR, DC, Riverside County, MA, IL, TX, NE state_implementations: - state: OR status: in_progress @@ -830,6 +830,14 @@ programs: variable: tx_ceap parameter_prefix: gov.states.tx.tdhca.ceap notes: Models the FPG income limit, the FY2024-only SMI limit, benefit amounts, and categorical eligibility through TANF enrollment, SNAP eligibility, and SSI receipt. Not modeled - net rather than gross gambling winnings, the Medicare premium deduction from counted Social Security, and the exclusion of means-tested veterans' pensions from counted income (10 TAC 6.4(c)) + - state: NE + status: partial + name: Nebraska LIHEAP + full_name: Nebraska Low Income Home Energy Assistance Program + variable: ne_liheap + parameter_prefix: gov.states.ne.dhhs.liheap + verified_start_year: 2026 + notes: FY2026 regular single-family heating schedule, gross-income eligibility, and earned-income disregard. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net self-employment income without another business deduction. Multifamily rates, economic vulnerability for heat included in rent, program disqualifications, detailed immigration conditions, business-record expense alternatives, farm-loss offsets, and discretionary heating supplements are not modeled. Requires a positive heating expense and a supported primary fuel. Calendar 2026 represents the season ending in 2026; earlier years have no verified formula. No cooling, crisis, weatherization, or equipment assistance. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml new file mode 100644 index 00000000000..07060e2be78 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml @@ -0,0 +1,182 @@ +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 + +- name: Case 1, wages receive the earned disregard only after gross eligibility. + period: 2026 + input: + people: + person1: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + employment_income: 18_000 + spm_units: + spm_unit: + members: &id001 + - person1 + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 0 + households: + household: + members: *id001 + state_code: NE + output: + ne_liheap_household_size: 1 + ne_liheap_earned_income: 18_000 + ne_liheap_gross_income: 18_000 + ne_liheap_fpg: 15_650 + ne_liheap_income_eligible: true + ne_liheap_eligible: true + ne_liheap: 550 +- name: Case 2, unearned income does not receive the earned disregard. + period: 2026 + input: + people: + person1: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + social_security_retirement: 18_000 + spm_units: + spm_unit: + members: &id002 + - person1 + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 0 + households: + household: + members: *id002 + state_code: NE + output: + ne_liheap_earned_income: 0 + ne_liheap_gross_income: 18_000 + ne_liheap_income_eligible: true + ne_liheap: 400 +- name: Case 3, business losses do not offset wages in the documented net-income approximation. + period: 2026 + input: + people: + person1: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + employment_income: 10_000 + self_employment_income: -5_000 + spm_units: + spm_unit: + members: &id003 + - person1 + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 0 + households: + household: + members: *id003 + state_code: NE + output: + ne_liheap_earned_income: 10_000 + ne_liheap_gross_income: 10_000 + ne_liheap: 700 +- name: Case 4, existing net business income is counted without another business deduction. + period: 2026 + input: + people: + person1: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + self_employment_income: 18_000 + spm_units: + spm_unit: + members: &id004 + - person1 + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 0 + households: + household: + members: *id004 + state_code: NE + output: + ne_liheap_earned_income: 18_000 + ne_liheap_gross_income: 18_000 + ne_liheap: 550 +- name: Case 5, student child earnings are excluded until age eighteen. + period: 2026 + input: + people: + person1: + age: 17 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + is_in_k12_school: true + employment_income: 30_000 + person2: + age: 18 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + is_in_k12_school: true + employment_income: 10_000 + spm_units: + spm_unit: + members: &id005 + - person1 + - person2 + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 0 + households: + household: + members: *id005 + state_code: NE + output: + ne_liheap_household_size: 2 + ne_liheap_earned_income: 10_000 + ne_liheap_gross_income: 10_000 + ne_liheap_fpg: 21_150 + ne_liheap: 700 +- name: Case 6, ineligible immigrant is excluded from size and their income is prorated. + period: 2026 + input: + people: + person1: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + employment_income: 10_000 + person2: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: UNDOCUMENTED + employment_income: 10_000 + interest_income: 1_000 + spm_units: + spm_unit: + members: &id006 + - person1 + - person2 + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 0 + households: + household: + members: *id006 + state_code: NE + output: + ne_liheap_household_size: 1 + ne_liheap_earned_income: 15_000 + ne_liheap_gross_income: 15_500 + ne_liheap_fpg: 15_650 + ne_liheap_income_eligible: true + ne_liheap: 550 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml new file mode 100644 index 00000000000..c59a2768a2e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml @@ -0,0 +1,333 @@ +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 + +- name: Case 1, fuel oil single-family schedule at 0 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: FUEL_OIL + output: + ne_liheap: 1_050 +- name: Case 2, fuel oil single-family schedule at 1 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 15_650 + ne_liheap_earned_income: 0 + heating_type: FUEL_OIL + output: + ne_liheap: 650 +- name: Case 3, fuel oil single-family schedule at 1.3 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 20_345 + ne_liheap_earned_income: 0 + heating_type: FUEL_OIL + output: + ne_liheap: 350 +- name: Case 4, fuel oil single-family schedule at 1.5 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 23_475 + ne_liheap_earned_income: 0 + heating_type: FUEL_OIL + output: + ne_liheap: 175 +- name: Case 5, wood single-family schedule at 0 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: WOOD + output: + ne_liheap: 800 +- name: Case 6, wood single-family schedule at 1 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 15_650 + ne_liheap_earned_income: 0 + heating_type: WOOD + output: + ne_liheap: 600 +- name: Case 7, wood single-family schedule at 1.3 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 20_345 + ne_liheap_earned_income: 0 + heating_type: WOOD + output: + ne_liheap: 350 +- name: Case 8, wood single-family schedule at 1.5 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 23_475 + ne_liheap_earned_income: 0 + heating_type: WOOD + output: + ne_liheap: 175 +- name: Case 9, propane single-family schedule at 0 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: PROPANE + output: + ne_liheap: 850 +- name: Case 10, propane single-family schedule at 1 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 15_650 + ne_liheap_earned_income: 0 + heating_type: PROPANE + output: + ne_liheap: 580 +- name: Case 11, propane single-family schedule at 1.3 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 20_345 + ne_liheap_earned_income: 0 + heating_type: PROPANE + output: + ne_liheap: 330 +- name: Case 12, propane single-family schedule at 1.5 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 23_475 + ne_liheap_earned_income: 0 + heating_type: PROPANE + output: + ne_liheap: 165 +- name: Case 13, natural gas single-family schedule at 0 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: NATURAL_GAS + output: + ne_liheap: 700 +- name: Case 14, natural gas single-family schedule at 1 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 15_650 + ne_liheap_earned_income: 0 + heating_type: NATURAL_GAS + output: + ne_liheap: 550 +- name: Case 15, natural gas single-family schedule at 1.3 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 20_345 + ne_liheap_earned_income: 0 + heating_type: NATURAL_GAS + output: + ne_liheap: 400 +- name: Case 16, natural gas single-family schedule at 1.5 FPG. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 23_475 + ne_liheap_earned_income: 0 + heating_type: NATURAL_GAS + output: + ne_liheap: 280 +- name: Case 17, countable income of 10955 respects the closed upper tier boundary. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 10_955 + ne_liheap_earned_income: 0 + heating_type: NATURAL_GAS + output: + ne_liheap: 700 +- name: Case 18, countable income of 10955 respects the closed upper tier boundary. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 10_955.01 + ne_liheap_earned_income: 0 + heating_type: NATURAL_GAS + output: + ne_liheap: 550 +- name: Case 19, countable income of 15650 respects the closed upper tier boundary. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 15_650.01 + ne_liheap_earned_income: 0 + heating_type: NATURAL_GAS + output: + ne_liheap: 400 +- name: Case 20, countable income of 20345 respects the closed upper tier boundary. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 20_345.01 + ne_liheap_earned_income: 0 + heating_type: NATURAL_GAS + output: + ne_liheap: 280 +- name: Case 21, countable income of -100 respects the closed upper tier boundary. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: -100 + ne_liheap_earned_income: 0 + heating_type: NATURAL_GAS + output: + ne_liheap: 700 +- name: Case 22, kerosene fuel mapping. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: KEROSENE + output: + ne_liheap: 1_050 +- name: Case 23, electricity fuel mapping. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: ELECTRICITY + output: + ne_liheap: 700 +- name: Case 24, coal fuel mapping. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: COAL + output: + ne_liheap: 700 +- name: Case 25, other fuel mapping. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: OTHER + output: + ne_liheap: 0 +- name: Case 26, solar fuel mapping. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: SOLAR + output: + ne_liheap: 0 +- name: Case 27, unspecified fuel mapping. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: UNSPECIFIED + output: + ne_liheap: 0 +- name: Case 28, none fuel mapping. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 0 + ne_liheap_earned_income: 0 + heating_type: NONE + output: + ne_liheap: 0 +- name: Case 29, seventh person increases eligibility but not payment bands. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 7 + ne_liheap_gross_income: 31_000 + ne_liheap_earned_income: 0 + heating_type: PROPANE + output: + ne_liheap: 580 +- name: Case 30, earned disregard lowers the payment tier only. + period: 2026 + input: + state_code: NE + ne_liheap_eligible: true + ne_liheap_household_size: 1 + ne_liheap_gross_income: 20_000 + ne_liheap_earned_income: 20_000 + heating_type: NATURAL_GAS + output: + ne_liheap: 400 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml new file mode 100644 index 00000000000..d4bc2bff276 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml @@ -0,0 +1,40 @@ +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 + +- name: Case 1, direct heating bill establishes energy responsibility. + period: 2026 + input: + state_code: NE + ne_liheap_income_eligible: true + heating_type: NATURAL_GAS + gas_expense: 100 + output: + ne_liheap_eligible: true +- name: Case 2, heat in rent does not by itself establish economic vulnerability. + period: 2026 + input: + state_code: NE + ne_liheap_income_eligible: true + heat_expense_included_in_rent: true + pre_subsidy_rent: 10_000 + output: + ne_liheap_eligible: false +- name: Case 3, income failure excludes household with heating expenses. + period: 2026 + input: + state_code: NE + ne_liheap_income_eligible: false + heating_type: NATURAL_GAS + gas_expense: 100 + output: + ne_liheap_eligible: false +- name: Case 4, another state receives no Nebraska benefit. + period: 2026 + input: + state_code: KS + ne_liheap_income_eligible: true + heating_type: NATURAL_GAS + gas_expense: 100 + output: + ne_liheap_eligible: false + ne_liheap: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml new file mode 100644 index 00000000000..b66665669af --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml @@ -0,0 +1,91 @@ +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 + +- name: Case 1, FY2026 guideline for 1 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 1 + output: + ne_liheap_fpg: 15_650 +- name: Case 2, FY2026 guideline for 2 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 2 + output: + ne_liheap_fpg: 21_150 +- name: Case 3, FY2026 guideline for 3 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 3 + output: + ne_liheap_fpg: 26_650 +- name: Case 4, FY2026 guideline for 4 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 4 + output: + ne_liheap_fpg: 32_150 +- name: Case 5, FY2026 guideline for 5 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 5 + output: + ne_liheap_fpg: 37_650 +- name: Case 6, FY2026 guideline for 6 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 6 + output: + ne_liheap_fpg: 43_150 +- name: Case 7, FY2026 guideline for 7 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 7 + output: + ne_liheap_fpg: 48_650 +- name: Case 8, FY2026 guideline for 8 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 8 + output: + ne_liheap_fpg: 54_150 +- name: Case 9, FY2026 guideline for 9 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 9 + output: + ne_liheap_fpg: 59_650 +- name: Case 10, FY2026 guideline for 10 members uses 2025 federal amounts. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 10 + output: + ne_liheap_fpg: 65_150 +- name: Case 11, no eligible members yields no guideline. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 0 + output: + ne_liheap_fpg: 0 + ne_liheap_income_eligible: false +- name: Case 12, unverified earlier years do not use the FY2026 schedule. + period: 2022 + input: + state_code: NE + heating_type: NATURAL_GAS + gas_expense: 1_000 + output: + ne_liheap: 0 + ne_liheap_fpg: 0 + ne_liheap_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml new file mode 100644 index 00000000000..64e8b543ee1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml @@ -0,0 +1,69 @@ +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 + +- name: Case 1, mixed households keep Nebraska eligibility and payments separate. + period: 2026 + input: + people: + person1: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + employment_income: 18_000 + person2: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: UNDOCUMENTED + person3: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + spm_units: + spm1: + members: + - person1 + tanf: 0 + heating_type: PROPANE + bottled_gas_expense: 1_000 + spm2: + members: + - person2 + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 1_000 + spm3: + members: + - person3 + tanf: 0 + heating_type: WOOD + wood_expense: 1_000 + households: + household1: + members: + - person1 + state_code: NE + household2: + members: + - person2 + state_code: NE + household3: + members: + - person3 + state_code: KS + output: + ne_liheap_household_size: + - 1 + - 0 + - 0 + ne_liheap_eligible: + - true + - false + - false + ne_liheap: + - 580 + - 0 + - 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.yaml new file mode 100644 index 00000000000..2f37c77c3c1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.yaml @@ -0,0 +1,41 @@ +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 + +- name: Case 1, gross income exactly at the FY2026 one-person limit. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 1 + ne_liheap_gross_income: 23_475 + output: + ne_liheap_fpg: 15_650 + ne_liheap_income_eligible: true + +- name: Case 2, earned-income disregard cannot establish income eligibility. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 1 + ne_liheap_gross_income: 23_476 + ne_liheap_earned_income: 23_476 + output: + ne_liheap_income_eligible: false + +- name: Case 3, ninth member increases the income limit without monthly rounding. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 9 + ne_liheap_gross_income: 89_475 + output: + ne_liheap_fpg: 59_650 + ne_liheap_income_eligible: true + +- name: Case 4, ninth member income limit is exceeded. + period: 2026 + input: + state_code: NE + ne_liheap_household_size: 9 + ne_liheap_gross_income: 89_476 + output: + ne_liheap_income_eligible: false diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py new file mode 100644 index 00000000000..c1ce699c8c5 --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py @@ -0,0 +1,52 @@ +from policyengine_us.model_api import * + + +class ne_liheap(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Nebraska LIHEAP regular heating assistance" + defined_for = "ne_liheap_eligible" + reference = "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2" + + def formula_2026(spm_unit, period, parameters): + p = parameters(period).gov.states.ne.dhhs.liheap + gross = spm_unit("ne_liheap_gross_income", period) + earned = spm_unit("ne_liheap_earned_income", period) + income = max_(gross - earned * p.earned_income_disregard, 0) + size = spm_unit("ne_liheap_household_size", period) + fpg = spm_unit("ne_liheap_fpg", period) + state_group = spm_unit.household("state_group_str", period) + fpg_year = period.start.year - int(p.fpg_year_lag) + federal = parameters(f"{fpg_year}-01-01").gov.hhs.fpg + # The payment bands stop growing at six people; eligibility does not. + payment_fpg = fpg - federal.additional_person[state_group] * max_( + size - p.payment_size_limit, 0 + ) + income_ratio = income / max_(payment_fpg, 1) + fuel = spm_unit("heating_type", period) + types = fuel.possible_values + # Single-family schedule only: no existing input distinguishes the + # 476 NAC 1-004.11/.16 dwelling categories. Multifamily rates are not + # inferred from tenure or subsidy status. This remains partial coverage. + # OTHER cannot isolate corn; SOLAR/UNSPECIFIED also lack a supported + # single-family table mapping. These fuel categories return zero. + # No FY2026 supplemental heating amount has been verified. + return select( + [ + (fuel == types.FUEL_OIL) | (fuel == types.KEROSENE), + fuel == types.WOOD, + fuel == types.PROPANE, + (fuel == types.NATURAL_GAS) + | (fuel == types.ELECTRICITY) + | (fuel == types.COAL), + ], + [ + p.payment.oil.calc(income_ratio, right=True), + p.payment.wood.calc(income_ratio, right=True), + p.payment.propane.calc(income_ratio, right=True), + p.payment.utility.calc(income_ratio, right=True), + ], + default=0, + ) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py new file mode 100644 index 00000000000..4b3b6813ecb --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class ne_liheap_earned_income(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Nebraska LIHEAP gross countable earned income" + defined_for = StateCode.NE + reference = "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7" + + def formula_2026(spm_unit, period, parameters): + person = spm_unit.members + countable = person("snap_countable_earner", period.first_month) + included = person("is_snap_immigration_status_eligible", period.first_month) + size = spm_unit("ne_liheap_household_size", period) + fraction = size / max_(spm_unit("spm_unit_size", period), 1) + share = where(included, 1, spm_unit.project(fraction)) + # Use existing net self-employment income without another business + # expense deduction. Nebraska's tax-return/49%-ledger distinction, + # capital gains from business assets, and farm-loss offsets require + # additional source information and are not modeled here. + earned = max_(person("employment_income", period), 0) + max_( + person("self_employment_income", period), 0 + ) + return spm_unit.sum(earned * countable * share) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py new file mode 100644 index 00000000000..0f65b13bb4c --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class ne_liheap_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Nebraska LIHEAP regular heating assistance eligibility" + defined_for = StateCode.NE + reference = "https://rules.nebraska.gov/rules?agencyId=37&titleId=231" + + def formula_2026(spm_unit, period, parameters): + income_eligible = spm_unit("ne_liheap_income_eligible", period) + # A positive heating bill demonstrates responsibility for energy + # costs. Heat included in rent can also qualify, but rent alone does + # not establish exposure to energy-price increases (476 NAC 1-004.06). + # That vulnerability and administrative disqualifications are not + # identifiable from existing inputs; no new inputs are introduced. + responsible = spm_unit("heating_expense", period) > 0 + return income_eligible & responsible diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_fpg.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_fpg.py new file mode 100644 index 00000000000..fc43df6d2cb --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_fpg.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class ne_liheap_fpg(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Nebraska LIHEAP annual federal poverty guideline" + defined_for = StateCode.NE + reference = "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1" + + def formula_2026(spm_unit, period, parameters): + p = parameters(period).gov.states.ne.dhhs.liheap + size = spm_unit("ne_liheap_household_size", period) + state_group = spm_unit.household("state_group_str", period) + # Annual 2026 represents the heating season ending in 2026. Household + # composition is current; only the federal guideline is lagged. + fpg_year = period.start.year - int(p.fpg_year_lag) + fpg = parameters(f"{fpg_year}-01-01").gov.hhs.fpg + amount = fpg.first_person[state_group] + fpg.additional_person[ + state_group + ] * max_(size - 1, 0) + return where(size > 0, amount, 0) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py new file mode 100644 index 00000000000..32d470a03bf --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class ne_liheap_gross_income(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Nebraska LIHEAP gross countable household income" + defined_for = StateCode.NE + reference = "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7" + + def formula_2026(spm_unit, period, parameters): + # 476 NAC 2-002.01 incorporates SNAP's income treatment, but not + # SNAP's net-income deductions or student/work eligibility tests. + p = parameters(period).gov.usda.snap.income.sources + person = spm_unit.members + included = person("is_snap_immigration_status_eligible", period.first_month) + size = spm_unit("ne_liheap_household_size", period) + fraction = size / max_(spm_unit("spm_unit_size", period), 1) + share = where(included, 1, spm_unit.project(fraction)) + unearned = max_(add(person, period, p.unearned), 0) + unit_unearned = add(spm_unit, period, p.unearned_spm_unit) + earned = spm_unit("ne_liheap_earned_income", period) + # Annual inputs approximate the agency's anticipated income at the + # application date. Existing SNAP source omissions also apply here. + return earned + spm_unit.sum(unearned * share) + max_(unit_unearned, 0) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py new file mode 100644 index 00000000000..41cc4472e88 --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ne_liheap_household_size(Variable): + value_type = int + entity = SPMUnit + definition_period = YEAR + label = "Nebraska LIHEAP eligible household size" + defined_for = StateCode.NE + reference = "https://rules.nebraska.gov/rules?agencyId=37&titleId=231" + + def formula_2026(spm_unit, period, parameters): + # 476 NAC 2-002.02 excludes members who do not satisfy SNAP's + # citizenship rules. SPM units approximate energy-purchasing units. + # LIHEAP-specific program violations and residency fraud are not + # represented by existing inputs and are not modeled. + return add( + spm_unit, period.first_month, ["is_snap_immigration_status_eligible"] + ) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py new file mode 100644 index 00000000000..bf7886ab6a9 --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class ne_liheap_income_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Nebraska LIHEAP income eligibility" + defined_for = StateCode.NE + reference = "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1" + + def formula_2026(spm_unit, period, parameters): + p = parameters(period).gov.states.ne.dhhs.liheap + income = spm_unit("ne_liheap_gross_income", period) + fpg = spm_unit("ne_liheap_fpg", period) + return (fpg > 0) & (income <= fpg * p.income_limit) From 461f9ebcf355b982db0497072db37a059c6ca51e Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 30 Sep 2026 19:59:24 -0400 Subject: [PATCH 2/7] Apply LIHEAP review fixes and shared guideline convention --- changelog.d/ne-liheap.added.md | 2 +- .../ne/dhhs/liheap/payment/multifamily.yaml | 27 ++++++++++++++++ policyengine_us/programs.yaml | 4 +-- .../gov/states/ne/dhhs/liheap/ne_liheap.yaml | 31 +++++++++++++++++++ .../states/ne/dhhs/liheap/ne_liheap_fpg.yaml | 15 ++++++--- .../variables/gov/hhs/tax_unit_fpg.py | 11 +++++-- .../gov/states/ne/dhhs/liheap/ne_liheap.py | 31 ++++++++++++------- .../ne/dhhs/liheap/ne_liheap_dwelling_type.py | 23 ++++++++++++++ .../ne/dhhs/liheap/ne_liheap_earned_income.py | 10 ++++-- .../ne/dhhs/liheap/ne_liheap_eligible.py | 19 +++++++----- .../states/ne/dhhs/liheap/ne_liheap_fpg.py | 15 +++++---- .../ne/dhhs/liheap/ne_liheap_gross_income.py | 8 +++-- .../dhhs/liheap/ne_liheap_household_size.py | 18 +++++++---- .../dhhs/liheap/ne_liheap_income_eligible.py | 2 +- 14 files changed, 170 insertions(+), 46 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/multifamily.yaml create mode 100644 policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_dwelling_type.py diff --git a/changelog.d/ne-liheap.added.md b/changelog.d/ne-liheap.added.md index b691f41d8f6..b5286788d4c 100644 --- a/changelog.d/ne-liheap.added.md +++ b/changelog.d/ne-liheap.added.md @@ -1 +1 @@ -Add partial FY2026 Nebraska LIHEAP regular heating assistance using existing inputs. +Add partial Nebraska LIHEAP regular heating assistance verified for FY2026, with a state-specific dwelling type selecting single-family or multifamily payments. diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/multifamily.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/multifamily.yaml new file mode 100644 index 00000000000..4c9ecab658e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment/multifamily.yaml @@ -0,0 +1,27 @@ +description: Nebraska provides these regular multi-family heating payments for all fuel types by countable income as a share of the federal poverty guideline under the Low Income Home Energy Assistance Program. +brackets: + - threshold: + 2025-10-01: -.inf + amount: + 2025-10-01: 380 + - threshold: + 2025-10-01: 0.7 + amount: + 2025-10-01: 300 + - threshold: + 2025-10-01: 1 + amount: + 2025-10-01: 220 + - threshold: + 2025-10-01: 1.3 + amount: + 2025-10-01: 154 +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + period: year + label: Nebraska LIHEAP multi-family heating payment + reference: + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025, Heating Payment Computation + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index df52c81153d..f967bf60d31 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -836,8 +836,8 @@ programs: full_name: Nebraska Low Income Home Energy Assistance Program variable: ne_liheap parameter_prefix: gov.states.ne.dhhs.liheap - verified_start_year: 2026 - notes: FY2026 regular single-family heating schedule, gross-income eligibility, and earned-income disregard. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net self-employment income without another business deduction. Multifamily rates, economic vulnerability for heat included in rent, program disqualifications, detailed immigration conditions, business-record expense alternatives, farm-loss offsets, and discretionary heating supplements are not modeled. Requires a positive heating expense and a supported primary fuel. Calendar 2026 represents the season ending in 2026; earlier years have no verified formula. No cooling, crisis, weatherization, or equipment assistance. + verified_years: "2026" + notes: FY2026 regular single-family and multifamily heating schedules, gross-income eligibility, and earned-income disregard. A state-specific dwelling-type input selects the schedule, defaulting to single-family when omitted. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net self-employment income without another business deduction. Economic vulnerability for heat included in rent, program disqualifications, detailed immigration conditions, business-record expense alternatives, farm-loss offsets, and discretionary heating supplements are not modeled. Requires a positive heating expense; single-family payments require a supported primary fuel, while multifamily payments cover all fuels. Calendar 2026 represents the season ending in 2026; earlier results use parameter backfilling and are unverified historical estimates. No cooling, crisis, weatherization, or equipment assistance. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml index c59a2768a2e..29d48d7dcb1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml @@ -331,3 +331,34 @@ heating_type: NATURAL_GAS output: ne_liheap: 400 + +- name: Case 31, multifamily dwelling payments at each closed income boundary. + # FY2026 heating table, multifamily all-fuel column: $380/$300/$220/$154. + period: 2026 + input: + state_code: [NE, NE, NE, NE, NE, NE, NE, NE] + ne_liheap_eligible: [true, true, true, true, true, true, true, true] + ne_liheap_household_size: [1, 1, 1, 1, 1, 1, 1, 1] + ne_liheap_gross_income: [0, 10_955, 10_955.01, 15_650, 15_650.01, 20_345, 20_345.01, 23_475] + ne_liheap_earned_income: [0, 0, 0, 0, 0, 0, 0, 0] + ne_liheap_dwelling_type: [MULTI_FAMILY, MULTI_FAMILY, MULTI_FAMILY, MULTI_FAMILY, + MULTI_FAMILY, MULTI_FAMILY, MULTI_FAMILY, MULTI_FAMILY] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + output: + ne_liheap: [380, 380, 300, 300, 220, 220, 154, 154] + +- name: Case 32, dwelling type selects multifamily payments for every fuel. + # Multifamily has one all-fuel column; single-family has fuel-specific columns. + period: 2026 + input: + state_code: [NE, NE, NE, NE, NE, NE] + ne_liheap_eligible: [true, true, true, true, true, true] + ne_liheap_household_size: [1, 1, 1, 1, 1, 1] + ne_liheap_gross_income: [0, 0, 0, 0, 0, 0] + ne_liheap_earned_income: [0, 0, 0, 0, 0, 0] + ne_liheap_dwelling_type: [SINGLE_FAMILY, MULTI_FAMILY, SINGLE_FAMILY, + MULTI_FAMILY, MULTI_FAMILY, MULTI_FAMILY] + heating_type: [FUEL_OIL, FUEL_OIL, WOOD, WOOD, OTHER, SOLAR] + output: + ne_liheap: [1_050, 380, 800, 380, 380, 380] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml index b66665669af..b3a34e55f19 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml @@ -79,13 +79,20 @@ output: ne_liheap_fpg: 0 ne_liheap_income_eligible: false -- name: Case 12, unverified earlier years do not use the FY2026 schedule. +# Backfilling checks the model convention, not verified historical Nebraska policy. +# The state schedule is backfilled, but the guideline uses the requested year - 1. +- name: Case 12, parameter backfill uses the 2021 guideline for a 2022 estimate. period: 2022 input: state_code: NE + age: 40 + employment_income: 0 + ssi: 0 + social_security: 0 heating_type: NATURAL_GAS gas_expense: 1_000 output: - ne_liheap: 0 - ne_liheap_fpg: 0 - ne_liheap_income_eligible: false + ne_liheap: 700 + ne_liheap_household_size: 1 + ne_liheap_fpg: 12_880 + ne_liheap_income_eligible: true diff --git a/policyengine_us/variables/gov/hhs/tax_unit_fpg.py b/policyengine_us/variables/gov/hhs/tax_unit_fpg.py index f492918fcbb..51714218342 100644 --- a/policyengine_us/variables/gov/hhs/tax_unit_fpg.py +++ b/policyengine_us/variables/gov/hhs/tax_unit_fpg.py @@ -1,8 +1,15 @@ from policyengine_us.model_api import * +from policyengine_core.periods import instant -def fpg(unit_size, state_group, period, parameters): - p_fpg = parameters(period).gov.hhs.fpg +def fpg(unit_size, state_group, period, parameters, year_lag=0): + """Return the annual guideline for the supplied size and guideline year. + + Lag only the parameter date, preserving its month and day. Callers supply + the current household size and apply any caps, policy rates, or rounding. + """ + guideline_date = instant(period).offset(-int(year_lag), "year") + p_fpg = parameters(guideline_date).gov.hhs.fpg p1 = p_fpg.first_person[state_group] pn = p_fpg.additional_person[state_group] return p1 + pn * (unit_size - 1) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py index c1ce699c8c5..e6dcee2a7de 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg class ne_liheap(Variable): @@ -7,34 +8,41 @@ class ne_liheap(Variable): definition_period = YEAR unit = USD label = "Nebraska LIHEAP regular heating assistance" + documentation = ( + "Verified for FY2026. Earlier years use model parameter backfilling " + "and are unverified historical estimates." + ) defined_for = "ne_liheap_eligible" reference = "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2" - def formula_2026(spm_unit, period, parameters): + def formula(spm_unit, period, parameters): p = parameters(period).gov.states.ne.dhhs.liheap gross = spm_unit("ne_liheap_gross_income", period) earned = spm_unit("ne_liheap_earned_income", period) income = max_(gross - earned * p.earned_income_disregard, 0) size = spm_unit("ne_liheap_household_size", period) - fpg = spm_unit("ne_liheap_fpg", period) state_group = spm_unit.household("state_group_str", period) - fpg_year = period.start.year - int(p.fpg_year_lag) - federal = parameters(f"{fpg_year}-01-01").gov.hhs.fpg # The payment bands stop growing at six people; eligibility does not. - payment_fpg = fpg - federal.additional_person[state_group] * max_( - size - p.payment_size_limit, 0 + payment_fpg = fpg( + clip(size, 1, p.payment_size_limit), + state_group, + period, + parameters, + year_lag=p.fpg_year_lag, ) + payment_fpg = where(size > 0, payment_fpg, 0) income_ratio = income / max_(payment_fpg, 1) fuel = spm_unit("heating_type", period) types = fuel.possible_values - # Single-family schedule only: no existing input distinguishes the - # 476 NAC 1-004.11/.16 dwelling categories. Multifamily rates are not - # inferred from tenure or subsidy status. This remains partial coverage. - # OTHER cannot isolate corn; SOLAR/UNSPECIFIED also lack a supported - # single-family table mapping. These fuel categories return zero. + dwelling = spm_unit("ne_liheap_dwelling_type", period) + multifamily = dwelling == dwelling.possible_values.MULTI_FAMILY + # The multi-family column covers all fuel types. For single-family homes, + # OTHER cannot isolate corn; SOLAR/UNSPECIFIED lack a table mapping. + # Unsupported single-family fuel categories return zero. # No FY2026 supplemental heating amount has been verified. return select( [ + multifamily, (fuel == types.FUEL_OIL) | (fuel == types.KEROSENE), fuel == types.WOOD, fuel == types.PROPANE, @@ -43,6 +51,7 @@ def formula_2026(spm_unit, period, parameters): | (fuel == types.COAL), ], [ + p.payment.multifamily.calc(income_ratio, right=True), p.payment.oil.calc(income_ratio, right=True), p.payment.wood.calc(income_ratio, right=True), p.payment.propane.calc(income_ratio, right=True), diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_dwelling_type.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_dwelling_type.py new file mode 100644 index 00000000000..aad1435ed39 --- /dev/null +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_dwelling_type.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class NELIHEAPDwellingType(Enum): + MULTI_FAMILY = "Multi-family arrangement" + SINGLE_FAMILY = "Single-family arrangement" + + +class ne_liheap_dwelling_type(Variable): + value_type = Enum + entity = SPMUnit + possible_values = NELIHEAPDwellingType + default_value = NELIHEAPDwellingType.SINGLE_FAMILY + definition_period = YEAR + label = "Dwelling type for Nebraska LIHEAP" + documentation = ( + "Under 476 NAC 1-004.11 and 1-004.16, multi-family means more than one " + "household occupies a structure, including apartments with separate " + "energy bills and communal arrangements with shared bills. Single-family " + "means one household occupies the structure. If omitted, the model " + "assumes single-family; report the type to apply the correct schedule." + ) + reference = "https://rules.nebraska.gov/rules?agencyId=37&titleId=231" diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py index 4b3b6813ecb..bd3d2aff899 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py @@ -8,13 +8,19 @@ class ne_liheap_earned_income(Variable): unit = USD label = "Nebraska LIHEAP gross countable earned income" defined_for = StateCode.NE - reference = "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7" + reference = ( + "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7", + "https://rules.nebraska.gov/rules?agencyId=37&titleId=230", + ) - def formula_2026(spm_unit, period, parameters): + def formula(spm_unit, period, parameters): person = spm_unit.members countable = person("snap_countable_earner", period.first_month) included = person("is_snap_immigration_status_eligible", period.first_month) size = spm_unit("ne_liheap_household_size", period) + # 475 NAC 3-002.06(A)-(B), incorporated by 476 NAC 2-002.01: + # prorate excluded members' countable income across all members and + # retain the eligible members' shares. Eligible members count in full. fraction = size / max_(spm_unit("spm_unit_size", period), 1) share = where(included, 1, spm_unit.project(fraction)) # Use existing net self-employment income without another business diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py index 0f65b13bb4c..325621fe1e5 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py @@ -7,14 +7,19 @@ class ne_liheap_eligible(Variable): definition_period = YEAR label = "Nebraska LIHEAP regular heating assistance eligibility" defined_for = StateCode.NE - reference = "https://rules.nebraska.gov/rules?agencyId=37&titleId=231" + reference = ( + "https://rules.nebraska.gov/rules?agencyId=37&titleId=231", + "https://dhhs.ne.gov/Documents/LIHEAP%20State%20Plan.pdf#page=9", + ) - def formula_2026(spm_unit, period, parameters): + def formula(spm_unit, period, parameters): income_eligible = spm_unit("ne_liheap_income_eligible", period) - # A positive heating bill demonstrates responsibility for energy - # costs. Heat included in rent can also qualify, but rent alone does - # not establish exposure to energy-price increases (476 NAC 1-004.06). - # That vulnerability and administrative disqualifications are not - # identifiable from existing inputs; no new inputs are introduced. + # 476 NAC 1-004.09 includes energy paid through rent; FY2026 plan 2.3 + # allows such renters when responsible for a portion of heating costs. + # Economic vulnerability still requires exposure to energy-cost increases + # (1-004.06 and 2-002(A)); the heat-in-rent flag cannot establish this. + # The positive-bill proxy below misses eligible renters without a separate + # bill. This is a coverage gap, not a legal exclusion of heat-in-rent + # households. Administrative disqualifications also remain unmodeled. responsible = spm_unit("heating_expense", period) > 0 return income_eligible & responsible diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_fpg.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_fpg.py index fc43df6d2cb..f9a45ebecdb 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_fpg.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_fpg.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg class ne_liheap_fpg(Variable): @@ -10,15 +11,13 @@ class ne_liheap_fpg(Variable): defined_for = StateCode.NE reference = "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1" - def formula_2026(spm_unit, period, parameters): + def formula(spm_unit, period, parameters): p = parameters(period).gov.states.ne.dhhs.liheap size = spm_unit("ne_liheap_household_size", period) state_group = spm_unit.household("state_group_str", period) - # Annual 2026 represents the heating season ending in 2026. Household - # composition is current; only the federal guideline is lagged. - fpg_year = period.start.year - int(p.fpg_year_lag) - fpg = parameters(f"{fpg_year}-01-01").gov.hhs.fpg - amount = fpg.first_person[state_group] + fpg.additional_person[ - state_group - ] * max_(size - 1, 0) + # The annual period represents the heating season ending in that year. + # Household composition is current; only the federal guideline is lagged. + amount = fpg( + max_(size, 1), state_group, period, parameters, year_lag=p.fpg_year_lag + ) return where(size > 0, amount, 0) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py index 32d470a03bf..d0efce46751 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py @@ -8,15 +8,19 @@ class ne_liheap_gross_income(Variable): unit = USD label = "Nebraska LIHEAP gross countable household income" defined_for = StateCode.NE - reference = "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7" + reference = ( + "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7", + "https://rules.nebraska.gov/rules?agencyId=37&titleId=230", + ) - def formula_2026(spm_unit, period, parameters): + def formula(spm_unit, period, parameters): # 476 NAC 2-002.01 incorporates SNAP's income treatment, but not # SNAP's net-income deductions or student/work eligibility tests. p = parameters(period).gov.usda.snap.income.sources person = spm_unit.members included = person("is_snap_immigration_status_eligible", period.first_month) size = spm_unit("ne_liheap_household_size", period) + # The same 475 NAC 3-002.06(A)-(B) proration applies to unearned income. fraction = size / max_(spm_unit("spm_unit_size", period), 1) share = where(included, 1, spm_unit.project(fraction)) unearned = max_(add(person, period, p.unearned), 0) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py index 41cc4472e88..4232f08aabd 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py @@ -7,13 +7,19 @@ class ne_liheap_household_size(Variable): definition_period = YEAR label = "Nebraska LIHEAP eligible household size" defined_for = StateCode.NE - reference = "https://rules.nebraska.gov/rules?agencyId=37&titleId=231" + reference = ( + "https://rules.nebraska.gov/rules?agencyId=37&titleId=231", + "https://dhhs.ne.gov/Documents/OBBB-SNAP-Changes-FAQ.pdf#page=3", + ) - def formula_2026(spm_unit, period, parameters): - # 476 NAC 2-002.02 excludes members who do not satisfy SNAP's - # citizenship rules. SPM units approximate energy-purchasing units. - # LIHEAP-specific program violations and residency fraud are not - # represented by existing inputs and are not modeled. + def formula(spm_unit, period, parameters): + # 476 NAC 2-002.02 incorporates SNAP citizenship/alien-status rules; + # DHHS's OBBBA FAQ, Q12, expressly applies those changes to LIHEAP. + # This is the immigration-status test, not SNAP work/student eligibility. + # Its current implementation cannot resolve waiting periods/exceptions, + # COFA status, or case-specific recertification timing. These remain gaps. + # SPM units approximate energy-purchasing units (476 NAC 1-004.09). + # LIHEAP-specific program violations and residency fraud are unmodeled. return add( spm_unit, period.first_month, ["is_snap_immigration_status_eligible"] ) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py index bf7886ab6a9..2112edd18fa 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py @@ -9,7 +9,7 @@ class ne_liheap_income_eligible(Variable): defined_for = StateCode.NE reference = "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1" - def formula_2026(spm_unit, period, parameters): + def formula(spm_unit, period, parameters): p = parameters(period).gov.states.ne.dhhs.liheap income = spm_unit("ne_liheap_gross_income", period) fpg = spm_unit("ne_liheap_fpg", period) From 3f4363941f4113b058897ad5abe34a6a940002f5 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 30 Sep 2026 20:46:20 -0400 Subject: [PATCH 3/7] Allow Nebraska LIHEAP heating included in rent --- changelog.d/ne-liheap.added.md | 2 +- policyengine_us/programs.yaml | 2 +- .../states/ne/dhhs/liheap/integration.yaml | 31 +++++++++++++++++++ .../ne/dhhs/liheap/ne_liheap_eligible.yaml | 22 ++++++++++--- .../gov/states/ne/dhhs/liheap/ne_liheap.py | 7 +++-- .../ne/dhhs/liheap/ne_liheap_eligible.py | 12 +++---- 6 files changed, 60 insertions(+), 16 deletions(-) diff --git a/changelog.d/ne-liheap.added.md b/changelog.d/ne-liheap.added.md index b5286788d4c..d18e3e338cc 100644 --- a/changelog.d/ne-liheap.added.md +++ b/changelog.d/ne-liheap.added.md @@ -1 +1 @@ -Add partial Nebraska LIHEAP regular heating assistance verified for FY2026, with a state-specific dwelling type selecting single-family or multifamily payments. +Add partial Nebraska LIHEAP regular heating assistance verified for FY2026, with single-family and multifamily schedules and assumed economic vulnerability for separately billed or rent-included heating. diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index f967bf60d31..62a8689262f 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -837,7 +837,7 @@ programs: variable: ne_liheap parameter_prefix: gov.states.ne.dhhs.liheap verified_years: "2026" - notes: FY2026 regular single-family and multifamily heating schedules, gross-income eligibility, and earned-income disregard. A state-specific dwelling-type input selects the schedule, defaulting to single-family when omitted. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net self-employment income without another business deduction. Economic vulnerability for heat included in rent, program disqualifications, detailed immigration conditions, business-record expense alternatives, farm-loss offsets, and discretionary heating supplements are not modeled. Requires a positive heating expense; single-family payments require a supported primary fuel, while multifamily payments cover all fuels. Calendar 2026 represents the season ending in 2026; earlier results use parameter backfilling and are unverified historical estimates. No cooling, crisis, weatherization, or equipment assistance. + notes: FY2026 regular single-family and multifamily heating schedules, gross-income eligibility, and earned-income disregard. A state-specific dwelling-type input selects the schedule, defaulting to single-family when omitted. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net self-employment income without another business deduction. Economic vulnerability is assumed for modeling; a positive heating expense or heat included in rent establishes heating responsibility, including zero separately reported expenses. Program disqualifications, detailed immigration conditions, business-record expense alternatives, farm-loss offsets, and discretionary heating supplements are not modeled. Single-family payments require a supported primary fuel, while multifamily payments cover all fuels. Calendar 2026 represents the season ending in 2026; earlier results use parameter backfilling and are unverified historical estimates. No cooling, crisis, weatherization, or equipment assistance. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml index 07060e2be78..32d36e3b205 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml @@ -180,3 +180,34 @@ ne_liheap_fpg: 15_650 ne_liheap_income_eligible: true ne_liheap: 550 + +- name: Case 7, multifamily heat in rent receives the full scheduled benefit with zero separate expense. + period: 2026 + input: + people: + person1: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + employment_income: 18_000 + spm_units: + spm_unit: + members: [person1] + ne_liheap_dwelling_type: MULTI_FAMILY + heat_expense_included_in_rent: true + heating_expense: 0 + tanf: 0 + households: + household: + members: [person1] + state_code: NE + output: + ne_liheap_household_size: 1 + ne_liheap_earned_income: 18_000 + ne_liheap_gross_income: 18_000 + ne_liheap_fpg: 15_650 + ne_liheap_income_eligible: true + ne_liheap_eligible: true + # Income after the 20% disregard is $14,400: multifamily Tier 2. + ne_liheap: 300 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml index d4bc2bff276..50ee587363b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml @@ -10,22 +10,23 @@ gas_expense: 100 output: ne_liheap_eligible: true -- name: Case 2, heat in rent does not by itself establish economic vulnerability. +- name: Case 2, heat in rent qualifies with zero separate heating expense under the vulnerability assumption. period: 2026 input: state_code: NE ne_liheap_income_eligible: true heat_expense_included_in_rent: true + heating_expense: 0 pre_subsidy_rent: 10_000 output: - ne_liheap_eligible: false -- name: Case 3, income failure excludes household with heating expenses. + ne_liheap_eligible: true +- name: Case 3, heat in rent does not bypass the income test. period: 2026 input: state_code: NE ne_liheap_income_eligible: false - heating_type: NATURAL_GAS - gas_expense: 100 + heat_expense_included_in_rent: true + heating_expense: 0 output: ne_liheap_eligible: false - name: Case 4, another state receives no Nebraska benefit. @@ -38,3 +39,14 @@ output: ne_liheap_eligible: false ne_liheap: 0 + +- name: Case 5, no reported heating responsibility remains ineligible. + period: 2026 + input: + state_code: NE + ne_liheap_income_eligible: true + heat_expense_included_in_rent: false + heating_expense: 0 + output: + ne_liheap_eligible: false + ne_liheap: 0 diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py index e6dcee2a7de..03ae45a99d3 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py @@ -36,9 +36,10 @@ def formula(spm_unit, period, parameters): types = fuel.possible_values dwelling = spm_unit("ne_liheap_dwelling_type", period) multifamily = dwelling == dwelling.possible_values.MULTI_FAMILY - # The multi-family column covers all fuel types. For single-family homes, - # OTHER cannot isolate corn; SOLAR/UNSPECIFIED lack a table mapping. - # Unsupported single-family fuel categories return zero. + # Corn shares the natural gas/electricity/coal payment column. No + # separate schedule is needed, but the fuel enum cannot isolate corn + # from OTHER. Single-family OTHER/SOLAR/UNSPECIFIED remain unmapped; + # the multifamily column covers all fuel types. # No FY2026 supplemental heating amount has been verified. return select( [ diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py index 325621fe1e5..20ebe1dbf6e 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py @@ -16,10 +16,10 @@ def formula(spm_unit, period, parameters): income_eligible = spm_unit("ne_liheap_income_eligible", period) # 476 NAC 1-004.09 includes energy paid through rent; FY2026 plan 2.3 # allows such renters when responsible for a portion of heating costs. - # Economic vulnerability still requires exposure to energy-cost increases - # (1-004.06 and 2-002(A)); the heat-in-rent flag cannot establish this. - # The positive-bill proxy below misses eligible renters without a separate - # bill. This is a coverage gap, not a legal exclusion of heat-in-rent - # households. Administrative disqualifications also remain unmodeled. - responsible = spm_unit("heating_expense", period) > 0 + # Modeling assumption: economic vulnerability under 1-004.06 and + # 2-002(A) is assumed, rather than separately verified. Accept heating + # paid through rent even when the separately reported expense is zero. + # Administrative disqualifications remain unmodeled. + heat_in_rent = spm_unit("heat_expense_included_in_rent", period) + responsible = (spm_unit("heating_expense", period) > 0) | heat_in_rent return income_eligible & responsible From bf99248171c0417582da408d627a7938e6242a7e Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 30 Sep 2026 23:05:48 -0400 Subject: [PATCH 4/7] Fix issues from review: Nebraska LIHEAP income and heat-in-rent eligibility - Count sstb_self_employment_income in earned income, floored at zero per source - Require a positive heating expense for subsidized-housing households with heat in rent (plan section 2.3); market-rate renters stay eligible - State plainly that an unspecified single-family fuel is paid $0 - Add tests for SSTB income, subsidized heat-in-rent households, proration with TANF and the refugee/asylee household-size exclusion; send heating_type explicitly in every eligibility or payment case Co-Authored-By: Claude Fable 5.1 --- policyengine_us/programs.yaml | 2 +- .../states/ne/dhhs/liheap/integration.yaml | 114 ++++++++++++++++ .../gov/states/ne/dhhs/liheap/ne_liheap.yaml | 23 ++++ .../dhhs/liheap/ne_liheap_earned_income.yaml | 24 ++++ .../ne/dhhs/liheap/ne_liheap_eligible.yaml | 64 +++++++++ .../dhhs/liheap/ne_liheap_gross_income.yaml | 117 ++++++++++++++++ .../dhhs/liheap/ne_liheap_household_size.yaml | 125 ++++++++++++++++++ .../gov/states/ne/dhhs/liheap/ne_liheap.py | 8 +- .../ne/dhhs/liheap/ne_liheap_earned_income.py | 17 ++- .../ne/dhhs/liheap/ne_liheap_eligible.py | 14 +- 10 files changed, 496 insertions(+), 12 deletions(-) create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.yaml diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 62a8689262f..f5a02452dbf 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -837,7 +837,7 @@ programs: variable: ne_liheap parameter_prefix: gov.states.ne.dhhs.liheap verified_years: "2026" - notes: FY2026 regular single-family and multifamily heating schedules, gross-income eligibility, and earned-income disregard. A state-specific dwelling-type input selects the schedule, defaulting to single-family when omitted. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net self-employment income without another business deduction. Economic vulnerability is assumed for modeling; a positive heating expense or heat included in rent establishes heating responsibility, including zero separately reported expenses. Program disqualifications, detailed immigration conditions, business-record expense alternatives, farm-loss offsets, and discretionary heating supplements are not modeled. Single-family payments require a supported primary fuel, while multifamily payments cover all fuels. Calendar 2026 represents the season ending in 2026; earlier results use parameter backfilling and are unverified historical estimates. No cooling, crisis, weatherization, or equipment assistance. + notes: FY2026 regular single-family and multifamily heating schedules, gross-income eligibility, and earned-income disregard. A state-specific dwelling-type input selects the schedule, defaulting to single-family when omitted. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net non-farm self-employment income (regular and SSTB inputs, each floored at zero) without another business deduction. Economic vulnerability is assumed for modeling; a positive heating expense establishes heating responsibility, and so does heat included in rent for market-rate renters, including zero separately reported expenses. Households receiving housing assistance or living in public housing need a positive heating expense (FY2026 plan section 2.3). Program disqualifications, detailed immigration conditions, business-record expense alternatives, farm self-employment income (neither positive farm income nor farm-loss offsets is read), and discretionary heating supplements are not modeled. Single-family payments require a supported primary fuel; an eligible single-family household with an unspecified, other, solar, or no heating fuel is paid $0 with no fallback fuel, including a heat-in-rent renter who omits the fuel and the dwelling type. Multifamily payments cover all fuels. Calendar 2026 represents the season ending in 2026; earlier results use parameter backfilling and are unverified historical estimates. No cooling, crisis, weatherization, or equipment assistance. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml index 32d36e3b205..8a3dd39d36b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml @@ -196,6 +196,7 @@ members: [person1] ne_liheap_dwelling_type: MULTI_FAMILY heat_expense_included_in_rent: true + heating_type: UNSPECIFIED heating_expense: 0 tanf: 0 households: @@ -211,3 +212,116 @@ ne_liheap_eligible: true # Income after the 20% disregard is $14,400: multifamily Tier 2. ne_liheap: 300 + +- name: Case 8, specified service trade self-employment income above the limit is ineligible. + # 475 NAC 3-002.04(B)(i), incorporated by 476 NAC 2-002.01, counts each + # source of self-employment. A self-employed bookkeeper reports net income + # in sstb_self_employment_income. + period: 2026 + input: + people: + person1: + age: 42 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + sstb_self_employment_income: 40_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 0 + households: + household: + members: [person1] + state_code: NE + output: + ne_liheap_household_size: 1 + ne_liheap_earned_income: 40_000 + ne_liheap_gross_income: 40_000 + ne_liheap_fpg: 15_650 + # 40,000 exceeds 150% of 15,650 = 23,475. The 20% earned-income + # disregard applies to the payment tier only, not to this gross test. + ne_liheap_income_eligible: false + ne_liheap_eligible: false + ne_liheap: 0 + +- name: Case 9, housing-assisted renter with heat in rent and no heating bill is ineligible. + # FY2026 state plan section 2.3: subsidized-housing renters must be + # responsible for a portion of the heating payment. + # https://dhhs.ne.gov/Documents/LIHEAP%20State%20Plan.pdf#page=9 + period: 2026 + input: + people: + person1: + age: 31 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + employment_income: 22_000 + person2: + age: 5 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + spm_units: + spm_unit: + members: [person1, person2] + receives_housing_assistance: true + ne_liheap_dwelling_type: MULTI_FAMILY + heat_expense_included_in_rent: true + heating_type: UNSPECIFIED + tanf: 0 + households: + household: + members: [person1, person2] + state_code: NE + output: + ne_liheap_household_size: 2 + ne_liheap_earned_income: 22_000 + ne_liheap_gross_income: 22_000 + # 2025 guideline for two: 15,650 + 5,500 = 21,150; limit 31,725. + ne_liheap_fpg: 21_150 + ne_liheap_income_eligible: true + heating_expense: 0 + # No housing assistance would pay the multifamily Tier 2 amount of 300: + # 22,000 - 0.2 * 22,000 = 17,600; 17,600 / 21,150 = 0.832. + ne_liheap_eligible: false + ne_liheap: 0 + +- name: Case 10, public housing tenant who pays part of the heating cost receives the multifamily payment. + period: 2026 + input: + people: + person1: + age: 71 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + social_security_retirement: 13_200 + spm_units: + spm_unit: + members: [person1] + ne_liheap_dwelling_type: MULTI_FAMILY + heat_expense_included_in_rent: true + heating_type: NATURAL_GAS + gas_expense: 420 + tanf: 0 + households: + household: + members: [person1] + state_code: NE + is_in_public_housing: true + output: + ne_liheap_household_size: 1 + ne_liheap_earned_income: 0 + # $1,100 a month of Social Security: 1,100 * 12 = 13,200. + ne_liheap_gross_income: 13_200 + ne_liheap_fpg: 15_650 + ne_liheap_income_eligible: true + # A $35 monthly gas charge on top of rent: 35 * 12 = 420. + heating_expense: 420 + ne_liheap_eligible: true + # No earned income to disregard: 13,200 / 15,650 = 0.843, multifamily Tier 2. + ne_liheap: 300 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml index 29d48d7dcb1..043afda9549 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml @@ -362,3 +362,26 @@ heating_type: [FUEL_OIL, FUEL_OIL, WOOD, WOOD, OTHER, SOLAR] output: ne_liheap: [1_050, 380, 800, 380, 380, 380] + +- name: Case 33, heat-in-rent renter with unspecified fuel and the default dwelling type is eligible but paid zero. + # Documented limitation: an unspecified single-family fuel has no payment + # column and no fallback fuel. Reporting MULTI_FAMILY selects the all-fuel + # column instead (integration Case 7). + period: 2026 + input: + state_code: NE + age: 29 + employment_income: 18_000 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + tanf: 0 + heat_expense_included_in_rent: true + heating_type: UNSPECIFIED + output: + heating_expense: 0 + ne_liheap_dwelling_type: SINGLE_FAMILY + # 18,000 is under the one-person limit of 150% * 15,650 = 23,475. + ne_liheap_income_eligible: true + ne_liheap_eligible: true + ne_liheap: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml new file mode 100644 index 00000000000..49747d64861 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml @@ -0,0 +1,24 @@ +# Source: 475 NAC 3-002.04(B)(i), incorporated by 476 NAC 2-002.01, counts +# each source of self-employment of the household. +# https://rules.nebraska.gov/rules?agencyId=37&titleId=230 + +- name: Case 1, specified service trade self-employment income counts as earned income. + period: 2026 + input: + state_code: NE + age: 42 + sstb_self_employment_income: 40_000 + output: + ne_liheap_earned_income: 40_000 + +- name: Case 2, a loss in one self-employment source does not offset wages or another business. + period: 2026 + input: + state_code: NE + age: 42 + employment_income: 12_000 + self_employment_income: 6_000 + sstb_self_employment_income: -4_000 + output: + # Each source is floored at zero: 12,000 + 6,000 + max(-4,000, 0) = 18,000. + ne_liheap_earned_income: 18_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml index 50ee587363b..7c0a37778f8 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml @@ -16,6 +16,7 @@ state_code: NE ne_liheap_income_eligible: true heat_expense_included_in_rent: true + heating_type: UNSPECIFIED heating_expense: 0 pre_subsidy_rent: 10_000 output: @@ -26,6 +27,7 @@ state_code: NE ne_liheap_income_eligible: false heat_expense_included_in_rent: true + heating_type: UNSPECIFIED heating_expense: 0 output: ne_liheap_eligible: false @@ -46,7 +48,69 @@ state_code: NE ne_liheap_income_eligible: true heat_expense_included_in_rent: false + heating_type: UNSPECIFIED heating_expense: 0 output: ne_liheap_eligible: false ne_liheap: 0 + +# Cases 6-9: FY2026 state plan section 2.3. Renters in subsidized housing must +# be responsible for a portion of the heating payment; market-rate renters with +# heat included in rent are accepted under the documented modeling assumption. +# https://dhhs.ne.gov/Documents/LIHEAP%20State%20Plan.pdf#page=9 +- name: Case 6, housing-assisted renter with heat in rent and no heating bill is ineligible. + period: 2026 + input: + state_code: NE + ne_liheap_income_eligible: true + receives_housing_assistance: true + heat_expense_included_in_rent: true + heating_type: NATURAL_GAS + gas_expense: 0 + output: + # The matching gas bill is zero, so no portion of the heating is paid. + heating_expense: 0 + ne_liheap_eligible: false + ne_liheap: 0 + +- name: Case 7, public housing tenant with heat in rent and no heating bill is ineligible. + period: 2026 + input: + state_code: NE + ne_liheap_income_eligible: true + is_in_public_housing: true + heat_expense_included_in_rent: true + heating_type: UNSPECIFIED + output: + # An unspecified fuel has no matching bill. + heating_expense: 0 + ne_liheap_eligible: false + ne_liheap: 0 + +- name: Case 8, housing-assisted renter who pays part of the heating cost is eligible. + period: 2026 + input: + state_code: NE + ne_liheap_income_eligible: true + receives_housing_assistance: true + heat_expense_included_in_rent: true + heating_type: NATURAL_GAS + gas_expense: 420 + output: + # A $35 monthly gas charge on top of rent: 35 * 12 = 420. + heating_expense: 420 + ne_liheap_eligible: true + +- name: Case 9, market-rate renter with heat in rent and no heating bill stays eligible. + period: 2026 + input: + state_code: NE + ne_liheap_income_eligible: true + receives_housing_assistance: false + is_in_public_housing: false + heat_expense_included_in_rent: true + heating_type: UNSPECIFIED + pre_subsidy_rent: 9_600 + output: + heating_expense: 0 + ne_liheap_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.yaml new file mode 100644 index 00000000000..c80bbbcd305 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.yaml @@ -0,0 +1,117 @@ +# Source: 475 NAC 3-002.06(A)-(B), incorporated by 476 NAC 2-002.01. An excluded +# member's countable income is divided evenly among all household members and +# the eligible members' shares are counted: eligible members / all members. +# https://rules.nebraska.gov/rules?agencyId=37&titleId=230 + +- name: Case 1, excluded member income is prorated by eligible members over all members. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 34 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + employment_income: 14_000 + person2: + age: 36 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: UNDOCUMENTED + employment_income: 21_000 + interest_income: 300 + person3: + age: 6 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 0 + households: + household: + members: [person1, person2, person3] + state_code: NE + output: + # Two eligible members of three: the excluded member's share is 2/3, + # which differs from excluded / all = 1/3 and 1 / all = 1/3. + ne_liheap_household_size: 2 + # 14,000 + 21,000 * 2 / 3 = 28,000 (a 1/3 share would give 21,000). + ne_liheap_earned_income: 28_000 + # 28,000 + 300 * 2 / 3 = 28,200. + ne_liheap_gross_income: 28_200 + # 2025 guideline for two: 15,650 + 5,500 = 21,150; limit 31,725. + ne_liheap_fpg: 21_150 + ne_liheap_income_eligible: true + ne_liheap_eligible: true + # 28,200 - 0.2 * 28,000 = 22,600; 22,600 / 21,150 = 1.069, + # natural gas Tier 3. + ne_liheap: 400 + +- name: Case 2, unit-level TANF is counted in full alongside prorated member income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 37 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: UNDOCUMENTED + employment_income: 15_000 + person2: + age: 35 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: UNDOCUMENTED + employment_income: 5_000 + child_support_received: 3_000 + person3: + age: 11 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + person4: + age: 8 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + person5: + age: 4 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + heating_type: PROPANE + bottled_gas_expense: 1_500 + # Child-only grant of $300 a month: 300 * 12 = 3,600. + tanf: 3_600 + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: NE + output: + # Three eligible children of five members: share 3/5, which differs + # from excluded / all = 2/5 and 1 / all = 1/5. + ne_liheap_household_size: 3 + # (15,000 + 5,000) * 3 / 5 = 12,000. + ne_liheap_earned_income: 12_000 + # 12,000 + 3,000 * 3 / 5 + 3,600 = 17,400. TANF is not prorated + # (3,600 * 3 / 5 = 2,160 would give 15,960). + ne_liheap_gross_income: 17_400 + # 2025 guideline for three: 15,650 + 2 * 5,500 = 26,650; limit 39,975. + ne_liheap_fpg: 26_650 + ne_liheap_income_eligible: true + ne_liheap_eligible: true + # 17,400 - 0.2 * 12,000 = 15,000; 15,000 / 26,650 = 0.563, + # propane Tier 1. + ne_liheap: 850 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml index 64e8b543ee1..de4d4eacc6f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml @@ -67,3 +67,128 @@ - 580 - 0 - 0 + +- name: Case 2, refugee and asylee members are excluded in FY2026 while lawful permanent residents count. + # 476 NAC 2-002.02 and DHHS OBBBA FAQ Q12: LIHEAP follows the SNAP + # citizenship rules, which no longer cover refugee or asylee status alone. + # https://dhhs.ne.gov/Documents/OBBB-SNAP-Changes-FAQ.pdf#page=3 + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 36 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: REFUGEE + employment_income: 31_200 + person2: + age: 33 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: REFUGEE + person3: + age: 2 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + person4: + age: 29 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: ASYLEE + employment_income: 24_000 + person5: + age: 45 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: LEGAL_PERMANENT_RESIDENT + employment_income: 24_000 + person6: + age: 43 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + immigration_status: LEGAL_PERMANENT_RESIDENT + spm_units: + spm1: + members: + - person1 + - person2 + - person3 + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 1_200 + spm2: + members: + - person4 + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 900 + spm3: + members: + - person5 + - person6 + tanf: 0 + heating_type: PROPANE + bottled_gas_expense: 1_500 + households: + household1: + members: + - person1 + - person2 + - person3 + state_code: NE + household2: + members: + - person4 + state_code: NE + household3: + members: + - person5 + - person6 + state_code: NE + output: + # Refugee parents with a citizen child: 1. Asylee alone: 0. + # Lawful permanent resident couple: 2. + ne_liheap_household_size: + - 1 + - 0 + - 2 + # Unit 1: full-time at the $15 minimum wage, 2,080 * 15 = 31,200, prorated + # by one eligible member of three: 31,200 / 3 = 10,400. + # Unit 2: no eligible member, so the share is 0 / 1. + ne_liheap_earned_income: + - 10_400 + - 0 + - 24_000 + ne_liheap_gross_income: + - 10_400 + - 0 + - 24_000 + # 2025 guideline: 15,650 for one; none without an eligible member; + # 15,650 + 5,500 = 21,150 for two. + ne_liheap_fpg: + - 15_650 + - 0 + - 21_150 + ne_liheap_income_eligible: + - true + - false + - true + ne_liheap_eligible: + - true + - false + - true + # Unit 1: 10,400 - 0.2 * 10,400 = 8,320; 8,320 / 15,650 = 0.532, + # natural gas Tier 1. + # Unit 3: 24,000 - 0.2 * 24,000 = 19,200; 19,200 / 21,150 = 0.908, + # propane Tier 2. + ne_liheap: + - 700 + - 0 + - 580 diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py index 03ae45a99d3..f1256e9b98d 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py @@ -38,8 +38,12 @@ def formula(spm_unit, period, parameters): multifamily = dwelling == dwelling.possible_values.MULTI_FAMILY # Corn shares the natural gas/electricity/coal payment column. No # separate schedule is needed, but the fuel enum cannot isolate corn - # from OTHER. Single-family OTHER/SOLAR/UNSPECIFIED remain unmapped; - # the multifamily column covers all fuel types. + # from OTHER. The multifamily column covers all fuel types. + # Limitation: an eligible single-family household whose heating_type + # is UNSPECIFIED, OTHER, SOLAR or NONE is paid $0; there is no + # fallback fuel. This includes a heat-in-rent renter who leaves + # heating_type at its UNSPECIFIED default and omits the dwelling + # type, which defaults to single-family. # No FY2026 supplemental heating amount has been verified. return select( [ diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py index bd3d2aff899..bee44d61414 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py @@ -23,11 +23,16 @@ def formula(spm_unit, period, parameters): # retain the eligible members' shares. Eligible members count in full. fraction = size / max_(spm_unit("spm_unit_size", period), 1) share = where(included, 1, spm_unit.project(fraction)) - # Use existing net self-employment income without another business - # expense deduction. Nebraska's tax-return/49%-ledger distinction, - # capital gains from business assets, and farm-loss offsets require - # additional source information and are not modeled here. - earned = max_(person("employment_income", period), 0) + max_( - person("self_employment_income", period), 0 + # 475 NAC 3-002.04(B)(i) counts each source of self-employment, so + # both existing net non-farm inputs are read, each floored at zero, + # without another business expense deduction. Farm self-employment + # income is not read: neither positive farm income nor farm-loss + # offsets are modeled. Nebraska's tax-return/49%-ledger distinction + # and capital gains from business assets require additional source + # information and are not modeled here. + earned = ( + max_(person("employment_income", period), 0) + + max_(person("self_employment_income", period), 0) + + max_(person("sstb_self_employment_income", period), 0) ) return spm_unit.sum(earned * countable * share) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py index 20ebe1dbf6e..859a85e570c 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py @@ -17,9 +17,17 @@ def formula(spm_unit, period, parameters): # 476 NAC 1-004.09 includes energy paid through rent; FY2026 plan 2.3 # allows such renters when responsible for a portion of heating costs. # Modeling assumption: economic vulnerability under 1-004.06 and - # 2-002(A) is assumed, rather than separately verified. Accept heating - # paid through rent even when the separately reported expense is zero. + # 2-002(A) is assumed, rather than separately verified. Market-rate + # renters with heating paid through rent are accepted even when the + # separately reported expense is zero. Plan 2.3 requires subsidized + # housing households to be responsible for a portion of the heating + # payment, so households receiving housing assistance or living in + # public housing need a positive heating expense. # Administrative disqualifications remain unmodeled. + has_heating_expense = spm_unit("heating_expense", period) > 0 heat_in_rent = spm_unit("heat_expense_included_in_rent", period) - responsible = (spm_unit("heating_expense", period) > 0) | heat_in_rent + housing_assisted = spm_unit("receives_housing_assistance", period) + public_housing = spm_unit.household("is_in_public_housing", period) + subsidized = housing_assisted | public_housing + responsible = has_heating_expense | (heat_in_rent & ~subsidized) return income_eligible & responsible From 89582437c71e81d987cc54c0ffd799ac09b679bb Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 1 Oct 2026 01:24:47 -0400 Subject: [PATCH 5/7] Count farm operations income in Nebraska LIHEAP --- policyengine_us/programs.yaml | 2 +- .../dhhs/liheap/ne_liheap_earned_income.yaml | 23 +++++++++++++++++++ .../ne/dhhs/liheap/ne_liheap_earned_income.py | 13 ++++++----- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index f5a02452dbf..114da233542 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -837,7 +837,7 @@ programs: variable: ne_liheap parameter_prefix: gov.states.ne.dhhs.liheap verified_years: "2026" - notes: FY2026 regular single-family and multifamily heating schedules, gross-income eligibility, and earned-income disregard. A state-specific dwelling-type input selects the schedule, defaulting to single-family when omitted. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net non-farm self-employment income (regular and SSTB inputs, each floored at zero) without another business deduction. Economic vulnerability is assumed for modeling; a positive heating expense establishes heating responsibility, and so does heat included in rent for market-rate renters, including zero separately reported expenses. Households receiving housing assistance or living in public housing need a positive heating expense (FY2026 plan section 2.3). Program disqualifications, detailed immigration conditions, business-record expense alternatives, farm self-employment income (neither positive farm income nor farm-loss offsets is read), and discretionary heating supplements are not modeled. Single-family payments require a supported primary fuel; an eligible single-family household with an unspecified, other, solar, or no heating fuel is paid $0 with no fallback fuel, including a heat-in-rent renter who omits the fuel and the dwelling type. Multifamily payments cover all fuels. Calendar 2026 represents the season ending in 2026; earlier results use parameter backfilling and are unverified historical estimates. No cooling, crisis, weatherization, or equipment assistance. + notes: FY2026 regular single-family and multifamily heating schedules, gross-income eligibility, and earned-income disregard. A state-specific dwelling-type input selects the schedule, defaulting to single-family when omitted. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net business and farm income (regular, SSTB and farm operations inputs, each floored at zero) without another business deduction. Economic vulnerability is assumed for modeling; a positive heating expense establishes heating responsibility, and so does heat included in rent for market-rate renters, including zero separately reported expenses. Households receiving housing assistance or living in public housing need a positive heating expense (FY2026 plan section 2.3). Program disqualifications, detailed immigration conditions, business-record expense alternatives, special farm-loss offsets requiring gross-receipts and tax-return evidence, and discretionary heating supplements are not modeled. Single-family payments require a supported primary fuel; an eligible single-family household with an unspecified, other, solar, or no heating fuel is paid $0 with no fallback fuel, including a heat-in-rent renter who omits the fuel and the dwelling type. Multifamily payments cover all fuels. Calendar 2026 represents the season ending in 2026; earlier results use parameter backfilling and are unverified historical estimates. No cooling, crisis, weatherization, or equipment assistance. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml index 49747d64861..c9caac87761 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml @@ -22,3 +22,26 @@ output: # Each source is floored at zero: 12,000 + 6,000 + max(-4,000, 0) = 18,000. ne_liheap_earned_income: 18_000 + +- name: Case 3, farm profits affect eligibility and payment while unsupported farm-loss offsets are excluded. + # 475 NAC 3-002.04(B): count farm profits with other self-employment. + # The special loss offset requires gross-receipts and tax-return evidence. + period: 2026 + input: + state_code: [NE, NE, NE] + age: [40, 40, 40] + employment_income: [0, 0, 12_000] + farm_operations_income: [18_000, 60_000, -5_000] + ssi: [0, 0, 0] + social_security: [0, 0, 0] + tanf: [0, 0, 0] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000] + output: + ne_liheap_earned_income: [18_000, 60_000, 12_000] + ne_liheap_gross_income: [18_000, 60_000, 12_000] + # One-person limit: 15,650 * 1.5 = 23,475. + ne_liheap_income_eligible: [true, false, true] + # After the 20% earned disregard: 14,400 and 9,600 fall in utility + # payment bands 2 and 1, respectively; 60,000 fails gross eligibility. + ne_liheap: [550, 0, 700] diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py index bee44d61414..2776eeab211 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py @@ -24,15 +24,16 @@ def formula(spm_unit, period, parameters): fraction = size / max_(spm_unit("spm_unit_size", period), 1) share = where(included, 1, spm_unit.project(fraction)) # 475 NAC 3-002.04(B)(i) counts each source of self-employment, so - # both existing net non-farm inputs are read, each floored at zero, - # without another business expense deduction. Farm self-employment - # income is not read: neither positive farm income nor farm-loss - # offsets are modeled. Nebraska's tax-return/49%-ledger distinction - # and capital gains from business assets require additional source - # information and are not modeled here. + # existing net business and farm inputs are read, each floored at zero, + # without another business expense deduction. The special farm-loss + # offset requires tax-return evidence and at least $1,000 of gross farm + # income, which existing inputs cannot establish. That offset, Nebraska's + # tax-return/49%-ledger distinction, and capital gains from business + # assets are not modeled here. earned = ( max_(person("employment_income", period), 0) + max_(person("self_employment_income", period), 0) + max_(person("sstb_self_employment_income", period), 0) + + max_(person("farm_operations_income", period), 0) ) return spm_unit.sum(earned * countable * share) From 39cd98794ae9aea1c54cde1e4e9ca800c122b040 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 1 Oct 2026 17:41:20 -0400 Subject: [PATCH 6/7] Address review items in Nebraska LIHEAP: pinned citations, heat-in-rent sourcing and boundary tests - Cite the ACF copy of the FY2026 state plan instead of the DHHS URL that now serves the FFY2027 plan - Cite the edition-pinned 475 NAC chapter 3 and 476 NAC chapters 1 and 2 PDFs instead of the live viewer - Quote both plan section 2.3 sentences and cite 476 NAC 3-002.02 and plan sections 1.1 and 9.1 for market-rate heat-in-rent renters - Add a single-family heat-in-rent payment case and a seven-person case that pins the six-person payment cap - Rename the local heating-bill flag, drop two redundant guards, note the size-6+ footnote wording, re-word two descriptions - Fix test headers, case names and inert inputs; make Case 30 depend on the earned-income disregard - Shorten the registry note Co-Authored-By: Claude Fable 5.1 --- .../dhhs/liheap/earned_income_disregard.yaml | 2 +- .../states/ne/dhhs/liheap/fpg_year_lag.yaml | 4 +- .../states/ne/dhhs/liheap/income_limit.yaml | 6 +- .../ne/dhhs/liheap/payment_size_limit.yaml | 2 +- policyengine_us/programs.yaml | 2 +- .../states/ne/dhhs/liheap/integration.yaml | 57 ++++++++++++++++--- .../gov/states/ne/dhhs/liheap/ne_liheap.yaml | 33 ++++++++--- .../dhhs/liheap/ne_liheap_earned_income.yaml | 3 +- .../ne/dhhs/liheap/ne_liheap_eligible.yaml | 30 ++++++---- .../states/ne/dhhs/liheap/ne_liheap_fpg.yaml | 2 +- .../dhhs/liheap/ne_liheap_gross_income.yaml | 2 +- .../dhhs/liheap/ne_liheap_household_size.yaml | 7 ++- .../gov/states/ne/dhhs/liheap/ne_liheap.py | 7 ++- .../ne/dhhs/liheap/ne_liheap_dwelling_type.py | 2 +- .../ne/dhhs/liheap/ne_liheap_earned_income.py | 5 +- .../ne/dhhs/liheap/ne_liheap_eligible.py | 29 ++++++---- .../ne/dhhs/liheap/ne_liheap_gross_income.py | 2 +- .../dhhs/liheap/ne_liheap_household_size.py | 7 ++- .../dhhs/liheap/ne_liheap_income_eligible.py | 5 +- 19 files changed, 151 insertions(+), 56 deletions(-) diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_disregard.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_disregard.yaml index 8f9350af5e0..ccaea440e6a 100644 --- a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_disregard.yaml +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_disregard.yaml @@ -1,4 +1,4 @@ -description: Nebraska disregards this share of gross countable earned income when determining regular heating payments after testing gross-income eligibility under the Low Income Home Energy Assistance Program. +description: Nebraska excludes this share of gross countable earned income when determining regular heating payments under the Low Income Home Energy Assistance Program. values: 2025-10-01: 0.2 metadata: diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml index fde423c25c8..8831ad37143 100644 --- a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml @@ -6,5 +6,7 @@ metadata: period: year label: Nebraska LIHEAP federal poverty guideline year lag reference: - - title: Nebraska LIHEAP Guidance Document effective October 1, 2025 + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025 (the one-person limit of $23,475 is 150% of the 2025 guideline) href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 + - title: HHS poverty guidelines, 2025 (Federal Register references) + href: https://aspe.hhs.gov/topics/poverty-economic-mobility/poverty-guidelines/prior-hhs-poverty-guidelines-federal-register-references diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml index e5bc1c8a07e..14b2cc2defa 100644 --- a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml @@ -6,5 +6,7 @@ metadata: period: year label: Nebraska LIHEAP income limit reference: - - title: Nebraska LIHEAP Guidance Document effective October 1, 2025 - href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 + - title: Nebraska LIHEAP Guidance Document effective October 1, 2025, pages 1-2 (income limits; "at or below 150% of the federal poverty level") + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 + - title: 476 NAC 2-002.01 Income Guidelines (total annual income "may not exceed 150% of the federal poverty level") + href: https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%202%20(06-26-2022).pdf/1747#page=1 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment_size_limit.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment_size_limit.yaml index 965fd6df34f..c4fea5d14ee 100644 --- a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment_size_limit.yaml +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/payment_size_limit.yaml @@ -1,4 +1,4 @@ -description: Nebraska caps household size at this number when determining regular heating payment income bands under the Low Income Home Energy Assistance Program. +description: Nebraska limits household size to this number when determining regular heating payment income bands under the Low Income Home Energy Assistance Program. values: 2025-10-01: 6 metadata: diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 114da233542..9a6e3927dc7 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -837,7 +837,7 @@ programs: variable: ne_liheap parameter_prefix: gov.states.ne.dhhs.liheap verified_years: "2026" - notes: FY2026 regular single-family and multifamily heating schedules, gross-income eligibility, and earned-income disregard. A state-specific dwelling-type input selects the schedule, defaulting to single-family when omitted. Uses existing SNAP income sources and immigration-status eligibility with an SPM-unit household approximation; counts existing net business and farm income (regular, SSTB and farm operations inputs, each floored at zero) without another business deduction. Economic vulnerability is assumed for modeling; a positive heating expense establishes heating responsibility, and so does heat included in rent for market-rate renters, including zero separately reported expenses. Households receiving housing assistance or living in public housing need a positive heating expense (FY2026 plan section 2.3). Program disqualifications, detailed immigration conditions, business-record expense alternatives, special farm-loss offsets requiring gross-receipts and tax-return evidence, and discretionary heating supplements are not modeled. Single-family payments require a supported primary fuel; an eligible single-family household with an unspecified, other, solar, or no heating fuel is paid $0 with no fallback fuel, including a heat-in-rent renter who omits the fuel and the dwelling type. Multifamily payments cover all fuels. Calendar 2026 represents the season ending in 2026; earlier results use parameter backfilling and are unverified historical estimates. No cooling, crisis, weatherization, or equipment assistance. + notes: FY2026 regular heating only, with the single-family and multifamily schedules and the earned-income disregard. Crisis, cooling and weatherization assistance are out of scope. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml index 8a3dd39d36b..1b532dd8c5f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml @@ -197,7 +197,6 @@ ne_liheap_dwelling_type: MULTI_FAMILY heat_expense_included_in_rent: true heating_type: UNSPECIFIED - heating_expense: 0 tanf: 0 households: household: @@ -209,14 +208,16 @@ ne_liheap_gross_income: 18_000 ne_liheap_fpg: 15_650 ne_liheap_income_eligible: true + heating_expense: 0 ne_liheap_eligible: true # Income after the 20% disregard is $14,400: multifamily Tier 2. ne_liheap: 300 - name: Case 8, specified service trade self-employment income above the limit is ineligible. - # 475 NAC 3-002.04(B)(i), incorporated by 476 NAC 2-002.01, counts each - # source of self-employment. A self-employed bookkeeper reports net income - # in sstb_self_employment_income. + # 475 NAC 3-002.04(B)(i) (text in effect for FY2026), incorporated by + # 476 NAC 2-002.01, counts each source of self-employment. A self-employed + # bookkeeper reports net income in sstb_self_employment_income. + # https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=44 period: 2026 input: people: @@ -248,9 +249,10 @@ ne_liheap: 0 - name: Case 9, housing-assisted renter with heat in rent and no heating bill is ineligible. - # FY2026 state plan section 2.3: subsidized-housing renters must be - # responsible for a portion of the heating payment. - # https://dhhs.ne.gov/Documents/LIHEAP%20State%20Plan.pdf#page=9 + # FY2026 state plan section 2.3 (page 9): "For subsidized housing, the + # household must be responsible for a portion of the heating payment to be + # eligible for heating." + # https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=9 period: 2026 input: people: @@ -325,3 +327,44 @@ ne_liheap_eligible: true # No earned income to disregard: 13,200 / 15,650 = 0.843, multifamily Tier 2. ne_liheap: 300 + +- name: Case 11, market-rate single-family renter with heat in rent and a zero gas bill receives the single-family payment. + # Plan section 2.3 (page 9) also says renters with utilities included in + # rent must be responsible for a portion of the heating; the model treats + # market-rate heat-in-rent renters as responsible. 476 NAC 3-002.02 lets + # the Department pay such a household directly, and plan sections 1.1 + # (page 5) and 9.1 (page 25) list them among households paid directly. + # https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=5,9,25 + # https://www.law.cornell.edu/regulations/nebraska/476-Neb-Admin-Code-ch-3-SS-002 + period: 2026 + input: + people: + person1: + age: 34 + ssi: 0 + ne_aabd: 0 + general_assistance: 0 + employment_income: 18_000 + spm_units: + spm_unit: + members: [person1] + ne_liheap_dwelling_type: SINGLE_FAMILY + heat_expense_included_in_rent: true + heating_type: NATURAL_GAS + gas_expense: 0 + tanf: 0 + households: + household: + members: [person1] + state_code: NE + output: + ne_liheap_household_size: 1 + ne_liheap_earned_income: 18_000 + ne_liheap_gross_income: 18_000 + ne_liheap_fpg: 15_650 + ne_liheap_income_eligible: true + heating_expense: 0 + ne_liheap_eligible: true + # 18,000 - 0.2 * 18,000 = 14,400; 14,400 / 15,650 = 0.920: single-family + # natural gas Tier 2. + ne_liheap: 550 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml index 043afda9549..19d49d91113 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml @@ -188,7 +188,7 @@ heating_type: NATURAL_GAS output: ne_liheap: 700 -- name: Case 18, countable income of 10955 respects the closed upper tier boundary. +- name: Case 18, countable income of 10955.01 falls into the next tier. period: 2026 input: state_code: NE @@ -199,7 +199,7 @@ heating_type: NATURAL_GAS output: ne_liheap: 550 -- name: Case 19, countable income of 15650 respects the closed upper tier boundary. +- name: Case 19, countable income of 15650.01 falls into the next tier. period: 2026 input: state_code: NE @@ -210,7 +210,7 @@ heating_type: NATURAL_GAS output: ne_liheap: 400 -- name: Case 20, countable income of 20345 respects the closed upper tier boundary. +- name: Case 20, countable income of 20345.01 falls into the next tier. period: 2026 input: state_code: NE @@ -221,7 +221,7 @@ heating_type: NATURAL_GAS output: ne_liheap: 280 -- name: Case 21, countable income of -100 respects the closed upper tier boundary. +- name: Case 21, negative countable income is paid at the lowest tier. period: 2026 input: state_code: NE @@ -326,11 +326,13 @@ state_code: NE ne_liheap_eligible: true ne_liheap_household_size: 1 - ne_liheap_gross_income: 20_000 - ne_liheap_earned_income: 20_000 + ne_liheap_gross_income: 17_000 + ne_liheap_earned_income: 17_000 heating_type: NATURAL_GAS output: - ne_liheap: 400 + # 17,000 - 0.2 * 17,000 = 13,600; 13,600 / 15,650 = 0.869 -> Tier 2 (550). + # Without the disregard, 17,000 / 15,650 = 1.086 would be Tier 3 (400). + ne_liheap: 550 - name: Case 31, multifamily dwelling payments at each closed income boundary. # FY2026 heating table, multifamily all-fuel column: $380/$300/$220/$154. @@ -385,3 +387,20 @@ ne_liheap_income_eligible: true ne_liheap_eligible: true ne_liheap: 0 + +- name: Case 34, seven-person payment bands use the six-person guideline at each closed boundary. + # Guidance p. 2 footnote for household sizes of 6 or more: $30,205 or less is + # Tier 1; $30,205.01 through $43,150 Tier 2; $43,150.01 through $56,095 Tier 3; + # above that Tier 4. These are 70%, 100% and 130% of the six-person 2025 + # guideline of 43,150. A five-person cap would put 30,205 in Tier 2 + # (30,205 / 37,650 = 0.802), so this pins the cap at six. + period: 2026 + input: + state_code: [NE, NE, NE, NE, NE, NE] + ne_liheap_eligible: [true, true, true, true, true, true] + ne_liheap_household_size: [7, 7, 7, 7, 7, 7] + ne_liheap_gross_income: [30_205, 30_205.01, 43_150, 43_150.01, 56_095, 56_095.01] + ne_liheap_earned_income: [0, 0, 0, 0, 0, 0] + heating_type: [PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE] + output: + ne_liheap: [850, 580, 580, 330, 330, 165] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml index c9caac87761..412bb55704d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.yaml @@ -1,6 +1,7 @@ # Source: 475 NAC 3-002.04(B)(i), incorporated by 476 NAC 2-002.01, counts # each source of self-employment of the household. -# https://rules.nebraska.gov/rules?agencyId=37&titleId=230 +# Text in effect 2024-09-17 to 2026-07-28; the current text renumbers it. +# https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=44 - name: Case 1, specified service trade self-employment income counts as earned income. period: 2026 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml index 7c0a37778f8..d6697bc82fa 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml @@ -1,5 +1,9 @@ -# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. -# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 +# Source: 476 NAC 1-004.09 (household, including energy paid through rent) and +# 2-002 (eligibility); FY2026 state plan section 2.3 (renters in subsidized +# housing and renters with utilities included in rent), page 9. +# https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%201%20(12-26-2020).pdf/1746#page=1 +# https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%202%20(06-26-2022).pdf/1747#page=1 +# https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=9 - name: Case 1, direct heating bill establishes energy responsibility. period: 2026 @@ -17,9 +21,8 @@ ne_liheap_income_eligible: true heat_expense_included_in_rent: true heating_type: UNSPECIFIED - heating_expense: 0 - pre_subsidy_rent: 10_000 output: + heating_expense: 0 ne_liheap_eligible: true - name: Case 3, heat in rent does not bypass the income test. period: 2026 @@ -28,8 +31,8 @@ ne_liheap_income_eligible: false heat_expense_included_in_rent: true heating_type: UNSPECIFIED - heating_expense: 0 output: + heating_expense: 0 ne_liheap_eligible: false - name: Case 4, another state receives no Nebraska benefit. period: 2026 @@ -49,15 +52,21 @@ ne_liheap_income_eligible: true heat_expense_included_in_rent: false heating_type: UNSPECIFIED - heating_expense: 0 output: + heating_expense: 0 ne_liheap_eligible: false ne_liheap: 0 -# Cases 6-9: FY2026 state plan section 2.3. Renters in subsidized housing must -# be responsible for a portion of the heating payment; market-rate renters with -# heat included in rent are accepted under the documented modeling assumption. -# https://dhhs.ne.gov/Documents/LIHEAP%20State%20Plan.pdf#page=9 +# Cases 6-9: FY2026 state plan section 2.3 (page 9): "For subsidized housing, +# the household must be responsible for a portion of the heating payment to be +# eligible for heating" and "For renters with utilities included in the rent, +# the household must be responsible for a portion of the heating." Market-rate +# renters with heat included in rent are treated as responsible under the +# documented modeling assumption; 476 NAC 3-002.02 lets the Department pay a +# household directly if utilities are included in rent, and plan sections 1.1 +# (page 5) and 9.1 (page 25) list such households among those paid directly. +# https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=5,9,25 +# https://www.law.cornell.edu/regulations/nebraska/476-Neb-Admin-Code-ch-3-SS-002 - name: Case 6, housing-assisted renter with heat in rent and no heating bill is ineligible. period: 2026 input: @@ -110,7 +119,6 @@ is_in_public_housing: false heat_expense_included_in_rent: true heating_type: UNSPECIFIED - pre_subsidy_rent: 9_600 output: heating_expense: 0 ne_liheap_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml index b3a34e55f19..3a5a4e910ca 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml @@ -1,7 +1,7 @@ # Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. # https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 -- name: Case 1, FY2026 guideline for 1 members uses 2025 federal amounts. +- name: Case 1, FY2026 guideline for 1 member uses 2025 federal amounts. period: 2026 input: state_code: NE diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.yaml index c80bbbcd305..bac8c185191 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.yaml @@ -1,7 +1,7 @@ # Source: 475 NAC 3-002.06(A)-(B), incorporated by 476 NAC 2-002.01. An excluded # member's countable income is divided evenly among all household members and # the eligible members' shares are counted: eligible members / all members. -# https://rules.nebraska.gov/rules?agencyId=37&titleId=230 +# https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=47 - name: Case 1, excluded member income is prorated by eligible members over all members. period: 2026 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml index de4d4eacc6f..bbbe2a5b37b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_household_size.yaml @@ -1,5 +1,8 @@ -# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. -# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 +# Source: 476 NAC 2-002.02 and 2-002.03 (members excluded for citizenship, +# residency or disqualification) and 475 NAC 3-002.06 (excluded members' +# income proration), text in effect for FY2026. +# https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%202%20(06-26-2022).pdf/1747#page=1 +# https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=47 - name: Case 1, mixed households keep Nebraska eligibility and payments separate. period: 2026 diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py index f1256e9b98d..750d5932f22 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py @@ -23,6 +23,10 @@ def formula(spm_unit, period, parameters): size = spm_unit("ne_liheap_household_size", period) state_group = spm_unit.household("state_group_str", period) # The payment bands stop growing at six people; eligibility does not. + # The Guidance footnote states the size-6+ tier cutoffs in "gross + # countable income", while the same page bases every payment on + # "income after the disregard is applied" with no size exception; the + # disregard is applied at every size here. payment_fpg = fpg( clip(size, 1, p.payment_size_limit), state_group, @@ -30,8 +34,7 @@ def formula(spm_unit, period, parameters): parameters, year_lag=p.fpg_year_lag, ) - payment_fpg = where(size > 0, payment_fpg, 0) - income_ratio = income / max_(payment_fpg, 1) + income_ratio = income / payment_fpg fuel = spm_unit("heating_type", period) types = fuel.possible_values dwelling = spm_unit("ne_liheap_dwelling_type", period) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_dwelling_type.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_dwelling_type.py index aad1435ed39..364f4c5c012 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_dwelling_type.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_dwelling_type.py @@ -20,4 +20,4 @@ class ne_liheap_dwelling_type(Variable): "means one household occupies the structure. If omitted, the model " "assumes single-family; report the type to apply the correct schedule." ) - reference = "https://rules.nebraska.gov/rules?agencyId=37&titleId=231" + reference = "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%201%20(12-26-2020).pdf/1746#page=2" diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py index 2776eeab211..a30839fdf4c 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py @@ -10,7 +10,7 @@ class ne_liheap_earned_income(Variable): defined_for = StateCode.NE reference = ( "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7", - "https://rules.nebraska.gov/rules?agencyId=37&titleId=230", + "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=44,47", ) def formula(spm_unit, period, parameters): @@ -23,7 +23,8 @@ def formula(spm_unit, period, parameters): # retain the eligible members' shares. Eligible members count in full. fraction = size / max_(spm_unit("spm_unit_size", period), 1) share = where(included, 1, spm_unit.project(fraction)) - # 475 NAC 3-002.04(B)(i) counts each source of self-employment, so + # 475 NAC 3-002.04(B)(i), in the text in effect for FY2026 (the current + # text renumbers it), counts each source of self-employment, so # existing net business and farm inputs are read, each floored at zero, # without another business expense deduction. The special farm-loss # offset requires tax-return evidence and at least $1,000 of gross farm diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py index 859a85e570c..2dabd59c129 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py @@ -8,26 +8,35 @@ class ne_liheap_eligible(Variable): label = "Nebraska LIHEAP regular heating assistance eligibility" defined_for = StateCode.NE reference = ( - "https://rules.nebraska.gov/rules?agencyId=37&titleId=231", - "https://dhhs.ne.gov/Documents/LIHEAP%20State%20Plan.pdf#page=9", + "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%201%20(12-26-2020).pdf/1746#page=1", + "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%202%20(06-26-2022).pdf/1747#page=1", + "https://www.law.cornell.edu/regulations/nebraska/476-Neb-Admin-Code-ch-3-SS-002", + "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=5,9,25", ) def formula(spm_unit, period, parameters): income_eligible = spm_unit("ne_liheap_income_eligible", period) - # 476 NAC 1-004.09 includes energy paid through rent; FY2026 plan 2.3 - # allows such renters when responsible for a portion of heating costs. + # 476 NAC 1-004.09 includes energy paid through rent. FY2026 plan + # section 2.3 (page 9) says "For subsidized housing, the household must + # be responsible for a portion of the heating payment to be eligible + # for heating" and "For renters with utilities included in the rent, + # the household must be responsible for a portion of the heating." # Modeling assumption: economic vulnerability under 1-004.06 and # 2-002(A) is assumed, rather than separately verified. Market-rate - # renters with heating paid through rent are accepted even when the - # separately reported expense is zero. Plan 2.3 requires subsidized - # housing households to be responsible for a portion of the heating - # payment, so households receiving housing assistance or living in + # renters with heating paid through rent are treated as responsible + # even when the separately reported expense is zero: 476 NAC 3-002.02 + # lets the Department pay a household directly "if utilities are + # included in rent", and plan sections 1.1 (page 5) and 9.1 (page 25) + # list households whose utilities are included in rent among those + # paid directly. Households receiving housing assistance or living in # public housing need a positive heating expense. # Administrative disqualifications remain unmodeled. - has_heating_expense = spm_unit("heating_expense", period) > 0 + # Not the repo variable has_heating_expense, which is false whenever + # heat is included in rent. + pays_heating_bill = spm_unit("heating_expense", period) > 0 heat_in_rent = spm_unit("heat_expense_included_in_rent", period) housing_assisted = spm_unit("receives_housing_assistance", period) public_housing = spm_unit.household("is_in_public_housing", period) subsidized = housing_assisted | public_housing - responsible = has_heating_expense | (heat_in_rent & ~subsidized) + responsible = pays_heating_bill | (heat_in_rent & ~subsidized) return income_eligible & responsible diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py index d0efce46751..2224f9f84d0 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py @@ -10,7 +10,7 @@ class ne_liheap_gross_income(Variable): defined_for = StateCode.NE reference = ( "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7", - "https://rules.nebraska.gov/rules?agencyId=37&titleId=230", + "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=47", ) def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py index 4232f08aabd..6e50e7deac8 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_household_size.py @@ -8,7 +8,7 @@ class ne_liheap_household_size(Variable): label = "Nebraska LIHEAP eligible household size" defined_for = StateCode.NE reference = ( - "https://rules.nebraska.gov/rules?agencyId=37&titleId=231", + "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%202%20(06-26-2022).pdf/1747#page=1", "https://dhhs.ne.gov/Documents/OBBB-SNAP-Changes-FAQ.pdf#page=3", ) @@ -16,8 +16,9 @@ def formula(spm_unit, period, parameters): # 476 NAC 2-002.02 incorporates SNAP citizenship/alien-status rules; # DHHS's OBBBA FAQ, Q12, expressly applies those changes to LIHEAP. # This is the immigration-status test, not SNAP work/student eligibility. - # Its current implementation cannot resolve waiting periods/exceptions, - # COFA status, or case-specific recertification timing. These remain gaps. + # The shared variable applies the SNAP qualified-alien waiting period + # and its exceptions; COFA status and case-specific recertification + # timing remain gaps. # SPM units approximate energy-purchasing units (476 NAC 1-004.09). # LIHEAP-specific program violations and residency fraud are unmodeled. return add( diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py index 2112edd18fa..bb420fe4dad 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py @@ -7,7 +7,10 @@ class ne_liheap_income_eligible(Variable): definition_period = YEAR label = "Nebraska LIHEAP income eligibility" defined_for = StateCode.NE - reference = "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1" + reference = ( + "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2", + "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%202%20(06-26-2022).pdf/1747#page=1", + ) def formula(spm_unit, period, parameters): p = parameters(period).gov.states.ne.dhhs.liheap From 73aa59057a550b5cf1d1b47296612458e10b1819 Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 2 Oct 2026 12:35:29 -0400 Subject: [PATCH 7/7] Address second Nebraska LIHEAP review Give every multi-page reference a single page in the link, with the pages named beside it. Cite 476 NAC 3-002.02 through the pinned chapter PDF and the 2025 poverty guideline notice directly. Move the earned income sources into a list parameter, inline the YAML anchors in the integration test, note that later years carry the FY2026 amounts forward, and place Nebraska alphabetically in the registry. Co-Authored-By: Claude Fable 5.1 --- .../ne/dhhs/liheap/earned_income_sources.yaml | 19 +++++++++ .../states/ne/dhhs/liheap/fpg_year_lag.yaml | 4 +- .../states/ne/dhhs/liheap/income_limit.yaml | 2 +- policyengine_us/programs.yaml | 16 ++++---- .../states/ne/dhhs/liheap/integration.yaml | 40 ++++++++----------- .../gov/states/ne/dhhs/liheap/ne_liheap.yaml | 4 +- .../ne/dhhs/liheap/ne_liheap_eligible.yaml | 4 +- .../states/ne/dhhs/liheap/ne_liheap_fpg.yaml | 4 +- .../liheap/ne_liheap_income_eligible.yaml | 4 +- .../gov/states/ne/dhhs/liheap/ne_liheap.py | 3 +- .../ne/dhhs/liheap/ne_liheap_earned_income.py | 13 +++--- .../ne/dhhs/liheap/ne_liheap_eligible.py | 6 ++- .../ne/dhhs/liheap/ne_liheap_gross_income.py | 1 + .../dhhs/liheap/ne_liheap_income_eligible.py | 3 +- 14 files changed, 69 insertions(+), 54 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_sources.yaml diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_sources.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_sources.yaml new file mode 100644 index 00000000000..9c6c0ae3fb2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/earned_income_sources.yaml @@ -0,0 +1,19 @@ +description: Nebraska counts these earned income sources under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: + - employment_income + # 475 NAC 3-002.04(B)(i), in the text in effect for FY2026, counts each + # source of self-employment. The existing net business and farm inputs are + # read without another business expense deduction. + - self_employment_income + - sstb_self_employment_income + - farm_operations_income +metadata: + unit: list + period: year + label: Nebraska LIHEAP earned income sources + reference: + - title: 475 NAC 3-002.04(B)(i), text in effect for FY2026, page 44 (each source of self-employment) + href: https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=44 + - title: Nebraska FY2026 state plan, Section 1.9, page 7 + href: https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml index 8831ad37143..6427304d368 100644 --- a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/fpg_year_lag.yaml @@ -8,5 +8,5 @@ metadata: reference: - title: Nebraska LIHEAP Guidance Document effective October 1, 2025 (the one-person limit of $23,475 is 150% of the 2025 guideline) href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 - - title: HHS poverty guidelines, 2025 (Federal Register references) - href: https://aspe.hhs.gov/topics/poverty-economic-mobility/poverty-guidelines/prior-hhs-poverty-guidelines-federal-register-references + - title: Annual Update of the HHS Poverty Guidelines, Federal Register, January 17, 2025, page 1 ($15,650 for one person, $5,500 for each additional person) + href: https://www.govinfo.gov/content/pkg/FR-2025-01-17/pdf/2025-01377.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml index 14b2cc2defa..eeba15cffa5 100644 --- a/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml +++ b/policyengine_us/parameters/gov/states/ne/dhhs/liheap/income_limit.yaml @@ -7,6 +7,6 @@ metadata: label: Nebraska LIHEAP income limit reference: - title: Nebraska LIHEAP Guidance Document effective October 1, 2025, pages 1-2 (income limits; "at or below 150% of the federal poverty level") - href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 + href: https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 - title: 476 NAC 2-002.01 Income Guidelines (total annual income "may not exceed 150% of the federal poverty level") href: https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%202%20(06-26-2022).pdf/1747#page=1 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 9a6e3927dc7..ae15f9203a6 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -802,7 +802,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: OR, DC, Riverside County, MA, IL, TX, NE + coverage: OR, DC, Riverside County, MA, IL, NE, TX state_implementations: - state: OR status: in_progress @@ -823,13 +823,6 @@ programs: name: Illinois LIHEAP full_name: Illinois Low Income Home Energy Assistance Program variable: il_liheap - - state: TX - status: partial - name: Texas CEAP - full_name: Texas Comprehensive Energy Assistance Program - variable: tx_ceap - parameter_prefix: gov.states.tx.tdhca.ceap - notes: Models the FPG income limit, the FY2024-only SMI limit, benefit amounts, and categorical eligibility through TANF enrollment, SNAP eligibility, and SSI receipt. Not modeled - net rather than gross gambling winnings, the Medicare premium deduction from counted Social Security, and the exclusion of means-tested veterans' pensions from counted income (10 TAC 6.4(c)) - state: NE status: partial name: Nebraska LIHEAP @@ -838,6 +831,13 @@ programs: parameter_prefix: gov.states.ne.dhhs.liheap verified_years: "2026" notes: FY2026 regular heating only, with the single-family and multifamily schedules and the earned-income disregard. Crisis, cooling and weatherization assistance are out of scope. + - state: TX + status: partial + name: Texas CEAP + full_name: Texas Comprehensive Energy Assistance Program + variable: tx_ceap + parameter_prefix: gov.states.tx.tdhca.ceap + notes: Models the FPG income limit, the FY2024-only SMI limit, benefit amounts, and categorical eligibility through TANF enrollment, SNAP eligibility, and SSI receipt. Not modeled - net rather than gross gambling winnings, the Medicare premium deduction from counted Social Security, and the exclusion of means-tested veterans' pensions from counted income (10 TAC 6.4(c)) # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml index 1b532dd8c5f..747e23eff7e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/integration.yaml @@ -1,5 +1,5 @@ -# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. -# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table (pages 1-2). +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 - name: Case 1, wages receive the earned disregard only after gross eligibility. period: 2026 @@ -13,14 +13,13 @@ employment_income: 18_000 spm_units: spm_unit: - members: &id001 - - person1 + members: [person1] heating_type: NATURAL_GAS gas_expense: 1_200 tanf: 0 households: household: - members: *id001 + members: [person1] state_code: NE output: ne_liheap_household_size: 1 @@ -42,14 +41,13 @@ social_security_retirement: 18_000 spm_units: spm_unit: - members: &id002 - - person1 + members: [person1] heating_type: NATURAL_GAS gas_expense: 1_200 tanf: 0 households: household: - members: *id002 + members: [person1] state_code: NE output: ne_liheap_earned_income: 0 @@ -69,14 +67,13 @@ self_employment_income: -5_000 spm_units: spm_unit: - members: &id003 - - person1 + members: [person1] heating_type: NATURAL_GAS gas_expense: 1_200 tanf: 0 households: household: - members: *id003 + members: [person1] state_code: NE output: ne_liheap_earned_income: 10_000 @@ -94,14 +91,13 @@ self_employment_income: 18_000 spm_units: spm_unit: - members: &id004 - - person1 + members: [person1] heating_type: NATURAL_GAS gas_expense: 1_200 tanf: 0 households: household: - members: *id004 + members: [person1] state_code: NE output: ne_liheap_earned_income: 18_000 @@ -127,15 +123,13 @@ employment_income: 10_000 spm_units: spm_unit: - members: &id005 - - person1 - - person2 + members: [person1, person2] heating_type: NATURAL_GAS gas_expense: 1_200 tanf: 0 households: household: - members: *id005 + members: [person1, person2] state_code: NE output: ne_liheap_household_size: 2 @@ -163,15 +157,13 @@ interest_income: 1_000 spm_units: spm_unit: - members: &id006 - - person1 - - person2 + members: [person1, person2] heating_type: NATURAL_GAS gas_expense: 1_200 tanf: 0 households: household: - members: *id006 + members: [person1, person2] state_code: NE output: ne_liheap_household_size: 1 @@ -334,8 +326,8 @@ # market-rate heat-in-rent renters as responsible. 476 NAC 3-002.02 lets # the Department pay such a household directly, and plan sections 1.1 # (page 5) and 9.1 (page 25) list them among households paid directly. - # https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=5,9,25 - # https://www.law.cornell.edu/regulations/nebraska/476-Neb-Admin-Code-ch-3-SS-002 + # https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=9 + # https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%203%20(12-26-2020).pdf/1748#page=1 period: 2026 input: people: diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml index 19d49d91113..b24fc258de6 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap.yaml @@ -1,5 +1,5 @@ -# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. -# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table (pages 1-2). +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 - name: Case 1, fuel oil single-family schedule at 0 FPG. period: 2026 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml index d6697bc82fa..e7aae52ed96 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_eligible.yaml @@ -65,8 +65,8 @@ # documented modeling assumption; 476 NAC 3-002.02 lets the Department pay a # household directly if utilities are included in rent, and plan sections 1.1 # (page 5) and 9.1 (page 25) list such households among those paid directly. -# https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=5,9,25 -# https://www.law.cornell.edu/regulations/nebraska/476-Neb-Admin-Code-ch-3-SS-002 +# https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=9 +# https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%203%20(12-26-2020).pdf/1748#page=1 - name: Case 6, housing-assisted renter with heat in rent and no heating bill is ineligible. period: 2026 input: diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml index 3a5a4e910ca..bcb0e4cdb69 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_fpg.yaml @@ -1,5 +1,5 @@ -# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. -# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table (pages 1-2). +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 - name: Case 1, FY2026 guideline for 1 member uses 2025 federal amounts. period: 2026 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.yaml index 2f37c77c3c1..71063f42881 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.yaml @@ -1,5 +1,5 @@ -# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table. -# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2 +# Source: Nebraska FY2026 LIHEAP Guidance, income guidelines and heating payment table (pages 1-2). +# https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1 - name: Case 1, gross income exactly at the FY2026 one-person limit. period: 2026 diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py index 750d5932f22..347b097900a 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap.py @@ -10,7 +10,8 @@ class ne_liheap(Variable): label = "Nebraska LIHEAP regular heating assistance" documentation = ( "Verified for FY2026. Earlier years use model parameter backfilling " - "and are unverified historical estimates." + "and are unverified historical estimates. Later years carry the " + "FY2026 amounts forward until a new schedule is added." ) defined_for = "ne_liheap_eligible" reference = "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=2" diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py index a30839fdf4c..8cdf5cf319b 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_earned_income.py @@ -10,7 +10,8 @@ class ne_liheap_earned_income(Variable): defined_for = StateCode.NE reference = ( "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7", - "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=44,47", + # 475 NAC 3-002.04(B)(i) (page 44) and 3-002.06 (pages 47-48). + "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=44", ) def formula(spm_unit, period, parameters): @@ -31,10 +32,8 @@ def formula(spm_unit, period, parameters): # income, which existing inputs cannot establish. That offset, Nebraska's # tax-return/49%-ledger distinction, and capital gains from business # assets are not modeled here. - earned = ( - max_(person("employment_income", period), 0) - + max_(person("self_employment_income", period), 0) - + max_(person("sstb_self_employment_income", period), 0) - + max_(person("farm_operations_income", period), 0) - ) + p = parameters(period).gov.states.ne.dhhs.liheap + earned = 0 + for source in p.earned_income_sources: + earned = earned + max_(person(source, period), 0) return spm_unit.sum(earned * countable * share) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py index 2dabd59c129..47c4f2d8336 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py @@ -10,8 +10,10 @@ class ne_liheap_eligible(Variable): reference = ( "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%201%20(12-26-2020).pdf/1746#page=1", "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%202%20(06-26-2022).pdf/1747#page=1", - "https://www.law.cornell.edu/regulations/nebraska/476-Neb-Admin-Code-ch-3-SS-002", - "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=5,9,25", + # 476 NAC 3-002.02. + "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%203%20(12-26-2020).pdf/1748#page=1", + # Sections 1.1 (page 5), 2.3 (page 9) and 9.1 (page 25). + "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=9", ) def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py index 2224f9f84d0..0bdfb007f69 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_gross_income.py @@ -10,6 +10,7 @@ class ne_liheap_gross_income(Variable): defined_for = StateCode.NE reference = ( "https://liheapch.acf.gov/docs/2026/state-plans/NE_Plan_2026.pdf#page=7", + # 475 NAC 3-002.06 (pages 47-48). "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/historical-chapter-pdfs/475%20NAC%203%20(09-17-2024)-202607280000.pdf#page=47", ) diff --git a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py index bb420fe4dad..cccfba53120 100644 --- a/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py +++ b/policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_income_eligible.py @@ -8,7 +8,8 @@ class ne_liheap_income_eligible(Variable): label = "Nebraska LIHEAP income eligibility" defined_for = StateCode.NE reference = ( - "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1,2", + # Pages 1-2: income limits and the heating payment table. + "https://dhhs.ne.gov/Documents/Low%20Income%20Home%20Energy%20Assistance%20Program%20%28LIHEAP%29%20Guidance%20Document%202026.pdf#page=1", "https://rules.nebraska.gov/api/fileStorage/GetAsByteArray/chapter-pdfs/476%20NAC%202%20(06-26-2022).pdf/1747#page=1", )