From 1b5ec6a9955d203b594a2dba96acc0b0ac3072ef Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 6 Oct 2026 15:46:02 -0400 Subject: [PATCH 1/8] Add Wyoming LIEAP qualified-member household size --- changelog.d/wy-liheap-wave2b.added.md | 1 + .../wy/dfs/lieap/wy_lieap_household_size.yaml | 60 +++++++++++++++++++ .../wy/dfs/lieap/wy_lieap_household_size.py | 19 ++++++ 3 files changed, 80 insertions(+) create mode 100644 changelog.d/wy-liheap-wave2b.added.md create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_household_size.yaml create mode 100644 policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_household_size.py diff --git a/changelog.d/wy-liheap-wave2b.added.md b/changelog.d/wy-liheap-wave2b.added.md new file mode 100644 index 00000000000..4445cd37b6c --- /dev/null +++ b/changelog.d/wy-liheap-wave2b.added.md @@ -0,0 +1 @@ +Add a Wyoming LIEAP household-size component counting citizens and qualified noncitizens under a documented modeling assumption. diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_household_size.yaml new file mode 100644 index 00000000000..076a3adcbcd --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_household_size.yaml @@ -0,0 +1,60 @@ +# Approved modeling convention: count citizens and qualified noncitizens within +# each SPM unit. Wyoming's FY2026 plan, section 17.3, establishes status +# verification but does not specify mixed-status household-size calculations. +# https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=38 + +- name: Case 1, a citizen child counts and an undocumented parent does not. + period: 2026 + input: + people: + person1: + age: 35 + immigration_status: UNDOCUMENTED + person2: + age: 8 + immigration_status: CITIZEN + spm_units: + spm_unit1: + members: [person1, person2] + households: + household1: + members: [person1, person2] + state_code: WY + output: + wy_lieap_household_size: 1 + +- name: Case 2, separate SPM units sharing a home retain their own qualifying-member counts. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: REFUGEE + person2: + age: 38 + immigration_status: ASYLEE + person3: + age: 30 + immigration_status: DACA + person4: + age: 28 + immigration_status: TPS + spm_units: + spm_unit1: + members: [person1, person2] + spm_unit2: + members: [person3, person4] + households: + household1: + members: [person1, person2, person3, person4] + state_code: WY + output: + wy_lieap_household_size: [2, 0] + +- name: Case 3, a qualifying member outside Wyoming has no Wyoming program household size. + period: 2026 + input: + immigration_status: LEGAL_PERMANENT_RESIDENT + state_code: CO + output: + wy_lieap_household_size: 0 diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_household_size.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_household_size.py new file mode 100644 index 00000000000..55b414c2b19 --- /dev/null +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_household_size.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class wy_lieap_household_size(Variable): + value_type = int + entity = SPMUnit + definition_period = YEAR + label = "Wyoming LIEAP household size" + documentation = ( + "Number of U.S. citizens and qualified noncitizens in the SPM unit. " + "Excluding other members from household size is an approved modeling " + "assumption: Wyoming's FY2026 plan requires immigration-status " + "verification but does not specify mixed-status household calculations. " + "The SPM unit approximates the group sharing home heating." + ) + # FY2026 state plan, section 17.3; the size convention is an assumption. + reference = "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=38" + defined_for = StateCode.WY + adds = ["is_citizen_or_legal_immigrant"] From d463804726280694b68d048a6d31bbe36fa88c00 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 6 Oct 2026 16:06:10 -0400 Subject: [PATCH 2/8] Implement Wyoming regular LIEAP heating assistance --- changelog.d/wy-liheap-wave2b.added.md | 2 +- .../lieap/income/earned_income_min_age.yaml | 15 + .../wy/dfs/lieap/income/earned_sources.yaml | 20 + .../wy/dfs/lieap/income/fpg_year_lag.yaml | 15 + .../lieap/income/gift_monthly_threshold.yaml | 11 + .../income/interest_monthly_threshold.yaml | 11 + .../wy/dfs/lieap/income/unearned_sources.yaml | 38 + .../dfs/lieap/income/veterans_fpg_rate.yaml | 15 + .../lieap/payment/entitlement_fraction.yaml | 81 + .../wy/dfs/lieap/payment/fuel_cost.yaml | 36 + .../wy/dfs/lieap/payment/holdback_rate.yaml | 11 + .../wy/dfs/lieap/payment/minimum_payment.yaml | 12 + .../gov/states/wy/dfs/lieap/smi_rate.yaml | 15 + policyengine_us/programs.yaml | 11 +- .../gov/states/wy/dfs/lieap/wy_lieap.yaml | 2086 +++++++++++++++++ .../dfs/lieap/wy_lieap_countable_income.yaml | 262 +++ .../wy/dfs/lieap/wy_lieap_eligible.yaml | 49 + .../wy/dfs/lieap/wy_lieap_income_limit.yaml | 111 + .../gov/states/wy/dfs/lieap/wy_lieap.py | 40 + .../wy/dfs/lieap/wy_lieap_countable_income.py | 69 + .../states/wy/dfs/lieap/wy_lieap_eligible.py | 28 + .../wy/dfs/lieap/wy_lieap_income_limit.py | 25 + 22 files changed, 2961 insertions(+), 2 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_income_min_age.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/income/gift_monthly_threshold.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/income/interest_monthly_threshold.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/income/veterans_fpg_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/fuel_cost.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/holdback_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/minimum_payment.yaml create mode 100644 policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_income_limit.yaml create mode 100644 policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py create mode 100644 policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py create mode 100644 policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py create mode 100644 policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py diff --git a/changelog.d/wy-liheap-wave2b.added.md b/changelog.d/wy-liheap-wave2b.added.md index 4445cd37b6c..cfb630d3b0d 100644 --- a/changelog.d/wy-liheap-wave2b.added.md +++ b/changelog.d/wy-liheap-wave2b.added.md @@ -1 +1 @@ -Add a Wyoming LIEAP household-size component counting citizens and qualified noncitizens under a documented modeling assumption. +Add Wyoming regular LIEAP heating benefits with income and household eligibility, published fuel standards, expense caps, and documented modeling assumptions for income bands, mixed-status households, income exclusions, and veterans benefits. diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_income_min_age.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_income_min_age.yaml new file mode 100644 index 00000000000..0e0fd67ef7b --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_income_min_age.yaml @@ -0,0 +1,15 @@ +description: Wyoming counts earnings from people at or above this age under the Low Income Energy Assistance Program. +# Approved convention follows the plan's unchecked under-18 earnings category. +# The adopted rule excludes only under-14 earnings or under-18 student earnings. +values: + 2025-10-01: 18 + +metadata: + unit: year + period: year + label: Wyoming LIEAP minimum age for countable earnings + reference: + - title: "FY2026 State Plan, section 1.9" + href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=6 + - title: "LIEAP Rules, Chapter 1, section 8(a)(ii)(A)" + href: https://rules.wyo.gov/Search.aspx?mode=7 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml new file mode 100644 index 00000000000..856ba7233b3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml @@ -0,0 +1,20 @@ +description: Wyoming counts these nonnegative earnings sources for adults under the Low Income Energy Assistance Program. +values: + 2025-10-01: + - employment_income + - self_employment_income + - sstb_self_employment_income + - farm_operations_income + - partnership_s_corp_income + +# Existing net business inputs approximate the allowed business-expense rules. +# No additional expense deduction is applied to amounts already reported net. +metadata: + unit: list + period: year + label: Wyoming LIEAP earned income sources + reference: + - title: FY2026 State Plan, section 1.9 + href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=6 + - title: LIEAP Rules, Chapter 1, sections 3(w) and 8(a) + href: https://rules.wyo.gov/Search.aspx?mode=7 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml new file mode 100644 index 00000000000..b55cd39f8c3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml @@ -0,0 +1,15 @@ +description: Wyoming uses the federal poverty guideline from this many years before the modeled fiscal year for the veterans exclusion under the Low Income Energy Assistance Program. +# Annual FY2026 represents the season starting in October 2025; use the +# guideline at season start. Earlier and later policy remains unverified. +values: + 2025-10-01: 1 + +metadata: + unit: year + period: year + label: Wyoming LIEAP poverty guideline year lag + reference: + - title: "LIEAP Rules, Chapter 1, section 8(a)(ii)(S)" + href: https://rules.wyo.gov/Search.aspx?mode=7 + - title: "FY2026 State Plan, fiscal-year dates" + href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/gift_monthly_threshold.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/gift_monthly_threshold.yaml new file mode 100644 index 00000000000..b366d4448fb --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/gift_monthly_threshold.yaml @@ -0,0 +1,11 @@ +description: Wyoming excludes gifts at or below this monthly amount under the Low Income Energy Assistance Program. +values: + 2025-10-01: 30 + +metadata: + unit: currency-USD + period: month + label: Wyoming LIEAP monthly gift threshold + reference: + - title: "LIEAP Rules, Chapter 1, section 8(a)(ii)(D)" + href: https://rules.wyo.gov/Search.aspx?mode=7 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/interest_monthly_threshold.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/interest_monthly_threshold.yaml new file mode 100644 index 00000000000..28a3d724fc6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/interest_monthly_threshold.yaml @@ -0,0 +1,11 @@ +description: Wyoming counts the full monthly interest income above this amount under the Low Income Energy Assistance Program. +values: + 2025-10-01: 30 + +metadata: + unit: currency-USD + period: month + label: Wyoming LIEAP monthly interest threshold + reference: + - title: "LIEAP Rules, Chapter 1, section 8(a)(i)(A)" + href: https://rules.wyo.gov/Search.aspx?mode=7 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml new file mode 100644 index 00000000000..01ff59d0755 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml @@ -0,0 +1,38 @@ +description: Wyoming counts these nonnegative unearned income sources before separate interest, gifts and veterans adjustments under the Low Income Energy Assistance Program. +values: + 2025-10-01: + - social_security + - ssi + - pension_income + - retirement_distributions + - railroad_benefits + - survivor_benefits + - unemployment_compensation + - workers_compensation + - disability_benefits + - general_assistance + - alimony_income + - rental_income + - farm_rent_income + - estate_income + - ordinary_dividend_income + +# TANF and child support received are excluded under the FY2026 plan. +# Adopted section 8(a)(ii)(L) excludes lump sums despite the plan's checked +# lump-sum box. Refunds, tax credits, balances and settlements are not added. +# Generic annual sources (including retirement and Social Security) cannot +# identify embedded lump sums or exempt reimbursements. Supply adjusted +# countable income directly for those cases. No new subtype input is added. +# Regular disability/worker/survivor income approximates nonexempt receipts; +# pension_income already includes annuities. No duplicate pension components. +# Medicare deducted from SSA remains unmodeled under the agreed scope. +# Contract payments and royalties lack dedicated inputs and are not imputed. +metadata: + unit: list + period: year + label: Wyoming LIEAP unearned income sources + reference: + - title: FY2026 State Plan, section 1.9 + href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=6 + - title: LIEAP Rules, Chapter 1, section 8(a) + href: https://rules.wyo.gov/Search.aspx?mode=7 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/veterans_fpg_rate.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/veterans_fpg_rate.yaml new file mode 100644 index 00000000000..f95fa7ed797 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/veterans_fpg_rate.yaml @@ -0,0 +1,15 @@ +description: Wyoming excludes veterans disability benefits up to this share of the federal poverty guideline under the Low Income Energy Assistance Program. +# Approved assumptions: one household-size exclusion per SPM unit and +# total veterans_benefits as the proxy for service-connected disability income. +# The rule does not settle multiple recipients, and the proxy can exclude +# other VA benefits that the service-connected rule does not cover. +values: + 2025-10-01: 1 + +metadata: + unit: /1 + period: year + label: Wyoming LIEAP veterans income exclusion rate + reference: + - title: "LIEAP Rules, Chapter 1, section 8(a)(ii)(S)" + href: https://rules.wyo.gov/Search.aspx?mode=7 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml new file mode 100644 index 00000000000..5b436fe0805 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml @@ -0,0 +1,81 @@ +description: Wyoming applies these modeled entitlement fractions by household income relative to the income limit under the Low Income Energy Assistance Program. +# Approved convention: compare the unrounded ratio with inclusive upper +# bounds .21, .26, .31, ... .86, then 1.00, using calc(..., right=True). +# These assumptions bridge gaps in the printed matrix; they are not recovered +# agency rounding instructions. The positive band at exactly 1.00 is the +# stated extension of the user's pattern and differs from the printed zero. +brackets: + - threshold: + 2025-10-01: -.inf + amount: + 2025-10-01: 0.8 + - threshold: + 2025-10-01: 0.21 + amount: + 2025-10-01: 0.75 + - threshold: + 2025-10-01: 0.26 + amount: + 2025-10-01: 0.7 + - threshold: + 2025-10-01: 0.31 + amount: + 2025-10-01: 0.65 + - threshold: + 2025-10-01: 0.36 + amount: + 2025-10-01: 0.6 + - threshold: + 2025-10-01: 0.41 + amount: + 2025-10-01: 0.55 + - threshold: + 2025-10-01: 0.46 + amount: + 2025-10-01: 0.5 + - threshold: + 2025-10-01: 0.51 + amount: + 2025-10-01: 0.45 + - threshold: + 2025-10-01: 0.56 + amount: + 2025-10-01: 0.4 + - threshold: + 2025-10-01: 0.61 + amount: + 2025-10-01: 0.35 + - threshold: + 2025-10-01: 0.66 + amount: + 2025-10-01: 0.3 + - threshold: + 2025-10-01: 0.71 + amount: + 2025-10-01: 0.25 + - threshold: + 2025-10-01: 0.76 + amount: + 2025-10-01: 0.2 + - threshold: + 2025-10-01: 0.81 + amount: + 2025-10-01: 0.15 + - threshold: + 2025-10-01: 0.86 + amount: + 2025-10-01: 0.1 + - threshold: + 2025-10-01: 1 + amount: + 2025-10-01: 0 + +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: /1 + period: year + label: Wyoming LIEAP entitlement fraction + reference: + - title: FY2026 Benefit Matrix, visible Table 1 on all fuel worksheets + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/fuel_cost.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/fuel_cost.yaml new file mode 100644 index 00000000000..a1b47c58279 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/fuel_cost.yaml @@ -0,0 +1,36 @@ +description: Wyoming uses these seasonal primary fuel cost standards under the Low Income Energy Assistance Program. +# Exact source cells retain electricity and natural-gas decimals. +# Zero entries mean no verified mapping to the six published fuel standards; +# they do not establish legal ineligibility. Kerosene is not silently mapped. +UNSPECIFIED: + 2025-10-01: 0 +ELECTRICITY: + 2025-10-01: 1_712.997 +NATURAL_GAS: + 2025-10-01: 1_550.85 +FUEL_OIL: + 2025-10-01: 2_640 +KEROSENE: + 2025-10-01: 0 +PROPANE: + 2025-10-01: 1_300 +WOOD: + 2025-10-01: 1_225 +COAL: + 2025-10-01: 525 +SOLAR: + 2025-10-01: 0 +OTHER: + 2025-10-01: 0 +NONE: + 2025-10-01: 0 + +metadata: + unit: currency-USD + period: year + label: Wyoming LIEAP seasonal fuel cost standard + breakdown: + - heating_type + reference: + - title: FY2026 Benefit Matrix, Coal H10, Heating Oil H10, Electric H10, Natural Gas H10, Propane F9, Wood H9 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/holdback_rate.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/holdback_rate.yaml new file mode 100644 index 00000000000..cefe5e6a935 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/holdback_rate.yaml @@ -0,0 +1,11 @@ +description: Wyoming withholds this share of the scheduled benefit under the Low Income Energy Assistance Program. +values: + 2025-10-01: 0.1 + +metadata: + unit: /1 + period: year + label: Wyoming LIEAP benefit holdback rate + reference: + - title: "FY2026 Benefit Matrix, visible Table 1 on all six fuel worksheets" + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/minimum_payment.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/minimum_payment.yaml new file mode 100644 index 00000000000..e80cc2f1296 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/minimum_payment.yaml @@ -0,0 +1,12 @@ +description: Wyoming does not authorize payments below this amount under the Low Income Energy Assistance Program. +# This is a payment cutoff, not an amount to raise a smaller award to. +values: + 2025-10-01: 10 + +metadata: + unit: currency-USD + period: year + label: Wyoming LIEAP minimum authorized payment + reference: + - title: "LIEAP Rules, Chapter 1, section 10(d)" + href: https://rules.wyo.gov/Search.aspx?mode=7 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml new file mode 100644 index 00000000000..9882d94d6f2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml @@ -0,0 +1,15 @@ +description: Wyoming limits household income to this share of state median income under the Low Income Energy Assistance Program. +# The current administrative standard is 60% SMI. The older 215% FPG +# statutory alternative is not applied, consistent with DFS's explanation. +values: + 2025-10-01: 0.6 + +metadata: + unit: /1 + period: year + label: Wyoming LIEAP state median income rate + reference: + - title: "FY2026 State Plan, section 2.1" + href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8 + - title: "DFS statutory cleanup recommendations, LIEAP #page 8,9" + href: https://wyoleg.gov/InterimCommittee/2016/10-0825AppendixC.pdf#page=8 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 756dc2c4988..0e220ba8518 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, KS, MS, TX + coverage: OR, DC, Riverside County, MA, IL, KS, MS, TX, WY state_implementations: - state: OR status: in_progress @@ -847,6 +847,15 @@ programs: 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: WY + status: partial + name: Wyoming LIEAP + full_name: Wyoming Low Income Energy Assistance Program + variable: wy_lieap + parameter_prefix: gov.states.wy.dfs.lieap + verified_years: "2026" + notes: FY2026 regular heating only. Approved assumptions use inclusive income-band upper bounds, qualified-member household size with all otherwise countable income and no extra proration, and one poverty-guideline exclusion per SPM unit using total veterans benefits as a disability-income proxy. Under-18 earnings, TANF, child support received and identifiable lump sums are excluded, with plan-rule conflicts documented. Annual inputs cannot identify embedded exempt lump sums or all special receipts; Medicare and sponsor-income adjustments, work registration, tribal routing and administrative eligibility details remain unmodeled. Unsupported fuels or missing eligible heating costs return zero. Other years are unverified estimates; crisis, cooling, weatherization and equipment assistance are out of scope. + # --- SSA programs --- - id: ssi name: SSI diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml new file mode 100644 index 00000000000..a1f6943a5cc --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml @@ -0,0 +1,2086 @@ +# All 96 FY2026 visible workbook values independently reconciled in source research. +# Ratios are inside the approved bands. The zero row uses 1.01 because the +# approved convention pays the last positive fraction at exactly 1.00. +# https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx + +- name: Case 1, coal published share 0.8 at ratio 0. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B21:F21 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: COAL + output: + wy_lieap: 378.0 + +- name: Case 2, coal published share 0.75 at ratio 0.25. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B22:F22 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 25000 + heating_type: COAL + output: + wy_lieap: 354.75 + +- name: Case 3, coal published share 0.7 at ratio 0.3. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B23:F23 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 30000 + heating_type: COAL + output: + wy_lieap: 330.5 + +- name: Case 4, coal published share 0.65 at ratio 0.35. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B24:F24 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 35000 + heating_type: COAL + output: + wy_lieap: 307.25 + +- name: Case 5, coal published share 0.6 at ratio 0.4. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B25:F25 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 40000 + heating_type: COAL + output: + wy_lieap: 283.0 + +- name: Case 6, coal published share 0.55 at ratio 0.45. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B26:F26 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 45000 + heating_type: COAL + output: + wy_lieap: 259.75 + +- name: Case 7, coal published share 0.5 at ratio 0.5. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B27:F27 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 50000 + heating_type: COAL + output: + wy_lieap: 236.5 + +- name: Case 8, coal published share 0.45 at ratio 0.55. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B28:F28 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 55000 + heating_type: COAL + output: + wy_lieap: 212.25 + +- name: Case 9, coal published share 0.4 at ratio 0.6. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B29:F29 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 60000 + heating_type: COAL + output: + wy_lieap: 189.0 + +- name: Case 10, coal published share 0.35 at ratio 0.65. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B30:F30 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 65000 + heating_type: COAL + output: + wy_lieap: 165.75 + +- name: Case 11, coal published share 0.3 at ratio 0.7. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B31:F31 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 70000 + heating_type: COAL + output: + wy_lieap: 141.5 + +- name: Case 12, coal published share 0.25 at ratio 0.75. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B32:F32 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 75000 + heating_type: COAL + output: + wy_lieap: 118.25 + +- name: Case 13, coal published share 0.2 at ratio 0.8. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B33:F33 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 80000 + heating_type: COAL + output: + wy_lieap: 94.0 + +- name: Case 14, coal published share 0.15 at ratio 0.85. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B34:F34 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 85000 + heating_type: COAL + output: + wy_lieap: 70.75 + +- name: Case 15, coal published share 0.1 at ratio 0.95. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B35:F35 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 95000 + heating_type: COAL + output: + wy_lieap: 47.5 + +- name: Case 16, coal published share 0.0 at ratio 1.01. + period: 2026 + absolute_error_margin: 0.001 + # Coal 25-26 cells B36:F36 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 101000 + heating_type: COAL + output: + wy_lieap: 0.0 + +- name: Case 17, fuel_oil published share 0.8 at ratio 0. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B22:F22 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: FUEL_OIL + output: + wy_lieap: 1901.0 + +- name: Case 18, fuel_oil published share 0.75 at ratio 0.25. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B23:F23 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 25000 + heating_type: FUEL_OIL + output: + wy_lieap: 1782.00 + +- name: Case 19, fuel_oil published share 0.7 at ratio 0.3. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B24:F24 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 30000 + heating_type: FUEL_OIL + output: + wy_lieap: 1663.0 + +- name: Case 20, fuel_oil published share 0.65 at ratio 0.35. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B25:F25 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 35000 + heating_type: FUEL_OIL + output: + wy_lieap: 1544.00 + +- name: Case 21, fuel_oil published share 0.6 at ratio 0.4. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B26:F26 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 40000 + heating_type: FUEL_OIL + output: + wy_lieap: 1426.0 + +- name: Case 22, fuel_oil published share 0.55 at ratio 0.45. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B27:F27 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 45000 + heating_type: FUEL_OIL + output: + wy_lieap: 1307.00 + +- name: Case 23, fuel_oil published share 0.5 at ratio 0.5. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B28:F28 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 50000 + heating_type: FUEL_OIL + output: + wy_lieap: 1188.0 + +- name: Case 24, fuel_oil published share 0.45 at ratio 0.55. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B29:F29 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 55000 + heating_type: FUEL_OIL + output: + wy_lieap: 1069.00 + +- name: Case 25, fuel_oil published share 0.4 at ratio 0.6. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B30:F30 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 60000 + heating_type: FUEL_OIL + output: + wy_lieap: 950.0 + +- name: Case 26, fuel_oil published share 0.35 at ratio 0.65. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B31:F31 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 65000 + heating_type: FUEL_OIL + output: + wy_lieap: 832.00 + +- name: Case 27, fuel_oil published share 0.3 at ratio 0.7. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B32:F32 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 70000 + heating_type: FUEL_OIL + output: + wy_lieap: 713.0 + +- name: Case 28, fuel_oil published share 0.25 at ratio 0.75. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B33:F33 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 75000 + heating_type: FUEL_OIL + output: + wy_lieap: 594.00 + +- name: Case 29, fuel_oil published share 0.2 at ratio 0.8. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B34:F34 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 80000 + heating_type: FUEL_OIL + output: + wy_lieap: 475.0 + +- name: Case 30, fuel_oil published share 0.15 at ratio 0.85. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B35:F35 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 85000 + heating_type: FUEL_OIL + output: + wy_lieap: 356.00 + +- name: Case 31, fuel_oil published share 0.1 at ratio 0.95. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B36:F36 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 95000 + heating_type: FUEL_OIL + output: + wy_lieap: 238.0 + +- name: Case 32, fuel_oil published share 0.0 at ratio 1.01. + period: 2026 + absolute_error_margin: 0.001 + # Heating Oil 25-26 cells B37:F37 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 101000 + heating_type: FUEL_OIL + output: + wy_lieap: 0.0 + +- name: Case 33, electricity published share 0.8 at ratio 0. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B21:F21 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: ELECTRICITY + output: + wy_lieap: 1233.3976 + +- name: Case 34, electricity published share 0.75 at ratio 0.25. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B22:F22 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 25000 + heating_type: ELECTRICITY + output: + wy_lieap: 1156.74775 + +- name: Case 35, electricity published share 0.7 at ratio 0.3. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B23:F23 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 30000 + heating_type: ELECTRICITY + output: + wy_lieap: 1079.0979 + +- name: Case 36, electricity published share 0.65 at ratio 0.35. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B24:F24 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 35000 + heating_type: ELECTRICITY + output: + wy_lieap: 1002.44805 + +- name: Case 37, electricity published share 0.6 at ratio 0.4. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B25:F25 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 40000 + heating_type: ELECTRICITY + output: + wy_lieap: 924.7982 + +- name: Case 38, electricity published share 0.55 at ratio 0.45. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B26:F26 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 45000 + heating_type: ELECTRICITY + output: + wy_lieap: 848.14835 + +- name: Case 39, electricity published share 0.5 at ratio 0.5. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B27:F27 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 50000 + heating_type: ELECTRICITY + output: + wy_lieap: 770.4985 + +- name: Case 40, electricity published share 0.45 at ratio 0.55. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B28:F28 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 55000 + heating_type: ELECTRICITY + output: + wy_lieap: 693.84865 + +- name: Case 41, electricity published share 0.4 at ratio 0.6. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B29:F29 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 60000 + heating_type: ELECTRICITY + output: + wy_lieap: 616.1988 + +- name: Case 42, electricity published share 0.35 at ratio 0.65. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B30:F30 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 65000 + heating_type: ELECTRICITY + output: + wy_lieap: 539.54895 + +- name: Case 43, electricity published share 0.3 at ratio 0.7. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B31:F31 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 70000 + heating_type: ELECTRICITY + output: + wy_lieap: 462.8991 + +- name: Case 44, electricity published share 0.25 at ratio 0.75. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B32:F32 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 75000 + heating_type: ELECTRICITY + output: + wy_lieap: 385.24925 + +- name: Case 45, electricity published share 0.2 at ratio 0.8. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B33:F33 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 80000 + heating_type: ELECTRICITY + output: + wy_lieap: 308.5994 + +- name: Case 46, electricity published share 0.15 at ratio 0.85. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B34:F34 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 85000 + heating_type: ELECTRICITY + output: + wy_lieap: 230.94955 + +- name: Case 47, electricity published share 0.1 at ratio 0.95. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B35:F35 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 95000 + heating_type: ELECTRICITY + output: + wy_lieap: 154.2997 + +- name: Case 48, electricity published share 0.0 at ratio 1.01. + period: 2026 + absolute_error_margin: 0.001 + # Electric 25-26 cells B36:F36 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 101000 + heating_type: ELECTRICITY + output: + wy_lieap: 0.0000 + +- name: Case 49, natural_gas published share 0.8 at ratio 0. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B21:F21 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: NATURAL_GAS + output: + wy_lieap: 1116.680 + +- name: Case 50, natural_gas published share 0.75 at ratio 0.25. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B22:F22 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 25000 + heating_type: NATURAL_GAS + output: + wy_lieap: 1047.1375 + +- name: Case 51, natural_gas published share 0.7 at ratio 0.3. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B23:F23 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 30000 + heating_type: NATURAL_GAS + output: + wy_lieap: 976.595 + +- name: Case 52, natural_gas published share 0.65 at ratio 0.35. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B24:F24 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 35000 + heating_type: NATURAL_GAS + output: + wy_lieap: 907.0525 + +- name: Case 53, natural_gas published share 0.6 at ratio 0.4. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B25:F25 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 40000 + heating_type: NATURAL_GAS + output: + wy_lieap: 837.510 + +- name: Case 54, natural_gas published share 0.55 at ratio 0.45. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B26:F26 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 45000 + heating_type: NATURAL_GAS + output: + wy_lieap: 767.9675 + +- name: Case 55, natural_gas published share 0.5 at ratio 0.5. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B27:F27 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 50000 + heating_type: NATURAL_GAS + output: + wy_lieap: 697.425 + +- name: Case 56, natural_gas published share 0.45 at ratio 0.55. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B28:F28 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 55000 + heating_type: NATURAL_GAS + output: + wy_lieap: 627.8825 + +- name: Case 57, natural_gas published share 0.4 at ratio 0.6. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B29:F29 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 60000 + heating_type: NATURAL_GAS + output: + wy_lieap: 558.340 + +- name: Case 58, natural_gas published share 0.35 at ratio 0.65. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B30:F30 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 65000 + heating_type: NATURAL_GAS + output: + wy_lieap: 488.7975 + +- name: Case 59, natural_gas published share 0.3 at ratio 0.7. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B31:F31 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 70000 + heating_type: NATURAL_GAS + output: + wy_lieap: 418.255 + +- name: Case 60, natural_gas published share 0.25 at ratio 0.75. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B32:F32 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 75000 + heating_type: NATURAL_GAS + output: + wy_lieap: 348.7125 + +- name: Case 61, natural_gas published share 0.2 at ratio 0.8. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B33:F33 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 80000 + heating_type: NATURAL_GAS + output: + wy_lieap: 279.170 + +- name: Case 62, natural_gas published share 0.15 at ratio 0.85. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B34:F34 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 85000 + heating_type: NATURAL_GAS + output: + wy_lieap: 209.6275 + +- name: Case 63, natural_gas published share 0.1 at ratio 0.95. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B35:F35 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 95000 + heating_type: NATURAL_GAS + output: + wy_lieap: 139.085 + +- name: Case 64, natural_gas published share 0.0 at ratio 1.01. + period: 2026 + absolute_error_margin: 0.001 + # Natural Gas 25-26 cells B36:F36 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 101000 + heating_type: NATURAL_GAS + output: + wy_lieap: 0.000 + +- name: Case 65, propane published share 0.8 at ratio 0. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B19:F19 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: PROPANE + output: + wy_lieap: 936.0 + +- name: Case 66, propane published share 0.75 at ratio 0.25. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B20:F20 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 25000 + heating_type: PROPANE + output: + wy_lieap: 877.00 + +- name: Case 67, propane published share 0.7 at ratio 0.3. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B21:F21 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 30000 + heating_type: PROPANE + output: + wy_lieap: 819.0 + +- name: Case 68, propane published share 0.65 at ratio 0.35. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B22:F22 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 35000 + heating_type: PROPANE + output: + wy_lieap: 760.00 + +- name: Case 69, propane published share 0.6 at ratio 0.4. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B23:F23 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 40000 + heating_type: PROPANE + output: + wy_lieap: 702.0 + +- name: Case 70, propane published share 0.55 at ratio 0.45. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B24:F24 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 45000 + heating_type: PROPANE + output: + wy_lieap: 643.00 + +- name: Case 71, propane published share 0.5 at ratio 0.5. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B25:F25 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 50000 + heating_type: PROPANE + output: + wy_lieap: 585.0 + +- name: Case 72, propane published share 0.45 at ratio 0.55. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B26:F26 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 55000 + heating_type: PROPANE + output: + wy_lieap: 526.00 + +- name: Case 73, propane published share 0.4 at ratio 0.6. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B27:F27 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 60000 + heating_type: PROPANE + output: + wy_lieap: 468.0 + +- name: Case 74, propane published share 0.35 at ratio 0.65. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B28:F28 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 65000 + heating_type: PROPANE + output: + wy_lieap: 409.00 + +- name: Case 75, propane published share 0.3 at ratio 0.7. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B29:F29 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 70000 + heating_type: PROPANE + output: + wy_lieap: 351.0 + +- name: Case 76, propane published share 0.25 at ratio 0.75. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B30:F30 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 75000 + heating_type: PROPANE + output: + wy_lieap: 292.00 + +- name: Case 77, propane published share 0.2 at ratio 0.8. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B31:F31 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 80000 + heating_type: PROPANE + output: + wy_lieap: 234.0 + +- name: Case 78, propane published share 0.15 at ratio 0.85. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B32:F32 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 85000 + heating_type: PROPANE + output: + wy_lieap: 175.00 + +- name: Case 79, propane published share 0.1 at ratio 0.95. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B33:F33 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 95000 + heating_type: PROPANE + output: + wy_lieap: 117.0 + +- name: Case 80, propane published share 0.0 at ratio 1.01. + period: 2026 + absolute_error_margin: 0.001 + # Propane 25-26 cells B34:F34 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 101000 + heating_type: PROPANE + output: + wy_lieap: 0.0 + +- name: Case 81, wood published share 0.8 at ratio 0. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B20:F20 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: WOOD + output: + wy_lieap: 882.0 + +- name: Case 82, wood published share 0.75 at ratio 0.25. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B21:F21 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 25000 + heating_type: WOOD + output: + wy_lieap: 826.75 + +- name: Case 83, wood published share 0.7 at ratio 0.3. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B22:F22 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 30000 + heating_type: WOOD + output: + wy_lieap: 771.5 + +- name: Case 84, wood published share 0.65 at ratio 0.35. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B23:F23 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 35000 + heating_type: WOOD + output: + wy_lieap: 716.25 + +- name: Case 85, wood published share 0.6 at ratio 0.4. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B24:F24 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 40000 + heating_type: WOOD + output: + wy_lieap: 661.0 + +- name: Case 86, wood published share 0.55 at ratio 0.45. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B25:F25 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 45000 + heating_type: WOOD + output: + wy_lieap: 606.75 + +- name: Case 87, wood published share 0.5 at ratio 0.5. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B26:F26 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 50000 + heating_type: WOOD + output: + wy_lieap: 551.5 + +- name: Case 88, wood published share 0.45 at ratio 0.55. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B27:F27 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 55000 + heating_type: WOOD + output: + wy_lieap: 496.25 + +- name: Case 89, wood published share 0.4 at ratio 0.6. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B28:F28 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 60000 + heating_type: WOOD + output: + wy_lieap: 441.0 + +- name: Case 90, wood published share 0.35 at ratio 0.65. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B29:F29 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 65000 + heating_type: WOOD + output: + wy_lieap: 385.75 + +- name: Case 91, wood published share 0.3 at ratio 0.7. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B30:F30 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 70000 + heating_type: WOOD + output: + wy_lieap: 330.5 + +- name: Case 92, wood published share 0.25 at ratio 0.75. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B31:F31 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 75000 + heating_type: WOOD + output: + wy_lieap: 275.25 + +- name: Case 93, wood published share 0.2 at ratio 0.8. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B32:F32 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 80000 + heating_type: WOOD + output: + wy_lieap: 220.0 + +- name: Case 94, wood published share 0.15 at ratio 0.85. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B33:F33 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 85000 + heating_type: WOOD + output: + wy_lieap: 165.75 + +- name: Case 95, wood published share 0.1 at ratio 0.95. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B34:F34 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 95000 + heating_type: WOOD + output: + wy_lieap: 110.5 + +- name: Case 96, wood published share 0.0 at ratio 1.01. + period: 2026 + absolute_error_margin: 0.001 + # Wood 25-26 cells B35:F35 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 101000 + heating_type: WOOD + output: + wy_lieap: 0.0 + +- name: Case 97, oil at inclusive ratio boundary .21. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 21000 + heating_type: FUEL_OIL + output: + wy_lieap: 1901.00 + +- name: Case 98, oil just above inclusive ratio boundary .21. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 21001 + heating_type: FUEL_OIL + output: + wy_lieap: 1782.00 + +- name: Case 99, oil at inclusive ratio boundary .26. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 26000 + heating_type: FUEL_OIL + output: + wy_lieap: 1782.00 + +- name: Case 100, oil just above inclusive ratio boundary .26. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 26001 + heating_type: FUEL_OIL + output: + wy_lieap: 1663.00 + +- name: Case 101, oil at inclusive ratio boundary .31. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 31000 + heating_type: FUEL_OIL + output: + wy_lieap: 1663.00 + +- name: Case 102, oil just above inclusive ratio boundary .31. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 31001 + heating_type: FUEL_OIL + output: + wy_lieap: 1544.00 + +- name: Case 103, oil at inclusive ratio boundary .36. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 36000 + heating_type: FUEL_OIL + output: + wy_lieap: 1544.00 + +- name: Case 104, oil just above inclusive ratio boundary .36. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 36001 + heating_type: FUEL_OIL + output: + wy_lieap: 1426.00 + +- name: Case 105, oil at inclusive ratio boundary .41. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 41000 + heating_type: FUEL_OIL + output: + wy_lieap: 1426.00 + +- name: Case 106, oil just above inclusive ratio boundary .41. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 41001 + heating_type: FUEL_OIL + output: + wy_lieap: 1307.00 + +- name: Case 107, oil at inclusive ratio boundary .46. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 46000 + heating_type: FUEL_OIL + output: + wy_lieap: 1307.00 + +- name: Case 108, oil just above inclusive ratio boundary .46. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 46001 + heating_type: FUEL_OIL + output: + wy_lieap: 1188.00 + +- name: Case 109, oil at inclusive ratio boundary .51. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 51000 + heating_type: FUEL_OIL + output: + wy_lieap: 1188.00 + +- name: Case 110, oil just above inclusive ratio boundary .51. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 51001 + heating_type: FUEL_OIL + output: + wy_lieap: 1069.00 + +- name: Case 111, oil at inclusive ratio boundary .56. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 56000 + heating_type: FUEL_OIL + output: + wy_lieap: 1069.00 + +- name: Case 112, oil just above inclusive ratio boundary .56. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 56001 + heating_type: FUEL_OIL + output: + wy_lieap: 950.00 + +- name: Case 113, oil at inclusive ratio boundary .61. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 61000 + heating_type: FUEL_OIL + output: + wy_lieap: 950.00 + +- name: Case 114, oil just above inclusive ratio boundary .61. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 61001 + heating_type: FUEL_OIL + output: + wy_lieap: 832.00 + +- name: Case 115, oil at inclusive ratio boundary .66. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 66000 + heating_type: FUEL_OIL + output: + wy_lieap: 832.00 + +- name: Case 116, oil just above inclusive ratio boundary .66. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 66001 + heating_type: FUEL_OIL + output: + wy_lieap: 713.00 + +- name: Case 117, oil at inclusive ratio boundary .71. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 71000 + heating_type: FUEL_OIL + output: + wy_lieap: 713.00 + +- name: Case 118, oil just above inclusive ratio boundary .71. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 71001 + heating_type: FUEL_OIL + output: + wy_lieap: 594.00 + +- name: Case 119, oil at inclusive ratio boundary .76. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 76000 + heating_type: FUEL_OIL + output: + wy_lieap: 594.00 + +- name: Case 120, oil just above inclusive ratio boundary .76. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 76001 + heating_type: FUEL_OIL + output: + wy_lieap: 475.00 + +- name: Case 121, oil at inclusive ratio boundary .81. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 81000 + heating_type: FUEL_OIL + output: + wy_lieap: 475.00 + +- name: Case 122, oil just above inclusive ratio boundary .81. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 81001 + heating_type: FUEL_OIL + output: + wy_lieap: 356.00 + +- name: Case 123, oil at inclusive ratio boundary .86. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 86000 + heating_type: FUEL_OIL + output: + wy_lieap: 356.00 + +- name: Case 124, oil just above inclusive ratio boundary .86. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 86001 + heating_type: FUEL_OIL + output: + wy_lieap: 238.00 + +- name: Case 125, oil at inclusive ratio boundary 1.00. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 100000 + heating_type: FUEL_OIL + output: + wy_lieap: 238.00 + +- name: Case 126, oil just above inclusive ratio boundary 1.00. + period: 2026 + absolute_error_margin: 0.001 + # Approved convention; no ratio rounding. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 100001 + heating_type: FUEL_OIL + output: + wy_lieap: 0 + +- name: Case 127, actual expense 0 with zero income. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 0 + wy_lieap_countable_income: 0 + heating_type: FUEL_OIL + output: + wy_lieap: 0 + +- name: Case 128, actual expense -100 with zero income. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: -100 + wy_lieap_countable_income: 0 + heating_type: FUEL_OIL + output: + wy_lieap: 0 + +- name: Case 129, actual expense 9 with zero income. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 9 + wy_lieap_countable_income: 0 + heating_type: FUEL_OIL + output: + wy_lieap: 0 + +- name: Case 130, actual expense 9.99 with zero income. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 9.99 + wy_lieap_countable_income: 0 + heating_type: FUEL_OIL + output: + wy_lieap: 0 + +- name: Case 131, actual expense 10 with zero income. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 10 + wy_lieap_countable_income: 0 + heating_type: FUEL_OIL + output: + wy_lieap: 10 + +- name: Case 132, actual expense 500 with zero income. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 500 + wy_lieap_countable_income: 0 + heating_type: FUEL_OIL + output: + wy_lieap: 500 + +- name: Case 133, unspecified has no supported FY2026 fuel standard. + period: 2026 + absolute_error_margin: 0.001 + # Zero for unsupported fuel does not establish legal ineligibility. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: UNSPECIFIED + output: + wy_lieap: 0 + +- name: Case 134, none has no supported FY2026 fuel standard. + period: 2026 + absolute_error_margin: 0.001 + # Zero for unsupported fuel does not establish legal ineligibility. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: NONE + output: + wy_lieap: 0 + +- name: Case 135, kerosene has no supported FY2026 fuel standard. + period: 2026 + absolute_error_margin: 0.001 + # Zero for unsupported fuel does not establish legal ineligibility. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: KEROSENE + output: + wy_lieap: 0 + +- name: Case 136, solar has no supported FY2026 fuel standard. + period: 2026 + absolute_error_margin: 0.001 + # Zero for unsupported fuel does not establish legal ineligibility. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: SOLAR + output: + wy_lieap: 0 + +- name: Case 137, other has no supported FY2026 fuel standard. + period: 2026 + absolute_error_margin: 0.001 + # Zero for unsupported fuel does not establish legal ineligibility. + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: OTHER + output: + wy_lieap: 0 + +- name: Case 138, negative countable income does not inflate the maximum. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: -10000 + heating_type: FUEL_OIL + output: + wy_lieap: 1901 + +- name: Case 139, unsubsidized heat in rent uses its documented heating share. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 500 + wy_lieap_countable_income: 0 + heating_type: NATURAL_GAS + heat_expense_included_in_rent: true + output: + wy_lieap: 500 + +- name: Case 140, subsidized rent with a direct heating bill is not automatically excluded. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 500 + wy_lieap_countable_income: 0 + heating_type: NATURAL_GAS + receives_housing_assistance: true + output: + wy_lieap: 500 + +- name: Case 141, zero qualifying members receive no award. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: WY + wy_lieap_household_size: 0 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: FUEL_OIL + output: + wy_lieap: 0 + +- name: Case 142, another state receives no Wyoming award. + period: 2026 + absolute_error_margin: 0.001 + input: + state_code: CO + wy_lieap_household_size: 1 + wy_lieap_income_limit: 100000 + heating_expense: 5000 + wy_lieap_countable_income: 0 + heating_type: FUEL_OIL + output: + wy_lieap: 0 + +- name: Case 143, adult earnings and support paid determine oil benefit while minor earnings and TANF are excluded. + period: 2026 + input: + people: + person1: {age: 40, employment_income: 12_000, child_support_expense: 2_400, child_support_received: 3_000, ssi: 0} + person2: {age: 17, employment_income: 6_000, is_full_time_student: false, ssi: 0} + spm_units: + spm_unit1: + members: [person1, person2] + wy_power: 6_000 + heating_type: FUEL_OIL + fuel_oil_expense: 3_000 + households: + household1: {members: [person1, person2], state_code: WY} + output: + wy_lieap_household_size: 2 + wy_lieap_countable_income: 9_600 + wy_lieap_income_limit: 46_853 + wy_lieap_eligible: true + heating_expense: 3_000 + # 9,600 / 46,853 < .21; 2,640 * .8 - ROUND(211.2) = 1,901. + wy_lieap: 1_901 + +- name: Case 144, two veterans share one poverty exclusion before calculating gas assistance. + period: 2026 + absolute_error_margin: 0.001 + input: + people: + person1: {age: 50, veterans_benefits: 30_000, ssi: 0} + person2: {age: 52, veterans_benefits: 30_000, ssi: 0} + spm_units: + spm_unit1: {members: [person1, person2], heating_type: NATURAL_GAS, gas_expense: 1_000} + households: + household1: {members: [person1, person2], state_code: WY} + output: + wy_lieap_household_size: 2 + wy_lieap_countable_income: 38_850 + wy_lieap_income_limit: 46_853 + heating_expense: 1_000 + # Ratio .829... selects .15; 1,550.85 * .15 - 23 = 209.6275. + wy_lieap: 209.6275 + +- name: Case 145, mixed-status family retains the parents income without a second award proration. + period: 2026 + input: + people: + person1: {age: 35, immigration_status: UNDOCUMENTED, employment_income: 20_000, ssi: 0} + person2: {age: 8, immigration_status: CITIZEN, ssi: 0} + spm_units: + spm_unit1: {members: [person1, person2], heating_type: COAL, coal_expense: 1_000} + households: + household1: {members: [person1, person2], state_code: WY} + output: + wy_lieap_household_size: 1 + wy_lieap_countable_income: 20_000 + wy_lieap_income_limit: 35_829 + wy_lieap_eligible: true + # Ratio .558... selects .45; 525 * .45 - 24 = 212.25. + wy_lieap: 212.25 + +- name: Case 146, electricity assistance uses the primary bill and annual investment thresholds. + period: 2026 + input: + age: 40 + state_code: WY + ssi: 0 + interest_income: 372 + ordinary_dividend_income: 200 + financial_assistance: 360 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_000 + gas_expense: 5_000 + output: + wy_lieap_countable_income: 572 + wy_lieap_income_limit: 35_829 + heating_expense: 1_000 + # Scheduled electric benefit 1,233.3976 is capped at the primary bill. + wy_lieap: 1_000 + +- name: Case 147, vectorized awards keep distinct SPM units and state eligibility separate. + period: 2026 + absolute_error_margin: 0.001 + input: + people: + person1: {age: 50, veterans_benefits: 30_000, ssi: 0} + person2: {age: 52, veterans_benefits: 30_000, ssi: 0} + person3: {age: 40, immigration_status: UNDOCUMENTED, ssi: 0} + person4: {age: 40, ssi: 0} + person5: {age: 40, ssi: 0} + spm_units: + spm_unit1: {members: [person1, person2], heating_type: NATURAL_GAS, gas_expense: 1_000} + spm_unit2: {members: [person3], heating_type: FUEL_OIL, fuel_oil_expense: 2_000} + spm_unit3: {members: [person4], heating_type: PROPANE, bottled_gas_expense: 9} + spm_unit4: {members: [person5], heating_type: WOOD, wood_expense: 2_000} + households: + household1: {members: [person1, person2, person3, person4], state_code: WY} + household2: {members: [person5], state_code: CO} + output: + wy_lieap_household_size: [2, 0, 1, 0] + wy_lieap_countable_income: [38_850, 0, 0, 0] + wy_lieap_income_limit: [46_853, 0, 35_829, 0] + wy_lieap: [209.6275, 0, 0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_countable_income.yaml new file mode 100644 index 00000000000..c571d2208f7 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_countable_income.yaml @@ -0,0 +1,262 @@ +# Income conventions approved October 6, 2026. Annual inputs approximate monthly income. +# FY2026 plan section 1.9 and adopted rule section 8: the plan excludes minors, +# TANF and child support; the rule excludes lump sums. Conflicts remain documented. + +- name: Case 1, adult earnings less paid child support. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + employment_income: 24000 + child_support_expense: 2400 + output: + wy_lieap_countable_income: 21600 + +- name: Case 2, all earnings of a seventeen-year-old nonstudent are excluded. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 17 + is_full_time_student: false + employment_income: 6000 + self_employment_income: 1200 + output: + wy_lieap_countable_income: 0 + +- name: Case 3, earnings start counting at eighteen. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 18 + employment_income: 6000 + output: + wy_lieap_countable_income: 6000 + +- name: Case 4, business and rental losses do not offset wages. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + employment_income: 10000 + self_employment_income: -5000 + rental_income: -2000 + farm_rent_income: -500 + output: + wy_lieap_countable_income: 10000 + +- name: Case 5, paid support cannot reduce unearned income. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + employment_income: 1000 + child_support_expense: 3000 + pension_income: 5000 + output: + wy_lieap_countable_income: 5000 + +- name: Case 6, interest at thirty dollars per month is excluded. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + interest_income: 360 + output: + wy_lieap_countable_income: 0 + +- name: Case 7, interest above thirty dollars per month counts in full. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + interest_income: 372 + output: + wy_lieap_countable_income: 372 + +- name: Case 8, dividends do not receive the interest threshold. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + ordinary_dividend_income: 360 + output: + wy_lieap_countable_income: 360 + +- name: Case 9, small monthly gifts are excluded. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + financial_assistance: 360 + output: + wy_lieap_countable_income: 0 + +- name: Case 10, gifts above the monthly threshold count in full. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + financial_assistance: 372 + output: + wy_lieap_countable_income: 372 + +- name: Case 11, total veterans benefits below one-person poverty guideline are excluded. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 50 + veterans_benefits: 15000 + output: + wy_lieap_countable_income: 0 + +- name: Case 12, veterans benefits exactly at one-person poverty guideline are excluded. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 50 + veterans_benefits: 15650 + output: + wy_lieap_countable_income: 0 + +- name: Case 13, only veterans benefits above the guideline count. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 50 + veterans_benefits: 30000 + output: + wy_lieap_countable_income: 14350 + +- name: Case 14, unused veterans exclusion cannot offset other income. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 50 + veterans_benefits: 10000 + pension_income: 5000 + output: + wy_lieap_countable_income: 5000 + +- name: Case 15, tanf and child support received are excluded. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + wy_power: 6000 + tanf: 6000 + child_support_received: 3000 + output: + wy_lieap_countable_income: 0 + +- name: Case 16, tax credits and asset balances are not countable receipts. + period: 2026 + input: + state_code: WY + ssi: 0 + age: 40 + eitc: 2000 + income_tax_refundable_credits: 3000 + bank_account_assets: 100000 + output: + wy_lieap_countable_income: 0 + +- name: Case 17, regular nonexcluded unearned sources count once. + period: 2026 + input: + state_code: WY + age: 40 + social_security: 1000 + ssi: 500 + pension_income: 2000 + retirement_distributions: 3000 + railroad_benefits: 400 + survivor_benefits: 300 + unemployment_compensation: 2000 + general_assistance: 100 + alimony_income: 800 + rental_income: 900 + farm_rent_income: 700 + ordinary_dividend_income: 200 + output: + wy_lieap_countable_income: 11900 + +- name: Case 18, two veterans share one two-person poverty exclusion. + period: 2026 + input: + people: + person1: {age: 50, veterans_benefits: 30_000, ssi: 0} + person2: {age: 52, veterans_benefits: 30_000, ssi: 0} + spm_units: + spm_unit1: {members: [person1, person2]} + households: + household1: {members: [person1, person2], state_code: WY} + output: + wy_lieap_household_size: 2 + # 60,000 - 2025 two-person FPG 21,150 = 38,850. + wy_lieap_countable_income: 38_850 + +- name: Case 19, support paid by one member cannot offset another members wages. + period: 2026 + input: + people: + person1: {age: 40, child_support_expense: 3_000, ssi: 0} + person2: {age: 38, employment_income: 12_000, ssi: 0} + spm_units: + spm_unit1: {members: [person1, person2]} + households: + household1: {members: [person1, person2], state_code: WY} + output: + wy_lieap_countable_income: 12_000 + +- name: Case 20, excluded immigration status does not exclude otherwise countable income. + period: 2026 + input: + people: + person1: {age: 35, immigration_status: UNDOCUMENTED, employment_income: 20_000, ssi: 0} + person2: {age: 8, immigration_status: CITIZEN, employment_income: 2_000, ssi: 0} + spm_units: + spm_unit1: {members: [person1, person2]} + households: + household1: {members: [person1, person2], state_code: WY} + output: + wy_lieap_household_size: 1 + wy_lieap_countable_income: 20_000 + +- name: Case 21, separate SPM units each receive one veterans exclusion. + period: 2026 + input: + people: + person1: {age: 50, veterans_benefits: 30_000, ssi: 0} + person2: {age: 52, veterans_benefits: 30_000, ssi: 0} + person3: {age: 40, veterans_benefits: 10_000, ssi: 0} + spm_units: + spm_unit1: {members: [person1, person2]} + spm_unit2: {members: [person3]} + households: + household1: {members: [person1, person2, person3], state_code: WY} + output: + wy_lieap_countable_income: [38_850, 0] + +- name: Case 22, Wyoming income calculation is zero in another state. + period: 2026 + input: + state_code: CO + age: 40 + employment_income: 20_000 + output: + wy_lieap_countable_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_eligible.yaml new file mode 100644 index 00000000000..17d177424a2 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_eligible.yaml @@ -0,0 +1,49 @@ +- name: Case 1, income exactly at the ceiling qualifies. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_countable_income: 35829 + heating_expense: 100 + output: + wy_lieap_eligible: true + +- name: Case 2, income above the ceiling is ineligible. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_countable_income: 35830 + heating_expense: 100 + output: + wy_lieap_eligible: false + +- name: Case 3, zero qualifying members is ineligible. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 0 + wy_lieap_countable_income: 0 + heating_expense: 100 + output: + wy_lieap_eligible: false + +- name: Case 4, no heating responsibility is ineligible. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_countable_income: 0 + heating_expense: 0 + output: + wy_lieap_eligible: false + +- name: Case 5, negative reported expense is ineligible. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 1 + wy_lieap_countable_income: 0 + heating_expense: -100 + output: + wy_lieap_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_income_limit.yaml new file mode 100644 index 00000000000..4ab9a7328bb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_income_limit.yaml @@ -0,0 +1,111 @@ +- name: Case 1, FY2026 income limit for 0 qualifying members. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 0 + output: + wy_lieap_income_limit: 0 + +- name: Case 2, FY2026 income limit for 1 qualifying members. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 1 + output: + wy_lieap_income_limit: 35829 + +- name: Case 3, FY2026 income limit for 2 qualifying members. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 2 + output: + wy_lieap_income_limit: 46853 + +- name: Case 4, FY2026 income limit for 3 qualifying members. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 3 + output: + wy_lieap_income_limit: 57877 + +- name: Case 5, FY2026 income limit for 4 qualifying members. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 4 + output: + wy_lieap_income_limit: 68902 + +- name: Case 6, FY2026 income limit for 5 qualifying members. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 5 + output: + wy_lieap_income_limit: 79926 + +- name: Case 7, FY2026 income limit for 6 qualifying members. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 6 + output: + wy_lieap_income_limit: 90950 + +- name: Case 8, FY2026 income limit for 7 qualifying members. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 7 + output: + wy_lieap_income_limit: 93017 + +- name: Case 9, FY2026 income limit for 8 qualifying members. + period: 2026 + input: + state_code: WY + wy_lieap_household_size: 8 + output: + wy_lieap_income_limit: 95085 + +- name: Case 10, FY2027 income limit for 1 qualifying members only. + period: 2027 + input: + state_code: WY + wy_lieap_household_size: 1 + output: + wy_lieap_income_limit: 35858 + +- name: Case 11, FY2027 income limit for 2 qualifying members only. + period: 2027 + input: + state_code: WY + wy_lieap_household_size: 2 + output: + wy_lieap_income_limit: 46892 + +- name: Case 12, FY2027 income limit for 3 qualifying members only. + period: 2027 + input: + state_code: WY + wy_lieap_household_size: 3 + output: + wy_lieap_income_limit: 57925 + +- name: Case 13, FY2027 income limit for 4 qualifying members only. + period: 2027 + input: + state_code: WY + wy_lieap_household_size: 4 + output: + wy_lieap_income_limit: 68959 + +- name: Case 14, FY2027 income limit for 5 qualifying members only. + period: 2027 + input: + state_code: WY + wy_lieap_household_size: 5 + output: + wy_lieap_income_limit: 79992 diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py new file mode 100644 index 00000000000..4e02bc15f38 --- /dev/null +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py @@ -0,0 +1,40 @@ +from policyengine_us.model_api import * + + +class wy_lieap(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Wyoming Low Income Energy Assistance Program benefit" + documentation = ( + "Regular FY2026 heating assistance. SPM units approximate shared-heat " + "households and report their own eligible seasonal primary heating cost. " + "Approved income bands use inclusive upper bounds without ratio rounding; " + "mixed-status households use qualified-member size, all otherwise countable " + "income and no additional proration. Renters use the same schedule. " + "Zero may indicate an unsupported fuel or missing eligible heating cost. " + "Years outside FY2026 are unverified estimates, including backfilled years." + ) + reference = ( + "https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx", + # Chapter 1, sections 10(d)-(e) and 13(b)(i), physical page 16. + "https://rules.wyo.gov/Search.aspx?mode=7", + ) + defined_for = "wy_lieap_eligible" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.wy.dfs.lieap.payment + income = max_(spm_unit("wy_lieap_countable_income", period), 0) + limit = spm_unit("wy_lieap_income_limit", period) + # Promote before division so float32 representations of exact decimal + # boundaries do not push a household into the next band. + ratio = income.astype(np.float64) / max_(limit, 1) + fraction = p.entitlement_fraction.calc(ratio, right=True) + heating_type = spm_unit("heating_type", period) + base = p.fuel_cost[heating_type] * fraction + # The workbook rounds only the withheld amount, half-up to dollars. + withheld = np.floor(base * p.holdback_rate + 0.5) + expense = max_(spm_unit("heating_expense", period), 0) + award = min_(base - withheld, expense) + return where(award >= p.minimum_payment, award, 0) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py new file mode 100644 index 00000000000..6c3a6b23e1a --- /dev/null +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py @@ -0,0 +1,69 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class wy_lieap_countable_income(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Wyoming LIEAP countable income" + documentation = ( + "Annual income approximates current monthly income. All members' otherwise " + "countable income is retained, including members excluded from household " + "size by immigration status. Under approved assumptions, all under-18 " + "earnings, TANF, child support received and identifiable lump sums are " + "excluded. Total veterans benefits proxy service-connected disability " + "payments and receive one household-size poverty exclusion per SPM unit. " + "This proxy can understate income from other kinds of VA benefits. " + "Annual source inputs cannot distinguish embedded lump sums, exempt " + "reimbursements or irregular receipts; supply countable income directly " + "when those adjustments are known. Medicare deductions remain unmodeled." + ) + reference = ( + # Section 1.9, physical page 6; minor-earnings/lump-sum conflicts documented. + "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=6", + # Current chapter 1, section 8(a), physical pages 11-13. + "https://rules.wyo.gov/Search.aspx?mode=7", + ) + defined_for = StateCode.WY + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.wy.dfs.lieap.income + person = spm_unit.members + # Supplied net business income approximates allowable expenses. + # Separate business and rental losses cannot offset positive sources. + earned = sum(max_(person(source, period), 0) for source in p.earned_sources) + support_paid = max_(person("child_support_expense", period), 0) + # The input does not identify court orders or monthly regularity. + # Deduct only from this payer's earnings, never another member's. + earned = where( + person("age", period) >= p.earned_income_min_age, + max_(earned - support_paid, 0), + 0, + ) + unearned = sum(max_(person(source, period), 0) for source in p.unearned_sources) + # These are thresholds, not deductions. Annualization assumes + # constant monthly receipts; interest and gifts are assessed separately. + interest = max_(person("interest_income", period), 0) + gifts = max_(person("financial_assistance", period), 0) + countable_interest = where( + interest > p.interest_monthly_threshold * MONTHS_IN_YEAR, interest, 0 + ) + countable_gifts = where( + gifts > p.gift_monthly_threshold * MONTHS_IN_YEAR, gifts, 0 + ) + size = spm_unit("wy_lieap_household_size", period) + state_group = spm_unit.household("state_group_str", period) + guideline = fpg( + max_(size, 1), state_group, period, parameters, year_lag=p.fpg_year_lag + ) + # Approved approximation: total VA income, one exclusion per SPM unit. + # Do not apply a separate allowance to each veteran, spouse or dependent. + veterans = spm_unit.sum(max_(person("veterans_benefits", period), 0)) + veterans_exclusion = where(size > 0, guideline * p.veterans_fpg_rate, 0) + countable_veterans = max_(veterans - veterans_exclusion, 0) + return ( + spm_unit.sum(earned + unearned + countable_interest + countable_gifts) + + countable_veterans + ) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py new file mode 100644 index 00000000000..9a7087fc257 --- /dev/null +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class wy_lieap_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Eligible for modeled Wyoming LIEAP" + documentation = ( + "Models residence, qualifying-member count, income and primary heating " + "responsibility. Positive reported heating expense represents the unit's " + "eligible seasonal bill or documented heat-in-rent share. Winter presence, " + "work registration, tribal program routing, institutional exclusions and " + "application verification are not separately observed." + ) + reference = ( + "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8", + # Chapter 1, sections 7 and 8(b). + "https://rules.wyo.gov/Search.aspx?mode=7", + ) + defined_for = StateCode.WY + + def formula(spm_unit, period, parameters): + size = spm_unit("wy_lieap_household_size", period) + income = spm_unit("wy_lieap_countable_income", period) + limit = spm_unit("wy_lieap_income_limit", period) + expense = spm_unit("heating_expense", period) + return (size > 0) & (income <= limit) & (expense > 0) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py new file mode 100644 index 00000000000..4b499fd7ad2 --- /dev/null +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import smi + + +class wy_lieap_income_limit(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Wyoming LIEAP income limit" + reference = ( + "https://dfs.wyo.gov/wp-content/uploads/2025/08/2025-0729-LIEAP-About-handout.pdf#page=1", + "https://dfs.wyo.gov/wp-content/uploads/2026/09/2026-0924-LIEAP-About-handout.pdf#page=1", + ) + defined_for = StateCode.WY + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.wy.dfs.lieap + size = spm_unit("wy_lieap_household_size", period) + state = spm_unit.household("state_code_str", period) + # Flooring the existing federal SMI calculation reproduces the + # FY2026 and FY2027 published annual ceilings. The rounding method + # is a numerical inference, not an explicit state instruction. + limit = np.floor(smi(size, state, period, parameters) * p.smi_rate) + return where(size > 0, limit, 0) From adec175a532806d5af80901242085d228b70a45d Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 11 Oct 2026 23:52:39 -0400 Subject: [PATCH 3/8] Fix Wyoming LIEAP exact income boundaries and citations --- changelog.d/wy-liheap-review-fixes.fixed.md | 1 + .../lieap/payment/entitlement_fraction.yaml | 3 +- .../gov/states/wy/dfs/lieap/smi_rate.yaml | 2 +- .../gov/states/wy/dfs/lieap/wy_lieap.yaml | 219 ++++++++++++++++++ .../gov/states/wy/dfs/lieap/wy_lieap.py | 15 +- .../wy/dfs/lieap/wy_lieap_countable_income.py | 4 +- .../wy/dfs/lieap/wy_lieap_income_limit.py | 2 +- 7 files changed, 237 insertions(+), 9 deletions(-) create mode 100644 changelog.d/wy-liheap-review-fixes.fixed.md diff --git a/changelog.d/wy-liheap-review-fixes.fixed.md b/changelog.d/wy-liheap-review-fixes.fixed.md new file mode 100644 index 00000000000..feab3d6fe19 --- /dev/null +++ b/changelog.d/wy-liheap-review-fixes.fixed.md @@ -0,0 +1 @@ +Preserve Wyoming LIEAP inclusive income-band ceilings at actual dollar boundaries and update source citations. diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml index 5b436fe0805..024f4642db4 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml @@ -1,6 +1,7 @@ description: Wyoming applies these modeled entitlement fractions by household income relative to the income limit under the Low Income Energy Assistance Program. # Approved convention: compare the unrounded ratio with inclusive upper -# bounds .21, .26, .31, ... .86, then 1.00, using calc(..., right=True). +# bounds .21, .26, .31, ... .86, then 1.00. The formula compares equivalent +# income ceilings at the precision of stored monetary inputs. # These assumptions bridge gaps in the printed matrix; they are not recovered # agency rounding instructions. The positive band at exactly 1.00 is the # stated extension of the user's pattern and differs from the printed zero. diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml index 9882d94d6f2..74fea232154 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml @@ -11,5 +11,5 @@ metadata: reference: - title: "FY2026 State Plan, section 2.1" href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8 - - title: "DFS statutory cleanup recommendations, LIEAP #page 8,9" + - title: "DFS statutory cleanup recommendations, LIEAP #page 8-9" href: https://wyoleg.gov/InterimCommittee/2016/10-0825AppendixC.pdf#page=8 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml index a1f6943a5cc..c215c6bb9c4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml @@ -2084,3 +2084,222 @@ wy_lieap_countable_income: [38_850, 0, 0, 0] wy_lieap_income_limit: [46_853, 0, 35_829, 0] wy_lieap: [209.6275, 0, 0, 0] + +- name: Case 148, real FY2026 incomes a cent below every band ceiling preserve inclusive selection. + period: 2026 + input: + people: + person1: {age: 40, immigration_status: CITIZEN, employment_income: 7524.08} + person2: {age: 40, immigration_status: CITIZEN, employment_income: 9315.53} + person3: {age: 40, immigration_status: CITIZEN, employment_income: 11106.98} + person4: {age: 40, immigration_status: CITIZEN, employment_income: 12898.43} + person5: {age: 40, immigration_status: CITIZEN, employment_income: 14689.88} + person6: {age: 40, immigration_status: CITIZEN, employment_income: 16481.33} + person7: {age: 40, immigration_status: CITIZEN, employment_income: 18272.78} + person8: {age: 40, immigration_status: CITIZEN, employment_income: 20064.23} + person9: {age: 40, immigration_status: CITIZEN, employment_income: 21855.68} + person10: {age: 40, immigration_status: CITIZEN, employment_income: 23647.13} + person11: {age: 40, immigration_status: CITIZEN, employment_income: 25438.58} + person12: {age: 40, immigration_status: CITIZEN, employment_income: 27230.03} + person13: {age: 40, immigration_status: CITIZEN, employment_income: 29021.48} + person14: {age: 40, immigration_status: CITIZEN, employment_income: 30812.93} + person15: {age: 40, immigration_status: CITIZEN, employment_income: 35828.99} + spm_units: + spm_unit1: {members: [person1], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit2: {members: [person2], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit3: {members: [person3], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit4: {members: [person4], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit5: {members: [person5], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit6: {members: [person6], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit7: {members: [person7], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit8: {members: [person8], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit9: {members: [person9], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit10: {members: [person10], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit11: {members: [person11], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit12: {members: [person12], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit13: {members: [person13], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit14: {members: [person14], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit15: {members: [person15], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + tax_units: + tax_unit1: {members: [person1]} + tax_unit2: {members: [person2]} + tax_unit3: {members: [person3]} + tax_unit4: {members: [person4]} + tax_unit5: {members: [person5]} + tax_unit6: {members: [person6]} + tax_unit7: {members: [person7]} + tax_unit8: {members: [person8]} + tax_unit9: {members: [person9]} + tax_unit10: {members: [person10]} + tax_unit11: {members: [person11]} + tax_unit12: {members: [person12]} + tax_unit13: {members: [person13]} + tax_unit14: {members: [person14]} + tax_unit15: {members: [person15]} + households: + household1: {members: [person1], state_code: WY} + household2: {members: [person2], state_code: WY} + household3: {members: [person3], state_code: WY} + household4: {members: [person4], state_code: WY} + household5: {members: [person5], state_code: WY} + household6: {members: [person6], state_code: WY} + household7: {members: [person7], state_code: WY} + household8: {members: [person8], state_code: WY} + household9: {members: [person9], state_code: WY} + household10: {members: [person10], state_code: WY} + household11: {members: [person11], state_code: WY} + household12: {members: [person12], state_code: WY} + household13: {members: [person13], state_code: WY} + household14: {members: [person14], state_code: WY} + household15: {members: [person15], state_code: WY} + output: + # Each one-person limit is $35,829. Apply the approved .21, .26, ..., + # .86, 1.00 ceilings to actual wages, then the $2,640 oil standard + # and the workbook's rounded 10 percent holdback. + wy_lieap: [1901, 1782, 1663, 1544, 1426, 1307, 1188, 1069, 950, 832, 713, 594, 475, 356, 238] + +- name: Case 149, real FY2026 incomes exactly at every band ceiling preserve inclusive selection. + period: 2026 + input: + people: + person1: {age: 40, immigration_status: CITIZEN, employment_income: 7524.09} + person2: {age: 40, immigration_status: CITIZEN, employment_income: 9315.54} + person3: {age: 40, immigration_status: CITIZEN, employment_income: 11106.99} + person4: {age: 40, immigration_status: CITIZEN, employment_income: 12898.44} + person5: {age: 40, immigration_status: CITIZEN, employment_income: 14689.89} + person6: {age: 40, immigration_status: CITIZEN, employment_income: 16481.34} + person7: {age: 40, immigration_status: CITIZEN, employment_income: 18272.79} + person8: {age: 40, immigration_status: CITIZEN, employment_income: 20064.24} + person9: {age: 40, immigration_status: CITIZEN, employment_income: 21855.69} + person10: {age: 40, immigration_status: CITIZEN, employment_income: 23647.14} + person11: {age: 40, immigration_status: CITIZEN, employment_income: 25438.59} + person12: {age: 40, immigration_status: CITIZEN, employment_income: 27230.04} + person13: {age: 40, immigration_status: CITIZEN, employment_income: 29021.49} + person14: {age: 40, immigration_status: CITIZEN, employment_income: 30812.94} + person15: {age: 40, immigration_status: CITIZEN, employment_income: 35829.00} + spm_units: + spm_unit1: {members: [person1], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit2: {members: [person2], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit3: {members: [person3], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit4: {members: [person4], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit5: {members: [person5], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit6: {members: [person6], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit7: {members: [person7], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit8: {members: [person8], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit9: {members: [person9], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit10: {members: [person10], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit11: {members: [person11], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit12: {members: [person12], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit13: {members: [person13], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit14: {members: [person14], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit15: {members: [person15], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + tax_units: + tax_unit1: {members: [person1]} + tax_unit2: {members: [person2]} + tax_unit3: {members: [person3]} + tax_unit4: {members: [person4]} + tax_unit5: {members: [person5]} + tax_unit6: {members: [person6]} + tax_unit7: {members: [person7]} + tax_unit8: {members: [person8]} + tax_unit9: {members: [person9]} + tax_unit10: {members: [person10]} + tax_unit11: {members: [person11]} + tax_unit12: {members: [person12]} + tax_unit13: {members: [person13]} + tax_unit14: {members: [person14]} + tax_unit15: {members: [person15]} + households: + household1: {members: [person1], state_code: WY} + household2: {members: [person2], state_code: WY} + household3: {members: [person3], state_code: WY} + household4: {members: [person4], state_code: WY} + household5: {members: [person5], state_code: WY} + household6: {members: [person6], state_code: WY} + household7: {members: [person7], state_code: WY} + household8: {members: [person8], state_code: WY} + household9: {members: [person9], state_code: WY} + household10: {members: [person10], state_code: WY} + household11: {members: [person11], state_code: WY} + household12: {members: [person12], state_code: WY} + household13: {members: [person13], state_code: WY} + household14: {members: [person14], state_code: WY} + household15: {members: [person15], state_code: WY} + output: + # Each one-person limit is $35,829. Apply the approved .21, .26, ..., + # .86, 1.00 ceilings to actual wages, then the $2,640 oil standard + # and the workbook's rounded 10 percent holdback. + wy_lieap: [1901, 1782, 1663, 1544, 1426, 1307, 1188, 1069, 950, 832, 713, 594, 475, 356, 238] + +- name: Case 150, real FY2026 incomes a cent above every band ceiling preserve inclusive selection. + period: 2026 + input: + people: + person1: {age: 40, immigration_status: CITIZEN, employment_income: 7524.10} + person2: {age: 40, immigration_status: CITIZEN, employment_income: 9315.55} + person3: {age: 40, immigration_status: CITIZEN, employment_income: 11107.00} + person4: {age: 40, immigration_status: CITIZEN, employment_income: 12898.45} + person5: {age: 40, immigration_status: CITIZEN, employment_income: 14689.90} + person6: {age: 40, immigration_status: CITIZEN, employment_income: 16481.35} + person7: {age: 40, immigration_status: CITIZEN, employment_income: 18272.80} + person8: {age: 40, immigration_status: CITIZEN, employment_income: 20064.25} + person9: {age: 40, immigration_status: CITIZEN, employment_income: 21855.70} + person10: {age: 40, immigration_status: CITIZEN, employment_income: 23647.15} + person11: {age: 40, immigration_status: CITIZEN, employment_income: 25438.60} + person12: {age: 40, immigration_status: CITIZEN, employment_income: 27230.05} + person13: {age: 40, immigration_status: CITIZEN, employment_income: 29021.50} + person14: {age: 40, immigration_status: CITIZEN, employment_income: 30812.95} + person15: {age: 40, immigration_status: CITIZEN, employment_income: 35829.01} + spm_units: + spm_unit1: {members: [person1], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit2: {members: [person2], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit3: {members: [person3], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit4: {members: [person4], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit5: {members: [person5], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit6: {members: [person6], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit7: {members: [person7], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit8: {members: [person8], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit9: {members: [person9], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit10: {members: [person10], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit11: {members: [person11], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit12: {members: [person12], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit13: {members: [person13], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit14: {members: [person14], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + spm_unit15: {members: [person15], heating_type: FUEL_OIL, fuel_oil_expense: 3_000} + tax_units: + tax_unit1: {members: [person1]} + tax_unit2: {members: [person2]} + tax_unit3: {members: [person3]} + tax_unit4: {members: [person4]} + tax_unit5: {members: [person5]} + tax_unit6: {members: [person6]} + tax_unit7: {members: [person7]} + tax_unit8: {members: [person8]} + tax_unit9: {members: [person9]} + tax_unit10: {members: [person10]} + tax_unit11: {members: [person11]} + tax_unit12: {members: [person12]} + tax_unit13: {members: [person13]} + tax_unit14: {members: [person14]} + tax_unit15: {members: [person15]} + households: + household1: {members: [person1], state_code: WY} + household2: {members: [person2], state_code: WY} + household3: {members: [person3], state_code: WY} + household4: {members: [person4], state_code: WY} + household5: {members: [person5], state_code: WY} + household6: {members: [person6], state_code: WY} + household7: {members: [person7], state_code: WY} + household8: {members: [person8], state_code: WY} + household9: {members: [person9], state_code: WY} + household10: {members: [person10], state_code: WY} + household11: {members: [person11], state_code: WY} + household12: {members: [person12], state_code: WY} + household13: {members: [person13], state_code: WY} + household14: {members: [person14], state_code: WY} + household15: {members: [person15], state_code: WY} + output: + # Each one-person limit is $35,829. Apply the approved .21, .26, ..., + # .86, 1.00 ceilings to actual wages, then the $2,640 oil standard + # and the workbook's rounded 10 percent holdback. + wy_lieap: [1782, 1663, 1544, 1426, 1307, 1188, 1069, 950, 832, 713, 594, 475, 356, 238, 0] diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py index 4e02bc15f38..f300d35efaf 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py @@ -27,10 +27,17 @@ def formula(spm_unit, period, parameters): p = parameters(period).gov.states.wy.dfs.lieap.payment income = max_(spm_unit("wy_lieap_countable_income", period), 0) limit = spm_unit("wy_lieap_income_limit", period) - # Promote before division so float32 representations of exact decimal - # boundaries do not push a household into the next band. - ratio = income.astype(np.float64) / max_(limit, 1) - fraction = p.entitlement_fraction.calc(ratio, right=True) + # Express each inclusive ceiling at the stored income precision. + scale = p.entitlement_fraction + ceilings = [ + (max_(limit, 1).astype(np.float64) * threshold).astype(income.dtype) + for threshold in scale.thresholds[1:] + ] + fraction = select( + [income <= ceiling for ceiling in ceilings], + scale.amounts[:-1], + default=scale.amounts[-1], + ) heating_type = spm_unit("heating_type", period) base = p.fuel_cost[heating_type] * fraction # The workbook rounds only the withheld amount, half-up to dollars. diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py index 6c3a6b23e1a..3a25963de3c 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py @@ -21,9 +21,9 @@ class wy_lieap_countable_income(Variable): "when those adjustments are known. Medicare deductions remain unmodeled." ) reference = ( - # Section 1.9, physical page 6; minor-earnings/lump-sum conflicts documented. + # Section 1.9; minor-earnings/lump-sum conflicts documented. "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=6", - # Current chapter 1, section 8(a), physical pages 11-13. + # Current chapter 1, section 8(a), PDF pages 11-13. "https://rules.wyo.gov/Search.aspx?mode=7", ) defined_for = StateCode.WY diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py index 4b499fd7ad2..71372b6f0f6 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py @@ -9,7 +9,7 @@ class wy_lieap_income_limit(Variable): unit = USD label = "Wyoming LIEAP income limit" reference = ( - "https://dfs.wyo.gov/wp-content/uploads/2025/08/2025-0729-LIEAP-About-handout.pdf#page=1", + "https://liheapch.acf.gov/profiles/povertytables/FY2026/wysmi.htm", "https://dfs.wyo.gov/wp-content/uploads/2026/09/2026-0924-LIEAP-About-handout.pdf#page=1", ) defined_for = StateCode.WY From c0d3239dac0c11c19659b2f7d5782d2d58b27f69 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 20 Oct 2026 20:40:35 -0400 Subject: [PATCH 4/8] Fix Wyoming LIEAP protected income and receipt mappings --- changelog.d/wy-liheap-current-income.fixed.md | 1 + .../wy/dfs/lieap/income/unearned_sources.yaml | 3 +- .../gov/states/wy/dfs/lieap/smi_rate.yaml | 11 +- policyengine_us/programs.yaml | 2 +- .../gov/states/wy/dfs/lieap/wy_lieap.yaml | 495 ++++++++++++++++++ .../gov/states/wy/dfs/lieap/wy_lieap.py | 7 + .../wy/dfs/lieap/wy_lieap_countable_income.py | 9 +- .../states/wy/dfs/lieap/wy_lieap_eligible.py | 7 +- .../gov/states/wy/dfs/lieap/wy_lieap_fpg.py | 24 + .../wy/dfs/lieap/wy_lieap_income_limit.py | 2 +- 10 files changed, 545 insertions(+), 16 deletions(-) create mode 100644 changelog.d/wy-liheap-current-income.fixed.md create mode 100644 policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_fpg.py diff --git a/changelog.d/wy-liheap-current-income.fixed.md b/changelog.d/wy-liheap-current-income.fixed.md new file mode 100644 index 00000000000..13a8a5ad33d --- /dev/null +++ b/changelog.d/wy-liheap-current-income.fixed.md @@ -0,0 +1 @@ +Apply the federal income protection and count total unemployment compensation and ordinary military retirement pay in Wyoming LIEAP. diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml index 01ff59d0755..3f4ea947bdf 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml @@ -4,10 +4,11 @@ values: - social_security - ssi - pension_income + - military_retirement_pay - retirement_distributions - railroad_benefits - survivor_benefits - - unemployment_compensation + - total_unemployment_compensation - workers_compensation - disability_benefits - general_assistance diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml index 74fea232154..7795afbb3bd 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml @@ -1,6 +1,7 @@ -description: Wyoming limits household income to this share of state median income under the Low Income Energy Assistance Program. -# The current administrative standard is 60% SMI. The older 215% FPG -# statutory alternative is not applied, consistent with DFS's explanation. +description: Wyoming uses this share of state median income for its ordinary income limit under the Low Income Energy Assistance Program. +# The FY2026 plan uses 60% SMI. Current Title 42 retains its eligibility +# guarantee at the lesser of 215% FPG or 60% SMI and permits federal-compliance +# modifications. Federal 110% FPG income protection is applied separately. values: 2025-10-01: 0.6 @@ -11,5 +12,5 @@ metadata: reference: - title: "FY2026 State Plan, section 2.1" href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8 - - title: "DFS statutory cleanup recommendations, LIEAP #page 8-9" - href: https://wyoleg.gov/InterimCommittee/2016/10-0825AppendixC.pdf#page=8 + - title: "Wyoming Statutes, Title 42, section 42-2-501(c)-(d) #page 34-35" + href: https://wyoleg.gov/statutes/compress/title42.pdf#page=34 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 7b753a201f0..cb98df1c577 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -967,7 +967,7 @@ programs: variable: wy_lieap parameter_prefix: gov.states.wy.dfs.lieap verified_years: "2026" - notes: FY2026 regular heating only. Approved assumptions use inclusive income-band upper bounds, qualified-member household size with all otherwise countable income and no extra proration, and one poverty-guideline exclusion per SPM unit using total veterans benefits as a disability-income proxy. Under-18 earnings, TANF, child support received and identifiable lump sums are excluded, with plan-rule conflicts documented. Annual inputs cannot identify embedded exempt lump sums or all special receipts; Medicare and sponsor-income adjustments, work registration, tribal routing and administrative eligibility details remain unmodeled. Unsupported fuels or missing eligible heating costs return zero. Other years are unverified estimates; crisis, cooling, weatherization and equipment assistance are out of scope. + notes: FY2026 regular heating only. Eligibility also protects income strictly below the federal 110% poverty floor. Federal-floor awards retain the approved ratio against the effective income limit; the exact agency payment method for that route is unverified. Approved assumptions use inclusive income-band upper bounds, qualified-member household size with all otherwise countable income and no extra proration, and one poverty-guideline exclusion per SPM unit using total veterans benefits as a disability-income proxy. Under-18 earnings, TANF, child support received and identifiable lump sums are excluded, with plan-rule conflicts documented. Annual inputs cannot identify embedded exempt lump sums or all special receipts; Medicare and sponsor-income adjustments, work registration, tribal routing and administrative eligibility details remain unmodeled. Unsupported fuels or missing eligible heating costs return zero. Other years are unverified estimates; crisis, cooling, weatherization and equipment assistance are out of scope. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml index c215c6bb9c4..f854cb021a5 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml @@ -2303,3 +2303,498 @@ # .86, 1.00 ceilings to actual wages, then the $2,640 oil standard # and the workbook's rounded 10 percent holdback. wy_lieap: [1782, 1663, 1544, 1426, 1307, 1188, 1069, 950, 832, 713, 594, 475, 356, 238, 0] + +# 42 USC 8624(b)(2)(B): income LESS THAN 110% of the 2025 guideline is +# protected. Native SMI limit 113688; 110% * (15650 + 16 * 5500) = 114015. +# The approved effective-limit ratio gives the protected oil household .10: +# 2640 * .10 - round_half_up(264 * .10) = 238, below its 3000 cost. +# Each economic household consists of adult relatives with separate tax units. +- name: Federal income protection applies below the floor and preserves strict equality controls. + period: 2026 + input: + people: + household_0_adult_0: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 113900 + household_0_adult_1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_4: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_5: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_6: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_7: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_8: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_9: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_10: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_11: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_12: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_13: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_14: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_15: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_0_adult_16: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_0: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 114015 + household_1_adult_1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_4: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_5: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_6: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_7: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_8: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_9: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_10: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_11: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_12: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_13: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_14: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_15: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_1_adult_16: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_0: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 114016 + household_2_adult_1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_4: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_5: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_6: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_7: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_8: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_9: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_10: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_11: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_12: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_13: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_14: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_15: + age: 40 + immigration_status: CITIZEN + ssi: 0 + household_2_adult_16: + age: 40 + immigration_status: CITIZEN + ssi: 0 + tax_units: + tax_0_0: + members: + - household_0_adult_0 + tax_0_1: + members: + - household_0_adult_1 + tax_0_2: + members: + - household_0_adult_2 + tax_0_3: + members: + - household_0_adult_3 + tax_0_4: + members: + - household_0_adult_4 + tax_0_5: + members: + - household_0_adult_5 + tax_0_6: + members: + - household_0_adult_6 + tax_0_7: + members: + - household_0_adult_7 + tax_0_8: + members: + - household_0_adult_8 + tax_0_9: + members: + - household_0_adult_9 + tax_0_10: + members: + - household_0_adult_10 + tax_0_11: + members: + - household_0_adult_11 + tax_0_12: + members: + - household_0_adult_12 + tax_0_13: + members: + - household_0_adult_13 + tax_0_14: + members: + - household_0_adult_14 + tax_0_15: + members: + - household_0_adult_15 + tax_0_16: + members: + - household_0_adult_16 + tax_1_0: + members: + - household_1_adult_0 + tax_1_1: + members: + - household_1_adult_1 + tax_1_2: + members: + - household_1_adult_2 + tax_1_3: + members: + - household_1_adult_3 + tax_1_4: + members: + - household_1_adult_4 + tax_1_5: + members: + - household_1_adult_5 + tax_1_6: + members: + - household_1_adult_6 + tax_1_7: + members: + - household_1_adult_7 + tax_1_8: + members: + - household_1_adult_8 + tax_1_9: + members: + - household_1_adult_9 + tax_1_10: + members: + - household_1_adult_10 + tax_1_11: + members: + - household_1_adult_11 + tax_1_12: + members: + - household_1_adult_12 + tax_1_13: + members: + - household_1_adult_13 + tax_1_14: + members: + - household_1_adult_14 + tax_1_15: + members: + - household_1_adult_15 + tax_1_16: + members: + - household_1_adult_16 + tax_2_0: + members: + - household_2_adult_0 + tax_2_1: + members: + - household_2_adult_1 + tax_2_2: + members: + - household_2_adult_2 + tax_2_3: + members: + - household_2_adult_3 + tax_2_4: + members: + - household_2_adult_4 + tax_2_5: + members: + - household_2_adult_5 + tax_2_6: + members: + - household_2_adult_6 + tax_2_7: + members: + - household_2_adult_7 + tax_2_8: + members: + - household_2_adult_8 + tax_2_9: + members: + - household_2_adult_9 + tax_2_10: + members: + - household_2_adult_10 + tax_2_11: + members: + - household_2_adult_11 + tax_2_12: + members: + - household_2_adult_12 + tax_2_13: + members: + - household_2_adult_13 + tax_2_14: + members: + - household_2_adult_14 + tax_2_15: + members: + - household_2_adult_15 + tax_2_16: + members: + - household_2_adult_16 + spm_units: + unit_0: + members: &id001 + - household_0_adult_0 + - household_0_adult_1 + - household_0_adult_2 + - household_0_adult_3 + - household_0_adult_4 + - household_0_adult_5 + - household_0_adult_6 + - household_0_adult_7 + - household_0_adult_8 + - household_0_adult_9 + - household_0_adult_10 + - household_0_adult_11 + - household_0_adult_12 + - household_0_adult_13 + - household_0_adult_14 + - household_0_adult_15 + - household_0_adult_16 + heating_type: FUEL_OIL + fuel_oil_expense: 3000 + unit_1: + members: &id002 + - household_1_adult_0 + - household_1_adult_1 + - household_1_adult_2 + - household_1_adult_3 + - household_1_adult_4 + - household_1_adult_5 + - household_1_adult_6 + - household_1_adult_7 + - household_1_adult_8 + - household_1_adult_9 + - household_1_adult_10 + - household_1_adult_11 + - household_1_adult_12 + - household_1_adult_13 + - household_1_adult_14 + - household_1_adult_15 + - household_1_adult_16 + heating_type: FUEL_OIL + fuel_oil_expense: 3000 + unit_2: + members: &id003 + - household_2_adult_0 + - household_2_adult_1 + - household_2_adult_2 + - household_2_adult_3 + - household_2_adult_4 + - household_2_adult_5 + - household_2_adult_6 + - household_2_adult_7 + - household_2_adult_8 + - household_2_adult_9 + - household_2_adult_10 + - household_2_adult_11 + - household_2_adult_12 + - household_2_adult_13 + - household_2_adult_14 + - household_2_adult_15 + - household_2_adult_16 + heating_type: FUEL_OIL + fuel_oil_expense: 3000 + households: + home_0: + members: *id001 + state_code: WY + home_1: + members: *id002 + state_code: WY + home_2: + members: *id003 + state_code: WY + output: + wy_lieap_household_size: + - 17 + - 17 + - 17 + wy_lieap_fpg: + - 103650 + - 103650 + - 103650 + wy_lieap_income_limit: + - 113688 + - 113688 + - 113688 + wy_lieap_countable_income: + - 113900 + - 114015 + - 114016 + wy_lieap_eligible: + - true + - false + - false + wy_lieap: + - 238 + - 0 + - 0 + +# Rules chapter 1, sections 3(nn) and 8(a)(i): nonexempt ordinary DoD +# retirement counts separately from pension and VA. 36000 exceeds 35829. +- name: Ordinary military retirement is counted separately from the veterans exclusion. + period: 2026 + input: + state_code: WY + age: 40 + immigration_status: CITIZEN + is_veteran: true + years_in_military: 20 + military_retirement_pay: 36000 + pension_income: 0 + veterans_benefits: 0 + ssi: 0 + heating_type: FUEL_OIL + fuel_oil_expense: 3000 + output: + military_retirement_income: 36000 + pension_income: 0 + veterans_benefits: 0 + wy_lieap_countable_income: 36000 + wy_lieap_income_limit: 35829 + wy_lieap_eligible: false + wy_lieap: 0 diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py index f300d35efaf..1d1f5aedf33 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py @@ -14,12 +14,15 @@ class wy_lieap(Variable): "mixed-status households use qualified-member size, all otherwise countable " "income and no additional proration. Renters use the same schedule. " "Zero may indicate an unsupported fuel or missing eligible heating cost. " + "Federal-floor households use the approved income-to-effective-limit " + "ratio convention; their exact agency payment method is unverified. " "Years outside FY2026 are unverified estimates, including backfilled years." ) reference = ( "https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx", # Chapter 1, sections 10(d)-(e) and 13(b)(i), physical page 16. "https://rules.wyo.gov/Search.aspx?mode=7", + "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", ) defined_for = "wy_lieap_eligible" @@ -27,6 +30,10 @@ def formula(spm_unit, period, parameters): p = parameters(period).gov.states.wy.dfs.lieap.payment income = max_(spm_unit("wy_lieap_countable_income", period), 0) limit = spm_unit("wy_lieap_income_limit", period) + floor_rate = parameters(period).gov.hhs.liheap.fpg_floor + guideline = spm_unit("wy_lieap_fpg", period).astype(np.float64) + federal_floor = np.round(guideline * floor_rate, 2) + limit = max_(limit, federal_floor) # Express each inclusive ceiling at the stored income precision. scale = p.entitlement_fraction ceilings = [ diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py index 3a25963de3c..37db4e70a2d 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py @@ -1,5 +1,4 @@ from policyengine_us.model_api import * -from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg class wy_lieap_countable_income(Variable): @@ -53,15 +52,11 @@ def formula(spm_unit, period, parameters): countable_gifts = where( gifts > p.gift_monthly_threshold * MONTHS_IN_YEAR, gifts, 0 ) - size = spm_unit("wy_lieap_household_size", period) - state_group = spm_unit.household("state_group_str", period) - guideline = fpg( - max_(size, 1), state_group, period, parameters, year_lag=p.fpg_year_lag - ) + guideline = spm_unit("wy_lieap_fpg", period) # Approved approximation: total VA income, one exclusion per SPM unit. # Do not apply a separate allowance to each veteran, spouse or dependent. veterans = spm_unit.sum(max_(person("veterans_benefits", period), 0)) - veterans_exclusion = where(size > 0, guideline * p.veterans_fpg_rate, 0) + veterans_exclusion = guideline * p.veterans_fpg_rate countable_veterans = max_(veterans - veterans_exclusion, 0) return ( spm_unit.sum(earned + unearned + countable_interest + countable_gifts) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py index 9a7087fc257..68e5f5b883b 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py @@ -17,6 +17,7 @@ class wy_lieap_eligible(Variable): "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8", # Chapter 1, sections 7 and 8(b). "https://rules.wyo.gov/Search.aspx?mode=7", + "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", ) defined_for = StateCode.WY @@ -24,5 +25,9 @@ def formula(spm_unit, period, parameters): size = spm_unit("wy_lieap_household_size", period) income = spm_unit("wy_lieap_countable_income", period) limit = spm_unit("wy_lieap_income_limit", period) + floor_rate = parameters(period).gov.hhs.liheap.fpg_floor + guideline = spm_unit("wy_lieap_fpg", period).astype(np.float64) + federal_floor = np.round(guideline * floor_rate, 2) + income_eligible = (income <= limit) | (income < federal_floor) expense = spm_unit("heating_expense", period) - return (size > 0) & (income <= limit) & (expense > 0) + return (size > 0) & income_eligible & (expense > 0) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_fpg.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_fpg.py new file mode 100644 index 00000000000..73165fe000b --- /dev/null +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_fpg.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class wy_lieap_fpg(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Federal poverty guideline for the Wyoming LIEAP household" + defined_for = StateCode.WY + reference = ( + "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", + "https://rules.wyo.gov/Search.aspx?mode=7", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.wy.dfs.lieap.income + size = spm_unit("wy_lieap_household_size", period) + state_group = spm_unit.household("state_group_str", period) + guideline = fpg( + max_(size, 1), state_group, period, parameters, year_lag=p.fpg_year_lag + ) + return where(size > 0, guideline, 0) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py index 71372b6f0f6..58e4e465f8d 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py @@ -7,7 +7,7 @@ class wy_lieap_income_limit(Variable): entity = SPMUnit definition_period = YEAR unit = USD - label = "Wyoming LIEAP income limit" + label = "Wyoming LIEAP state median income limit" reference = ( "https://liheapch.acf.gov/profiles/povertytables/FY2026/wysmi.htm", "https://dfs.wyo.gov/wp-content/uploads/2026/09/2026-0924-LIEAP-About-handout.pdf#page=1", From 34f9768711ce83250ba2b0c0723cef47147c6f91 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 21 Oct 2026 01:15:47 -0400 Subject: [PATCH 5/8] Consolidate Wyoming LIHEAP changelog and registry note One added changelog fragment for the new program and a one- or two-sentence programs.yaml note; limitations stay in code comments and the PR body. Co-Authored-By: Claude Opus 5.5 --- changelog.d/wy-liheap-current-income.fixed.md | 1 - changelog.d/wy-liheap-review-fixes.fixed.md | 1 - changelog.d/wy-liheap-wave2b.added.md | 2 +- policyengine_us/programs.yaml | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 changelog.d/wy-liheap-current-income.fixed.md delete mode 100644 changelog.d/wy-liheap-review-fixes.fixed.md diff --git a/changelog.d/wy-liheap-current-income.fixed.md b/changelog.d/wy-liheap-current-income.fixed.md deleted file mode 100644 index 13a8a5ad33d..00000000000 --- a/changelog.d/wy-liheap-current-income.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Apply the federal income protection and count total unemployment compensation and ordinary military retirement pay in Wyoming LIEAP. diff --git a/changelog.d/wy-liheap-review-fixes.fixed.md b/changelog.d/wy-liheap-review-fixes.fixed.md deleted file mode 100644 index feab3d6fe19..00000000000 --- a/changelog.d/wy-liheap-review-fixes.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Preserve Wyoming LIEAP inclusive income-band ceilings at actual dollar boundaries and update source citations. diff --git a/changelog.d/wy-liheap-wave2b.added.md b/changelog.d/wy-liheap-wave2b.added.md index cfb630d3b0d..8bb4e1d5cf5 100644 --- a/changelog.d/wy-liheap-wave2b.added.md +++ b/changelog.d/wy-liheap-wave2b.added.md @@ -1 +1 @@ -Add Wyoming regular LIEAP heating benefits with income and household eligibility, published fuel standards, expense caps, and documented modeling assumptions for income bands, mixed-status households, income exclusions, and veterans benefits. +Add Wyoming LIEAP (wy_lieap): FY2026 regular heating benefit from the published fuel cost standards with the 60% state median income test. diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index cb98df1c577..7c4a557efcb 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -967,7 +967,7 @@ programs: variable: wy_lieap parameter_prefix: gov.states.wy.dfs.lieap verified_years: "2026" - notes: FY2026 regular heating only. Eligibility also protects income strictly below the federal 110% poverty floor. Federal-floor awards retain the approved ratio against the effective income limit; the exact agency payment method for that route is unverified. Approved assumptions use inclusive income-band upper bounds, qualified-member household size with all otherwise countable income and no extra proration, and one poverty-guideline exclusion per SPM unit using total veterans benefits as a disability-income proxy. Under-18 earnings, TANF, child support received and identifiable lump sums are excluded, with plan-rule conflicts documented. Annual inputs cannot identify embedded exempt lump sums or all special receipts; Medicare and sponsor-income adjustments, work registration, tribal routing and administrative eligibility details remain unmodeled. Unsupported fuels or missing eligible heating costs return zero. Other years are unverified estimates; crisis, cooling, weatherization and equipment assistance are out of scope. + notes: FY2026 regular heating from the published fuel cost standards. Crisis, cooling, weatherization and equipment assistance are out of scope. # --- SSA programs --- - id: ssi From 9b5042a8262951a258bc5bd7c09c3a44118a1e10 Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 23 Oct 2026 22:46:03 -0400 Subject: [PATCH 6/8] Address review findings for Wyoming LIHEAP Co-Authored-By: Claude Opus 5.5 --- .../wy/dfs/lieap/income/earned_sources.yaml | 4 +- .../wy/dfs/lieap/income/fpg_year_lag.yaml | 2 +- .../wy/dfs/lieap/income/unearned_sources.yaml | 13 +- .../gov/states/wy/dfs/lieap/wy_lieap.yaml | 554 +++--------------- .../gov/states/wy/dfs/lieap/wy_lieap.py | 10 +- .../wy/dfs/lieap/wy_lieap_countable_income.py | 17 +- .../states/wy/dfs/lieap/wy_lieap_eligible.py | 2 + source_conflicts/candidates.yaml | 67 +++ 8 files changed, 184 insertions(+), 485 deletions(-) diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml index 856ba7233b3..133d2699d46 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml @@ -14,7 +14,7 @@ metadata: period: year label: Wyoming LIEAP earned income sources reference: - - title: FY2026 State Plan, section 1.9 - href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=6 + - title: "FY2026 State Plan, section 1.9 #page 5-6" + href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=5 - title: LIEAP Rules, Chapter 1, sections 3(w) and 8(a) href: https://rules.wyo.gov/Search.aspx?mode=7 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml index b55cd39f8c3..da0dff1e05f 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml @@ -1,4 +1,4 @@ -description: Wyoming uses the federal poverty guideline from this many years before the modeled fiscal year for the veterans exclusion under the Low Income Energy Assistance Program. +description: Wyoming uses the federal poverty guideline from this many years before the modeled fiscal year for the veterans exclusion and the federal income floor under the Low Income Energy Assistance Program. # Annual FY2026 represents the season starting in October 2025; use the # guideline at season start. Earlier and later policy remains unverified. values: diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml index 3f4ea947bdf..f3279445873 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml @@ -1,10 +1,9 @@ -description: Wyoming counts these nonnegative unearned income sources before separate interest, gifts and veterans adjustments under the Low Income Energy Assistance Program. +description: Wyoming counts these nonnegative unearned income sources before separate Social Security, interest, gifts and veterans adjustments under the Low Income Energy Assistance Program. values: 2025-10-01: - - social_security - ssi - pension_income - - military_retirement_pay + - military_retirement_income - retirement_distributions - railroad_benefits - survivor_benefits @@ -26,14 +25,16 @@ values: # countable income directly for those cases. No new subtype input is added. # Regular disability/worker/survivor income approximates nonexempt receipts; # pension_income already includes annuities. No duplicate pension components. -# Medicare deducted from SSA remains unmodeled under the agreed scope. +# military_retirement_income adds retirement pay and survivor annuities. +# Social Security is counted in the formula, net of the Medicare Part B +# premium deducted from it (rules 8(a)(ii)(U)). # Contract payments and royalties lack dedicated inputs and are not imputed. metadata: unit: list period: year label: Wyoming LIEAP unearned income sources reference: - - title: FY2026 State Plan, section 1.9 - href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=6 + - title: "FY2026 State Plan, section 1.9 #page 5-6" + href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=5 - title: LIEAP Rules, Chapter 1, section 8(a) href: https://rules.wyo.gov/Search.aspx?mode=7 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml index f854cb021a5..05e037752d4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml @@ -1793,6 +1793,10 @@ output: wy_lieap: 0 +# Rules 10(d) apply the $10 cutoff to the computed benefit, and 13(b)(i) +# then limit payment to the actual primary fuel cost. The adjusted oil +# benefit 2,640 * .8 - round_half_up(211.2) = 1,901 passes the cutoff, +# so a bill below $10 is paid in full. - name: Case 129, actual expense 9 with zero income. period: 2026 absolute_error_margin: 0.001 @@ -1804,7 +1808,8 @@ wy_lieap_countable_income: 0 heating_type: FUEL_OIL output: - wy_lieap: 0 + # min(1,901, 9) = 9. + wy_lieap: 9 - name: Case 130, actual expense 9.99 with zero income. period: 2026 @@ -1817,7 +1822,8 @@ wy_lieap_countable_income: 0 heating_type: FUEL_OIL output: - wy_lieap: 0 + # min(1,901, 9.99) = 9.99. + wy_lieap: 9.99 - name: Case 131, actual expense 10 with zero income. period: 2026 @@ -2083,7 +2089,9 @@ wy_lieap_household_size: [2, 0, 1, 0] wy_lieap_countable_income: [38_850, 0, 0, 0] wy_lieap_income_limit: [46_853, 0, 35_829, 0] - wy_lieap: [209.6275, 0, 0, 0] + # The propane unit's adjusted benefit 1,300 * .8 - round_half_up(104) = 936 + # passes the $10 cutoff and is then limited to its $9 bill. + wy_lieap: [209.6275, 0, 9, 0] - name: Case 148, real FY2026 incomes a cent below every band ceiling preserve inclusive selection. period: 2026 @@ -2305,478 +2313,31 @@ wy_lieap: [1782, 1663, 1544, 1426, 1307, 1188, 1069, 950, 832, 713, 594, 475, 356, 238, 0] # 42 USC 8624(b)(2)(B): income LESS THAN 110% of the 2025 guideline is -# protected. Native SMI limit 113688; 110% * (15650 + 16 * 5500) = 114015. -# The approved effective-limit ratio gives the protected oil household .10: -# 2640 * .10 - round_half_up(264 * .10) = 238, below its 3000 cost. -# Each economic household consists of adult relatives with separate tax units. -- name: Federal income protection applies below the floor and preserves strict equality controls. - period: 2026 - input: - people: - household_0_adult_0: - age: 40 - immigration_status: CITIZEN - ssi: 0 - employment_income: 113900 - household_0_adult_1: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_2: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_3: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_4: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_5: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_6: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_7: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_8: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_9: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_10: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_11: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_12: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_13: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_14: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_15: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_0_adult_16: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_0: - age: 40 - immigration_status: CITIZEN - ssi: 0 - employment_income: 114015 - household_1_adult_1: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_2: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_3: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_4: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_5: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_6: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_7: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_8: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_9: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_10: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_11: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_12: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_13: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_14: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_15: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_1_adult_16: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_0: - age: 40 - immigration_status: CITIZEN - ssi: 0 - employment_income: 114016 - household_2_adult_1: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_2: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_3: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_4: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_5: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_6: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_7: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_8: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_9: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_10: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_11: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_12: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_13: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_14: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_15: - age: 40 - immigration_status: CITIZEN - ssi: 0 - household_2_adult_16: - age: 40 - immigration_status: CITIZEN - ssi: 0 - tax_units: - tax_0_0: - members: - - household_0_adult_0 - tax_0_1: - members: - - household_0_adult_1 - tax_0_2: - members: - - household_0_adult_2 - tax_0_3: - members: - - household_0_adult_3 - tax_0_4: - members: - - household_0_adult_4 - tax_0_5: - members: - - household_0_adult_5 - tax_0_6: - members: - - household_0_adult_6 - tax_0_7: - members: - - household_0_adult_7 - tax_0_8: - members: - - household_0_adult_8 - tax_0_9: - members: - - household_0_adult_9 - tax_0_10: - members: - - household_0_adult_10 - tax_0_11: - members: - - household_0_adult_11 - tax_0_12: - members: - - household_0_adult_12 - tax_0_13: - members: - - household_0_adult_13 - tax_0_14: - members: - - household_0_adult_14 - tax_0_15: - members: - - household_0_adult_15 - tax_0_16: - members: - - household_0_adult_16 - tax_1_0: - members: - - household_1_adult_0 - tax_1_1: - members: - - household_1_adult_1 - tax_1_2: - members: - - household_1_adult_2 - tax_1_3: - members: - - household_1_adult_3 - tax_1_4: - members: - - household_1_adult_4 - tax_1_5: - members: - - household_1_adult_5 - tax_1_6: - members: - - household_1_adult_6 - tax_1_7: - members: - - household_1_adult_7 - tax_1_8: - members: - - household_1_adult_8 - tax_1_9: - members: - - household_1_adult_9 - tax_1_10: - members: - - household_1_adult_10 - tax_1_11: - members: - - household_1_adult_11 - tax_1_12: - members: - - household_1_adult_12 - tax_1_13: - members: - - household_1_adult_13 - tax_1_14: - members: - - household_1_adult_14 - tax_1_15: - members: - - household_1_adult_15 - tax_1_16: - members: - - household_1_adult_16 - tax_2_0: - members: - - household_2_adult_0 - tax_2_1: - members: - - household_2_adult_1 - tax_2_2: - members: - - household_2_adult_2 - tax_2_3: - members: - - household_2_adult_3 - tax_2_4: - members: - - household_2_adult_4 - tax_2_5: - members: - - household_2_adult_5 - tax_2_6: - members: - - household_2_adult_6 - tax_2_7: - members: - - household_2_adult_7 - tax_2_8: - members: - - household_2_adult_8 - tax_2_9: - members: - - household_2_adult_9 - tax_2_10: - members: - - household_2_adult_10 - tax_2_11: - members: - - household_2_adult_11 - tax_2_12: - members: - - household_2_adult_12 - tax_2_13: - members: - - household_2_adult_13 - tax_2_14: - members: - - household_2_adult_14 - tax_2_15: - members: - - household_2_adult_15 - tax_2_16: - members: - - household_2_adult_16 - spm_units: - unit_0: - members: &id001 - - household_0_adult_0 - - household_0_adult_1 - - household_0_adult_2 - - household_0_adult_3 - - household_0_adult_4 - - household_0_adult_5 - - household_0_adult_6 - - household_0_adult_7 - - household_0_adult_8 - - household_0_adult_9 - - household_0_adult_10 - - household_0_adult_11 - - household_0_adult_12 - - household_0_adult_13 - - household_0_adult_14 - - household_0_adult_15 - - household_0_adult_16 - heating_type: FUEL_OIL - fuel_oil_expense: 3000 - unit_1: - members: &id002 - - household_1_adult_0 - - household_1_adult_1 - - household_1_adult_2 - - household_1_adult_3 - - household_1_adult_4 - - household_1_adult_5 - - household_1_adult_6 - - household_1_adult_7 - - household_1_adult_8 - - household_1_adult_9 - - household_1_adult_10 - - household_1_adult_11 - - household_1_adult_12 - - household_1_adult_13 - - household_1_adult_14 - - household_1_adult_15 - - household_1_adult_16 - heating_type: FUEL_OIL - fuel_oil_expense: 3000 - unit_2: - members: &id003 - - household_2_adult_0 - - household_2_adult_1 - - household_2_adult_2 - - household_2_adult_3 - - household_2_adult_4 - - household_2_adult_5 - - household_2_adult_6 - - household_2_adult_7 - - household_2_adult_8 - - household_2_adult_9 - - household_2_adult_10 - - household_2_adult_11 - - household_2_adult_12 - - household_2_adult_13 - - household_2_adult_14 - - household_2_adult_15 - - household_2_adult_16 - heating_type: FUEL_OIL - fuel_oil_expense: 3000 - households: - home_0: - members: *id001 - state_code: WY - home_1: - members: *id002 - state_code: WY - home_2: - members: *id003 - state_code: WY - output: - wy_lieap_household_size: - - 17 - - 17 - - 17 - wy_lieap_fpg: - - 103650 - - 103650 - - 103650 - wy_lieap_income_limit: - - 113688 - - 113688 - - 113688 - wy_lieap_countable_income: - - 113900 - - 114015 - - 114016 - wy_lieap_eligible: - - true - - false - - false - wy_lieap: - - 238 - - 0 - - 0 +# protected. Each unit enters a 17-member household; the guideline and +# limit still compute from that size. Native SMI limit 113,688; +# 110% * (15,650 + 16 * 5,500) = 114,015. +# Unit 1: 113,900 is above 113,688 but below 114,015, so it qualifies. +# Its ratio to the effective limit, 113,900 / 114,015 = .999, selects .10: +# 2,640 * .10 - round_half_up(264 * .10) = 238, below its 3,000 cost. +# Unit 2: 114,015 equals the floor, so it is not protected. +- name: Case 151, federal income protection applies only below the 110 percent poverty floor. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [WY, WY] + wy_lieap_household_size: [17, 17] + wy_lieap_countable_income: [113_900, 114_015] + heating_type: [FUEL_OIL, FUEL_OIL] + heating_expense: [3_000, 3_000] + output: + wy_lieap_fpg: [103_650, 103_650] + wy_lieap_income_limit: [113_688, 113_688] + wy_lieap_eligible: [true, false] + wy_lieap: [238, 0] # Rules chapter 1, sections 3(nn) and 8(a)(i): nonexempt ordinary DoD # retirement counts separately from pension and VA. 36000 exceeds 35829. -- name: Ordinary military retirement is counted separately from the veterans exclusion. +- name: Case 152, ordinary military retirement is counted separately from the veterans exclusion. period: 2026 input: state_code: WY @@ -2798,3 +2359,52 @@ wy_lieap_income_limit: 35829 wy_lieap_eligible: false wy_lieap: 0 + +# Rules chapter 1, section 3(nn) counts gross non-exempt money from any +# source, and no section 8(a)(ii) exemption covers a uniformed-services +# survivor annuity. military_retirement_income adds the $40,000 Survivor +# Benefit Plan annuity, which exceeds the $35,829 one-person FY2026 limit +# and the $17,215 federal floor (110% * 15,650). +- name: Case 153, a military survivor annuity counts as military retirement income. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: WY + age: 70 + immigration_status: CITIZEN + military_retirement_pay_survivors: 40_000 + ssi: 0 + heating_type: NATURAL_GAS + gas_expense: 1_500 + output: + military_retirement_income: 40_000 + wy_lieap_countable_income: 40_000 + wy_lieap_income_limit: 35_829 + wy_lieap_eligible: false + wy_lieap: 0 + +# Rules chapter 1, section 8(a)(ii)(U) exempts Medicare deducted from SSA, +# and FY2026 plan section 1.9 counts Social Security excluding the Medicare +# deduction. The 2026 Part B premium is 202.90 * 12 = 2,434.80; $37,000 of +# Social Security is above the Medicare Savings Program limits, so the +# person pays it: 37,000 - 2,434.80 = 34,565.20, within the $35,829 limit. +# Ratio 34,565.20 / 35,829 = .965 selects .10: +# 1,550.85 * .10 = 155.085; round_half_up(15.5085) = 16 withheld; +# 155.085 - 16 = 139.085, below the $1,500 bill. +- name: Case 154, Social Security counts net of the Medicare Part B premium. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: WY + age: 70 + immigration_status: CITIZEN + social_security_retirement: 37_000 + ssi: 0 + heating_type: NATURAL_GAS + gas_expense: 1_500 + output: + medicare_part_b_premium: 2_434.8 + wy_lieap_countable_income: 34_565.2 + wy_lieap_income_limit: 35_829 + wy_lieap_eligible: true + wy_lieap: 139.085 diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py index 1d1f5aedf33..780cced4fb6 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py @@ -49,6 +49,12 @@ def formula(spm_unit, period, parameters): base = p.fuel_cost[heating_type] * fraction # The workbook rounds only the withheld amount, half-up to dollars. withheld = np.floor(base * p.holdback_rate + 0.5) + adjusted_benefit = base - withheld + # Rules 10(d) bar a computed benefit below the minimum before + # 13(b)(i) limits payment to the actual primary fuel cost. expense = max_(spm_unit("heating_expense", period), 0) - award = min_(base - withheld, expense) - return where(award >= p.minimum_payment, award, 0) + return where( + adjusted_benefit >= p.minimum_payment, + min_(adjusted_benefit, expense), + 0, + ) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py index 37db4e70a2d..44728e43518 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py @@ -17,7 +17,8 @@ class wy_lieap_countable_income(Variable): "This proxy can understate income from other kinds of VA benefits. " "Annual source inputs cannot distinguish embedded lump sums, exempt " "reimbursements or irregular receipts; supply countable income directly " - "when those adjustments are known. Medicare deductions remain unmodeled." + "when those adjustments are known. Social Security counts net of the " + "Medicare Part B premium the person pays." ) reference = ( # Section 1.9; minor-earnings/lump-sum conflicts documented. @@ -42,6 +43,12 @@ def formula(spm_unit, period, parameters): 0, ) unearned = sum(max_(person(source, period), 0) for source in p.unearned_sources) + # Rules 8(a)(ii)(U) exempt "Medicare deducted from SSA", and plan section + # 1.9 counts Social Security excluding the Medicare deduction. + # medicare_part_b_premium is zero for a person who is not enrolled and + # excludes the share a Medicare Savings Program pays. + premium = person("medicare_part_b_premium", period) + social_security = max_(person("social_security", period) - premium, 0) # These are thresholds, not deductions. Annualization assumes # constant monthly receipts; interest and gifts are assessed separately. interest = max_(person("interest_income", period), 0) @@ -59,6 +66,12 @@ def formula(spm_unit, period, parameters): veterans_exclusion = guideline * p.veterans_fpg_rate countable_veterans = max_(veterans - veterans_exclusion, 0) return ( - spm_unit.sum(earned + unearned + countable_interest + countable_gifts) + spm_unit.sum( + earned + + unearned + + social_security + + countable_interest + + countable_gifts + ) + countable_veterans ) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py index 68e5f5b883b..db3c549561c 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py @@ -22,6 +22,8 @@ class wy_lieap_eligible(Variable): defined_for = StateCode.WY def formula(spm_unit, period, parameters): + # Follows FY2026 plan section 1.4, which elects no categorical eligibility; + # rules 7(a)(i) list POWER, SNAP and veteran or survivor pension recipients. size = spm_unit("wy_lieap_household_size", period) income = spm_unit("wy_lieap_countable_income", period) limit = spm_unit("wy_lieap_income_limit", period) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 7d8c41658c6..3f7ef2e8d7e 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -5602,6 +5602,73 @@ candidates: state: unreviewed note: 'PE-US follows the Rules; establish whether the chart header denotes a different calculation. Code not yet on main: wy_ccap_income_eligible, wy_ccap_countable_income.' +- id: us-wy:lieap-income-floor-vs-smi-limit + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Can Wyoming's 60% SMI limit exclude a large household whose income is below the federal 110% + poverty-guideline floor? + sources: + - kind: statute + citation: 42 U.S.C. 8624(b)(2)(B) + url: https://www.law.cornell.edu/uscode/text/42/8624 + - kind: plan + citation: Wyoming FY2026 LIEAP State Plan, section 2.1, 60% SMI for all household sizes + url: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8 + readings: + statute: Income below 110% of the poverty guideline cannot by itself exclude the household. + other: The 60% SMI limit falls below that floor starting at household size 17. + example: A 17-person household earning $113,900 exceeds the $113,688 state limit but is below the $114,015 floor + and receives a $238 heating-oil benefit in the PR. + pe_us: + follows: statute + code: [] + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10346 + state: unreviewed + note: 'The open PR applies the federal floor and sets the benefit fraction from income relative to the raised + limit; the agency payment method for these households is unverified. Code not yet on main: wy_lieap_eligible, + wy_lieap.' +- id: us-wy:lieap-income-limit-statute-lesser-of + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Does W.S. 42-2-501(c), which requires eligibility at incomes not exceeding the lesser of 215% of the + poverty level or 60% of state median income, set a coverage minimum or the income ceiling? + sources: + - kind: statute + citation: W.S. 42-2-501(c)-(d) + url: https://wyoleg.gov/statutes/compress/title42.pdf#page=34 + - kind: regulation + citation: Wyoming DFS LIEAP Rules, Chapter 1, sections 3(oo) and 7(a)(ii) + url: https://rules.wyo.gov/Search.aspx?mode=7 + - kind: plan + citation: Wyoming FY2026 LIEAP State Plan, section 2.1, 60% SMI for all household sizes + url: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8 + - kind: agency-practice + citation: DFS 2016 statute clean-up request, Appendix C, asking to remove the 215% clause + url: https://wyoleg.gov/InterimCommittee/2016/10-0825AppendixC.pdf#page=8 + readings: + statute: The state plan must cover households with incomes at or below the lesser of 215% of the poverty level + or 60% of state median income. + other: Rules 3(oo) and 7(a)(ii) treat the section 42-2-501(c) standard as the maximum income, and the FY2026 + plan applies 60% of state median income for every household size. + example: A one-person FY2026 household with $34,000 of countable income is above 215% of the 2025 guideline + ($33,647.50) and within 60% of state median income ($35,829), and the PR finds it income-eligible. + pe_us: + follows: conflicting-source + code: [] + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10346 + state: unreviewed + note: 'The open PR reads the statute as a coverage minimum that the plan meets and applies 60% of state median + income for every size. Under the ceiling reading, FY2026 sizes 1-3 with incomes of $33,647.50-$35,829, + $45,472.50-$46,853 and $57,297.50-$57,877 would be ineligible. No amendment history for the clause was found. + Code not yet on main: wy_lieap_income_limit, smi_rate.yaml.' - id: us:additional-child-credit-housing-deduction-bar program: income-tax years: From 932f077d48fb10ab011c277ee54b4425ff6dfb09 Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 23 Oct 2026 22:47:00 -0400 Subject: [PATCH 7/8] Sum Wyoming LIHEAP income without built-in sum Co-Authored-By: Claude Opus 5.5 --- .../gov/states/wy/dfs/lieap/wy_lieap_countable_income.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py index 44728e43518..dd3b47aba5c 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py @@ -33,7 +33,9 @@ def formula(spm_unit, period, parameters): person = spm_unit.members # Supplied net business income approximates allowable expenses. # Separate business and rental losses cannot offset positive sources. - earned = sum(max_(person(source, period), 0) for source in p.earned_sources) + earned = 0 + for source in p.earned_sources: + earned = earned + max_(person(source, period), 0) support_paid = max_(person("child_support_expense", period), 0) # The input does not identify court orders or monthly regularity. # Deduct only from this payer's earnings, never another member's. @@ -42,7 +44,9 @@ def formula(spm_unit, period, parameters): max_(earned - support_paid, 0), 0, ) - unearned = sum(max_(person(source, period), 0) for source in p.unearned_sources) + unearned = 0 + for source in p.unearned_sources: + unearned = unearned + max_(person(source, period), 0) # Rules 8(a)(ii)(U) exempt "Medicare deducted from SSA", and plan section # 1.9 counts Social Security excluding the Medicare deduction. # medicare_part_b_premium is zero for a person who is not enrolled and From 5403e873fd3e7fa4bf0db6a4eb9da3a2813a94e4 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 27 Oct 2026 15:41:49 -0400 Subject: [PATCH 8/8] Address review of Wyoming LIHEAP Co-Authored-By: Claude Opus 5.5 --- .../lieap/income/earned_income_min_age.yaml | 9 +- .../wy/dfs/lieap/income/earned_sources.yaml | 6 +- .../wy/dfs/lieap/income/fpg_year_lag.yaml | 4 +- .../lieap/income/gift_monthly_threshold.yaml | 4 +- .../income/interest_monthly_threshold.yaml | 4 +- .../wy/dfs/lieap/income/unearned_sources.yaml | 7 +- .../dfs/lieap/income/veterans_fpg_rate.yaml | 6 +- .../lieap/payment/entitlement_fraction.yaml | 16 +- .../wy/dfs/lieap/payment/fuel_cost.yaml | 24 +- .../wy/dfs/lieap/payment/minimum_payment.yaml | 4 +- .../gov/states/wy/dfs/lieap/smi_rate.yaml | 12 +- .../gov/states/wy/dfs/lieap/wy_lieap.yaml | 268 +++++++++++------- .../dfs/lieap/wy_lieap_countable_income.yaml | 41 ++- .../wy/dfs/lieap/wy_lieap_household_size.yaml | 2 +- .../wy/dfs/lieap/wy_lieap_income_limit.yaml | 16 +- .../gov/states/wy/dfs/lieap/wy_lieap.py | 55 ++-- .../wy/dfs/lieap/wy_lieap_countable_income.py | 22 +- .../states/wy/dfs/lieap/wy_lieap_eligible.py | 29 +- .../gov/states/wy/dfs/lieap/wy_lieap_fpg.py | 3 +- .../wy/dfs/lieap/wy_lieap_household_size.py | 2 +- .../wy/dfs/lieap/wy_lieap_income_limit.py | 9 +- source_conflicts/candidates.yaml | 104 +++++-- 22 files changed, 450 insertions(+), 197 deletions(-) diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_income_min_age.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_income_min_age.yaml index 0e0fd67ef7b..bbf61a8b0c4 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_income_min_age.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_income_min_age.yaml @@ -1,6 +1,7 @@ description: Wyoming counts earnings from people at or above this age under the Low Income Energy Assistance Program. -# Approved convention follows the plan's unchecked under-18 earnings category. -# The adopted rule excludes only under-14 earnings or under-18 student earnings. +# Follows FY2026 plan section 1.9, which leaves the earned income of a child +# under 18 unchecked; rule 8(a)(ii)(A) exempts only the earnings of a child +# under 14 or of a full-time student under 18. values: 2025-10-01: 18 @@ -11,5 +12,5 @@ metadata: reference: - title: "FY2026 State Plan, section 1.9" href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=6 - - title: "LIEAP Rules, Chapter 1, section 8(a)(ii)(A)" - href: https://rules.wyo.gov/Search.aspx?mode=7 + - title: 049-1 Wyo. Code R. § 1-8(a)(ii)(A) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml index 133d2699d46..4f885c5ef44 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_sources.yaml @@ -16,5 +16,7 @@ metadata: reference: - title: "FY2026 State Plan, section 1.9 #page 5-6" href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=5 - - title: LIEAP Rules, Chapter 1, sections 3(w) and 8(a) - href: https://rules.wyo.gov/Search.aspx?mode=7 + - title: 049-1 Wyo. Code R. § 1-3(w) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-3 + - title: 049-1 Wyo. Code R. § 1-8(a) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml index da0dff1e05f..0f75fcae4f2 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml @@ -9,7 +9,7 @@ metadata: period: year label: Wyoming LIEAP poverty guideline year lag reference: - - title: "LIEAP Rules, Chapter 1, section 8(a)(ii)(S)" - href: https://rules.wyo.gov/Search.aspx?mode=7 + - title: 049-1 Wyo. Code R. § 1-8(a)(ii)(S) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8 - title: "FY2026 State Plan, fiscal-year dates" href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/gift_monthly_threshold.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/gift_monthly_threshold.yaml index b366d4448fb..f020a3d4644 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/gift_monthly_threshold.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/gift_monthly_threshold.yaml @@ -7,5 +7,5 @@ metadata: period: month label: Wyoming LIEAP monthly gift threshold reference: - - title: "LIEAP Rules, Chapter 1, section 8(a)(ii)(D)" - href: https://rules.wyo.gov/Search.aspx?mode=7 + - title: 049-1 Wyo. Code R. § 1-8(a)(ii)(D) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/interest_monthly_threshold.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/interest_monthly_threshold.yaml index 28a3d724fc6..c8b033dea14 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/interest_monthly_threshold.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/interest_monthly_threshold.yaml @@ -7,5 +7,5 @@ metadata: period: month label: Wyoming LIEAP monthly interest threshold reference: - - title: "LIEAP Rules, Chapter 1, section 8(a)(i)(A)" - href: https://rules.wyo.gov/Search.aspx?mode=7 + - title: 049-1 Wyo. Code R. § 1-8(a)(i)(A) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml index f3279445873..9da8788837c 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml @@ -29,6 +29,9 @@ values: # Social Security is counted in the formula, net of the Medicare Part B # premium deducted from it (rules 8(a)(ii)(U)). # Contract payments and royalties lack dedicated inputs and are not imputed. +# wy_ssp is left out because rule 8(a)(ii)(U) exempts "The optional State +# Medicaid Supplement Benefit", the $20 State Supplemental Payment that +# Wyoming EOM M1804 pays to receive federal match for Medicaid. metadata: unit: list period: year @@ -36,5 +39,5 @@ metadata: reference: - title: "FY2026 State Plan, section 1.9 #page 5-6" href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=5 - - title: LIEAP Rules, Chapter 1, section 8(a) - href: https://rules.wyo.gov/Search.aspx?mode=7 + - title: 049-1 Wyo. Code R. § 1-8(a) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/veterans_fpg_rate.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/veterans_fpg_rate.yaml index f95fa7ed797..e9fb9f452bc 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/veterans_fpg_rate.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/income/veterans_fpg_rate.yaml @@ -1,5 +1,5 @@ description: Wyoming excludes veterans disability benefits up to this share of the federal poverty guideline under the Low Income Energy Assistance Program. -# Approved assumptions: one household-size exclusion per SPM unit and +# Modeling assumptions: one household-size exclusion per SPM unit and # total veterans_benefits as the proxy for service-connected disability income. # The rule does not settle multiple recipients, and the proxy can exclude # other VA benefits that the service-connected rule does not cover. @@ -11,5 +11,5 @@ metadata: period: year label: Wyoming LIEAP veterans income exclusion rate reference: - - title: "LIEAP Rules, Chapter 1, section 8(a)(ii)(S)" - href: https://rules.wyo.gov/Search.aspx?mode=7 + - title: 049-1 Wyo. Code R. § 1-8(a)(ii)(S) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml index 024f4642db4..85694cd93a4 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/entitlement_fraction.yaml @@ -1,10 +1,12 @@ description: Wyoming applies these modeled entitlement fractions by household income relative to the income limit under the Low Income Energy Assistance Program. -# Approved convention: compare the unrounded ratio with inclusive upper -# bounds .21, .26, .31, ... .86, then 1.00. The formula compares equivalent -# income ceilings at the precision of stored monetary inputs. -# These assumptions bridge gaps in the printed matrix; they are not recovered -# agency rounding instructions. The positive band at exactly 1.00 is the -# stated extension of the user's pattern and differs from the printed zero. +# Table 1 prints rows "0 - .20", ".21- .25", ... ".86 - .99" and "1.00 +". +# Each threshold is the printed start of its row, so a ratio exactly at a +# start takes that row's fraction and a ratio of 1.00 or more takes zero. +# A ratio between printed rows takes the earlier row (.205 takes the +# "0 - .20" fraction), as if truncated to two decimals; the matrix gives no +# rounding instruction. +# The formula compares equivalent income ceilings at the precision of stored +# monetary inputs. brackets: - threshold: 2025-10-01: -.inf @@ -80,3 +82,5 @@ metadata: reference: - title: FY2026 Benefit Matrix, visible Table 1 on all fuel worksheets href: https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx + - title: 049-1 Wyo. Code R. § 1-10(c) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-10 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/fuel_cost.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/fuel_cost.yaml index a1b47c58279..4aeaa8f7500 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/fuel_cost.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/fuel_cost.yaml @@ -1,7 +1,13 @@ description: Wyoming uses these seasonal primary fuel cost standards under the Low Income Energy Assistance Program. # Exact source cells retain electricity and natural-gas decimals. -# Zero entries mean no verified mapping to the six published fuel standards; -# they do not establish legal ineligibility. Kerosene is not silently mapped. +# KEROSENE takes the heating oil standard: rule 3(hh) lists diesel and oil +# fuel types, the oil worksheet is "Diesel Heating Oil", and heating_expense +# reads a kerosene bill as fuel_oil_expense. +# SOLAR takes the electricity standard because heating_expense reads a solar +# home's bill as its grid electricity bill. +# OTHER takes the wood standard as the closest published worksheet. DFS pays +# unregulated and other fuel types (plan section 2.3; DFS LIEAP page) but +# publishes standards only for the six worksheets. UNSPECIFIED: 2025-10-01: 0 ELECTRICITY: @@ -11,7 +17,7 @@ NATURAL_GAS: FUEL_OIL: 2025-10-01: 2_640 KEROSENE: - 2025-10-01: 0 + 2025-10-01: 2_640 PROPANE: 2025-10-01: 1_300 WOOD: @@ -19,9 +25,9 @@ WOOD: COAL: 2025-10-01: 525 SOLAR: - 2025-10-01: 0 + 2025-10-01: 1_712.997 OTHER: - 2025-10-01: 0 + 2025-10-01: 1_225 NONE: 2025-10-01: 0 @@ -34,3 +40,11 @@ metadata: reference: - title: FY2026 Benefit Matrix, Coal H10, Heating Oil H10, Electric H10, Natural Gas H10, Propane F9, Wood H9 href: https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx + - title: 049-1 Wyo. Code R. § 1-3(hh) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-3 + - title: FY2026 State Plan, section 2.3 + href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=9 + - title: Wyoming DFS, Low Income Energy Assistance Program (LIEAP) + href: https://dfs.wyo.gov/assistance-programs/home-utilities-energy-assistance/low-income-energy-assistance-program-lieap/ + - title: Wyoming DFS, About LIEAP handout (September 24, 2026) + href: https://dfs.wyo.gov/wp-content/uploads/2026/09/2026-0924-LIEAP-About-handout.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/minimum_payment.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/minimum_payment.yaml index e80cc2f1296..ed17356f870 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/minimum_payment.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/payment/minimum_payment.yaml @@ -8,5 +8,5 @@ metadata: period: year label: Wyoming LIEAP minimum authorized payment reference: - - title: "LIEAP Rules, Chapter 1, section 10(d)" - href: https://rules.wyo.gov/Search.aspx?mode=7 + - title: 049-1 Wyo. Code R. § 1-10(d) + href: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-10 diff --git a/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml b/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml index 7795afbb3bd..4146ac9ad42 100644 --- a/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml +++ b/policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml @@ -1,7 +1,11 @@ description: Wyoming uses this share of state median income for its ordinary income limit under the Low Income Energy Assistance Program. -# The FY2026 plan uses 60% SMI. Current Title 42 retains its eligibility -# guarantee at the lesser of 215% FPG or 60% SMI and permits federal-compliance -# modifications. Federal 110% FPG income protection is applied separately. +# The FY2026 plan uses 60% SMI for every household size. W.S. 42-2-501(c) +# requires eligibility up to the lesser of 215% FPG or 60% of state median +# household income, read here as a coverage minimum that a 60% SMI limit +# always meets. 2017 SF0063 replaced "greater" with "lesser" after a 2016 DFS +# request to drop the 215% clause; rules 3(oo) and 7(a)(ii) date from the +# earlier "greater of" text. Federal 110% FPG income protection is applied +# separately. values: 2025-10-01: 0.6 @@ -14,3 +18,5 @@ metadata: href: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8 - title: "Wyoming Statutes, Title 42, section 42-2-501(c)-(d) #page 34-35" href: https://wyoleg.gov/statutes/compress/title42.pdf#page=34 + - title: "2017 Wyo. Sess. Laws, SF0063 (Enrolled Act 43), amending W.S. 42-2-501(c) #page 7-8" + href: https://wyoleg.gov/2017/Enroll/SF0063.pdf#page=7 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml index 05e037752d4..6267befb8f6 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap.yaml @@ -1,6 +1,6 @@ # All 96 FY2026 visible workbook values independently reconciled in source research. -# Ratios are inside the approved bands. The zero row uses 1.01 because the -# approved convention pays the last positive fraction at exactly 1.00. +# Ratios fall inside the printed Table 1 rows. The zero-row cases use 1.01, +# above the limit; Case 125 pins the "1.00 +" row at exactly 1.00. # https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx - name: Case 1, coal published share 0.8 at ratio 0. @@ -1347,10 +1347,11 @@ output: wy_lieap: 0.0 -- name: Case 97, oil at inclusive ratio boundary .21. +- name: Case 97, oil exactly at the .21 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .21 pays .75; no ratio rounding. + # 2,640 * .75 = 1,980; 1,980 - 198 = 1,782. input: state_code: WY wy_lieap_household_size: 1 @@ -1359,12 +1360,12 @@ wy_lieap_countable_income: 21000 heating_type: FUEL_OIL output: - wy_lieap: 1901.00 + wy_lieap: 1782.00 -- name: Case 98, oil just above inclusive ratio boundary .21. +- name: Case 98, oil just above the .21 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1375,10 +1376,11 @@ output: wy_lieap: 1782.00 -- name: Case 99, oil at inclusive ratio boundary .26. +- name: Case 99, oil exactly at the .26 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .26 pays .70; no ratio rounding. + # 2,640 * .70 = 1,848; 1,848 - 185 = 1,663. input: state_code: WY wy_lieap_household_size: 1 @@ -1387,12 +1389,12 @@ wy_lieap_countable_income: 26000 heating_type: FUEL_OIL output: - wy_lieap: 1782.00 + wy_lieap: 1663.00 -- name: Case 100, oil just above inclusive ratio boundary .26. +- name: Case 100, oil just above the .26 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1403,10 +1405,11 @@ output: wy_lieap: 1663.00 -- name: Case 101, oil at inclusive ratio boundary .31. +- name: Case 101, oil exactly at the .31 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .31 pays .65; no ratio rounding. + # 2,640 * .65 = 1,716; 1,716 - 172 = 1,544. input: state_code: WY wy_lieap_household_size: 1 @@ -1415,12 +1418,12 @@ wy_lieap_countable_income: 31000 heating_type: FUEL_OIL output: - wy_lieap: 1663.00 + wy_lieap: 1544.00 -- name: Case 102, oil just above inclusive ratio boundary .31. +- name: Case 102, oil just above the .31 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1431,10 +1434,11 @@ output: wy_lieap: 1544.00 -- name: Case 103, oil at inclusive ratio boundary .36. +- name: Case 103, oil exactly at the .36 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .36 pays .60; no ratio rounding. + # 2,640 * .60 = 1,584; 1,584 - 158 = 1,426. input: state_code: WY wy_lieap_household_size: 1 @@ -1443,12 +1447,12 @@ wy_lieap_countable_income: 36000 heating_type: FUEL_OIL output: - wy_lieap: 1544.00 + wy_lieap: 1426.00 -- name: Case 104, oil just above inclusive ratio boundary .36. +- name: Case 104, oil just above the .36 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1459,10 +1463,11 @@ output: wy_lieap: 1426.00 -- name: Case 105, oil at inclusive ratio boundary .41. +- name: Case 105, oil exactly at the .41 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .41 pays .55; no ratio rounding. + # 2,640 * .55 = 1,452; 1,452 - 145 = 1,307. input: state_code: WY wy_lieap_household_size: 1 @@ -1471,12 +1476,12 @@ wy_lieap_countable_income: 41000 heating_type: FUEL_OIL output: - wy_lieap: 1426.00 + wy_lieap: 1307.00 -- name: Case 106, oil just above inclusive ratio boundary .41. +- name: Case 106, oil just above the .41 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1487,10 +1492,11 @@ output: wy_lieap: 1307.00 -- name: Case 107, oil at inclusive ratio boundary .46. +- name: Case 107, oil exactly at the .46 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .46 pays .50; no ratio rounding. + # 2,640 * .50 = 1,320; 1,320 - 132 = 1,188. input: state_code: WY wy_lieap_household_size: 1 @@ -1499,12 +1505,12 @@ wy_lieap_countable_income: 46000 heating_type: FUEL_OIL output: - wy_lieap: 1307.00 + wy_lieap: 1188.00 -- name: Case 108, oil just above inclusive ratio boundary .46. +- name: Case 108, oil just above the .46 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1515,10 +1521,11 @@ output: wy_lieap: 1188.00 -- name: Case 109, oil at inclusive ratio boundary .51. +- name: Case 109, oil exactly at the .51 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .51 pays .45; no ratio rounding. + # 2,640 * .45 = 1,188; 1,188 - 119 = 1,069. input: state_code: WY wy_lieap_household_size: 1 @@ -1527,12 +1534,12 @@ wy_lieap_countable_income: 51000 heating_type: FUEL_OIL output: - wy_lieap: 1188.00 + wy_lieap: 1069.00 -- name: Case 110, oil just above inclusive ratio boundary .51. +- name: Case 110, oil just above the .51 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1543,10 +1550,11 @@ output: wy_lieap: 1069.00 -- name: Case 111, oil at inclusive ratio boundary .56. +- name: Case 111, oil exactly at the .56 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .56 pays .40; no ratio rounding. + # 2,640 * .40 = 1,056; 1,056 - 106 = 950. input: state_code: WY wy_lieap_household_size: 1 @@ -1555,12 +1563,12 @@ wy_lieap_countable_income: 56000 heating_type: FUEL_OIL output: - wy_lieap: 1069.00 + wy_lieap: 950.00 -- name: Case 112, oil just above inclusive ratio boundary .56. +- name: Case 112, oil just above the .56 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1571,10 +1579,11 @@ output: wy_lieap: 950.00 -- name: Case 113, oil at inclusive ratio boundary .61. +- name: Case 113, oil exactly at the .61 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .61 pays .35; no ratio rounding. + # 2,640 * .35 = 924; 924 - 92 = 832. input: state_code: WY wy_lieap_household_size: 1 @@ -1583,12 +1592,12 @@ wy_lieap_countable_income: 61000 heating_type: FUEL_OIL output: - wy_lieap: 950.00 + wy_lieap: 832.00 -- name: Case 114, oil just above inclusive ratio boundary .61. +- name: Case 114, oil just above the .61 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1599,10 +1608,11 @@ output: wy_lieap: 832.00 -- name: Case 115, oil at inclusive ratio boundary .66. +- name: Case 115, oil exactly at the .66 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .66 pays .30; no ratio rounding. + # 2,640 * .30 = 792; 792 - 79 = 713. input: state_code: WY wy_lieap_household_size: 1 @@ -1611,12 +1621,12 @@ wy_lieap_countable_income: 66000 heating_type: FUEL_OIL output: - wy_lieap: 832.00 + wy_lieap: 713.00 -- name: Case 116, oil just above inclusive ratio boundary .66. +- name: Case 116, oil just above the .66 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1627,10 +1637,11 @@ output: wy_lieap: 713.00 -- name: Case 117, oil at inclusive ratio boundary .71. +- name: Case 117, oil exactly at the .71 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .71 pays .25; no ratio rounding. + # 2,640 * .25 = 660; 660 - 66 = 594. input: state_code: WY wy_lieap_household_size: 1 @@ -1639,12 +1650,12 @@ wy_lieap_countable_income: 71000 heating_type: FUEL_OIL output: - wy_lieap: 713.00 + wy_lieap: 594.00 -- name: Case 118, oil just above inclusive ratio boundary .71. +- name: Case 118, oil just above the .71 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1655,10 +1666,11 @@ output: wy_lieap: 594.00 -- name: Case 119, oil at inclusive ratio boundary .76. +- name: Case 119, oil exactly at the .76 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .76 pays .20; no ratio rounding. + # 2,640 * .20 = 528; 528 - 53 = 475. input: state_code: WY wy_lieap_household_size: 1 @@ -1667,12 +1679,12 @@ wy_lieap_countable_income: 76000 heating_type: FUEL_OIL output: - wy_lieap: 594.00 + wy_lieap: 475.00 -- name: Case 120, oil just above inclusive ratio boundary .76. +- name: Case 120, oil just above the .76 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1683,10 +1695,11 @@ output: wy_lieap: 475.00 -- name: Case 121, oil at inclusive ratio boundary .81. +- name: Case 121, oil exactly at the .81 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .81 pays .15; no ratio rounding. + # 2,640 * .15 = 396; 396 - 40 = 356. input: state_code: WY wy_lieap_household_size: 1 @@ -1695,12 +1708,12 @@ wy_lieap_countable_income: 81000 heating_type: FUEL_OIL output: - wy_lieap: 475.00 + wy_lieap: 356.00 -- name: Case 122, oil just above inclusive ratio boundary .81. +- name: Case 122, oil just above the .81 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1711,10 +1724,11 @@ output: wy_lieap: 356.00 -- name: Case 123, oil at inclusive ratio boundary .86. +- name: Case 123, oil exactly at the .86 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # The printed row starting at .86 pays .10; no ratio rounding. + # 2,640 * .10 = 264; 264 - 26 = 238. input: state_code: WY wy_lieap_household_size: 1 @@ -1723,12 +1737,12 @@ wy_lieap_countable_income: 86000 heating_type: FUEL_OIL output: - wy_lieap: 356.00 + wy_lieap: 238.00 -- name: Case 124, oil just above inclusive ratio boundary .86. +- name: Case 124, oil just above the .86 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1739,10 +1753,10 @@ output: wy_lieap: 238.00 -- name: Case 125, oil at inclusive ratio boundary 1.00. +- name: Case 125, oil exactly at the 1.00 Table 1 row start pays zero. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Income at the limit is eligible, but the printed "1.00 +" row pays 0. input: state_code: WY wy_lieap_household_size: 1 @@ -1751,12 +1765,12 @@ wy_lieap_countable_income: 100000 heating_type: FUEL_OIL output: - wy_lieap: 238.00 + wy_lieap: 0 -- name: Case 126, oil just above inclusive ratio boundary 1.00. +- name: Case 126, oil just above the 1.00 Table 1 row start. period: 2026 absolute_error_margin: 0.001 - # Approved convention; no ratio rounding. + # Table 1 rows start at their printed ratios; no ratio rounding. input: state_code: WY wy_lieap_household_size: 1 @@ -1879,10 +1893,12 @@ output: wy_lieap: 0 -- name: Case 135, kerosene has no supported FY2026 fuel standard. +- name: Case 135, kerosene uses the heating oil standard. period: 2026 absolute_error_margin: 0.001 - # Zero for unsupported fuel does not establish legal ineligibility. + # Rule 3(hh) lists diesel and oil fuel types; the oil worksheet is + # "Diesel Heating Oil". Ratio 0 pays .80: 2,640 * .80 = 2,112; + # 2,112 - round_half_up(211.2) = 1,901, below the 5,000 cost. input: state_code: WY wy_lieap_household_size: 1 @@ -1891,12 +1907,14 @@ wy_lieap_countable_income: 0 heating_type: KEROSENE output: - wy_lieap: 0 + wy_lieap: 1901 -- name: Case 136, solar has no supported FY2026 fuel standard. +- name: Case 136, solar uses the electricity standard. period: 2026 absolute_error_margin: 0.001 - # Zero for unsupported fuel does not establish legal ineligibility. + # heating_expense reads a solar home's bill as its grid electricity bill. + # Ratio 0 pays .80: 1,712.997 * .80 = 1,370.3976; + # 1,370.3976 - round_half_up(137.03976) = 1,233.3976, below the 5,000 cost. input: state_code: WY wy_lieap_household_size: 1 @@ -1905,12 +1923,14 @@ wy_lieap_countable_income: 0 heating_type: SOLAR output: - wy_lieap: 0 + wy_lieap: 1233.3976 -- name: Case 137, other has no supported FY2026 fuel standard. +- name: Case 137, other fuel uses the wood standard as the closest published worksheet. period: 2026 absolute_error_margin: 0.001 - # Zero for unsupported fuel does not establish legal ineligibility. + # DFS serves other fuel types but publishes six worksheets; the wood + # standard is the closest. Ratio 0 pays .80: 1,225 * .80 = 980; + # 980 - round_half_up(98) = 882, below the 5,000 cost. input: state_code: WY wy_lieap_household_size: 1 @@ -1919,7 +1939,7 @@ wy_lieap_countable_income: 0 heating_type: OTHER output: - wy_lieap: 0 + wy_lieap: 882 - name: Case 138, negative countable income does not inflate the maximum. period: 2026 @@ -2093,7 +2113,7 @@ # passes the $10 cutoff and is then limited to its $9 bill. wy_lieap: [209.6275, 0, 9, 0] -- name: Case 148, real FY2026 incomes a cent below every band ceiling preserve inclusive selection. +- name: Case 148, real FY2026 incomes a cent below every Table 1 row start stay in the preceding row. period: 2026 input: people: @@ -2161,12 +2181,13 @@ household14: {members: [person14], state_code: WY} household15: {members: [person15], state_code: WY} output: - # Each one-person limit is $35,829. Apply the approved .21, .26, ..., - # .86, 1.00 ceilings to actual wages, then the $2,640 oil standard - # and the workbook's rounded 10 percent holdback. + # Each one-person limit is $35,829, so the rows start at $35,829 times + # .21, .26, ..., .86 and 1.00, in cents. Wages a cent below a start stay + # in the preceding row, then the $2,640 oil standard and the workbook's + # rounded 10 percent holdback apply (person1: .80, 2,112 - 211 = 1,901). wy_lieap: [1901, 1782, 1663, 1544, 1426, 1307, 1188, 1069, 950, 832, 713, 594, 475, 356, 238] -- name: Case 149, real FY2026 incomes exactly at every band ceiling preserve inclusive selection. +- name: Case 149, real FY2026 incomes exactly at every Table 1 row start take that row. period: 2026 input: people: @@ -2234,12 +2255,15 @@ household14: {members: [person14], state_code: WY} household15: {members: [person15], state_code: WY} output: - # Each one-person limit is $35,829. Apply the approved .21, .26, ..., - # .86, 1.00 ceilings to actual wages, then the $2,640 oil standard - # and the workbook's rounded 10 percent holdback. - wy_lieap: [1901, 1782, 1663, 1544, 1426, 1307, 1188, 1069, 950, 832, 713, 594, 475, 356, 238] + # Each one-person limit is $35,829, so the rows start at $35,829 times + # .21, .26, ..., .86 and 1.00, in cents. Wages exactly at a start take + # that row, then the $2,640 oil standard and the workbook's rounded + # 10 percent holdback apply (person1: .75, 1,980 - 198 = 1,782; + # person14: .10, 264 - 26 = 238). Person15 at the limit is eligible, + # but the "1.00 +" row pays 0. + wy_lieap: [1782, 1663, 1544, 1426, 1307, 1188, 1069, 950, 832, 713, 594, 475, 356, 238, 0] -- name: Case 150, real FY2026 incomes a cent above every band ceiling preserve inclusive selection. +- name: Case 150, real FY2026 incomes a cent above every Table 1 row start take that row. period: 2026 input: people: @@ -2307,9 +2331,10 @@ household14: {members: [person14], state_code: WY} household15: {members: [person15], state_code: WY} output: - # Each one-person limit is $35,829. Apply the approved .21, .26, ..., - # .86, 1.00 ceilings to actual wages, then the $2,640 oil standard - # and the workbook's rounded 10 percent holdback. + # Each one-person limit is $35,829, so the rows start at $35,829 times + # .21, .26, ..., .86 and 1.00, in cents. Wages a cent above a start stay + # in that row, then the $2,640 oil standard and the workbook's rounded + # 10 percent holdback apply. Person15 is above the limit and ineligible. wy_lieap: [1782, 1663, 1544, 1426, 1307, 1188, 1069, 950, 832, 713, 594, 475, 356, 238, 0] # 42 USC 8624(b)(2)(B): income LESS THAN 110% of the 2025 guideline is @@ -2408,3 +2433,48 @@ wy_lieap_income_limit: 35_829 wy_lieap_eligible: true wy_lieap: 139.085 + +# Rule 3(hh) lists diesel and oil fuel types, and heating_expense reads a +# kerosene bill as fuel_oil_expense, so the $2,640 oil standard applies. +# 20,000 / 35,829 = .558 is below the .56 row start ($20,064.24), so the +# .51-.55 row pays .45: 2,640 * .45 = 1,188; +# 1,188 - round_half_up(118.8) = 1,069, below the $1,500 bill. +- name: Case 155, a kerosene bill uses the heating oil standard. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: WY + age: 40 + immigration_status: CITIZEN + employment_income: 20_000 + ssi: 0 + heating_type: KEROSENE + fuel_oil_expense: 1_500 + output: + heating_expense: 1_500 + wy_lieap_countable_income: 20_000 + wy_lieap_income_limit: 35_829 + wy_lieap_eligible: true + wy_lieap: 1_069 + +# Rules 3(kk), 8(b)(i)(B) and 10(e) and plan section 2.3 serve a renter +# whose heat is included in rent on the standard benefit formula. With no +# separate gas bill, heating_expense is 0 and no bill caps the award. +# 20,000 / 35,829 = .558 takes the .45 fraction: 1,550.85 * .45 = 697.8825; +# 697.8825 - round_half_up(69.78825) = 697.8825 - 70 = 627.8825. +- name: Case 156, heat included in rent with no separate bill receives the standard gas formula. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: WY + age: 40 + immigration_status: CITIZEN + employment_income: 20_000 + ssi: 0 + heating_type: NATURAL_GAS + heat_expense_included_in_rent: true + output: + heating_expense: 0 + wy_lieap_countable_income: 20_000 + wy_lieap_eligible: true + wy_lieap: 627.8825 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_countable_income.yaml index c571d2208f7..bc541481267 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_countable_income.yaml @@ -1,4 +1,4 @@ -# Income conventions approved October 6, 2026. Annual inputs approximate monthly income. +# Modeling assumption: annual inputs approximate monthly income. # FY2026 plan section 1.9 and adopted rule section 8: the plan excludes minors, # TANF and child support; the rule excludes lump sums. Conflicts remain documented. @@ -260,3 +260,42 @@ employment_income: 20_000 output: wy_lieap_countable_income: 0 + +# Each listed source gets a distinct amount, so dropping any one changes the +# total. Earned: 1,000 + 2,000 + 3,000 + 4,000 = 10,000 for an adult. +# Unearned: 500 + 600 + 700 = 1,800. Countable: 10,000 + 1,800 = 11,800. +- name: Case 23, business, farm, partnership, workers compensation, disability and estate income each count. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: WY + ssi: 0 + age: 40 + self_employment_income: 1_000 + sstb_self_employment_income: 2_000 + farm_operations_income: 3_000 + partnership_s_corp_income: 4_000 + workers_compensation: 500 + disability_benefits: 600 + estate_income: 700 + output: + wy_lieap_countable_income: 11_800 + +# Rule 8(a)(ii)(U) exempts Medicare deducted from SSA. The 2026 Part B +# premium is 202.90 * 12 = 2,434.80. It is entered directly because at this +# income a Medicare Savings Program would pay it; Case 154 in wy_lieap.yaml +# derives the premium for a person who pays it. Social Security counts as +# max(1,000 - 2,434.80, 0) = 0, and the excess premium cannot reduce wages: +# 10,000 + 0 = 10,000. +- name: Case 24, a Part B premium above Social Security cannot reduce other income. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: WY + ssi: 0 + age: 70 + employment_income: 10_000 + social_security: 1_000 + medicare_part_b_premium: 2_434.8 + output: + wy_lieap_countable_income: 10_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_household_size.yaml index 076a3adcbcd..138c3c4dffb 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_household_size.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_household_size.yaml @@ -1,4 +1,4 @@ -# Approved modeling convention: count citizens and qualified noncitizens within +# Modeling assumption: count citizens and qualified noncitizens within # each SPM unit. Wyoming's FY2026 plan, section 17.3, establishes status # verification but does not specify mixed-status household-size calculations. # https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=38 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_income_limit.yaml index 4ab9a7328bb..cc45d2a35d0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_income_limit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/wy_lieap_income_limit.yaml @@ -68,7 +68,9 @@ state_code: WY wy_lieap_household_size: 8 output: - wy_lieap_income_limit: 95085 + # floor(114,837 * .6) = 68,902; size factor .52 + 5 * .16 + 2 * .03 = 1.38; + # floor(68,902 * 1.38) = floor(95,084.76) = 95,084 (HHS FY2026 table). + wy_lieap_income_limit: 95084 - name: Case 10, FY2027 income limit for 1 qualifying members only. period: 2027 @@ -109,3 +111,15 @@ wy_lieap_household_size: 5 output: wy_lieap_income_limit: 79992 + +# HHS LIHEAP IM 2025-02 Attachment 4 prints $99,218 for 10 Wyoming members. +# floor(114,837 * .6) = 68,902; size factor .52 + 5 * .16 + 4 * .03 = 1.44; +# floor(68,902 * 1.44) = floor(99,218.88) = 99,218. +- name: Case 15, FY2026 income limit for 10 qualifying members. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: WY + wy_lieap_household_size: 10 + output: + wy_lieap_income_limit: 99_218 diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py index 780cced4fb6..75eaa9b9465 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py @@ -10,18 +10,32 @@ class wy_lieap(Variable): documentation = ( "Regular FY2026 heating assistance. SPM units approximate shared-heat " "households and report their own eligible seasonal primary heating cost. " - "Approved income bands use inclusive upper bounds without ratio rounding; " - "mixed-status households use qualified-member size, all otherwise countable " - "income and no additional proration. Renters use the same schedule. " - "Zero may indicate an unsupported fuel or missing eligible heating cost. " - "Federal-floor households use the approved income-to-effective-limit " - "ratio convention; their exact agency payment method is unverified. " - "Years outside FY2026 are unverified estimates, including backfilled years." + "Each printed Table 1 row starts at its listed ratio, so a ratio exactly " + "at .21 takes the .21-.25 fraction and a ratio of 1.00 or more takes the " + "1.00+ zero; a ratio between printed rows takes the earlier row, as if " + "truncated to two decimals. Mixed-status households use qualified-member " + "size, all otherwise countable income and no additional proration. " + "Renters use the same schedule (rule 10(e)). The award is capped at a " + "reported heating expense; a household whose heat is included in rent " + "and reports no separate bill receives the standard formula for its " + "fuel. Zero may indicate an unspecified fuel or missing heating " + "responsibility. Federal-floor households take the fraction for their " + "income relative to the raised limit, a modeling assumption; their exact " + "agency payment method is unverified. Years outside FY2026 are " + "unverified estimates, including backfilled years." ) reference = ( "https://liheapch.acf.gov/docs/2026/benefits-matricies/WY_BenefitMatrix_2026.xlsx", - # Chapter 1, sections 10(d)-(e) and 13(b)(i), physical page 16. - "https://rules.wyo.gov/Search.aspx?mode=7", + # Rules 3(cc) and 3(kk). + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-3", + # Rule 8(b)(i)(B). + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8", + # Rules 10(c)-(e). + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-10", + # Rule 13(b)(i). + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-13", + # FY2026 State Plan, section 2.3. + "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8", "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", ) defined_for = "wy_lieap_eligible" @@ -34,14 +48,17 @@ def formula(spm_unit, period, parameters): guideline = spm_unit("wy_lieap_fpg", period).astype(np.float64) federal_floor = np.round(guideline * floor_rate, 2) limit = max_(limit, federal_floor) - # Express each inclusive ceiling at the stored income precision. + # Table 1 prints rows "0 - .20", ".21- .25", ... ".86 - .99" and + # "1.00 +", so each listed ratio starts its row. Income below the + # ceiling at a row's start stays in the preceding, higher-paying row. + # The ceilings are kept at the precision of stored monetary inputs. scale = p.entitlement_fraction ceilings = [ (max_(limit, 1).astype(np.float64) * threshold).astype(income.dtype) for threshold in scale.thresholds[1:] ] fraction = select( - [income <= ceiling for ceiling in ceilings], + [income < ceiling for ceiling in ceilings], scale.amounts[:-1], default=scale.amounts[-1], ) @@ -50,11 +67,11 @@ def formula(spm_unit, period, parameters): # The workbook rounds only the withheld amount, half-up to dollars. withheld = np.floor(base * p.holdback_rate + 0.5) adjusted_benefit = base - withheld - # Rules 10(d) bar a computed benefit below the minimum before - # 13(b)(i) limits payment to the actual primary fuel cost. - expense = max_(spm_unit("heating_expense", period), 0) - return where( - adjusted_benefit >= p.minimum_payment, - min_(adjusted_benefit, expense), - 0, - ) + # Rule 10(d) bars a computed benefit below the minimum before rule + # 13(b)(i) limits payment to the actual primary fuel cost. Rule 10(e) + # pays a renter whose heat is included in rent on the standard + # formula, so the cost cap applies only when a heating bill is + # reported. + expense = spm_unit("heating_expense", period) + payment = where(expense > 0, min_(adjusted_benefit, expense), adjusted_benefit) + return where(adjusted_benefit >= p.minimum_payment, payment, 0) diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py index dd3b47aba5c..c79b2d9854b 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py @@ -10,10 +10,12 @@ class wy_lieap_countable_income(Variable): documentation = ( "Annual income approximates current monthly income. All members' otherwise " "countable income is retained, including members excluded from household " - "size by immigration status. Under approved assumptions, all under-18 " - "earnings, TANF, child support received and identifiable lump sums are " - "excluded. Total veterans benefits proxy service-connected disability " - "payments and receive one household-size poverty exclusion per SPM unit. " + "size by immigration status. Following FY2026 plan section 1.9, all " + "under-18 earnings, TANF and child support received are excluded; " + "identifiable lump sums are excluded under rule 8(a)(ii)(L). As a " + "modeling assumption, total veterans benefits proxy service-connected " + "disability payments and receive one household-size poverty exclusion " + "per SPM unit. " "This proxy can understate income from other kinds of VA benefits. " "Annual source inputs cannot distinguish embedded lump sums, exempt " "reimbursements or irregular receipts; supply countable income directly " @@ -21,10 +23,12 @@ class wy_lieap_countable_income(Variable): "Medicare Part B premium the person pays." ) reference = ( - # Section 1.9; minor-earnings/lump-sum conflicts documented. - "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=6", - # Current chapter 1, section 8(a), PDF pages 11-13. - "https://rules.wyo.gov/Search.aspx?mode=7", + # FY2026 State Plan, section 1.9, PDF pages 5-6. + "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=5", + # Rules 3(w) and 3(nn). + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-3", + # Rule 8(a). + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8", ) defined_for = StateCode.WY @@ -64,7 +68,7 @@ def formula(spm_unit, period, parameters): gifts > p.gift_monthly_threshold * MONTHS_IN_YEAR, gifts, 0 ) guideline = spm_unit("wy_lieap_fpg", period) - # Approved approximation: total VA income, one exclusion per SPM unit. + # Modeling assumption: total VA income, one exclusion per SPM unit. # Do not apply a separate allowance to each veteran, spouse or dependent. veterans = spm_unit.sum(max_(person("veterans_benefits", period), 0)) veterans_exclusion = guideline * p.veterans_fpg_rate diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py index db3c549561c..f7c5bfc379d 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py @@ -8,15 +8,21 @@ class wy_lieap_eligible(Variable): label = "Eligible for modeled Wyoming LIEAP" documentation = ( "Models residence, qualifying-member count, income and primary heating " - "responsibility. Positive reported heating expense represents the unit's " - "eligible seasonal bill or documented heat-in-rent share. Winter presence, " - "work registration, tribal program routing, institutional exclusions and " - "application verification are not separately observed." + "responsibility. A positive reported heating expense, or heat included " + "in rent, establishes responsibility for the primary heating cost. " + "Winter presence, work registration, tribal program routing, " + "institutional exclusions and application verification are not " + "separately observed." ) reference = ( - "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8", - # Chapter 1, sections 7 and 8(b). - "https://rules.wyo.gov/Search.aspx?mode=7", + # FY2026 State Plan, sections 1.4, 2.1 and 2.3, PDF pages 5,8. + "https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=5", + # Rule 3(kk). + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-3", + # Rule 7. + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-7", + # Rule 8(b). + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8", "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", ) defined_for = StateCode.WY @@ -31,5 +37,10 @@ def formula(spm_unit, period, parameters): guideline = spm_unit("wy_lieap_fpg", period).astype(np.float64) federal_floor = np.round(guideline * floor_rate, 2) income_eligible = (income <= limit) | (income < federal_floor) - expense = spm_unit("heating_expense", period) - return (size > 0) & income_eligible & (expense > 0) + # Rule 8(b)(i) makes a household vulnerable when it is billed for or + # pays its heating fuel, or when its rent includes a prorated heating + # cost; rule 3(kk) allows the energy purchase to be in the form of rent. + responsible = (spm_unit("heating_expense", period) > 0) | spm_unit( + "heat_expense_included_in_rent", period + ) + return (size > 0) & income_eligible & responsible diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_fpg.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_fpg.py index 73165fe000b..466696ef74a 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_fpg.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_fpg.py @@ -11,7 +11,8 @@ class wy_lieap_fpg(Variable): defined_for = StateCode.WY reference = ( "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", - "https://rules.wyo.gov/Search.aspx?mode=7", + # Rule 8(a)(ii)(S). + "https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8", ) def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_household_size.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_household_size.py index 55b414c2b19..945fb0b428c 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_household_size.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_household_size.py @@ -8,7 +8,7 @@ class wy_lieap_household_size(Variable): label = "Wyoming LIEAP household size" documentation = ( "Number of U.S. citizens and qualified noncitizens in the SPM unit. " - "Excluding other members from household size is an approved modeling " + "Excluding other members from household size is a modeling " "assumption: Wyoming's FY2026 plan requires immigration-status " "verification but does not specify mixed-status household calculations. " "The SPM unit approximates the group sharing home heating." diff --git a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py index 58e4e465f8d..44bac90ffe8 100644 --- a/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py +++ b/policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py @@ -1,5 +1,5 @@ from policyengine_us.model_api import * -from policyengine_us.variables.gov.hhs.hhs_smi import smi +from policyengine_us.variables.gov.hhs.hhs_smi import liheap_smi_limit class wy_lieap_income_limit(Variable): @@ -10,6 +10,8 @@ class wy_lieap_income_limit(Variable): label = "Wyoming LIEAP state median income limit" reference = ( "https://liheapch.acf.gov/profiles/povertytables/FY2026/wysmi.htm", + # HHS LIHEAP IM 2025-02, Attachment 4, PDF pages 3,6. + "https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf#page=3", "https://dfs.wyo.gov/wp-content/uploads/2026/09/2026-0924-LIEAP-About-handout.pdf#page=1", ) defined_for = StateCode.WY @@ -18,8 +20,5 @@ def formula(spm_unit, period, parameters): p = parameters(period).gov.states.wy.dfs.lieap size = spm_unit("wy_lieap_household_size", period) state = spm_unit.household("state_code_str", period) - # Flooring the existing federal SMI calculation reproduces the - # FY2026 and FY2027 published annual ceilings. The rounding method - # is a numerical inference, not an explicit state instruction. - limit = np.floor(smi(size, state, period, parameters) * p.smi_rate) + limit = liheap_smi_limit(size, state, p.smi_rate, period, parameters) return where(size > 0, limit, 0) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index d507adc507a..5160ede3788 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -5878,16 +5878,20 @@ candidates: statute: Income below 110% of the poverty guideline cannot by itself exclude the household. other: The 60% SMI limit falls below that floor starting at household size 17. example: A 17-person household earning $113,900 exceeds the $113,688 state limit but is below the $114,015 floor - and receives a $238 heating-oil benefit in the PR. + and receives a $238 heating-oil benefit in PE-US. pe_us: follows: statute - code: [] + code: + - policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py + - policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap.py + - policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml + - policyengine_us/parameters/gov/states/wy/dfs/lieap/income/fpg_year_lag.yaml prs: - https://github.com/PolicyEngine/policyengine-us/pull/10346 state: unreviewed - note: 'The open PR applies the federal floor and sets the benefit fraction from income relative to the raised - limit; the agency payment method for these households is unverified. Code not yet on main: wy_lieap_eligible, - wy_lieap.' + note: PE-US applies the floor to the prior year's guideline, rounded to cents, with the statute's strict "less + than" (wy_lieap_eligible.py), and sets the benefit fraction from income relative to the raised limit (wy_lieap.py); + the agency payment method for these households is unverified. - id: us-wy:lieap-income-limit-statute-lesser-of program: liheap years: @@ -5900,9 +5904,16 @@ candidates: - kind: statute citation: W.S. 42-2-501(c)-(d) url: https://wyoleg.gov/statutes/compress/title42.pdf#page=34 + - kind: statute + citation: 2017 Wyo. Sess. Laws, SF0063 (Enrolled Act 43), effective July 1, 2017, striking "greater" and inserting + "lesser" in W.S. 42-2-501(c) and changing "state median income" to "state median household income" + url: https://wyoleg.gov/2017/Enroll/SF0063.pdf#page=7 - kind: regulation - citation: Wyoming DFS LIEAP Rules, Chapter 1, sections 3(oo) and 7(a)(ii) - url: https://rules.wyo.gov/Search.aspx?mode=7 + citation: 049-1 Wyo. Code R. § 1-3(oo) + url: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-3 + - kind: regulation + citation: 049-1 Wyo. Code R. § 1-7(a)(ii) + url: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-7 - kind: plan citation: Wyoming FY2026 LIEAP State Plan, section 2.1, 60% SMI for all household sizes url: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=8 @@ -5910,22 +5921,79 @@ candidates: citation: DFS 2016 statute clean-up request, Appendix C, asking to remove the 215% clause url: https://wyoleg.gov/InterimCommittee/2016/10-0825AppendixC.pdf#page=8 readings: - statute: The state plan must cover households with incomes at or below the lesser of 215% of the poverty level - or 60% of state median income. - other: Rules 3(oo) and 7(a)(ii) treat the section 42-2-501(c) standard as the maximum income, and the FY2026 - plan applies 60% of state median income for every household size. + statute: Since the 2017 amendment, the state plan must cover households with incomes at or below the lesser of + 215% of the poverty level or 60% of state median household income, a coverage minimum that a 60% SMI limit + always meets. + other: Rules 3(oo) and 7(a)(ii), adopted under the pre-2017 "greater of" text, treat the section 42-2-501(c) + standard as the maximum income, which would cap the FY2026 plan's 60% of state median income at 215% of the + poverty level for small households. example: A one-person FY2026 household with $34,000 of countable income is above 215% of the 2025 guideline - ($33,647.50) and within 60% of state median income ($35,829), and the PR finds it income-eligible. + ($33,647.50) and within 60% of state median income ($35,829), and PE-US finds it income-eligible. pe_us: - follows: conflicting-source - code: [] + follows: statute + code: + - policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_income_limit.py + - policyengine_us/parameters/gov/states/wy/dfs/lieap/smi_rate.yaml prs: - https://github.com/PolicyEngine/policyengine-us/pull/10346 state: unreviewed - note: 'The open PR reads the statute as a coverage minimum that the plan meets and applies 60% of state median - income for every size. Under the ceiling reading, FY2026 sizes 1-3 with incomes of $33,647.50-$35,829, - $45,472.50-$46,853 and $57,297.50-$57,877 would be ineligible. No amendment history for the clause was found. - Code not yet on main: wy_lieap_income_limit, smi_rate.yaml.' + note: PE-US reads W.S. 42-2-501(c) as a coverage minimum and applies 60% of state median income for every size + (wy_lieap_income_limit.py, smi_rate.yaml). The amendment history supports that reading. Until 2017 the clause read + "greater of", which could require coverage above the federal maximum. DFS asked in 2016 to drop the 215% clause + because it uses 60% of state median income, and SF0063 then made the lesser amount the minimum. Under the ceiling + reading, FY2026 sizes 1-3 with incomes of $33,647.50-$35,829, $45,472.50-$46,853 and $57,297.50-$57,877 would be + ineligible. +- id: us-wy:lieap-plan-vs-rules-income-items + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Does Wyoming LIEAP follow the FY2026 plan or the adopted Chapter 1 rules for minors' earnings, POWER and + child support received, categorical eligibility, lump sums and child support paid? + sources: + - kind: regulation + citation: 049-1 Wyo. Code R. § 1-3(nn) + url: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-3 + - kind: regulation + citation: 049-1 Wyo. Code R. § 1-7(a)(i) + url: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-7 + - kind: regulation + citation: 049-1 Wyo. Code R. § 1-8(a)(ii)(A), (a)(ii)(L) and (a)(iii) + url: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-8 + - kind: regulation + citation: 049-1 Wyo. Code R. § 1-9(g)(ii)(B) + url: https://www.law.cornell.edu/regulations/wyoming/agency-049/subagency-0024/chapter-1/049-1-Wyo-Code-R-SSSS-1-9 + - kind: plan + citation: Wyoming FY2026 LIEAP State Plan, sections 1.4 and 1.9 + url: https://dfs.wyo.gov/wp-content/uploads/2025/10/FFY2026-LIEAP-State-Model-Plan.pdf#page=5 + readings: + statute: No statute addresses these items. The rules exempt only the earnings of a child under 14 or of a + full-time student under 18 (8(a)(ii)(A)); count "the household's total gross non-exempt money received from + any source" with no exemption for POWER or child support received (3(nn)); list adults receiving POWER, SNAP or + veteran or survivor pension payments as eligible if they meet all other factors (7(a)(i)); exempt lump sums + such as tax refunds, rebates or credits (8(a)(ii)(L)), while 9(g)(ii)(B) lists prizes, including lottery + winnings, as income evidence; and deduct court-ordered child support paid "from earnings" (8(a)(iii)). + other: The FY2026 plan leaves the earned income of a child under 18, TANF benefits and child support unchecked as + countable income and checks one-time lump sums such as rebates, credits and lottery winnings (1.9), and it + answers "No" to categorical eligibility (1.4). + example: A parent with $40,000 of wages, $8,000 of child support received and a $1,500 natural gas bill has + countable income of $40,000 under the plan, within the $46,853 two-person limit, and PE-US pays $209.63; counting + the support under rule 3(nn) gives $48,000, above the limit. + pe_us: + follows: conflicting-source + code: + - policyengine_us/parameters/gov/states/wy/dfs/lieap/income/earned_income_min_age.yaml + - policyengine_us/parameters/gov/states/wy/dfs/lieap/income/unearned_sources.yaml + - policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_countable_income.py + - policyengine_us/variables/gov/states/wy/dfs/lieap/wy_lieap_eligible.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10346 + state: open + note: PE-US follows the plan for under-18 earnings, POWER and child support received (earned_income_min_age.yaml, + unearned_sources.yaml) and for categorical eligibility (wy_lieap_eligible.py). It follows rule 8(a)(ii)(L) over + the plan in excluding lump sums and has no lottery-winnings input. It deducts child support paid only from the + payer's own earnings (wy_lieap_countable_income.py), since rule 8(a)(iii) does not say whose earnings. - id: us:additional-child-credit-housing-deduction-bar program: income-tax years: