diff --git a/changelog.d/oh-liheap.added.md b/changelog.d/oh-liheap.added.md new file mode 100644 index 00000000000..e7f8a80a878 --- /dev/null +++ b/changelog.d/oh-liheap.added.md @@ -0,0 +1 @@ +Add a partial Ohio HEAP model for household composition, income, eligibility and regular heating payments, with sourced historical payment caps and explicitly estimated later awards. diff --git a/policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml b/policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml new file mode 100644 index 00000000000..ae7cb296211 --- /dev/null +++ b/policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml @@ -0,0 +1,11 @@ +description: The US Department of Health and Human Services limits income-based exclusion to households with income of at least this percentage of the poverty guideline under the Low Income Home Energy Assistance Program. +# Pub. L. 98-558, section 605(a)(2), added the floor for fiscal year 1986 and later. +values: + 1985-10-01: 1.1 +metadata: + period: year + unit: /1 + label: LIHEAP poverty guideline income floor + reference: + - title: 42 U.S.C. 8624(b)(2)(B) + href: https://www.law.cornell.edu/uscode/text/42/8624 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_rate.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_rate.yaml new file mode 100644 index 00000000000..05830cbae46 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_rate.yaml @@ -0,0 +1,18 @@ +description: Ohio limits income to this multiple of the federal poverty guideline for households within the applicable size range under the Home Energy Assistance Program. +values: + 2022-07-01: 1.75 +metadata: + unit: /1 + period: year + label: Ohio HEAP federal poverty guideline rate + reference: + - title: Ohio 2022-2023 Energy Assistance Programs Guidelines, section E-2.2 + href: https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7 + - title: Ohio Energy Assistance Programs Application, July 2023-May 2024 + href: https://dam.assets.ohio.gov/image/upload/development.ohio.gov/individual/energyassistance/2023-2024-Heap-Application-ES-BW.pdf#page=1 + - title: Ohio Energy Assistance Programs Application, July 2024-May 2025 + href: https://clevelandohio.gov/sites/clevelandohio/files/aging/2024-2025_HEAP_application_B_W_1.pdf#page=1 + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026 + href: https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=1 + - title: Ohio JFS 00330 Energy Assistance Programs Application, July 2026-May 2027 + href: https://www.lccaa.net/wp-content/uploads/2026/07/2026-2027-EAP-Application-7-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_year_lag.yaml new file mode 100644 index 00000000000..5965febfc29 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_year_lag.yaml @@ -0,0 +1,17 @@ +description: Ohio uses federal poverty guidelines from this many years before the modeled benefit year under the Home Energy Assistance Program. +# Model year 2026 represents the July 2025-May 2026 program season. The +# 2022-2023 Guidelines print 175% of the 2022 guidelines ($8,260 per added +# member), and the 2024-2025 application prints 175% of the 2024 guidelines. +values: + 2022-07-01: 1 +metadata: + unit: year + period: year + label: Ohio HEAP federal poverty guideline year lag + reference: + - title: Ohio 2022-2023 Energy Assistance Programs Guidelines, section E-2.2 + href: https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7 + - title: Ohio Energy Assistance Programs Application, July 2024-May 2025 + href: https://clevelandohio.gov/sites/clevelandohio/files/aging/2024-2025_HEAP_application_B_W_1.pdf#page=1 + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026 + href: https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/maximum_fpg_household_size.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/maximum_fpg_household_size.yaml new file mode 100644 index 00000000000..3bd40cc76e2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/maximum_fpg_household_size.yaml @@ -0,0 +1,31 @@ +description: Ohio uses the federal poverty guideline income limit through this household size before switching to state median income under the Home Energy Assistance Program. +# The 2022-2023 Guidelines apply 175% FPG to every household size; the FY2023 +# plan's section 2.1 lists 60% SMI for all sizes, but the Guidelines govern. +# The July 2023-May 2024 application prints 175% FPG limits through size eight +# and adds $8,995 per added member, so that season keeps the all-sizes rule. +# The 2024-2025 application prints FPG limits through size seven, and the +# FY2025 plan's section 2.1 puts size eight on 60% SMI. +values: + 2022-07-01: .inf + 2024-07-01: 7 + 2025-07-01: 8 + 2026-07-01: 7 +metadata: + unit: person + period: year + label: Ohio HEAP maximum household size for poverty guideline limit + reference: + - title: Ohio 2022-2023 Energy Assistance Programs Guidelines, section E-2.2 + href: https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7 + - title: Ohio FY2023 LIHEAP State Plan, section 2.1 + href: https://liheapch.acf.gov/docs/2023/state-plans/OH_Plan_2023.pdf#page=8 + - title: Ohio Energy Assistance Programs Application, July 2023-May 2024 + href: https://dam.assets.ohio.gov/image/upload/development.ohio.gov/individual/energyassistance/2023-2024-Heap-Application-ES-BW.pdf#page=1 + - title: Ohio Energy Assistance Programs Application, July 2024-May 2025 + href: https://clevelandohio.gov/sites/clevelandohio/files/aging/2024-2025_HEAP_application_B_W_1.pdf#page=1 + - title: Ohio FY2025 LIHEAP State Plan, section 2.1 + href: https://liheapch.acf.gov/docs/2025/state-plans/OH_Plan_2025.pdf#page=8 + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026 + href: https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=1 + - title: Ohio JFS 00330 Energy Assistance Programs Application, July 2026-May 2027 + href: https://www.lccaa.net/wp-content/uploads/2026/07/2026-2027-EAP-Application-7-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/smi_rate.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/smi_rate.yaml new file mode 100644 index 00000000000..ad1a5fc6346 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/smi_rate.yaml @@ -0,0 +1,14 @@ +description: Ohio limits income to this fraction of state median income for households above the poverty-guideline household-size limit under the Home Energy Assistance Program. +values: + 2024-07-01: 0.6 +metadata: + unit: /1 + period: year + label: Ohio HEAP state median income rate + reference: + - title: Ohio Energy Assistance Programs Application, July 2024-May 2025 + href: https://clevelandohio.gov/sites/clevelandohio/files/aging/2024-2025_HEAP_application_B_W_1.pdf#page=1 + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026 + href: https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=1 + - title: Ohio JFS 00330 Energy Assistance Programs Application, July 2026-May 2027 + href: https://www.lccaa.net/wp-content/uploads/2026/07/2026-2027-EAP-Application-7-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/smi_year_lag.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/smi_year_lag.yaml new file mode 100644 index 00000000000..6e6f1a6ccca --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/smi_year_lag.yaml @@ -0,0 +1,28 @@ +description: Ohio uses state median income from this many years before the modeled benefit year under the Home Energy Assistance Program. +# Inferred from the federal cap, not stated: 42 USC 8624(b)(2)(B) caps +# eligibility at the greater of 150% of poverty and 60% of SMI, so Ohio's +# printed switch from 175% FPG to 60% SMI shows which SMI year it used. +# The 2024-25 application prints 175% FPG through size 7 ($82,845): only +# the FFY2025 SMI ($109,319) fits, because with FFY2024 the size-7 175% FPG +# limit exceeds the cap. The 2025-26 application prints 175% FPG through +# size 8 ($94,762): only the FFY2026 SMI ($114,593) fits. Those seasons +# therefore use no lag. The 2026-27 Consumers' Counsel fact sheet's limits +# for sizes 8, 11 and 12 equal the HHS FFY2026 60% SMI amounts (sizes 9 and +# 10 are $2-3 higher), so that season reuses FFY2026 (a one-year lag, also +# inferred). +values: + 2024-07-01: 0 + 2026-07-01: 1 +metadata: + unit: year + period: year + label: Ohio HEAP state median income year lag + reference: + - title: 42 USC 8624(b)(2)(B) + href: https://www.law.cornell.edu/uscode/text/42/8624 + - title: Ohio Energy Assistance Programs Application, July 2024-May 2025 + href: https://clevelandohio.gov/sites/clevelandohio/files/aging/2024-2025_HEAP_application_B_W_1.pdf#page=1 + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026 + href: https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=1 + - title: Ohio Consumers' Counsel, Home Energy Assistance Program (HEAP) fact sheet, 2026-2027 + href: https://occ.ohio.gov/sites/default/files/2026-08/OCC-Home-Energy-Assistance-Program-HEAP_0.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/adult_age.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/adult_age.yaml new file mode 100644 index 00000000000..c1d98ab3320 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/adult_age.yaml @@ -0,0 +1,12 @@ +description: Ohio excludes the income of dependent members below this age, other than Social Security, under the Home Energy Assistance Program. +values: + 2025-07-01: 18 +metadata: + unit: year + period: year + label: Ohio HEAP adult income age + reference: + - title: Ohio 2022-2023 Energy Assistance Programs Guidelines, section E-2.2 + href: https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7 + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026, Total Household Eligible Income Section + href: https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=7 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/deductions.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/deductions.yaml new file mode 100644 index 00000000000..5d5b3eeb143 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/deductions.yaml @@ -0,0 +1,20 @@ +description: Ohio deducts these expenses from countable income under the Home Energy Assistance Program. +# The premium inputs are disjoint (payroll premiums are only in the pretax +# input), so each premium is deducted once. +values: + 2025-07-01: + - child_support_expense + - health_insurance_premiums_without_medicare_part_b + - pre_tax_health_insurance_premiums + - medicare_part_b_premium +metadata: + unit: list + period: year + label: Ohio HEAP income deductions + reference: + - title: "Ohio 2022-2023 Energy Assistance Programs Guidelines, Appendices XII and XXIII #page 57,74" + href: https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=57 + - title: "Ohio FY2026 LIHEAP State Plan, revision 2, section 1.9 #page 5-6" + href: https://dam.assets.ohio.gov/image/upload/v1769700600/development.ohio.gov/individual/energyassistance/DETAILED_MODEL_PLAN_LIHEAP__10_01_2025.pdf#page=5 + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026 + href: https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=7 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/earned.yaml new file mode 100644 index 00000000000..1a12069b520 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/earned.yaml @@ -0,0 +1,18 @@ +description: Ohio uses these sources as earned income under the Home Energy Assistance Program. +# Existing net business inputs are used without another expense deduction. +values: + 2025-07-01: + - employment_income + - self_employment_income + - sstb_self_employment_income + - farm_operations_income + - partnership_s_corp_income +metadata: + unit: list + period: year + label: Ohio HEAP earned income sources + reference: + - title: "Ohio 2022-2023 Energy Assistance Programs Guidelines, sections E-2.2-2.3 and Appendix XXIII #page 7-8,73" + href: https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7 + - title: "Ohio FY2026 LIHEAP State Plan, revision 2, section 1.9 #page 5-6" + href: https://dam.assets.ohio.gov/image/upload/v1769700600/development.ohio.gov/individual/energyassistance/DETAILED_MODEL_PLAN_LIHEAP__10_01_2025.pdf#page=5 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/unearned.yaml new file mode 100644 index 00000000000..f99e515d438 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/unearned.yaml @@ -0,0 +1,53 @@ +description: Ohio uses these sources as unearned income under the Home Energy Assistance Program. +values: + 2025-07-01: + - total_unemployment_compensation + - strike_benefits + # Social Security is counted in the formula, including a dependent + # minor's benefit paid to an adult payee (Guidelines section E-2.2). + - ssi + - pension_income + # Military retirement pay is a separate input from the pension inputs that + # pension_income adds, so both are listed; a household reports the amount + # in one or the other. Appendix XXIII lists military pensions. + - military_retirement_pay + # Railroad Retirement is a retirement benefit that is not on the excluded + # income list; section E-2.3 counts any income not listed elsewhere. + - railroad_benefits + # The FY2026 plan, section 1.9 (page 6), leaves "General Assistance + # benefits" unchecked. The Guidelines list it as neither countable nor + # excluded (pages 73-76), and E-2.3 (page 8) states "Other Countable Income + # includes any income not listed above." The Guidelines govern. + - general_assistance + - survivor_benefits + # The current application excludes VA disabilities, but this aggregate + # cannot separate them from other VA receipts. Its inclusion is provisional + # and does not accurately apply the documented VA subtype distinction. + - veterans_benefits + - workers_compensation + - disability_benefits + - alimony_income + - rental_income + - farm_rent_income + - interest_income + - ordinary_dividend_income + - retirement_distributions + - estate_income + - capital_gains + - gambling_winnings +# Retirement account withdrawals are distinct from pension income in the model. +# The Guidelines explicitly count capital gains and estate/trust settlements, not +# merely asset sale proceeds. Those inputs do not capture every principal payout. +# TANF, child support received and gifts are excluded (Guidelines pages 75-76; +# unchecked in the FY2026 plan). +metadata: + unit: list + period: year + label: Ohio HEAP unearned income sources + reference: + - title: "Ohio 2022-2023 Energy Assistance Programs Guidelines, sections E-2.2-2.3 and Appendix XXIII #page 7-8,73-76" + href: https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7 + - title: "Ohio FY2026 LIHEAP State Plan, revision 2, section 1.9 (current income inclusions and exclusions) #page 5-6" + href: https://dam.assets.ohio.gov/image/upload/v1769700600/development.ohio.gov/individual/energyassistance/DETAILED_MODEL_PLAN_LIHEAP__10_01_2025.pdf#page=5 + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026 (VA disabilities excluded) + href: https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=7 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/intercept.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/intercept.yaml new file mode 100644 index 00000000000..b5652281808 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/intercept.yaml @@ -0,0 +1,44 @@ +description: Ohio sets this payment formula intercept under the Home Energy Assistance Program. +# The 2021 values carry through 2022; no final 2022 workbook was found. +# The 2024 and 2025 covers give credit percentages, but no formula sheet. +# These estimated intercepts apply the final 2023 workbook's $950 winter +# cost and page 11 method to the cover percentages: 0.50 x 950 = 475 and +# 0.265 x 950 = 251.75. Matching cover maxima does not verify interior awards. +# Ohio's January 16, 2025 notice confirms the operative 2025 range $24-$441 +# and prior-year range $41-$811; it does not supply current coefficients. +# The minimum awards include PIPP treatment, which remains unmodeled. +# The 2026 estimate fits the FY2026 matrix range in FY2027 draft plan items +# 2.5-2.6 ($31 minimum, $546 maximum); the matrix itself is not public. A 31% +# credit at 50% of poverty reproduces the maximum (0.31 x 950 x 1.06 x 1.75 = +# 546.30), and 28.5% at 150% is one of the credits (28.2%-29.1%) whose coal +# PIPP minimum, 0.19 of the regular award as in every published workbook, +# rounds to $31 (0.285 x 950 x 0.6 x 0.19 = 30.87): 0.31 x 950 + 50 x 0.2375 = +# 306.375. The draft estimates FY2027 at the same range, so the 2026 estimate +# carries forward. +values: + 2021-01-01: 593.2133 + 2023-01-01: 731.5 + 2024-01-01: 475 + 2025-01-01: 251.75 + 2026-01-01: 306.375 +metadata: + unit: currency-USD + period: year + label: Ohio HEAP payment intercept + reference: + - title: Ohio Department of Development IU-2025-5, January 16, 2025 + href: https://wofb.org/wp-content/uploads/2025/01/IU-2025-5-HEAP-Customer-Benefit-Update.pdf#page=1 + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=11 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=11 + - title: Ohio 2024 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 + - title: Ohio FY2025 LIHEAP State Plan, section 2.6 + href: https://liheapch.acf.gov/docs/2025/state-plans/OH_Plan_2025.pdf#page=9 + - title: Ohio FY2026 LIHEAP State Plan, revision 2, section 2.6 + href: https://dam.assets.ohio.gov/image/upload/v1769700600/development.ohio.gov/individual/energyassistance/DETAILED_MODEL_PLAN_LIHEAP__10_01_2025.pdf#page=9 + - title: Ohio FY2027 HEAP State Plan draft (July 2026), sections 2.5-2.6 + href: https://dam.assets.ohio.gov/image/upload/v1783702985/jfs.ohio.gov/Energy%20and%20Community%20Assistance/2026-2027_Draft_HEAP_State_Plan.pdf#page=9 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/maximum_poverty_ratio.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/maximum_poverty_ratio.yaml new file mode 100644 index 00000000000..8174e59d0b2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/maximum_poverty_ratio.yaml @@ -0,0 +1,14 @@ +description: Ohio uses no more than this federal poverty ratio when calculating payments under the Home Energy Assistance Program. +# The final 2021 and 2023 regional payment tables label their terminal row +# 150+. Later-year payment schedules remain unverified carryforward estimates. +values: + 2021-01-01: 1.5 +metadata: + unit: /1 + period: year + label: Ohio HEAP maximum poverty ratio for payments + reference: + - title: "Ohio 2021 FINAL HEAP Benefit Matrix, regional payment tables #page 16,20" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=16 + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, regional payment tables #page 16,20" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=16 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/minimum_poverty_ratio.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/minimum_poverty_ratio.yaml new file mode 100644 index 00000000000..ccca3ed7fb6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/minimum_poverty_ratio.yaml @@ -0,0 +1,14 @@ +description: Ohio uses at least this federal poverty ratio when calculating payments under the Home Energy Assistance Program. +values: + 2021-01-01: 0.5 +metadata: + unit: /1 + period: year + label: Ohio HEAP minimum poverty ratio for payments + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/slope.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/slope.yaml new file mode 100644 index 00000000000..5135872d2c7 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/slope.yaml @@ -0,0 +1,30 @@ +description: Ohio sets this payment reduction per federal poverty percentage point under the Home Energy Assistance Program. +# The 2021 values carry through 2022; no final 2022 workbook was found. +# For 2024 and 2025, these estimates use (46% - 38%) / 100 x $950 = 0.76 +# and (25% - 22%) / 100 x $950 = 0.285, applying the final 2023 workbook's +# method and winter cost to draft cover percentages. No current formula +# sheet or interior award table verifies those assumptions. For 2026, +# (31% - 28.5%) / 100 x $950 = 0.2375, fitted to the FY2026 matrix range (see +# the intercept); it carries into 2027 and later without extending verified +# coverage. +values: + 2021-01-01: 0.9813 + 2023-01-01: 1.33 + 2024-01-01: 0.76 + 2025-01-01: 0.285 + 2026-01-01: 0.2375 +metadata: + unit: currency-USD + period: year + label: Ohio HEAP payment reduction per poverty percentage point + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=11 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=11 + - title: Ohio 2024 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 + - title: Ohio FY2027 HEAP State Plan draft (July 2026), sections 2.5-2.6 + href: https://dam.assets.ohio.gov/image/upload/v1783702985/jfs.ohio.gov/Energy%20and%20Community%20Assistance/2026-2027_Draft_HEAP_State_Plan.pdf#page=9 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/bulk_fuel.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/bulk_fuel.yaml new file mode 100644 index 00000000000..1cd865b0eaf --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/bulk_fuel.yaml @@ -0,0 +1,17 @@ +description: Ohio uses this fuel cost ratio for propane, fuel oil, and kerosene under the Home Energy Assistance Program. +# The 2024 and 2025 draft workbooks' equal propane and oil/kerosene maximums +# ($811 and $441) are consistent with the 2023 ratio carrying forward. +values: + 2021-01-01: 0.852 + 2023-01-01: 1 +metadata: + unit: /1 + period: year + label: Ohio HEAP propane oil and kerosene fuel cost ratio + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=9 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=9 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/coal_wood.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/coal_wood.yaml new file mode 100644 index 00000000000..13b993ddd5d --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/coal_wood.yaml @@ -0,0 +1,19 @@ +description: Ohio uses this fuel cost ratio for coal and wood under the Home Energy Assistance Program. +# The 2024 and 2025 draft workbooks' coal/wood maximums and minimums +# ($486/$41 and $264/$24) are consistent with the 2023 ratio carrying forward. +values: + 2021-01-01: 0.5325 + 2023-01-01: 0.6 +metadata: + unit: /1 + period: year + label: Ohio HEAP coal and wood fuel cost ratio + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=9 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=9 + - title: Ohio 2024 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/gas_electricity.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/gas_electricity.yaml new file mode 100644 index 00000000000..0602b9cc9a4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/gas_electricity.yaml @@ -0,0 +1,25 @@ +description: Ohio uses this fuel cost ratio for natural gas and electricity under the Home Energy Assistance Program. +# Uses the published four-decimal ratios. With the printed 0.5523 ratio, 19 +# printed 2023 gas/electric cells differ by $1 from this formula (the 2021 +# workbook's printed slope and ratios leave 36 cells of every fuel $1 off); +# unprinted precision is not inferred. The 2024 and 2025 draft workbooks do +# not print the ratio: any ratio from 0.7236 to 0.7247 reproduces their +# gas/electric maximums ($587 and $319) against the propane maximums ($811 and +# $441), so the shortest value in that range is used and carried forward. +values: + 2021-01-01: 0.5882 + 2023-01-01: 0.5523 + 2024-01-01: 0.724 +metadata: + unit: /1 + period: year + label: Ohio HEAP gas and electricity fuel cost ratio + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=9 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=9 + - title: Ohio 2024 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/adjustment.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/adjustment.yaml new file mode 100644 index 00000000000..1d471abde01 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/adjustment.yaml @@ -0,0 +1,16 @@ +description: Ohio sets this regional payment adjustment for northern and southern counties under the Home Energy Assistance Program. +values: + 2021-01-01: 0.06 +metadata: + unit: /1 + period: year + label: Ohio HEAP regional payment adjustment + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: Ohio 2024 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/central_counties.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/central_counties.yaml new file mode 100644 index 00000000000..a4830b8fad5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/central_counties.yaml @@ -0,0 +1,66 @@ +description: Ohio uses these counties as the central region, with no regional adjustment, under the Home Energy Assistance Program. +# The final 2021 and 2023 workbooks assign all 88 counties identically. +values: + 2021-01-01: + - ALLEN_COUNTY_OH + - ASHLAND_COUNTY_OH + - ATHENS_COUNTY_OH + - AUGLAIZE_COUNTY_OH + - BELMONT_COUNTY_OH + - BUTLER_COUNTY_OH + - CARROLL_COUNTY_OH + - CHAMPAIGN_COUNTY_OH + - CLARK_COUNTY_OH + - CLINTON_COUNTY_OH + - COLUMBIANA_COUNTY_OH + - COSHOCTON_COUNTY_OH + - CRAWFORD_COUNTY_OH + - DARKE_COUNTY_OH + - DELAWARE_COUNTY_OH + - FAIRFIELD_COUNTY_OH + - FAYETTE_COUNTY_OH + - FRANKLIN_COUNTY_OH + - GREENE_COUNTY_OH + - GUERNSEY_COUNTY_OH + - HARDIN_COUNTY_OH + - HARRISON_COUNTY_OH + - HOCKING_COUNTY_OH + - HOLMES_COUNTY_OH + - JEFFERSON_COUNTY_OH + - KNOX_COUNTY_OH + - LICKING_COUNTY_OH + - LOGAN_COUNTY_OH + - MADISON_COUNTY_OH + - MARION_COUNTY_OH + - MERCER_COUNTY_OH + - MIAMI_COUNTY_OH + - MONROE_COUNTY_OH + - MONTGOMERY_COUNTY_OH + - MORGAN_COUNTY_OH + - MORROW_COUNTY_OH + - MUSKINGUM_COUNTY_OH + - NOBLE_COUNTY_OH + - PERRY_COUNTY_OH + - PICKAWAY_COUNTY_OH + - PREBLE_COUNTY_OH + - RICHLAND_COUNTY_OH + - ROSS_COUNTY_OH + - SHELBY_COUNTY_OH + - STARK_COUNTY_OH + - TUSCARAWAS_COUNTY_OH + - UNION_COUNTY_OH + - VAN_WERT_COUNTY_OH + - VINTON_COUNTY_OH + - WARREN_COUNTY_OH + - WASHINGTON_COUNTY_OH + - WAYNE_COUNTY_OH + - WYANDOT_COUNTY_OH +metadata: + unit: list + period: year + label: Ohio HEAP central counties + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=8 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/northern_counties.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/northern_counties.yaml new file mode 100644 index 00000000000..36fe9c4795f --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/northern_counties.yaml @@ -0,0 +1,37 @@ +description: Ohio uses these counties as the northern region under the Home Energy Assistance Program. +# The final 2021 and 2023 workbooks assign all 88 counties identically. +values: + 2021-01-01: + - ASHTABULA_COUNTY_OH + - CUYAHOGA_COUNTY_OH + - DEFIANCE_COUNTY_OH + - ERIE_COUNTY_OH + - FULTON_COUNTY_OH + - GEAUGA_COUNTY_OH + - HANCOCK_COUNTY_OH + - HENRY_COUNTY_OH + - HURON_COUNTY_OH + - LAKE_COUNTY_OH + - LORAIN_COUNTY_OH + - LUCAS_COUNTY_OH + - MAHONING_COUNTY_OH + - MEDINA_COUNTY_OH + - OTTAWA_COUNTY_OH + - PAULDING_COUNTY_OH + - PORTAGE_COUNTY_OH + - PUTNAM_COUNTY_OH + - SANDUSKY_COUNTY_OH + - SENECA_COUNTY_OH + - SUMMIT_COUNTY_OH + - TRUMBULL_COUNTY_OH + - WILLIAMS_COUNTY_OH + - WOOD_COUNTY_OH +metadata: + unit: list + period: year + label: Ohio HEAP northern counties + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=8 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/southern_counties.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/southern_counties.yaml new file mode 100644 index 00000000000..a64a0cd5f0f --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/southern_counties.yaml @@ -0,0 +1,24 @@ +description: Ohio uses these counties as the southern region under the Home Energy Assistance Program. +# The final 2021 and 2023 workbooks assign all 88 counties identically. +values: + 2021-01-01: + - ADAMS_COUNTY_OH + - BROWN_COUNTY_OH + - CLERMONT_COUNTY_OH + - GALLIA_COUNTY_OH + - HAMILTON_COUNTY_OH + - HIGHLAND_COUNTY_OH + - JACKSON_COUNTY_OH + - LAWRENCE_COUNTY_OH + - MEIGS_COUNTY_OH + - PIKE_COUNTY_OH + - SCIOTO_COUNTY_OH +metadata: + unit: list + period: year + label: Ohio HEAP southern counties + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=8 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=8 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/elderly_age.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/elderly_age.yaml new file mode 100644 index 00000000000..fa9d15859ae --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/elderly_age.yaml @@ -0,0 +1,16 @@ +description: Ohio sets this minimum age for a targeted-household member under the Home Energy Assistance Program. +values: + 2021-01-01: 60 +metadata: + unit: year + period: year + label: Ohio HEAP targeted household elderly minimum age + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: Ohio 2024 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/multiplier.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/multiplier.yaml new file mode 100644 index 00000000000..d5c36be8f1f --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/multiplier.yaml @@ -0,0 +1,17 @@ +description: Ohio provides targeted households this multiple of the payment under the Home Energy Assistance Program. +values: + 2021-01-01: 1.5 + 2023-01-01: 1.75 +metadata: + unit: /1 + period: year + label: Ohio HEAP targeted household payment multiplier + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: Ohio 2024 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/young_child_age.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/young_child_age.yaml new file mode 100644 index 00000000000..2a7bb7622c3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/young_child_age.yaml @@ -0,0 +1,14 @@ +description: Ohio sets this maximum child age for a targeted household under the Home Energy Assistance Program. +values: + 2023-01-01: 5 +metadata: + unit: year + period: year + label: Ohio HEAP targeted household young child maximum age + reference: + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: Ohio 2024 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/young_child_in_effect.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/young_child_in_effect.yaml new file mode 100644 index 00000000000..f35a03f474c --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/young_child_in_effect.yaml @@ -0,0 +1,19 @@ +description: Ohio uses this indicator to target households with a young child under the Home Energy Assistance Program. +# The final 2021 workbook targets only elderly and disabled members; young +# children are first targeted in the final 2023 workbook. +values: + 2021-01-01: false + 2023-01-01: true +metadata: + unit: bool + period: year + label: Ohio HEAP young child targeting in effect + reference: + - title: Ohio 2021 FINAL HEAP Benefit Matrix + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 + - title: Ohio 2023 FINAL LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: Ohio 2024 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: Ohio 2025 DRAFT LIHEAP Benefit Matrix + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 5250ab3aa89..a168932c310 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -808,8 +808,15 @@ programs: category: Benefits agency: HHS status: partial - coverage: DC, Riverside County, MA, IL, IN, KS, KY, MD, MS, NC, NE, NJ, NY, OR, TX + coverage: DC, Riverside County, MA, IL, IN, KS, KY, MD, MS, NC, NE, NJ, NY, OH, OR, TX state_implementations: + - state: OH + status: partial + name: Ohio HEAP + full_name: Ohio Home Energy Assistance Program + variable: oh_liheap + parameter_prefix: gov.states.oh.odjfs.liheap + notes: Regular heating only, without the PIPP reduction; crisis, cooling and weatherization assistance are out of scope. Payment coefficients after 2023 are estimates from workbook covers and published benefit ranges, so no full benefit year is verified. - state: DC status: complete name: DC LIHEAP diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.yaml new file mode 100644 index 00000000000..6b6b39ea3fc --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.yaml @@ -0,0 +1,400 @@ +# Ohio income and eligibility components only; no payment schedule or final award is asserted. + +# 2025-2026 application p1: the $27,387 limit is inclusive; the FY2026 plan and the +# Guidelines have no asset test. +- name: Case 1, exact one person income ceiling qualifies without an asset test. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 27_387 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + spm_unit_assets: 1_000_000 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_eligible: true + +# One dollar above $27,387 fails even with TANF and SNAP receipts; FY2026 plan item 1.4 +# answers No to categorical eligibility. +- name: Case 2, TANF and SNAP receipts do not bypass income above the limit. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 27_388 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 3_600 + snap: 6_000 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_eligible: false + +# Regular eligibility still requires a primary heating burden. +- name: Case 3, no separate bill and no heat in rent means no heating responsibility. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 0 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_eligible: false + +# Canonical NONE means no heating; an unrelated gas bill cannot establish a primary heating burden. +- name: Case 4, explicit no heating fails despite a gas bill. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NONE + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_eligible: false + +# Application p1 counts undesignated heat payments in rent; Guidelines E-4 (p12) does not +# require the bill in a member's name for HEAP. +- name: Case 5, verified nonsubsidized heat in rent qualifies without a separate bill. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 0 + heat_expense_included_in_rent: true + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_eligible: true + +# Current plan p8 requires verification the subsidized tenant pays some utility cost. +- name: Case 6, housing assistance with heat in rent needs a reported own portion. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 0 + heat_expense_included_in_rent: true + receives_housing_assistance: true + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_eligible: false + +# A positive primary gas bill stands in for the subsidized tenant's own portion. +- name: Case 7, reported heating portion restores subsidized heat in rent eligibility. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 120 + heat_expense_included_in_rent: true + receives_housing_assistance: true + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_eligible: true + +# Public-housing status independently identifies subsidized heat in rent even when receives_housing_assistance is unset. +- name: Case 8, public housing alone identifies the subsidy restriction. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 0 + heat_expense_included_in_rent: true + households: + household: + members: [person1] + state_code: OH + is_in_public_housing: true + output: + oh_liheap_eligible: false + +# Guidelines E-2.8 (p10) requires at least one citizen or qualified member; a size-0 unit fails. +- name: Case 9, no qualified household member fails eligibility. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_eligible: false + +# Guidelines E-2.1 and E-2.8 (pp7, 10): the parent is excluded from size, not income. The +# full 28,000 exceeds the size-1 limit of 27,387; prorating by headcount would approve. +- name: Case 10, nonqualified adult income is counted in full against citizen child size. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + is_tax_unit_dependent: false + ssi: 0 + employment_income: 28_000 + person2: + age: 8 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_household_size: 1 + oh_liheap_countable_income: 28_000 + oh_liheap_income_limit: 27_387 + oh_liheap_eligible: false + +# Only the Ohio component is defined for Ohio residence. +- name: Case 11, out of state residence does not qualify for Ohio assistance. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: WV + output: + oh_liheap_eligible: false + +# Final FY2026 plan Section 2.3, physical p8 permits subsidized heat-in-rent +# tenants who pay all or part of a separate electric bill; liability is verified. +- name: Case 12, housing assistance with heat in rent and a separate electric bill qualifies. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + rent: 6_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 0 + electricity_expense: 1_200 + heat_expense_included_in_rent: true + receives_housing_assistance: true + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_eligible: true + +- name: Case 13, public housing with heat in rent and a separate electric bill qualifies. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + rent: 6_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 0 + electricity_expense: 1_200 + heat_expense_included_in_rent: true + receives_housing_assistance: false + households: + household: + members: [person1] + state_code: OH + is_in_public_housing: true + output: + oh_liheap_eligible: true + +# 2022-2023 Guidelines E-2.2 (p7) apply 175% FPG to every size: size 9 limit +# (13,590 + 8 x 4,720) x 1.75 = 89,862.5 -> 89,862. Wages 50,000 + 30,000 = 80,000 qualify; +# 60% SMI (floor(0.6 x 93,649) = 56,189 x 1.41 = 79,226) would have denied them. +- name: Case 14, a nine member household in 2023 uses the poverty guideline limit. + period: 2023 + input: + people: + person1: + age: 42 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 50_000 + person2: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 30_000 + person3: + age: 17 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + person4: + age: 15 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + person5: + age: 13 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + person6: + age: 11 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + person7: + age: 9 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + person8: + age: 6 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + person9: + age: 3 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + heating_type: NATURAL_GAS + gas_expense: 1_800 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9] + state_code: OH + output: + oh_liheap_household_size: 9 + oh_liheap_countable_income: 80_000 + oh_liheap_income_limit: 89_862 + oh_liheap_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.yaml new file mode 100644 index 00000000000..9ac82473276 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.yaml @@ -0,0 +1,97 @@ +# Ohio income and eligibility components only; no payment schedule or final award is asserted. + +# 2025-2026 application p1 HEAP limits: whole-dollar 175% of the 2025 FPG, not the adjacent +# 200% HWAP column. +- name: Case 1, all eight current published annual FPG limits match exactly. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH, OH, OH, OH, OH, OH, OH] + oh_liheap_household_size: [1, 2, 3, 4, 5, 6, 7, 8] + output: + oh_liheap_income_limit: [27_387, 37_012, 46_637, 56_262, 65_887, 75_512, 85_137, 94_762] + +# 2024-2025 application p1: 175% of the 2024 FPG through size seven: 15,060 x 1.75 = 26,355; +# (15,060 + 6 x 5,380) x 1.75 = 82,845. With no SMI lag before the 2026-2027 season, +# sizes 8 and 9 use the HHS FFY2025 order: floor(0.6 x 109,319) = 65,591, then +# 65,591 x 1.38 = 90,515.58 -> 90,515; 65,591 x 1.41 = 92,483.31 -> 92,483. +- name: Case 2, the 2025 limits switch from the poverty guideline to same year state median income at + size eight. + period: 2025 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH, OH, OH] + oh_liheap_household_size: [1, 7, 8, 9] + output: + oh_liheap_income_limit: [26_355, 82_845, 90_515, 92_483] + +# Safe intermediate behavior for a household with no qualified members. +- name: Case 3, zero qualified size has zero income limit. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: OH + oh_liheap_household_size: 0 + output: + oh_liheap_income_limit: 0 + +# JFS 00330 (07/2026), p1: the seven annual HEAP limits for July 2026-May 2027. +- name: Case 4, all seven published 2027 FPG household limits match the operative application. + period: 2027 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH, OH, OH, OH, OH, OH] + oh_liheap_household_size: [1, 2, 3, 4, 5, 6, 7] + output: + oh_liheap_income_limit: [27_930, 37_870, 47_810, 57_750, 67_690, 77_630, 87_570] + +# The form switches to 60% SMI above seven people. With the one-year lag, the 2026-2027 +# limits use the FFY2026 Ohio SMI of 114,593 in the HHS order: floor(0.6 x 114,593) = +# 68,755, then x 1.38/1.41/1.44/1.47/1.50 = 94,881.9/96,944.55/99,007.2/101,069.85/ +# 103,132.5, each floored. The Consumers' Counsel sheet matches sizes 8, 11 and 12 but +# prints $96,946 and $99,010 for sizes 9 and 10, which no rounding order reproduces (they +# exceed unrounded 60% of SMI); the model follows the HHS table. +- name: Case 5, the 2027 limits for eight to twelve members use the prior year state median income. + period: 2027 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH, OH, OH, OH] + oh_liheap_household_size: [8, 9, 10, 11, 12] + output: + oh_liheap_income_limit: [94_881, 96_944, 99_007, 101_069, 103_132] + +# 2022-2023 Guidelines E-2.2 (p7): 175% of the 2022 FPG for every size, adding $8,260 per +# member above eight; no SMI switch. 13,590 x 1.75 = 23,782.5; (13,590 + 7 x 4,720) x 1.75 +# = 81,602.5; + 8,260 = 89,862.5; + 8,260 = 98,122.5; each floored to whole dollars. +- name: Case 6, the 2023 limits use the poverty guideline for every household size. + period: 2023 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH, OH, OH] + oh_liheap_household_size: [1, 8, 9, 10] + output: + oh_liheap_income_limit: [23_782, 81_602, 89_862, 98_122] + +# July 2023-May 2024 application p1: 175% of the 2023 FPG for every size: 14,580 x 1.75 = +# 25,515; size 8 prints 88,480 ((14,580 + 7 x 5,140) x 1.75); each added member adds 8,995: +# 97,475. +- name: Case 7, the 2024 limits keep the poverty guideline rule for large households. + period: 2024 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH, OH] + oh_liheap_household_size: [1, 8, 9] + output: + oh_liheap_income_limit: [25_515, 88_480, 97_475] + +# 2025-2026 application p1: FPG through size eight: (15,650 + 7 x 5,500) x 1.75 = 94,762.5. +# With no SMI lag before the 2026-2027 season, size nine uses the HHS FFY2026 order: +# floor(0.6 x 114,593) = 68,755, then 68,755 x 1.41 = 96,944.55 -> 96,944. +- name: Case 8, the 2026 limits switch to same year state median income at size nine. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH] + oh_liheap_household_size: [8, 9] + output: + oh_liheap_income_limit: [94_762, 96_944] diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.yaml new file mode 100644 index 00000000000..ae91c00f5a8 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.yaml @@ -0,0 +1,544 @@ +# Ohio income and eligibility components only; no payment schedule or final award is asserted. + +# Guidelines E-2.3 (p8): 12,000 + 6,000 + 600 + 1,200 + 1,200 = 21,000; the net business +# inputs need no further expense deduction. +- name: Case 1, adult wages and existing net business sources count without another deduction. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + self_employment_income: 6_000 + sstb_self_employment_income: 600 + farm_operations_income: 1_200 + partnership_s_corp_income: 1_200 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 21_000 + +# FY2026 plan p6 and Guidelines pp73-74: 2,400 rent + 1,200 farm rent + 600 survivor + +# 1,200 pension + 2,400 Social Security + 1,200 SSI = 9,000. +- name: Case 2, independent rental retirement survivor and SSI receipts all count once. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 1_200 + rental_income: 2_400 + farm_rent_income: 1_200 + survivor_benefits: 600 + pension_income: 1_200 + social_security: 2_400 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 9_000 + +# Guidelines p74 explicitly lists IRA withdrawals, estate/trust settlements, lottery, interest, dividends and capital gain; current plan includes lump sums. Existing source inputs are disjoint. +- name: Case 3, withdrawals estate receipts lottery winnings gains interest and dividends count. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + retirement_distributions: 3_600 + estate_income: 1_200 + gambling_winnings: 600 + capital_gains: 600 + interest_income: 120 + ordinary_dividend_income: 240 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 6_360 + +# Guidelines E-2.2 (p7): a dependent minor's income is excluded except SS/SSDI paid to an +# adult payee. Parent wages 12,000 + child Social Security 1,200 = 13,200; the child's +# SSI 2,400, wages 6,000 and net business 1,200 are excluded. +- name: Case 4, age 17 dependent income is excluded except Social Security. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + person2: + age: 17 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 2_400 + employment_income: 6_000 + self_employment_income: 1_200 + social_security: 1_200 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 13_200 + +# A 17-year-old who is not a dependent minor has all income counted: +# 12,000 + 2,400 SSI + 6,000 wages + 1,200 net business + 1,200 Social Security = 22,800. +- name: Case 5, age 17 nondependent income follows the dependent minor boundary. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + person2: + age: 17 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 2_400 + employment_income: 6_000 + self_employment_income: 1_200 + social_security: 1_200 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 22_800 + +# Guidelines E-2.2 (p7) count members 18 or older, so an 18-year-old dependent's income all +# counts: 12,000 + 2,400 + 6,000 + 1,200 + 1,200 = 22,800. +- name: Case 6, age 18 dependent income follows the adult age boundary. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + person2: + age: 18 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 2_400 + employment_income: 6_000 + self_employment_income: 1_200 + social_security: 1_200 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 22_800 + +# Guidelines E-2.3 (p8) enters a reported business loss as 0: 12,000 wages + 600 positive +# business + 1,200 SSI = 13,800; losses do not offset other sources. +- name: Case 7, each business loss is floored before wages and positive income are added. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 1_200 + employment_income: 12_000 + self_employment_income: -6_000 + farm_operations_income: -2_400 + partnership_s_corp_income: 600 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 13_800 + +# Guidelines pp75-76 exclude TANF (OWF) and child support received; SNAP is a noncash +# benefit and is not an income source; alimony counts (p73). +# General assistance is on neither list, so the E-2.3 catch-all (p8) counts it; the FY2026 +# plan (p6) leaves it unchecked. 12,000 wages + 1,200 alimony + 1,200 GA = 14,400. +- name: Case 8, TANF and child support are excluded while alimony and general assistance count. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + child_support_received: 6_000 + alimony_income: 1_200 + general_assistance: 1_200 + person2: + age: 8 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + tanf: 3_600 + snap: 6_000 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 14_400 + +# Current FY2026 application physical p7 and Guidelines p74 deduct child support paid. 30,000 - 3,600 = 26,400, below the one-person ceiling of 27,387. +- name: Case 9, child support paid changes an otherwise over limit household to eligible. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 30_000 + child_support_expense: 3_600 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 26_400 + oh_liheap_income_limit: 27_387 + oh_liheap_eligible: true + +# The same deduction cannot produce negative countable income: max(1,200 - 2,400, 0) = 0. +- name: Case 10, child support paid above income floors countable income at zero. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 1_200 + child_support_expense: 2_400 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 0 + oh_liheap_eligible: true + +# Application physical p7 excludes support received while deducting support paid. A parent receives support for the resident child and pays for another child: 12,000 + 600 dividends - 1,200 = 11,400. +- name: Case 11, support received stays excluded when the household also pays child support. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + ordinary_dividend_income: 600 + child_support_received: 6_000 + child_support_expense: 1_200 + person2: + age: 8 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 11_400 + +# Guidelines Appendix XXIII (p74), the 2025-2026 application (p7) and the FY2026 plan (p6) +# deduct Medicare premiums. 2026 standard Part B premium 202.90 x 12 = 2,434.80: +# 28,000 Social Security - 2,434.80 = 25,565.20. +- name: Case 12, the Medicare Part B premium is deducted from an elderly member's Social Security income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + social_security: 28_000 + medicare_part_b_premium: 2_434.8 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 25_565.2 + +# Guidelines Appendix XXIII (p73) lists military pensions, and E-2.3 (p8) counts income not +# listed elsewhere, including Railroad Retirement. Each 30,000 counts in full and exceeds +# the 27,387 one-person limit. +- name: Case 13, military retirement pay and railroad retirement benefits count. + period: 2026 + input: + state_code: [OH, OH] + age: [62, 62] + immigration_status: [CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false] + ssi: [0, 0] + military_retirement_pay: [30_000, 0] + railroad_benefits: [0, 30_000] + heating_type: [NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_200, 1_200] + output: + oh_liheap_countable_income: [30_000, 30_000] + oh_liheap_income_limit: [27_387, 27_387] + oh_liheap_eligible: [false, false] + +# Guidelines E-2.2 (p7) count only members 18 or older plus a minor's SS/SSDI. The child's +# 1,500 of dividends and 9,000 of SSI are excluded: countable 30,000 <= 37,012 (size 2). +- name: Case 14, a dependent child's dividends and SSI are excluded. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 30_000 + person2: + age: 12 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 9_000 + ordinary_dividend_income: 1_500 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 30_000 + oh_liheap_income_limit: 37_012 + oh_liheap_eligible: true + +# A minor's Social Security paid to an adult payee counts (Guidelines E-2.2, p7): an $800 +# monthly survivor benefit adds 9,600: 30,000 + 9,600 = 39,600 > 37,012. +- name: Case 15, a dependent child's Social Security survivor benefit counts. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 30_000 + person2: + age: 12 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + social_security: 9_600 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 39_600 + oh_liheap_income_limit: 37_012 + oh_liheap_eligible: false + +# Each source is floored at zero, so rental, farm rent and capital losses cannot offset +# other income: 12,000 wages + 600 interest = 12,600 (offsetting would give 1,200). +- name: Case 16, rental farm rent and capital losses do not offset other income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + rental_income: -6_000 + farm_rent_income: -2_400 + capital_gains: -3_000 + interest_income: 600 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 12_600 + +# Guidelines Appendix XXIII (pp73-74) counts unemployment, Workers' Compensation, employment +# disability payouts, strike benefits and VA pensions; the FY2026 plan (p7) counts VA +# pension but not VA disability. Workers earn Ohio's 2026 $11.00 minimum wage (Commerce +# poster) for 40 hours = 440 a week; each household reports one source: +# Unemployment: 26 weeks x 440 = 11,440 + 26 weeks x 220 (half the weekly wage, +# ORC 4141.30(B)(3)) = 5,720 -> 17,160 +# (total_unemployment_compensation uses the reported amount). +# Strike: 46 weeks x 440 = 20,240 + 6 weeks x 500 UAW strike assistance (uaw.org strike +# FAQ) = 3,000 -> 23,240. +# VA pension: a disabled veteran under 65 with no other income receives the full MAPR +# effective Dec. 1, 2025 for a veteran with no dependents (va.gov) -> 17,441. +# Workers' compensation: 40 weeks x 440 = 17,600 + 12 weeks x 427 (BWC 2026 temporary +# total minimum; 72% of 440 is lower) = 5,124 -> 22,724. +# Disability: 39 weeks x 440 = 17,160 + 13 weeks x 264 (60% BLS median short-term +# disability replacement x 440) = 3,432 -> 20,592. +- name: Case 17, unemployment strike VA pension workers compensation and disability benefits each count. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH, OH, OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, + FRANKLIN_COUNTY_OH] + age: [40, 40, 58, 40, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false] + is_disabled: [false, false, true, false, false] + ssi: [0, 0, 0, 0, 0] + employment_income: [11_440, 20_240, 0, 17_600, 17_160] + unemployment_compensation: [5_720, 0, 0, 0, 0] + strike_benefits: [0, 3_000, 0, 0, 0] + veterans_benefits: [0, 0, 17_441, 0, 0] + workers_compensation: [0, 0, 0, 5_124, 0] + disability_benefits: [0, 0, 0, 0, 3_432] + output: + oh_liheap_countable_income: [17_160, 23_240, 17_441, 22_724, 20_592] + +# Guidelines Appendix XXIII (p74) deducts health premiums, and Appendix XII (p57) shows +# them as pre-tax pay stub deductions. Full-time at Ohio's 2026 $11.00 minimum wage: +# 11 x 2,080 = 22,880. KFF 2025 average worker contribution for single coverage, withheld +# pretax: 1,440. 22,880 - 1,440 = 21,440. +- name: Case 18, a health insurance premium withheld from pay before tax is deducted from wages. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 22_880 + pre_tax_health_insurance_premiums: 1_440 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: OH + county: FRANKLIN_COUNTY_OH + output: + oh_liheap_countable_income: 21_440 + +# Case 12's household also pays the 2026 Part D base beneficiary premium (CMS), 38.99 x 12 +# = 467.88. Each premium is deducted once, so Part B is not counted twice: +# 28,000 - 2,434.80 - 467.88 = 25,097.32. +- name: Case 19, a Part D premium is deducted alongside the Medicare Part B premium without counting Part B twice. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + social_security: 28_000 + medicare_part_b_premium: 2_434.8 + health_insurance_premiums_without_medicare_part_b: 467.88 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: OH + county: FRANKLIN_COUNTY_OH + output: + oh_liheap_countable_income: 25_097.32 diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap.yaml new file mode 100644 index 00000000000..9a40f7d25ab --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap.yaml @@ -0,0 +1,639 @@ +# Final 2021 workbook (also used for 2022) and final 2023 workbook: page 1 factors, +# page 8 counties, pages 9-11 formula/tables, pages 16 and 20 terminal 150+ rows. +# 2024-2025 use coefficients estimated from draft covers; 2026 uses coefficients +# fitted to the FY2026 matrix range ($31-$546) in the FY2027 draft plan, carried +# to 2027. PIPP enrollment/reduction remains unmodeled. Every case gives +# heating_type. Case 11 uses the explicit .5523 gas factor: printed amounts are +# 334 and 579 instead. +- name: Case 1, published ordinary fuel amounts are not capped at a small reported heating bill. + period: 2023 + input: + state_code: [OH, OH, OH, OH, OH, OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, + FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [40, 40, 40, 40, 40, 40, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false, false, false] + ssi: [0, 0, 0, 0, 0, 0, 0] + employment_income: [0, 0, 0, 0, 0, 0, 0] + heating_type: [NATURAL_GAS, ELECTRICITY, PROPANE, FUEL_OIL, KEROSENE, COAL, WOOD] + heating_expense: [1, 1, 1, 1, 1, 1, 1] + output: + oh_liheap: [367, 367, 665, 665, 665, 399, 399] +- name: Case 2, the weighted award uses the elderly disability and young-child boundaries. + period: 2023 + input: + people: + age59_adult: + age: 59 + immigration_status: CITIZEN + is_disabled: false + ssi: 0 + employment_income: 0 + age60_adult: + age: 60 + immigration_status: CITIZEN + is_disabled: false + ssi: 0 + employment_income: 0 + disabled_adult: + age: 40 + immigration_status: CITIZEN + is_disabled: true + ssi: 0 + employment_income: 0 + child5_adult: + age: 40 + immigration_status: CITIZEN + is_disabled: false + ssi: 0 + employment_income: 0 + child5_child: + age: 5 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + child6_adult: + age: 40 + immigration_status: CITIZEN + is_disabled: false + ssi: 0 + employment_income: 0 + child6_child: + age: 6 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + spm_units: + age59: + members: &id001 [age59_adult] + heating_type: PROPANE + heating_expense: 1 + age60: + members: &id002 [age60_adult] + heating_type: PROPANE + heating_expense: 1 + disabled: + members: &id003 [disabled_adult] + heating_type: PROPANE + heating_expense: 1 + child5: + members: &id004 [child5_adult, child5_child] + heating_type: PROPANE + heating_expense: 1 + child6: + members: &id005 [child6_adult, child6_child] + heating_type: PROPANE + heating_expense: 1 + households: + age59: + members: *id001 + state_code: OH + county: FRANKLIN_COUNTY_OH + age60: + members: *id002 + state_code: OH + county: FRANKLIN_COUNTY_OH + disabled: + members: *id003 + state_code: OH + county: FRANKLIN_COUNTY_OH + child5: + members: *id004 + state_code: OH + county: FRANKLIN_COUNTY_OH + child6: + members: *id005 + state_code: OH + county: FRANKLIN_COUNTY_OH + output: + oh_liheap: [665, 1164, 1164, 1164, 665] +- name: Case 3, all eighty-eight published county assignments select the correct regional payment. + period: 2023 + input: + state_code: [OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, + OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, + OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, + OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH, OH] + county: [ADAMS_COUNTY_OH, ALLEN_COUNTY_OH, ASHLAND_COUNTY_OH, ASHTABULA_COUNTY_OH, ATHENS_COUNTY_OH, + AUGLAIZE_COUNTY_OH, BELMONT_COUNTY_OH, BROWN_COUNTY_OH, BUTLER_COUNTY_OH, CARROLL_COUNTY_OH, CHAMPAIGN_COUNTY_OH, + CLARK_COUNTY_OH, CLERMONT_COUNTY_OH, CLINTON_COUNTY_OH, COLUMBIANA_COUNTY_OH, COSHOCTON_COUNTY_OH, + CRAWFORD_COUNTY_OH, CUYAHOGA_COUNTY_OH, DARKE_COUNTY_OH, DEFIANCE_COUNTY_OH, DELAWARE_COUNTY_OH, + ERIE_COUNTY_OH, FAIRFIELD_COUNTY_OH, FAYETTE_COUNTY_OH, FRANKLIN_COUNTY_OH, FULTON_COUNTY_OH, GALLIA_COUNTY_OH, + GEAUGA_COUNTY_OH, GREENE_COUNTY_OH, GUERNSEY_COUNTY_OH, HAMILTON_COUNTY_OH, HANCOCK_COUNTY_OH, HARDIN_COUNTY_OH, + HARRISON_COUNTY_OH, HENRY_COUNTY_OH, HIGHLAND_COUNTY_OH, HOCKING_COUNTY_OH, HOLMES_COUNTY_OH, HURON_COUNTY_OH, + JACKSON_COUNTY_OH, JEFFERSON_COUNTY_OH, KNOX_COUNTY_OH, LAKE_COUNTY_OH, LAWRENCE_COUNTY_OH, LICKING_COUNTY_OH, + LOGAN_COUNTY_OH, LORAIN_COUNTY_OH, LUCAS_COUNTY_OH, MADISON_COUNTY_OH, MAHONING_COUNTY_OH, MARION_COUNTY_OH, + MEDINA_COUNTY_OH, MEIGS_COUNTY_OH, MERCER_COUNTY_OH, MIAMI_COUNTY_OH, MONROE_COUNTY_OH, MONTGOMERY_COUNTY_OH, + MORGAN_COUNTY_OH, MORROW_COUNTY_OH, MUSKINGUM_COUNTY_OH, NOBLE_COUNTY_OH, OTTAWA_COUNTY_OH, PAULDING_COUNTY_OH, + PERRY_COUNTY_OH, PICKAWAY_COUNTY_OH, PIKE_COUNTY_OH, PORTAGE_COUNTY_OH, PREBLE_COUNTY_OH, PUTNAM_COUNTY_OH, + RICHLAND_COUNTY_OH, ROSS_COUNTY_OH, SANDUSKY_COUNTY_OH, SCIOTO_COUNTY_OH, SENECA_COUNTY_OH, SHELBY_COUNTY_OH, + STARK_COUNTY_OH, SUMMIT_COUNTY_OH, TRUMBULL_COUNTY_OH, TUSCARAWAS_COUNTY_OH, UNION_COUNTY_OH, VAN_WERT_COUNTY_OH, + VINTON_COUNTY_OH, WARREN_COUNTY_OH, WASHINGTON_COUNTY_OH, WAYNE_COUNTY_OH, WILLIAMS_COUNTY_OH, WOOD_COUNTY_OH, + WYANDOT_COUNTY_OH] + age: [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, + CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, + CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, + CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, + CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, + CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, + CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, + CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, + CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false] + ssi: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + employment_income: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + heating_type: [PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, + PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, + PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, + PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, + PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, + PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, + PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, + PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, + PROPANE] + heating_expense: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + output: + oh_liheap: [625, 665, 665, 705, 665, 665, 665, 625, 665, 665, 665, 665, 625, 665, 665, 665, 665, 705, + 665, 705, 665, 705, 665, 665, 665, 705, 625, 705, 665, 665, 625, 705, 665, 665, 705, 625, 665, 665, + 705, 625, 665, 665, 705, 625, 665, 665, 705, 705, 665, 705, 665, 705, 625, 665, 665, 665, 665, 665, + 665, 665, 665, 705, 705, 665, 665, 625, 705, 665, 705, 665, 665, 705, 625, 705, 665, 665, 705, 705, + 665, 665, 665, 665, 665, 665, 665, 705, 705, 665] +- name: Case 4, the 2023 poverty floor and published percentage rows use the 2022 guideline. + period: 2023 + input: + state_code: [OH, OH, OH, OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [40, 40, 40, 40, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false] + ssi: [0, 0, 0, 0, 0] + employment_income: [0, 6795, 6930.9, 13590, 20385] + heating_type: [PROPANE, PROPANE, PROPANE, PROPANE, PROPANE] + heating_expense: [1, 1, 1, 1, 1] + output: + oh_liheap: [665, 665, 664, 599, 532] +# 2026 estimate: 306.375 - 0.2375 x poverty percent, 2025 FPG 15,650. The historical +# 150+ payment cap also carries forward: eligible income at or above 150% gives +# 306.375 - 35.625 = 270.75 -> 271; 27,388 is above the 27,387 income limit and gives 0. +- name: Case 5, estimated later awards carry forward the historical payment cap while ordinary eligibility applies. + period: 2026 + input: + state_code: [OH, OH, OH, OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [40, 40, 40, 40, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false] + ssi: [0, 0, 0, 0, 0] + employment_income: [23475, 23475.01, 25431.25, 27387, 27388] + heating_type: [PROPANE, PROPANE, PROPANE, PROPANE, PROPANE] + heating_expense: [1, 1, 1, 1, 1] + output: + oh_liheap_eligible: [true, true, true, true, false] + oh_liheap: [271, 271, 271, 271, 0] +# 15,650 / 2025 FPG 15,650 = 100%: 306.375 - 23.75 = 282.625 -> 283. +- name: Case 6, the 2026 estimate uses the lagged 2025 poverty guideline. + period: 2026 + input: + state_code: [OH] + county: [FRANKLIN_COUNTY_OH] + age: [40] + immigration_status: [CITIZEN] + is_tax_unit_dependent: [false] + ssi: [0] + employment_income: [15650] + heating_type: [PROPANE] + heating_expense: [1] + output: + oh_liheap: [283] +# 15,960 / 2026 FPG 15,960 = 100%: 306.375 - 23.75 = 282.625 -> 283. The FY2027 draft +# plan estimates FY2027 at the FY2026 range. +- name: Case 7, the 2027 estimate carries the 2026 coefficients forward with the lagged 2026 poverty guideline. + period: 2027 + input: + state_code: [OH] + county: [FRANKLIN_COUNTY_OH] + age: [40] + immigration_status: [CITIZEN] + is_tax_unit_dependent: [false] + ssi: [0] + employment_income: [15960] + heating_type: [PROPANE] + heating_expense: [1] + output: + oh_liheap: [283] +# $0 income uses the 50% floor: 306.375 - 11.875 = 294.5. Fuel oil in northern Ashtabula +# (avoids the exact 294.5 central tie): 294.5 x 1.06 = 312.17 -> 312. Subsidized gas +# tenant with an electric bill: 294.5 x 0.724 = 213.22 -> 213. +# UNSPECIFIED with heat in unsubsidized rent is eligible but has no fuel column ($0; +# see #9754); NONE is ineligible. +- name: Case 8, eligible heat-in-rent households use their reported primary fuel and existing liability + rules. + period: 2026 + input: + state_code: [OH, OH, OH, OH, OH] + county: [ASHTABULA_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [40, 40, 40, 40, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false] + ssi: [0, 0, 0, 0, 0] + employment_income: [0, 0, 0, 0, 0] + heating_type: [FUEL_OIL, NATURAL_GAS, NATURAL_GAS, UNSPECIFIED, NONE] + heating_expense: [0, 0, 0, 0, 0] + heat_expense_included_in_rent: [true, true, true, true, true] + receives_housing_assistance: [false, true, true, false, false] + is_in_public_housing: [false, false, false, false, false] + electricity_expense: [0, 1200, 0, 0, 0] + output: + oh_liheap_eligible: [true, true, false, true, false] + oh_liheap: [312, 213, 0, 0, 0] +# Eligible with a $0 estimate: no workbook column for SOLAR, OTHER or UNSPECIFIED (#9754), +# and no region for UNKNOWN or non-Ohio counties; Pennsylvania is outside Ohio. +- name: Case 9, unpriced fuels and unknown or foreign counties have unsupported zero estimates. + period: 2026 + input: + state_code: [OH, OH, OH, OH, OH, PA] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, UNKNOWN, LOS_ANGELES_COUNTY_CA, + FRANKLIN_COUNTY_OH] + age: [40, 40, 40, 40, 40, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false, false] + ssi: [0, 0, 0, 0, 0, 0] + employment_income: [0, 0, 0, 0, 0, 0] + heating_type: [SOLAR, OTHER, UNSPECIFIED, NATURAL_GAS, NATURAL_GAS, PROPANE] + heating_expense: [1, 1, 1, 1, 1, 1] + output: + oh_liheap_eligible: [true, true, true, true, true, false] + oh_liheap: [0, 0, 0, 0, 0, 0] +- name: Case 10, rounding follows all regional and targeted adjustments rather than rounding intermediate + payments. + period: 2023 + input: + state_code: [OH, OH, OH, OH] + county: [ASHTABULA_COUNTY_OH, ADAMS_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [60, 60, 60, 60] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false] + ssi: [0, 0, 0, 0] + employment_income: [0, 0, 0, 0] + heating_type: [PROPANE, PROPANE, WOOD, NATURAL_GAS] + heating_expense: [1, 1, 1, 1] + output: + oh_liheap: [1234, 1094, 698, 643] +- name: Case 11, the printed gas factor determines estimates at cells with unpublished precision differences. + period: 2023 + input: + state_code: [OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [40, 60] + immigration_status: [CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false] + ssi: [0, 0] + employment_income: [13046.4, 13590] + heating_type: [NATURAL_GAS, NATURAL_GAS] + heating_expense: [1, 1] + output: + oh_liheap: [333, 578] +# Final 2021 workbook, pages 9-11: 593.2133 - 0.9813 x poverty percent, 2020 FPG 12,760. +# 50%: base 544.15; gas x 0.5882 = 320.07, propane x 0.852 = 463.61, coal x 0.5325 = 289.76. +# Elderly x 1.5: gas 480.10, propane 695.42. 75% (9,570): base 519.62; propane 442.71, +# gas 305.64. 100% (12,760): base 495.08; fuel oil x 0.852 = 421.81. Northern +# Ashtabula elderly propane 544.15 x 0.852 x 1.06 x 1.5 = 737.15; southern Adams elderly +# wood 544.15 x 0.5325 x 0.94 x 1.5 = 408.56. Each matches the printed 2021 table. +- name: Case 12, the 2021 payments follow the final 2021 workbook coefficients. + period: 2021 + input: + state_code: [OH, OH, OH, OH, OH, OH, OH, OH, OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, + FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, ASHTABULA_COUNTY_OH, ADAMS_COUNTY_OH] + age: [40, 40, 40, 60, 60, 40, 40, 40, 60, 60] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, + CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false, false, false, false, false, false] + ssi: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + employment_income: [0, 0, 0, 0, 0, 9_570, 9_570, 12_760, 0, 0] + heating_type: [NATURAL_GAS, PROPANE, COAL, NATURAL_GAS, PROPANE, PROPANE, NATURAL_GAS, FUEL_OIL, PROPANE, + WOOD] + heating_expense: [1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200] + output: + oh_liheap: [320, 464, 290, 480, 695, 443, 306, 422, 737, 409] + +# The 2021 workbook targets elderly and disabled members only: no young-child weight. +# Size 2 at $0 uses the 50% floor: 544.15 x 0.852 = 463.61 -> 464. +- name: Case 13, a household with a five year old child is not targeted in 2021. + period: 2021 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 0 + person2: + age: 5 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: PROPANE + heating_expense: 1_200 + households: + household: + members: [person1, person2] + state_code: OH + county: FRANKLIN_COUNTY_OH + output: + oh_liheap_household_size: 2 + oh_liheap_eligible: true + oh_liheap: 464 + +# The final 2023 workbook adds children five and under: (731.5 - 66.5) x 1 x 1.75 +# = 1,163.75 -> 1,164 for the same household as Case 13. +- name: Case 14, the same household with a five year old child is targeted in 2023. + period: 2023 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 0 + person2: + age: 5 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: PROPANE + heating_expense: 1_200 + households: + household: + members: [person1, person2] + state_code: OH + county: FRANKLIN_COUNTY_OH + output: + oh_liheap_household_size: 2 + oh_liheap_eligible: true + oh_liheap: 1_164 + +# No final 2022 workbook was found, so 2022 carries the 2021 coefficients. $0 rows equal +# Case 12 (320, 464, 290; elderly propane 695). 12,880 is 100% of the 2021 FPG: +# 593.2133 - 98.13 = 495.08 x 0.852 = 421.81 -> 422. +- name: Case 15, the 2022 payments carry the final 2021 workbook through. + period: 2022 + input: + state_code: [OH, OH, OH, OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [40, 40, 40, 60, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false] + ssi: [0, 0, 0, 0, 0] + employment_income: [0, 0, 0, 0, 12_880] + heating_type: [NATURAL_GAS, PROPANE, COAL, PROPANE, PROPANE] + heating_expense: [1_200, 1_200, 1_200, 1_200, 1_200] + output: + oh_liheap: [320, 464, 290, 695, 422] + +# 2024 draft workbook: 475 - 0.76 x poverty percent, 2023 FPG 14,580. 50%: base 437; +# gas x 0.724 = 316.39, propane 437, coal x 0.6 = 262.2. Northern elderly x 1.06 x 1.75: +# gas 586.90, propane 810.64, coal 486.38 (the printed $587/$811/$486 maximums). +# Southern Adams propane 437 x 0.94 = 410.78. 100% (14,580): 399. 150% (21,870): 361. +- name: Case 16, the 2024 payments use coefficients estimated from the draft workbook cover. + period: 2024 + input: + state_code: [OH, OH, OH, OH, OH, OH, OH, OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, ASHTABULA_COUNTY_OH, ASHTABULA_COUNTY_OH, + ASHTABULA_COUNTY_OH, ADAMS_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [40, 40, 40, 60, 60, 60, 40, 40, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false, false, false, false, false] + ssi: [0, 0, 0, 0, 0, 0, 0, 0, 0] + employment_income: [0, 0, 0, 0, 0, 0, 0, 14_580, 21_870] + heating_type: [NATURAL_GAS, PROPANE, COAL, NATURAL_GAS, PROPANE, COAL, PROPANE, PROPANE, PROPANE] + heating_expense: [1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200] + output: + oh_liheap: [316, 437, 262, 587, 811, 486, 411, 399, 361] + +# 2025 draft workbook: 251.75 - 0.285 x poverty percent, 2024 FPG 15,060. 50%: base 237.5. +# Northern elderly x 1.06 x 1.75: gas 318.97, propane 440.56, coal 264.34 (the printed +# $319/$441/$264 maximums). Central elderly x 1.75: gas 300.91, propane 415.63, coal 249.38. +# Central gas 171.95. 100% (15,060): 223.25 propane. Central non-targeted propane and coal +# at the 50% floor (237.5 and 142.5) are exact half-dollar ties and are not asserted. +- name: Case 17, the 2025 payments use coefficients estimated from the draft workbook cover. + period: 2025 + input: + state_code: [OH, OH, OH, OH, OH, OH, OH, OH] + county: [ASHTABULA_COUNTY_OH, ASHTABULA_COUNTY_OH, ASHTABULA_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, + FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [60, 60, 60, 60, 60, 60, 40, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false, false, false, false] + ssi: [0, 0, 0, 0, 0, 0, 0, 0] + employment_income: [0, 0, 0, 0, 0, 0, 0, 15_060] + heating_type: [NATURAL_GAS, PROPANE, COAL, NATURAL_GAS, PROPANE, COAL, NATURAL_GAS, PROPANE] + heating_expense: [1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200] + output: + oh_liheap: [319, 441, 264, 301, 416, 249, 172, 223] + +# A 70-year-old with $28,000 of Social Security and the 2026 standard Part B premium +# ($202.90 x 12 = $2,434.80) counts 25,565.20, within the 27,387 limit. 25,565.20 / 15,650 +# = 163.36%, capped at 150% for the estimated payment: 270.75 x 1.75 = 473.81 -> 474. +# Without a premium, 28,000 is over the limit and the payment is 0. +- name: Case 18, the Medicare Part B premium deduction makes an elderly Social Security recipient eligible. + period: 2026 + input: + state_code: [OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [70, 70] + immigration_status: [CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false] + ssi: [0, 0] + employment_income: [0, 0] + social_security: [28_000, 28_000] + medicare_part_b_premium: [2_434.8, 0] + heating_type: [PROPANE, PROPANE] + heating_expense: [1_200, 1_200] + output: + oh_liheap_eligible: [true, false] + oh_liheap: [474, 0] + +# With no county or county_fips input, county falls back to the state's alphabetically +# first county, Adams (southern, -6%): propane 294.5 x 0.94 = 276.83 -> 277; gas +# 294.5 x 0.724 x 0.94 = 200.42 -> 200. This documents the fallback; it is not a policy rule. +- name: Case 19, an omitted county uses the documented Adams County fallback. + period: 2026 + input: + state_code: [OH, OH] + age: [40, 40] + immigration_status: [CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false] + ssi: [0, 0] + employment_income: [0, 0] + heating_type: [PROPANE, NATURAL_GAS] + heating_expense: [1_200, 1_200] + output: + county: [ADAMS_COUNTY_OH, ADAMS_COUNTY_OH] + oh_liheap: [277, 200] + +# An explicit UNKNOWN county matches no regional list, so the regional factor is 0. +- name: Case 20, an explicit unknown county returns an unsupported zero estimate. + period: 2026 + input: + state_code: [OH, OH] + county: [UNKNOWN, UNKNOWN] + age: [40, 40] + immigration_status: [CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false] + ssi: [0, 0] + employment_income: [0, 0] + heating_type: [PROPANE, NATURAL_GAS] + heating_expense: [1_200, 1_200] + output: + oh_liheap: [0, 0] + +# Undocumented adult is excluded from size but not income: size 2, income 18,000 + 12,000 +# = 30,000 <= 37,012. Poverty uses the size-2 2025 FPG 21,150: 141.84%; +# 306.375 - 33.69 = 272.69 -> 273 (SPM size 3 would give 280; size 1, 271). Not targeted. +- name: Case 21, a mixed status family payment uses qualified household size with counted income. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_tax_unit_dependent: false + ssi: 0 + employment_income: 18_000 + person2: + age: 38 + immigration_status: UNDOCUMENTED + is_tax_unit_dependent: false + ssi: 0 + employment_income: 12_000 + person3: + age: 8 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: PROPANE + heating_expense: 1_200 + households: + household: + members: [person1, person2, person3] + state_code: OH + county: FRANKLIN_COUNTY_OH + output: + oh_liheap_household_size: 2 + oh_liheap_countable_income: 30_000 + oh_liheap_income_limit: 37_012 + oh_liheap_eligible: true + oh_liheap: 273 + +# Row 1: a business loss floors to 0, so the 50% floor applies: 294.5 x 0.724 = 213.22 +# -> 213. Row 2: wages 15,650 with rental and capital losses still count 15,650 (100%): +# 282.625 x 0.724 = 204.62 -> 205; letting the losses offset would give 213. +- name: Case 22, losses do not raise the payment or offset other income. + period: 2026 + input: + state_code: [OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [40, 40] + immigration_status: [CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false] + ssi: [0, 0] + employment_income: [0, 15_650] + self_employment_income: [-20_000, 0] + rental_income: [0, -6_000] + capital_gains: [0, -3_000] + heating_type: [NATURAL_GAS, NATURAL_GAS] + heating_expense: [1_200, 1_200] + output: + oh_liheap: [213, 205] + +# Final 2021 workbook, Tables 2B and 2C, physical pages 16 and 20: the last +# row is explicitly 150+, including the displayed weighted awards. Test actual +# income at 150%, near/at the 175% eligibility limit, and above the limit. +- name: Case 23, final 2021 regional terminal awards remain constant above 150 percent of poverty. + period: 2021 + input: + state_code: [OH, OH, OH, OH, OH, OH, OH] + county: [ASHTABULA_COUNTY_OH, ASHTABULA_COUNTY_OH, ADAMS_COUNTY_OH, ADAMS_COUNTY_OH, ASHTABULA_COUNTY_OH, ADAMS_COUNTY_OH, ASHTABULA_COUNTY_OH] + age: [40, 40, 40, 40, 60, 60, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false, false, false] + ssi: [0, 0, 0, 0, 0, 0, 0] + employment_income: [19140, 22330, 19140, 22330, 22330, 22330, 22331] + heating_type: [PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE] + heating_expense: [1200, 1200, 1200, 1200, 1200, 1200, 1200] + output: + oh_liheap_eligible: [true, true, true, true, true, true, false] + oh_liheap: [403, 403, 357, 357, 604, 536, 0] + +# Final 2023 workbook, Tables 2B and 2C, physical pages 16 and 20: the last +# row is explicitly 150+, including the displayed weighted awards. Test actual +# income at 150%, near/at the 175% eligibility limit, and above the limit. +- name: Case 24, final 2023 regional terminal awards remain constant above 150 percent of poverty. + period: 2023 + input: + state_code: [OH, OH, OH, OH, OH, OH, OH] + county: [ASHTABULA_COUNTY_OH, ASHTABULA_COUNTY_OH, ADAMS_COUNTY_OH, ADAMS_COUNTY_OH, ASHTABULA_COUNTY_OH, ADAMS_COUNTY_OH, ASHTABULA_COUNTY_OH] + age: [40, 40, 40, 40, 60, 60, 40] + immigration_status: [CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false, false, false, false, false, false] + ssi: [0, 0, 0, 0, 0, 0, 0] + employment_income: [20385, 23782, 20385, 23782, 23782, 23782, 23783] + heating_type: [PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE] + heating_expense: [1200, 1200, 1200, 1200, 1200, 1200, 1200] + output: + oh_liheap_eligible: [true, true, true, true, true, true, false] + oh_liheap: [564, 564, 500, 500, 987, 875, 0] + +# 42 U.S.C. 8624(b)(2)(B): a state may not exclude a household on income below 110% of the +# poverty level. Size 20 (set directly) in 2026: 60% of FFY2026 SMI is +# floor(floor(0.6 x 114,593) x 1.74) = floor(68,755 x 1.74) = 119,633, below the 2025 +# guideline 15,650 + 19 x 5,500 = 120,150. Income at 100% of the guideline exceeds the +# printed limit but is below 1.1 x 120,150 = 132,165, so the household stays eligible: +# 306.375 - 0.2375 x 100 = 282.625 -> 283. Income of exactly 132,165 is not below 110% +# and fails. +- name: Case 25, the federal 110 percent poverty floor keeps a large household eligible above the state median income limit. + period: 2026 + input: + state_code: [OH, OH] + county: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH] + age: [40, 40] + immigration_status: [CITIZEN, CITIZEN] + is_tax_unit_dependent: [false, false] + ssi: [0, 0] + oh_liheap_household_size: [20, 20] + employment_income: [120_150, 132_165] + heating_type: [PROPANE, PROPANE] + heating_expense: [1_200, 1_200] + output: + oh_liheap_income_limit: [119_633, 119_633] + oh_liheap_eligible: [true, false] + oh_liheap: [283, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap_household_size.yaml new file mode 100644 index 00000000000..d6d653cf3ab --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap_household_size.yaml @@ -0,0 +1,73 @@ +# Ohio qualified household size; Case 2 also checks that a unit with no qualified member is ineligible and unpaid. + +# Guidelines E-2.1 and E-2.8 (pp7, 10): count qualified members including minors; no SNAP-specific waiting bar. +- name: Case 1, citizen minors and qualified adults count but nonqualified members do not. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: LEGAL_PERMANENT_RESIDENT + is_tax_unit_dependent: false + ssi: 0 + person2: + age: 39 + immigration_status: ASYLEE + is_tax_unit_dependent: false + ssi: 0 + person3: + age: 8 + immigration_status: CITIZEN + is_tax_unit_dependent: true + ssi: 0 + person4: + age: 19 + immigration_status: DACA + is_tax_unit_dependent: false + ssi: 0 + person5: + age: 18 + immigration_status: UNDOCUMENTED + is_tax_unit_dependent: false + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: OH + output: + oh_liheap_household_size: 3 + +# Guidelines E-2.8 (p10): a household needs at least one citizen or qualified member. With +# no qualified member and no income, the size gate alone blocks eligibility (limit 0, +# income 0), so no award is paid. +- name: Case 2, all nonqualified members produce a zero qualified size. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + is_tax_unit_dependent: false + ssi: 0 + person2: + age: 8 + immigration_status: DACA + is_tax_unit_dependent: true + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_household_size: 0 + oh_liheap_eligible: false + oh_liheap: 0 diff --git a/policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.py b/policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.py new file mode 100644 index 00000000000..ff7faa36467 --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.py @@ -0,0 +1,56 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class oh_liheap_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Ohio HEAP eligibility" + defined_for = StateCode.OH + reference = ( + "https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=1", + "https://dam.assets.ohio.gov/image/upload/v1769700600/development.ohio.gov/individual/energyassistance/DETAILED_MODEL_PLAN_LIHEAP__10_01_2025.pdf#page=8", + # Section E-4: heat-in-rent bills need not be in a member's name for HEAP. + "https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=12", + "https://www.law.cornell.edu/uscode/text/42/8624", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.oh.odjfs.liheap.eligibility + p_hhs = parameters(period).gov.hhs.liheap + size = spm_unit("oh_liheap_household_size", period) + income = spm_unit("oh_liheap_countable_income", period) + limit = spm_unit("oh_liheap_income_limit", period) + guideline = fpg( + max_(size, 1), + spm_unit.household("state_group_str", period), + period, + parameters, + year_lag=p.fpg_year_lag, + ) + # 42 U.S.C. 8624(b)(2)(B) bars excluding a household on income below + # 110% of the poverty guideline; Ohio's 60% SMI limit falls below that + # floor from household size 17 in 2025-2027. + income_eligible = (income <= limit) | (income < p_hhs.fpg_floor * guideline) + heat_in_rent = spm_unit("heat_expense_included_in_rent", period) + subsidized = spm_unit("receives_housing_assistance", period) | ( + spm_unit.household("is_in_public_housing", period) + ) + # Reported bills and rental terms approximate verified liability. + # Guidelines E-4 (page 12): "For HEAP only, the utility bill does not + # have to be in a household member's name (for example, heat included + # in the rent ...)". FY2026 plan item 2.3 (page 8) makes tenants whose + # electric bills are not in their name ineligible "unless they provide + # verification that they pay all or a portion" of the electric bill. + # The model follows the Guidelines for unsubsidized tenants and the + # plan and application for subsidized ones. + pays_electricity = spm_unit("electricity_expense", period) > 0 + responsible = (spm_unit("heating_expense", period) > 0) | ( + heat_in_rent & (~subsidized | pays_electricity) + ) + heating_type = spm_unit("heating_type", period) + fuel = heating_type.possible_values + # No categorical income bypass or asset test. Existing inputs cannot + # identify every excluded institution, boarding house, or legal fixture. + return (size > 0) & income_eligible & responsible & (heating_type != fuel.NONE) diff --git a/policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.py b/policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.py new file mode 100644 index 00000000000..51602dd435c --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.py @@ -0,0 +1,53 @@ +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 oh_liheap_income_limit(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Ohio HEAP annual income limit" + defined_for = StateCode.OH + reference = ( + "https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7", + "https://clevelandohio.gov/sites/clevelandohio/files/aging/2024-2025_HEAP_application_B_W_1.pdf#page=1", + "https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=1", + "https://www.lccaa.net/wp-content/uploads/2026/07/2026-2027-EAP-Application-7-2026.pdf#page=1", + "https://occ.ohio.gov/sites/default/files/2026-08/OCC-Home-Energy-Assistance-Program-HEAP_0.pdf#page=1", + # HHS 60% SMI tables, Ohio row for sizes 7-12 and footnotes. + # PDF pages 5-6 + "https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM%202024-02_Att4SMITable.pdf#page=5", + # PDF pages 5-6 + "https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf#page=5", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.oh.odjfs.liheap.eligibility + size = spm_unit("oh_liheap_household_size", period) + state_group = spm_unit.household("state_group_str", period) + state = spm_unit.household("state_code_str", period) + guideline = fpg( + max_(size, 1), + state_group, + period, + parameters, + year_lag=p.fpg_year_lag, + ) + # FPG applies to all sizes in 2022-23, sizes 1-7 in 2024-25 and + # 2026-27, and sizes 1-8 in 2025-26. Flooring reproduces the printed + # whole-dollar limits; the 2022-23 cents do not change the outcome for + # whole-dollar income. + fpg_limit = np.floor(guideline * p.fpg_rate) + # Larger units use 60% of SMI: the current federal fiscal year's SMI for + # 2024-25 and 2025-26 and the prior year's for 2026-27 (smi_year_lag), + # inferred from the federal cap and the Consumers' Counsel limits. + smi_date = period.start.offset(-int(p.smi_year_lag), "year") + # The HHS floor order reproduces every HHS FFY2025 and FFY2026 amount + # and the Consumers' Counsel 2026-27 sizes 8, 11 and 12. Its sizes 9 + # and 10 ($96,946, $99,010) exceed even unrounded 60% of SMI + # ($96,945.68, $99,008.35); the HHS $96,944 and $99,007 apply. + smi_limit = liheap_smi_limit(size, state, p.smi_rate, smi_date, parameters) + limit = where(size <= p.maximum_fpg_household_size, fpg_limit, smi_limit) + return where(size > 0, limit, 0) diff --git a/policyengine_us/variables/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.py b/policyengine_us/variables/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.py new file mode 100644 index 00000000000..9710297b0a0 --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.py @@ -0,0 +1,56 @@ +from policyengine_us.model_api import * + + +class oh_liheap_countable_income(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Ohio HEAP annual countable household income" + defined_for = StateCode.OH + reference = ( + # Sections E-2.2-2.3 and Appendices XII and XXIII. + # PDF pages 7-8, 57, 73-74 + "https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7", + # Current income-source checklist. + # PDF pages 5-6 + "https://dam.assets.ohio.gov/image/upload/v1769700600/development.ohio.gov/individual/energyassistance/DETAILED_MODEL_PLAN_LIHEAP__10_01_2025.pdf#page=5", + # Current application deductions and excluded VA disabilities. + "https://www.clevelandohio.gov/sites/clevelandohio/files/aging/Home%20repair%20Applications/2025-2026_HEAP_application_B_W.pdf#page=7", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.oh.odjfs.liheap.income + person = spm_unit.members + # Tax-unit dependency approximates the policy's dependent-minor test. + dependent_minor = (person("age", period) < p.adult_age) & person( + "is_tax_unit_dependent", period + ) + # Keep the existing net business inputs without another expense + # deduction. Section E-2.3 counts a reported business loss as zero, and + # each source is floored at zero so a loss in one source cannot offset + # another. + income = 0 + for sources in [p.sources.earned, p.sources.unearned]: + for source in sources: + income = income + max_(person(source, period, options=[ADD]), 0) + # Guidelines E-2.2 (page 7) count the income of members 18 or older and + # a minor's SS/SSDI paid to an adult payee; a child's SSI and other + # income are not counted. The FY2026 plan (page 6) excludes only + # "Earned income of a child under the age of 18"; the Guidelines govern. + social_security = max_(person("social_security", period), 0) + counted = where(dependent_minor, 0, income) + social_security + # Nonqualified members' income is not prorated or excluded. Annual + # inputs represent the 12-month option; a separate favorable 30-day + # comparison and whole-dollar document processing are not modeled. + # Existing estate/financial inputs cannot capture all principal payouts, + # nonretirement investment draws, royalties, or legal settlements. + # Guidelines Appendix XXIII (page 74) and the application (page 7) + # deduct child support paid and health, dental, vision, prescription + # plan, and Medicare premiums, including premiums withheld before tax + # (Appendix XII, page 57); the FY2026 plan (page 6) counts Social + # Security "Excluding MediCare deduction". The premium inputs are + # disjoint, so no premium is deducted twice. Spenddown, disability + # premium, and legal-fee deductions have no input. + deductions = add(spm_unit, period, p.deductions) + return max_(spm_unit.sum(counted) - deductions, 0) diff --git a/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py new file mode 100644 index 00000000000..f02005ea2fe --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py @@ -0,0 +1,111 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class oh_liheap(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Ohio HEAP regular heating assistance" + defined_for = "oh_liheap_eligible" + reference = ( + # Final 2021 workbook. + # PDF pages 1, 8-11, 15-16, 19-20 + "https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1", + # Factors, counties and formula. + # PDF pages 1, 8-11, 15-16, 19-20, 29 + "https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1", + # 2024 and 2025 draft workbook covers. + "https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1", + "https://liheapch.acf.gov/docs/2026/benefits-matricies/OH_BenefitMatrix_2026.pdf#page=1", + # January 2025 customer FAQ: 75% PIPP reduction, not currently modeled. + "https://wofb.org/wp-content/uploads/2025/01/ATTACHMENT-2025-5-HEAP-FAQ-for-Customers.pdf#page=1", + # FY2027 draft plan items 2.5-2.6: FY2026 matrix range. + "https://dam.assets.ohio.gov/image/upload/v1783702985/jfs.ohio.gov/Energy%20and%20Community%20Assistance/2026-2027_Draft_HEAP_State_Plan.pdf#page=9", + # Sections E-1, E-2, E-2.10 and E-4: income, disability and heating facts. + # PDF pages 5-6, 10-12 + "https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=5", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.oh.odjfs.liheap + payment = p.payment + size = spm_unit("oh_liheap_household_size", period) + guideline = fpg( + max_(size, 1), + spm_unit.household("state_group_str", period), + period, + parameters, + year_lag=p.eligibility.fpg_year_lag, + ) + income = spm_unit("oh_liheap_countable_income", period) + poverty_percentage = 100 * np.clip( + income / guideline, + payment.formula.minimum_poverty_ratio, + payment.formula.maximum_poverty_ratio, + ) + # Final 2021 and 2023 regional tables label their terminal row 150+; + # eligibility can extend to 175%, but payments stop decreasing at 150%. + # Later coefficients are estimates: 2024-2025 from the draft covers and + # 2026 from the FY2026 matrix range in the FY2027 draft plan; the 2026 + # estimate carries into 2027 and later without verification. + # Annual income approximates the favorable 30-day/12-month comparison. + # Guidelines still follow the requested year and state lag. + base = max_( + payment.formula.intercept - payment.formula.slope * poverty_percentage, + 0, + ) + heating_type = spm_unit("heating_type", period) + fuel = heating_type.possible_values + fuel_ratio = select( + [ + (heating_type == fuel.NATURAL_GAS) | (heating_type == fuel.ELECTRICITY), + (heating_type == fuel.PROPANE) + | (heating_type == fuel.FUEL_OIL) + | (heating_type == fuel.KEROSENE), + (heating_type == fuel.COAL) | (heating_type == fuel.WOOD), + ], + [ + payment.fuel_cost_ratio.gas_electricity, + payment.fuel_cost_ratio.bulk_fuel, + payment.fuel_cost_ratio.coal_wood, + ], + default=0, + ) + county = spm_unit.household("county_str", period) + regional = payment.regional + regional_factor = select( + [ + np.isin(county, regional.northern_counties), + np.isin(county, regional.southern_counties), + np.isin(county, regional.central_counties), + ], + [1 + regional.adjustment, 1 - regional.adjustment, 1], + default=0, + ) + targeting = payment.targeted + age = spm_unit.members("age", period) + # is_disabled approximates verified permanent and total disability. + targeted_member = (age >= targeting.elderly_age) | spm_unit.members( + "is_disabled", period + ) + if targeting.young_child_in_effect: + targeted_member = targeted_member | (age <= targeting.young_child_age) + targeted = spm_unit.any(targeted_member) + multiplier = where(targeted, targeting.multiplier, 1) + # No existing input identifies PIPP enrollment: estimate the non-PIPP + # award and leave its 75% reduction unmodeled. Unpriced fuel or an + # explicit UNKNOWN or non-Ohio county returns an unsupported zero, not a + # finding of legal ineligibility: SOLAR and OTHER have no workbook + # column, and UNSPECIFIED pays $0 (see #9754 for the default fuel). + # An omitted county cannot be detected: the county input then defaults + # to the state's alphabetically first county, Adams, a southern county, + # so the estimate uses the 6% southern reduction. + # The workbooks print four-decimal coefficients. With the printed 2021 + # slope and fuel ratios, 36 printed 2021 cells (every fuel) differ by $1, + # and with the printed 2023 gas ratio, 19 printed 2023 gas and + # electricity cells do. Final half-up rounding matches the other printed + # fuel calculations; do not round a component before the regional and + # targeted adjustments. + return np.floor(base * fuel_ratio * regional_factor * multiplier + 0.5) diff --git a/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap_household_size.py b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap_household_size.py new file mode 100644 index 00000000000..2ea6788246a --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap_household_size.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class oh_liheap_household_size(Variable): + value_type = int + entity = SPMUnit + definition_period = YEAR + label = "Ohio HEAP household size" + defined_for = StateCode.OH + # Sections E-2.1 and E-2.8. + # PDF pages 7, 10 + reference = "https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7" + + # Nonqualified members are excluded from size, but their income counts. + # SPM membership approximates the energy economic unit. Custody, temporary + # absences, foster arrangements, and separate roomers need verified facts + # that the existing inputs do not fully identify. + adds = ["is_citizen_or_legal_immigrant"]