Skip to content

Pay Hawaii's LIHEAP Energy Credit on electric (cooling) accounts - #10734

Merged
hua7450 merged 5 commits into
mainfrom
hi-liheap-cooling
Nov 12, 2026
Merged

hua7450 merged 5 commits into
mainfrom
hi-liheap-cooling

Conversation

@hua7450

@hua7450 hua7450 commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

Pays Hawaii's LIHEAP Energy Credit on electric accounts, which Hawaii books as cooling, not only on gas accounts.

Fixes #10733

What and why

The FY2026 Policies and Procedures pay the Energy Credit once per federal fiscal year to the account the household picks: "Gas paid as heating and Electric paid as cooling" (1.4, p. 57), and "An applicant can apply for one utility type, gas or electric" (2.12, p. 61). The FY2026 ACF plan uses the same income limits and subsidized-dwelling size groups for cooling (items 3.1 and 3.5), the matrix prints the flat amounts for both (p. 2), and the FY2026 matrix is headed "H-HEAP HEATING AND COOLING ENERGY CREDIT (EC)". On main, hi_liheap_eligible accepts only a gas bill or gas heat in rent, so households with only an electric account got $0.

The account test becomes:

electric_bill = pre_subsidy_electricity_expense > 0

utilities_in_rent = ~tenant_pays_utilities

responsible = ((gas_bill | electric_bill | utilities_in_rent) & (heating_type != UNSPECIFIED)) | (heat_in_rent & heating_type in (NATURAL_GAS, ELECTRICITY))

The electric route mirrors main's gas route, which accepts any reported heating type. Hawaii lets any household choose the gas or the electric account and asks no cooling-cost question, so the route has no has_cooling_expense condition. This follows Hawaii's text rather than the all-state cooling-only definition, which also requires a cooling cost. Utilities included in the rent qualify too: the draft's Energy Credit offsets "rent or applicant's share of the electric/gas cost when rent includes electric/gas" (p. 55), and the 2026-11-02 ruling on us-hi:liheap-utilities-in-rent follows the draft manual and application. Main applied it to gas in rent only, because only the gas account paid. hi_liheap_subsidized_amount reads hi_liheap_eligible, so the flat $375, $425 and $475 amounts reach subsidized and public-housing households on the electric account with no formula change. The registry note says the credit is paid on the electric account for any eligible household with that bill or with utilities in its rent.

Test plan

Tests were not run locally; CI runs them.

  • YAML tests with expected values from the FY2026 flat amounts (matrix p. 2; size groups in plan item 3.5):
    • Eligibility, new case: households with an electric bill are eligible whether they have no heating, electric heat or propane heat, with or without a cooling cost. They are ineligible without an electric bill or with UNSPECIFIED fuel. Case 1 on main already tests the income limit.
    • Payment, new case: a Honolulu voucher holder with no heating gets $375 with or without a cooling cost, and a public-housing family of three gets $425. A private dwelling is eligible but this output stays $0.
    • Utilities in rent, new cases: a home with no heating whose utilities are in the rent (tenant_pays_utilities false) is eligible with no bill, and an unspecified fuel is not; a Honolulu public-housing tenant aged 70 whose utilities are in the rent gets $375.
    • Heat in the rent, two new rows in Case 4: propane or an unspecified fuel with heat in the rent and no bill is ineligible (rows 11 and 12), so only gas or electric heat in the rent qualifies.
    • The test wage is Hawaii's 2026 minimum wage of $16 (HRS 387-2). The electric bill is $168 a month, the average HCEOC cites from EIA.
  • One existing case changes (two rows). Its inputs are unchanged, and the changed value has a "Was …, now …" comment:
    • Case 4, row 4, an electric-heated home with a $900 electric bill and no gas bill: false to true.
    • Case 4, row 9, electric heat in the rent with no bill: false to true.
    • Case 4 is renamed "the credit needs a gas or electric bill, or gas or electric heat through rent".
  • Source-conflict register: candidate us-hi:liheap-utilities-in-rent (ruled 2026-11-02, draft manual and application over the 2020 manual) now covers the electric account and lists this PR; its manual source also cites the Energy Credit definition (p. 55).
  • make format (ruff)
  • Changelog fragment in changelog.d/

Not modeled

  • Private dwellings still get no dollar award on either account, because the FY2026 statewide value per point is unpublished.
  • Utilities in rent: the size of the household's share has no input, so a household whose utilities are in the rent gets the full flat amount on a subsidized dwelling.
  • A bill paid by a third party outside the home, or a rent-free household sent with utilities in the rent, is not identified (draft 2.12 and 4.2 item 8).
  • Photovoltaic net producers have no input.
  • The FY2027 draft flat amounts ($400, $450, $500) are not encoded.

axiom: TheAxiomFoundation/rulespec-us#2177 queued

🤖 Generated with Claude Code

hua7450 and others added 3 commits November 8, 2026 22:01
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both manuals pay electricity as cooling and let the household choose the
utility credited, so any reported heating type with a gas or electric bill
qualifies, with no cooling-cost condition. Update the main case whose row
changes and drop a duplicate row from the cooling case.

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

codecov Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (aae7f98) to head (2bb2ed7).
⚠️ Report is 169 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main    #10734   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         2    +1     
  Lines           37        39    +2     
=========================================
+ Hits            37        39    +2     
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.

@DTrim99

DTrim99 commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Pay Hawaii's LIHEAP Energy Credit on electric (cooling) accounts

Head reviewed: 09381beb93. First review.

Summary

The core change is right. Hawaii's sources pay the regular Energy Credit on an electric account, at the same flat amounts as a gas account, once a year, with no cooling-cost test. The formula does that, cannot pay twice, and leaves every household that qualified on gas unchanged. CI is green at the head and every new term is pinned by a test.

One item should be addressed before merge: the electric account has no route through rent. The same sentences that the 2026-11-02 ruling follows for gas in rent say "electric/gas", inputs for it exist, and the body's stated reason for the gap is not accurate.

Counts: 0 critical, 1 should, 3 suggestions.

Answers to the Hawaii questions, from the sources:

  • Same flat amounts for gas and electric? Yes. There is one matrix, headed "H-HEAP HEATING AND COOLING ENERGY CREDIT (EC)", with one set of flat amounts: $375, $425, $475. The plan prints the same minimum and maximum for heating (2.6) and cooling (3.6). The formula looks up size only, never fuel.
  • One utility type? Yes. One credit per federal fiscal year, on one account. The formula ORs the two bills into one eligibility flag and pays one amount, so a household with both bills gets one credit.
  • Gas households unchanged? Yes. The head's account test is main's test OR an electric bill, and the amount does not depend on the route.
  • Electric bill enough, with no heating or cooling cost? Yes. Hawaii requires "a current electric or gas bill" and asks no cooling question.
  • Subsidized dwellings on the electric account? Paid the same flat amount as on gas. Correct.
  • Utilities in rent on the electric account? The draft manual pays them; the head does not (S1).

Critical

None.

Should address

S1. Electricity included in rent pays $0, while gas in rent pays, and the body's reason for the gap does not hold.

Where.

  • policyengine_us/variables/gov/states/hi/dhs/liheap/hi_liheap_eligible.py:50-54: the rent arm is heat_in_rent & (fuel == types.NATURAL_GAS) only.
  • policyengine_us/tests/policy/baseline/gov/states/hi/dhs/liheap/hi_liheap_eligible.yaml:97-98 and row 9 at line 113: "Electricity in rent is not gas", expecting false.
  • PR body, "Not modeled", second bullet, and "Source-conflict register: not applicable".

Governing text. Every sentence the gas-in-rent route rests on names both utilities:

  • Energy Credit definition (FY2026 packet p. 55): "a one-time only assistance paid to the residential utility company account of an eligible household to help offset the energy costs for heating or cooling of the household, or to offset rent or applicant's share of the electric/gas cost when rent includes electric/gas or is prorated amongst units on a shared meter."
  • Draft 2.1 (p. 58): "The applicant or an adult household member shall be responsible for paying the utility bill to the utility company, or the household's prorated share of the utility bill if rent includes utilities or the bill is prorated amongst units."
  • Draft 4.2 item 8 (p. 65): the same wording.
  • 2026 application, question 23 (p. 4): "Does rent/mortgage include electric/gas service?"
  • The accepted FY2027 plan puts the policy under cooling as well as heating. Item 3.3 (p. 12): "Verification from landlord or property manager about how utilites are charged and attestation that the renter's utility will be offset by the credit until exhausted."

The backlog entry us-hi:liheap-utilities-in-rent was ruled on 2026-11-02: "follow the draft manual and application." Its question and example cover gas only, because main modeled only the gas account. This PR makes the electric account a paying account, so the same ruling now reaches electricity, and the head departs from it there without a record.

The body's reason. The body says "no input marks electricity in rent when the heat is not electric." Two inputs do:

  • tenant_pays_utilities (household, default true; false means utilities are included in rent). Merged Indiana EAP reads it for exactly this: electric_in_rent = ~spm_unit.household("tenant_pays_utilities", period) (policyengine_us/variables/gov/states/in/ihcda/eap/in_eap.py:44). Georgia LIHEAP reads it too.
  • heat_expense_included_in_rent with heating_type ELECTRICITY, which the body itself names and then leaves at $0.

Households.

Household (period 2026) Draft manual Head
(a) One person aged 70, public housing in Honolulu, Social Security $18,000, heating_type NONE, tenant_pays_utilities false, no separate electric or gas bill Eligible; size 1 flat amount $375 responsible false, $0
(b) The same person with heating_type ELECTRICITY and heat_expense_included_in_rent true, no bills Eligible; $375 false, $0 (Case 4 row 9)
(c) Household (b) with NATURAL_GAS instead Eligible; $375 true, $375

Household (a) is the candidate's own example with electricity in place of gas. Every home has electric service, so "all utilities in the rent" always includes electricity; that was not true of gas, which is why the gap did not matter on main.

Why this is a should and not a critical. The body discloses the gap, the 2020 manual reads the other way ("Households where all utilities are included in the rent" are ineligible, p. 9), and the choice between those sources is a recorded ruling. What is missing is either the code or the record for the electric side.

Fix. Either:

  • Encode it (preferred, since the ruling already picks the source). For example:
    utilities_in_rent = ~spm_unit.household("tenant_pays_utilities", period)
    rent_fuel = (fuel == types.NATURAL_GAS) | (fuel == types.ELECTRICITY)
    responsible = (
        (gas_bill | electric_bill | utilities_in_rent) & (fuel != types.UNSPECIFIED)
    ) | (heat_in_rent & rent_fuel)
    Flip Case 4 row 9 to true, add a row for household (a), and add a subsidized-amount row expecting $375. Each new term needs a row that fails without it.
  • Or keep the gap and record it. Extend us-hi:liheap-utilities-in-rent (question, readings and example) to the electric account, with the reason for stopping at gas. Correct the body's "no input" sentence and the "Source-conflict register: not applicable" line. Reword the Case 4 comment: "Electricity in rent is not gas" was the reason when only gas paid, and it no longer explains row 9.

Either way, update rulespec-us#2177 (interpretation 5, which says "The text does not settle whether such households are paid on the electric account", and companion test 7).

Suggestions

G1. The FY2027 plan is accepted, and period 2027 pays the FY2026 amounts on both accounts.

  • The FY2027 plan reads "Submission Accepted by CO (Revision Basic prototype #1)" and was posted 2026-11-04. Items 2.6 (p. 11) and 3.6 (p. 14) print "Minimum Benefit $400 Maximum Benefit $1,400". Cooling runs 03/01/2027 to 09/30/2027 (p. 4). Item 3.5 (p. 13) adds households that "have no rent or mortgage expense" to the flat-rate group.
  • The body calls the FY2027 amounts "draft". The $400 minimum is no longer a draft. The $450 and $500 amounts appear only in DHS's own packet, status "Saved" (p. 56); the Clearinghouse has no FY2027 matrix yet.
  • At the head, a one-person voucher household with an electric bill gets $375 in period 2027; the accepted plan's minimum is $400.
  • The PR claims FY2026 only and the registry entry has no verified_years, so this is a suggestion, as it was on Add Hawaii LIHEAP regular heating eligibility and subsidized-dwelling benefit #10614. Update the body's wording now, and encode FY2027 or end-date the FY2026 values in a follow-up.

G2. Add a row with both bills.

  • No test with a hi_liheap_subsidized_amount output has both gas_expense and pre_subsidy_electricity_expense above zero. Subsidized Cases 1-3 pin electricity to 0, and Case 5 has no gas.
  • The formula cannot pay twice as written, so nothing is wrong today. A row would pin the one-credit rule (2.12) against a later rewrite that sums per-account amounts.
  • Example: one voucher holder in Honolulu, heating_type NATURAL_GAS, gas $900, electric $2,016, wages $33,280. Expected: eligible, $375.

G3. Housekeeping.

  • hi_liheap_subsidized_amount.yaml:355: "Plan 3.5 (page 13) gives cooling the same flat amounts". Plan 3.5 prints the three size groups with no dollars. The dollars are on matrix p. 2, and plan 3.6 (p. 14) gives the $375 minimum. The PR body words this correctly.
  • hi_liheap_eligible.py: the formula comment and the new test comments rest on "application Q17", but reference has no application link. Consider adding https://humanservices.hawaii.gov/bessd/files/2026/06/2026-Application-Packet.pdf#page=4.
  • hi_liheap_eligible.py:11: # PDF pages 5,9,12 drops the spaces the line below it keeps (# PDF pages 1, 3).
  • rulespec-us#2177 says the tests "have not yet passed in CI at this head". They have now.

Verified correct

1. Hawaii pays its regular benefit on an electric account in FY2026. No source conflicts on this point.

  • Draft 1.4 (packet p. 57): "for the purpose of providing EC assistance to eligible households. Gas paid as heating and Electric paid as cooling." The 2020 manual has the same sentence (p. 4).
  • Draft 4.2 item 4 (p. 65): "The household shall submit a current electric or gas bill."
  • Plan 1.1 (p. 4): cooling assistance 03/01/2026 to 09/30/2026, the same dates as heating.
  • Plan 1.2 (p. 4): read in order, the allocation column gives heating 5%, cooling 50%, year-round crisis 15%, weatherization 10%, carryover 10% and administration 10%, which total 100%. The text layer prints the values one row above their labels. Cooling is the larger share of the regular benefit.
  • Application p. 1: "provides heating and/or cooling assistance to needy households by assisting with a one-time payment toward their electric or gas bill."
  • This is the regular benefit. Crisis (ECI) is a separate component, and 2.12 bars receiving both.

2. The amount is right for an electric account.

  • Matrix p. 2: "H-HEAP HEATING AND COOLING ENERGY CREDIT (EC) ... Household size 1-2 $375; Household size 3-5 $425; Household size 6 or more $475." There is no cooling column and no bill cap.
  • Plan 2.6 (p. 10) and 3.6 (p. 14) both print "Minimum Benefit $375 Maximum Benefit $1,400".
  • hi_liheap_subsidized_amount is where(subsidized, p.subsidized_amount.calc(size), 0). It has no fuel key, so a NONE-heated home reaches no lookup that could miss.

3. The new condition, term by term.

Term Rule Verdict
pre_subsidy_electricity_expense > 0 4.2 item 4, a current electric bill Matches
No has_cooling_expense The application asks only which bill (Q17). Air conditioning is collected as performance data only (2.11 item 5, p. 61) Wider than the shared sibling pattern, and sourced
Any reported heating_type 2.12 lets any applicant pick either account; main's gas route already works this way Matches
heating_type UNSPECIFIED pays $0 Convention from #9754, not a Hawaii rule; pinned by Case 5 row 6 Accepted across the wave
Subsidized housing Flat rate for "Public Housing, Rent Subsidy" (matrix p. 2) Matches; same read as the gas route
Electricity in rent Draft 2.1, 4.2 item 8 Not paid: S1
Photovoltaic net producers, third-party payers 2.12 ineligible households 4 and 6 No input; disclosed for PV

4. No double payment, and gas results are unchanged.

  • 2.12 (p. 61): "an eligible household can only receive one payment per federal fiscal year." "An applicant can apply for one utility type, gas or electric. Once approved, benefits cannot be transferred from one utility type to the other." "There is no splitting or sharing of benefits among different accounts." Application Q17: "I would like assistance with my bill for (Check only one): Electric / Gas".
  • Main: (gas_bill & fuel != UNSPECIFIED) | (heat_in_rent & fuel == NATURAL_GAS). Head: ((gas_bill | electric_bill) & fuel != UNSPECIFIED) | (heat_in_rent & fuel == NATURAL_GAS). The head is main's test plus one OR term, so nothing that was true becomes false.
  • One eligibility flag feeds one amount, so both bills give one credit. Nothing else reads either variable at the head.
  • Existing expectations in the two changed test files are unchanged apart from Case 4 row 4.

5. The one changed expectation is intended. Case 4 row 4: ELECTRICITY, electric $900, gas $0, income $20,000. (false OR true) AND true gives true. Was false on main.

6. Mutation check. Every new term has a row that fails without it.

Change Row that fails
Drop electric_bill Case 4 row 4; Case 5 rows 1-4; subsidized Case 5
Add a has_cooling_expense condition Case 5 row 4; subsidized Case 5 unit 3
Let cooling cost alone qualify, without a bill Case 5 row 5
Restrict the electric route to NONE heating Case 5 rows 2-3; Case 4 row 4
Move electric_bill outside the UNSPECIFIED gate Case 5 row 6
Move gas_bill outside the gate Case 4 row 6

7. Non-residents. hi_liheap_eligible is gated to Hawaii and the new term reads an ungated float. The amount scale has a 0 bracket, so size 0 is a valid key. Case 1 has a California row and passes.

8. Periods. Every variable read by the new term is annual. The PR keeps options=[ADD] on the ssi read as main has it; #10730 removes it in a different hunk.

9. Registry. The Hawaii note in programs.yaml:1109 matches the code: gas or electric account, subsidized flat benefit, points only for private dwellings. Cooling is removed from the out-of-scope list. No verified_years is claimed. The LIHEAP coverage line is untouched.

10. National total. #10730's gov.hhs.liheap.regular_payments already lists hi_liheap_subsidized_amount. This PR adds no variable, so there is nothing to add.

Hand-checked expectations (limits and amounts from matrix pp. 2-3):

Case Arithmetic Result
Eligible Case 4 row 1 NATURAL_GAS, gas 900: (T or F) and T true ✓
row 2 NATURAL_GAS, no bill, no rent false ✓
row 3 NATURAL_GAS in rent true ✓
row 4 ELECTRICITY, electric 900: (F or T) and T true ✓ (changed)
row 5 PROPANE, bottled gas only false ✓
row 6 UNSPECIFIED, gas 900: T and F false ✓
rows 7, 8, 10 Gas 900 with NONE, ELECTRICITY, and ELECTRICITY in rent true ✓
row 9 ELECTRICITY in rent, no bills false per the code; see S1
Eligible Case 5 rows 1-4 Electric 168 x 12 = 2,016 > 0; fuel NONE, ELECTRICITY, PROPANE, NONE without cooling; 20,000 ≤ 41,941 true ✓
row 5 NONE, electric 0, cooling cost true false ✓
row 6 UNSPECIFIED, electric 2,016 false ✓
Subsidized Case 5 unit 1 16 x 2,080 = 33,280 ≤ 41,941; voucher; size 1 375 ✓
unit 2 Same, no voucher eligible, 0 ✓
unit 3 As unit 1, no cooling cost 375 ✓
unit 4 Three people, 33,280 ≤ 67,751; public housing; size 3 425 ✓

Citations checked against the documents.

Claim Found
Body: 1.4, p. 57, "Gas paid as heating and Electric paid as cooling" ✓ packet p. 57
Body: 2.12, p. 61, "An applicant can apply for one utility type, gas or electric" ✓ packet p. 61
Body: matrix headed "H-HEAP HEATING AND COOLING ENERGY CREDIT (EC)", flat amounts on p. 2 ✓
Plan 3.1-3.3 on p. 12; 3.5 on p. 13 ✓
Variable comments: plan pages 5, 9, 12 and 10, 13; draft manual pages 57-58, 60-61, 65, 67 ✓
Application Q17 and Q23-24 ✓ application p. 4
$16 minimum wage from 2026 (HRS 387-2) ✓
$168 average monthly electric bill, HCEOC citing EIA 2019 ✓ HCEOC energy page

Not checked: the Yes/No answers to plan items 2.2, 2.3, 3.2 and 3.3 are check boxes that are not in the PDF text layer, and I did not view page images. The FY2026 plan prints no description under any of them, which is consistent with "No".

Other checks.

Axiom line assessment

axiom: TheAxiomFoundation/rulespec-us#2177 queued is valid.

  • The issue is OPEN, labelled pe-parity, and names head 09381beb93.
  • It is dispatch-ready: module paths, corpus citations, verbatim source text, required outputs, and 11 companion tests derived from the sources.
  • Its required outputs match the head's formula term for term, and its interpretations list matches the body's gaps.
  • If S1 changes the code, update the eligibility output, companion test 7 and interpretation 5. Its "not yet passed in CI" sentences are now out of date (G3).

CI status

Green: 39 checks pass and 3 workflow placeholders are skipped, on run 43153832766 at head 09381beb93.

The PR's own test files ran at this head in the selective-test job: hi_liheap_eligible.yaml 5 passed and hi_liheap_subsidized_amount.yaml 5 passed. The run of all six Hawaii LIHEAP test files also passed. No local run was needed.

Branch status

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 one change. Now that the electric account pays, a household with electricity in its rent gets $0 while gas in rent pays, although the draft manual sentences the 2026-11-02 ruling follows say "electric/gas", and tenant_pays_utilities is available as an input. Please either encode the electric side or extend us-hi:liheap-utilities-in-rent to cover it and correct the body's "no input" sentence (Should Address 1 in the report above).

The core change is right: one flat credit on either account, no double payment, gas results unchanged, and every new term is pinned by a test. The three suggestions are optional. CI is green at 09381beb93.

… rent

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

hua7450 commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks, David. Encoded in 6983cd97c9, as the 2026-11-02 ruling already picks the draft manual and application:

  • responsible now also opens on ~tenant_pays_utilities for any known fuel, and on heat in the rent for NATURAL_GAS or ELECTRICITY.
  • Case 4 row 9 (electric heat in the rent, no bill) flips to true with a "Was false, now true" comment. A new eligibility case covers a home with no heating whose utilities are in the rent (true) and an unspecified fuel (false). A new subsidized-amount case pays a Honolulu public-housing tenant aged 70 with utilities in the rent $375.
  • us-hi:liheap-utilities-in-rent now covers the electric account (question, readings, example, note) and lists this PR. The body's "no input" sentence and the register line are corrected, and LIHEAP cooling: encode Hawaii H-HEAP Energy Credit on electric (cooling) accounts (PE-US PR 10734) TheAxiomFoundation/rulespec-us#2177 (interpretation 5, companion test 7) is updated.

Tests were not run locally.

@hua7450
hua7450 requested a review from DTrim99 November 12, 2026 17:10
@DTrim99

DTrim99 commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator

PR Review (round 2): Pay Hawaii's LIHEAP Energy Credit on electric (cooling) accounts

Head reviewed: 6983cd97c9 (round 1 was at 09381beb93). One fix commit since round 1, no merge of main.

Summary

The round-1 finding is fixed. Utilities in the rent and electric heat in the rent now qualify, each new term has a row that fails without it, and the three new or changed expectations are right by hand. The backlog entry, the PR body and the queued Axiom issue now say the same thing as the code. CI is green at the new head and both changed test files ran there.

One new item should be addressed before merge, and it is a one-row fix. Flipping Case 4 row 9 to true was correct, but that row was the only one where heat in the rent gave false. No row now fails if the rent arm's fuel condition is removed.

Nothing that was eligible at round 1 or on main loses eligibility or changes amount. A household that does not send tenant_pays_utilities gets the round-1 result, except electric heat in the rent, which is the intended change.

Counts: 0 critical, 1 should, 3 suggestions.

How each claim below was established: the formula and mutation results are hand traces of the head's code against the test rows ("by my reading"); I ran no test locally. Source quotes come from the documents themselves, downloaded and read for this round. CI results come from the job log. Merge results come from merges I ran.

Prior findings

Finding Status Evidence
S1. Electricity included in rent pays $0 while gas in rent pays; the body's reason for the gap does not hold Fixed (encoded, the preferred option) Code. hi_liheap_eligible.py:54-58 adds utilities_in_rent = ~spm_unit.household("tenant_pays_utilities", period) inside the known-fuel gate, and the rent arm accepts NATURAL_GAS or ELECTRICITY. Tests that fail without the fix (by my reading). Case 4 row 9 (electric heat in rent, no bill, now true) pins ELECTRICITY in the rent arm. Eligibility Case 6 row 1 and subsidized-amount Case 6 ($375) pin utilities_in_rent. Case 6 row 2 (UNSPECIFIED, false) pins the gate on the new term. Round-1 households. (a) now $375, (b) now eligible and $375, (c) unchanged at $375. Record. us-hi:liheap-utilities-in-rent covers the electric account and lists this PR; see "The ruling record" below. Body. The "no input" sentence is gone, "Not modeled" now says only that the size of the share has no input, and the register line names the candidate. Axiom issue. Required output, inputs, interpretation 5 and companion test 7 are updated, and test 12 is new.
G1. FY2027 plan is accepted; body calls the FY2027 amounts "draft" Not taken (optional) Body wording unchanged.
G2. Add a row with both bills Not taken (optional) No amount row has both a gas and an electric bill.
G3. Housekeeping (plan 3.5 comment, application link in reference, page-comment spacing, CI sentence in the issue) Not taken (optional) All four are as they were. The issue's CI sentence was true again when it was rewritten for the new head.

New findings

Critical

None.

Should address

N-S1. The rent arm's fuel condition is no longer pinned by any test.

Where.

  • policyengine_us/variables/gov/states/hi/dhs/liheap/hi_liheap_eligible.py:55-58: rent_fuel = (fuel == NATURAL_GAS) | (fuel == ELECTRICITY) and ... | (heat_in_rent & rent_fuel).
  • policyengine_us/tests/policy/baseline/gov/states/hi/dhs/liheap/hi_liheap_eligible.yaml:105 and :115 (Case 4).

What. At round 1, row 9 (electric heat in rent, no bill, false) was the only row with heat in the rent and a false result. It was the row that failed if the fuel test was dropped from the rent arm. The fix flips it to true, which is right, and adds no replacement. Every row at the head with heat_expense_included_in_rent true has gas or electric heat and expects true: Case 4 rows 3, 9 and 10, and subsidized-amount Case 3 unit 1 (which also has a gas bill).

Mutation. Replace heat_in_rent & rent_fuel with heat_in_rent. By my reading, all 12 cases in the two changed test files still pass. I did not run it.

Household the mutant gets wrong, unnoticed. One person in Hawaii, period 2026, income $20,000, heat_expense_included_in_rent true, heating_type UNSPECIFIED, no gas or electric bill, tenant_pays_utilities not sent.

  • Head: false. This matches main and the convention that UNSPECIFIED pays nothing.
  • Mutant: true.

This is an ordinary input, not a corner. The heating_type documentation says UNSPECIFIED "is also the right value when heat is included in rent and the fuel is unknown". The same mutant also pays propane, fuel oil and no-heating homes with heat in the rent and no bill, which were false on main and are false at the head.

The inclusion side is pinned: dropping ELECTRICITY from rent_fuel fails row 9, and dropping NATURAL_GAS fails row 3.

Fix. Add two rows to Case 4 or Case 6, both with heat in the rent, no bills and tenant_pays_utilities left at its default:

  • heating_type UNSPECIFIED: false.
  • heating_type PROPANE: false.

Optional third row: PROPANE with tenant_pays_utilities false, expecting true. Case 6 shows "any known fuel" for NONE only.

Suggestions

N-G1. The utilities-in-rent term takes the flag at its word: it checks neither rent nor tenure.

  • hi_liheap_eligible.py:54 reads tenant_pays_utilities alone. A household that sends it false with a known fuel is eligible whether or not it pays any rent.
  • Households that do not send it are unaffected. The input defaults to true, nothing in this repository sets it, and ~true is false.
  • Owners. The input's documentation says owners "stay true", so a correctly built owner household is unchanged. An owner sent with false is treated as having utilities in the housing payment. Hawaii's application does ask owners this ("Does rent/mortgage include electric/gas service?", and whether a maintenance fee includes utilities, application p. 4, questions 22-23), so that reading is defensible.
  • No housing cost at all. This is the case the draft excludes. Draft 4.2 item 8 (packet p. 65): "If the utility bill is paid by a third party not in the household, the household shall not be eligible." Draft 2.12, ineligible household 4 (p. 61): "A household in which electric and/or gas utility bill are paid for by a third-party outside of the home". A household sent with the flag false, no rent and no bill is eligible at the head, and gets $375 to $475 if it is also flagged subsidized.
  • Why this is a suggestion. It needs a caller to send "utilities are in the rent" with no rent, which contradicts itself. Main's gas-in-rent arm has the same shape and was accepted on Add Hawaii LIHEAP regular heating eligibility and subsidized-dwelling benefit #10614. The dollar output is limited to subsidized dwellings. The PR's own two new cases and the candidate's example send no rent either.
  • Options. Say in the formula comment or under "Not modeled" that a third-party payer and a rent-free household are not identified (the Axiom issue's interpretation 4 already says so). Or require a housing payment, as merged Georgia LIHEAP does (rent > 0) and Indiana EAP does (a minimum rent), and send rent in the two new cases. A rent-only guard would leave out the owner whose maintenance fee includes utilities, so the comment is the lighter choice.

N-G2. The candidate quotes a page its sources list does not cite.

  • source_conflicts/candidates.yaml, entry us-hi:liheap-utilities-in-rent: readings.statute now quotes the Energy Credit definition, which is on packet p. 55. The manual source still reads "sections 2.1 and 4.2, model plan packet PDF pages 58 and 65" with a #page=58 link.
  • Add the definitions section and page 55 to that citation, or add a second source row.
  • The same page is missing from the page list in hi_liheap_eligible.py:15-16 ("PDF pages 57-58, 60-61, 65, 67"), although the formula comment now rests on the definition.
  • hi_liheap_eligible.yaml:142-143 attributes the sentence "the household's prorated share of the utility bill if rent includes utilities" to "the draft's Energy Credit definition and 2.1". The sentence is 2.1's (and 4.2 item 8's); the definition uses different words.

N-G3. Leftovers in rulespec-us#2177 and the registry note.

The issue's operative parts match the head. Four descriptive passages under "Why queued" and "PolicyEngine implementation" were not updated:

  • Scope still lists "an electric share of utilities paid through rent" as out of scope. The required output now includes it. If the size of the share is meant, say so.
  • Variables describes only the electric-bill term and says "no new input". The formula now also reads tenant_pays_utilities, which the Inputs line lists.
  • Tests says five cases in each file and one changed row. Each file has six cases, and Case 4 has two changed rows.
  • Why queued says "The PR has no review yet, and CI has not yet run its tests at this head." It has been reviewed once, and CI has now passed at 6983cd97c9.

Optional: a companion test for eligibility Case 6 (no heating, utilities in the rent, private dwelling: eligible; UNSPECIFIED: not). Test 12 covers only the public-housing variant.

The Hawaii note in programs.yaml:1109 still says "for any eligible household with that bill". It is not wrong, but it does not mention utilities in the rent.

Verified

1. The formula at the head, term by term (hand trace of hi_liheap_eligible.py:45-59).

responsible = ((gas_bill | electric_bill | utilities_in_rent) & (fuel != UNSPECIFIED)) | (heat_in_rent & (fuel is NATURAL_GAS or ELECTRICITY))

Term Rule Verdict
~tenant_pays_utilities, read as spm_unit.household(...) for the year Draft 2.1 and 4.2 item 8: "or the household's prorated share of the utility bill if rent includes utilities"; Energy Credit definition, p. 55; application Q23 Matches. A household-level yearly boolean projected to the SPM unit, the same way is_in_public_housing is read in the amount variable. Every SPM unit in the household gets the household's value.
Flag not sent Default true utilities_in_rent false; result as at round 1
Known-fuel gate on the new term UNSPECIFIED pays nothing (wave convention) Inside the gate; Case 6 row 2
Heat in rent with ELECTRICITY Definition: "when rent includes electric/gas" Matches; Case 4 row 9
Heat in rent with PROPANE, another fuel, NONE or UNSPECIFIED, no bill, flag true Unchanged from main Still false by my reading; not pinned (N-S1)
No rent or tenure check on the new term 4.2 item 8, 2.12 item 4 N-G1

2. Nothing eligible before becomes ineligible, and no amount changes.

  • The head's account test is the round-1 test with two terms added by OR: utilities_in_rent inside the gate, and ELECTRICITY in the rent arm. Nothing true can become false.
  • hi_liheap_subsidized_amount is unchanged since round 1: where(subsidized, flat amount by size, 0). The amount depends only on qualified size and the subsidized test.
  • The other four Hawaii LIHEAP variables and all parameters are unchanged since round 1.

3. The amount still needs a subsidized dwelling, and a private dwelling gets what Hawaii's rules give it.

  • Matrix p. 2: the flat rate is for "Public Housing, Rent Subsidy, or Photovoltaic (PV) Households"; "EC PD households are awarded points". The draft defines subsidized housing as rent "based on the amount of the tenant's income" (p. 56).
  • An unsubsidized household with utilities in the rent is therefore a private dwelling. At the head it is eligible (Case 6 row 1) and this output is $0. The body says private dwellings get no dollar award because the value per point is unpublished, and claims nothing more.
  • hi_liheap_points is unchanged. Its energy-burden point needs an electric bill, and the draft defines energy burden on a bill "paid by the household to the utility company" (p. 55), so a household with utilities in the rent earns no burden point.

4. One credit a year. One eligibility flag feeds one amount. A household with a bill and utilities in the rent, or both rent routes, gets one credit. Nothing else at the head reads either variable.

5. Mutation check on the new terms (by my reading; not run).

Change Row that fails
Drop utilities_in_rent Eligibility Case 6 row 1; subsidized Case 6
Drop the ~ Case 4 row 2 (turns true); Case 6 row 1 (turns false)
Move utilities_in_rent outside the UNSPECIFIED gate Case 6 row 2
Drop ELECTRICITY from rent_fuel Case 4 row 9
Drop NATURAL_GAS from rent_fuel Case 4 row 3
Drop rent_fuel altogether None (N-S1)

6. Hand-checked expectations (limits and amounts from matrix pp. 2-3; one-person limit $41,941).

Case Trace Result
Eligibility Case 4 row 9 (changed) ELECTRICITY, heat in rent, no bills, flag default. Gate group: (F or F or F) and T = F. Rent arm: T and (F or T) = T. Income 20,000 ≤ 41,941 true ✓
Case 4 rows 1-8 and 10 (unchanged values, new formula) Rows 1, 7, 8, 10 gas bill with a known fuel; row 3 gas in rent; row 4 electric bill; rows 2 and 5 no bill, no rent route, flag default; row 6 UNSPECIFIED T, F, T, T, F, F, T, T, T ✓
Case 5 rows 1-6 (unchanged) Rows 1-4 electric bill 2,016; row 5 no bill, flag default; row 6 UNSPECIFIED T, T, T, T, F, F ✓
Case 6 row 1 (new) NONE, flag false, no bills: (F or F or T) and T true ✓
Case 6 row 2 (new) UNSPECIFIED, flag false: T and F = F; no heat in rent false ✓
Subsidized Case 6 (new) Aged 70, citizen by default, size 1. Social Security 18,000 ≤ 41,941. NONE, flag false, gas and electric default to 0: responsible. Public housing, size 1-2 eligible, $375 ✓

Subsidized Case 6 does not pin SNAP. The household passes the income test, so SNAP receipt cannot change the result.

7. Quotes and pages in the fix commit, checked against the documents.

Claim Found
"rent or applicant's share of the electric/gas cost when rent includes electric/gas" (Case 4 comment, candidate, subsidized Case 6) ✓ packet p. 55, Energy Credit definition
"the household's prorated share of the utility bill if rent includes utilities" ✓ p. 58 (2.1) and p. 65 (4.2 item 8)
Application Q23 asks whether rent includes "electric/gas service"; Q17 "Check only one: Electric / Gas" ✓ application p. 4
2020 manual: "Households where all utilities are included in the rent" ✓ p. 9, item g
Plan 2.3 "Renters with utilities included in the rent?" ✓ plan p. 9. The Yes/No answer is a check box outside the text layer; I did not view the page image. The entry's "No" is unchanged from main.
Flat amounts $375, $425, $475 ✓ matrix p. 2

The draft also backs the route in a place the PR does not cite. Section 2.5 (p. 60): "If the subscriber is a realty company, realtor, organization, or management company, and the rent includes utilities, or the bill is prorated amongst units, the Landlord Agreement and Verification Form must be completed."

8. The ruling record.

Fields of us-hi:liheap-utilities-in-rent at the head, against CONTRIBUTING.md "Source conflicts", step 1:

Field At the head
id, program us-hi:liheap-utilities-in-rent, liheap
years 2026 to 2026, federal-fiscal
question Now "gas or electricity"; was "gas"
sources Four, unchanged: draft manual pp. 58 and 65, application p. 4, 2020 manual p. 9, plan p. 9. All four links open and show the text.
readings statute adds the Energy Credit definition quote; other unchanged
example "gas or electricity in the rent receives $375 under the draft manual and $0 under the 2020 manual"; matches subsidized Case 6
pe_us.follows gap-fill, unchanged
pe_us.code hi_liheap_eligible.py, a tracked file
pe_us.prs #10614 and #10734
state ruled, unchanged
note The ruling sentence is intact: "Ruled 2026-11-02: follow the draft manual and application." A new sentence attributes the electric account to this PR.

No marker is added, which is right at this step. The guard test passed in CI at the head.

Is extending a ruled entry's question consistent with the ruling? Yes, in my reading. The ruling chooses between sources, not between fuels: "follow the draft manual and application". Both sides of the conflict are fuel-neutral. The draft says "if rent includes utilities" and "when rent includes electric/gas", the application asks about "electric/gas service", and the 2020 manual excludes households where "all utilities" are in the rent. The question said "gas" only because main paid only the gas account. This PR opens the electric account, and the same sentences then decide the same question for it. That is the same conflict and the same choice, not a new one, and step 1 tells a PR to update an existing backlog item. The note keeps the ruling's words apart from the PR's application of them.

It does not need a new ruling. Because the question of an entry marked ruled was reworded after the ruling, the project lead should see the new wording at merge. I recommend that as a confirmation and do not make it a condition.

9. Guards. The edited comments in hi_liheap_eligible.py contain none of the conflict-sounding phrases the source-conflict ratchet counts, and no Hawaii LIHEAP file is in its known-unmarked list. The PR touches no income list and no partner contract test.

10. PR body. The formula in the body matches the head. The changed rows (Case 4 rows 4 and 9) and the new cases are disclosed. The changelog fragment is updated to match.

Axiom

axiom: TheAxiomFoundation/rulespec-us#2177 queued is valid.

  • The issue is OPEN, labelled pe-parity, was updated at 17:10 UTC on 2026-11-12 and names head 6983cd97c9.
  • Its required output matches the head term for term: a gas or electric bill with a known heating_type, "or tenant_pays_utilities false (utilities in the rent) with heating_type other than UNSPECIFIED, or else heat_expense_included_in_rent with heating_type NATURAL_GAS or ELECTRICITY".
  • The Inputs line lists tenant_pays_utilities. Companion test 7 now expects true, test 12 is the public-housing case at $375, interpretation 5 describes the ruling applied to both accounts, and the delivery checklist names both rent cases.
  • Four descriptive passages lag behind (N-G3). They do not change what an encoder is asked to build.

CI

Run 43266409441 at head 6983cd97c9: 38 checks pass and none fail. One status is still pending: codecov/project, the external coverage report, which runs no tests.

The PR's own test files ran at this head in the selective-test job: hi_liheap_eligible.yaml 6 passed and hi_liheap_subsidized_amount.yaml 6 passed. The run of all six Hawaii LIHEAP test files passed too. The author did not run tests locally, and neither did I; CI is the only run.

Branch

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 one change, a two-row test fix. The round-1 finding is fixed: utilities in the rent and electric heat in the rent now qualify, each new term has a row that fails without it, and the backlog entry, the description and rulespec-us#2177 match the code.

Flipping Case 4 row 9 to true was right, but that row was the only one where heat in the rent gave false. Every row with heat in the rent now has gas or electric heat and expects true, so by my reading heat_in_rent & rent_fuel can be replaced with heat_in_rent and no test fails; that would pay a home with heat in the rent and an UNSPECIFIED or propane fuel. Please add those two rows, both expecting false (New finding N-S1 in the report above).

Three optional suggestions are in the report. One for the project lead to see at merge: the question of the ruled entry us-hi:liheap-utilities-in-rent was reworded to cover electricity; I read that as the same ruling applied to the newly opened account, not a new choice. CI is green at 6983cd97c9 apart from the pending coverage status.

Case 4 adds propane and unspecified heat in the rent with no bill, both
ineligible, so dropping the gas-or-electric condition fails a test. Cite the
draft's Energy Credit definition (p. 55) in the candidate and the variable,
attribute the Case 6 quote to 2.1 and 4.2, note that a third-party payer or a
rent-free home is not identified, and mention utilities in the rent in the
registry note.

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

hua7450 commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks, David. In 2bb2ed796c:

  • N-S1. Case 4 has two new rows, both with heat in the rent, no bills and tenant_pays_utilities at its default: PROPANE (row 11) and UNSPECIFIED (row 12), both false. Dropping the fuel condition from the rent arm now fails both. I left out the optional third row; Case 6 row 1 already pins the utilities-in-rent term for a known fuel.
  • N-G1. The formula comment and "Not modeled" now say that a third-party payer or a rent-free home is not identified. No rent guard, for the owner reason you give.
  • N-G2. The candidate's manual source and the variable's page list now include the Energy Credit definition (p. 55), and the Case 6 comment attributes the quote to 2.1 and 4.2.
  • N-G3. LIHEAP cooling: encode Hawaii H-HEAP Energy Credit on electric (cooling) accounts (PE-US PR 10734) TheAxiomFoundation/rulespec-us#2177 is updated: scope (the size of the share), variables (tenant_pays_utilities and electric heat in the rent), tests (six cases in each file), the review sentence, interpretation 4 (rent-free household), and new companion tests 13 (the two new rows) and 14 (Case 6). The registry note now mentions utilities in the rent.

No formula changed.

@hua7450
hua7450 requested a review from DTrim99 November 12, 2026 18:51
@DTrim99

DTrim99 commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator

PR Review (round 3): Pay Hawaii's LIHEAP Energy Credit on electric (cooling) accounts

Summary

I read the one commit since round 2, 2bb2ed796c, at the new head. It adds the two rows round 2 asked for, takes all three suggestions, and changes no formula. Nothing is open.

Prior findings

Finding Status Evidence
N-S1: the rent arm's fuel condition was pinned by no test Fixed hi_liheap_eligible.yaml Case 4 has two new rows with heat in the rent, no bills and tenant_pays_utilities at its default: row 11 PROPANE and row 12 UNSPECIFIED, both expecting false. By hand at the head: the bill group is (false or false or false) and the rent arm is true and (not gas, not electric), so both are false. With heat_in_rent & rent_fuel replaced by heat_in_rent, both rows turn true and the case fails (hand trace, not run). All ten input lists and the output list have 12 entries.
N-G1: the utilities-in-rent term checks neither rent nor tenure Taken (comment route) The formula comment and "Not modeled" now say a third-party payer or a rent-free home is not identified. No rent guard, which keeps the owner whose maintenance fee includes utilities.
N-G2: the candidate quoted a page its sources did not cite Taken us-hi:liheap-utilities-in-rent and the variable's page list now include the Energy Credit definition on packet p. 55; the reference link opens at p. 55, the first page in its comment. The Case 6 comment attributes the quote to draft 2.1 and 4.2.
N-G3: leftovers in rulespec-us#2177 and the registry note Taken The registry note now says "with that bill or with utilities in its rent". The issue names head 2bb2ed796c and was updated with the commit.
Round-1 suggestions G1-G3 Not taken (optional) Unchanged.

New findings

Critical: none. Should address: none. Suggestions: none.

Verified

  • No formula change. The only changes under policyengine_us/variables are comment and reference lines in hi_liheap_eligible.py. No parameter changed, and the only test change is the two rows above. Every result from round 2 stands.
  • Existing rows. Rows 1 to 10 of Case 4 keep their inputs and expected values.
  • Guards. The new comment line has none of the wording the source-conflict ratchet counts. The candidate keeps state: ruled and the ruling sentence.

Axiom

axiom: TheAxiomFoundation/rulespec-us#2177 queued is valid: OPEN, labelled pe-parity, updated 2026-11-12 18:51 UTC, and it names head 2bb2ed796c.

CI

At head 2bb2ed796c, 32 checks pass and none fail. Quick Feedback, which runs the changed test file, passed, and so did all four baseline state shards and PR validation. Six checks were still running when I posted this (Contrib (other-shard-1), Contrib (states-shard-1), Contrib (states-shard-2), Contrib (states-shard-3), Contrib (states-shard-4), Contrib (other-shard-3)); they run the contributed-reform tests, not the Hawaii LIHEAP test files.

Branch

12 commits behind main; the merge with main is clean.

Verdict: APPROVE

@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.

Approving. Case 4's two new rows (propane and an unspecified fuel with heat in the rent and no bills, both false) pin the fuel condition on the rent arm, the three suggestions are taken, and no formula changed since round 2.

Quick Feedback, the baseline state shards and PR validation pass at 2bb2ed796c. The six contributed-reform shards were still running when I approved; please let them finish before merging.

@hua7450
hua7450 merged commit 7d1dd52 into main Nov 12, 2026
38 checks passed
@hua7450
hua7450 deleted the hi-liheap-cooling branch November 12, 2026 20:06
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 Hawaii LIHEAP Energy Credit on electric (cooling) accounts

2 participants