From 68f4882f22a54efa9c259dcea01d0519e38a1fce Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 3 Oct 2026 19:49:20 -0400 Subject: [PATCH 01/10] Add OH regular heating LIHEAP components --- changelog.d/oh-liheap.added.md | 1 + .../oh/odjfs/liheap/eligibility/fpg_rate.yaml | 10 + .../liheap/eligibility/fpg_year_lag.yaml | 11 + .../maximum_fpg_household_size.yaml | 13 + .../oh/odjfs/liheap/eligibility/smi_rate.yaml | 10 + .../liheap/income/earned_income_min_age.yaml | 10 + .../odjfs/liheap/income/sources/earned.yaml | 18 + .../odjfs/liheap/income/sources/unearned.yaml | 39 +++ policyengine_us/programs.yaml | 6 + .../eligibility/oh_liheap_eligible.yaml | 272 +++++++++++++++ .../eligibility/oh_liheap_income_limit.yaml | 64 ++++ .../income/oh_liheap_countable_income.yaml | 326 ++++++++++++++++++ .../liheap/oh_liheap_household_size.yaml | 72 ++++ .../liheap/eligibility/oh_liheap_eligible.py | 35 ++ .../eligibility/oh_liheap_income_limit.py | 41 +++ .../income/oh_liheap_countable_income.py | 46 +++ .../odjfs/liheap/oh_liheap_household_size.py | 17 + 17 files changed, 991 insertions(+) create mode 100644 changelog.d/oh-liheap.added.md create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_year_lag.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/maximum_fpg_household_size.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/smi_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/earned_income_min_age.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/earned.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/unearned.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap_household_size.yaml create mode 100644 policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.py create mode 100644 policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.py create mode 100644 policyengine_us/variables/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.py create mode 100644 policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap_household_size.py diff --git a/changelog.d/oh-liheap.added.md b/changelog.d/oh-liheap.added.md new file mode 100644 index 00000000000..f456961794a --- /dev/null +++ b/changelog.d/oh-liheap.added.md @@ -0,0 +1 @@ +Add Ohio HEAP household, income, and heating eligibility components. 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..3f760c6f6d3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_rate.yaml @@ -0,0 +1,10 @@ +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: + 2025-07-01: 1.75 +metadata: + unit: /1 + period: year + label: Ohio HEAP federal poverty guideline rate + reference: + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026, page 1 + 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/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_year_lag.yaml new file mode 100644 index 00000000000..a354584f445 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/fpg_year_lag.yaml @@ -0,0 +1,11 @@ +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. +values: + 2025-07-01: 1 +metadata: + unit: year + period: year + label: Ohio HEAP federal poverty guideline year lag + reference: + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026, page 1 (2025 poverty guidelines) + 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..a4a06ef1b48 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/maximum_fpg_household_size.yaml @@ -0,0 +1,13 @@ +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. +values: + 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 Energy Assistance Programs Application, July 2025-May 2026, page 1 + 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, page 1 + 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..1626ea67090 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/smi_rate.yaml @@ -0,0 +1,10 @@ +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: + 2025-07-01: 0.6 +metadata: + unit: /1 + period: year + label: Ohio HEAP state median income rate + reference: + - title: Ohio Energy Assistance Programs Application, July 2025-May 2026, page 1 + 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/income/earned_income_min_age.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/earned_income_min_age.yaml new file mode 100644 index 00000000000..c24b81cbcca --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/earned_income_min_age.yaml @@ -0,0 +1,10 @@ +description: Ohio excludes earned income of dependent household members below this age under the Home Energy Assistance Program. +values: + 2025-07-01: 18 +metadata: + unit: year + period: year + label: Ohio HEAP dependent earned income minimum age + reference: + - title: Ohio 2022-2023 Energy Assistance Programs Guidelines, section E-2.2, page 7 (dependent minor earnings) + href: https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.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..45662189144 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/earned.yaml @@ -0,0 +1,18 @@ +description: Ohio counts these earned income sources, except for dependent minors, 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, pages 7-8 and 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, pages 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..afc726ac4f4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/sources/unearned.yaml @@ -0,0 +1,39 @@ +description: Ohio counts these unearned income sources for household members of all ages under the Home Energy Assistance Program. +values: + 2025-07-01: + - unemployment_compensation + - strike_benefits + - social_security + - ssi + - pension_income + - 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 manual explicitly counts capital gains and estate/trust settlements, not +# merely asset sale proceeds. Those inputs do not capture every principal payout. +# Current plan excludes TANF, general assistance, child support, and cash gifts. +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, pages 7-8 and 73-74 + 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, pages 5-6 (current income inclusions and exclusions) + 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, physical page 7 (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/programs.yaml b/policyengine_us/programs.yaml index 756dc2c4988..725fac830a8 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -804,6 +804,12 @@ programs: status: partial coverage: OR, DC, Riverside County, MA, IL, KS, MS, TX state_implementations: + - state: OH + status: in_progress + name: Ohio LIHEAP + full_name: Ohio Low Income Home Energy Assistance Program + parameter_prefix: gov.states.oh.odjfs.liheap + notes: Income and ordinary eligibility components are implemented. The operative FY2026/FY2027 final payment matrix is still unavailable; historical final workbooks and provisional current ranges do not establish current awards. Regular heating only; historical backfills do not establish verified coverage. - state: OR status: in_progress name: 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..d0bd478e267 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.yaml @@ -0,0 +1,272 @@ +# Ohio income and eligibility components only; no payment schedule or final award is asserted. + +# Application p1 limit27387 is inclusive; current plan/manual has 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 above27387fails even with categorical-benefit receipts; current plan categoricalNo. +- 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 energy household includes undesignated heating in rent; flag represents verified arrangement in the contract. +- 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 + +# Positive primary gas bill is the approved proxy for the tenant own portion; no guessed benefit amount. +- 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 + +# Manual p10 requires an eligible citizen/qualified member; size0must not pass a safe fallback limit. +- 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 + +# Manual pp7,10: parent excluded from size, not income. Full28000 exceeds size1limit27387; headcount proration would incorrectly 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 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..8bfb0cda1cf --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.yaml @@ -0,0 +1,64 @@ +# Ohio income and eligibility components only; no payment schedule or final award is asserted. + +# 2025–2026 application p1 literal HEAP limits; whole-dollar175%of2025FPG, not the adjacent200%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] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200] + 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] + +# Unverified2025 estimate uses2024FPG15060 and52720, multiplied by1.75; no frozen2025guideline. +- name: Case 2, historical backfill uses its requested year federal guideline. + period: 2025 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH] + heating_type: [NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_200, 1_200] + oh_liheap_household_size: [1, 8] + output: + oh_liheap_income_limit: [26_355, 92_260] + +# 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 + heating_type: NATURAL_GAS + gas_expense: 1_200 + oh_liheap_household_size: 0 + output: + oh_liheap_income_limit: 0 + +# JFS00330 (07/2026), physical p1: seven literal annual HEAP limits for July2026-May2027. +- 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] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200] + 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 expressly switches to 60% SMI above seven people but prints no SMI dollar table. +# Federal FY2027 four-person SMI117810 with factors1.38 and1.41 gives97546.68/99667.26. +# Whole-dollar annual limits are the documented model approximation, not printed state amounts. +- name: Case 5, the 2027 eighth household member switches to the explicit SMI rule. + period: 2027 + absolute_error_margin: 0.01 + input: + state_code: [OH, OH] + heating_type: [NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_200, 1_200] + oh_liheap_household_size: [8, 9] + output: + oh_liheap_income_limit: [97_546, 99_667] 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..a9901952d31 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.yaml @@ -0,0 +1,326 @@ +# Ohio income and eligibility components only; no payment schedule or final award is asserted. + +# Manual p8:12000+6000+600+1200+1200=21000; existing net-business inputs need no added work-expense calculation. +- 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 21_000 + +# Current plan p6 and manual pp73–74:2400rent+1200farmrent+600survivor+1200pension+2400SSA+1200SSI=9000. +- 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 9_000 + +# Manual 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 6_360 + +# Manual pp7–8,76: only earned income of dependent minors is excluded. Child SSI2400 and SSA1200 remain included; otherwise wages6000 and netbusiness1200 count too. +- name: Case 4, age 17 dependent income follows the earned exemption 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: true + ssi: 2_400 + employment_income: 6_000 + self_employment_income: 1_200 + social_security: 1_200 + 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: 15_600 + +# Manual pp7–8,76: only earned income of dependent minors is excluded. Child SSI2400 and SSA1200 remain included; otherwise wages6000 and netbusiness1200 count too. +- name: Case 5, age 17 nondependent income follows the earned exemption 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 22_800 + +# Manual pp7–8,76: only earned income of dependent minors is excluded. Child SSI2400 and SSA1200 remain included; otherwise wages6000 and netbusiness1200 count too. +- name: Case 6, age 18 dependent income follows the earned exemption 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 22_800 + +# Manual p8 directs reported business losses to0:12000wages+600positive business+1200SSI=13800; 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 13_800 + +# Current plan p6 checkbox selections: TANF/general assistance/child support excluded, alimony included. SNAP is noncash excluded income. +- name: Case 8, TANF general assistance and child support are excluded while alimony counts. + 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + tanf: 3_600 + snap: 6_000 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 13_200 + +# Current FY2026 application physical p7 and manual physical 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_liheap_countable_income: 11_400 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..81230a09127 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap_household_size.yaml @@ -0,0 +1,72 @@ +# Ohio income and eligibility components only; no payment schedule or final award is asserted. + +# Manual 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: OH + output: + oh_liheap_household_size: 3 + +# Manual p10: nonqualified members are excluded from household membership used for eligibility. +- name: Case 2, all nonqualified members produce a zero qualified size. + period: 2026 + absolute_error_margin: 0.01 + 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 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..3be376382e5 --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_eligible.py @@ -0,0 +1,35 @@ +from policyengine_us.model_api import * + + +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", + ) + + def formula(spm_unit, period, parameters): + size = spm_unit("oh_liheap_household_size", period) + income = spm_unit("oh_liheap_countable_income", period) + limit = spm_unit("oh_liheap_income_limit", period) + 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) + ) + # A primary heating bill approximates the verified household liability, + # including the household's own portion in subsidized housing. For + # nonsubsidized heat in rent, the flag represents the verified arrangement. + responsible = (spm_unit("heating_expense", period) > 0) | ( + heat_in_rent & ~subsidized + ) + 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 <= limit) & 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..f9c1c3160d9 --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/eligibility/oh_liheap_income_limit.py @@ -0,0 +1,41 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg +from policyengine_us.variables.gov.hhs.hhs_smi import smi + + +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://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", + ) + + 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, + ) + # Flooring reproduces the printed FPG amounts: sizes 1-8 for the + # 2025-26 application and 1-7 for 2026-27. Larger units use 60% SMI. + # The 2026-27 Consumers' Counsel fact sheet's larger-household dollar + # figures do not reconcile to the current federal SMI. Use the state + # application's express percentage; whole-dollar flooring remains an + # annual approximation, not a verified large-household dollar table. + limit = where( + size <= p.maximum_fpg_household_size, + guideline * p.fpg_rate, + smi(size, state, period, parameters) * p.smi_rate, + ) + return where(size > 0, np.floor(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..2a5ac714aa1 --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/income/oh_liheap_countable_income.py @@ -0,0 +1,46 @@ +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 Appendix XXIII, pages 7-8 and 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, 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, page 7. + "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 + dependent_minor = (person("age", period) < p.earned_income_min_age) & person( + "is_tax_unit_dependent", period + ) + # Tax-unit dependency approximates the policy's dependent-minor test. + # Keep the existing net business inputs without another expense + # deduction. Section E-2.3 counts a reported business loss as zero. + earned = 0 + for source in p.sources.earned: + earned = earned + max_(person(source, period), 0) + unearned = 0 + for source in p.sources.unearned: + unearned = unearned + max_(person(source, period, options=[ADD]), 0) + # Minor unearned income, including SSA paid through an adult guardian, + # counts. 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. + # Medicare deductions are deferred. Other premium, spenddown, disability + # premium, and legal-fee deductions need source/input reconciliation; + # existing aggregates do not isolate the covered non-Medicare amounts. + income = spm_unit.sum(earned * ~dependent_minor + unearned) + child_support_paid = add(spm_unit, period, ["child_support_expense"]) + return max_(income - child_support_paid, 0) 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..4ab33fbd7df --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap_household_size.py @@ -0,0 +1,17 @@ +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.6, physical pages 7 and 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"] From 5224cf3a6f25a24cb976420c1787b7e450ccadcd Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 3 Oct 2026 22:50:55 -0400 Subject: [PATCH 02/10] Fix Ohio LIHEAP heat-in-rent electricity eligibility --- .../eligibility/oh_liheap_eligible.yaml | 55 +++++++++++++++++++ .../liheap/eligibility/oh_liheap_eligible.py | 9 +-- 2 files changed, 60 insertions(+), 4 deletions(-) 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 index d0bd478e267..568853ec072 100644 --- 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 @@ -270,3 +270,58 @@ 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 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 index 3be376382e5..098078dd017 100644 --- 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 @@ -20,11 +20,12 @@ def formula(spm_unit, period, parameters): subsidized = spm_unit("receives_housing_assistance", period) | ( spm_unit.household("is_in_public_housing", period) ) - # A primary heating bill approximates the verified household liability, - # including the household's own portion in subsidized housing. For - # nonsubsidized heat in rent, the flag represents the verified arrangement. + # Reported bills and rental terms approximate verified liability. The + # heating plan also permits subsidized heat-in-rent tenants who pay all + # or part of a separate electric bill (Section 2.3). + pays_electricity = spm_unit("electricity_expense", period) > 0 responsible = (spm_unit("heating_expense", period) > 0) | ( - heat_in_rent & ~subsidized + heat_in_rent & (~subsidized | pays_electricity) ) heating_type = spm_unit("heating_type", period) fuel = heating_type.possible_values From e057d4a22b644151e47ef74da2cec896b32cde28 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 6 Oct 2026 15:49:51 -0400 Subject: [PATCH 03/10] Clarify Ohio LIHEAP eligibility-only coverage --- policyengine_us/programs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 725fac830a8..c3824490ad1 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -809,7 +809,7 @@ programs: name: Ohio LIHEAP full_name: Ohio Low Income Home Energy Assistance Program parameter_prefix: gov.states.oh.odjfs.liheap - notes: Income and ordinary eligibility components are implemented. The operative FY2026/FY2027 final payment matrix is still unavailable; historical final workbooks and provisional current ranges do not establish current awards. Regular heating only; historical backfills do not establish verified coverage. + notes: Income and ordinary eligibility components are implemented. Income limits follow the stated FPG/SMI rates, with the published large-household dollar discrepancy documented in code. The current final award is deferred pending an adopted FY2026/FY2027 payment matrix; historical workbooks and provisional current ranges do not establish current awards. Regular heating only; historical backfills do not establish verified coverage. - state: OR status: in_progress name: LIHEAP From e66470d13de82c9ff607efd61d47fac07620a713 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 6 Oct 2026 16:20:05 -0400 Subject: [PATCH 04/10] Add Ohio heating payment estimates from final 2023 workbook --- changelog.d/oh-liheap.added.md | 2 +- .../liheap/payment/formula/intercept.yaml | 11 + .../formula/minimum_poverty_ratio.yaml | 11 + .../odjfs/liheap/payment/formula/slope.yaml | 11 + .../payment/fuel_cost_ratio/bulk_fuel.yaml | 11 + .../payment/fuel_cost_ratio/coal_wood.yaml | 11 + .../fuel_cost_ratio/gas_electricity.yaml | 13 + .../liheap/payment/regional/adjustment.yaml | 11 + .../payment/regional/central_counties.yaml | 64 ++++ .../payment/regional/northern_counties.yaml | 35 +++ .../payment/regional/southern_counties.yaml | 22 ++ .../liheap/payment/targeted/elderly_age.yaml | 11 + .../liheap/payment/targeted/multiplier.yaml | 11 + .../payment/targeted/young_child_age.yaml | 11 + policyengine_us/programs.yaml | 5 +- .../gov/states/oh/odjfs/liheap/oh_liheap.yaml | 295 ++++++++++++++++++ .../gov/states/oh/odjfs/liheap/oh_liheap.py | 86 +++++ 17 files changed, 618 insertions(+), 3 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/intercept.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/minimum_poverty_ratio.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/slope.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/bulk_fuel.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/coal_wood.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/gas_electricity.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/adjustment.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/central_counties.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/northern_counties.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/southern_counties.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/elderly_age.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/multiplier.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/young_child_age.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap.yaml create mode 100644 policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py diff --git a/changelog.d/oh-liheap.added.md b/changelog.d/oh-liheap.added.md index f456961794a..63e57397055 100644 --- a/changelog.d/oh-liheap.added.md +++ b/changelog.d/oh-liheap.added.md @@ -1 +1 @@ -Add Ohio HEAP household, income, and heating eligibility components. +Add Ohio HEAP household, income, eligibility, and regular heating payment estimates using final 2023 workbook values carried forward while awaiting an updated final schedule. 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..643481c2ab7 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/intercept.yaml @@ -0,0 +1,11 @@ +description: Ohio starts the payment formula with this intercept under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +values: + 2023-01-01: 731.5 +metadata: + unit: currency-USD + period: year + label: Ohio HEAP payment intercept + reference: + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 11" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=11 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..0984eb30a60 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/minimum_poverty_ratio.yaml @@ -0,0 +1,11 @@ +description: Ohio uses at least this federal poverty ratio when calculating payments under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +values: + 2023-01-01: 0.5 +metadata: + unit: /1 + period: year + label: Ohio HEAP minimum poverty ratio for payments + reference: + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.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..36fe5b2f098 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/slope.yaml @@ -0,0 +1,11 @@ +description: Ohio reduces the payment formula by this amount per federal poverty percentage point under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +values: + 2023-01-01: 1.33 +metadata: + unit: currency-USD + period: year + label: Ohio HEAP payment reduction per poverty percentage point + reference: + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 11" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=11 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..aa22f05a6aa --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/bulk_fuel.yaml @@ -0,0 +1,11 @@ +description: Ohio uses this fuel cost ratio for propane, fuel oil, and kerosene under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +values: + 2023-01-01: 1 +metadata: + unit: /1 + period: year + label: Ohio HEAP propane oil and kerosene fuel cost ratio + reference: + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 9" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=9 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..e2fb37c9a86 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/coal_wood.yaml @@ -0,0 +1,11 @@ +description: Ohio uses this fuel cost ratio for coal and wood under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +values: + 2023-01-01: 0.6 +metadata: + unit: /1 + period: year + label: Ohio HEAP coal and wood fuel cost ratio + reference: + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 9" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=9 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..6d109a49ab0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/gas_electricity.yaml @@ -0,0 +1,13 @@ +description: Ohio uses this fuel cost ratio for natural gas and electricity under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +# Uses the published four-decimal ratio. Some printed gas/electric dollar +# cells differ by $1 from this formula; unprinted precision is not inferred. +values: + 2023-01-01: 0.5523 +metadata: + unit: /1 + period: year + label: Ohio HEAP gas and electricity fuel cost ratio + reference: + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 9" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=9 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..65074850f05 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/adjustment.yaml @@ -0,0 +1,11 @@ +description: Ohio adjusts payments up or down by this share for designated northern and southern counties under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +values: + 2023-01-01: 0.06 +metadata: + unit: /1 + period: year + label: Ohio HEAP regional payment adjustment + reference: + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.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..d5fff78d916 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/central_counties.yaml @@ -0,0 +1,64 @@ +description: Ohio does not regionally adjust payments for these counties under the Home Energy Assistance Program. +# Final 2023 county assignment; carried forward pending an updated schedule. +values: + 2023-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 2023 FINAL LIHEAP Benefit Matrix, #page 8" + 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..c2b157f0078 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/northern_counties.yaml @@ -0,0 +1,35 @@ +description: Ohio increases payments for these counties under the Home Energy Assistance Program. +# Final 2023 county assignment; carried forward pending an updated schedule. +values: + 2023-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 2023 FINAL LIHEAP Benefit Matrix, #page 8" + 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..318e027a298 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/regional/southern_counties.yaml @@ -0,0 +1,22 @@ +description: Ohio decreases payments for these counties under the Home Energy Assistance Program. +# Final 2023 county assignment; carried forward pending an updated schedule. +values: + 2023-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 2023 FINAL LIHEAP Benefit Matrix, #page 8" + 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..86be5685e01 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/elderly_age.yaml @@ -0,0 +1,11 @@ +description: Ohio increases payments for households with a member at least this age under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +values: + 2023-01-01: 60 +metadata: + unit: year + period: year + label: Ohio HEAP targeted household elderly minimum age + reference: + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.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..119527ff9af --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/multiplier.yaml @@ -0,0 +1,11 @@ +description: Ohio multiplies payments by this factor for households with an older, disabled, or young member under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +values: + 2023-01-01: 1.75 +metadata: + unit: /1 + period: year + label: Ohio HEAP targeted household payment multiplier + reference: + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.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..b2b4c7d285f --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/young_child_age.yaml @@ -0,0 +1,11 @@ +description: Ohio increases payments for households with a child no older than this age under the Home Energy Assistance Program. +# Final 2023 workbook; carried forward pending an updated final schedule. +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, #page 1" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index c3824490ad1..adb57b1beb4 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -805,11 +805,12 @@ programs: coverage: OR, DC, Riverside County, MA, IL, KS, MS, TX state_implementations: - state: OH - status: in_progress + status: partial name: Ohio LIHEAP full_name: Ohio Low Income Home Energy Assistance Program + variable: oh_liheap parameter_prefix: gov.states.oh.odjfs.liheap - notes: Income and ordinary eligibility components are implemented. Income limits follow the stated FPG/SMI rates, with the published large-household dollar discrepancy documented in code. The current final award is deferred pending an adopted FY2026/FY2027 payment matrix; historical workbooks and provisional current ranges do not establish current awards. Regular heating only; historical backfills do not establish verified coverage. + notes: Regular heating eligibility and a non-PIPP payment estimate using final 2023 workbook values, dated from 2023 and carried forward pending an updated final schedule. Formula extension above the printed 150% poverty payment range is an approved estimate; the workbook's cover allows 175%. PIPP enrollment and its payment reduction are unmodeled. Some gas/electric table cells differ by one dollar from the printed fuel ratio. Unpriced fuels and unknown counties remain unsupported. Income limits follow the stated FPG/SMI rates with the published large-household discrepancy documented. Earlier-year backfills and later-year payments are unverified estimates; complete historical-year coverage is not claimed. - state: OR status: in_progress name: LIHEAP 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..0a099c90005 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/oh_liheap.yaml @@ -0,0 +1,295 @@ +# Final 2023 workbook: page 1 factors, page 8 counties, pages 9-11 formula/tables. +# Payments after 2023 carry historical values forward. Above 150% FPG is a user-approved +# extrapolation; 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] +- name: Case 5, the approved extrapolation covers income above 150 percent while ordinary eligibility + still 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: [532, 532, 515, 499, 0] +- name: Case 6, the 2026 estimate carries payment values forward but updates the lagged 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: [599] +- name: Case 7, the 2027 estimate carries payment values forward but updates the lagged 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: [599] +- 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: [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, 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: [665, 367, 0, 0, 0] +- 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: [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] 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..66c7a6f5bed --- /dev/null +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py @@ -0,0 +1,86 @@ +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 = ( + # Physical pages 1,8-11,15-16,19-20,29: factors, counties and formula. + "https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1", + # Sections E-1, E-2, E-2.10 and E-4: income, disability and heating facts. + "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 * max_( + income / guideline, payment.formula.minimum_poverty_ratio + ) + # The final 2023 workbook's filled coefficients are used from 2023, + # carrying forward until an updated final schedule is available. Its + # cover allows 175% FPG but detailed tables end at 150%; extending the + # formula above 150% is an explicitly approved estimate, not a sourced + # payment rule. 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, + ) + age = spm_unit.members("age", period) + # is_disabled approximates verified permanent and total disability. + targeted = spm_unit.any( + (age >= payment.targeted.elderly_age) + | (age <= payment.targeted.young_child_age) + | spm_unit.members("is_disabled", period) + ) + multiplier = where(targeted, payment.targeted.multiplier, 1) + # No existing input identifies PIPP enrollment: estimate the non-PIPP + # award and leave its 75% reduction unmodeled. Unknown county or unpriced + # fuel returns an unsupported zero, not a finding of legal ineligibility. + # The published gas ratio has four decimals; some table cells differ by + # $1. 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) From 7d383d4955df164d68c74be74c57f81b476d41e8 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 6 Oct 2026 18:37:31 -0400 Subject: [PATCH 05/10] Fix Ohio LIHEAP years, limits and income counting from review - Encode the FINAL 2021 benefit workbook (intercept, slope, fuel ratios, targeted multiplier, no young-child targeting); the 2021 values carry through 2022 because no final 2022 workbook was found. - Encode the 2024 and 2025 benefit workbook values, derived from the workbooks' credit percentages and matching their printed fuel maximums ($811/$441). The 2025 values carry into 2026 and later as unverified estimates: the 2026 workbook is not published. - Date the income-limit rules: 175% FPG for every size in 2022-23, FPG through size 7 with 60% SMI above from 2024-25, size 8 on FPG from 2025-07-01. Use the FFY2025 SMI for 2024-25 and the FFY2026 SMI for 2025-26 and 2026-27, inferred from the printed FPG-to-SMI switch points under the 42 USC 8624(b)(2)(B) cap and the 2026-27 OCC limits, and round as the HHS tables do (truncate 60% of the four-person median, then the size-adjusted amount), reproducing every published HHS amount. - Deduct the Medicare Part B premium; count military retirement pay, railroad benefits and general assistance (Guidelines catch-all, followed over the plan); count a minor's Social Security but not a child's SSI or other income; floor each source at zero. - Document that an omitted county falls back to Adams County. - Put OH on the LIHEAP coverage line; verified_years 2025. - Add and update tests for each change. Co-Authored-By: Claude Opus 5.5 --- changelog.d/oh-liheap.added.md | 2 +- .../oh/odjfs/liheap/eligibility/fpg_rate.yaml | 10 +- .../liheap/eligibility/fpg_year_lag.yaml | 12 +- .../maximum_fpg_household_size.yaml | 19 +- .../oh/odjfs/liheap/eligibility/smi_rate.yaml | 8 +- .../liheap/eligibility/smi_year_lag.yaml | 28 ++ .../oh/odjfs/liheap/income/adult_age.yaml | 12 + .../liheap/income/earned_income_min_age.yaml | 10 - .../odjfs/liheap/income/sources/unearned.yaml | 22 +- .../liheap/payment/formula/intercept.yaml | 27 +- .../formula/minimum_poverty_ratio.yaml | 7 +- .../odjfs/liheap/payment/formula/slope.yaml | 15 +- .../payment/fuel_cost_ratio/bulk_fuel.yaml | 8 +- .../payment/fuel_cost_ratio/coal_wood.yaml | 10 +- .../fuel_cost_ratio/gas_electricity.yaml | 17 +- .../liheap/payment/regional/adjustment.yaml | 9 +- .../payment/regional/central_counties.yaml | 6 +- .../payment/regional/northern_counties.yaml | 6 +- .../payment/regional/southern_counties.yaml | 6 +- .../liheap/payment/targeted/elderly_age.yaml | 9 +- .../liheap/payment/targeted/multiplier.yaml | 10 +- .../payment/targeted/young_child_age.yaml | 5 +- .../targeted/young_child_in_effect.yaml | 19 ++ policyengine_us/programs.yaml | 5 +- .../eligibility/oh_liheap_eligible.yaml | 69 +++++ .../eligibility/oh_liheap_income_limit.yaml | 73 ++++- .../income/oh_liheap_countable_income.yaml | 167 +++++++++- .../gov/states/oh/odjfs/liheap/oh_liheap.yaml | 292 +++++++++++++++++- .../eligibility/oh_liheap_income_limit.py | 43 ++- .../income/oh_liheap_countable_income.py | 48 +-- .../gov/states/oh/odjfs/liheap/oh_liheap.py | 40 ++- 31 files changed, 890 insertions(+), 124 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/eligibility/smi_year_lag.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/adult_age.yaml delete mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/earned_income_min_age.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/targeted/young_child_in_effect.yaml diff --git a/changelog.d/oh-liheap.added.md b/changelog.d/oh-liheap.added.md index 63e57397055..e9709aa9e46 100644 --- a/changelog.d/oh-liheap.added.md +++ b/changelog.d/oh-liheap.added.md @@ -1 +1 @@ -Add Ohio HEAP household, income, eligibility, and regular heating payment estimates using final 2023 workbook values carried forward while awaiting an updated final schedule. +Add Ohio HEAP household, income, eligibility, and regular heating payments from the 2021, 2023, 2024 and 2025 benefit workbooks. 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 index 3f760c6f6d3..9a304d84227 100644 --- 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 @@ -1,10 +1,16 @@ 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: - 2025-07-01: 1.75 + 2022-07-01: 1.75 metadata: unit: /1 period: year label: Ohio HEAP federal poverty guideline rate reference: - - title: Ohio Energy Assistance Programs Application, July 2025-May 2026, page 1 + - 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 + - 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 index a354584f445..5965febfc29 100644 --- 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 @@ -1,11 +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. +# 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: - 2025-07-01: 1 + 2022-07-01: 1 metadata: unit: year period: year label: Ohio HEAP federal poverty guideline year lag reference: - - title: Ohio Energy Assistance Programs Application, July 2025-May 2026, page 1 (2025 poverty guidelines) + - 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 index a4a06ef1b48..ffe18a9e028 100644 --- 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 @@ -1,5 +1,12 @@ 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. +# No 2023-2024 rule was found, so that season keeps the 2022-2023 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: @@ -7,7 +14,15 @@ metadata: period: year label: Ohio HEAP maximum household size for poverty guideline limit reference: - - title: Ohio Energy Assistance Programs Application, July 2025-May 2026, page 1 + - 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 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, 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 index 1626ea67090..ad1a5fc6346 100644 --- 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 @@ -1,10 +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: - 2025-07-01: 0.6 + 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 2025-May 2026, 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/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..f3ca8da0d22 --- /dev/null +++ b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/adult_age.yaml @@ -0,0 +1,12 @@ +description: Ohio counts the income of household members at least this age 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/earned_income_min_age.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/earned_income_min_age.yaml deleted file mode 100644 index c24b81cbcca..00000000000 --- a/policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/earned_income_min_age.yaml +++ /dev/null @@ -1,10 +0,0 @@ -description: Ohio excludes earned income of dependent household members below this age under the Home Energy Assistance Program. -values: - 2025-07-01: 18 -metadata: - unit: year - period: year - label: Ohio HEAP dependent earned income minimum age - reference: - - title: Ohio 2022-2023 Energy Assistance Programs Guidelines, section E-2.2, page 7 (dependent minor earnings) - href: https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=7 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 index afc726ac4f4..2edad2a768a 100644 --- 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 @@ -1,11 +1,24 @@ -description: Ohio counts these unearned income sources for household members of all ages under the Home Energy Assistance Program. +description: Ohio counts these unearned income sources, except for dependent minors, under the Home Energy Assistance Program. values: 2025-07-01: - unemployment_compensation - strike_benefits - - social_security + # 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 @@ -25,13 +38,14 @@ values: # Retirement account withdrawals are distinct from pension income in the model. # The manual explicitly counts capital gains and estate/trust settlements, not # merely asset sale proceeds. Those inputs do not capture every principal payout. -# Current plan excludes TANF, general assistance, child support, and cash gifts. +# 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, pages 7-8 and 73-74 + - title: "Ohio 2022-2023 Energy Assistance Programs Guidelines, sections E-2.2-2.3 and Appendix XXIII, pages 7-8 and 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, pages 5-6 (current income inclusions and exclusions) 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/payment/formula/intercept.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/intercept.yaml index 643481c2ab7..45132179450 100644 --- 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 @@ -1,11 +1,36 @@ description: Ohio starts the payment formula with this intercept under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. +# The 2021 values carry through 2022; no final 2022 workbook was found. +# The 2024 and 2025 draft workbooks print only their maximum and minimum +# credit percentages (46%/38% and 25%/22%). Applying the 2023 workbook's +# page 11 method with its $950 high winter cost gives 0.50 x 950 = 475 and +# 0.265 x 950 = 251.75. These reproduce the printed credit percentages and +# every printed fuel maximum, including the $811 and $441 maximums in the +# FY2025 and FY2026 plans. The printed minimum dollar amounts ($41 and $24) +# include a further factor of about 0.2 that the model does not apply. +# The 2025 draft values carry into 2026 and later. The FY2027 draft plan's +# section 2.6 reports the unpublished 2026 matrix at a $31 minimum and $546 +# maximum, so 2026 and later payments are unverified estimates. values: + 2021-01-01: 593.2133 2023-01-01: 731.5 + 2024-01-01: 475 + 2025-01-01: 251.75 metadata: unit: currency-USD period: year label: Ohio HEAP payment intercept reference: + - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 11" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=11 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 11" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=11 + - title: "Ohio 2024 DRAFT LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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 LIHEAP State Plan draft, section 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/minimum_poverty_ratio.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/minimum_poverty_ratio.yaml index 0984eb30a60..f8529c0ee91 100644 --- 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 @@ -1,11 +1,14 @@ description: Ohio uses at least this federal poverty ratio when calculating payments under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. values: - 2023-01-01: 0.5 + 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, #page 1" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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 index 36fe5b2f098..cc77cf69236 100644 --- 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 @@ -1,11 +1,24 @@ description: Ohio reduces the payment formula by this amount per federal poverty percentage point under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. +# The 2021 values carry through 2022; no final 2022 workbook was found. +# For the 2024 and 2025 draft workbooks, (46% - 38%) / 100 x $950 = 0.76 and +# (25% - 22%) / 100 x $950 = 0.285, using the 2023 workbook's page 11 method +# and high winter cost. The 2025 draft value carries into 2026 and later, +# which are unverified estimates. values: + 2021-01-01: 0.9813 2023-01-01: 1.33 + 2024-01-01: 0.76 + 2025-01-01: 0.285 metadata: unit: currency-USD period: year label: Ohio HEAP payment reduction per poverty percentage point reference: + - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 11" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=11 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 11" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=11 + - title: "Ohio 2024 DRAFT LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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/bulk_fuel.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/bulk_fuel.yaml index aa22f05a6aa..73562ee146c 100644 --- 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 @@ -1,11 +1,17 @@ description: Ohio uses this fuel cost ratio for propane, fuel oil, and kerosene under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. +# 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, #page 9" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=9 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 9" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=9 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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 index e2fb37c9a86..c048975e264 100644 --- 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 @@ -1,11 +1,19 @@ description: Ohio uses this fuel cost ratio for coal and wood under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. +# 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, #page 9" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=9 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 9" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=9 + - title: "Ohio 2024 DRAFT LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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 index 6d109a49ab0..2ab1ef1f81d 100644 --- 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 @@ -1,13 +1,24 @@ description: Ohio uses this fuel cost ratio for natural gas and electricity under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. -# Uses the published four-decimal ratio. Some printed gas/electric dollar -# cells differ by $1 from this formula; unprinted precision is not inferred. +# Uses the published four-decimal ratios. Some printed 2023 gas/electric +# dollar cells differ by $1 from this formula; 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, #page 9" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=9 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 9" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=9 + - title: "Ohio 2024 DRAFT LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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 index 65074850f05..57395e58e73 100644 --- 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 @@ -1,11 +1,16 @@ description: Ohio adjusts payments up or down by this share for designated northern and southern counties under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. values: - 2023-01-01: 0.06 + 2021-01-01: 0.06 metadata: unit: /1 period: year label: Ohio HEAP regional payment adjustment reference: + - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: "Ohio 2024 DRAFT LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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 index d5fff78d916..e303c433a84 100644 --- 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 @@ -1,7 +1,7 @@ description: Ohio does not regionally adjust payments for these counties under the Home Energy Assistance Program. -# Final 2023 county assignment; carried forward pending an updated schedule. +# The final 2021 and 2023 workbooks assign all 88 counties identically. values: - 2023-01-01: + 2021-01-01: - ALLEN_COUNTY_OH - ASHLAND_COUNTY_OH - ATHENS_COUNTY_OH @@ -60,5 +60,7 @@ metadata: period: year label: Ohio HEAP central counties reference: + - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 8" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=8 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 8" 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 index c2b157f0078..c0800985d17 100644 --- 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 @@ -1,7 +1,7 @@ description: Ohio increases payments for these counties under the Home Energy Assistance Program. -# Final 2023 county assignment; carried forward pending an updated schedule. +# The final 2021 and 2023 workbooks assign all 88 counties identically. values: - 2023-01-01: + 2021-01-01: - ASHTABULA_COUNTY_OH - CUYAHOGA_COUNTY_OH - DEFIANCE_COUNTY_OH @@ -31,5 +31,7 @@ metadata: period: year label: Ohio HEAP northern counties reference: + - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 8" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=8 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 8" 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 index 318e027a298..3b93a2b0046 100644 --- 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 @@ -1,7 +1,7 @@ description: Ohio decreases payments for these counties under the Home Energy Assistance Program. -# Final 2023 county assignment; carried forward pending an updated schedule. +# The final 2021 and 2023 workbooks assign all 88 counties identically. values: - 2023-01-01: + 2021-01-01: - ADAMS_COUNTY_OH - BROWN_COUNTY_OH - CLERMONT_COUNTY_OH @@ -18,5 +18,7 @@ metadata: period: year label: Ohio HEAP southern counties reference: + - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 8" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=8 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 8" 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 index 86be5685e01..fcd78dc1cb7 100644 --- 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 @@ -1,11 +1,16 @@ description: Ohio increases payments for households with a member at least this age under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. values: - 2023-01-01: 60 + 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, #page 1" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: "Ohio 2024 DRAFT LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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 index 119527ff9af..9ab0b501903 100644 --- 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 @@ -1,11 +1,17 @@ -description: Ohio multiplies payments by this factor for households with an older, disabled, or young member under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. +description: Ohio multiplies payments by this factor for targeted households 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, #page 1" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: "Ohio 2024 DRAFT LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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 index b2b4c7d285f..54be63dccac 100644 --- 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 @@ -1,5 +1,4 @@ description: Ohio increases payments for households with a child no older than this age under the Home Energy Assistance Program. -# Final 2023 workbook; carried forward pending an updated final schedule. values: 2023-01-01: 5 metadata: @@ -9,3 +8,7 @@ metadata: reference: - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: "Ohio 2024 DRAFT LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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..dbda4f1332b --- /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, #page 1" + href: https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1 + - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2024/benefits-matricies/OH_BenefitMatrix_2024.pdf#page=1 + - title: "Ohio 2024 DRAFT LIHEAP Benefit Matrix, #page 1" + href: https://liheapch.acf.gov/docs/2025/benefits-matricies/OH_BenefitMatrix_2025.pdf#page=1 + - title: "Ohio 2025 DRAFT LIHEAP Benefit Matrix, #page 1" + 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 adb57b1beb4..ca75ee8de5a 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -802,7 +802,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: OR, DC, Riverside County, MA, IL, KS, MS, TX + coverage: OR, DC, Riverside County, MA, IL, KS, MS, OH, TX state_implementations: - state: OH status: partial @@ -810,7 +810,8 @@ programs: full_name: Ohio Low Income Home Energy Assistance Program variable: oh_liheap parameter_prefix: gov.states.oh.odjfs.liheap - notes: Regular heating eligibility and a non-PIPP payment estimate using final 2023 workbook values, dated from 2023 and carried forward pending an updated final schedule. Formula extension above the printed 150% poverty payment range is an approved estimate; the workbook's cover allows 175%. PIPP enrollment and its payment reduction are unmodeled. Some gas/electric table cells differ by one dollar from the printed fuel ratio. Unpriced fuels and unknown counties remain unsupported. Income limits follow the stated FPG/SMI rates with the published large-household discrepancy documented. Earlier-year backfills and later-year payments are unverified estimates; complete historical-year coverage is not claimed. + verified_years: "2025" + notes: FY2025 regular heating only, from the 2024-25 application and the 2025 benefit workbook. Crisis, cooling and weatherization assistance are out of scope. - state: OR status: in_progress name: 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 index 568853ec072..255d49ceef5 100644 --- 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 @@ -325,3 +325,72 @@ 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 index 8bfb0cda1cf..8b3a38dd7a3 100644 --- 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 @@ -13,17 +13,21 @@ output: oh_liheap_income_limit: [27_387, 37_012, 46_637, 56_262, 65_887, 75_512, 85_137, 94_762] -# Unverified2025 estimate uses2024FPG15060 and52720, multiplied by1.75; no frozen2025guideline. -- name: Case 2, historical backfill uses its requested year federal guideline. +# 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] - heating_type: [NATURAL_GAS, NATURAL_GAS] - gas_expense: [1_200, 1_200] - oh_liheap_household_size: [1, 8] + state_code: [OH, OH, OH, OH] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_200, 1_200, 1_200, 1_200] + oh_liheap_household_size: [1, 7, 8, 9] output: - oh_liheap_income_limit: [26_355, 92_260] + 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. @@ -49,16 +53,61 @@ output: oh_liheap_income_limit: [27_930, 37_870, 47_810, 57_750, 67_690, 77_630, 87_570] -# The form expressly switches to 60% SMI above seven people but prints no SMI dollar table. -# Federal FY2027 four-person SMI117810 with factors1.38 and1.41 gives97546.68/99667.26. -# Whole-dollar annual limits are the documented model approximation, not printed state amounts. -- name: Case 5, the 2027 eighth household member switches to the explicit SMI rule. +# 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] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_200, 1_200, 1_200, 1_200, 1_200] + 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] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_200, 1_200, 1_200, 1_200] + oh_liheap_household_size: [1, 8, 9, 10] + output: + oh_liheap_income_limit: [23_782, 81_602, 89_862, 98_122] + +# No 2023-2024 rule was found, so model year 2024 keeps the all-sizes rule with the 2023 +# FPG: 14,580 x 1.75 = 25,515; (14,580 + 7 x 5,140) x 1.75 = 88,480; +# (14,580 + 8 x 5,140) x 1.75 = 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] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_200, 1_200, 1_200] + 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] heating_type: [NATURAL_GAS, NATURAL_GAS] gas_expense: [1_200, 1_200] oh_liheap_household_size: [8, 9] output: - oh_liheap_income_limit: [97_546, 99_667] + 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 index a9901952d31..96c14b5e718 100644 --- 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 @@ -85,8 +85,10 @@ output: oh_liheap_countable_income: 6_360 -# Manual pp7–8,76: only earned income of dependent minors is excluded. Child SSI2400 and SSA1200 remain included; otherwise wages6000 and netbusiness1200 count too. -- name: Case 4, age 17 dependent income follows the earned exemption boundary. +# 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: @@ -115,10 +117,11 @@ members: [person1, person2] state_code: OH output: - oh_liheap_countable_income: 15_600 + oh_liheap_countable_income: 13_200 -# Manual pp7–8,76: only earned income of dependent minors is excluded. Child SSI2400 and SSA1200 remain included; otherwise wages6000 and netbusiness1200 count too. -- name: Case 5, age 17 nondependent income follows the earned exemption boundary. +# 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: @@ -149,8 +152,9 @@ output: oh_liheap_countable_income: 22_800 -# Manual pp7–8,76: only earned income of dependent minors is excluded. Child SSI2400 and SSA1200 remain included; otherwise wages6000 and netbusiness1200 count too. -- name: Case 6, age 18 dependent income follows the earned exemption boundary. +# 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: @@ -208,8 +212,11 @@ output: oh_liheap_countable_income: 13_800 -# Current plan p6 checkbox selections: TANF/general assistance/child support excluded, alimony included. SNAP is noncash excluded income. -- name: Case 8, TANF general assistance and child support are excluded while alimony counts. +# 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: @@ -240,7 +247,7 @@ members: [person1, person2] state_code: OH output: - oh_liheap_countable_income: 13_200 + oh_liheap_countable_income: 14_400 # Current FY2026 application physical p7 and manual physical 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. @@ -324,3 +331,143 @@ 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + output: + oh_liheap_countable_income: 12_600 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 index 0a099c90005..8baadbc6184 100644 --- 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 @@ -1,7 +1,9 @@ -# Final 2023 workbook: page 1 factors, page 8 counties, pages 9-11 formula/tables. -# Payments after 2023 carry historical values forward. Above 150% FPG is a user-approved -# extrapolation; 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. +# Final 2021 workbook (also used for 2022) and final 2023 workbook: page 1 factors, +# page 8 counties, pages 9-11 formula/tables. 2024 and 2025 use the draft workbook +# coefficients; the 2025 values carry forward to 2026-2027. Above 150% FPG is a +# user-approved extrapolation; 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: @@ -186,6 +188,9 @@ heating_expense: [1, 1, 1, 1, 1] output: oh_liheap: [665, 665, 664, 599, 532] +# 2025 draft values carried to 2026: 251.75 - 0.285 x poverty percent, 2025 FPG 15,650. +# 150% -> 209; 150.00006% -> 208.99998 -> 209; 162.5% -> 205.44 -> 205; +# 174.997% -> 201.88 -> 202; 27,388 is above the 27,387 limit -> 0. - name: Case 5, the approved extrapolation covers income above 150 percent while ordinary eligibility still applies. period: 2026 @@ -201,7 +206,8 @@ heating_expense: [1, 1, 1, 1, 1] output: oh_liheap_eligible: [true, true, true, true, false] - oh_liheap: [532, 532, 515, 499, 0] + oh_liheap: [209, 209, 205, 202, 0] +# 15,650 / 2025 FPG 15,650 = 100%: 251.75 - 28.5 = 223.25 -> 223. - name: Case 6, the 2026 estimate carries payment values forward but updates the lagged poverty guideline. period: 2026 input: @@ -215,7 +221,8 @@ heating_type: [PROPANE] heating_expense: [1] output: - oh_liheap: [599] + oh_liheap: [223] +# 15,960 / 2026 FPG 15,960 = 100%: 251.75 - 28.5 = 223.25 -> 223. - name: Case 7, the 2027 estimate carries payment values forward but updates the lagged poverty guideline. period: 2027 input: @@ -229,13 +236,16 @@ heating_type: [PROPANE] heating_expense: [1] output: - oh_liheap: [599] + oh_liheap: [223] +# $0 income uses the 50% floor: 251.75 - 14.25 = 237.5. Fuel oil in northern Ashtabula +# (avoids the exact 237.5 central tie): 237.5 x 1.06 = 251.75 -> 252. Subsidized gas +# tenant with an electric bill: 237.5 x 0.724 = 171.95 -> 172. - 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: [FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_OH, FRANKLIN_COUNTY_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] @@ -248,7 +258,7 @@ is_in_public_housing: [false, false, false, false, false] electricity_expense: [0, 1200, 0, 0, 0] output: - oh_liheap: [665, 367, 0, 0, 0] + oh_liheap: [252, 172, 0, 0, 0] - name: Case 9, unpriced fuels and unknown or foreign counties have unsupported zero estimates. period: 2026 input: @@ -293,3 +303,267 @@ 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 follow the 2024 draft workbook coefficients. + 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 follow the 2025 draft workbook coefficients. + 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%: (251.75 - 46.56) x 1.75 = 359.09 -> 359. 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: [359, 0] + +# With no county or county_fips input, county falls back to the state's alphabetically +# first county, Adams (southern, -6%): propane 237.5 x 0.94 = 223.25 -> 223; gas +# 237.5 x 0.724 x 0.94 = 161.63 -> 162. 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: [223, 162] + +# 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%; +# 251.75 - 40.43 = 211.32 -> 211 (SPM size 3 would give 220; size 1, 197). 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: 211 + +# Row 1: a business loss floors to 0, so the 50% floor applies: 237.5 x 0.724 = 171.95 +# -> 172. Row 2: wages 15,650 with rental and capital losses still count 15,650 (100%): +# 223.25 x 0.724 = 161.63 -> 162; letting the losses offset would give 172. +- 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: [172, 162] 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 index f9c1c3160d9..0c3b55c2813 100644 --- 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 @@ -1,6 +1,5 @@ from policyengine_us.model_api import * from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg -from policyengine_us.variables.gov.hhs.hhs_smi import smi class oh_liheap_income_limit(Variable): @@ -11,8 +10,14 @@ class oh_liheap_income_limit(Variable): 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 (page 5; footnotes page 6). + "https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM%202024-02_Att4SMITable.pdf#page=5", + "https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_SMIStateTable_Att4.pdf#page=5", ) def formula(spm_unit, period, parameters): @@ -27,15 +32,29 @@ def formula(spm_unit, period, parameters): parameters, year_lag=p.fpg_year_lag, ) - # Flooring reproduces the printed FPG amounts: sizes 1-8 for the - # 2025-26 application and 1-7 for 2026-27. Larger units use 60% SMI. - # The 2026-27 Consumers' Counsel fact sheet's larger-household dollar - # figures do not reconcile to the current federal SMI. Use the state - # application's express percentage; whole-dollar flooring remains an - # annual approximation, not a verified large-household dollar table. - limit = where( - size <= p.maximum_fpg_household_size, - guideline * p.fpg_rate, - smi(size, state, period, parameters) * p.smi_rate, + # 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") + federal = parameters(smi_date).gov.hhs.smi + # HHS truncates 60% of the four-person median, then the size-adjusted + # amount, in its footnote's order. This 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. + four_person_limit = np.floor(federal.amount[state] * p.smi_rate) + adjustment = federal.household_size_adjustment + threshold = federal.additional_person_threshold + size_share = ( + adjustment.first_person + + adjustment.second_to_sixth_person * clip(size - 1, 0, threshold - 1) + + adjustment.additional_person * max_(size - threshold, 0) ) - return where(size > 0, np.floor(limit), 0) + smi_limit = np.floor(four_person_limit * size_share) + 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 index 2a5ac714aa1..1f9a69a4f65 100644 --- 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 @@ -20,27 +20,37 @@ class oh_liheap_countable_income(Variable): def formula(spm_unit, period, parameters): p = parameters(period).gov.states.oh.odjfs.liheap.income person = spm_unit.members - dependent_minor = (person("age", period) < p.earned_income_min_age) & person( + # Tax-unit dependency approximates the policy's dependent-minor test. + dependent_minor = (person("age", period) < p.adult_age) & person( "is_tax_unit_dependent", period ) - # Tax-unit dependency approximates the policy's dependent-minor test. # Keep the existing net business inputs without another expense - # deduction. Section E-2.3 counts a reported business loss as zero. - earned = 0 - for source in p.sources.earned: - earned = earned + max_(person(source, period), 0) - unearned = 0 - for source in p.sources.unearned: - unearned = unearned + max_(person(source, period, options=[ADD]), 0) - # Minor unearned income, including SSA paid through an adult guardian, - # counts. 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. + # 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. - # Medicare deductions are deferred. Other premium, spenddown, disability - # premium, and legal-fee deductions need source/input reconciliation; - # existing aggregates do not isolate the covered non-Medicare amounts. - income = spm_unit.sum(earned * ~dependent_minor + unearned) - child_support_paid = add(spm_unit, period, ["child_support_expense"]) - return max_(income - child_support_paid, 0) + # Guidelines Appendix XXIII (page 74) and the application (page 7) + # deduct Medicare premiums and child support paid; the FY2026 plan + # (page 6) counts Social Security "Excluding MediCare deduction". + # Only the Medicare Part B premium has an input. Other premium, + # spenddown, disability premium, and legal-fee deductions need + # source/input reconciliation; existing aggregates do not isolate the + # covered non-Medicare amounts. + deductions = add( + spm_unit, period, ["child_support_expense", "medicare_part_b_premium"] + ) + 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 index 66c7a6f5bed..cec57765d3a 100644 --- a/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py @@ -10,8 +10,13 @@ class oh_liheap(Variable): label = "Ohio HEAP regular heating assistance" defined_for = "oh_liheap_eligible" reference = ( + # Final 2021 workbook, physical pages 1, 8, 9 and 11. + "https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1", # Physical pages 1,8-11,15-16,19-20,29: factors, counties and formula. "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", # Sections E-1, E-2, E-2.10 and E-4: income, disability and heating facts. "https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=5", ) @@ -31,12 +36,13 @@ def formula(spm_unit, period, parameters): poverty_percentage = 100 * max_( income / guideline, payment.formula.minimum_poverty_ratio ) - # The final 2023 workbook's filled coefficients are used from 2023, - # carrying forward until an updated final schedule is available. Its - # cover allows 175% FPG but detailed tables end at 150%; extending the - # formula above 150% is an explicitly approved estimate, not a sourced - # payment rule. Annual income approximates the favorable 30-day/12-month - # comparison. Guidelines still follow the requested year and state lag. + # Coefficients follow the final 2021 and 2023 workbooks and the 2024 + # and 2025 draft workbooks; the 2025 values carry into 2026 and later as + # unverified estimates (no 2026 workbook was found). Covers allow + # 175% FPG but detailed tables end at 150%; extending the formula above + # 150% is an explicitly approved estimate, not a sourced payment rule. + # 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, @@ -69,18 +75,24 @@ def formula(spm_unit, period, parameters): [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 = spm_unit.any( - (age >= payment.targeted.elderly_age) - | (age <= payment.targeted.young_child_age) - | spm_unit.members("is_disabled", period) + targeted_member = (age >= targeting.elderly_age) | spm_unit.members( + "is_disabled", period ) - multiplier = where(targeted, payment.targeted.multiplier, 1) + 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. Unknown county or unpriced - # fuel returns an unsupported zero, not a finding of legal ineligibility. - # The published gas ratio has four decimals; some table cells differ by + # 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. 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 2023 gas ratio has four decimals; some 2023 table cells differ by # $1. 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) From 6937a92a3ebe428c6e459c86e1e86f768eb00e9c Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 7 Oct 2026 22:56:55 -0400 Subject: [PATCH 06/10] Fix issues from review: deduct non-Medicare health premiums Deduct health_insurance_premiums_without_medicare_part_b (Guidelines Appendix XXIII) and test each counted unearned source. Co-Authored-By: Claude Opus 5.5 --- .../income/oh_liheap_countable_income.yaml | 95 +++++++++++++++++++ .../income/oh_liheap_countable_income.py | 19 ++-- 2 files changed, 107 insertions(+), 7 deletions(-) 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 index 96c14b5e718..530511b4cf0 100644 --- 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 @@ -471,3 +471,98 @@ state_code: OH output: oh_liheap_countable_income: 12_600 + +# Guidelines Appendix XXIII (pp72-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. +# 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] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_200, 1_200, 1_200, 1_200, 1_200] + output: + oh_liheap_countable_income: [17_160, 23_240, 17_441, 22_724, 20_592] + +# Guidelines Appendix XXIII (p74) and the 2025-2026 application (p7) deduct health, dental +# and vision premiums. Full-time at Ohio's 2026 $11.00 minimum wage: 11 x 2,080 = 22,880. +# KFF 2025 average worker contribution for single coverage is 1,440: +# 22,880 - 1,440 = 21,440. +- name: Case 18, an employee health insurance premium 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 + health_insurance_premiums_without_medicare_part_b: 1_440 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + 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] + heating_type: NATURAL_GAS + gas_expense: 1_200 + households: + household: + members: [person1] + state_code: OH + county: FRANKLIN_COUNTY_OH + output: + oh_liheap_countable_income: 25_097.32 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 index 1f9a69a4f65..63aaa2fbcf1 100644 --- 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 @@ -44,13 +44,18 @@ def formula(spm_unit, period, parameters): # 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 Medicare premiums and child support paid; the FY2026 plan - # (page 6) counts Social Security "Excluding MediCare deduction". - # Only the Medicare Part B premium has an input. Other premium, - # spenddown, disability premium, and legal-fee deductions need - # source/input reconciliation; existing aggregates do not isolate the - # covered non-Medicare amounts. + # deduct child support paid and health, dental, vision, prescription + # plan, and Medicare premiums; the FY2026 plan (page 6) counts Social + # Security "Excluding MediCare deduction". The non-Part-B premium input + # excludes the Part B premium, so no premium is deducted twice. + # Spenddown, disability premium, and legal-fee deductions have no input. deductions = add( - spm_unit, period, ["child_support_expense", "medicare_part_b_premium"] + spm_unit, + period, + [ + "child_support_expense", + "health_insurance_premiums_without_medicare_part_b", + "medicare_part_b_premium", + ], ) return max_(spm_unit.sum(counted) - deductions, 0) From 49ae4ecaeb9de310a0676149e69e0d3bf5e46ce6 Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 7 Oct 2026 23:24:44 -0400 Subject: [PATCH 07/10] Apply the reference page-citation convention One reference entry per source; single-page citations keep the page only in the href; multi-page titles end with a quoted #page list and the href opens the first cited page; variable references use '# PDF pages ...' comments above multi-page hrefs (CLAUDE.md, PolicyEngine/policyengine-us PR 10009). Reference lines only. Co-Authored-By: Claude Opus 5.5 --- .../gov/states/oh/odjfs/liheap/income/sources/earned.yaml | 4 ++-- .../states/oh/odjfs/liheap/income/sources/unearned.yaml | 6 +++--- .../states/oh/odjfs/liheap/payment/formula/intercept.yaml | 8 ++++---- .../liheap/payment/formula/minimum_poverty_ratio.yaml | 6 +++--- .../gov/states/oh/odjfs/liheap/payment/formula/slope.yaml | 8 ++++---- .../odjfs/liheap/payment/fuel_cost_ratio/bulk_fuel.yaml | 6 +++--- .../odjfs/liheap/payment/fuel_cost_ratio/coal_wood.yaml | 8 ++++---- .../liheap/payment/fuel_cost_ratio/gas_electricity.yaml | 8 ++++---- .../oh/odjfs/liheap/payment/regional/adjustment.yaml | 8 ++++---- .../odjfs/liheap/payment/regional/central_counties.yaml | 4 ++-- .../odjfs/liheap/payment/regional/northern_counties.yaml | 4 ++-- .../odjfs/liheap/payment/regional/southern_counties.yaml | 4 ++-- .../oh/odjfs/liheap/payment/targeted/elderly_age.yaml | 8 ++++---- .../oh/odjfs/liheap/payment/targeted/multiplier.yaml | 8 ++++---- .../oh/odjfs/liheap/payment/targeted/young_child_age.yaml | 6 +++--- .../liheap/payment/targeted/young_child_in_effect.yaml | 8 ++++---- .../oh/odjfs/liheap/eligibility/oh_liheap_income_limit.py | 4 +++- .../oh/odjfs/liheap/income/oh_liheap_countable_income.py | 8 +++++--- .../variables/gov/states/oh/odjfs/liheap/oh_liheap.py | 6 ++++-- .../states/oh/odjfs/liheap/oh_liheap_household_size.py | 3 ++- 20 files changed, 66 insertions(+), 59 deletions(-) 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 index 45662189144..a6e0b4193d2 100644 --- 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 @@ -12,7 +12,7 @@ metadata: 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, pages 7-8 and 73 + - 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, pages 5-6 + - 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 index 2edad2a768a..2b8a091f617 100644 --- 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 @@ -45,9 +45,9 @@ metadata: 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, pages 7-8 and 73-76" + - 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, pages 5-6 (current income inclusions and exclusions) + - 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, physical page 7 (VA disabilities excluded) + - 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 index 45132179450..5be781bc190 100644 --- 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 @@ -20,13 +20,13 @@ metadata: period: year label: Ohio HEAP payment intercept reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 11" + - 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, #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, #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, #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 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 index f8529c0ee91..ccca3ed7fb6 100644 --- 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 @@ -6,9 +6,9 @@ metadata: period: year label: Ohio HEAP minimum poverty ratio for payments reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 1" + - 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, #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, #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 index cc77cf69236..133cc6dfe55 100644 --- 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 @@ -14,11 +14,11 @@ metadata: period: year label: Ohio HEAP payment reduction per poverty percentage point reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 11" + - 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, #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, #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, #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/bulk_fuel.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/bulk_fuel.yaml index 73562ee146c..1cd865b0eaf 100644 --- 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 @@ -9,9 +9,9 @@ metadata: period: year label: Ohio HEAP propane oil and kerosene fuel cost ratio reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 9" + - 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, #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, #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/coal_wood.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/coal_wood.yaml index c048975e264..13b993ddd5d 100644 --- 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 @@ -9,11 +9,11 @@ metadata: period: year label: Ohio HEAP coal and wood fuel cost ratio reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 9" + - 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, #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, #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, #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 index 2ab1ef1f81d..913903f3568 100644 --- 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 @@ -14,11 +14,11 @@ metadata: period: year label: Ohio HEAP gas and electricity fuel cost ratio reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 9" + - 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, #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, #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, #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 index 57395e58e73..a32142d1868 100644 --- 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 @@ -6,11 +6,11 @@ metadata: period: year label: Ohio HEAP regional payment adjustment reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 1" + - 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, #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, #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, #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 index e303c433a84..eac79d0d4b5 100644 --- 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 @@ -60,7 +60,7 @@ metadata: period: year label: Ohio HEAP central counties reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 8" + - 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, #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 index c0800985d17..9011dcd8b17 100644 --- 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 @@ -31,7 +31,7 @@ metadata: period: year label: Ohio HEAP northern counties reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 8" + - 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, #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 index 3b93a2b0046..dbe886e85af 100644 --- 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 @@ -18,7 +18,7 @@ metadata: period: year label: Ohio HEAP southern counties reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 8" + - 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, #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 index fcd78dc1cb7..e172bbfbb0c 100644 --- 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 @@ -6,11 +6,11 @@ metadata: period: year label: Ohio HEAP targeted household elderly minimum age reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 1" + - 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, #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, #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, #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 index 9ab0b501903..aa73f08f70f 100644 --- 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 @@ -7,11 +7,11 @@ metadata: period: year label: Ohio HEAP targeted household payment multiplier reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 1" + - 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, #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, #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, #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 index 54be63dccac..9292006374d 100644 --- 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 @@ -6,9 +6,9 @@ metadata: period: year label: Ohio HEAP targeted household young child maximum age reference: - - title: "Ohio 2023 FINAL LIHEAP Benefit Matrix, #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, #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, #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 index dbda4f1332b..f35a03f474c 100644 --- 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 @@ -9,11 +9,11 @@ metadata: period: year label: Ohio HEAP young child targeting in effect reference: - - title: "Ohio 2021 FINAL HEAP Benefit Matrix, #page 1" + - 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, #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, #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, #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/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 index 0c3b55c2813..955b661cce6 100644 --- 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 @@ -15,8 +15,10 @@ class oh_liheap_income_limit(Variable): "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 (page 5; footnotes page 6). + # 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", ) 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 index 63aaa2fbcf1..b26c258391a 100644 --- 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 @@ -9,11 +9,13 @@ class oh_liheap_countable_income(Variable): label = "Ohio HEAP annual countable household income" defined_for = StateCode.OH reference = ( - # Sections E-2.2-2.3 and Appendix XXIII, pages 7-8 and 73-74. + # Sections E-2.2-2.3 and Appendix XXIII. + # PDF pages 7-8, 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, pages 5-6. + # 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, page 7. + # 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", ) 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 index cec57765d3a..6b1d97543fe 100644 --- a/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py @@ -10,9 +10,11 @@ class oh_liheap(Variable): label = "Ohio HEAP regular heating assistance" defined_for = "oh_liheap_eligible" reference = ( - # Final 2021 workbook, physical pages 1, 8, 9 and 11. + # Final 2021 workbook. + # PDF pages 1, 8-9, 11 "https://liheapch.acf.gov/sites/default/files/webfiles/docs/OH_BenefitMatrix_2022.pdf#page=1", - # Physical pages 1,8-11,15-16,19-20,29: factors, counties and formula. + # 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", 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 index 4ab33fbd7df..ba6024c8db1 100644 --- 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 @@ -7,7 +7,8 @@ class oh_liheap_household_size(Variable): definition_period = YEAR label = "Ohio HEAP household size" defined_for = StateCode.OH - # Sections E-2.1 and E-2.6, physical pages 7 and 10. + # Sections E-2.1 and E-2.6. + # 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. From 10c6487c5a32b9fab5539f1f3a70ff0ee8fb8227 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 8 Oct 2026 00:37:47 -0400 Subject: [PATCH 08/10] Fix Ohio HEAP terminal payment row and document coverage gaps --- changelog.d/oh-liheap.added.md | 2 +- .../liheap/payment/formula/intercept.yaml | 22 ++++--- .../formula/maximum_poverty_ratio.yaml | 14 ++++ .../odjfs/liheap/payment/formula/slope.yaml | 9 +-- policyengine_us/programs.yaml | 3 +- .../gov/states/oh/odjfs/liheap/oh_liheap.yaml | 65 +++++++++++++++---- .../gov/states/oh/odjfs/liheap/oh_liheap.py | 17 +++-- 7 files changed, 94 insertions(+), 38 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/maximum_poverty_ratio.yaml diff --git a/changelog.d/oh-liheap.added.md b/changelog.d/oh-liheap.added.md index e9709aa9e46..e7f8a80a878 100644 --- a/changelog.d/oh-liheap.added.md +++ b/changelog.d/oh-liheap.added.md @@ -1 +1 @@ -Add Ohio HEAP household, income, eligibility, and regular heating payments from the 2021, 2023, 2024 and 2025 benefit workbooks. +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/states/oh/odjfs/liheap/payment/formula/intercept.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/intercept.yaml index 5be781bc190..e6375671484 100644 --- 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 @@ -1,15 +1,15 @@ description: Ohio starts the payment formula with this intercept under the Home Energy Assistance Program. # The 2021 values carry through 2022; no final 2022 workbook was found. -# The 2024 and 2025 draft workbooks print only their maximum and minimum -# credit percentages (46%/38% and 25%/22%). Applying the 2023 workbook's -# page 11 method with its $950 high winter cost gives 0.50 x 950 = 475 and -# 0.265 x 950 = 251.75. These reproduce the printed credit percentages and -# every printed fuel maximum, including the $811 and $441 maximums in the -# FY2025 and FY2026 plans. The printed minimum dollar amounts ($41 and $24) -# include a further factor of about 0.2 that the model does not apply. -# The 2025 draft values carry into 2026 and later. The FY2027 draft plan's -# section 2.6 reports the unpublished 2026 matrix at a $31 minimum and $546 -# maximum, so 2026 and later payments are unverified estimates. +# 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 2025 estimates carry into 2026 and later. The FY2027 draft plan's +# section 2.6 describes an unpublished 2026 matrix with a $31 minimum and +# $546 maximum; no current formula or complete payment table was found. values: 2021-01-01: 593.2133 2023-01-01: 731.5 @@ -20,6 +20,8 @@ metadata: 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 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/slope.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/slope.yaml index 133cc6dfe55..630a2946591 100644 --- 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 @@ -1,9 +1,10 @@ description: Ohio reduces the payment formula by this amount per federal poverty percentage point under the Home Energy Assistance Program. # The 2021 values carry through 2022; no final 2022 workbook was found. -# For the 2024 and 2025 draft workbooks, (46% - 38%) / 100 x $950 = 0.76 and -# (25% - 22%) / 100 x $950 = 0.285, using the 2023 workbook's page 11 method -# and high winter cost. The 2025 draft value carries into 2026 and later, -# which are unverified estimates. +# 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. The 2025 +# estimate carries into 2026 and later without extending verified coverage. values: 2021-01-01: 0.9813 2023-01-01: 1.33 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index f7fc1dad59f..0413cf67560 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -816,8 +816,7 @@ programs: full_name: Ohio Low Income Home Energy Assistance Program variable: oh_liheap parameter_prefix: gov.states.oh.odjfs.liheap - verified_years: "2025" - notes: FY2025 regular heating only, from the 2024-25 application and the 2025 benefit workbook. Crisis, cooling and weatherization assistance are out of scope. + notes: Regular heating only. Final 2021 and 2023 non-PIPP formula components and published payment rows are tested; some printed gas awards differ by $1. The 2024-2025 coefficients are estimates from workbook covers, and 2026 onward carries those estimates forward. No full benefit year is verified. PIPP reductions and the favorable 30-day income election remain unmodeled. Crisis, cooling and weatherization assistance are out of scope. - state: DC status: complete name: DC LIHEAP 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 index 8baadbc6184..a5200b255e3 100644 --- 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 @@ -1,7 +1,7 @@ # Final 2021 workbook (also used for 2022) and final 2023 workbook: page 1 factors, -# page 8 counties, pages 9-11 formula/tables. 2024 and 2025 use the draft workbook -# coefficients; the 2025 values carry forward to 2026-2027. Above 150% FPG is a -# user-approved extrapolation; PIPP enrollment/reduction remains unmodeled. Every case +# page 8 counties, pages 9-11 formula/tables, pages 16 and 20 terminal 150+ rows. +# 2024-2025 use coefficients estimated from draft covers; these are carried +# forward to 2026-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. @@ -189,10 +189,9 @@ output: oh_liheap: [665, 665, 664, 599, 532] # 2025 draft values carried to 2026: 251.75 - 0.285 x poverty percent, 2025 FPG 15,650. -# 150% -> 209; 150.00006% -> 208.99998 -> 209; 162.5% -> 205.44 -> 205; -# 174.997% -> 201.88 -> 202; 27,388 is above the 27,387 limit -> 0. -- name: Case 5, the approved extrapolation covers income above 150 percent while ordinary eligibility - still applies. +# The historical 150+ payment cap also carries forward: eligible income at or +# above 150% gives 209; 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] @@ -206,7 +205,7 @@ heating_expense: [1, 1, 1, 1, 1] output: oh_liheap_eligible: [true, true, true, true, false] - oh_liheap: [209, 209, 205, 202, 0] + oh_liheap: [209, 209, 209, 209, 0] # 15,650 / 2025 FPG 15,650 = 100%: 251.75 - 28.5 = 223.25 -> 223. - name: Case 6, the 2026 estimate carries payment values forward but updates the lagged poverty guideline. period: 2026 @@ -413,7 +412,7 @@ # 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 follow the 2024 draft workbook coefficients. +- 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] @@ -434,7 +433,7 @@ # $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 follow the 2025 draft workbook coefficients. +- 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] @@ -452,8 +451,8 @@ # 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%: (251.75 - 46.56) x 1.75 = 359.09 -> 359. Without a premium, 28,000 is over -# the limit and the payment is 0. +# = 163.36%, capped at 150% for the estimated payment: 209 x 1.75 = 365.75 -> 366. +# 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: @@ -470,7 +469,7 @@ heating_expense: [1_200, 1_200] output: oh_liheap_eligible: [true, false] - oh_liheap: [359, 0] + oh_liheap: [366, 0] # With no county or county_fips input, county falls back to the state's alphabetically # first county, Adams (southern, -6%): propane 237.5 x 0.94 = 223.25 -> 223; gas @@ -508,7 +507,7 @@ # 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%; -# 251.75 - 40.43 = 211.32 -> 211 (SPM size 3 would give 220; size 1, 197). Not targeted. +# 251.75 - 40.43 = 211.32 -> 211 (SPM size 3 would give 220; size 1, 209). Not targeted. - name: Case 21, a mixed status family payment uses qualified household size with counted income. period: 2026 input: @@ -567,3 +566,41 @@ heating_expense: [1_200, 1_200] output: oh_liheap: [172, 162] + +# 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] 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 index 6b1d97543fe..a03bf0f2b44 100644 --- a/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py @@ -19,6 +19,8 @@ class oh_liheap(Variable): # 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", # Sections E-1, E-2, E-2.10 and E-4: income, disability and heating facts. "https://irp.cdn-website.com/aa88b0b1/files/uploaded/2022-24%20ATTACHMENT%202022-2023%20EAP%20Guidelines%20%281%29.pdf#page=5", ) @@ -35,14 +37,15 @@ def formula(spm_unit, period, parameters): year_lag=p.eligibility.fpg_year_lag, ) income = spm_unit("oh_liheap_countable_income", period) - poverty_percentage = 100 * max_( - income / guideline, payment.formula.minimum_poverty_ratio + poverty_percentage = 100 * np.clip( + income / guideline, + payment.formula.minimum_poverty_ratio, + payment.formula.maximum_poverty_ratio, ) - # Coefficients follow the final 2021 and 2023 workbooks and the 2024 - # and 2025 draft workbooks; the 2025 values carry into 2026 and later as - # unverified estimates (no 2026 workbook was found). Covers allow - # 175% FPG but detailed tables end at 150%; extending the formula above - # 150% is an explicitly approved estimate, not a sourced payment rule. + # 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 reconstructed from cover figures; + # the 2025 estimates carry into 2026 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_( From 21bc12d41471fa97f2607b68b135065831028e13 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sun, 11 Oct 2026 23:45:53 -0400 Subject: [PATCH 09/10] Use the shared SMI helper for the Ohio LIHEAP income limit Calls liheap_smi_limit from PR 10019 instead of repeating the HHS floor-then-floor calculation. Limits are unchanged. Co-Authored-By: Claude Opus 5.5 --- .../eligibility/oh_liheap_income_limit.py | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) 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 index 955b661cce6..51602dd435c 100644 --- 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 @@ -1,4 +1,5 @@ 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 @@ -43,20 +44,10 @@ def formula(spm_unit, period, parameters): # 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") - federal = parameters(smi_date).gov.hhs.smi - # HHS truncates 60% of the four-person median, then the size-adjusted - # amount, in its footnote's order. This 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. - four_person_limit = np.floor(federal.amount[state] * p.smi_rate) - adjustment = federal.household_size_adjustment - threshold = federal.additional_person_threshold - size_share = ( - adjustment.first_person - + adjustment.second_to_sixth_person * clip(size - 1, 0, threshold - 1) - + adjustment.additional_person * max_(size - threshold, 0) - ) - smi_limit = np.floor(four_person_limit * size_share) + # 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) From a2cb1869c5fa5a4f6b6c7db2fe1d0e7ea85fda00 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 15 Oct 2026 16:11:39 -0400 Subject: [PATCH 10/10] Address review round 1 on Ohio LIHEAP - S1: Unearned source list reads raw unemployment_compensation; main's #9558 guard fails - S2: Premium deduction misses payroll (pretax) premiums (main #10046) - S3: 2026 and 2027 pay the 2025 coefficients ($441 maximum) although the FY2026 matrix pays $31-$546 - S4: Size gate and NONE check are untested - S5: Twelve parameter descriptions use off-template verbs - S6: Wrong section label, two incomplete page lists, heat-in-rent branch lacks its E-4 citation - REC-C: Coordinator recommendation C: federal 110% poverty floor (applies to Ohio from size 17) Also applies the in-scope suggestions. Tests not run locally; CI validates. Co-Authored-By: Claude Opus 5.5 --- .../parameters/gov/hhs/liheap/fpg_floor.yaml | 11 +++ .../oh/odjfs/liheap/eligibility/fpg_rate.yaml | 2 + .../maximum_fpg_household_size.yaml | 9 +- .../oh/odjfs/liheap/income/adult_age.yaml | 2 +- .../oh/odjfs/liheap/income/deductions.yaml | 20 +++++ .../odjfs/liheap/income/sources/earned.yaml | 2 +- .../odjfs/liheap/income/sources/unearned.yaml | 6 +- .../liheap/payment/formula/intercept.yaml | 16 ++-- .../odjfs/liheap/payment/formula/slope.yaml | 11 ++- .../fuel_cost_ratio/gas_electricity.yaml | 13 +-- .../liheap/payment/regional/adjustment.yaml | 2 +- .../payment/regional/central_counties.yaml | 2 +- .../payment/regional/northern_counties.yaml | 2 +- .../payment/regional/southern_counties.yaml | 2 +- .../liheap/payment/targeted/elderly_age.yaml | 2 +- .../liheap/payment/targeted/multiplier.yaml | 2 +- .../payment/targeted/young_child_age.yaml | 2 +- policyengine_us/programs.yaml | 6 +- .../eligibility/oh_liheap_eligible.yaml | 16 ++-- .../eligibility/oh_liheap_income_limit.yaml | 28 ++---- .../income/oh_liheap_countable_income.yaml | 58 ++++-------- .../gov/states/oh/odjfs/liheap/oh_liheap.yaml | 89 +++++++++++++------ .../liheap/oh_liheap_household_size.yaml | 13 +-- .../liheap/eligibility/oh_liheap_eligible.py | 32 +++++-- .../income/oh_liheap_countable_income.py | 23 ++--- .../gov/states/oh/odjfs/liheap/oh_liheap.py | 28 +++--- .../odjfs/liheap/oh_liheap_household_size.py | 2 +- 27 files changed, 234 insertions(+), 167 deletions(-) create mode 100644 policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml create mode 100644 policyengine_us/parameters/gov/states/oh/odjfs/liheap/income/deductions.yaml 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 index 9a304d84227..05830cbae46 100644 --- 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 @@ -8,6 +8,8 @@ metadata: 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 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 index ffe18a9e028..3bd40cc76e2 100644 --- 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 @@ -1,9 +1,10 @@ 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. -# No 2023-2024 rule was found, so that season keeps the 2022-2023 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. +# 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 @@ -18,6 +19,8 @@ metadata: 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 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 index f3ca8da0d22..c1d98ab3320 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio counts the income of household members at least this age under the Home Energy Assistance Program. +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: 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 index a6e0b4193d2..1a12069b520 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio counts these earned income sources, except for dependent minors, under the Home Energy Assistance Program. +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: 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 index 2b8a091f617..f99e515d438 100644 --- 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 @@ -1,7 +1,7 @@ -description: Ohio counts these unearned income sources, except for dependent minors, under the Home Energy Assistance Program. +description: Ohio uses these sources as unearned income under the Home Energy Assistance Program. values: 2025-07-01: - - unemployment_compensation + - 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). @@ -36,7 +36,7 @@ values: - capital_gains - gambling_winnings # Retirement account withdrawals are distinct from pension income in the model. -# The manual explicitly counts capital gains and estate/trust settlements, not +# 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). 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 index e6375671484..b5652281808 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio starts the payment formula with this intercept under the Home Energy Assistance Program. +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 @@ -7,14 +7,20 @@ description: Ohio starts the payment formula with this intercept under the Home # 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 2025 estimates carry into 2026 and later. The FY2027 draft plan's -# section 2.6 describes an unpublished 2026 matrix with a $31 minimum and -# $546 maximum; no current formula or complete payment table was found. +# 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 @@ -34,5 +40,5 @@ metadata: 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 LIHEAP State Plan draft, section 2.6 + - 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/slope.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/formula/slope.yaml index 630a2946591..5135872d2c7 100644 --- 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 @@ -1,15 +1,18 @@ -description: Ohio reduces the payment formula by this amount per federal poverty percentage point under the Home Energy Assistance Program. +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. The 2025 -# estimate carries into 2026 and later without extending verified coverage. +# 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 @@ -23,3 +26,5 @@ metadata: 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/gas_electricity.yaml b/policyengine_us/parameters/gov/states/oh/odjfs/liheap/payment/fuel_cost_ratio/gas_electricity.yaml index 913903f3568..0602b9cc9a4 100644 --- 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 @@ -1,10 +1,11 @@ description: Ohio uses this fuel cost ratio for natural gas and electricity under the Home Energy Assistance Program. -# Uses the published four-decimal ratios. Some printed 2023 gas/electric -# dollar cells differ by $1 from this formula; 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. +# 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 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 index a32142d1868..1d471abde01 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio adjusts payments up or down by this share for designated northern and southern counties under the Home Energy Assistance Program. +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: 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 index eac79d0d4b5..a4830b8fad5 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio does not regionally adjust payments for these counties under the Home Energy Assistance Program. +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: 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 index 9011dcd8b17..36fe9c4795f 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio increases payments for these counties under the Home Energy Assistance Program. +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: 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 index dbe886e85af..a64a0cd5f0f 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio decreases payments for these counties under the Home Energy Assistance Program. +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: 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 index e172bbfbb0c..fa9d15859ae 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio increases payments for households with a member at least this age under the Home Energy Assistance Program. +description: Ohio sets this minimum age for a targeted-household member under the Home Energy Assistance Program. values: 2021-01-01: 60 metadata: 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 index aa73f08f70f..d5c36be8f1f 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio multiplies payments by this factor for targeted households under the Home Energy Assistance Program. +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 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 index 9292006374d..2a7bb7622c3 100644 --- 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 @@ -1,4 +1,4 @@ -description: Ohio increases payments for households with a child no older than this age under the Home Energy Assistance Program. +description: Ohio sets this maximum child age for a targeted household under the Home Energy Assistance Program. values: 2023-01-01: 5 metadata: diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index d541516e537..a168932c310 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -812,11 +812,11 @@ programs: state_implementations: - state: OH status: partial - name: Ohio LIHEAP - full_name: Ohio Low Income Home Energy Assistance Program + name: Ohio HEAP + full_name: Ohio Home Energy Assistance Program variable: oh_liheap parameter_prefix: gov.states.oh.odjfs.liheap - notes: Regular heating only. Final 2021 and 2023 non-PIPP formula components and published payment rows are tested; some printed gas awards differ by $1. The 2024-2025 coefficients are estimates from workbook covers, and 2026 onward carries those estimates forward. No full benefit year is verified. PIPP reductions and the favorable 30-day income election remain unmodeled. Crisis, cooling and weatherization assistance are out of scope. + 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 index 255d49ceef5..6b6b39ea3fc 100644 --- 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 @@ -1,6 +1,7 @@ # Ohio income and eligibility components only; no payment schedule or final award is asserted. -# Application p1 limit27387 is inclusive; current plan/manual has no asset test. +# 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: @@ -24,7 +25,8 @@ output: oh_liheap_eligible: true -# One dollar above27387fails even with categorical-benefit receipts; current plan categoricalNo. +# 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: @@ -95,7 +97,8 @@ output: oh_liheap_eligible: false -# Application p1 energy household includes undesignated heating in rent; flag represents verified arrangement in the contract. +# 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: @@ -144,7 +147,7 @@ output: oh_liheap_eligible: false -# Positive primary gas bill is the approved proxy for the tenant own portion; no guessed benefit amount. +# 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: @@ -194,7 +197,7 @@ output: oh_liheap_eligible: false -# Manual p10 requires an eligible citizen/qualified member; size0must not pass a safe fallback limit. +# 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: @@ -217,7 +220,8 @@ output: oh_liheap_eligible: false -# Manual pp7,10: parent excluded from size, not income. Full28000 exceeds size1limit27387; headcount proration would incorrectly approve. +# 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: 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 index 8b3a38dd7a3..9ac82473276 100644 --- 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 @@ -1,14 +1,12 @@ # Ohio income and eligibility components only; no payment schedule or final award is asserted. -# 2025–2026 application p1 literal HEAP limits; whole-dollar175%of2025FPG, not the adjacent200%HWAP column. +# 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] - heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, - NATURAL_GAS] - gas_expense: [1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200] 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] @@ -23,8 +21,6 @@ absolute_error_margin: 0.01 input: state_code: [OH, OH, OH, OH] - heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] - gas_expense: [1_200, 1_200, 1_200, 1_200] oh_liheap_household_size: [1, 7, 8, 9] output: oh_liheap_income_limit: [26_355, 82_845, 90_515, 92_483] @@ -35,20 +31,16 @@ absolute_error_margin: 0.01 input: state_code: OH - heating_type: NATURAL_GAS - gas_expense: 1_200 oh_liheap_household_size: 0 output: oh_liheap_income_limit: 0 -# JFS00330 (07/2026), physical p1: seven literal annual HEAP limits for July2026-May2027. +# 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] - heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] - gas_expense: [1_200, 1_200, 1_200, 1_200, 1_200, 1_200, 1_200] 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] @@ -64,8 +56,6 @@ absolute_error_margin: 0.01 input: state_code: [OH, OH, OH, OH, OH] - heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] - gas_expense: [1_200, 1_200, 1_200, 1_200, 1_200] oh_liheap_household_size: [8, 9, 10, 11, 12] output: oh_liheap_income_limit: [94_881, 96_944, 99_007, 101_069, 103_132] @@ -78,22 +68,18 @@ absolute_error_margin: 0.01 input: state_code: [OH, OH, OH, OH] - heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] - gas_expense: [1_200, 1_200, 1_200, 1_200] oh_liheap_household_size: [1, 8, 9, 10] output: oh_liheap_income_limit: [23_782, 81_602, 89_862, 98_122] -# No 2023-2024 rule was found, so model year 2024 keeps the all-sizes rule with the 2023 -# FPG: 14,580 x 1.75 = 25,515; (14,580 + 7 x 5,140) x 1.75 = 88,480; -# (14,580 + 8 x 5,140) x 1.75 = 97,475. +# 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] - heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] - gas_expense: [1_200, 1_200, 1_200] oh_liheap_household_size: [1, 8, 9] output: oh_liheap_income_limit: [25_515, 88_480, 97_475] @@ -106,8 +92,6 @@ absolute_error_margin: 0.01 input: state_code: [OH, OH] - heating_type: [NATURAL_GAS, NATURAL_GAS] - gas_expense: [1_200, 1_200] 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 index 530511b4cf0..ae91c00f5a8 100644 --- 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 @@ -1,6 +1,7 @@ # Ohio income and eligibility components only; no payment schedule or final award is asserted. -# Manual p8:12000+6000+600+1200+1200=21000; existing net-business inputs need no added work-expense calculation. +# 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 @@ -19,8 +20,6 @@ spm_units: spm_unit: members: [person1] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1] @@ -28,7 +27,8 @@ output: oh_liheap_countable_income: 21_000 -# Current plan p6 and manual pp73–74:2400rent+1200farmrent+600survivor+1200pension+2400SSA+1200SSI=9000. +# 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 @@ -47,8 +47,6 @@ spm_units: spm_unit: members: [person1] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1] @@ -56,7 +54,7 @@ output: oh_liheap_countable_income: 9_000 -# Manual p74 explicitly lists IRA withdrawals, estate/trust settlements, lottery, interest, dividends and capital gain; current plan includes lump sums. Existing source inputs are disjoint. +# 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 @@ -76,8 +74,6 @@ spm_units: spm_unit: members: [person1] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1] @@ -110,8 +106,6 @@ spm_units: spm_unit: members: [person1, person2] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1, person2] @@ -143,8 +137,6 @@ spm_units: spm_unit: members: [person1, person2] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1, person2] @@ -176,8 +168,6 @@ spm_units: spm_unit: members: [person1, person2] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1, person2] @@ -185,7 +175,8 @@ output: oh_liheap_countable_income: 22_800 -# Manual p8 directs reported business losses to0:12000wages+600positive business+1200SSI=13800; losses do not offset other sources. +# 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 @@ -203,8 +194,6 @@ spm_units: spm_unit: members: [person1] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1] @@ -238,8 +227,6 @@ spm_units: spm_unit: members: [person1, person2] - heating_type: NATURAL_GAS - gas_expense: 1_200 tanf: 3_600 snap: 6_000 households: @@ -249,7 +236,7 @@ output: oh_liheap_countable_income: 14_400 -# Current FY2026 application physical p7 and manual physical p74 deduct child support paid. 30,000 - 3,600 = 26,400, below the one-person ceiling of 27,387. +# 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: @@ -323,8 +310,6 @@ spm_units: spm_unit: members: [person1, person2] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1, person2] @@ -350,8 +335,6 @@ spm_units: spm_unit: members: [person1] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1] @@ -463,8 +446,6 @@ spm_units: spm_unit: members: [person1] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1] @@ -472,12 +453,13 @@ output: oh_liheap_countable_income: 12_600 -# Guidelines Appendix XXIII (pp72-74) counts unemployment, Workers' Compensation, employment +# 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. +# 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 @@ -504,16 +486,14 @@ veterans_benefits: [0, 0, 17_441, 0, 0] workers_compensation: [0, 0, 0, 5_124, 0] disability_benefits: [0, 0, 0, 0, 3_432] - heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] - gas_expense: [1_200, 1_200, 1_200, 1_200, 1_200] output: oh_liheap_countable_income: [17_160, 23_240, 17_441, 22_724, 20_592] -# Guidelines Appendix XXIII (p74) and the 2025-2026 application (p7) deduct health, dental -# and vision premiums. Full-time at Ohio's 2026 $11.00 minimum wage: 11 x 2,080 = 22,880. -# KFF 2025 average worker contribution for single coverage is 1,440: -# 22,880 - 1,440 = 21,440. -- name: Case 18, an employee health insurance premium is deducted from wages. +# 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: @@ -524,12 +504,10 @@ is_tax_unit_dependent: false ssi: 0 employment_income: 22_880 - health_insurance_premiums_without_medicare_part_b: 1_440 + pre_tax_health_insurance_premiums: 1_440 spm_units: spm_unit: members: [person1] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1] @@ -557,8 +535,6 @@ spm_units: spm_unit: members: [person1] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1] 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 index a5200b255e3..9a40f7d25ab 100644 --- 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 @@ -1,8 +1,9 @@ # 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; these are carried -# forward to 2026-2027. PIPP enrollment/reduction remains unmodeled. Every case -# gives heating_type. Case 11 uses the explicit .5523 gas factor: printed amounts are +# 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 @@ -188,9 +189,9 @@ heating_expense: [1, 1, 1, 1, 1] output: oh_liheap: [665, 665, 664, 599, 532] -# 2025 draft values carried to 2026: 251.75 - 0.285 x poverty percent, 2025 FPG 15,650. -# The historical 150+ payment cap also carries forward: eligible income at or -# above 150% gives 209; 27,388 is above the 27,387 income limit and gives 0. +# 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: @@ -205,9 +206,9 @@ heating_expense: [1, 1, 1, 1, 1] output: oh_liheap_eligible: [true, true, true, true, false] - oh_liheap: [209, 209, 209, 209, 0] -# 15,650 / 2025 FPG 15,650 = 100%: 251.75 - 28.5 = 223.25 -> 223. -- name: Case 6, the 2026 estimate carries payment values forward but updates the lagged poverty guideline. + 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] @@ -220,9 +221,10 @@ heating_type: [PROPANE] heating_expense: [1] output: - oh_liheap: [223] -# 15,960 / 2026 FPG 15,960 = 100%: 251.75 - 28.5 = 223.25 -> 223. -- name: Case 7, the 2027 estimate carries payment values forward but updates the lagged poverty guideline. + 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] @@ -235,10 +237,12 @@ heating_type: [PROPANE] heating_expense: [1] output: - oh_liheap: [223] -# $0 income uses the 50% floor: 251.75 - 14.25 = 237.5. Fuel oil in northern Ashtabula -# (avoids the exact 237.5 central tie): 237.5 x 1.06 = 251.75 -> 252. Subsidized gas -# tenant with an electric bill: 237.5 x 0.724 = 171.95 -> 172. + 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 @@ -257,7 +261,10 @@ is_in_public_housing: [false, false, false, false, false] electricity_expense: [0, 1200, 0, 0, 0] output: - oh_liheap: [252, 172, 0, 0, 0] + 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: @@ -272,6 +279,7 @@ 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. @@ -451,7 +459,7 @@ # 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: 209 x 1.75 = 365.75 -> 366. +# = 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 @@ -469,11 +477,11 @@ heating_expense: [1_200, 1_200] output: oh_liheap_eligible: [true, false] - oh_liheap: [366, 0] + 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 237.5 x 0.94 = 223.25 -> 223; gas -# 237.5 x 0.724 x 0.94 = 161.63 -> 162. This documents the fallback; it is not a policy rule. +# 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: @@ -487,7 +495,7 @@ heating_expense: [1_200, 1_200] output: county: [ADAMS_COUNTY_OH, ADAMS_COUNTY_OH] - oh_liheap: [223, 162] + 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. @@ -507,7 +515,7 @@ # 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%; -# 251.75 - 40.43 = 211.32 -> 211 (SPM size 3 would give 220; size 1, 209). Not targeted. +# 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: @@ -544,11 +552,11 @@ oh_liheap_countable_income: 30_000 oh_liheap_income_limit: 37_012 oh_liheap_eligible: true - oh_liheap: 211 + oh_liheap: 273 -# Row 1: a business loss floors to 0, so the 50% floor applies: 237.5 x 0.724 = 171.95 -# -> 172. Row 2: wages 15,650 with rental and capital losses still count 15,650 (100%): -# 223.25 x 0.724 = 161.63 -> 162; letting the losses offset would give 172. +# 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: @@ -565,7 +573,7 @@ heating_type: [NATURAL_GAS, NATURAL_GAS] heating_expense: [1_200, 1_200] output: - oh_liheap: [172, 162] + 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 @@ -604,3 +612,28 @@ 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 index 81230a09127..d6d653cf3ab 100644 --- 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 @@ -1,6 +1,6 @@ -# Ohio income and eligibility components only; no payment schedule or final award is asserted. +# Ohio qualified household size; Case 2 also checks that a unit with no qualified member is ineligible and unpaid. -# Manual pp7,10: count qualified members including minors; no SNAP-specific waiting bar. +# 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 @@ -34,8 +34,6 @@ spm_units: spm_unit: members: [person1, person2, person3, person4, person5] - heating_type: NATURAL_GAS - gas_expense: 1_200 households: household: members: [person1, person2, person3, person4, person5] @@ -43,10 +41,11 @@ output: oh_liheap_household_size: 3 -# Manual p10: nonqualified members are excluded from household membership used for eligibility. +# 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 - absolute_error_margin: 0.01 input: people: person1: @@ -70,3 +69,5 @@ 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 index 098078dd017..ff7faa36467 100644 --- 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 @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg class oh_liheap_eligible(Variable): @@ -10,19 +11,40 @@ class oh_liheap_eligible(Variable): 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. The - # heating plan also permits subsidized heat-in-rent tenants who pay all - # or part of a separate electric bill (Section 2.3). + # 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) @@ -31,6 +53,4 @@ def formula(spm_unit, period, parameters): 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 <= limit) & responsible & (heating_type != fuel.NONE) - ) + return (size > 0) & income_eligible & responsible & (heating_type != fuel.NONE) 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 index b26c258391a..9710297b0a0 100644 --- 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 @@ -9,8 +9,8 @@ class oh_liheap_countable_income(Variable): label = "Ohio HEAP annual countable household income" defined_for = StateCode.OH reference = ( - # Sections E-2.2-2.3 and Appendix XXIII. - # PDF pages 7-8, 73-74 + # 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 @@ -47,17 +47,10 @@ def formula(spm_unit, period, parameters): # 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; the FY2026 plan (page 6) counts Social - # Security "Excluding MediCare deduction". The non-Part-B premium input - # excludes the Part B premium, so no premium is deducted twice. - # Spenddown, disability premium, and legal-fee deductions have no input. - deductions = add( - spm_unit, - period, - [ - "child_support_expense", - "health_insurance_premiums_without_medicare_part_b", - "medicare_part_b_premium", - ], - ) + # 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 index a03bf0f2b44..f02005ea2fe 100644 --- a/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py +++ b/policyengine_us/variables/gov/states/oh/odjfs/liheap/oh_liheap.py @@ -11,7 +11,7 @@ class oh_liheap(Variable): defined_for = "oh_liheap_eligible" reference = ( # Final 2021 workbook. - # PDF pages 1, 8-9, 11 + # 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 @@ -21,7 +21,10 @@ class oh_liheap(Variable): "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", ) @@ -44,8 +47,9 @@ def formula(spm_unit, period, parameters): ) # 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 reconstructed from cover figures; - # the 2025 estimates carry into 2026 and later without verification. + # 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_( @@ -93,11 +97,15 @@ def formula(spm_unit, period, parameters): # 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. 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 2023 gas ratio has four decimals; some 2023 table cells differ by - # $1. Final half-up rounding matches the other printed fuel calculations; - # do not round a component before the regional and targeted adjustments. + # 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 index ba6024c8db1..2ea6788246a 100644 --- 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 @@ -7,7 +7,7 @@ class oh_liheap_household_size(Variable): definition_period = YEAR label = "Ohio HEAP household size" defined_for = StateCode.OH - # Sections E-2.1 and E-2.6. + # 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"