diff --git a/changelog.d/wv-liheap-wave2c.added.md b/changelog.d/wv-liheap-wave2c.added.md new file mode 100644 index 00000000000..308711ddf73 --- /dev/null +++ b/changelog.d/wv-liheap-wave2c.added.md @@ -0,0 +1 @@ +Add West Virginia LIEAP regular heating payments for FY2026 and FY2027 for one through twenty qualified members, with the manual's income rules, income ceiling and payment chart. diff --git a/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/covers_non_ssi_recipients.yaml b/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/covers_non_ssi_recipients.yaml index c3b74216bf2..6594bdf9bc5 100644 --- a/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/covers_non_ssi_recipients.yaml +++ b/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/covers_non_ssi_recipients.yaml @@ -55,7 +55,7 @@ metadata: - title: Wyoming Medicaid Eligibility Online Manual M1005 - SSI and SSI Related href: https://ecom.wyo.gov/m1000-aged-blind-or-disabled-program/m1005-ssi-and-ssi-related - title: West Virginia Income Maintenance Manual 23.11.4 - SSI-Related/Non-Cash Assistance (October 5, 2026 edition) - href: https://bfa.wv.gov/media/40005/download?inline#page=1889 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1889 AK: 2018-01-01: true diff --git a/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/income/limit/requires_income_below_limit.yaml b/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/income/limit/requires_income_below_limit.yaml index ca59754fbae..0b52c10f083 100644 --- a/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/income/limit/requires_income_below_limit.yaml +++ b/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/income/limit/requires_income_below_limit.yaml @@ -25,7 +25,7 @@ metadata: - title: "North Dakota Administrative Code 75-02-02.1-40(1)(a)(2) (the income level \"which establishes supplemental security income eligibility\") and 75-02-02.1-41.1 (recipient liability is net income \"remaining after\" the Medicaid income level) #page 89,93" href: https://www.ndlegis.gov/information/acdata/pdf/75-02-02.1.pdf#page=89 - title: West Virginia Income Maintenance Manual § 4.14.3 Step 5 - SSI-Related income eligibility ("equal to or less than the appropriate SSI Maximum Payment Level") - href: https://bfa.wv.gov/media/40005/download?inline#page=662 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=662 - title: West Virginia Income Maintenance Manual (archived) § 10.23.C Step 5 - SSI-Related income eligibility (rev. 5/13) href: https://www.wvdhhr.org/bcf/policy/imm/new_manual/immanual/manual_pdf_files/chapter_10/ch10_23.pdf#page=4 - title: 42 U.S. Code § 1382(a)(1)(A) and (2)(A) - SSI eligible individual (income "at a rate of not more than" the benefit rate) diff --git a/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/income/limit/uses_ssi_federal_benefit_rate.yaml b/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/income/limit/uses_ssi_federal_benefit_rate.yaml index ee4ac8b5f37..1c73997359a 100644 --- a/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/income/limit/uses_ssi_federal_benefit_rate.yaml +++ b/policyengine_us/parameters/gov/hhs/medicaid/eligibility/categories/senior_or_disabled/income/limit/uses_ssi_federal_benefit_rate.yaml @@ -41,7 +41,7 @@ metadata: - title: Washington Administrative Code 182-512-0100(2)(a) - SSI-related categorically needy medical eligibility href: https://app.leg.wa.gov/wac/default.aspx?cite=182-512-0100 - title: "West Virginia Income Maintenance Manual, Chapter 4 Appendix A (SSI Max), § 23.9 (SSI Related/Non-Cash Assistance, optional categorically needy) and § 23.11.4 SSI-Related/Non-Cash Assistance #page 405,1859,1889" - href: https://bfa.wv.gov/media/40005/download?inline#page=405 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=405 - title: West Virginia Income Maintenance Manual (archived), § 16.7.H SSI-Related/Non-Cash Assistance (rev. 10/13) href: https://www.wvdhhr.org/bcf/policy/imm/new_manual/immanual/manual_pdf_files/chapter_16/ch16_7.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/fpg_rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/fpg_rate.yaml new file mode 100644 index 00000000000..e47285fff41 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/fpg_rate.yaml @@ -0,0 +1,12 @@ +description: West Virginia limits income to this share of federal poverty guidelines for larger households under the Low Income Energy Assistance Program. +values: + 2025-10-01: 1.5 +metadata: + unit: /1 + period: year + label: West Virginia LIEAP fpg rate + reference: + - title: "West Virginia accepted FY2026 LIHEAP State Plan, heating eligibility #page 9,11" + href: https://liheapch.acf.gov/docs/2026/state-plans/WV_Plan_2026.pdf#page=9 + - title: "West Virginia submitted FY2027 LIHEAP State Plan, heating eligibility #page 9,12" + href: https://bfa.wv.gov/media/39990/download?inline=#page=9 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/fpg_year_lag.yaml new file mode 100644 index 00000000000..5876324e288 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/fpg_year_lag.yaml @@ -0,0 +1,14 @@ +# The plan names HHS Poverty Guidelines without a year. The printed limits fix the +# lag: 150% x $54,150 / 12 = $6,768.75, printed as $6,769 for eight in FY2026. +description: West Virginia uses poverty guidelines from this many calendar years before the benefit year under the Low Income Energy Assistance Program. +values: + 2025-10-01: 1 +metadata: + unit: int + period: year + label: West Virginia LIEAP fpg year lag + reference: + - title: West Virginia Income Maintenance Manual, Chapter 4 Appendix A + href: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=407 + - title: West Virginia Income Maintenance Manual, October 2026 edition, Chapter 4 Appendix A + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=405 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/smi_max_household_size.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/smi_max_household_size.yaml new file mode 100644 index 00000000000..bc75adc52fa --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/smi_max_household_size.yaml @@ -0,0 +1,12 @@ +description: West Virginia uses state median income through this household size under the Low Income Energy Assistance Program. +values: + 2025-10-01: 7 +metadata: + unit: person + period: year + label: West Virginia LIEAP smi max household size + reference: + - title: "West Virginia accepted FY2026 LIHEAP State Plan, heating eligibility #page 9,11" + href: https://liheapch.acf.gov/docs/2026/state-plans/WV_Plan_2026.pdf#page=9 + - title: "West Virginia submitted FY2027 LIHEAP State Plan, heating eligibility #page 9,12" + href: https://bfa.wv.gov/media/39990/download?inline=#page=9 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/smi_rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/smi_rate.yaml new file mode 100644 index 00000000000..08ea2faf425 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/eligibility/smi_rate.yaml @@ -0,0 +1,12 @@ +description: West Virginia limits income to this share of state median income for smaller households under the Low Income Energy Assistance Program. +values: + 2025-10-01: 0.6 +metadata: + unit: /1 + period: year + label: West Virginia LIEAP smi rate + reference: + - title: "West Virginia accepted FY2026 LIHEAP State Plan, heating eligibility #page 9,11" + href: https://liheapch.acf.gov/docs/2026/state-plans/WV_Plan_2026.pdf#page=9 + - title: "West Virginia submitted FY2027 LIHEAP State Plan, heating eligibility #page 9,12" + href: https://bfa.wv.gov/media/39990/download?inline=#page=9 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/income/sources.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/income/sources.yaml new file mode 100644 index 00000000000..b532aefbabe --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/income/sources.yaml @@ -0,0 +1,51 @@ +description: West Virginia counts these represented recurring income sources under the Low Income Energy Assistance Program. +values: + 2025-10-01: + - employment_income + # Active-duty basic pay, entered apart from employment_income; enter it in one + # of the two. + - military_basic_pay + # The source deducts 20% from gross receipts. Existing inputs are already net; + # using them without another deduction is an explicit modeling approximation. + - self_employment_income + - sstb_self_employment_income + - farm_operations_income + - partnership_s_corp_income + - estate_income + - total_unemployment_compensation + - strike_benefits + - pension_income + - military_retirement_income + # Railroad retirement is paid by the Railroad Retirement Board, not SSA. + - railroad_benefits + - retirement_distributions + - survivor_benefits + - general_assistance + - rental_income + - farm_rent_income + - alimony_income + - child_support_received + - interest_income + - ordinary_dividend_income + - veterans_benefits + - workers_compensation + - disability_benefits + - financial_assistance + # The only input able to carry contract, mineral-rights, jury-duty or settlement + # receipts, which the manual's all-source rule counts. + - miscellaneous_income +# All members' income counts, regardless of age or immigration qualification. +# Take-up-gated TANF is counted separately once at the household level. +# Military retirement includes Survivor Benefit Plan annuities. +# RSDI, SSI and nonrecurring lump sums are excluded. Aggregate annual receipts +# are treated as recurring; VA Aid and Attendance cannot be separated from +# veterans_benefits. +metadata: + unit: list + period: year + label: West Virginia LIEAP recurring income sources + reference: + - title: "West Virginia Income Maintenance Manual, Chapter 21.3.1.A #page 1732-1735" + href: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1732 + - title: "West Virginia Income Maintenance Manual, October 2026 edition, Chapter 21.3.1.A #page 1726-1729" + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1726 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/amount_step.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/amount_step.yaml new file mode 100644 index 00000000000..959d114e9d0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/amount_step.yaml @@ -0,0 +1,16 @@ +# Across the two finite published grids, all 840 occupied cells equal +# base_amount + amount_step * (household_size - 1 - zero_based_band). +# This is exact transcription compression, not a legal extrapolation rule. +# The finite table does not define payments for blank cells or sizes above 20. +description: West Virginia varies adjacent published base payments by this amount under the Low Income Energy Assistance Program. +values: + 2025-10-01: 5 +metadata: + unit: currency-USD + period: year + label: West Virginia LIEAP published base payment step + reference: + - title: "West Virginia Income Maintenance Manual, Appendix A #page 1780-1781" + href: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1780 + - title: "West Virginia Income Maintenance Manual, October 2026 edition, Appendix A #page 1775-1776" + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1775 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/base_amount.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/base_amount.yaml new file mode 100644 index 00000000000..4673b54a9ae --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/base_amount.yaml @@ -0,0 +1,16 @@ +# Across the two finite published grids, all 840 occupied cells equal +# base_amount + amount_step * (household_size - 1 - zero_based_band). +# This is exact transcription compression, not a legal extrapolation rule. +# The finite table does not define payments for blank cells or sizes above 20. +description: West Virginia sets this first-row one-person base payment under the Low Income Energy Assistance Program. +values: + 2025-10-01: 160 +metadata: + unit: currency-USD + period: year + label: West Virginia LIEAP first published base amount + reference: + - title: "West Virginia Income Maintenance Manual, Appendix A #page 1780-1781" + href: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1780 + - title: "West Virginia Income Maintenance Manual, October 2026 edition, Appendix A #page 1775-1776" + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1775 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/fuel_multiplier.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/fuel_multiplier.yaml new file mode 100644 index 00000000000..d11806f2b47 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/fuel_multiplier.yaml @@ -0,0 +1,23 @@ +# bulk_fuel covers the source's LPG, coal, wood, fuel oil and kerosene rows. +# These are total payment multipliers, as confirmed by the printed products; +# do not add the base amount again. No multiplier is inferred for other fuels. +description: West Virginia multiplies regular base payments by these heating-source factors under the Low Income Energy Assistance Program. +electricity: + values: + 2025-10-01: 1.75 +natural_gas: + values: + 2025-10-01: 1.198 +bulk_fuel: + values: + 2025-10-01: 1.089 +metadata: + propagate_metadata_to_children: true + unit: /1 + period: year + label: West Virginia LIEAP heating-source payment multiplier + reference: + - title: "West Virginia Income Maintenance Manual, section 21.4.11.B #page 1761-1762" + href: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1761 + - title: "West Virginia Income Maintenance Manual, October 2026 edition, section 21.4.11.B #page 1757-1758" + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1757 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/income_band.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/income_band.yaml new file mode 100644 index 00000000000..b699113a6a8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/income_band.yaml @@ -0,0 +1,222 @@ +# Use the first matching inclusive published upper bound with calc(right=True). +# Ordered upper bounds and continuous monthly income resolve the printed From +# values that overlap and the gaps between whole-dollar rows. +# Retain every printed upper bound, including irregular larger-family intervals. +# Band 40 is the sentinel above the final published row, not another payment. +description: West Virginia determines this zero-based payment row from monthly countable income under the Low Income Energy Assistance Program. +brackets: + - threshold: + 2025-10-01: -.inf + amount: + 2025-10-01: 0 + - threshold: + 2025-10-01: 2_077 + 2026-10-01: 2_157 + amount: + 2025-10-01: 1 + - threshold: + 2025-10-01: 2_454 + 2026-10-01: 2_550 + amount: + 2025-10-01: 2 + - threshold: + 2025-10-01: 2_832 + 2026-10-01: 2_942 + amount: + 2025-10-01: 3 + - threshold: + 2025-10-01: 3_209 + 2026-10-01: 3_335 + amount: + 2025-10-01: 4 + - threshold: + 2025-10-01: 3_587 + 2026-10-01: 3_427 + amount: + 2025-10-01: 5 + - threshold: + 2025-10-01: 3_965 + 2026-10-01: 4_120 + amount: + 2025-10-01: 6 + - threshold: + 2025-10-01: 4_343 + 2026-10-01: 4_512 + amount: + 2025-10-01: 7 + - threshold: + 2025-10-01: 4_720 + 2026-10-01: 4_904 + amount: + 2025-10-01: 8 + - threshold: + 2025-10-01: 5_099 + 2026-10-01: 5_296 + amount: + 2025-10-01: 9 + - threshold: + 2025-10-01: 5_475 + 2026-10-01: 5_689 + amount: + 2025-10-01: 10 + - threshold: + 2025-10-01: 5_853 + 2026-10-01: 6_081 + amount: + 2025-10-01: 11 + - threshold: + 2025-10-01: 6_230 + 2026-10-01: 6_474 + amount: + 2025-10-01: 12 + - threshold: + 2025-10-01: 6_301 + 2026-10-01: 6_548 + amount: + 2025-10-01: 13 + - threshold: + 2025-10-01: 6_372 + 2026-10-01: 6_621 + amount: + 2025-10-01: 14 + - threshold: + 2025-10-01: 6_572 + 2026-10-01: 6_793 + amount: + 2025-10-01: 15 + - threshold: + 2025-10-01: 6_769 + 2026-10-01: 6_965 + amount: + 2025-10-01: 16 + - threshold: + 2025-10-01: 7_113 + 2026-10-01: 7_320 + amount: + 2025-10-01: 17 + - threshold: + 2025-10-01: 7_456 + 2026-10-01: 7_675 + amount: + 2025-10-01: 18 + - threshold: + 2025-10-01: 7_800 + 2026-10-01: 8_030 + amount: + 2025-10-01: 19 + - threshold: + 2025-10-01: 8_144 + 2026-10-01: 8_385 + amount: + 2025-10-01: 20 + - threshold: + 2025-10-01: 8_477 + 2026-10-01: 8_740 + amount: + 2025-10-01: 21 + - threshold: + 2025-10-01: 8_831 + 2026-10-01: 9_095 + amount: + 2025-10-01: 22 + - threshold: + 2025-10-01: 9_175 + 2026-10-01: 9_805 + amount: + 2025-10-01: 23 + - threshold: + 2025-10-01: 9_519 + 2026-10-01: 10_160 + amount: + 2025-10-01: 24 + - threshold: + 2025-10-01: 9_863 + 2026-10-01: 10_515 + amount: + 2025-10-01: 25 + - threshold: + 2025-10-01: 10_206 + 2026-10-01: 10_870 + amount: + 2025-10-01: 26 + - threshold: + 2025-10-01: 10_550 + 2026-10-01: 11_225 + amount: + 2025-10-01: 27 + - threshold: + 2025-10-01: 10_894 + 2026-10-01: 11_580 + amount: + 2025-10-01: 28 + - threshold: + 2025-10-01: 11_238 + 2026-10-01: 11_935 + amount: + 2025-10-01: 29 + - threshold: + 2025-10-01: 11_581 + 2026-10-01: 12_290 + amount: + 2025-10-01: 30 + - threshold: + 2025-10-01: 11_925 + 2026-10-01: 12_645 + amount: + 2025-10-01: 31 + - threshold: + 2025-10-01: 12_269 + 2026-10-01: 13_000 + amount: + 2025-10-01: 32 + - threshold: + 2025-10-01: 12_956 + 2026-10-01: 13_355 + amount: + 2025-10-01: 33 + - threshold: + 2025-10-01: 13_300 + 2026-10-01: 13_710 + amount: + 2025-10-01: 34 + - threshold: + 2025-10-01: 13_644 + 2026-10-01: 14_065 + amount: + 2025-10-01: 35 + - threshold: + 2025-10-01: 13_988 + 2026-10-01: 14_420 + amount: + 2025-10-01: 36 + - threshold: + 2025-10-01: 14_331 + 2026-10-01: 14_775 + amount: + 2025-10-01: 37 + - threshold: + 2025-10-01: 14_675 + 2026-10-01: 15_130 + amount: + 2025-10-01: 38 + - threshold: + 2025-10-01: 15_019 + 2026-10-01: 15_485 + amount: + 2025-10-01: 39 + - threshold: + 2025-10-01: 15_363 + 2026-10-01: 15_840 + amount: + 2025-10-01: 40 +metadata: + type: single_amount + threshold_unit: currency-USD + amount_unit: /1 + period: month + label: West Virginia LIEAP monthly income band index + reference: + - title: "West Virginia Income Maintenance Manual, Appendix A #page 1780-1781" + href: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1780 + - title: "West Virginia Income Maintenance Manual, October 2026 edition, Appendix A #page 1775-1776" + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1775 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/max_household_size.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/max_household_size.yaml new file mode 100644 index 00000000000..c1e8713d588 --- /dev/null +++ b/policyengine_us/parameters/gov/states/wv/dhhr/lieap/payment/max_household_size.yaml @@ -0,0 +1,16 @@ +# Across the two finite published grids, all 840 occupied cells equal +# base_amount + amount_step * (household_size - 1 - zero_based_band). +# This is exact transcription compression, not a legal extrapolation rule. +# The finite table does not define payments for blank cells or sizes above 20. +description: West Virginia publishes regular payment amounts through this household size under the Low Income Energy Assistance Program. +values: + 2025-10-01: 20 +metadata: + unit: person + period: year + label: West Virginia LIEAP maximum published payment household size + reference: + - title: "West Virginia Income Maintenance Manual, Appendix A #page 1780-1781" + href: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1780 + - title: "West Virginia Income Maintenance Manual, October 2026 edition, Appendix A #page 1775-1776" + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1775 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/works/income/child_support_disregard.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/works/income/child_support_disregard.yaml index 6efb1fbb176..ae93fee2413 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/works/income/child_support_disregard.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/works/income/child_support_disregard.yaml @@ -8,7 +8,7 @@ metadata: label: West Virginia Works child support disregard reference: - title: WV Income Maintenance Manual Chapter 4 Section 4.5.2.B - href: https://bfa.wv.gov/media/40005/download?inline#page=590 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=590 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/works/income/earned_income_disregard/rate.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/works/income/earned_income_disregard/rate.yaml index dce67a5704e..786a351fd7e 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/works/income/earned_income_disregard/rate.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/works/income/earned_income_disregard/rate.yaml @@ -9,4 +9,4 @@ metadata: label: West Virginia Works earned income disregard rate reference: - title: WV Income Maintenance Manual Chapter 4 Section 4.5.2.A.1 - href: https://bfa.wv.gov/media/40005/download?inline#page=590 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=590 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/works/income/standard_of_need/amount.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/works/income/standard_of_need/amount.yaml index 8fc58296462..2bf21259a83 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/works/income/standard_of_need/amount.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/works/income/standard_of_need/amount.yaml @@ -11,9 +11,9 @@ metadata: label: West Virginia Works standard of need amount reference: - title: WV Income Maintenance Manual Chapter 10, Appendix A - href: https://bfa.wv.gov/media/40005/download?inline#page=405 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=405 - title: WV Income Maintenance Manual Appendix A Income limit(2024) - href: https://bfa.wv.gov/media/40005/download?inline#page=405 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=405 1: 2017-01-01: 581 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/works/max_household_size.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/works/max_household_size.yaml index 4db112544e2..5bbf0f59268 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/works/max_household_size.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/works/max_household_size.yaml @@ -9,4 +9,4 @@ metadata: label: West Virginia Works maximum household size reference: - title: WV Income Maintenance Manual Appendix A Income Limits(2024) - href: https://bfa.wv.gov/media/40005/download?inline#page=405 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=405 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/works/payment_standard/amount.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/works/payment_standard/amount.yaml index 2c361447081..e1d2b282aea 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/works/payment_standard/amount.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/works/payment_standard/amount.yaml @@ -11,7 +11,7 @@ metadata: label: West Virginia Works payment standard amount reference: - title: WV Income Maintenance Manual Appendix A Income Limit (2024) - href: https://bfa.wv.gov/media/40005/download?inline#page=405 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=405 1: 2017-06-01: 262 diff --git a/policyengine_us/parameters/gov/states/wv/dhhr/works/resources/limit.yaml b/policyengine_us/parameters/gov/states/wv/dhhr/works/resources/limit.yaml index cd5522b2dcb..f09cbe93f89 100644 --- a/policyengine_us/parameters/gov/states/wv/dhhr/works/resources/limit.yaml +++ b/policyengine_us/parameters/gov/states/wv/dhhr/works/resources/limit.yaml @@ -9,4 +9,4 @@ metadata: label: West Virginia Works resource limit reference: - title: WV Income Maintenance Manual Chapter 11.3 - href: https://bfa.wv.gov/media/40005/download?inline#page=746 + href: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=746 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index f654dcc4120..0aa75d3fa47 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -987,7 +987,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: AK, AR, AL, AZ, CA, CO, CT, DC, DE, GA, HI, Riverside County, MA, FL, IL, IA, ID, IN, KS, KY, LA, MD, ME, MN, MO, MS, MT, NC, ND, NE, NH, NJ, NM, NV, NY, OH, OK, OR, PA, SC, SD, RI, TN, TX, UT, VA, VT, WA, WI, WY + coverage: AK, AR, AL, AZ, CA, CO, CT, DC, DE, GA, HI, Riverside County, MA, FL, IL, IA, ID, IN, KS, KY, LA, MD, ME, MN, MO, MS, MT, NC, ND, NE, NH, NJ, NM, NV, NY, OH, OK, OR, PA, SC, SD, RI, TN, TX, UT, VA, VT, WA, WI, WV, WY state_implementations: - state: AL status: partial @@ -1353,6 +1353,14 @@ programs: parameter_prefix: gov.states.wi.doa.wheap verified_years: "2026" notes: FFY2026 regular heating benefit from the HE+ formula with the published heat proxy table. The non-heating electric benefit, crisis and weatherization are out of scope. + - state: WV + status: partial + name: West Virginia LIEAP + full_name: West Virginia Low Income Energy Assistance Program + variable: wv_lieap + parameter_prefix: gov.states.wv.dhhr.lieap + verified_years: "2026-2027" + notes: FY2026-FY2027 regular heating payments for households of one to twenty qualified members. Crisis, cooling, weatherization, equipment and the utility discount are out of scope. - state: WY status: partial name: Wyoming LIEAP diff --git a/policyengine_us/tests/code_health/known_dead_reference_urls/midatlantic.toml b/policyengine_us/tests/code_health/known_dead_reference_urls/midatlantic.toml index 3e017c9c33f..8ab016b9cb7 100644 --- a/policyengine_us/tests/code_health/known_dead_reference_urls/midatlantic.toml +++ b/policyengine_us/tests/code_health/known_dead_reference_urls/midatlantic.toml @@ -6,7 +6,7 @@ [[dead]] prefix = "https://bfa.wv.gov/media/2766/download?inline" verified = "2026-10-01" -replacement = "https://bfa.wv.gov/media/40005/download?inline" +replacement = "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline" [[dead]] prefix = "https://data.virginia.gov/dataset/general-child-care-subsidy-program-maximum-reimbursement-rates" @@ -21,12 +21,12 @@ replacement = "https://web.archive.org/web/20161226193813/https://dhhr.wv.gov/bc [[dead]] prefix = "https://dhhr.wv.gov/bcf/Services/familyassistance/Documents/744/ch10_apa.pdf" verified = "2026-10-01" -replacement = "https://bfa.wv.gov/media/40005/download?inline" +replacement = "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline" [[dead]] prefix = "https://dhhr.wv.gov/bcf/Services/familyassistance/PolicyManual/Documents/Chapter%2011/ch11_3.pdf" verified = "2026-10-01" -replacement = "https://bfa.wv.gov/media/40005/download?inline" +replacement = "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline" [[dead]] prefix = "https://dhss.delaware.gov/dss/childcr/" diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap.yaml new file mode 100644 index 00000000000..740af4ce0d1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap.yaml @@ -0,0 +1,419 @@ +# Published regular LIEAP tables and multiplication examples, not crisis caps. +# FY2026: PDF pages 1761-1762,1780-1781 +# https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1761 +# FY2027: PDF pages 1757-1758,1775-1776 +# https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1757 +# Continuous published upper bounds apply, with no income rounding. + +- name: Case 1, zero income receives each supported fuel amount without a bill cap. + period: 2026 + absolute_error_margin: 0.01 + # One qualified person has base $160: electricity * 1.75 = $280; + # gas * 1.198 = $191.68; the other five published fuels * 1.089 = $174.24. + # Unsupported fuels have no modeled award, not a legal eligibility denial. + input: + state_code: [WV, WV, WV, WV, WV, WV, WV, WV, WV, WV, WV] + is_citizen_or_legal_immigrant: [true, true, true, true, true, true, + true, true, true, true, true] + heating_type: [ELECTRICITY, NATURAL_GAS, PROPANE, FUEL_OIL, KEROSENE, + WOOD, COAL, UNSPECIFIED, NONE, SOLAR, OTHER] + pre_subsidy_electricity_expense: [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0] + gas_expense: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] + bottled_gas_expense: [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0] + fuel_oil_expense: [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0] + wood_expense: [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + coal_expense: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0] + other_heating_fuel_expense: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] + output: + wv_lieap: [280, 191.68, 174.24, 174.24, 174.24, 174.24, 174.24, + 0, 0, 0, 0] + +- name: Case 2, FY2026 upper bounds apply continuously with an inclusive ceiling. + period: 2026 + absolute_error_margin: 0.01 + # Monthly wages: 2077, 2077.25, 2077.50, 2078, 2454 and 2454.01. + # Only exact 2077 uses base 160; the next four use 155. Last row is over limit. + input: + state_code: [WV, WV, WV, WV, WV, WV] + is_citizen_or_legal_immigrant: [true, true, true, true, true, true] + employment_income: [24_924, 24_927, 24_930, 24_936, 29_448, 29_448.12] + heating_type: [ELECTRICITY, ELECTRICITY, ELECTRICITY, + ELECTRICITY, ELECTRICITY, ELECTRICITY] + pre_subsidy_electricity_expense: [1_200, 1_200, 1_200, 1_200, 1_200, 1_200] + output: + wv_lieap: [280, 271.25, 271.25, 271.25, 271.25, 0] + +- name: Case 3, FY2027 uses its own upper bounds and inclusive income ceiling. + period: 2027 + absolute_error_margin: 0.01 + # Monthly wages: 2157, 2157.25, 2157.50, 2158, 2550 and 2550.01. + input: + state_code: [WV, WV, WV, WV, WV, WV] + is_citizen_or_legal_immigrant: [true, true, true, true, true, true] + employment_income: [25_884, 25_887, 25_890, 25_896, 30_600, 30_600.12] + heating_type: [ELECTRICITY, ELECTRICITY, ELECTRICITY, + ELECTRICITY, ELECTRICITY, ELECTRICITY] + pre_subsidy_electricity_expense: [1_200, 1_200, 1_200, 1_200, 1_200, 1_200] + output: + wv_lieap: [280, 271.25, 271.25, 271.25, 271.25, 0] + +- name: Case 4, the literal FY2027 third-person upper bound is not smoothed. + period: 2027 + absolute_error_margin: 0.01 + # Monthly 3400 is within the printed 3427 upper bound: base 150 x 1.089 = 163.35. + # Monthly 3430 is in the next row: base 145 x 1.089 = 157.905, rounded 157.91. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 40_800} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + person3: {age: 40, is_citizen_or_legal_immigrant: true} + person4: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 41_160} + person5: {age: 40, is_citizen_or_legal_immigrant: true} + person6: {age: 40, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1, person2, person3] + heating_type: PROPANE + bottled_gas_expense: 1_200 + spm_unit2: + members: [person4, person5, person6] + heating_type: PROPANE + bottled_gas_expense: 1_200 + households: + household1: + members: [person1, person2, person3] + state_code: WV + household2: + members: [person4, person5, person6] + state_code: WV + output: + wv_lieap: [163.35, 157.91] + +- name: Case 5, the literal FY2026 larger-family upper bound is not smoothed. + period: 2026 + absolute_error_margin: 0.01 + # Monthly 8477 uses band 20 and base 110; monthly 8480 uses band 21 and base 105. + # Both are below the eleven-person 8831 monthly ceiling. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 101_724} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + person3: {age: 40, is_citizen_or_legal_immigrant: true} + person4: {age: 40, is_citizen_or_legal_immigrant: true} + person5: {age: 40, is_citizen_or_legal_immigrant: true} + person6: {age: 40, is_citizen_or_legal_immigrant: true} + person7: {age: 40, is_citizen_or_legal_immigrant: true} + person8: {age: 40, is_citizen_or_legal_immigrant: true} + person9: {age: 40, is_citizen_or_legal_immigrant: true} + person10: {age: 40, is_citizen_or_legal_immigrant: true} + person11: {age: 40, is_citizen_or_legal_immigrant: true} + person12: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 101_760} + person13: {age: 40, is_citizen_or_legal_immigrant: true} + person14: {age: 40, is_citizen_or_legal_immigrant: true} + person15: {age: 40, is_citizen_or_legal_immigrant: true} + person16: {age: 40, is_citizen_or_legal_immigrant: true} + person17: {age: 40, is_citizen_or_legal_immigrant: true} + person18: {age: 40, is_citizen_or_legal_immigrant: true} + person19: {age: 40, is_citizen_or_legal_immigrant: true} + person20: {age: 40, is_citizen_or_legal_immigrant: true} + person21: {age: 40, is_citizen_or_legal_immigrant: true} + person22: {age: 40, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + spm_unit2: + members: [person12, person13, person14, person15, person16, person17, person18, person19, person20, person21, person22] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + households: + household1: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11] + state_code: WV + household2: + members: [person12, person13, person14, person15, person16, person17, person18, person19, person20, person21, person22] + state_code: WV + output: + wv_lieap: [192.5, 183.75] + +- name: Case 6, a reachable bulk-fuel half cent rounds up for five people. + period: 2026 + absolute_error_margin: 0.001 + # Monthly 5300 is below the five-person 5475 ceiling and uses base 135. + # The printed 135 x 1.089 = 147.015 rounds to 147.02, not 147.01. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 63_600} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + person3: {age: 40, is_citizen_or_legal_immigrant: true} + person4: {age: 40, is_citizen_or_legal_immigrant: true} + person5: {age: 40, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1, person2, person3, person4, person5] + heating_type: PROPANE + bottled_gas_expense: 1_200 + households: + household1: + members: [person1, person2, person3, person4, person5] + state_code: WV + output: + wv_lieap: 147.02 + +- name: Case 7, twenty people reach base 65 while twenty-one remains unmodeled. + period: 2026 + absolute_error_margin: 0.001 + # Twenty people at the 180_225 federal ceiling (15_018.75 monthly, below the + # chart's 15_019) use band 38 and base 65. + # 65 x 1.089 = 70.785 rounds to 70.79. Twenty-one with zero income is + # within the ordinary income limit but outside modeled payment-table coverage; + # zero for that row is not a legal ineligibility determination. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 180_225} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + person3: {age: 40, is_citizen_or_legal_immigrant: true} + person4: {age: 40, is_citizen_or_legal_immigrant: true} + person5: {age: 40, is_citizen_or_legal_immigrant: true} + person6: {age: 40, is_citizen_or_legal_immigrant: true} + person7: {age: 40, is_citizen_or_legal_immigrant: true} + person8: {age: 40, is_citizen_or_legal_immigrant: true} + person9: {age: 40, is_citizen_or_legal_immigrant: true} + person10: {age: 40, is_citizen_or_legal_immigrant: true} + person11: {age: 40, is_citizen_or_legal_immigrant: true} + person12: {age: 40, is_citizen_or_legal_immigrant: true} + person13: {age: 40, is_citizen_or_legal_immigrant: true} + person14: {age: 40, is_citizen_or_legal_immigrant: true} + person15: {age: 40, is_citizen_or_legal_immigrant: true} + person16: {age: 40, is_citizen_or_legal_immigrant: true} + person17: {age: 40, is_citizen_or_legal_immigrant: true} + person18: {age: 40, is_citizen_or_legal_immigrant: true} + person19: {age: 40, is_citizen_or_legal_immigrant: true} + person20: {age: 40, is_citizen_or_legal_immigrant: true} + person21: {age: 40, is_citizen_or_legal_immigrant: true} + person22: {age: 40, is_citizen_or_legal_immigrant: true} + person23: {age: 40, is_citizen_or_legal_immigrant: true} + person24: {age: 40, is_citizen_or_legal_immigrant: true} + person25: {age: 40, is_citizen_or_legal_immigrant: true} + person26: {age: 40, is_citizen_or_legal_immigrant: true} + person27: {age: 40, is_citizen_or_legal_immigrant: true} + person28: {age: 40, is_citizen_or_legal_immigrant: true} + person29: {age: 40, is_citizen_or_legal_immigrant: true} + person30: {age: 40, is_citizen_or_legal_immigrant: true} + person31: {age: 40, is_citizen_or_legal_immigrant: true} + person32: {age: 40, is_citizen_or_legal_immigrant: true} + person33: {age: 40, is_citizen_or_legal_immigrant: true} + person34: {age: 40, is_citizen_or_legal_immigrant: true} + person35: {age: 40, is_citizen_or_legal_immigrant: true} + person36: {age: 40, is_citizen_or_legal_immigrant: true} + person37: {age: 40, is_citizen_or_legal_immigrant: true} + person38: {age: 40, is_citizen_or_legal_immigrant: true} + person39: {age: 40, is_citizen_or_legal_immigrant: true} + person40: {age: 40, is_citizen_or_legal_immigrant: true} + person41: {age: 40, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16, person17, person18, person19, person20] + heating_type: PROPANE + bottled_gas_expense: 1_200 + spm_unit2: + members: [person21, person22, person23, person24, person25, person26, person27, person28, person29, person30, person31, person32, person33, person34, person35, person36, person37, person38, person39, person40, person41] + heating_type: PROPANE + bottled_gas_expense: 1_200 + households: + household1: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15, person16, person17, person18, person19, person20] + state_code: WV + household2: + members: [person21, person22, person23, person24, person25, person26, person27, person28, person29, person30, person31, person32, person33, person34, person35, person36, person37, person38, person39, person40, person41] + state_code: WV + output: + wv_lieap: [70.79, 0] + +- name: Case 8, represented heating responsibility allows direct and stated costs. + period: 2027 + absolute_error_margin: 0.01 + # Rows 1-2 pay direct heat, including a subsidized tenant; no bill cap applies. + # Row 4 bundled rent has no responsibility override and remains unmodeled. + # Known-obligation overrides are isolated in Case 9 so no input on this + # variable suppresses its derived default for the other units in this case. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + person3: {age: 40, is_citizen_or_legal_immigrant: true} + person4: {age: 40, is_citizen_or_legal_immigrant: true} + person5: {age: 40, is_citizen_or_legal_immigrant: true} + person6: {age: 40, is_citizen_or_legal_immigrant: false} + spm_units: + spm_unit1: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1 + spm_unit2: + members: [person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + receives_housing_assistance: true + spm_unit3: + members: [person3] + heating_type: ELECTRICITY + spm_unit4: + members: [person4] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + receives_housing_assistance: true + heat_expense_included_in_rent: true + spm_unit5: + members: [person5] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + spm_unit6: + members: [person6] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + households: + household1: {members: [person1], state_code: WV} + household2: {members: [person2], state_code: WV} + household3: {members: [person3], state_code: WV} + household4: {members: [person4], state_code: WV} + household5: {members: [person5], state_code: OH} + household6: {members: [person6], state_code: WV} + output: + wv_lieap: [280, 280, 0, 0, 0, 0] + +- name: Case 9, known responsibility for auxiliary and stated rent costs is supplied. + period: 2027 + absolute_error_margin: 0.01 + # The FY2027 manual expressly recognizes auxiliary electricity for self-cut + # wood. A separately documented heating charge in rent also qualifies. + # These existing responsibility facts are supplied only in this case; normal + # bill-based defaults remain independently exercised in Case 8. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1] + heating_type: WOOD + wood_expense: 0 + pre_subsidy_electricity_expense: 200 + has_heating_expense: true + spm_unit2: + members: [person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 200 + heat_expense_included_in_rent: true + has_heating_expense: true + households: + household1: {members: [person1], state_code: WV} + household2: {members: [person2], state_code: WV} + output: + wv_lieap: [174.24, 280] + +- name: Case 10, a nonqualified member's income counts without enlarging the payment size. + period: 2026 + absolute_error_margin: 0.01 + # Size 1 and monthly income 2000 use the first row, base 160, so 160 x 1.75 = 280. + # Size 2 would use base 165 and pay 288.75. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true} + person2: {age: 40, is_citizen_or_legal_immigrant: false, employment_income: 24_000} + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + households: + household1: {members: [person1, person2], state_code: WV} + output: + wv_lieap_household_size: 1 + wv_lieap_income_limit: 29_448 + wv_lieap: 280 + +- name: Case 11, FY2026 income above the federal ceiling pays nothing within a rounded chart limit. + period: 2026 + absolute_error_margin: 0.01 + # Three people: HHS's 60% SMI amount 47_575 is below the chart's 3_965 x 12 = 47_580. + # 47_575 is 3_964.58 monthly, row 5, base 145, x 1.75 = 253.75; 47_578 is over the ceiling. + # Eight people: 150% of the 2025 guideline 81_225 is below the chart's 6_769 x 12 = 81_228. + # 81_225 is 6_768.75 monthly, row 15, base 120, x 1.75 = 210; 81_227 is over the ceiling. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 47_575} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + person3: {age: 40, is_citizen_or_legal_immigrant: true} + person4: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 47_578} + person5: {age: 40, is_citizen_or_legal_immigrant: true} + person6: {age: 40, is_citizen_or_legal_immigrant: true} + person7: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 81_225} + person8: {age: 40, is_citizen_or_legal_immigrant: true} + person9: {age: 40, is_citizen_or_legal_immigrant: true} + person10: {age: 40, is_citizen_or_legal_immigrant: true} + person11: {age: 40, is_citizen_or_legal_immigrant: true} + person12: {age: 40, is_citizen_or_legal_immigrant: true} + person13: {age: 40, is_citizen_or_legal_immigrant: true} + person14: {age: 40, is_citizen_or_legal_immigrant: true} + person15: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 81_227} + person16: {age: 40, is_citizen_or_legal_immigrant: true} + person17: {age: 40, is_citizen_or_legal_immigrant: true} + person18: {age: 40, is_citizen_or_legal_immigrant: true} + person19: {age: 40, is_citizen_or_legal_immigrant: true} + person20: {age: 40, is_citizen_or_legal_immigrant: true} + person21: {age: 40, is_citizen_or_legal_immigrant: true} + person22: {age: 40, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1, person2, person3] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + spm_unit2: + members: [person4, person5, person6] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + spm_unit3: + members: [person7, person8, person9, person10, person11, person12, person13, person14] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + spm_unit4: + members: [person15, person16, person17, person18, person19, person20, person21, person22] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + households: + household1: {members: [person1, person2, person3], state_code: WV} + household2: {members: [person4, person5, person6], state_code: WV} + household3: {members: [person7, person8, person9, person10, person11, person12, person13, person14], state_code: WV} + household4: {members: [person15, person16, person17, person18, person19, person20, person21, person22], state_code: WV} + output: + wv_lieap: [253.75, 0, 210, 0] + +- name: Case 12, FY2027 income above the federal ceiling pays nothing within a rounded chart limit. + period: 2027 + absolute_error_margin: 0.01 + # HHS's 60% SMI amount for three, 49_435, is below the chart's 4_120 x 12 = 49_440. + # 49_435 is 4_119.58 monthly, row 5, base 145, x 1.75 = 253.75; 49_438 is over the ceiling. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 49_435} + person2: {age: 40, is_citizen_or_legal_immigrant: true} + person3: {age: 40, is_citizen_or_legal_immigrant: true} + person4: {age: 40, is_citizen_or_legal_immigrant: true, employment_income: 49_438} + person5: {age: 40, is_citizen_or_legal_immigrant: true} + person6: {age: 40, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1, person2, person3] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + spm_unit2: + members: [person4, person5, person6] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + households: + household1: {members: [person1, person2, person3], state_code: WV} + household2: {members: [person4, person5, person6], state_code: WV} + output: + wv_lieap: [253.75, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_countable_income.yaml new file mode 100644 index 00000000000..d583103955f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_countable_income.yaml @@ -0,0 +1,868 @@ +# Independent source-derived tests for annualized countable income only. +# Earlier operative IMM, section 21.3.1.A.1-4/B/D (physical pages 1732-1735, 1739). +# https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1732 +# Current October 1, 2026 IMM, section 21.3.1.A.1-3/A.5/B (physical pages 1726-1729, 1734). +# https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1726 +# Annual flow inputs approximate steady application-month receipt; they do not +# reconstruct application dates, pay-frequency conversions or partial months. +# The detailed manual governs over unchecked summary-plan income categories. +# Capital/death/prize facts in Case 7 are explicitly nonrecurring. + +- name: Case 1, minors and nonqualified members retain their recurring earnings. + # The operative manual has no blanket minor-earnings exclusion. + # Every unit counts 12_000 + 6_000, including nonqualified parent earnings. + # The seventeenth/eighteenth birthday does not change this income rule. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 12000 + person2: + age: 17 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 6000 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 12000 + person4: + age: 18 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 6000 + person5: + age: 40 + is_citizen_or_legal_immigrant: false + ssi: 0 + employment_income: 12000 + person6: + age: 10 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 6000 + spm_units: + spm_unit1: + members: + - person1 + - person2 + wv_works: 0 + spm_unit2: + members: + - person3 + - person4 + wv_works: 0 + spm_unit3: + members: + - person5 + - person6 + wv_works: 0 + households: + household1: + members: + - person1 + - person2 + state_code: WV + household2: + members: + - person3 + - person4 + state_code: WV + household3: + members: + - person5 + - person6 + state_code: WV + output: + wv_lieap_countable_income: + - 18000 + - 18000 + - 18000 + +- name: Case 2, recurring represented income sources include assistance and ordinary VA. + # 500 + 2_400 + 300 + 600 + 700 + 400 + 900 + (200 + 100) + # + (250 + 50) + 800 + 1_000 + 900 + 1_100 + 1_200 + 1_300 = 12_700. + # VA here is ordinary recurring benefits, not excluded Aid and Attendance. + # Estate income and child support here are recurring, not inheritance or arrears. + # Outside-household cash assistance and GA count under the all-source rule. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + military_basic_pay: 500 + unemployment_compensation: 2400 + strike_benefits: 300 + rental_income: 600 + farm_rent_income: 700 + alimony_income: 400 + child_support_received: 900 + taxable_interest_income: 200 + tax_exempt_interest_income: 100 + qualified_dividend_income: 250 + non_qualified_dividend_income: 50 + veterans_benefits: 800 + workers_compensation: 1000 + disability_benefits: 900 + estate_income: 1100 + financial_assistance: 1200 + general_assistance: 1300 + spm_units: + spm_unit1: + members: + - person1 + wv_works: 0 + households: + household1: + members: + - person1 + state_code: WV + output: + wv_lieap_countable_income: + - 12700 + +- name: Case 3, pensions account distributions and non-SSA survivor benefits count once. + # Recurring pensions: 1_000 + 2_000 + 300 + 400 = 3_700. + # Recurring account withdrawals: 5_000 + 600 + 700 + 80 + 90 + 10 + 110 + 20 + 30 = 6_640. + # Non-SSA survivors 500 gives 3_700 + 6_640 + 500 = 10_840. + # All three RSDI categories are excluded; no narrower pension classifications + # are supplied alongside their potentially overlapping pension aggregates. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_citizen_or_legal_immigrant: true + ssi: 0 + taxable_public_pension_income: 1000 + taxable_private_pension_income: 2000 + tax_exempt_public_pension_income: 300 + tax_exempt_private_pension_income: 400 + taxable_ira_distributions: 5000 + tax_exempt_ira_distributions: 600 + taxable_401k_distributions: 700 + tax_exempt_401k_distributions: 80 + taxable_sep_distributions: 90 + tax_exempt_sep_distributions: 10 + taxable_403b_distributions: 110 + tax_exempt_403b_distributions: 20 + keogh_distributions: 30 + survivor_benefits: 500 + social_security_retirement: 18000 + social_security_disability: 12000 + social_security_survivors: 3600 + spm_units: + spm_unit1: + members: + - person1 + wv_works: 0 + households: + household1: + members: + - person1 + state_code: WV + output: + wv_lieap_countable_income: + - 10840 + +- name: Case 4, monthly WV WORKS aggregates once and general assistance remains countable. + # First unit: GA 600 + 900 plus WV WORKS 100 + 200 = 1_800. + # Second unit: GA 50 plus WV WORKS 25 * 12 = 350. + # WV WORKS is an SPMUnit monthly benefit, not a per-person or annual-times-12 amount. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + general_assistance: 600 + person2: + age: 8 + is_citizen_or_legal_immigrant: true + ssi: 0 + general_assistance: 900 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + general_assistance: 50 + spm_units: + spm_unit1: + members: + - person1 + - person2 + wv_works: + 2026-01: 100 + 2026-02: 200 + 2026-03: 0 + 2026-04: 0 + 2026-05: 0 + 2026-06: 0 + 2026-07: 0 + 2026-08: 0 + 2026-09: 0 + 2026-10: 0 + 2026-11: 0 + 2026-12: 0 + spm_unit2: + members: + - person3 + wv_works: + 2026-01: 25 + 2026-02: 25 + 2026-03: 25 + 2026-04: 25 + 2026-05: 25 + 2026-06: 25 + 2026-07: 25 + 2026-08: 25 + 2026-09: 25 + 2026-10: 25 + 2026-11: 25 + 2026-12: 25 + households: + household1: + members: + - person1 + - person2 + state_code: WV + household2: + members: + - person3 + state_code: WV + output: + wv_lieap_countable_income: + - 1800 + - 350 + +- name: Case 5, existing net businesses are not discounted again and losses do not offset earnings. + # Net-business approximation: do not apply the manual gross-receipts 20% deduction twice. + # First unit sums 1_000 + 2_000 + 3_000 + 4_000 = 10_000. + # Second counts wages 10_000 + positive business 2_000 + 3_000 = 15_000. + # Negative business streams contribute zero; the all-loss unit has zero income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + self_employment_income: 1000 + sstb_self_employment_income: 2000 + farm_operations_income: 3000 + partnership_s_corp_income: 4000 + person2: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 10000 + self_employment_income: -9000 + sstb_self_employment_income: 2000 + farm_operations_income: -7000 + partnership_s_corp_income: 3000 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + self_employment_income: -1000 + sstb_self_employment_income: -2000 + farm_operations_income: -3000 + partnership_s_corp_income: -4000 + spm_units: + spm_unit1: + members: + - person1 + wv_works: 0 + spm_unit2: + members: + - person2 + wv_works: 0 + spm_unit3: + members: + - person3 + wv_works: 0 + households: + household1: + members: + - person1 + state_code: WV + household2: + members: + - person2 + state_code: WV + household3: + members: + - person3 + state_code: WV + output: + wv_lieap_countable_income: + - 10000 + - 15000 + - 0 + +- name: Case 6, student funding RSDI SSI and SNAP do not enlarge recurring wages. + # Only the 10_000 ordinary wages count; these are not work-study wages. + # Scholarships/grants 5_000, Pell 3_000, SSDI 2_400, annual SSI 1_200 and SNAP 6_000 are excluded. + # No separate work-study dollar input exists; this does not assert exclusion of mixed-job wages. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 20 + is_citizen_or_legal_immigrant: true + ssi: 1200 + employment_income: 10000 + educational_assistance: 5000 + pell_grant: 3000 + social_security_disability: 2400 + spm_units: + spm_unit1: + members: + - person1 + wv_works: 0 + snap: 6000 + households: + household1: + members: + - person1 + state_code: WV + output: + wv_lieap_countable_income: + - 10000 + +- name: Case 7, specifically nonrecurring proceeds are excluded under the documented input convention. + # Fixture facts: one asset sale, one gambling prize and one life-insurance death payment. + # The manual excludes nonrecurring lump sums, not all possible recurring installments. + # Existing annual fields cannot distinguish those installments; this scenario + # does not claim a legal blanket exclusion or test unobserved recurrence. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + long_term_capital_gains: 10000 + gambling_winnings: 2000 + life_insurance_benefits: 50000 + spm_units: + spm_unit1: + members: + - person1 + wv_works: 0 + households: + household1: + members: + - person1 + state_code: WV + output: + wv_lieap_countable_income: + - 0 + +- name: Case 8, income remains unprorated in mixed states and all-nonqualified households. + # WV counts both 6_000 incomes and separately the all-nonqualified unit 15_000. + # Income is not conditioned on qualified household size; this is not eligibility. + # The Virginia unit has zero under the WV-only public variable. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 6000 + person2: + age: 12 + is_citizen_or_legal_immigrant: false + ssi: 0 + employment_income: 6000 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 25000 + person4: + age: 40 + is_citizen_or_legal_immigrant: false + ssi: 0 + employment_income: 15000 + spm_units: + spm_unit1: + members: + - person1 + - person2 + wv_works: 0 + spm_unit2: + members: + - person3 + wv_works: 0 + spm_unit3: + members: + - person4 + wv_works: 0 + households: + household1: + members: + - person1 + - person2 + state_code: WV + household2: + members: + - person3 + state_code: VA + household3: + members: + - person4 + state_code: WV + output: + wv_lieap_countable_income: + - 12000 + - 0 + - 15000 + +- name: Case 9, the current FY2027 manual preserves recurring and excluded income treatment. + # Current manual A.1-3 retain the income rules; exclusions are now A.5. + # 2_000 + 1_000 + 300 + 400 + 500 + ordinary VA 600 + WV WORKS 1_200 = 6_000. + # RSDI 18_000, SSI 1_200 and educational assistance 800 remain excluded. + # The new Zero Income A.4 is about responsibility and adds no income to this fixture. + period: 2027 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + employment_income: 2000 + general_assistance: 300 + taxable_private_pension_income: 400 + taxable_ira_distributions: 500 + veterans_benefits: 600 + social_security_retirement: 18000 + person2: + age: 17 + is_citizen_or_legal_immigrant: false + ssi: 1200 + employment_income: 1000 + educational_assistance: 800 + spm_units: + spm_unit1: + members: + - person1 + - person2 + wv_works: + 2027-01: 100 + 2027-02: 100 + 2027-03: 100 + 2027-04: 100 + 2027-05: 100 + 2027-06: 100 + 2027-07: 100 + 2027-08: 100 + 2027-09: 100 + 2027-10: 100 + 2027-11: 100 + 2027-12: 100 + households: + household1: + members: + - person1 + - person2 + state_code: WV + output: + wv_lieap_countable_income: + - 6000 + +- name: Case 10, estate losses do not offset wages or another member estate income. + period: 2026 + absolute_error_margin: 0.01 + # No-deduction rule applied to an input explicitly defined as net income or loss. + # Person 1 wages 12_000 plus zero from their -10_000 estate loss, + # plus Person 2 recurring estate income 1_000 = 13_000. + # Flooring after summing member estates would wrongly erase the positive 1_000. + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 12_000 + estate_income: -10_000 + ssi: 0 + person2: + age: 35 + is_citizen_or_legal_immigrant: true + estate_income: 1_000 + ssi: 0 + spm_units: + spm_unit1: + members: [person1, person2] + wv_works: 0 + households: + household1: + members: [person1, person2] + state_code: WV + output: + wv_lieap_countable_income: 13_000 + +# Military pay is separate from pension_income. Rental losses cannot erase pensions or a different member's positive rent. +# Expected [60_000, 30_000, 12_000 + 1_000] are supported countable-income outputs only. +- name: Case 11, military retirement and positive receipts survive rental losses. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + military_retirement_pay: 60_000 + person2_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + taxable_private_pension_income: 30_000 + rental_income: -30_000 + person3_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + employment_income: 12_000 + rental_income: -10_000 + person3_2: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + rental_income: 1_000 + spm_units: + spm_unit1: + members: + - person1_1 + wv_works: 0 + spm_unit2: + members: + - person2_1 + wv_works: 0 + spm_unit3: + members: + - person3_1 + - person3_2 + wv_works: 0 + tax_units: + tax_unit1: + members: + - person1_1 + tax_unit2: + members: + - person2_1 + tax_unit3: + members: + - person3_1 + - person3_2 + households: + household1: + members: + - person1_1 + state_code: WV + household2: + members: + - person2_1 + state_code: WV + household3: + members: + - person3_1 + - person3_2 + state_code: WV + output: + wv_lieap_countable_income: + - 60_000 + - 30_000 + - 13_000 + +# Reported zero falls back to modeled UI; nonzero reported values override it. +# Negative reported UI is zero for LIEAP, retaining the 12_000 wages. +- name: Case 12, shared unemployment receipts retain overrides and floor negative amounts. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + employment_income: 12_000 + unemployment_compensation: 0 + modeled_state_unemployment_compensation: 6_000 + person2_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + employment_income: 12_000 + unemployment_compensation: 1_200 + modeled_state_unemployment_compensation: 6_000 + person3_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + employment_income: 12_000 + unemployment_compensation: -100 + modeled_state_unemployment_compensation: 6_000 + spm_units: + spm_unit1: + members: + - person1_1 + wv_works: 0 + spm_unit2: + members: + - person2_1 + wv_works: 0 + spm_unit3: + members: + - person3_1 + wv_works: 0 + tax_units: + tax_unit1: + members: + - person1_1 + tax_unit2: + members: + - person2_1 + tax_unit3: + members: + - person3_1 + households: + household1: + members: + - person1_1 + state_code: WV + household2: + members: + - person2_1 + state_code: WV + household3: + members: + - person3_1 + state_code: WV + output: + total_unemployment_compensation: + - 6_000 + - 1_200 + - -100 + wv_lieap_countable_income: + - 18_000 + - 13_200 + - 12_000 + +# Component receipt control: the supplied annual WV WORKS 6_000 represents 500/month. +# Generic TANF annualizes once and suppresses the benefit for the nonparticipant. +- name: Case 13, monthly TANF receipt counts once only for participants. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + employment_income: 6_000 + person1_2: + age: 8 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + person2_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + employment_income: 6_000 + person2_2: + age: 8 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + spm_units: + spm_unit1: + members: + - person1_1 + - person1_2 + wv_works: 6_000 + takes_up_tanf_if_eligible: true + spm_unit2: + members: + - person2_1 + - person2_2 + wv_works: 6_000 + takes_up_tanf_if_eligible: false + tax_units: + tax_unit1: + members: + - person1_1 + - person1_2 + tax_unit2: + members: + - person2_1 + - person2_2 + households: + household1: + members: + - person1_1 + - person1_2 + state_code: WV + household2: + members: + - person2_1 + - person2_2 + state_code: WV + output: + tanf: + - 6_000 + - 0 + wv_lieap_countable_income: + - 12_000 + - 6_000 + +# No WV WORKS or TANF entitlement override. A zero-income parent and child have a +# modeled size-two payment standard of 480/month, hence 5_760 annually. +# The eligible nonparticipant receives zero. This tests income receipt handling. +- name: Case 14, actual modeled WV WORKS flows into income only when received. + period: 2027 + absolute_error_margin: 0.01 + input: + people: + person1_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + employment_income_before_lsr: 0 + is_tax_unit_head_or_spouse: true + person1_2: + age: 8 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + is_tax_unit_dependent: true + person2_1: + age: 40 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + employment_income_before_lsr: 0 + is_tax_unit_head_or_spouse: true + person2_2: + age: 8 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security: 0 + is_tax_unit_dependent: true + spm_units: + spm_unit1: + members: + - person1_1 + - person1_2 + snap: 0 + takes_up_tanf_if_eligible: true + spm_unit2: + members: + - person2_1 + - person2_2 + snap: 0 + takes_up_tanf_if_eligible: false + tax_units: + tax_unit1: + members: + - person1_1 + - person1_2 + tax_unit2: + members: + - person2_1 + - person2_2 + households: + household1: + members: + - person1_1 + - person1_2 + state_code: WV + household2: + members: + - person2_1 + - person2_2 + state_code: WV + output: + tanf: + - 5_760 + - 0 + wv_lieap_countable_income: + - 5_760 + - 0 + +# Manual 21.3.1.A.3 counts all sources; 21.3.1.A.5 excludes only SSA's RSDI and +# SSI, so Railroad Retirement Board payments of 20,000 count and RSDI of 6,000 +# does not. +- name: Case 15, railroad retirement counts although RSDI does not. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 66 + is_citizen_or_legal_immigrant: true + ssi: 0 + social_security_retirement: 6_000 + railroad_benefits: 20_000 + spm_units: + spm_unit: + members: [person1] + wv_works: 0 + households: + household: + members: [person1] + state_code: WV + output: + wv_lieap_countable_income: 20_000 + +# Manual 21.3.1.A.3 counts all sources and prorates recurring receipts such as a +# yearly mineral-rights check, so 3,000 of recurring miscellaneous income counts. +- name: Case 16, recurring miscellaneous receipts count under the all-source rule. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + is_citizen_or_legal_immigrant: true + ssi: 0 + miscellaneous_income: 3_000 + spm_units: + spm_unit: + members: [person1] + wv_works: 0 + households: + household: + members: [person1] + state_code: WV + output: + wv_lieap_countable_income: 3_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_household_size.yaml new file mode 100644 index 00000000000..61280925358 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_household_size.yaml @@ -0,0 +1,127 @@ +# Household composition: earlier official IMM 21.3.1.B, physical page 1735; +# current IMM 21.3.1.B and citizenship, physical pages 1729 and 1734. +# https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1735 +# https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1729 +# The SPM unit stands in for the manual's one-household assistance group. +# These component tests make no claim about income or final benefit eligibility. + +- name: Case 1, one qualified adult is counted. + period: 2026 + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household1: + members: [person1] + state_code: WV + output: + wv_lieap_household_size: 1 + +- name: Case 2, qualified adults and children count while nonqualified members do not. + period: 2026 + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true} + person2: {age: 38, is_citizen_or_legal_immigrant: false} + person3: {age: 15, is_citizen_or_legal_immigrant: true} + person4: {age: 8, is_citizen_or_legal_immigrant: true} + person5: {age: 65, is_citizen_or_legal_immigrant: false} + spm_units: + spm_unit1: + members: [person1, person2, person3, person4, person5] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household1: + members: [person1, person2, person3, person4, person5] + state_code: WV + output: + wv_lieap_household_size: 3 + +- name: Case 3, an entirely nonqualified household has no qualified members. + period: 2026 + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: false} + person2: {age: 38, is_citizen_or_legal_immigrant: false} + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household1: + members: [person1, person2] + state_code: WV + output: + wv_lieap_household_size: 0 + +- name: Case 4, qualified children count even when the adults are nonqualified. + period: 2026 + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: false} + person2: {age: 38, is_citizen_or_legal_immigrant: false} + person3: {age: 15, is_citizen_or_legal_immigrant: true} + person4: {age: 8, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1, person2, person3, person4] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household1: + members: [person1, person2, person3, person4] + state_code: WV + output: + wv_lieap_household_size: 2 + +- name: Case 5, mixed states and qualification counts remain independent. + period: 2026 + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true} + person2: {age: 38, is_citizen_or_legal_immigrant: false} + person3: {age: 40, is_citizen_or_legal_immigrant: true} + person4: {age: 38, is_citizen_or_legal_immigrant: true} + person5: {age: 40, is_citizen_or_legal_immigrant: true} + person6: {age: 38, is_citizen_or_legal_immigrant: true} + person7: {age: 8, is_citizen_or_legal_immigrant: true} + person8: {age: 50, is_citizen_or_legal_immigrant: false} + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + spm_unit2: + members: [person3, person4] + heating_type: NATURAL_GAS + gas_expense: 1_200 + spm_unit3: + members: [person5, person6, person7] + heating_type: NATURAL_GAS + gas_expense: 1_200 + spm_unit4: + members: [person8] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household1: + members: [person1, person2] + state_code: WV + household2: + members: [person3, person4] + state_code: OH + household3: + members: [person5, person6, person7] + state_code: WV + household4: + members: [person8] + state_code: WV + output: + wv_lieap_household_size: [1, 0, 3, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_income_eligible.yaml new file mode 100644 index 00000000000..7af280a0a8f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_income_eligible.yaml @@ -0,0 +1,105 @@ +# Current Income Maintenance Manual, section 21.3.1.A, physical page 1726. +# https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1726 + +- name: Case 1, the FY2026 ceiling is inclusive with qualified and state guards. + period: 2026 + # One qualified person has a $2,454 monthly ceiling, or $29,448 annually. + # The second row earns $2,454.01 per month. No qualified member must fail + # even when both countable income and the household limit are zero. + input: + state_code: [WV, WV, WV, OH] + age: [40, 40, 40, 40] + is_citizen_or_legal_immigrant: [true, true, false, true] + employment_income: [29_448, 29_448.12, 0, 0] + output: + wv_lieap_income_limit: [29_448, 29_448, 0, 0] + wv_lieap_income_eligible: [true, false, false, false] + +- name: Case 2, the FY2027 ceiling remains inclusive without changing the formula. + period: 2027 + # The requested-year one-person limit is $2,550 monthly, or $30,600 annually. + input: + state_code: [WV, WV] + age: [40, 40] + is_citizen_or_legal_immigrant: [true, true] + employment_income: [30_600, 30_600.12] + output: + wv_lieap_income_eligible: [true, false] + +- name: Case 3, reported SNAP TANF or SSI receipt does not bypass the ceiling. + period: 2026 + # Every two-person group has $40,000 wages, above its $3,209 * 12 = $38,508 + # ceiling. Reported receipt facts do not override the manual's income test. + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income_before_lsr: 40_000 + person2: + age: 8 + is_citizen_or_legal_immigrant: true + person3: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income_before_lsr: 40_000 + person4: + age: 8 + is_citizen_or_legal_immigrant: true + person5: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income_before_lsr: 40_000 + person6: + age: 8 + is_citizen_or_legal_immigrant: true + receives_ssi: + 2026-01: true + spm_units: + spm_unit1: + members: [person1, person2] + receives_snap: + 2026-01: true + spm_unit2: + members: [person3, person4] + receives_tanf: + 2026-01: true + spm_unit3: + members: [person5, person6] + households: + household1: {members: [person1, person2], state_code: WV} + household2: {members: [person3, person4], state_code: WV} + household3: {members: [person5, person6], state_code: WV} + output: + wv_lieap_income_eligible: [false, false, false] + +- name: Case 4, nonqualified members income counts without increasing the limit. + period: 2026 + # Both groups have $36,000 wages. With one qualified person, the limit is + # $29,448; with two qualified people, the limit is $38,508. + input: + people: + person1: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 18_000 + person2: + age: 40 + is_citizen_or_legal_immigrant: false + employment_income: 18_000 + person3: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 18_000 + person4: + age: 40 + is_citizen_or_legal_immigrant: true + employment_income: 18_000 + spm_units: + spm_unit1: {members: [person1, person2]} + spm_unit2: {members: [person3, person4]} + households: + household1: {members: [person1, person2], state_code: WV} + household2: {members: [person3, person4], state_code: WV} + output: + wv_lieap_income_eligible: [false, true] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_income_limit.yaml new file mode 100644 index 00000000000..10318e54403 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/dhhr/lieap/wv_lieap_income_limit.yaml @@ -0,0 +1,348 @@ +# Sources: the FY2026 chart prints sizes 1-10 and adds $688 for each further person. +# https://bfa.wv.gov/utility-assistancelieap +# https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1780 +# FY2027 adopted operational IMM gives separately verified sizes 1-11. +# https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1775 +# The 60% SMI through 7 and 150% FPG from 8 split is explicit in the accepted FY2026 plan. +# https://liheapch.acf.gov/docs/2026/state-plans/WV_Plan_2026.pdf#page=11 +# Expected limits are the published monthly amounts x 12, stopped at the ceiling of +# 42 U.S.C. 8624(b)(2)(B): HHS's 60% SMI amounts through 7, 150% of the guideline from 8. +# https://www.law.cornell.edu/uscode/text/42/8624#b_2_B +# https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf#page=3 +# https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_Att4SMITable_States_FY2027.pdf#page=3 +# Both were checked independently by hand; no model formula was used. +# FY2026 size 11 is 8831/month: the chart's 8144 + 688 = 8832 is above 150% of the +# guideline, 8831.25. +# Payment-grid overlaps and larger-family defects are outside this component. + +- name: Case 1, FY2026 limits for 1 through 11 qualified members stop at the federal ceiling. + period: 2026 + absolute_error_margin: 0.01 + # Size 1: 60% of requested-year SMI; published $2,454/month x 12 = $29,448/year. + # Size 2: 60% of requested-year SMI; published $3,209/month x 12 = $38,508/year. + # Size 3: published $3,965/month x 12 = $47,580/year, above HHS's $47,575. + # Size 4: published $4,720/month x 12 = $56,640/year, above HHS's $56,637. + # Size 5: published $5,475/month x 12 = $65,700/year, above HHS's $65,698. + # Size 6: 60% of requested-year SMI; published $6,230/month x 12 = $74,760/year. + # Size 7: published $6,372/month x 12 = $76,464/year, above HHS's $76,459. + # Size 8: published $6,769/month x 12 = $81,228/year, above 1.5 x $54,150 = $81,225. + # Size 9: 150% of prior-year FPG; published $7,456/month x 12 = $89,472/year. + # Size 10: published $8,144/month x 12 = $97,728/year, above 1.5 x $65,150 = $97,725. + # Size 11: 150% of prior-year FPG; published $8,831/month x 12 = $105,972/year. + input: + people: + person1: {age: 70, is_citizen_or_legal_immigrant: true} + person2: {age: 70, is_citizen_or_legal_immigrant: true} + person3: {age: 68, is_citizen_or_legal_immigrant: true} + person4: {age: 70, is_citizen_or_legal_immigrant: true} + person5: {age: 68, is_citizen_or_legal_immigrant: true} + person6: {age: 45, is_citizen_or_legal_immigrant: true} + person7: {age: 70, is_citizen_or_legal_immigrant: true} + person8: {age: 68, is_citizen_or_legal_immigrant: true} + person9: {age: 45, is_citizen_or_legal_immigrant: true} + person10: {age: 44, is_citizen_or_legal_immigrant: true} + person11: {age: 70, is_citizen_or_legal_immigrant: true} + person12: {age: 68, is_citizen_or_legal_immigrant: true} + person13: {age: 45, is_citizen_or_legal_immigrant: true} + person14: {age: 44, is_citizen_or_legal_immigrant: true} + person15: {age: 22, is_citizen_or_legal_immigrant: true} + person16: {age: 70, is_citizen_or_legal_immigrant: true} + person17: {age: 68, is_citizen_or_legal_immigrant: true} + person18: {age: 45, is_citizen_or_legal_immigrant: true} + person19: {age: 44, is_citizen_or_legal_immigrant: true} + person20: {age: 22, is_citizen_or_legal_immigrant: true} + person21: {age: 17, is_citizen_or_legal_immigrant: true} + person22: {age: 70, is_citizen_or_legal_immigrant: true} + person23: {age: 68, is_citizen_or_legal_immigrant: true} + person24: {age: 45, is_citizen_or_legal_immigrant: true} + person25: {age: 44, is_citizen_or_legal_immigrant: true} + person26: {age: 22, is_citizen_or_legal_immigrant: true} + person27: {age: 17, is_citizen_or_legal_immigrant: true} + person28: {age: 15, is_citizen_or_legal_immigrant: true} + person29: {age: 70, is_citizen_or_legal_immigrant: true} + person30: {age: 68, is_citizen_or_legal_immigrant: true} + person31: {age: 45, is_citizen_or_legal_immigrant: true} + person32: {age: 44, is_citizen_or_legal_immigrant: true} + person33: {age: 22, is_citizen_or_legal_immigrant: true} + person34: {age: 17, is_citizen_or_legal_immigrant: true} + person35: {age: 15, is_citizen_or_legal_immigrant: true} + person36: {age: 12, is_citizen_or_legal_immigrant: true} + person37: {age: 70, is_citizen_or_legal_immigrant: true} + person38: {age: 68, is_citizen_or_legal_immigrant: true} + person39: {age: 45, is_citizen_or_legal_immigrant: true} + person40: {age: 44, is_citizen_or_legal_immigrant: true} + person41: {age: 22, is_citizen_or_legal_immigrant: true} + person42: {age: 17, is_citizen_or_legal_immigrant: true} + person43: {age: 15, is_citizen_or_legal_immigrant: true} + person44: {age: 12, is_citizen_or_legal_immigrant: true} + person45: {age: 9, is_citizen_or_legal_immigrant: true} + person46: {age: 70, is_citizen_or_legal_immigrant: true} + person47: {age: 68, is_citizen_or_legal_immigrant: true} + person48: {age: 45, is_citizen_or_legal_immigrant: true} + person49: {age: 44, is_citizen_or_legal_immigrant: true} + person50: {age: 22, is_citizen_or_legal_immigrant: true} + person51: {age: 17, is_citizen_or_legal_immigrant: true} + person52: {age: 15, is_citizen_or_legal_immigrant: true} + person53: {age: 12, is_citizen_or_legal_immigrant: true} + person54: {age: 9, is_citizen_or_legal_immigrant: true} + person55: {age: 7, is_citizen_or_legal_immigrant: true} + person56: {age: 70, is_citizen_or_legal_immigrant: true} + person57: {age: 68, is_citizen_or_legal_immigrant: true} + person58: {age: 45, is_citizen_or_legal_immigrant: true} + person59: {age: 44, is_citizen_or_legal_immigrant: true} + person60: {age: 22, is_citizen_or_legal_immigrant: true} + person61: {age: 17, is_citizen_or_legal_immigrant: true} + person62: {age: 15, is_citizen_or_legal_immigrant: true} + person63: {age: 12, is_citizen_or_legal_immigrant: true} + person64: {age: 9, is_citizen_or_legal_immigrant: true} + person65: {age: 7, is_citizen_or_legal_immigrant: true} + person66: {age: 3, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: {members: [person1]} + spm_unit2: {members: [person2, person3]} + spm_unit3: {members: [person4, person5, person6]} + spm_unit4: {members: [person7, person8, person9, person10]} + spm_unit5: {members: [person11, person12, person13, person14, person15]} + spm_unit6: {members: [person16, person17, person18, person19, person20, person21]} + spm_unit7: {members: [person22, person23, person24, person25, person26, person27, person28]} + spm_unit8: {members: [person29, person30, person31, person32, person33, person34, person35, person36]} + spm_unit9: {members: [person37, person38, person39, person40, person41, person42, person43, person44, person45]} + spm_unit10: {members: [person46, person47, person48, person49, person50, person51, person52, person53, person54, person55]} + spm_unit11: {members: [person56, person57, person58, person59, person60, person61, person62, person63, person64, person65, person66]} + households: + household1: {members: [person1], state_code: WV} + household2: {members: [person2, person3], state_code: WV} + household3: {members: [person4, person5, person6], state_code: WV} + household4: {members: [person7, person8, person9, person10], state_code: WV} + household5: {members: [person11, person12, person13, person14, person15], state_code: WV} + household6: {members: [person16, person17, person18, person19, person20, person21], state_code: WV} + household7: {members: [person22, person23, person24, person25, person26, person27, person28], state_code: WV} + household8: {members: [person29, person30, person31, person32, person33, person34, person35, person36], state_code: WV} + household9: {members: [person37, person38, person39, person40, person41, person42, person43, person44, person45], state_code: WV} + household10: {members: [person46, person47, person48, person49, person50, person51, person52, person53, person54, person55], state_code: WV} + household11: {members: [person56, person57, person58, person59, person60, person61, person62, person63, person64, person65, person66], state_code: WV} + output: + wv_lieap_income_limit: + - 29_448 + - 38_508 + - 47_575 + - 56_637 + - 65_698 + - 74_760 + - 76_459 + - 81_225 + - 89_472 + - 97_725 + - 105_972 + +- name: Case 2, FY2027 limits for 1 through 11 qualified members stop at the federal ceiling. + period: 2027 + absolute_error_margin: 0.01 + # Size 1: 60% of requested-year SMI; published $2,550/month x 12 = $30,600/year. + # Size 2: published $3,335/month x 12 = $40,020/year, above HHS's $40,019. + # Size 3: published $4,120/month x 12 = $49,440/year, above HHS's $49,435. + # Size 4: 60% of requested-year SMI; published $4,904/month x 12 = $58,848/year. + # Size 5: 60% of requested-year SMI; published $5,689/month x 12 = $68,268/year. + # Size 6: published $6,474/month x 12 = $77,688/year, above HHS's $77,684. + # Size 7: published $6,621/month x 12 = $79,452/year, above HHS's $79,450. + # Size 8: 150% of prior-year FPG; published $6,965/month x 12 = $83,580/year. + # Size 9: 150% of prior-year FPG; published $7,675/month x 12 = $92,100/year. + # Size 10: 150% of prior-year FPG; published $8,385/month x 12 = $100,620/year. + # Size 11: 150% of prior-year FPG; published $9,095/month x 12 = $109,140/year. + input: + people: + person1: {age: 70, is_citizen_or_legal_immigrant: true} + person2: {age: 70, is_citizen_or_legal_immigrant: true} + person3: {age: 68, is_citizen_or_legal_immigrant: true} + person4: {age: 70, is_citizen_or_legal_immigrant: true} + person5: {age: 68, is_citizen_or_legal_immigrant: true} + person6: {age: 45, is_citizen_or_legal_immigrant: true} + person7: {age: 70, is_citizen_or_legal_immigrant: true} + person8: {age: 68, is_citizen_or_legal_immigrant: true} + person9: {age: 45, is_citizen_or_legal_immigrant: true} + person10: {age: 44, is_citizen_or_legal_immigrant: true} + person11: {age: 70, is_citizen_or_legal_immigrant: true} + person12: {age: 68, is_citizen_or_legal_immigrant: true} + person13: {age: 45, is_citizen_or_legal_immigrant: true} + person14: {age: 44, is_citizen_or_legal_immigrant: true} + person15: {age: 22, is_citizen_or_legal_immigrant: true} + person16: {age: 70, is_citizen_or_legal_immigrant: true} + person17: {age: 68, is_citizen_or_legal_immigrant: true} + person18: {age: 45, is_citizen_or_legal_immigrant: true} + person19: {age: 44, is_citizen_or_legal_immigrant: true} + person20: {age: 22, is_citizen_or_legal_immigrant: true} + person21: {age: 17, is_citizen_or_legal_immigrant: true} + person22: {age: 70, is_citizen_or_legal_immigrant: true} + person23: {age: 68, is_citizen_or_legal_immigrant: true} + person24: {age: 45, is_citizen_or_legal_immigrant: true} + person25: {age: 44, is_citizen_or_legal_immigrant: true} + person26: {age: 22, is_citizen_or_legal_immigrant: true} + person27: {age: 17, is_citizen_or_legal_immigrant: true} + person28: {age: 15, is_citizen_or_legal_immigrant: true} + person29: {age: 70, is_citizen_or_legal_immigrant: true} + person30: {age: 68, is_citizen_or_legal_immigrant: true} + person31: {age: 45, is_citizen_or_legal_immigrant: true} + person32: {age: 44, is_citizen_or_legal_immigrant: true} + person33: {age: 22, is_citizen_or_legal_immigrant: true} + person34: {age: 17, is_citizen_or_legal_immigrant: true} + person35: {age: 15, is_citizen_or_legal_immigrant: true} + person36: {age: 12, is_citizen_or_legal_immigrant: true} + person37: {age: 70, is_citizen_or_legal_immigrant: true} + person38: {age: 68, is_citizen_or_legal_immigrant: true} + person39: {age: 45, is_citizen_or_legal_immigrant: true} + person40: {age: 44, is_citizen_or_legal_immigrant: true} + person41: {age: 22, is_citizen_or_legal_immigrant: true} + person42: {age: 17, is_citizen_or_legal_immigrant: true} + person43: {age: 15, is_citizen_or_legal_immigrant: true} + person44: {age: 12, is_citizen_or_legal_immigrant: true} + person45: {age: 9, is_citizen_or_legal_immigrant: true} + person46: {age: 70, is_citizen_or_legal_immigrant: true} + person47: {age: 68, is_citizen_or_legal_immigrant: true} + person48: {age: 45, is_citizen_or_legal_immigrant: true} + person49: {age: 44, is_citizen_or_legal_immigrant: true} + person50: {age: 22, is_citizen_or_legal_immigrant: true} + person51: {age: 17, is_citizen_or_legal_immigrant: true} + person52: {age: 15, is_citizen_or_legal_immigrant: true} + person53: {age: 12, is_citizen_or_legal_immigrant: true} + person54: {age: 9, is_citizen_or_legal_immigrant: true} + person55: {age: 7, is_citizen_or_legal_immigrant: true} + person56: {age: 70, is_citizen_or_legal_immigrant: true} + person57: {age: 68, is_citizen_or_legal_immigrant: true} + person58: {age: 45, is_citizen_or_legal_immigrant: true} + person59: {age: 44, is_citizen_or_legal_immigrant: true} + person60: {age: 22, is_citizen_or_legal_immigrant: true} + person61: {age: 17, is_citizen_or_legal_immigrant: true} + person62: {age: 15, is_citizen_or_legal_immigrant: true} + person63: {age: 12, is_citizen_or_legal_immigrant: true} + person64: {age: 9, is_citizen_or_legal_immigrant: true} + person65: {age: 7, is_citizen_or_legal_immigrant: true} + person66: {age: 3, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: {members: [person1]} + spm_unit2: {members: [person2, person3]} + spm_unit3: {members: [person4, person5, person6]} + spm_unit4: {members: [person7, person8, person9, person10]} + spm_unit5: {members: [person11, person12, person13, person14, person15]} + spm_unit6: {members: [person16, person17, person18, person19, person20, person21]} + spm_unit7: {members: [person22, person23, person24, person25, person26, person27, person28]} + spm_unit8: {members: [person29, person30, person31, person32, person33, person34, person35, person36]} + spm_unit9: {members: [person37, person38, person39, person40, person41, person42, person43, person44, person45]} + spm_unit10: {members: [person46, person47, person48, person49, person50, person51, person52, person53, person54, person55]} + spm_unit11: {members: [person56, person57, person58, person59, person60, person61, person62, person63, person64, person65, person66]} + households: + household1: {members: [person1], state_code: WV} + household2: {members: [person2, person3], state_code: WV} + household3: {members: [person4, person5, person6], state_code: WV} + household4: {members: [person7, person8, person9, person10], state_code: WV} + household5: {members: [person11, person12, person13, person14, person15], state_code: WV} + household6: {members: [person16, person17, person18, person19, person20, person21], state_code: WV} + household7: {members: [person22, person23, person24, person25, person26, person27, person28], state_code: WV} + household8: {members: [person29, person30, person31, person32, person33, person34, person35, person36], state_code: WV} + household9: {members: [person37, person38, person39, person40, person41, person42, person43, person44, person45], state_code: WV} + household10: {members: [person46, person47, person48, person49, person50, person51, person52, person53, person54, person55], state_code: WV} + household11: {members: [person56, person57, person58, person59, person60, person61, person62, person63, person64, person65, person66], state_code: WV} + output: + wv_lieap_income_limit: + - 30_600 + - 40_019 + - 49_435 + - 58_848 + - 68_268 + - 77_684 + - 79_450 + - 83_580 + - 92_100 + - 100_620 + - 109_140 + +- name: Case 3, eight residents with seven qualified members stay on the SMI branch. + period: 2026 + absolute_error_margin: 0.01 + # Qualified size 7: HHS's FY2026 amount 76459, below the chart's 6372 x 12 = 76464. + input: + people: + person1: {age: 70, is_citizen_or_legal_immigrant: true} + person2: {age: 68, is_citizen_or_legal_immigrant: true} + person3: {age: 45, is_citizen_or_legal_immigrant: true} + person4: {age: 44, is_citizen_or_legal_immigrant: true} + person5: {age: 22, is_citizen_or_legal_immigrant: true} + person6: {age: 17, is_citizen_or_legal_immigrant: true} + person7: {age: 15, is_citizen_or_legal_immigrant: true} + person8: {age: 12, is_citizen_or_legal_immigrant: false} + spm_units: + spm_unit1: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + households: + household1: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: WV + output: + wv_lieap_income_limit: 76_459 + +- name: Case 4, nine residents with eight qualified members use the FPG branch. + period: 2026 + absolute_error_margin: 0.01 + # Qualified size 8: 1.5 x 54150 = 81225, below the chart's 6769 x 12 = 81228. + input: + people: + person1: {age: 70, is_citizen_or_legal_immigrant: true} + person2: {age: 68, is_citizen_or_legal_immigrant: true} + person3: {age: 45, is_citizen_or_legal_immigrant: true} + person4: {age: 44, is_citizen_or_legal_immigrant: true} + person5: {age: 22, is_citizen_or_legal_immigrant: true} + person6: {age: 17, is_citizen_or_legal_immigrant: true} + person7: {age: 15, is_citizen_or_legal_immigrant: true} + person8: {age: 12, is_citizen_or_legal_immigrant: true} + person9: {age: 9, is_citizen_or_legal_immigrant: false} + spm_units: + spm_unit1: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + households: + household1: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: WV + output: + wv_lieap_income_limit: 81_225 + +- name: Case 5, mixed WV and neighboring-state households retain independent limits. + period: 2026 + absolute_error_margin: 0.01 + # WV size 1 uses 2454 monthly and size 8 stops at 81225; the WV variable is zero in Ohio. + input: + people: + person1: {age: 40, is_citizen_or_legal_immigrant: true} + person2: {age: 70, is_citizen_or_legal_immigrant: true} + person3: {age: 68, is_citizen_or_legal_immigrant: true} + person4: {age: 45, is_citizen_or_legal_immigrant: true} + person5: {age: 44, is_citizen_or_legal_immigrant: true} + person6: {age: 22, is_citizen_or_legal_immigrant: true} + person7: {age: 17, is_citizen_or_legal_immigrant: true} + person8: {age: 15, is_citizen_or_legal_immigrant: true} + person9: {age: 12, is_citizen_or_legal_immigrant: true} + person10: {age: 70, is_citizen_or_legal_immigrant: true} + person11: {age: 68, is_citizen_or_legal_immigrant: true} + person12: {age: 45, is_citizen_or_legal_immigrant: true} + person13: {age: 44, is_citizen_or_legal_immigrant: true} + person14: {age: 22, is_citizen_or_legal_immigrant: true} + person15: {age: 17, is_citizen_or_legal_immigrant: true} + person16: {age: 15, is_citizen_or_legal_immigrant: true} + person17: {age: 12, is_citizen_or_legal_immigrant: true} + spm_units: + spm_unit1: + members: [person1] + spm_unit2: + members: [person2, person3, person4, person5, person6, person7, person8, person9] + spm_unit3: + members: [person10, person11, person12, person13, person14, person15, person16, person17] + households: + household1: + members: [person1] + state_code: WV + household2: + members: [person2, person3, person4, person5, person6, person7, person8, person9] + state_code: OH + household3: + members: [person10, person11, person12, person13, person14, person15, person16, person17] + state_code: WV + output: + wv_lieap_income_limit: [29448, 0, 81225] diff --git a/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap.py b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap.py new file mode 100644 index 00000000000..34d7aba7073 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap.py @@ -0,0 +1,56 @@ +from policyengine_us.model_api import * + + +class wv_lieap(Variable): + value_type = float + entity = SPMUnit + label = "West Virginia modeled regular heating LIEAP payment" + unit = USD + definition_period = YEAR + defined_for = "wv_lieap_income_eligible" + reference = ( + # PDF pages 1736-1738,1760-1762,1780-1781 + "https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1736", + # PDF pages 1730-1734,1757-1758,1775-1776 + "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1730", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.wv.dhhr.lieap.payment + size = spm_unit("wv_lieap_household_size", period) + income = spm_unit("wv_lieap_countable_income", period) / MONTHS_IN_YEAR + # Use the printed upper bounds continuously, including cents: the printed + # integer lower bounds overlap and leave cent gaps. + band = p.income_band.calc(income, right=True) + # Exact compression of every occupied published cell, not extrapolation. + # In both verified years, income eligibility confines sizes 1-20 to occupied + # table cells. + base = p.base_amount + p.amount_step * (size - 1 - band) + heating = spm_unit("heating_type", period) + types = heating.possible_values + multiplier = select( + [ + heating == types.ELECTRICITY, + heating == types.NATURAL_GAS, + (heating == types.FUEL_OIL) + | (heating == types.KEROSENE) + | (heating == types.PROPANE) + | (heating == types.WOOD) + | (heating == types.COAL), + ], + [ + p.fuel_multiplier.electricity, + p.fuel_multiplier.natural_gas, + p.fuel_multiplier.bulk_fuel, + ], + default=0, + ) + # Integer bases and three-decimal multipliers give exact dollar mills. + # Convert those to cents half up, matching the printed $70.79/$147.02. + mills = np.rint(base * multiplier * 1_000) + amount = np.floor((mills + 5) / 10) / 100 + pays_for_heat = spm_unit("has_heating_expense", period) + # Above 20 members is unmodeled coverage, not legal ineligibility. + # Existing heating-cost facts approximate the documented obligation; + # designated rent charges and some dwelling facts remain unobserved. + return where((size <= p.max_household_size) & pays_for_heat, amount, 0) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_countable_income.py b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_countable_income.py new file mode 100644 index 00000000000..9863a956079 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_countable_income.py @@ -0,0 +1,29 @@ +from policyengine_us.model_api import * + + +class wv_lieap_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "West Virginia LIEAP annual countable income" + unit = USD + definition_period = YEAR + defined_for = StateCode.WV + reference = ( + # PDF pages 1732-1735 + "https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1732", + # PDF pages 1726-1729 + "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1726", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.wv.dhhr.lieap.income + person = spm_unit.members + # Floor each member/source before aggregation so losses cannot erase + # another receipt. The operative manual counts minor and nonqualified members' income, + # TANF and general assistance. RSDI and SSI are expressly excluded. + # Annual flows approximate recurring application-month receipts. Generic + # VA cannot identify excluded Aid and Attendance. + income = 0 + for source in p.sources: + income = income + max_(add(person, period, [source]), 0) + return spm_unit.sum(income) + spm_unit("tanf", period) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_household_size.py b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_household_size.py new file mode 100644 index 00000000000..2379ae38796 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_household_size.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class wv_lieap_household_size(Variable): + value_type = int + entity = SPMUnit + label = "West Virginia LIEAP qualified household size" + definition_period = YEAR + defined_for = StateCode.WV + reference = ( + # PDF pages 1735,1739 + "https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1735", + # PDF pages 1729,1734 + "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1729", + ) + # The manual treats everyone living in the home as one assistance group, whether + # or not they share heating costs. The SPM unit stands in for that group, so a + # household with more than one SPM unit is split. Anyone already paid as part of + # another group leaves the size and income, but that receipt history is + # unavailable. Nonqualified members' income remains countable. + adds = ["is_citizen_or_legal_immigrant"] diff --git a/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_eligible.py new file mode 100644 index 00000000000..9c4dd83ead8 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_eligible.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class wv_lieap_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "West Virginia LIEAP income eligible" + definition_period = YEAR + defined_for = StateCode.WV + reference = ( + # PDF pages 1732,1756 + "https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1732", + # PDF pages 1726,1752 + "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1726", + ) + + def formula(spm_unit, period, parameters): + size = spm_unit("wv_lieap_household_size", period) + income = spm_unit("wv_lieap_countable_income", period) + limit = spm_unit("wv_lieap_income_limit", period) + return (size > 0) & (income <= limit) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_limit.py b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_limit.py new file mode 100644 index 00000000000..c8d0e611003 --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_limit.py @@ -0,0 +1,47 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import liheap_smi_limit +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class wv_lieap_income_limit(Variable): + value_type = float + entity = SPMUnit + label = "West Virginia LIEAP annual income limit" + unit = USD + definition_period = YEAR + defined_for = StateCode.WV + reference = ( + "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", + # FY2026 federal amounts, PDF pages 3,6 + "https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf#page=3", + # FY2027 federal amounts, PDF pages 3,6 + "https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_Att4SMITable_States_FY2027.pdf#page=3", + # PDF pages 9,11 + "https://liheapch.acf.gov/docs/2026/state-plans/WV_Plan_2026.pdf#page=9", + # PDF pages 9,12 + "https://bfa.wv.gov/media/39990/download?inline=#page=9", + # FY2026 chart, PDF pages 407,1785 + "https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=407", + # FY2027 chart, PDF pages 405,1779 + "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=405", + ) + + def formula(spm_unit, period, parameters): + size = spm_unit("wv_lieap_household_size", period) + state = spm_unit.household("state_code_str", period) + group = spm_unit.household("state_group_str", period) + p = parameters(period).gov.states.wv.dhhr.lieap.eligibility + annual_smi = liheap_smi_limit(size, state, p.smi_rate, period, parameters) + annual_fpg = p.fpg_rate * fpg( + size, group, period, parameters, year_lag=p.fpg_year_lag + ) + annual = where(size <= p.smi_max_household_size, annual_smi, annual_fpg) + # Nearest-dollar monthly rounding matches all ten published agency rows. + # Apply the actual guideline to additional members: the chart's rounded + # add-on for each member above ten overshoots 150% of the guideline. + monthly = np.floor(annual / MONTHS_IN_YEAR + 0.5) + # 42 U.S.C. 8624(b)(2)(B) pays no household above the greater of 60% of SMI + # and 150% of the guideline, which is annual at every size. A published + # monthly amount that rounds up therefore stops there. + limit = min_(monthly * MONTHS_IN_YEAR, annual) + return where(size > 0, limit, 0) diff --git a/policyengine_us/variables/gov/states/wv/dhhr/works/eligibility/wv_works_income_eligible.py b/policyengine_us/variables/gov/states/wv/dhhr/works/eligibility/wv_works_income_eligible.py index fa7f6129205..b36c79993d7 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/works/eligibility/wv_works_income_eligible.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/works/eligibility/wv_works_income_eligible.py @@ -6,7 +6,7 @@ class wv_works_income_eligible(Variable): entity = SPMUnit label = "West Virginia WV Works income eligible" definition_period = MONTH - reference = "https://bfa.wv.gov/media/40005/download?inline#page=593" + reference = "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=593" defined_for = StateCode.WV def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/wv/dhhr/works/income/earned/wv_works_countable_earned_income.py b/policyengine_us/variables/gov/states/wv/dhhr/works/income/earned/wv_works_countable_earned_income.py index 3276fb14015..3494a11287b 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/works/income/earned/wv_works_countable_earned_income.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/works/income/earned/wv_works_countable_earned_income.py @@ -7,7 +7,7 @@ class wv_works_countable_earned_income(Variable): label = "West Virginia WV Works countable earned income" unit = USD definition_period = MONTH - reference = "https://bfa.wv.gov/media/39948/download?inline#page=590" + reference = "https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=590" defined_for = StateCode.WV def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/wv/dhhr/works/income/unearned/wv_works_countable_unearned_income.py b/policyengine_us/variables/gov/states/wv/dhhr/works/income/unearned/wv_works_countable_unearned_income.py index b2eb5c7d7a7..8951527e16f 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/works/income/unearned/wv_works_countable_unearned_income.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/works/income/unearned/wv_works_countable_unearned_income.py @@ -7,7 +7,7 @@ class wv_works_countable_unearned_income(Variable): label = "West Virginia WV Works countable unearned income" unit = USD definition_period = MONTH - reference = "https://bfa.wv.gov/media/40005/download?inline#page=590" + reference = "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=590" defined_for = StateCode.WV def formula(spm_unit, period, parameters): diff --git a/policyengine_us/variables/gov/states/wv/dhhr/works/income/wv_works_countable_income.py b/policyengine_us/variables/gov/states/wv/dhhr/works/income/wv_works_countable_income.py index 8fb386f4947..1a0b79792d6 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/works/income/wv_works_countable_income.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/works/income/wv_works_countable_income.py @@ -7,7 +7,7 @@ class wv_works_countable_income(Variable): label = "West Virginia WV Works countable income" unit = USD definition_period = MONTH - reference = "https://bfa.wv.gov/media/40005/download?inline#page=593" + reference = "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=593" defined_for = StateCode.WV # Step 7: Add together the total countable earned and unearned income diff --git a/policyengine_us/variables/gov/states/wv/dhhr/works/wv_works.py b/policyengine_us/variables/gov/states/wv/dhhr/works/wv_works.py index 6a7a6d92c34..5e6cda75ef5 100644 --- a/policyengine_us/variables/gov/states/wv/dhhr/works/wv_works.py +++ b/policyengine_us/variables/gov/states/wv/dhhr/works/wv_works.py @@ -7,7 +7,7 @@ class wv_works(Variable): label = "West Virginia WV Works benefit" unit = USD definition_period = MONTH - reference = "https://bfa.wv.gov/media/40005/download?inline#page=593" + reference = "https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=593" defined_for = "wv_works_eligible" def formula(spm_unit, period, parameters): diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 15835a001d7..6025a2b3e21 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -11448,6 +11448,164 @@ candidates: threshold and federal-method conditions by year. Code not yet on main: gov/states/wv/tax/income/subtractions/wv_claim_of_right_subtraction.yaml, policyengine_us/variables/gov/states/wv/tax/income/subtractions/wv_subtractions.py, wv_claim_of_right_subtraction, gov.states.wv.tax.income.subtractions.claim_of_right.threshold.' +- id: us-wv:liheap-income-limit-above-federal-ceiling + program: liheap + years: + from: 2026 + to: 2027 + type: federal-fiscal + question: Can West Virginia's whole-dollar monthly LIEAP limits pay a household whose income exceeds both 150% of the + poverty guideline and HHS's 60% state median income amount? + sources: + - kind: statute + citation: 42 U.S.C. 8624(b)(2)(B) + url: https://www.law.cornell.edu/uscode/text/42/8624#b_2_B + - kind: guidance + citation: HHS LIHEAP IM 2025-02 Attachment 4, Mandatory Use in LIHEAP for FY26, West Virginia, pages 3 and 6 + url: https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf#page=3 + - kind: guidance + citation: HHS LIHEAP FY2027 Attachment 4, Mandatory Use in LIHEAP for FY27, West Virginia, pages 3 and 6 + url: https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_Att4SMITable_States_FY2027.pdf#page=3 + - kind: manual + citation: West Virginia Income Maintenance Manual, Chapter 4 Appendix A, PDF page 407 (FY2026 chart) + url: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=407 + - kind: manual + citation: West Virginia Income Maintenance Manual, update 881, Chapter 4 Appendix A, PDF page 405 (FY2027 chart) + url: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=405 + readings: + statute: Payments go only to households whose income does not exceed the greater of 150% of the poverty guideline + and 60% of the state median income that HHS publishes and adjusts for household size. + other: The charts round each monthly limit to the nearest dollar, and the FY2026 chart adds a rounded $688 for each + member above ten, which puts the limits above the federal maximum at several sizes. + example: In FY2026, three people with $47,578 of countable income and electric heat are within the printed $47,580 + limit ($3,965 a month), which would pay $253.75, but exceed the $47,575 federal maximum and receive $0 in the PR. + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_limit.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10618 + state: ruled + note: 'Ruled under the 2026-10-19 statute-first rule. The PR stops each limit at the federal maximum. Printed and capped + annual limits: FY2026 size 3, $47,580 and $47,575; 4, $56,640 and $56,637; 5, $65,700 and $65,698; 7, $76,464 and + $76,459; sizes 8 and 10, $3 lower ($81,228 and $81,225 at 8). From size 11 the FY2026 chart adds $688 a person, + while the PR uses 150% of the guideline, rounded by month and capped: $105,972 against the printed $105,984 at 11 + and $180,225 against $180,288 at 20. FY2027 size 2, $40,020 and $40,019; 3, $49,440 and + $49,435; 6, $77,688 and $77,684; 7, $79,452 and $79,450. Other sizes keep the printed amount, which rounds down or + equals the maximum. Verify each later fiscal-year chart.' + +- id: us-wv:liheap-plan-categorical-eligibility + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Do West Virginia households receiving TANF, SSI or SNAP bypass the LIEAP income test, as FY2026 plan item 1.4 + answers, or does the manual's income test apply to every assistance group? + sources: + - kind: manual + citation: West Virginia Income Maintenance Manual, 21.3.1.A and 21.4.9.A, PDF pages 1732 and 1756 + url: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1732 + - kind: plan + citation: West Virginia FY2026 LIHEAP State Plan, item 1.4, page 5 + url: https://liheapch.acf.gov/docs/2026/state-plans/WV_Plan_2026.pdf#page=5 + - kind: plan + citation: West Virginia submitted FY2027 LIHEAP State Plan, item 1.4, page 5 + url: https://bfa.wv.gov/media/39990/download?inline=#page=5 + readings: + statute: No statute is supplied; the manual denies a group above the ceiling, and its 21.4.9.A example verifies a + working member's income when another member receives SSI. + other: FY2026 plan item 1.4 answers Yes for TANF, SSI and SNAP in heating. The FY2027 plan answers No for all of them. + example: In FY2026, a two-person SNAP household with $40,000 of wages is above the $38,508 limit and ineligible under + the manual, and categorically eligible under plan item 1.4. + pe_us: + follows: gap-fill + code: + - policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_eligible.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10618 + state: ruled + note: 'Ruled 2026-10-06: follow the manual over the plan.' + +- id: us-wv:liheap-plan-income-and-benefit-items + program: liheap + years: + from: 2026 + to: 2027 + type: federal-fiscal + question: Do income sources and benefit factors follow West Virginia's manual or the check boxes in plan items 1.9 and + 2.5? + sources: + - kind: manual + citation: West Virginia Income Maintenance Manual, 21.3.1.A and 21.4.11.B, PDF pages 1732-1735 and 1761-1762 + url: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1732 + - kind: manual + citation: West Virginia Income Maintenance Manual, update 881, 21.3.1.A and 21.4.11.B, PDF pages 1726-1729 and + 1757-1758 + url: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1726 + - kind: plan + citation: West Virginia FY2026 LIHEAP State Plan, items 1.9 and 2.5, pages 6-7 and 11 + url: https://liheapch.acf.gov/docs/2026/state-plans/WV_Plan_2026.pdf#page=6 + - kind: plan + citation: West Virginia submitted FY2027 LIHEAP State Plan, items 1.9 and 2.5, pages 6-7 and 12 + url: https://bfa.wv.gov/media/39990/download?inline=#page=6 + readings: + statute: No statute is supplied; the manual considers all sources of income, excludes nonrecurring lump sums and sets + the payment by income, group size and energy type. + other: Plan item 1.9 leaves general assistance, TANF, cash gifts and (in FY2026 only) a child's earnings unchecked and + checks one-time lump sums. Plan item 2.5 also checks individual bill, energy burden and energy need. + example: In FY2026, a parent's $12,000 of wages and a 17-year-old's $6,000 of wages count $18,000 under the manual and + $12,000 under the plan. + pe_us: + follows: gap-fill + code: + - policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_countable_income.py + - policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap.py + - policyengine_us/parameters/gov/states/wv/dhhr/lieap/income/sources.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10618 + state: ruled + note: 'Ruled 2026-10-06: follow the manual over the plan. Veterans benefits have their own item, + us-wv:liheap-veterans-benefits.' + +- id: us-wv:liheap-veterans-benefits + program: liheap + years: + from: 2026 + to: 2027 + type: federal-fiscal + question: Does West Virginia LIEAP exclude all veterans benefits, as the agency's December 2025 announcement and the + plan's unchecked box read, or only VA Aid and Attendance payments, as both manual editions read? + sources: + - kind: manual + citation: West Virginia Income Maintenance Manual, 21.3.1.A.4, PDF pages 1734-1735 + url: https://web.archive.org/web/20260302130424/https://bfa.wv.gov/media/39948/download?inline#page=1734 + - kind: manual + citation: West Virginia Income Maintenance Manual, update 881, 21.3.1.A.5, PDF page 1729 + url: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1729 + - kind: agency-practice + citation: West Virginia Department of Human Services announcement, December 18, 2025 + url: https://dohs.wv.gov/article/west-virginia-department-human-services-announces-automatic-lieap-application-mailing-low + - kind: plan + citation: West Virginia FY2026 LIHEAP State Plan, item 1.9, page 7 + url: https://liheapch.acf.gov/docs/2026/state-plans/WV_Plan_2026.pdf#page=7 + readings: + statute: No statute is supplied; both manual editions list only "Veterans Affairs (VA) Aid and Attendance payments" + among the exclusions. + other: The announcement's income table says "Social Security & Veterans Benefits Excluded", and plan item 1.9 leaves + "Veterans Administration (VA) benefits" unchecked. + example: In FY2026, one person with electric heat, $20,000 of wages and $12,000 of VA compensation counts $32,000 and + receives $0 under the manual, and counts $20,000 and receives $280 under the announcement. + pe_us: + follows: gap-fill + code: + - policyengine_us/parameters/gov/states/wv/dhhr/lieap/income/sources.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10618 + state: unreviewed + note: PE-US follows the manual, whose two editions are both later than the announcement, and counts veterans_benefits in + full because the input cannot separate Aid and Attendance. + - id: us-wv:medicaid-ssi-related-non-cash-income-at-standard program: medicaid years: @@ -11465,10 +11623,10 @@ candidates: url: https://www.ecfr.gov/current/title-42/section-435.210 - kind: manual citation: West Virginia Income Maintenance Manual § 23.11.4 (consolidated PDF built 2026-10-05, PDF p.1889) - url: https://bfa.wv.gov/media/40005/download?inline#page=1889 + url: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=1889 - kind: manual citation: West Virginia Income Maintenance Manual § 4.14.3 Step 5 (PDF p.662) - url: https://bfa.wv.gov/media/40005/download?inline#page=662 + url: https://web.archive.org/web/20261023203756/https://bfa.wv.gov/media/40005/download?inline#page=662 readings: statute: The optional group covers people who meet SSI's income requirement, which admits income at or below the benefit rate.