Skip to content

Add Ohio HEAP regular heating assistance - #9975

Open
hua7450 wants to merge 14 commits into
mainfrom
oh-liheap
Open

hua7450 wants to merge 14 commits into
mainfrom
oh-liheap

Conversation

@hua7450

@hua7450 hua7450 commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Adds Ohio's Home Energy Assistance Program (HEAP) regular heating benefit, the state's LIHEAP program. The model counts citizens and qualified noncitizens for household size, counts the income of every member except a dependent minor's income other than Social Security, subtracts child support paid, the Medicare Part B premium and other health insurance premiums, including premiums withheld from pay before tax, and tests annual income against 175% of the prior year's poverty guideline, or 60% of state median income above a household-size cutoff. Under 42 USC 8624(b)(2)(B), it never excludes a household whose income is below 110% of that guideline. It then applies the Ohio benefit workbook formula: an intercept minus a slope per poverty percentage point, times a fuel cost ratio, a 6% regional adjustment and a multiplier for households with an elderly, disabled or young child member. The poverty percentage stops at 150% for the payment, as in the final workbooks' 150+ rows, while eligibility extends to 175%. In 2025, a Franklin County adult who heats with propane and earns $15,060, 100% of the 2024 guideline, receives $223 ($251.75 − $0.285 × 100 = $223.25). A household there with a member 60 or older and no income receives $416 ($237.50 at the 50% floor × 1.75); in northern Ashtabula County, the same household receives $441, the maximum benefit the FY2026 plan reports.

The registry marks Ohio partial. The final 2021 and 2023 payment components and printed rows are tested; the 2024 and 2025 coefficients are estimates from the draft workbook covers, the 2026 coefficients are estimates fitted to the FY2026 matrix range ($31–$546) that the FY2027 draft plan reports, and 2027 carries them forward.

Fixes #9966

Regulatory authority

The clearinghouse file names run one year ahead of the workbook titles; for example, OH_BenefitMatrix_2022.pdf holds the 2021 FINAL workbook.

Eligibility

Requirement Source How modeled
Ohio residence — defined_for = StateCode.OH
Household size counts citizens and qualified noncitizens Guidelines sections E-2.1 and E-2.8, pages 6–7, 10 Counts SPM unit members with is_citizen_or_legal_immigrant, with no SNAP-specific waiting periods or bars. Nonqualified members' income counts in full. A household with no qualified member is ineligible.
Annual income limit Guidelines section E-2.2, page 7; applications, page 1; FY2023, FY2025 and FY2026 plans section 2.1, page 8; Consumers' Counsel fact sheet; 42 USC 8624(b)(2)(B) 175% of the prior year's guideline through a size cutoff, and 60% of state median income (SMI) above it: the FFY2025 SMI in 2025 and the FFY2026 SMI in 2026 and 2027; see Years covered. The guideline limit is floored to the whole dollar, which reproduces every printed limit. The SMI limit calls the shared liheap_smi_limit helper (#10019), which follows the HHS tables' rounding order: 60% of the four-person median is truncated, then the size-adjusted amount. This reproduces every published HHS FFY2025 and FFY2026 amount. Limits are inclusive. One person: $27,387 in 2026. A household with income below 110% of the same lagged guideline is never excluded on income: oh_liheap_eligible applies the shared federal parameter gov.hhs.liheap.fpg_floor (1.1) as an alternative income test, and oh_liheap_income_limit still returns the printed limit. Ohio's 60% SMI limit falls below that floor for 17 or more members in 2025–2027 (2026, size 20: $119,633 against $132,165).
Heating responsibility Guidelines section E-4, page 12; FY2026 plan section 2.3, page 8; 2025–2026 application, page 1 A positive heating bill or heat included in unsubsidized rent qualifies; section E-4 does not require the bill to be in a member's name. A household with housing assistance or in public housing whose rent includes heat needs a positive heating expense or a separate electricity bill. heating_type NONE is ineligible.
No categorical eligibility and no asset test Guidelines section E-2.6, page 9; FY2026 plan question 1.4 (page 5) and section 2.3 (page 8) SNAP, SSI or TANF receipt does not waive the income limit; assets are not tested.

Countable income

Item Source How modeled
Earned income Guidelines sections E-2.2–E-2.3 and Appendix XXIII, pages 7–8, 73; FY2026 plan section 1.9, pages 5–6 Counts wages and net self-employment, SSTB, farm operations and partnership/S-corporation income, each floored at zero, with no further business-expense deduction. Section E-2.3 counts a business loss as zero.
Unearned income Guidelines Appendix XXIII, pages 73–74; FY2026 plan section 1.9, pages 5–6 Counts unemployment (total_unemployment_compensation), strike benefits, SSI, pensions, military retirement pay, railroad retirement, survivor benefits, veterans benefits, workers' compensation, disability benefits, alimony, rental and farm rental income, interest, ordinary dividends, retirement account distributions, estate income, capital gains, gambling winnings and general assistance. Floors each source at zero, so a loss in one source offsets nothing.
Excluded income Guidelines Appendix XXIII, pages 75–76; FY2026 plan section 1.9, page 6 TANF (Ohio Works First), child support received and cash gifts are not counted.
Social Security Guidelines section E-2.2, page 7 Counts every member's Social Security, including a dependent minor's benefit.
Dependent minors Guidelines section E-2.2, page 7 Excludes all other income, including SSI, of members under 18 who are tax dependents. A 17-year-old who is not a dependent counts as an adult.
Deductions Guidelines Appendices XII and XXIII, pages 57, 74; 2025–2026 application, page 7; FY2026 plan section 1.9, page 6 ("Excluding MediCare deduction") Subtracts the list in income/deductions.yaml from household income, floored at zero: child support paid (child_support_expense), medicare_part_b_premium, other health premiums including prescription plans (health_insurance_premiums_without_medicare_part_b), and premiums withheld from pay before tax (pre_tax_health_insurance_premiums; Appendix XII, page 57, shows pre-tax MEDICAL INS and DENTAL INS). The premium inputs are disjoint, so no premium is deducted twice.
Income period Guidelines section E-2.5, page 9 Annual inputs represent the 12-month income option.

Benefit

The payment equals (intercept − slope × poverty percentage) × fuel cost ratio × regional factor × targeted multiplier, rounded half up to the dollar after every factor applies.

  • The poverty percentage divides countable income by the same lagged guideline the limit uses, with a 50% floor and a 150% cap; the base floors at $0.
  • Natural gas and electricity use the gas ratio; propane, fuel oil and kerosene use the bulk ratio; coal and wood use the coal ratio. Solar, other and unspecified fuel stay eligible but pay $0. Heat-in-rent households use their reported primary fuel.
  • The 24 northern counties add 6%, the 11 southern counties subtract 6% and the 53 central counties are unchanged. The 2021 and 2023 final workbooks assign all 88 counties identically.
  • A household with a member 60 or older or with is_disabled, and from 2023 a child 5 or younger, receives the targeted multiplier.
  • The final 2021 and 2023 regional tables (pages 16 and 20) end in a 150+ row, so a household between 150% and the 175% limit receives the 150% award (maximum_poverty_ratio).
  • The reported bill does not cap the award.
Coefficient 2021–2022 2023 2024 (estimated) 2025 (estimated) 2026 onward (estimated)
Intercept 593.2133 731.5 475 251.75 306.375
Slope per poverty percentage point 0.9813 1.33 0.76 0.285 0.2375
Gas and electricity ratio 0.5882 0.5523 0.724 0.724 0.724
Propane, fuel oil and kerosene ratio 0.852 1 1 1 1
Coal and wood ratio 0.5325 0.6 0.6 0.6 0.6
Targeted multiplier 1.5 1.75 1.75 1.75 1.75
Child 5 or younger targeted No Yes Yes Yes Yes
Maximum award (northern, targeted, propane) $737 $1,234 $811 $441 $546

Years covered

Model year Season Income limit One-person limit Payment coefficients
2021 July 2020–May 2021 2022–2023 rule, backfilled — 2021 FINAL workbook
2022 July 2021–May 2022 2022–2023 rule, backfilled — 2021 FINAL workbook, carried through
2023 July 2022–May 2023 175% of the 2022 guideline for every size, adding $8,260 per member above eight $23,782 2023 FINAL workbook
2024 July 2023–May 2024 175% of the 2023 guideline for every size, adding $8,995 per member above eight (July 2023 application) $25,515 2024 DRAFT workbook
2025 July 2024–May 2025 175% of the 2024 guideline through size 7; 60% of FFY2025 SMI above $26,355 2025 DRAFT workbook
2026 July 2025–May 2026 175% of the 2025 guideline through size 8; 60% of FFY2026 SMI above $27,387 2026 estimate fitted to the FY2026 matrix range ($31–$546)
2027 July 2026–May 2027 175% of the 2026 guideline through size 7; 60% of FFY2026 SMI above $27,930 2026 estimate, carried forward (the FY2027 draft plan estimates the same range)

A calendar-year period reads the parameters in force on January 1. Formulas are undated. The registry entry is partial with no verified_years: no full benefit year is verified, although the 2021 and 2023 coefficients reproduce 4,793 of the 4,848 printed non-PIPP cells (the other 55 are $1 off). The income sources and deductions follow the current rules in every year.

  • Payments. With the printed four-decimal slope and fuel ratios, the 2021 and 2023 coefficients reproduce 4,793 of the 4,848 printed non-PIPP cells in Tables 2A–2C; the other 55 (36 in 2021 across every fuel, 19 in 2023 for gas and electricity) are $1 off because the workbooks carry more decimals. No FINAL 2022 workbook was found, so 2022 carries the 2021 values. The 2024 and 2025 DRAFT workbooks print only maximum and minimum credit percentages (46% and 38%; 25% and 22%). The model applies them to the 2023 workbook's $950 high winter cost at 50% and 150% of the guideline, which gives intercepts of $475 and $251.75 and slopes of 0.76 and 0.285. These coefficients reproduce every printed fuel maximum ($587, $811 and $486 in 2024; $319, $441 and $264 in 2025) and the $811 and $441 maximums the FY2025 and FY2026 plans report. Ohio's January 16, 2025 notice (IU-2025-5) confirms the 2025 range of $24–$441 and the prior-year range of $41–$811, but no formula sheet or interior award table verifies the coefficients. The drafts do not print a gas and electricity ratio: any value from 0.7236 to 0.7247 reproduces their gas maximums, and the model uses 0.724. The drafts' printed minimum awards ($41 in 2024 and $24 in 2025, for coal and wood) include the PIPP reduction, which the model does not apply. Every workbook's printed minimum equals 0.19 of the regular central award at 150% of poverty (2021 to the cent: $49.85, $72.20, $45.13), and the 2024 and 2025 coefficients reproduce all six draft minimums under that relation.
  • 2026 and later. Eligibility for 2026 follows the 2025–2026 application. The FY2027 draft plan (items 2.5–2.6, page 9) attaches the FY 2026 Benefit Matrix, which governs model year 2026, with a $31 minimum and a $546 maximum; the matrix itself is not public, and the clearinghouse has not posted FY2027 files. The model fits a labelled 2026 estimate with the 2024–2025 method: 31% and 28.5% of the $950 high winter cost give an intercept of 306.375 and a slope of 0.2375. The maximum fixes the 31% credit (294.50 × 1.855 = 546.30, $546). 28.5% is one of the credits (about 28.2%–29.1%) for which the coal minimum, 0.19 of the regular award at 150%, rounds to $31 (270.75 × 0.6 × 0.19 = 30.87). The draft estimates FY2027 at the same range, so 2027 carries the 2026 values. Recheck liheapch.acf.gov/docs/2027/benefits-matricies/ once ACF posts them.
  • Income limits. The size cutoff for the poverty-guideline limit is dated: every size from July 2022, size 7 from July 2024, size 8 from July 2025 and size 7 from July 2026. The July 2023–May 2024 application prints 175% of the 2023 guideline for sizes 1–8 and adds $8,995 per member above eight, so model year 2024 keeps the all-sizes rule. Ohio does not state which SMI year it uses; the model infers it. 42 USC 8624(b)(2)(B) caps eligibility at the greater of 150% of the poverty guideline and 60% of SMI, so the size at which each application switches from 175% of the guideline to 60% of SMI shows the SMI year. Only the FFY2025 Ohio SMI ($109,319) fits the 2024–2025 switch after size 7, and only the FFY2026 SMI ($114,593) fits the 2025–2026 switch after size 8, so those seasons use the SMI of the federal fiscal year in progress. The Consumers' Counsel 2026–2027 limits for sizes 8, 11 and 12 equal the HHS FFY2026 amounts, so that season uses a one-year lag. Its sizes 9 and 10 ($96,946 and $99,010) exceed even the unrounded 60% of SMI ($96,945.68 and $99,008.35), so no rounding produces them; they look misprinted, and the model uses the HHS amounts ($96,944 and $99,007). Under 42 USC 8624(b)(2)(B), income below 110% of the guideline always passes the income test; the printed 60% SMI limits fall below that floor for 17 or more members in 2025–2027.

Not modeled and source conflicts

Item Source Model treatment
Percentage of Income Payment Plan (PIPP) reduction 2023 FINAL workbook; January 2025 HEAP customer FAQ No input identifies PIPP enrollment; the model estimates the non-PIPP award and does not apply the 75% reduction.
Omitted county — county falls back to the state's alphabetically first county, Adams, so a household with no county input receives the 6% southern reduction. An explicit UNKNOWN or non-Ohio county receives $0.
2026 and 2027 interior awards FY2027 draft plan items 2.5–2.6, page 9 The coefficients are fitted to the $31–$546 range; matching the range does not verify interior awards.
2024 and 2025 interior awards 2024 and 2025 DRAFT workbook covers; IU-2025-5 The coefficients are estimated from the cover percentages; matching the cover maximums does not verify awards between them.
Workbook coefficient precision 2021 and 2023 FINAL workbooks, pages 9 and 11 The printed four-decimal coefficients (the 2021 slope and fuel ratios, the 2023 gas ratio) leave 55 of 4,848 printed non-PIPP cells $1 off (36 in 2021, every fuel; 19 in 2023, gas and electricity); the model does not infer unprinted precision.
VA disability exclusion 2025–2026 application, page 7 veterans_benefits cannot separate VA disability payments, so all VA benefits count.
Disability premiums, spenddown and legal-fee deductions Guidelines Appendix XXIII, page 74 No inputs isolate them.
A minor's Social Security paid to someone other than an adult payee Guidelines section E-2.2, page 7 The payee is not an input; every minor's Social Security counts.
Verified permanent and total disability Guidelines section E-2.10, page 10 is_disabled approximates it.
Economic unit, custody, temporary absences and roomers Guidelines section E-2.1, page 6 The SPM unit approximates the energy household.
Favorable 30-day income comparison Guidelines section E-2.5, page 9 Annual inputs approximate the 12-month option.
Solar, other and unspecified fuel Guidelines section E-4, page 12; 2023 FINAL workbook, page 9 Eligible with a $0 estimate: no workbook column prices them (#9754 for unspecified fuel).
Crisis, cooling, weatherization and equipment assistance — Out of scope.

Where sources differ, the model follows the source in the last column:

Topic Source not followed Source followed and model treatment
2022–2023 income limit FY2023 plan section 2.1 (page 8) lists 60% of SMI for every size Guidelines section E-2.2 (page 7) applies 175% of the guideline to every size, adding $8,260 per member above eight. The model follows the Guidelines.
General assistance FY2026 plan section 1.9 (page 6) leaves "General Assistance benefits" unchecked Guidelines section E-2.3 (page 8) counts "any income not listed above", and Appendix XXIII (pages 73–76) lists general assistance as neither countable nor excluded. The model counts general_assistance.
Minors' income FY2026 plan section 1.9 (page 6) excludes only "Earned income of a child under the age of 18" Guidelines section E-2.2 (page 7) counts adults' income plus a minor's Social Security paid to an adult payee, and not a child's SSI. The model excludes a dependent minor's SSI and other income and counts the minor's Social Security.
Heat in rent FY2026 plan section 2.3 (page 8): "Tenants whose electric bills are not in the renter's name(s) are ineligible to receive benefits, unless they provide verification that they pay all or a portion (i.e., HUD Section 8 housing) of the electric bill." Guidelines section 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, in landlord's name, etc.) to receive a benefit." The model follows E-4 for unsubsidized tenants and requires a heating or electricity bill for subsidized and public-housing tenants (2025–2026 application, page 1).
Above 150% of poverty Both FINAL workbooks' Table 4 (page 29) prints ">150 0.00", and Table 2A ends at 150 Tables 2B and 2C (pages 16, 20) end "150+", and the covers count customers from 151% to 175%. The model pays the 150% award up to the 175% limit.

Microsimulation: the microsimulation datasets carry no heating inputs, so population totals are about $0 until #9754 lands. Callers must send heating_type with the matching fuel bill.

Test plan

68 YAML cases in 5 files cover:

  • the 2021 FINAL printed table for gas, propane, coal, fuel oil and wood at the 50%, 75% and 100% rows, with elderly targeting and northern and southern counties, plus the 2022 carry-through;
  • the 2023 FINAL table for all seven priced fuels, all 88 county assignments, targeting at ages 59 and 60, disability and children aged 5 and 6, the 50% floor and percentage rows, rounding after the regional and targeted factors, and the printed four-decimal gas ratio;
  • a household with a 5-year-old that is untargeted in 2021 ($464) and targeted in 2023 ($1,164);
  • the 2024 and 2025 DRAFT fuel maximums, the 2026 estimate and its 2027 carry-forward with the updated guideline ($283 at 100% of poverty in both years), and the 150% payment cap up to the limit ($271 in 2026);
  • the final 2021 and 2023 regional 150+ rows in northern and southern counties, with and without targeting, at 150% of the guideline, at the 175% limit and $1 above it;
  • every printed 2026 and 2027 poverty-guideline limit, the HHS SMI limits for sizes 8 and 9 in 2025 and size 9 in 2026 (the switch points) and sizes 8–12 in 2027, the 2023 all-sizes rule, the 2024 limits from the July 2023 application and a zero-size household;
  • the federal 110% floor for a 20-member household above the 60% SMI limit ($283) and at exactly 110% of the guideline ($0);
  • inclusive limits, no TANF or SNAP bypass, every heating-responsibility route including subsidized heat in rent with an electricity bill, no heat, NONE with heat in rent, no qualified member, a zero-size household that is ineligible and unpaid, a nonqualified adult's income and out of state;
  • net business sources, every unearned source, per-source loss floors for business, rental, farm rent and capital losses, the age 17 and 18 and dependent boundaries, a child's Social Security counted and SSI excluded, TANF and child support received excluded, general assistance counted, child support paid and its floor, the Part B premium, a health premium withheld from pay before tax, other health premiums without counting Part B twice, and military and railroad retirement;
  • final awards for an elderly Social Security recipient with and without the Part B premium ($474 and $0), an omitted county ($277 and $200), an UNKNOWN county ($0), a mixed-status family of size 2 ($273), losses that do not offset income, unpriced fuels that stay eligible with $0 and a bill smaller than the award.

Every eligibility and payment case specifies heating_type; the isolated limit, income and size cases omit it because those variables never read it. CI validates them.

  • YAML tests whose expected values come from an external source (statute, official form or worksheet, official calculator)
  • make format
  • Changelog fragment in changelog.d/

axiom: TheAxiomFoundation/rulespec-us#1540 queued

🤖 Generated with Claude Code

hua7450 and others added 6 commits October 3, 2026 19:49
- 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 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	policyengine_us/programs.yaml
@codecov

codecov Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (909176a) to head (21bc12d).
⚠️ Report is 414 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #9975   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         5    +1     
  Lines           76       103   +27     
  Branches         2         3    +1     
=========================================
+ Hits            76       103   +27     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

hua7450 and others added 4 commits October 7, 2026 22:56
Deduct health_insurance_premiums_without_medicare_part_b (Guidelines Appendix XXIII) and test each counted unearned source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	policyengine_us/programs.yaml
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 <noreply@anthropic.com>
hua7450 and others added 2 commits October 11, 2026 23:45
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 <noreply@anthropic.com>
@DTrim99

DTrim99 commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Add Ohio HEAP regular heating assistance

PR #9975: Add Ohio HEAP regular heating assistance (author: hua7450, head 21bc12d414)

Scope: Ohio's Home Energy Assistance Program (HEAP), the state's LIHEAP regular heating credit. The Ohio Department of Development ran it through the 2025-26 season, and the Ohio Department of Job and Family Services (ODJFS) runs it now. The PR covers:

  • household size, which counts citizens and qualified noncitizens, and countable income, which counts members 18 and over (a dependent minor's income is excluded except Social Security), with child support paid, the Medicare Part B premium and other health premiums deducted, and each source floored at zero;
  • the income limit: 175% of the prior year's poverty guideline, switching to 60% of state median income (SMI) above a dated size cutoff (none through model year 2024, then 7, 8 and 7 for 2025-2027);
  • the benefit-workbook formula: (A − B × poverty %) × fuel ratio × regional factor (±6%) × targeted-household multiplier, with the poverty percentage clipped to 50-150%;
  • heating responsibility, including heat in rent and subsidized housing.

The Percentage of Income Payment Plan (PIPP) reduction, crisis, cooling and weatherization are out of scope. The PR changes 35 files: 23 parameters, 5 variables, 5 test files (67 cases), programs.yaml and a changelog fragment. Payment parameters are dated 2021-01-01, 2023-01-01, 2024-01-01 and 2025-01-01; eligibility parameters by season start (2022-07-01 to 2026-07-01). The tests use periods 2021-2027, and the registry lists Ohio partial with no verified_years.

Overall: the workbook formula, the income limits and the income rules are right where the sources print them.

  • The 2021 and 2023 FINAL workbooks' A, B, fuel ratios, target factors, ±6% regions and all 88 county assignments are encoded as printed. With the printed four-decimal ratios, the formula reproduces 4,793 of the 4,848 printed non-PIPP cells; the other 55 are $1 off because the workbooks carry more decimals (G2).
  • The 2024 and 2025 coefficients, estimated from the draft covers, reproduce every printed maximum. In every workbook the printed minimum equals 0.19 of the regular central award at 150% (the 2021 cover matches to the cent), and under that relation the PR's coefficients also reproduce all six draft minimums, which the PR does not claim.
  • Every printed 175% limit for 2025-2027 and every HHS 60% SMI amount the tests use reproduce, and the SMI-year inference from the federal cap holds. The 2024 limits match a July 2023 application the PR says it could not find (G1).
  • The income rules follow Guidelines Appendix XXIII, and Social Security is counted net of Medicare premiums, as plan item 1.9 ("Excluding MediCare deduction") requires. Every one of the 25 listed income sources is nonzero in at least one test, which none of the three posted siblings achieved.

There are no critical findings. The six should-address items:

  • S1: a merge blocker from main's Integrate modeled state unemployment insurance into income flows #9558. The unearned list reads the raw unemployment_compensation, so main's code-health guard fails on the merged tree. Ohio has no modeled unemployment insurance yet, so no value changes today.
  • S2: the health-premium deduction reads only the non-payroll premium input. Main's Document disjoint health premium inputs and correct consumer treatment #10046 (merged after the last push) makes payroll (pretax) premiums a separate, disjoint input, which this formula never deducts, though Ohio deducts premiums shown on pay stubs.
  • S3: model years 2026 and 2027 pay the 2025 coefficients (maximum $441). By the PR's own year mapping, the FY2026 matrix governs model year 2026, and the FY2027 draft plan reports its range as $31 to $546.
  • S4: two eligibility conjuncts have no test that would fail if they were removed; dropping the size gate pays a household with no qualified member.
  • S5: twelve parameter descriptions use verbs outside the house template.
  • S6: one wrong section label, two incomplete page lists, and the heat-in-rent branch does not cite the Guidelines rule it rests on.

All 67 cases pass locally at the head and on the merged tree. The model outputs quoted below were reproduced by running the head code, or the merged tree for S1 and S2. Values that a proposed fix or a published range implies are hand computations and are labelled as such. The untested-logic claims in S4 were confirmed by mutating the code and rerunning the PR's tests.

Path prefixes used below:

  • P/ = policyengine_us/parameters/gov/states/oh/odjfs/liheap/
  • V/ = policyengine_us/variables/gov/states/oh/odjfs/liheap/
  • T/ = policyengine_us/tests/policy/baseline/gov/states/oh/odjfs/liheap/
  • G = 2022-2023 Energy Assistance Programs Guidelines (PDF page = printed page)
  • W21, W23 = the 2021 FINAL and 2023 FINAL benefit-matrix workbooks

Line numbers refer to head 21bc12d414.

Source Documents

# Document Link Use
1 G: 2022-2023 Energy Assistance Programs Guidelines (78 pp, "Effective July 1, 2022", Ohio Department of Development) G, p. 7 E-1 (p5); E-2 (p5-6); E-2.1 (p6-7); E-2.2 (p7); E-2.3 (p8); E-2.6 (p9); E-2.8 (p10); E-2.10 (p10-11); E-4 (p11-12); Appendix XII (p57); Appendix XXIII (p73-76)
2 FY2026 LIHEAP State Plan, Revision #2 (52 pp, report period 10/01/2025-09/30/2026, "Submission Accepted by CO") Development copy, p. 9 1.4, 1.8, 1.9 (p5-6); 2.1, 2.3 (p8); 2.5 "The FY 2025 Benefit Matrix (see attached)" and 2.6 $24 / $441 (p9). The text layer lacks the checkbox states, so the rendered pages were read
3 FY2027 HEAP State Plan, "DRAFT: July 2026" (51 pp; applicant ODJFS; funding period 10/1/2026-09/30/2027) draft, p. 9 2.1, 2.3 (p8); 2.5 "The FY 2026 Benefit Matrix (see attached)" and 2.6 $31 / $546.00 (p9)
4 FY2021-FY2025 plans (accepted) FY2021, FY2022, FY2023, FY2024, FY2025 Each 2.5 (p9) attaches the previous fiscal year's matrix; 2.6 ranges $41/$785, $45/$785, $50/$930, $50/$930, $41/$811; 2.1 and 2.3 (p8)
5 Ohio's draft 2022-2023 HEAP State Plan (22 pp, August 2022) p. 5 Not cited in the PR. "The FY2022 Benefit Matrix (see attached)"; "Minimum Benefit $46.03 Maximum Benefit $930.47" (G1)
6 W21: 2021 FINAL HEAP Benefit Matrix (29 pp, dated 11/12/2020) W21, p. 11 Cover (p1); Table 1 counties (p8); Tables 2A (p9-10), 2B (p15-16) and 2C (p19-20); formula (p11); PIPP tables (p12-14, 17-18, 21-22); Tables 3A/3B (p23-26); Table 4 (p27-29)
7 W23: 2023 FINAL LIHEAP Benefit Matrix (29 pp, dated 11/18/2022) W23, p. 11 Same layout as W21
8 2024 DRAFT (dated 11/27/2023) and 2025 DRAFT (dated 5/1/2025) matrix covers (1 p each) 2024, 2025 Credit percentages 46/38 and 25/22; maximum and minimum by fuel
9 IU-2025-5 (January 16, 2025) and the customer FAQ IU-2025-5, FAQ "This year ... $24 to $441, a change from the prior year's range of $41 to $811"; PIPP "75% HEAP reduction"
10 Energy Assistance Programs Applications, July 2022 to May 2027 2022-23, 2023-24, 2024-25, 2025-26, JFS 00330, 2026-27 p1 limits, size cutoffs and subsidized-housing rule; p7 adult income, deductions, child support and VA disability exclusions. The PR cites all but 2022-23 and 2023-24
11 Ohio Consumers' Counsel HEAP fact sheet, 2026-2027 OCC 2026-27 limits: 175% of the guideline for sizes 1-7, 60% of SMI for 8-12
12 HHS LIHEAP IM 2024-02 and IM 2025-02, Attachment 4 FFY2025, p. 5, FFY2026, p. 5 Ohio SMI $109,319 and $114,593 (p2); 60% of SMI for sizes 7-12 (p5)
13 42 USC 8624(b)(2)(B) LII Federal cap: the greater of 150% of poverty and 60% of SMI

Critical (Must Fix)

None.

Should Address

S1. Merge blocker: after merging main, the unearned list reads the reported-only unemployment_compensation, so main's guard fails

  • Where: P/income/sources/unearned.yaml:4 (- unemployment_compensation).
  • What changed on main: Integrate modeled state unemployment insurance into income flows #9558 (merged 2026-10-13, the day after this PR's last push) added total_unemployment_compensation, which uses the reported amount when present and otherwise the modeled state unemployment insurance programs. It moved every income-source list under parameters/ to the total, including the merged LIHEAP lists (for example nj/dca/liheap/income/sources/unearned.yaml:4), and added policyengine_us/tests/code_health/test_unemployment_compensation_readers.py, which fails on any raw list entry.
  • Reproduced on the git merge-tree result of main 8ae01aa3cb and this head: test_parameter_source_lists_do_not_read_raw_unemployment_compensation fails with one violation, parameters/gov/states/oh/odjfs/liheap/income/sources/unearned.yaml:4. The file's other three tests pass, and the PR's 67 cases still pass on that tree.
  • Source: G Appendix XXIII, p. 73 counts "Unemployment (excluding Title III, refer to Excluded Income)" as Supplemental Countable Income, and plan item 1.9, p. 5 checks "Unemployment insurance". Neither separates reported from modeled amounts.
  • Impact: main models unemployment insurance for AL, NJ, NY, OK, PA and UT only (gov.states.household.modeled_state_unemployment_compensation), so for Ohio households the total equals the reported amount and no value changes today. The guard still blocks the merge, and the raw entry would silently drop Ohio UI once it is modeled.
  • Why should, not critical: the head is correct against its base and CI is green. git merge-tree shows a clean textual merge, but this has to change before merge (as Add Alabama LIHEAP regular heating assistance #9967 S1, Add Rhode Island LIHEAP regular heating assistance #9972 S1 and Add Georgia LIHEAP regular heating assistance #9968 S1).
  • Fix: replace the entry with total_unemployment_compensation. T/income/oh_liheap_countable_income.yaml Case 17's first unit reports unemployment compensation, so it keeps covering the entry. Update rulespec-us#1540's required-outputs list, which names unemployment_compensation.

S2. The premium deduction misses payroll (pretax) health premiums, which main's #10046 now keeps in a separate input

  • Where: V/income/oh_liheap_countable_income.py:54-62 deducts child_support_expense, health_insurance_premiums_without_medicare_part_b and medicare_part_b_premium. pre_tax_health_insurance_premiums is never read.
  • Source:
    • G E-2.2, p. 7: "The household Countable Income is the gross income amount before taxes (minus allowable deductions)".
    • G Appendix XXIII, p. 74 deducts "Health Insurance Premiums (Dental, Health and Vision Insurance)", "Prescription plans" and "Medicare Premiums", proved by a "Premium Statement ..., cancelled Check or Pay Stub". Appendix XII (p. 57), "Paystubs Showing Insurance and Child Support Deductions", highlights a pay stub's "Pre-tax Deductions" for "MEDICAL INS" and "DENTAL INS" (rendered page).
    • So gross wages count, and a premium withheld from them before tax is deducted.
  • What changed on main: Document disjoint health premium inputs and correct consumer treatment #10046 (merged 2026-10-14) documents that "Pretax payroll payments belong only in pre_tax_health_insurance_premiums" and that "The pretax and non-pretax sets are disjoint". It added pre_tax_health_insurance_premiums to the SNAP, HUD and Pennsylvania CCW premium deductions and to spm_unit_health_insurance_premiums. CCW's new comment reads "Appendix A Part I(A) counts wages before health insurance deductions; Part II(C) permits unreimbursed health care premiums without a tax test", which is Ohio's structure too. At this PR's base the pretax input already existed ("Health insurance premiums paid through pre-tax payroll deductions") but sat outside the SPM premium aggregate.
  • Impact (reproduced on the merged tree): period 2026, one adult with $28,000 of wages and a $1,000 payroll premium in pre_tax_health_insurance_premiums counts $28,000, above the $27,387 limit, so the household is ineligible and gets $0. With the same premium in the non-pretax input it counts $27,000, is eligible and gets $151. Under the Guidelines it counts $27,000.
  • T/income/oh_liheap_countable_income.yaml Case 18 deducts "an employee health insurance premium" (the KFF average worker contribution for single coverage) through health_insurance_premiums_without_medicare_part_b. On main that input excludes payroll payments, so the case no longer describes a typical employer-plan premium.
  • Why should, not critical: the PR follows its base's convention, which the SNAP, HUD and CCW readers shared until Document disjoint health premium inputs and correct consumer treatment #10046 merged after the last push. 2026 eligibility is claimed, so this has to change before merge.
  • Fix: add pre_tax_health_insurance_premiums to the deductions, preferably by moving the deduction list into a parameter, as the income-source lists already are. Move Case 18's premium to the pretax input or add a payroll case, and update rulespec-us#1540's countable-income definition and inputs.

S3. Model years 2026 and 2027 pay the 2025 coefficients ($441 maximum), but the FY2026 matrix, which by the PR's own mapping governs 2026, pays $31 to $546

  • Where: P/payment/formula/intercept.yaml:13-17 and P/payment/formula/slope.yaml:8-12 end in a single 2025-01-01 entry that carries forward, as the comments at intercept.yaml:10-12 and slope.yaml:6-7 say. The carried awards are pinned by T/oh_liheap.yaml Cases 5, 6, 8, 18, 19, 21 and 22 (period 2026) and Case 7 (period 2027).
  • The PR maps workbook N to model year N, the season from July N−1 to May N whose credit is applied from January N. Ohio's January 16, 2025 notice confirms that mapping for the 2025 and 2024 workbooks (IU-2025-5): "This year, the HEAP customer benefit range will be $24 to $441, a change from the prior year's range of $41 to $811."
  • Each state plan attaches the previous fiscal year's matrix, and in the two latest accepted plans its item 2.6 range equals that matrix exactly:
    • FY2025 plan, p. 9: "The FY 2024 Benefit Matrix (see attached) is submitted with the State Plan assuming Ohio's LIHEAP funding level remains the same", with "Minimum Benefit $41 Maximum Benefit $811" (the 2024 DRAFT).
    • FY2026 plan, p. 9: "The FY 2025 Benefit Matrix (see attached) ...", with $24 and $441 (the 2025 DRAFT).
    • FY2027 draft plan, p. 9: "The FY 2026 Benefit Matrix (see attached) is submitted with the State Plan assuming Ohio's LIHEAP funding level remains the same. A final version of the FY 2027 Benefit Matrix will be submitted when funding information is finalized." and "Minimum Benefit $31 Maximum Benefit $546.00".
    • So the FY2026 matrix belongs to the 2025-26 season, model year 2026, and its maximum is $546. The draft also estimates FY2027 at the same range.
  • Impact:
    • Reproduced at head: period 2026, an Ashtabula County member aged 60 who heats with propane and has no income (the maximum cell) gets $441. The FY2026 maximum is $546.
    • The maximum pins the base at the 50% floor: $546 / (1.06 × 1.75) = $294.34, which is 31% of the $950 winter cost the PR assumes (0.31 × 950 × 1.855 = 546.30), against the PR's $237.50 (hand-computed).
    • The minimum is a PIPP cell. In every workbook the printed minimum equals 0.19 of the regular central award at 150%. W21's cover gives it to the cent (0.19 × $237.50 coal = $45.13), and the PR's own 2024 and 2025 coefficients reproduce all six draft minimums that way. With unchanged fuel ratios, the $31 minimum puts the 2026 base at 150% at about $268-$276, against the PR's $209 (hand-computed).
    • So eligible 2026 awards run about 24% to 32% low. The Franklin County propane household at 100% of the guideline (Case 6) gets $223 at head and about $281-$285 within these bounds (hand-computed).
  • The PR body mentions "a 2026 Benefit Matrix with a $31 minimum and a $546 maximum" that "is not public" and keeps the $441 maximum for "2026 and later". It does not say that, under its own mapping, that matrix is the one for model year 2026. The author's rulespec-us#1540 does: "Payments for model year 2026 and later cannot be source-grounded until it is."
  • Why should, not critical: 2026 and 2027 payments are documented as unverified carry-forwards, and the matrix itself is unpublished. This is the class of Add Alabama LIHEAP regular heating assistance #9967 S2: a published plan contradicts a carried-forward value, the reach is every eligible household, and the PR body understates it.
  • Fix:
    • Add a labelled 2026-01-01 estimate that fits the FY2026 range, citing FY2027 draft plan items 2.5-2.6 (p9). For example, 31% and 28.5% of $950 give A = 306.375 and B = 0.2375: the maximum cell is 294.50 × 1.855 = 546.30, $546, and the coal minimum is 270.75 × 0.6 × 0.19 = 30.87, $31 (hand-computed).
    • Or, at minimum, say in the parameter comments, the registry notes and the PR body that the FY2026 matrix governs model year 2026 and pays up to $546, so the carried values understate 2026 and 2027, and relabel or drop the 2026 and 2027 award assertions.
    • Replace the estimate when ODJFS publishes the matrix; the Clearinghouse has no FY2027 Ohio files yet.

S4. Two eligibility conjuncts have no test that would fail if they were removed

Each mutation below, applied to the head on its own, still passes all 67 cases.

  1. The size gate, (size > 0) at V/eligibility/oh_liheap_eligible.py:35.
    • Without it, a unit with no qualified member and no income passes the income test (limit 0, income 0) and is paid, because oh_liheap computes the poverty ratio with max_(size, 1).
    • Reproduced under the mutation: in 2026, a unit of one undocumented adult with no income and a gas bill becomes oh_liheap_eligible: true (false at head). By the formula it would then be paid 237.5 × 0.724 = $172 (hand-computed).
    • Every size-0 case that reaches eligibility has income above $0: T/eligibility/oh_liheap_eligible.yaml Case 9 (line 198, $12,000) fails the income test anyway, and T/oh_liheap_household_size.yaml Case 2 (line 47, no income) asserts only the size.
    • G E-2.8 (p. 10): "As long as there is one citizen in the household (whether adult or child) the household could be eligible for assistance."
    • Fix: add oh_liheap_eligible: false and oh_liheap: 0 to household-size Case 2. Unlike Add Rhode Island LIHEAP regular heating assistance #9972 S3.3, the award changes here, not just the flag.
  2. The NONE check, heating_type != fuel.NONE at the same line.
    • T/eligibility/oh_liheap_eligible.yaml Case 4 (line 76, NONE with a gas bill) is false through responsible already, because heating_expense reads no bill for NONE.
    • T/oh_liheap.yaml Case 8's fifth unit (line 242, NONE with heat in unsubsidized rent) is the only case that reaches the check, and it asserts only oh_liheap, which is $0 anyway because NONE has no fuel ratio.
    • Reproduced under the mutation: in 2026, a NONE household with heat in unsubsidized rent becomes oh_liheap_eligible: true (false at head). Its award stays $0, which is why Case 8 still passes.
    • Fix: add oh_liheap_eligible: [true, true, false, true, false] to Case 8. The fourth unit (UNSPECIFIED) is eligible with $0 (G3).

A control mutation confirms the method: dropping ~subsidized | (line 28) fails T/eligibility/oh_liheap_eligible.yaml Case 5 and T/oh_liheap.yaml Case 8. Every listed income source is nonzero in at least one case, and by inspection the other branches are pinned: the limit's size-0 mask and floor, each size cutoff and SMI lag, the dependent-minor rule and its Social Security exception, the per-source floors, each deduction and the final floor, each heating-responsibility route including public housing, the 50% floor and 150% cap, every fuel group, the three regions and the unknown-county zero, and each targeting boundary. Consistency: #9967 S3, #9972 S3 and #9968 S2 rated untested logic SHOULD.

S5. Twelve parameter descriptions use verbs outside the house template

All 23 descriptions end with "under the Home Energy Assistance Program." with nothing after it, and Ohio's program name is fine there (merged New York HEAP uses the same name). Eleven use template verbs (limits or uses). These twelve do not:

File:line Current Suggested
P/income/adult_age.yaml:1 "counts the income of household members at least this age" "Ohio excludes the income of dependent members below this age, other than Social Security, under the Home Energy Assistance Program."
P/income/sources/earned.yaml:1 "counts these earned income sources, except for dependent minors" "Ohio uses these sources as earned income under the ..."
P/income/sources/unearned.yaml:1 "counts these unearned income sources, except for dependent minors" "Ohio uses these sources as unearned income under the ..."
P/payment/formula/intercept.yaml:1 "starts the payment formula with this intercept" "Ohio sets this payment formula intercept under the ..."
P/payment/formula/slope.yaml:1 "reduces the payment formula by this amount per federal poverty percentage point" "Ohio sets this payment reduction per federal poverty percentage point under the ..."
P/payment/regional/adjustment.yaml:1 "adjusts payments up or down by this share for designated northern and southern counties" "Ohio sets this regional payment adjustment for northern and southern counties under the ..."
P/payment/regional/central_counties.yaml:1 "does not regionally adjust payments for these counties" "Ohio uses these counties as the central region, with no regional adjustment, under the ..."
P/payment/regional/northern_counties.yaml:1 "increases payments for these counties" "Ohio uses these counties as the northern region under the ..."
P/payment/regional/southern_counties.yaml:1 "decreases payments for these counties" "Ohio uses these counties as the southern region under the ..."
P/payment/targeted/elderly_age.yaml:1 "increases payments for households with a member at least this age" "Ohio sets this minimum age for a targeted-household member under the ..."
P/payment/targeted/multiplier.yaml:1 "multiplies payments by this factor for targeted households" "Ohio provides targeted households this multiple of the payment under the ..."
P/payment/targeted/young_child_age.yaml:1 "increases payments for households with a child no older than this age" "Ohio sets this maximum child age for a targeted household under the ..."

The eleven that fit: fpg_rate and smi_rate (limits); fpg_year_lag, maximum_fpg_household_size, smi_year_lag, both poverty-ratio bounds, the three fuel ratios and young_child_in_effect (uses). Consistency: #9967 S4, #9972 S4, #9968 S3 and #9745 S6.

S6. A wrong section label, two incomplete page lists, and the heat-in-rent branch does not cite its rule

File:line Problem Fix
V/oh_liheap_household_size.py:10 "Sections E-2.1 and E-2.6": E-2.6 is the asset test (G p. 9). The immigration rule the variable applies is E-2.8 (G p. 10), which the PR body cites correctly "Sections E-2.1 and E-2.8"
V/eligibility/oh_liheap_eligible.py:10-13 Cites the application (p1) and plan item 2.3 (p8) only. The unsubsidized heat-in-rent branch (~subsidized, line 28) rests on G E-4, p. 12: "Note: For HEAP only, the utility bill does not have to be in a household member's name (for example, heat included in the rent, in landlord's name, etc.) to receive a benefit." Plan 2.3 says the opposite for renters with utilities in the rent (G7) Add the Guidelines reference with #page=12
V/oh_liheap.py:24-25 The Guidelines link (#page=5) stands for E-1, E-2, E-2.10 and E-4, which run over pages 5-6 and 10-12, with no # PDF pages line Add # PDF pages 5-6, 10-12
V/oh_liheap.py:13-15 # PDF pages 1, 8-9, 11 for W21 leaves out page 10 (rows 98-150) and pages 15-16 and 19-20 (Tables 2B and 2C, whose 150+ rows the cap rests on), which the W23 line lists # PDF pages 1, 8-11, 15-16, 19-20

Consistency: #9972 S5 rated wrong anchors and missing page lists SHOULD; the brief rates incorrect section citations SHOULD.

Suggestions

G1. Backfilled and carried years: a July 2023 application confirms 2024, and the FY2022 matrix paid more than the 2021 carry-through

  • Model year 2024. The PR body says "No 2023–2024 rule was found, so model year 2024 keeps the 2022–2023 rule".
    • The state-hosted July 2023-May 2024 application, p. 1 prints the 175% limits for sizes 1-8 ($25,515, $34,510, $43,505, $52,500, $61,495, $70,490, $79,485, $88,480) and "households with more than eight members must add $8,995 to the yearly income".
    • That is exactly the PR's 2024 rule (T/eligibility/oh_liheap_income_limit.yaml Case 7: 25,515, 88,480 and 97,475). Cite it in P/eligibility/maximum_fpg_household_size.yaml and fpg_rate.yaml and correct the PR body.
    • The July 2022-May 2023 application likewise adds "$8,260" per member above eight, matching the Guidelines.
  • Model year 2022. The PR carries the 2021 workbook forward (reproduced: period 2022, an Ashtabula member aged 60 with propane and no income gets $737).
    • Ohio's draft 2022-2023 HEAP State Plan (August 2022), p. 5 attaches "The FY2022 Benefit Matrix" with "Minimum Benefit $46.03 Maximum Benefit $930.47". The accepted FY2023 plan's item 2.6 rounds these to $50 and $930 (p. 9).
    • So 2022 awards run about 26% low at the maximum. 2022 is unclaimed and documented as a carry-through, so this is a suggestion: record the FY2022 range in the parameter comments and registry notes, or gate 2022 payments.

G2. Encode the workbook ratios at the precision the tables use, and correct "reproduce the printed table"

  • With the printed four-decimal ratios, the formula misses 19 of W23's 2,424 printed non-PIPP cells (all gas and electricity) and 36 of W21's 2,424 (every fuel), each by $1. This audit covered Tables 2A, 2B and 2C, rows 50 to 150+. For example, W21 Table 2A row 89 prints $646 for weighted propane where the formula gives 646.51, so $647, and W23 row 100 prints $579 for weighted gas where it gives $578.
  • The PR body says the 2021 coefficients "reproduce the 2021 FINAL workbook's printed table" and that 2023 differs at "two cells". The registry notes mention only gas.
  • Every cell of both workbooks reproduces with these values:
    • W23: gas 0.5523335.
    • W21: the unrounded slope 0.0011 × 892.05 = 0.981255, with gas 0.58821435, propane and oil 0.85197, and coal 0.532482.
    • Both gas ratios imply the same $524.72 gas winter cost (0.58821435 × 892.05 = 0.5523335 × 950 = 524.72). So each ratio is a fuel cost divided by the high winter cost and can be encoded that way.
  • T/oh_liheap.yaml Case 11 (line 291) can then assert the printed $334 and $579 instead of $333 and $578. 2021 and 2023 are unclaimed, so this is a suggestion, as Add Alabama LIHEAP regular heating assistance #9967 G1's $1-$2 differences were.

G3. Fuels that are eligible but paid $0

  • Reproduced at head (period 2026, no income): SOLAR with an electric bill, OTHER with an other-fuel bill, and UNSPECIFIED with heat in unsubsidized rent are each oh_liheap_eligible: true with oh_liheap: 0. T/oh_liheap.yaml Case 9 asserts only the $0.
  • G E-4, p. 12 lists the eligible primary heat sources: "A regulated or unregulated utility (gas and electric); A permanent, free-standing fuel tank (oil and propane); A legal fireplace (wood); or A legally vented wood/coal stove." OTHER fits none of them. heating_expense treats SOLAR homes as grid-tied with electric heat, which fits the gas and electricity column.
  • Either pay SOLAR at the gas and electricity ratio and make OTHER ineligible, or make the flag match the $0. Add a # See #9754 note for UNSPECIFIED (Add New Jersey LIHEAP regular heating assistance #9745 G1, Add Alabama LIHEAP regular heating assistance #9967 G2, Add Georgia LIHEAP regular heating assistance #9968 G2).

G4. Self-employment and rental results may net within Schedule 1

  • G E-2.3, p. 8: self-employed applicants use "The amount listed on the Schedule 1 lines 3, 5, and 6", and "If a loss is reported on the tax documentation submitted, enter $0 in the 12-month field." Appendix XXIII (p73) lists "landlord" under self-employment. Read together, business (line 3), rental and partnership (line 5) and farm (line 6) results form one self-employment figure, floored at $0 as a whole.
  • The PR floors each source separately (V/income/oh_liheap_countable_income.py:34-36), so a business gain and a rental loss count the gain in full. Reproduced at head: $6,000 of self-employment income and a $6,000 rental loss count $6,000; netting gives $0 (hand-computed). Wages are never offset under either reading.
  • The per-source reading is conservative and recorded in rulespec-us#1540 (interpretation 18, "settled"). Either add the Schedule 1 reading to the PR body's conflict table, or net self_employment_income, sstb_self_employment_income, partnership_s_corp_income, farm_operations_income, rental_income and farm_rent_income before a single floor.

G5. PIPP is the largest unmodeled factor

  • The covers project 76% to 82% of HEAP households on PIPP Plus (W21 75.82%, W23 76.12%, 2024 80.50%, 2025 82.12%), and "those on both HEAP and PIPP receive a 75% HEAP reduction" (FAQ question 2). The model pays every household the non-PIPP award, which the PR documents.
  • An optional PIPP-enrollment input (default false) would let household users get the right award. The workbooks' PIPP tables are not uniform: Table 2A's PIPP cells are a quarter of the regular cells, and Table 2C's are about a fifth. A plain 25% factor would match the FAQ but not every printed PIPP cell.

G6. Test and comment hygiene

  • About ten comments lost the spaces around their numbers:
    • T/eligibility/oh_liheap_eligible.yaml: line 3 ("limit27387"), line 27 ("above27387fails", "categoricalNo"), line 197 ("size0must") and line 220 ("Full28000 exceeds size1limit27387");
    • T/eligibility/oh_liheap_income_limit.yaml: line 3 ("whole-dollar175%of2025FPG", "adjacent200%HWAP") and line 44 ("JFS00330", "July2026-May2027");
    • T/income/oh_liheap_countable_income.yaml: line 3 ("p8:12000+6000+600+1200+1200=21000"), line 31 ("pp73–74:2400rent+1200farmrent...") and line 188 ("to0:12000wages+600positive business+1200SSI=13800").
  • Two comments refer to internal decisions: "flag represents verified arrangement in the contract" (T/eligibility/oh_liheap_eligible.yaml:98) and "the approved proxy" (line 147), as in Add Rhode Island LIHEAP regular heating assistance #9972 G7.
  • Several comments call the Guidelines "Manual" (for example T/eligibility/oh_liheap_eligible.yaml:197 and T/oh_liheap_household_size.yaml:46), and others say "Guidelines".
  • The isolated limit and income tests set heating_type and fuel bills that those variables never read.

G7. PR body and issue housekeeping

  • Add two rows to the conflict table:
    • Plan item 2.3 makes renters with utilities in the rent ineligible unless they pay part of the electric bill (FY2026 plan, p. 8), while G E-4 (p12) lets heat-in-rent households receive HEAP. The model follows E-4 for unsubsidized tenants (Remove complex pass-through reform #1540 interpretation 14).
    • Table 4 in both FINAL workbooks (p29) prints ">150 0.00", and Table 2A's last row is "150", while Tables 2B and 2C end "150+". The covers' "151% to 175%" customer counts support the 150+ reading the PR follows (Remove complex pass-through reform #1540 interpretation 5).
  • Correct "No 2023–2024 rule was found" (G1), "two cells" and "reproduce the printed table" (G2).
  • The registry entry is named "Ohio LIHEAP" ("Ohio Low Income Home Energy Assistance Program"). Merged New York uses its program's own name ("New York HEAP", "New York Home Energy Assistance Program"), which would fit Ohio too.
  • The make format box is unchecked, although CI lint passed.
  • rulespec-us#1540 still calls the PR "open as a draft" and says the tests were "Not run locally". All 67 pass locally at this head.

Verified correct

  • Workbook formula (W21 and W23):
    • "(A - (B * POVERTY RATIO)) * VENDOR COST RATIO = PAYMENT", with A = 593.2133 and B = 0.9813 from a $892.05 high winter cost and 61%/50% credits (W21 p11), and A = 731.5 and B = 1.33 from $950 and 70%/56% (W23 p11).
    • Fuel ratios as printed (p9): 0.5882, 0.852, 0.852 and 0.5325, then 0.5523, 1, 1 and 0.6. Propane, fuel oil and kerosene share the bulk ratio; coal and wood share one.
    • Target factors 1.50 (a member 60 or older or disabled) and 1.75 (adding "5 yrs or under") from the covers (p1). The FY2021 and FY2022 plans target only older and disabled members, so carrying young_child_in_effect: false through 2022 fits.
    • Regions of +6% and −6% (p1; Tables 2B and 2C headed 1.0600 and 0.9400). Table 1 (p8) assigns 24 northern, 11 southern and 53 central counties, identically in both workbooks and in the PR's lists.
    • The 50% floor ("Households falling at or beneath 50% of the poverty level will receive maximum benefits", p1), the 150+ terminal rows (p16, p20) and half-up rounding after every factor.
    • Tables 3A and 3B use the 2020 and 2022 guidelines ($12,760 and $13,590 at 100%), which supports the one-year guideline lag.
  • 2024 and 2025 estimates: A = 475 and B = 0.76, and A = 251.75 and B = 0.285, from 46%/38% and 25%/22% of $950, reproduce every cover maximum ($587/$811/$486 and $319/$441/$264). The gas ratio 0.724 lies in the 0.7236-0.7247 band both gas maxima allow. The printed minimums equal 0.19 of the regular central award at 150% in every workbook (W21's cover to the cent: $49.85, $72.20 and $45.13), and with the PR's coefficients that relation reproduces all six draft minimums (2024: $50, $69, $41; 2025: $29, $40, $24).
  • Limits:
    • 2026: all 8 printed limits ($27,387 ... $94,762). 2027: all 7 ($27,930 ... $87,570). 2025: $26,355 and $82,845. 2023: $23,782, $81,602, $89,862 and $98,122 (G E-2.2, p7, floored). 2024: $25,515, $88,480 and $97,475, matching the July 2023 application (G1).
    • 60% of SMI: HHS FFY2025 $90,515 and $92,483, and FFY2026 $94,881, $96,944, $99,007, $101,069 and $103,132 (Attachment 4, p5), through the shared liheap_smi_limit helper.
    • Size cutoffs of 7, 8 and 7 (applications p1; the FY2025, FY2026 and FY2027 draft plans' item 2.1 put SMI at sizes 8, 9 and 8).
    • The SMI-year inference holds. With FFY2024 SMI, the 2024-25 size-7 limit ($82,845) would exceed 60% of SMI ($81,085); with FFY2025, the 2025-26 size-8 limit ($94,762) would exceed it ($90,515). With FFY2027 SMI ($117,810), the 2026-27 form could have kept size 8 on the guideline ($97,510 against $97,546), so its switch after seven fits FFY2026, as the OCC sheet's sizes 8, 11 and 12 show.
    • Limits are inclusive ("equal to or less than", G E-2.2, p7) and floored to whole dollars, as the applications print them.
  • Timing: HEAP runs from July 1 to May 31 and credits from January (G E-1, p5; applications p1). Period N reads January 1 of N, inside the season from July N−1 to May N.
  • Income (G E-2.2-E-2.3, p7-8; Appendix XXIII, p73-76; application p7):
    • Gross income of members 18 and over. A dependent minor's income is excluded except Social Security: "A minor that is awarded SS/SSDI and has a payee and/or a guardian of their award that is 18 years or older, this counts as included income" (p7).
    • Nonqualified members' income counts in full (E-2.1 note, p7; E-2.8, p10).
    • Every listed source maps to an Appendix XXIII category: wages and self-employment, including landlord income (p73); unemployment, workers' compensation, employment disability payouts and strike benefits (p73-74); pensions including military pensions and widow's benefits, SSI and alimony (p73); and IRA and annuity withdrawals, estate and trust payouts, lottery winnings, interest, dividends and capital gains (p74). Railroad retirement and general assistance count through E-2.3's catch-all, as documented.
    • TANF (Ohio Works First), child support received and gifts are excluded (p75-76; application p7).
    • Child support paid, Medicare premiums and other health premiums are deducted (p74; application p7), so Social Security counts net of Medicare, as plan item 1.9's checked "Excluding MediCare deduction" box requires (rendered page 5). That is the counterpart of Alabama's "Including" box in Add Alabama LIHEAP regular heating assistance #9967.
    • Each source is floored at zero, so no loss offsets wages (E-2.3: "If a loss is reported ... enter $0").
  • Household: is_citizen_or_legal_immigrant (8 U.S.C. 1641 qualified statuses, DACA excluded) matches the "Proof of Legal Residency/Qualified Alien" list (E-2.8, p10). A unit with no qualified member is ineligible.
  • Eligibility: Ohio residence; no asset test (E-2.6, p9; plan item 2.3); no categorical eligibility (plan item 1.4 answered No); heat in unsubsidized rent qualifies (E-4, p12); subsidized and public-housing tenants with heat in rent need a bill ("If you live in federally subsidized housing and have a utility bill in your name, you may be eligible", application p1; plan item 2.3); NONE is ineligible.
  • Code patterns: no hard-coded values in the limit and payment formulas (the deduction list is in code, S2). defined_for = StateCode.OH on four variables, and oh_liheap is gated by oh_liheap_eligible. Vectorized formulas; all 23 parameters are read; the shared fpg() and liheap_smi_limit() helpers are reused. Mixed-state and unknown-county rows return $0, and the omitted-county fallback (Adams, −6%) mirrors merged New Jersey's Atlantic fallback and is documented and tested.
  • Tests:
    • 67 of 67 pass locally at head (policyengine-core 3.32.29) and on the merged tree. Periods are plain, and every case sets heating_type.
    • Hand-checked against the workbooks, applications and HHS tables: T/oh_liheap.yaml Cases 1-4, 10, 12-17, 21, 23 and 24; income-limit Cases 1, 2 and 4-8; countable-income Cases 1, 4, 7, 12, 16 and 17; eligibility Cases 1, 2 and 14.
  • Changelog: changelog.d/oh-liheap.added.md is top level and typed added.

Checklist results (LIHEAP wave 2a)

  1. State plan and manual first: pass, with S3. I read the accepted FY2021-FY2026 plans (rendered checkboxes for FY2026), the FY2027 draft, Ohio's draft 2022-23 plan, the Guidelines, the five applications from July 2022 to July 2026, the OCC sheet, IU-2025-5 and its FAQ, both FINAL workbooks and both draft covers. I verified every encoded factor, county, limit and branch. The FY2026 matrix's range is not applied to 2026 (S3).
  2. Income definition: pass at head on sources and loss floors. Social Security counts net of Medicare (plan 1.9; Appendix XXIII), and annual income stands in for the 12-month option. Payroll premiums are not deducted (S2), and the UI entry needs the total after rebase (S1). Schedule 1 netting is a reading point (G4).
  3. Backdating: the July 2023 application confirms the 2024 limits (G1). 2021 and 2023 payments reproduce the FINAL workbooks within $1 (G2). 2022 carries 2021 although the FY2022 matrix paid up to $930.47 (G1, unclaimed). 2026 and 2027 carry 2025 although the FY2026 matrix pays up to $546 (S3).
  4. Household and arrangement rules: pass on subsidized and public housing, heat in rent, renters, no categorical eligibility and the targeted-household weight. PIPP is documented as unmodeled (G5), and three fuel cases are eligible but paid $0 (G3). Two eligibility conjuncts are unpinned (S4).
  5. Tests: 67 cases, more than 8 hand-checked. The size grids (1-8 in 2026, 1-7 in 2027), switch points, the limit edge, the 50% and 150% edges, the targeting boundaries and every income source are covered, and periods are plain. Gaps are in S4.
  6. Parameter descriptions: twelve use off-template verbs (S5). There are no trailing clauses.
  7. References: one wrong section label, two incomplete page lists and a missing Guidelines citation for a branch (S6). Multi-page titles use #page 7-8,73 and #page 16,20 correctly.
  8. Wiring: pass. The programs.yaml entry and coverage line are well formed. No aggregate wiring, which matches OR, NY, NJ and MD on main (none of them is in household_state_benefits). defined_for gating is on every variable. No take-up, as in the siblings.
  9. Axiom: valid queued line. rulespec-us#1540 is open, labelled pe-parity, dispatch-ready and current to 21bc12d414. It needs updates for S1-S4 (see below).
  10. Branch and CI: all checks are green at head. 12 ahead and 82 behind main. No textual conflicts, but main's UI guard fails on the merged tree (S1), and Document disjoint health premium inputs and correct consumer treatment #10046 changes the premium inputs (S2).
  11. Integrate modeled state unemployment insurance into income flows #9558: S1. No modeled Ohio UI exists, so the effect today is the guard failure only.
  12. IIJA and FY2027: no IIJA supplement; none of the FY2021-FY2027 plans, the Guidelines or the covers mentions one. The FY2027 draft estimates FY2027 benefits at the FY2026 matrix's $31-$546 (S3), JFS 00330 says credits may come "as early as October 2026", and the 2026-27 limits are encoded and correct.
  13. Mutation check: S4. The control mutation fails as expected.

CI status

28 of 28 checks pass at 21bc12d414 (gh pr checks 9975, run of 2026-10-12). The three "skipping" entries belong to a superseded run on the same SHA.

Branch status

Axiom line

axiom: TheAxiomFoundation/rulespec-us#1540 queued: valid format, and the issue meets the bar.

  • rulespec-us#1540 is open and labelled pe-parity (plus enhancement), with no comments, and was last updated 2026-10-12.
  • It is dispatch-ready under the Add AMT parameters for 2020-2023 #1467 standard. It has:
    • proposed us-oh/ module paths with corpus status;
    • verbatim Guidelines, application, plan, workbook and HHS text;
    • required outputs for all 5 variables;
    • 15 companion tests derived from the workbooks, applications, plans and HHS tables ("Every expected value comes from the cited sources, none from policyengine-us output").
  • It describes head 21bc12d414 correctly, including the 2026 gap ("Payments for model year 2026 and later cannot be source-grounded"), the heat-in-rent conflict (interpretation 14) and the 2023 gas-precision disagreement (interpretation 6).
  • Updates needed when the fixes land:
    • the UI input in the required outputs (S1) and the payroll-premium deduction (S2);
    • the 2026 estimate or caveat (S3) and the new eligibility cases (S4);
    • the July 2023 application (interpretation 9), the FY2022 range (interpretation 4) and W21's 36 $1 cells ("The 2021 and 2023 payments reproduce the FINAL tables");
    • the stale "open as a draft" and "Not run locally".

Next steps

  1. S1: rebase onto main and switch P/income/sources/unearned.yaml:4 to total_unemployment_compensation.
  2. S2: deduct pre_tax_health_insurance_premiums (ideally from a parameter list) and move Case 18's premium to it or add a payroll case.
  3. S3: add a labelled 2026 estimate that fits the FY2026 range, or state plainly that 2026 and 2027 are understated, and correct the PR body.
  4. S4: add the size-0 and NONE eligibility assertions.
  5. S5-S6: align the twelve descriptions and fix the four references.
  6. Optionally address G1-G7, then refresh the PR body and rulespec-us#1540 and re-request review.

0 critical and 6 should-address findings, plus 7 suggestions.

Verdict: REQUEST_CHANGES

@DTrim99 DTrim99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for 6 should items; details in the full report above. The encoded workbook formula, fuel ratios, regions, county assignments and limits check out: 4,793 of 4,848 printed cells match exactly and the rest are $1 off. All 67 tests pass and CI is green. (1) Merge blocker from main's #9558: the guard fails on the merged tree at income/sources/unearned.yaml:4. (2) The deduction reads only health_insurance_premiums_without_medicare_part_b, so payroll premiums (pre_tax_health_insurance_premiums, separate on main since #10046) are never deducted. Example: $28,000 of wages with a $1,000 payroll premium gets $0 where the Guidelines give $151. (3) 2026 and 2027 pay the 2025 coefficients (max $441), while the FY2027 draft plan reports the FY2026 matrix range as $31–$546, so 2026 awards run about 24–32% low. Encode the FY2026 matrix if it can be obtained; otherwise document the carry-forward and narrow the year claim. (4) Two eligibility conditions pass every test even when removed: the size check and the NONE check. (5) Twelve parameter descriptions are off the house template. (6) A wrong section label (E-2.6 should be E-2.8), two incomplete page lists, and no E-4 citation on the heat-in-rent branch.

hua7450 and others added 2 commits October 15, 2026 15:13
- 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 <noreply@anthropic.com>
@hua7450

hua7450 commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the review. Fixes pushed in a2cb186. The branch also merges upstream/main, which brings in #9558 and #10046.

  • S1: income/sources/unearned.yaml now lists total_unemployment_compensation, so main's guard no longer flags the list. Ohio has no modeled unemployment insurance, so no values change. Countable-income Case 17 keeps its reported $5,720 unemployment row (26 weeks × $220, ORC 4141.30(B)(3)), and the total returns that amount.
  • S2: The deductions now live in a new parameter, income/deductions.yaml, which adds pre_tax_health_insurance_premiums to child support paid, health_insurance_premiums_without_medicare_part_b and medicare_part_b_premium. The formula reads it with add(spm_unit, period, p.deductions). The inputs are disjoint on main, so no premium counts twice. Countable-income Case 18 now puts the $1,440 KFF worker premium in the pretax input (still $21,440), Case 19 keeps the non-pretax Part D premium, and the reference adds Appendix XII (page 57).
  • S3: I added a labelled 2026-01-01 estimate using your fit: intercept 306.375 and slope 0.2375 (31% and 28.5% of $950), citing FY2027 draft plan items 2.5–2.6 (page 9). The northern targeted propane maximum is now $546, and under the 0.19 PIPP relation the coal minimum rounds to $31. The draft estimates FY2027 at the same range, so 2027 carries the 2026 values. I recomputed the 2026–2027 cases by hand: Cases 6 and 7 pay $283, Case 5 pays $271 at the 150% cap, Case 8 pays $312 and $213, Case 18 pays $474, Case 19 pays $277 and $200, Case 21 pays $273, and Case 22 pays $213 and $205. The parameter comments, oh_liheap.py, the registry note and the PR body now label the 2026 values as estimates fitted to the published FY2026 range; the matrix itself is not public.
  • S4: Household-size Case 2 now asserts oh_liheap_eligible: false and oh_liheap: 0. With no qualified member and no income, only the size gate blocks it. oh_liheap.yaml Case 8 asserts oh_liheap_eligible: [true, true, false, true, false], so its NONE row pins the NONE check. The size gate sits outside the new 110% floor (see the last item below), so a zero-size unit cannot pass through the floor.
  • S5: All twelve descriptions now use your suggested wording. The new deductions parameter reads "Ohio deducts these expenses from countable income under the Home Energy Assistance Program."
  • S6: oh_liheap_household_size.py cites E-2.8. oh_liheap_eligible.py adds the Guidelines E-4 link (#page=12) with a comment that quotes E-4 and plan item 2.3. oh_liheap.py lists # PDF pages 1, 8-11, 15-16, 19-20 for the 2021 workbook and # PDF pages 5-6, 10-12 for the Guidelines.
  • G1: Partly done. maximum_fpg_household_size.yaml and fpg_rate.yaml now cite the July 2023–May 2024 application. The "No 2023–2024 rule was found" sentence is replaced in maximum_fpg_household_size.yaml, income-limit Case 7 and the PR body; no values change. I did not add the FY2022 range: history is out of scope for this PR, and 2022 stays an unclaimed carry-through.
  • G2: Partly done. I did not re-encode the ratios, because 2021 and 2023 are unclaimed years and history is out of scope for this PR. The comments in oh_liheap.py and gas_electricity.yaml now give the $1 misses from the printed four-decimal coefficients: 36 cells in 2021 across every fuel, from the rounded slope as well as the ratios, and 19 in 2023 for gas and electricity. The PR body gives the same counts, 55 of 4,848 in all. The registry note no longer says only gas cells differ.
  • G3: Partly done. I declined to pay SOLAR at the gas ratio or make OTHER ineligible. Ohio's workbooks have no solar or other column, and our LIHEAP convention keeps such fuels eligible with a documented $0. oh_liheap.yaml Case 9 now asserts oh_liheap_eligible: [true, true, true, true, true, false] next to the $0 awards, and the comment in oh_liheap.py names SOLAR, OTHER and UNSPECIFIED and points to Default heating_type to electricity and remove the UNSPECIFIED-gated state heating adapters #9754.
  • G4: Declined. Across the LIHEAP states we keep per-source floors on the existing net business inputs and treat rental_income as non-negative. The per-source reading stays recorded as interpretation 18 in LIHEAP wave 2a: encode Ohio HEAP regular heating assistance TheAxiomFoundation/rulespec-us#1540.
  • G5: Declined, because new inputs are out of scope for this PR. The unmodeled PIPP reduction stays documented in oh_liheap.py, the registry note and the PR body.
  • G6: Done. The run-together numbers now have spaces, the two internal-decision comments are reworded, and "Guidelines" replaces "manual" throughout, including the unearned.yaml comment. The isolated limit, income and size cases no longer send heating_type or fuel bills. Every case that asserts eligibility or an award still sends heating_type.
  • G7: Done. The conflict table adds the plan 2.3 vs E-4 heat-in-rent row and the Table 4 ">150 0.00" vs "150+" row under neutral column headers. The "No 2023–2024 rule", "two cells" and "reproduce the printed table" statements are corrected. The registry entry is now "Ohio HEAP" ("Ohio Home Energy Assistance Program"), and the make format box is checked. The Axiom issue no longer calls the PR a draft, and it records your run of the 67 earlier cases.
  • Federal 110% floor (not one of your items): following 42 U.S.C. 8624(b)(2)(B), oh_liheap_eligible now passes a household whose income is below 110% of the lagged guideline. It uses the shared federal parameter gov.hhs.liheap.fpg_floor, which the Florida and Georgia PRs (Add Florida LIHEAP regular heating assistance #9969 and Add Georgia LIHEAP regular heating assistance #9968) add as an identical file. Ohio's 60% SMI limit falls below the floor from size 17 in 2025–2027. New oh_liheap.yaml Case 25 (size 20, 2026) pays $283 at 100% of poverty, above the $119,633 limit, and $0 at exactly $132,165. oh_liheap_income_limit still returns the printed limits. The PR now has 68 cases.
  • LIHEAP wave 2a: encode Ohio HEAP regular heating assistance TheAxiomFoundation/rulespec-us#1540 is refreshed to this head.

@hua7450
hua7450 requested a review from DTrim99 October 15, 2026 21:08

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Ohio HEAP regular heating assistance

2 participants