Skip to content

Add Delaware LIHEAP summer cooling electric benefit eligibility - #10762

Merged
hua7450 merged 7 commits into
mainfrom
de-liheap-cooling
Nov 13, 2026
Merged

hua7450 merged 7 commits into
mainfrom
de-liheap-cooling

Conversation

@hua7450

@hua7450 hua7450 commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

Adds an eligibility flag for Delaware's Summer Cooling Assistance electric benefit. No amount is modeled, because Delaware splits leftover funds equally among eligible households.

Fixes #10761

Targets main: an eligibility flag with no amount, so nothing is added to the national LIHEAP total.

What and why

The FY2026 plan targets the program to "households with members sixty or older, disabled, children five and under, and members that suffer from chronic breathing conditions" (item 3.3, p. 12). It says "everyone who is eligible, receives the same amount" (3.4) and that the benefit "is calculated equally between all the eligible households" (3.5, p. 13). The FY2027 plan repeats these provisions (pp. 11-12). DHSS says "Eligibility requires prior application for LIHEAP during the program year". The historical DEAP manual's SCAP chart defines LIHEAP eligibility as "Purchase Source of Heating or Cooling" (p. 100), and plan item 3.3 sets no cooling policy for subsidized renters or renters with utilities in the rent. Section 415 of the same 2015 manual asks for a heating bill for "cooling electric"; this PR follows the current plan and the chart, as it already does on the manual's income test, season dates and targeted groups. The choice is recorded as us-de:liheap-cooling-heating-bill (ruled 2026-11-12).

  • New de_liheap_income_eligible holds the household and income test, moved unchanged from de_liheap_eligible, which now reads it.
  • de_liheap_cooling_eligible (bool), true when both hold:
    • de_liheap_eligible (the household buys its heating), or de_liheap_income_eligible, with no heating responsibility test, and has_cooling_expense;
    • a member 60 or older, under 6, or disabled.
  • No amount variable, and nothing is added to the national LIHEAP total.
  • heating_type UNSPECIFIED does not qualify. This is a PolicyEngine convention (callers send heating_type; issue 9754), not a Delaware rule: Delaware's regular heating formula pays unsubsidized heat in rent with an unknown fuel from its electric column. Every known fuel and NONE (no heating) can qualify.
  • No electricity bill is required: every household is assumed to have an active electric account.
  • has_cooling_expense is the route for a household that does not buy its heating: it stands for the purchased source of cooling in the SCAP chart. It is a modeling reading; no Delaware text asks the household to show a cooling cost. A household that buys its heating qualifies without it: the chart reads "Heating or Cooling", and manual 303.2 A processes a current heating applicant's SCAP application automatically.

Test plan

  • YAML tests with expected values worked from the sources above. 13 cases in 1 file: each vulnerable route, the age edges, income over the limit, a home with no heating and a public-housing tenant with heat in the rent who pay for cooling (both eligible though not eligible for heating), no heating bill and no cooling cost, a heating client with no cooling cost (eligible), and UNSPECIFIED fuel with heat in rent.
  • Source-conflict register: new candidate us-de:liheap-cooling-heating-bill (manual 415 against the SCAP chart and plan 3.3; ruled 2026-11-12 for the chart and the plan). us-de:liheap-income-floor-vs-smi-limit now names de_liheap_income_eligible.py, where the federal floor moved.
  • make format (ruff)
  • Changelog fragment in changelog.d/

Not modeled

  • The chronic breathing condition route has no input.
  • Targeted households only. The plans let the State extend the benefit to every LIHEAP applicant when funds allow. HHS profiles count more cooling households than households with a targeted member in FY2023 and FY2024 (10,038 and 9,626 cooling households), and 88 cooling households in FY2025. No 2026 decision was found, so the flag keeps the targeted rule and programs.yaml no longer lists 2026 as verified.

axiom: TheAxiomFoundation/rulespec-us#2175 queued

🤖 Generated with Claude Code

hua7450 and others added 4 commits November 8, 2026 22:06
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every household is assumed to have an active electric account, and no
Delaware rule uses the bill for the flag, so the flag no longer requires a
positive electricity bill. The heating-bill rule that excludes homes with no
heating is in manual section 415, not 416. Tests drop the illustrative
electric bill and the no-bill 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 (3615979).
⚠️ Report is 195 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main    #10762   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         3    +2     
  Lines           37        54   +17     
=========================================
+ Hits            37        54   +17     
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: Add Delaware LIHEAP summer cooling electric benefit eligibility

Reviewed at head 785cf190bd396eb7095a81e53b2fac356d715b06.

Summary

The PR adds one boolean, de_liheap_cooling_eligible, two age parameters, 11 YAML cases and a second Delaware registry entry. It changes no existing variable or test, so no existing result moves. CI is green and every quote and page in the PR body checks out against the FY2026 plan, the FY2027 plan, the DHSS page and the 2015 manual.

The formula has four conditions. One (de_liheap_eligible) is sourced. The other three are narrower than the sources, or rest on a source choice that is not recorded:

  • the vulnerable-member test is the plan's default, which the plan lets the State lift; federal data show cooling reached more households than heating in FY2024, and nothing in the PR shows which rule applied in summer 2026;
  • the heating_type test refuses a household that Delaware's own regular heating formula pays;
  • has_cooling_expense is required with no Delaware source, while the one thing the sources do require (an electric account) is assumed;
  • the heating-bill gate comes from one sentence of a 2015 manual; the same manual's eligibility chart and the current plan's renter answers read differently, and the PR says the source-conflict register does not apply.

No critical findings. Four should-address findings and three suggestions.

Critical (must fix)

None.

Should address

1. The vulnerable-member condition is contingent in the plan, and the latest federal data show Delaware paid beyond it. verified_years: "2026" is not backed for the narrow rule.
policyengine_us/variables/gov/states/de/dhss/liheap/cooling/de_liheap_cooling_eligible.py lines 32-42 and 48; policyengine_us/programs.yaml lines 1161-1162.

  • FY2026 plan, item 3.4 (p. 12): "The cooling assistance is only provided to the vulnerable population, unless there is sufficient funding to extend the eligibility for the assistance to other portions of the population. ... If SCAP Electric assistance is extended to entire eligible population, everyone who has applied for LIHEAP during the program year, will receive the same SCAP Electric benefit." Item 3.3 on the same page: "However, there can be exceptions to the targeted households depending on the availability of funding." The FY2027 plan repeats both (pp. 11-12).
  • The 2015 manual's SCAP eligibility chart (p. 100) applies the age, disability and breathing tests only on the air-conditioner branch. On the payment branch it says: "Eligible for SCAP. Criteria and the amount of LIHEAP SCAP Payment for HHs declared by State and defined by State LIHEAP PM."
  • HHS, LIHEAP FY2024 State Profile, Delaware: "Cooling Assistance served 9,626 households with a reported average benefit of $494"; heating served 8,820; total households served 11,072; households with any vulnerable member (elderly, young child or disabled) 72%. 72% of 11,072 is 7,972. So at least 9,626 - 7,972 = 1,654 cooling households had no elderly, young-child or disabled member. Unless every one of them qualified on a chronic breathing condition alone, the extension was in force in FY2024.
  • The FY2026 plan budgets 20% of funds to cooling, the same as the prior year (item 1.2, p. 4). The FY2026 cooling season ended on 31 August 2026, so the State's 2026 decision already exists.

Household: Delaware, 2026, one adult aged 40, not disabled, wages $20,000, heating_type: NATURAL_GAS, gas_expense: 900, has_cooling_expense: true. de_liheap_eligible is true. Actual de_liheap_cooling_eligible: false. Expected: true in a year the State extends SCAP Electric (as in FY2024); false only if summer 2026 was limited to the targeted groups.

Fix: establish from DHSS which rule applied in summer 2026 (and FY2027 when known). Put the choice in a dated boolean parameter (for example cooling/vulnerable_member_required) so the flag follows each year's declaration. If the 2026 decision cannot be sourced, keep the default but say so in the code comment and the registry note, cite the FY2024 profile, and do not list 2026 as verified. The body's "Not modeled" line discloses the extension, but treats it as the exception; the federal data say it was the rule in the latest reported year.

2. The heating_type test has no Delaware source and refuses a household that Delaware's regular heating formula pays. The PR body's statement about it is not accurate for Delaware.
de_liheap_cooling_eligible.py lines 28-31 and 47; test file .../cooling/de_liheap_cooling_eligible.yaml Case 10 (lines 193-214).

  • FY2026 plan, item 3.5 (p. 13): the cooling electric benefit "is distributed only to the LIHEAP eligible households. Cooling Electric Benefit is calculated equally between all the eligible households." The benefit is flat; no fuel enters it.
  • FY2026 plan, item 2.3 (p. 9): "If heat is in rent and the household pays the entire rent amount, the fuel type for the benefit is determined to be electric." de_liheap_eligible and de_liheap follow this: with heat in rent and no housing subsidy, an UNSPECIFIED fuel is eligible and is paid from the electric column (existing de_liheap_eligible.yaml Case 7).
  • Item 3.3 (p. 12) answers "No" to differing cooling eligibility for "Renters with utilities included in the rent".
  • The PR body says "heating_type UNSPECIFIED pays $0, as in every state LIHEAP program." Delaware's regular heating program pays this household, so the sentence is wrong for the state under review. The test comment concedes the point: "Unsubsidized heat in rent passes de_liheap_eligible with an unknown building fuel, but heating_type is a required input for cooling."

de_liheap_eligible already returns false for an UNSPECIFIED fuel when heat is not in rent, so the new term has exactly one effect: it turns off the heat-in-rent households that regular heating accepts.

Household (Case 10): Delaware, 2026, aged 67, social_security_retirement: 18_000, heat_expense_included_in_rent: true, no housing subsidy, heating_type: UNSPECIFIED, has_cooling_expense: true. de_liheap_eligible is true and de_liheap is $588 (18,000 / 39,342 = 45.8% of the limit, band 4, electric column). Expected cooling flag: true (a LIHEAP-eligible household with a member sixty or older). Actual: false.

Fix: remove heating_type_reported and change Case 10 to true. The UNSPECIFIED convention from #9754 is about not guessing a fuel where the amount or the bill depends on it; here nothing depends on the fuel and the state's own rule supplies one. If the term stays, the body and the comment at line 28 should say it is a PolicyEngine convention with no Delaware source and should not claim it matches Delaware's regular program.

3. has_cooling_expense is required with no Delaware source, while the electric account the sources do require is assumed.
de_liheap_cooling_eligible.py lines 43-44 and 49; test Case 8 (lines 154-171).

  • The comment at line 43 states a rule ("A cooling payment requires a cooling cost paid apart from rent") and cites nothing. The PR body's reason is that this is "the input the all-state cooling work uses".
  • 2015 manual, section 303.1 (p. 21): the purpose is "a benefit paid to their electric company in order to encourage households with elderly and disabled members to use air conditioning". "When an eligible household does not already have air conditioning ... DEAP will purchase, deliver, and install a room sized air conditioner." So a household with no air conditioning is still eligible.
  • Section 303.2 A (pp. 21-22): "If applicant has a current FAP application, the SCAP application is automatically processed via computer." "A benefit will automatically be processed by the sub grantee on behalf of the DEAP client." Under B, the electric companies "review lists for active clients".
  • DHSS Utility Assistance: "Provides a one-time payment to help offset summer electricity costs."
  • FY2026 plan, item 3.4 (p. 12): "everyone who is eligible, receives the same amount".

No source asks the household to show a cooling cost. What the sources need is an active electric account, because the payment goes to the electric company. The PR drops that term ("No electricity bill is required: every household is assumed to have an active electric account") and keeps the unsourced one. The siblings that use has_cooling_expense (FL #10740, DC #10742) pair it with pre_subsidy_electricity_expense > 0; Delaware is the one state whose sources name the electric company, and it is the one that leaves the bill out.

has_cooling_expense is an input with a default of false, so every household that does not set it is ineligible.

Household: Delaware, 2026, aged 67, social_security_retirement: 18_000, heating_type: NATURAL_GAS, gas_expense: 900, pre_subsidy_electricity_expense: 1_200, has_cooling_expense not set. de_liheap_eligible is true. Expected: true (a current heating client aged sixty or older with an electric account is processed automatically). Actual: false.

Fix: gate on the electric bill (pre_subsidy_electricity_expense > 0), which is what the payment mechanism requires, in place of has_cooling_expense; or keep has_cooling_expense alongside it and label it in the comment and body as a modeling interpretation, with the reason. Add or change the test that pins the term kept.

4. The heating-bill gate rests on one sentence of a 2015 manual. The same manual's chart and the current plan read differently, and the PR records no source conflict.
de_liheap_cooling_eligible.py lines 23-27; PR body, "Source-conflict register: not applicable."

  • Followed: 2015 manual, section 415 (p. 32): "applicants must be responsible for paying a heating bill in order to receive assistance for heating, crisis and cooling electric."
  • Same manual, SCAP eligibility chart dated 2/24/2015 and marked FINAL (p. 100): LIHEAP eligibility is "A. Purchase Source of Heating or Cooling".
  • Current plan, item 3.3 (FY2026 p. 12, FY2027 p. 11): for cooling, "Renters Living in subsidized housing?" No, and "Renters with utilities included in the rent?" No. Item 2.3 answers Yes to both for heating. By reading de_liheap_eligible, the cooling flag inherits the two heating policies the plan says cooling does not have.
  • The manual is not the one in force. It is a 2015 bid document. Section 415 itself sets eligibility at "200% of the Federal Poverty Level" (the plan uses 60% of state median income). Plan item 4.2 (p. 14) quotes a current "LIHEAP POLICY MANUAL, SECTION 300" whose crisis text differs from the 2015 file. The PR already sets the manual aside on the income test, the season dates and the targeted groups.

The 2015 manual can fill a gap the plan leaves. It should not settle a point where the plan and the manual's own chart point the other way, without a record of the choice.

Household: Delaware, 2026, public-housing tenant aged 70 (is_in_public_housing: true), social_security_retirement: 14_000, heat_expense_included_in_rent: true, heating_type: NATURAL_GAS, pays its own electric bill, has_cooling_expense: true. de_liheap_eligible is false (subsidized heat in rent). Actual cooling flag: false. Under section 415: false. Under the chart on p. 100 and plan item 3.3: true, because the household buys its source of cooling and the plan has no separate cooling policy for subsidized renters. The same split applies to a home with heating_type: NONE (Case 9), which is rare in Delaware.

Fix: either follow the plan and the chart (LIHEAP income and household eligibility plus an electric account, without the heating-responsibility test), or keep section 415 and record the choice: add a candidate to the source-conflict backlog, name both readings in the comment at lines 23-27, and correct the body line. A test for the subsidized heat-in-rent tenant should pin whichever reading is chosen.

Suggestions

  1. State the "no amount" reasoning accurately. Not modeling an amount is still the right call: I found no published per-household SCAP Electric figure for 2026, and plan item 3.5 declines to print a matrix. But the body's "Delaware splits leftover funds" is not what the plan says. Item 1.2 budgets 20% of FY2026 funds and 10% of FY2027 funds to cooling. Item 3.6 prints a range: "Minimum Benefit $1 Maximum Benefit $1,000" (FY2026 p. 13) and $1 to $1,250 (FY2027 p. 12). In FY2024 cooling was the largest component: $5,082,447 (30% of funds) against $3,919,357 for heating, an average of $494 for 9,626 households. Consider adding the plan range to the registry note and opening a follow-up issue for the amount, since a benefit of this size is absent from Delaware household totals.
  2. Registry years. The new entry says verified_years: "2026" and "FY2026 eligibility only", while both parameter files cite the FY2027 plan and Case 11 tests 2027. Make the entry and the test claim the same years.
  3. Say what stands in for "disabled". The plans do not define it; item 2.3 reads "disability status" from the LIHEAP client record. is_disabled alone is a reasonable stand-in and matches ID, LA and FL, but the comment at lines 32-34 should say it is a stand-in, as it does for the breathing-condition route.

Verified correct

  • Quotes and pages. FY2026 plan: targeting sentence in item 3.3 at p. 12; "everyone who is eligible, receives the same amount" in item 3.4 at p. 12; "calculated equally between all the eligible households" in item 3.5 at p. 13. FY2027 plan: item 3.3 at p. 11, items 3.4-3.6 at p. 12. DHSS page: "Eligibility requires prior application for LIHEAP during the program year", present today. Manual: sections 303-303.2 at pp. 21-22, section 415 at p. 32. All four reference anchors on the variable and both anchors on each parameter open on the cited text. Check boxes on plan pp. 4, 12 and 13 and the chart on manual p. 100 were read from page images.
  • Income limit. Item 3.1 sets cooling at 60% of state median income for all sizes in both plans, the same as heating, so reading de_liheap_eligible gives the right income test.
  • Age thresholds. "sixty or older" is age >= 60. "children five and under" is age < 6; plan item 2.3 (p. 10) scores a member "under 6 years" and one "60 years of age or older", and manual 303.4 says "children under six (6) years of age". Parameter values 60 and 6, units, labels and descriptions are right, and the descriptions follow the house template.
  • Chronic breathing conditions have no input; the gap is disclosed in the body, the comment and the registry note.
  • Hand-checked expectations (11 of 11):
    • Case 1: income at most 18,000 <= 39,342 (one-person limit, published matrix); gas bill 900 > 0; 67 >= 60; cooling cost. True.
    • Case 2: 65,000 less at most about 13,500 of estimated tax (federal about 5,600; payroll 4,973; Delaware about 2,900) leaves about 51,500 > 39,342, and above 1.1 x 15,650 = 17,215. Heating false, cooling false.
    • Case 3: 60 >= 60. True. Case 4: 59, not disabled, no child. False.
    • Case 5: child 5 < 6. True. Case 6: child 6, parent 32. False.
    • Case 7: disabled, aged 40. True.
    • Case 8: has_cooling_expense false. False by the code (see should-address 3).
    • Case 9: heating_type: NONE, no heat in rent, so no heating responsibility. Heating false, cooling false.
    • Case 10: heat in rent, unsubsidized, UNSPECIFIED: heating true; cooling false by the code (see should-address 2).
    • Case 11: 2027, 18,000 is below 60% of state median income for one person. True.
  • Mutation rule. Every term is pinned: de_liheap_eligible by Cases 2 and 9; heating_type_reported by Case 10; the elderly age by Cases 3 and 4; the child age by Cases 5 and 6; the disability route by Case 7; any over members by Case 5; has_cooling_expense by Case 8.
  • No double payment and no changed results. The PR adds a flag and no amount. No existing variable, parameter or test is edited.
  • Other-state rows. defined_for = StateCode.DE; the formula reads two scalar parameters and no keyed lookup, so it evaluates for mixed-state populations.
  • Periods. Every input is annual; no add and no options=[ADD].
  • Registry. A second Delaware implementation under liheap is allowed (labels are unique by name), the variable and the parameter prefix resolve, and eligibility-only entries have precedent (il_fpp_eligible, ca_riv_liheap_eligible). The note describes the flag accurately apart from the points above. The regular Delaware note now points to the new entry.
  • National total. Leaving the flag out of gov.hhs.liheap.regular_payments is right. The registry check that Add a national LIHEAP total, an Illinois regular heating payment and LIHEAP cooling registry notes #10730 adds counts only float variables, so a boolean entry does not trip it.
  • Main-side guards. No income list is touched (Integrate modeled state unemployment insurance into income flows #9558, Count military SBP annuities in state benefit income lists #10317 and Count each Social Security benefit once in Pennsylvania CCW countable income #10408 do not apply). No new comment matches the source-conflict ratchet's patterns (Tie source-conflict markers to the register shared with Axiom #10287).
  • Changelog. changelog.d/de-liheap-cooling.added.md is present with a suitable type.

Axiom line assessment

axiom: TheAxiomFoundation/rulespec-us#2175 queued is valid. The issue is OPEN, labelled pe-parity, names head 785cf190bd, and is dispatch-ready: module paths, corpus status, verbatim source text, required output and nine companion tests derived from the sources. It lists the targeted-only reading, the UNSPECIFIED term ("No Delaware source states this rule") and the cooling-cost term as interpretations, which matches findings 1-3. One sentence is stale ("They have not yet passed in CI at this head"). Any formula change from findings 1-4 needs the issue's required output and companion tests updated in the same round.

CI status

All checks pass at head 785cf190bd (run 43138509945): the baseline and contrib shards, the Python shards, microsimulation, PR validation, Household API Partners and Quick Feedback with full patch coverage. The PR's test file ran in that run.

Branch status

Two commits behind main. The merge with main is clean. The merge is also clean with each sibling today: #10730, #10732, #10734, #10736, #10738, #10740 and #10742. All of them edit policyengine_us/programs.yaml, on different lines.

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 on four points, all about how the new flag's conditions are sourced (Should Address 1-4 in the report above):

  1. The vulnerable-member condition is the plan's default, which item 3.4 lets the State lift. HHS's FY2024 profile shows cooling reached 9,626 households against 8,820 for heating, so verified_years: "2026" needs the summer 2026 rule or a caveat.
  2. The heating_type test turns off an unsubsidized heat-in-rent household that de_liheap_eligible accepts and de_liheap pays, and the body's "as in every state LIHEAP program" is not accurate for Delaware.
  3. has_cooling_expense is required with no Delaware source, while the electric account the payment goes to is assumed.
  4. The heating-bill gate follows one sentence of the 2015 manual where that manual's own chart and the current plan read differently, with no source-conflict record.

Every quote and page in the body checks out, the age thresholds are right, all 11 expectations hold by hand, and no existing result moves. The three suggestions are optional. CI is green at 785cf190bd.

…eating responsibility

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 e87cd041c1:

  1. Targeted members. I looked for DHSS's summer 2026 decision and found none. HHS profiles show the extension in FY2023 and FY2024 (10,038 and 9,626 cooling households, more than had a targeted member) and only 88 cooling households in FY2025; the FY2027 plan cuts cooling to 10% of funds and says the benefit "is not guaranteed and is dependent on funding availability". The flag keeps the targeted rule, the comment and registry note cite the profiles, and programs.yaml no longer lists 2026 as verified.
  2. heating_type. Kept: callers must send heating_type in every state LIHEAP program, and the default is tracked in issue 9754. The body and the comment now say it is a PolicyEngine convention, not a Delaware rule, and that Delaware's heating formula pays this household.
  3. has_cooling_expense. Kept, and the electric-bill gate is not added: we assume every household holds an active energy account and do not proxy it with a bill. The comment and body now give its basis: it stands for the purchased source of cooling in the SCAP chart (p. 100) and is the input every state's cooling assistance uses; no Delaware text asks for a cooling cost.
  4. Heating-bill gate. Now follows the plan and the chart. New de_liheap_income_eligible holds the household and income test, moved unchanged out of de_liheap_eligible, and the cooling flag reads it with no heating responsibility test. Case 9 (no heating, pays for cooling) flips to true, and a new Case 12 pays a public-housing tenant aged 70 with heat in the rent. LIHEAP cooling: encode Delaware Summer Cooling Assistance electric benefit eligibility (PE-US PR 10762) TheAxiomFoundation/rulespec-us#2175 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): Add Delaware LIHEAP summer cooling electric benefit eligibility

Reviewed at head e87cd041c1ea8bf149c63a021b0ea6b55637a6e2 (round 1 was at 785cf190bd). One fix commit since round 1; no merges of main.

Summary

The fix commit does what the reply says. The refactor of de_liheap_eligible is exact, no existing Delaware expectation changed, and CI ran every Delaware LIHEAP test file green at this head. Findings 1 and 2 are closed: each was declined with a reason that the sources back and that the code, the registry and the body now state. The heating-bill gate (finding 4) is gone from the cooling flag and two cases pin its absence.

Three points remain, all small:

  • the choice between manual section 415 and the plan and chart is still not in the source-conflict backlog, and the body's reason for leaving it out ("no statute conflict") is not the repository's rule;
  • has_cooling_expense is still required from every household, including one that pays a heating bill. The chart the PR now relies on reads "Heating or Cooling", and the three sibling PRs that use this input use it as the alternative to a heating cost, not on top of one;
  • the refactor moved the federal-floor line out of the file an existing backlog item names.

No critical findings. Three should-address items (two are the open remainder of round-1 findings 3 and 4, one is new) and four suggestions.

A correction to round 1: I wrote that the 2015 manual "is not the one in force". The backlog holds a ruled Delaware LIHEAP item (us-de:liheap-plan-income-checklist, ruled 2026-11-02 and 2026-11-03) which follows the manual over the plan because the 2020 statement of work lists the manual as an applicable document and the plan item is a checkbox summary. I should have cited it. It does not undo round-1 finding 4, because the manual's own chart still reads against section 415, but it is the reason the choice needs a record whichever way the code goes (should-address 1).

Prior findings

Finding Status Evidence
Should 1: targeted-member rule is contingent; verified_years: "2026" not backed Declined with a record; closed Round 1 offered this route. All three parts are done: the comment at de_liheap_cooling_eligible.py lines 38-44 says no 2026 decision was found and cites the profiles; the registry note says the same; the verified_years line is removed from the cooling entry (140 of the 203 state entries carry none, so the entry is still valid). The figures are real, read from the HHS profiles themselves: FY2023 "Cooling Assistance served 10,038 households" (11,431 served, 73% with a vulnerable member, so about 8,345); FY2024 9,626 (72% of 11,072 is 7,972); FY2025 "Cooling Assistance served 88 households with a reported average benefit of $717", 2% of funds. The FY2027 plan says "The cooling benefit is not guaranteed and is dependent on funding availability" (p. 27) and budgets 10% to cooling against 20% the year before (item 1.2, p. 4). Cases 4 and 6 pin the targeted rule.
Should 2: heating_type UNSPECIFIED term has no Delaware source Declined with reason; closed Round 1 allowed keeping the term if labelled. Lines 34-35 now read "PolicyEngine convention, not a Delaware rule". The body says the same, names issue 9754 (open) and says Delaware's heating formula pays this household from the electric column; the inaccurate "as in every state LIHEAP program" sentence is gone. The Case 10 comment was corrected to match. Case 10 still pins the term.
Should 3: has_cooling_expense required with no Delaware source; electric account assumed Partly closed; one part open (should-address 2) Not adding an electric-bill gate is a sound decline: the model assumes an active account, the same approach as Nevada #10738, now on main. The body labels the cooling cost "a modeling reading; no Delaware text asks the household to show a cooling cost". The reason given for it does not hold for a household that buys its heating, and the "every state" sentence is not accurate.
Should 4: heating-bill gate rests on manual 415 against the chart and the plan; no source conflict recorded Code fixed; record open (should-address 1) The flag now reads de_liheap_income_eligible. By my reading, Case 9 (no heating, pays for cooling) and Case 12 (public housing, heat in the rent, aged 70) would both be false if the formula still read de_liheap_eligible; both passed in CI as true. The conflict itself is still unrecorded.
Suggestion 1: state the "no amount" reasoning accurately; add the plan range Not taken (optional) The body still says "splits leftover funds".
Suggestion 2: registry years Taken in effect The entry no longer claims a year.
Suggestion 3: say is_disabled is a stand-in Not taken (optional) The comment is unchanged on this point.

New findings

Critical (must fix)

None.

Should address

1. The heating-bill choice is still not recorded (open remainder of round-1 finding 4).
de_liheap_cooling_eligible.py lines 25-33; PR body, test plan line "Source-conflict register: no statute conflict."

The body now names the conflict and the choice: section 415 "asks for a heating bill for 'cooling electric'; this PR follows the current plan and the chart". It then says the register does not apply because both sources are non-statute, and that the choice is "stated above and in the code comment".

  • CONTRIBUTING.md, "Source conflicts": "When a PR takes such a reading, or finds one already in the code, the conflict goes into the register", and step 1: "The ruling PR records the conflict in source_conflicts/candidates.yaml". The rule is about conflicting sources, not only statutes.
  • The backlog on main already holds this kind of item for this program: us-de:liheap-plan-income-checklist (manual against plan, "No statute is supplied", follows: gap-fill, ruled). 87 backlog items cite no statute or regulation, among them us-ca:liheap-subsidized-heat-in-rent and us-hi:liheap-utilities-in-rent.
  • That Delaware ruling went for the manual: "follow the manual over the plan. Neither text is a statute. The statement of work lists the manual as an applicable document, and plan 1.9 is a checkbox summary." Plan item 3.3's renter answers are check boxes too, and section 415 is an operative sentence that names "cooling electric" (p. 32): "applicants must be responsible for paying a heating bill in order to receive assistance for heating, crisis and cooling electric. In order to receive an air conditioner, the applicant must have an electric bill." Against it stands the manual's own SCAP chart, marked FINAL and dated 2/24/2015 (p. 100): "LIHEAP Eligibility: A. Purchase Source of Heating or Cooling". Section 415 carries no date.
  • The code comment does not mention section 415, so the body's "and in the code comment" is not accurate. A reader of the file sees only the reading that was followed.

Household (Case 12): Delaware, 2026, public-housing tenant aged 70, social_security_retirement: 14_000, heat_expense_included_in_rent: true, has_cooling_expense: true. Under the chart: true (the head). Under section 415: false.

Fix: no formula change is needed for this item. Add a candidate to source_conflicts/candidates.yaml (for example us-de:liheap-cooling-heating-bill; years 2026-2027; sources: manual 415 p. 32, the chart p. 100, plan item 3.3 p. 12; both readings; the Case 12 household as the example; pe_us.follows, the cooling variable as the code path, this PR; state: unreviewed), and say in its note that us-de:liheap-plan-income-checklist followed the manual, so the two can be ruled together. Name section 415 in the comment at lines 25-33 and correct the body line.

2. has_cooling_expense is required from households that buy their heating, which no source and no sibling does (open remainder of round-1 finding 3).
de_liheap_cooling_eligible.py lines 53-61; test Case 8 (lines 154-171); PR body, "has_cooling_expense is required".

The reply gives two reasons for the term.

  • "It stands for the purchased source of cooling in the SCAP chart." The chart says "Purchase Source of Heating or Cooling". A cooling cost is the sourced condition for a home with no heating bill (Cases 9 and 12). A household that buys its heating already meets the chart, and it meets section 415 as well. Manual 303.2 A (pp. 21-22): "If applicant has a current FAP application, the SCAP application is automatically processed via computer." So this household is paid under both readings of should-address 1, and the flag refuses it.
  • "It is the input every state's cooling assistance uses" (also the comment at line 53). On main no LIHEAP variable reads has_cooling_expense: California (Pay California's regular HEAP utility benefit to cooling-only households #10732) uses a gas or electric bill and Nevada (Pay the Nevada LIHEAP Fixed Annual Credit to cooling-only households, assuming an energy account #10738) assumes an account and asks for no cooling cost. The three open siblings that do read it use it as the alternative to a heating cost: Oregon energy_cost = heating_cost | cooling_only, Florida (responsible & fuel_qualifies) | cooling_only, DC cooling_only when heating expenses are zero. Delaware is the only one that asks for it on top of a heating bill.

Household: Delaware, 2026, aged 67, social_security_retirement: 18_000, heating_type: NATURAL_GAS, gas_expense: 900, has_cooling_expense not set (the default is false). By hand trace: de_liheap_income_eligible true, de_liheap_eligible true, de_liheap paid; cooling flag false. Expected: true.

Fix (preferred): make the cooling cost the alternative, as the chart and the siblings do:

purchases_heating = spm_unit("de_liheap_eligible", period)
return heating_type_reported & has_vulnerable_member & (
    purchases_heating | (income_eligible & has_cooling_expense)
)

Case 8 still pins the cooling term (income eligible by input, no gas bill, no cooling cost: false). Add a case for the heating client with no cooling cost (true). Every term is then sourced and the "every state" sentence can go. Otherwise keep the formula, and say in the comment (not only the body) that this is a modeling reading with no Delaware text, that the chart is also met by a heating purchase, and that a current heating client who reports no cooling cost is refused; and drop or correct the "every state's" claim in the comment and the body.

3. The refactor moved the federal-floor line out of the file an existing backlog item names (new).
source_conflicts/candidates.yaml lines 2390-2419 on main, item us-de:liheap-income-floor-vs-smi-limit.

The item lists policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py under pe_us.code, and its note says "PE-US applies the floor, rounded to cents with the statute's strict 'less than' (de_liheap_eligible.py)". At this head the floor (income < federal_floor) is in de_liheap_income_eligible.py, and de_liheap_eligible.py no longer holds it. The guard passes, because the old file still exists, but the register entry and the marker that follow from this item would point at a file with no deciding line.

Fix: in the same edit as should-address 1, change the code path and the note to de_liheap_income_eligible.py.

Suggestions

  1. References. The comment at lines 16-17 says "PDF pages 21-22, 100", but the only manual link opens at page 21, and the chart is now the basis of the formula; add ...HSS_15027Liheap_MAN.pdf#page=100. The comment cites FY2023, but only the FY2024 and FY2025 profiles are linked; the FY2023 one is at https://liheappm.acf.gov/sites/default/files/private/congress/profiles/2023/FY2023DelawareProfile-508Compliant.pdf.
  2. Registry note. It cites the two years the benefit was extended and not the year it reached 88 households. One clause on FY2025, or the FY2027 plan's "not guaranteed", would keep the note from reading as if the extension were usual.
  3. A direct test for de_liheap_income_eligible. It is asserted once (Case 2, false) and exercised through the existing files. A small file of its own, with a true case and the federal-floor branch, would pin the new variable where it lives.
  4. rulespec-us#2175 wording. Three sentences are stale: "They have not yet passed in CI at this head" (they have), "The PR has no review yet", and the first "Why queued" bullet, which still says the flag reads Delaware's regular heating eligibility. Interpretation 9 repeats the "every state's" sentence.

Verified

  • Refactor of de_liheap_eligible (read line by line; values confirmed by the CI run). Round 1 returned (size > 0) & ((income <= limit) | (income < federal_floor)) & heating_responsibility. The head returns de_liheap_income_eligible & heating_responsibility, and the new variable returns (size > 0) & ((income <= limit) | (income < federal_floor)) from the same five reads, the same fpg call with the same year_lag, and the same rounding. The heating-responsibility block is untouched. Both variables are gated to Delaware, so the conjunction is the same for every household. The only other reader is de_liheap (defined_for = "de_liheap_eligible"). No existing Delaware test file is in the diff, and CI ran de_liheap.yaml, de_liheap_eligible.yaml (12 cases), the income-limit, income-band, household-size and countable-income files green at this head.
  • New variable. de_liheap_income_eligible: SPM unit, year, bool, defined_for = StateCode.DE, a plain label, and two references that show the text (42 U.S.C. 8624(b)(2)(B); FY2026 plan p. 9, item 2.1, "State Median Income 60.00%"). No keyed lookup, so it evaluates in mixed-state populations.
  • No household that was eligible at round 1 loses the flag. de_liheap_eligible implies de_liheap_income_eligible, so the change only adds households (by reading the two formulas).
  • Mutation rule (by my reading of the tests; no mutation was run). Income test: Case 2. No heating-responsibility test: Cases 9 and 12. heating_type_reported: Case 10. Age edges: Cases 3-6. Disability: Case 7. Cooling cost: Case 8.
  • Changed and new expectations, by hand.
    • Case 2: taxes on $65,000 would have to exceed $25,658 to reach the $39,342 limit; they cannot, and the result is also above 1.1 x $15,650 = $17,215. de_liheap_income_eligible false, cooling false.
    • Cases 3-8: the input is renamed to de_liheap_income_eligible: true; outputs unchanged.
    • Case 9: $18,000 <= $39,342; heating_type: NONE with no heat in rent, so heating false; not UNSPECIFIED, aged 67, cooling cost. Cooling true.
    • Case 12: $14,000 <= $39,342; heat in rent in public housing, so heating false; NATURAL_GAS, aged 70, cooling cost. Cooling true.
  • Sources in the reply. The FY2023, FY2024 and FY2025 profiles, the FY2027 plan sentence and budget share, the chart on manual p. 100 and section 415 on p. 32 were each opened and read. Both profile links in the reference tuple return the PDF.
  • Registry. The cooling entry is status: partial, names the variable and prefix, claims no year, and its note matches the code (income test, cooling cost, the three member routes, the extension and the missing 2026 decision). The regular Delaware entry is unchanged.
  • Source-conflict guard (a run I executed: the guard's own pattern over the comments of the three changed variable files). No comment matches, so the ratchet does not move. No Delaware LIHEAP file is in KNOWN_UNMARKED. The backlog path in should-address 3 still resolves to a tracked file, so the guard passes.
  • Other guards. No income list is touched. The flag is boolean and stays out of gov.hhs.liheap.regular_payments. The changelog fragment is present.

Axiom

axiom: TheAxiomFoundation/rulespec-us#2175 queued is valid. The issue is OPEN, labelled pe-parity, names head e87cd041c1, and was updated with the fix: the required output reads de_liheap_income_eligible "with no heating responsibility test", companion tests 8 and 10 are YAML Cases 9 and 12, and interpretations 3, 7, 8 and 9 record the targeted-rule choice, the plan and chart over section 415, the heating_type convention and the cooling-cost reading. A formula change for should-address 2 needs the required output, interpretation 9 and one companion test updated in the same round.

CI

All 39 checks pass at e87cd041c1 (run 43266435790, finished 18:28 UTC on 2026-11-12). Nothing is pending. The Quick Feedback log shows de_liheap_cooling_eligible.yaml with 12 passes and every other Delaware LIHEAP test file passing, 509 tests in all, with full patch coverage. The author did not run tests locally; this run is the evidence for every expectation above.

Branch

Nine commits behind main. The merge with main is clean; main now includes California #10732 and Nevada #10738. The merge is also clean with each open sibling's current head: #10730, #10734, #10736, #10740 and #10742 (all edit policyengine_us/programs.yaml on different lines). Adding a candidate will touch source_conflicts/candidates.yaml, which other open PRs also append to.

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 three small changes. None needs a formula change unless you take the preferred fix for the second. Findings 1 and 2 from round 1 are closed: each was declined with a reason the sources back, and the code, registry and description now state it. The refactor of de_liheap_eligible is exact, and no existing Delaware expectation changed.

  1. Record the heating-bill choice. This one follows from a gap in my round-1 review. I said the 2015 manual was not in force and offered "follow the plan and the chart" without a record. The backlog on main already has a ruled Delaware item, us-de:liheap-plan-income-checklist, that follows that manual over the plan. So the choice between section 415 and the plan and chart needs a candidate whichever way the code goes. The code comment should also name section 415 (Should Address 1).
  2. has_cooling_expense is still required from a household that buys its heating. The chart the PR now relies on reads "Heating or Cooling", and the sibling PRs use the input as the alternative to a heating cost. The comment's "the input every state's cooling assistance uses" isn't accurate: California and Nevada don't read it. Either make it the alternative (sketch in the report) or say in the comment that it is a modeling reading and that a current heating client with no reported cooling cost is refused (Should Address 2).
  3. A stale path from the refactor. us-de:liheap-income-floor-vs-smi-limit still names de_liheap_eligible.py for the federal-floor line, which now lives in de_liheap_income_eligible.py (Should Address 3).

CI is green at e87cd041c1.

…ng-bill choice

A household that buys its heating now qualifies for the SCAP electric benefit
without a cooling cost (SCAP chart "Heating or Cooling"; manual 303.2 A); the
cooling cost stays the route for a household that does not. New Case 13 pins
it. Record manual 415 against the chart and plan 3.3 as candidate
us-de:liheap-cooling-heating-bill (ruled 2026-11-12), name 415 in the comment,
point us-de:liheap-income-floor-vs-smi-limit at de_liheap_income_eligible.py,
add the FY2023 profile, and note FY2025's 88 households in the registry.

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 2908ce8c4d:

  1. Heating-bill choice. New candidate us-de:liheap-cooling-heating-bill: the SCAP chart (p. 100) and plan 3.3 against section 415 (p. 32), with the Case 12 household as the example, following the chart and the plan. The project lead ruled this on 2026-11-12, so it is ruled. Its note says how it sits beside us-de:liheap-plan-income-checklist: there the manual was followed over the plan's checklist; here the manual is split between section 415 and its own chart, and the plan sides with the chart. The code comment names section 415, and the body's register line is corrected.
  2. Cooling cost. I took your preferred fix: heating_type_reported & has_vulnerable_member & (de_liheap_eligible | (de_liheap_income_eligible & has_cooling_expense)), citing 303.2 A for heating applicants. New Case 13 (gas heat, no cooling cost) expects true, and Case 8 still pins the cooling term. The "every state" sentence is gone from the comment, the body and interpretation 9.
  3. Stale path. us-de:liheap-income-floor-vs-smi-limit now names de_liheap_income_eligible.py in its code list and note, and lists this PR.

Suggestions:

  • 1. The FY2023 profile is added, and the manual comment now lists page 32. The manual stays one reference entry with its page list in the comment above it, per the repository's reference rule of one entry per document.
  • 2. The registry note now says FY2025 served 88 households.
  • 3. Not taken: both branches of de_liheap_income_eligible are already pinned where it is read. The limit is pinned by Case 2 here, and the federal floor by the 25-person case in de_liheap.yaml.
  • 4. LIHEAP cooling: encode Delaware Summer Cooling Assistance electric benefit eligibility (PE-US PR 10762) TheAxiomFoundation/rulespec-us#2175 is updated: the review and CI sentences, the first "Why queued" bullet, scope, required output, inputs, interpretations 7 and 9, and new companion test 11.

@hua7450
hua7450 requested a review from DTrim99 November 12, 2026 20:03
@DTrim99

DTrim99 commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator

PR Review (round 3): Add Delaware LIHEAP summer cooling electric benefit eligibility

Reviewed at head 2908ce8c4d (round 2 was at e87cd041c1). There is one fix commit since round 2, touching five files, and no merges of main. I ran no tests and no Python for this round. Every result below rests on reading the head, hand traces, the sources or the CI run at this head, and each one says which.

Summary

The fix commit closes all three round-2 items in substance:

  • Cooling cost. The flag now uses round 2's preferred formula, so a household that buys its heating qualifies without a cooling cost. New Case 13 would fail without that change.
  • Heating-bill choice. It is now a backlog candidate with every field CONTRIBUTING.md asks for. The code comment names section 415, and the body line is corrected.
  • Stale backlog path. Corrected.

One thing is left. The new candidate says state: ruled, but no ruling is on record. The note names no one and links nothing. This PR, issue 10761 and rulespec-us#2175 hold no comment from anyone but the author and me. The Georgia (#10746) and Oklahoma (#10748) cooling PRs drew the same finding today. The reading itself is sound, and I agree with it.

CI is green at this head (40 of 40 checks). The Delaware LIHEAP test files, including the new case, ran and passed. The branch merges cleanly with current main and with each open sibling.

0 critical, 1 should address, 2 suggestions.

Prior findings (round 2)

Finding Status Evidence
Should 1: the heating-bill choice is not recorded Recorded; one field still open (new should 1) Candidate. us-de:liheap-cooling-heating-bill is at source_conflicts/candidates.yaml lines 2390-2424. Each field is checked under Verified. Comment. Lines 32-33 of de_liheap_cooling_eligible.py now read: "Manual section 415 asks for a heating bill for "cooling electric"; the plan and the chart are followed." Body. The test-plan line now names the candidate instead of "no statute conflict". Open. state: ruled has no ruling record (new should 1).
Should 2: has_cooling_expense was required of households that buy their heating Fixed (the preferred option) Formula. Lines 59 and 64-68 return heating_type_reported & has_vulnerable_member & (purchases_heating | (income_eligible & has_cooling_expense)), where purchases_heating = de_liheap_eligible. Test. Case 13 (gas heat, has_cooling_expense: false, aged 67) expects true. By my reading it would be false under the round-2 formula, which required the cooling cost of every household. Case 8 still pins the cooling cost. Wording. The "every state's cooling assistance" sentence is gone from the comment, the body and interpretation 9 of rulespec-us#2175. Lines 60-62 now call the term a "Modeling reading, with no Delaware text". Source. The comment cites manual 303.2 A for heating clients, and I read the quoted sentence on PDF page 22: "If applicant has a current FAP application, the SCAP application is automatically processed via computer."
Should 3: the refactor moved the federal-floor line out of the file us-de:liheap-income-floor-vs-smi-limit names Fixed Item. Its pe_us.code and note now name de_liheap_income_eligible.py, which holds the floor (line 29: (income <= limit) | (income < federal_floor)), and prs adds #10762. Old file. Dropping de_liheap_eligible.py from the item is right: it now only reads the income flag (line 39). Checked by reading.
Suggestion 1: references Taken; I withdraw the extra-link part Profile. The FY2023 profile is added (line 20); its PDF shows "Cooling Assistance served 10,038 households". Pages. The page comment now lists pages 21-22, 32 and 100. Withdrawn. The author is right about the separate #page=100 link I asked for. CLAUDE.md says "One reference entry per source document; URLs that differ only by #page= are one source" and "Variable reference tuples have no title: put a # PDF pages 61-62, 67 comment above a multi-page href".
Suggestion 2: registry note Taken The note now says "FY2025 served 88 households".
Suggestion 3: a direct test for de_liheap_income_eligible Not taken (optional); the reason holds Checked by reading the tests: Case 2 here pins the limit (above it, false). de_liheap.yaml Case 36 pins the floor from both sides: 25 people with $150,000 are eligible and get $155, and exactly $162,415 is ineligible and gets $0, under the strict "less than".
Suggestion 4: rulespec-us#2175 wording Taken Updated: the review sentence, the first "Why queued" bullet (accurate again, since the flag reads de_liheap_eligible), the scope, the required output, interpretations 7 and 9, and new companion test 11. Two CI sentences went out of date once CI finished (suggestion 2 below).

New findings

Critical (must fix)

None.

Should address

1. The new candidate says state: ruled, but no ruling is on record.

  • Where: source_conflicts/candidates.yaml lines 2390-2424, us-de:liheap-cooling-heating-bill (lines 2445-2479 in the tree merged with main).
    • The note says: "Ruled 2026-11-12: follow the plan and the SCAP chart."
    • The body says "(ruled 2026-11-12)" twice, and interpretation 7 of rulespec-us#2175 says "ruled 2026-11-12".
  • What is missing: the note names no role and links no record.
    • As of this review, the PR thread holds comments only from the codecov bot, the author and me.
    • The PR has no review from anyone else. Issue 10761 and rulespec-us#2175 have no comments.
    • Recent ruled items in the same file name the project lead and link the comment. Examples: "Ruled by the project lead, 2026-11-02: Apply each state's rule for a Medicaid applicant whose spouse is not aged, blind or disabled #10640 (comment)", and "Ruled 2026-11-05 for the regulation by the project lead; the ruling record is ...".
    • The reply says the project lead ruled, but a later reader of the register has no way to check that.
  • The substance is sound, and I agree with it.
    • The manual's SCAP chart (PDF page 100, marked FINAL and dated 2/24/2015) reads "A. Purchase Source of Heating or Cooling".
    • Section 415 (PDF page 32, undated) reads "applicants must be responsible for paying a heating bill in order to receive assistance for heating, crisis and cooling electric".
    • Plan item 3.3 (FY2026 PDF page 12) answers No for "Renters Living in subsidized housing?" and "Renters with utilities included in the rent?". Item 2.3 answers Yes to both for heating.
    • The note's account of how this item sits beside us-de:liheap-plan-income-checklist is accurate. That ruling chose the manual over a plan checklist. Here the manual is split between section 415 and its own chart, and the plan's cooling answers side with the chart.
  • The household it decides (Case 12): Delaware, 2026, a public-housing tenant aged 70 with $14,000 of Social Security, heat in the rent and a cooling cost. Under the chart and the plan it is eligible, which is what the head returns. Under section 415 it is not.
  • Fix: either record the ruling where it can be linked and put the role and the link in the note (a short comment by the project lead on this PR is enough), or set state: unreviewed until a ruling exists and drop "ruled 2026-11-12" from the body and from interpretation 7 of the issue. Neither route needs a code change.

Suggestions

  1. Candidate sources for 2027.
    • The candidate's years.to is 2027, but its only plan source is the FY2026 item 3.3. The FY2027 plan prints the same renter rows in item 3.3 on page 11, and round 1 read their answers there; add it as a source.
    • The question says the purchased-source test is what "the manual's SCAP chart and the plan provide". The plan only sets no different cooling policy for renters, as readings already says, so the question could say that too.
  2. rulespec-us#2175: two CI sentences are now out of date.
    • "CI has not yet run its tests at this head" (under Why queued) and "They have not yet passed in CI at this head" (under Tests) are no longer true: all 13 cases passed in run 43296491059.
    • "round 2 (2026-11-12) asked for the changes at this head" reads as if round 2 reviewed this head. Round 2 reviewed e87cd041c1.

Verified

  • The whole formula at the head (read in full). de_liheap_cooling_eligible.py lines 25-68. There are four terms:

    • heating_type != UNSPECIFIED;
    • a member with age >= 60, age < 6 or is_disabled, with the age thresholds read from gov.states.de.dhss.liheap.cooling;
    • de_liheap_eligible, or else de_liheap_income_eligible & has_cooling_expense.
    • Both eligibility variables are unchanged in this commit.
  • Mutation rule (by my reading of the tests; I ran no mutation).

    • heating_type_reported: Case 10. UNSPECIFIED fuel with unsubsidized heat in rent makes de_liheap_eligible true, so this term is the only thing that makes the result false.
    • has_vulnerable_member: Cases 4 and 6 would be true without it.
    • The purchases_heating disjunct: Case 13 would be false without it.
    • The second disjunct as a whole: Cases 9 and 12 have de_liheap_eligible false, so they would be false without it.
    • income_eligible inside the second disjunct: Case 2 has income over the limit, a gas bill, a cooling cost and a member aged 63. de_liheap_eligible is false through the income test, so the case would be true without this conjunct.
    • has_cooling_expense inside the second disjunct: Case 8 is income eligible by input and has natural gas with no bill, so heating_expense is 0 and has_heating_expense is false. It has no cooling cost, so it would be true without this conjunct.
    • Substituting the first disjunct: replacing de_liheap_eligible with de_liheap_income_eligible would turn Case 8 true, and replacing it with has_heating_expense would turn Case 2 true.
  • No household that was right at round 2 changes (by reading).

    • The round-2 result was income_eligible & reported & vulnerable & cooling. That implies the new second disjunct, so every household true at round 2 is still true.
    • The only new true results are heating-eligible households with a targeted member and no cooling cost, which is the intended change.
    • Regular heating results cannot move, because neither eligibility variable changed. CI ran the 510 Delaware LIHEAP tests green.
  • Hand checks under the new formula. The FY2026 one-person limit is $39,342 and the FY2027 limit is $40,380. CI passed all 13 cases.

    • Case 13 (new): Social Security of $18,000 is below $39,342. The $900 gas bill with no heat in rent makes has_heating_expense true, and the fuel is known, so de_liheap_eligible is true. NATURAL_GAS counts as reported, and the member is 67. Expected true and true.
    • Case 8 (comment added, value unchanged): income eligible by input. Natural gas with no gas bill makes heating_expense 0, so the unit is not heating eligible. It has no cooling cost. Expected false.
    • Cases 1 and 11 (FY2026 and FY2027): $18,000 with a gas bill makes the unit heating eligible, so both disjuncts hold, and the member is 67. Expected true.
    • Case 2: de_liheap_income_eligible is false, so both disjuncts fail. Expected false and false.
    • Cases 3-7: with no gas bill these units are not heating eligible. Income eligibility (an input) and a cooling cost leave only the targeted-member test, which gives age 60 true, 59 false, a child of 5 true, a child of 6 false, and a disabled adult true.
    • Case 9: NONE means no heating eligibility. $18,000 and a cooling cost give true.
    • Case 10: unsubsidized heat in rent makes it heating eligible, but UNSPECIFIED fuel does not count as reported. Expected false.
    • Case 12: subsidized heat in rent means no heating eligibility. $14,000 and a cooling cost give true.
  • Candidate fields, checked against CONTRIBUTING.md "Source conflicts", step 1.

    Field At the head
    id, program us-de:liheap-cooling-heating-bill, liheap
    years 2026 to 2027, federal-fiscal (the PR's Cases 1-10, 12 and 13 are 2026 and Case 11 is 2027)
    question Purchased source of heating or cooling (chart, plan) or a heating bill (section 415). See suggestion 1.
    sources Three. Manual p. 100 (chart), FY2026 plan p. 12 (item 3.3) and manual p. 32 (section 415). Each link opens the document. I found the chart's and section 415's quoted text on the cited pages, and the item 3.3 row labels on page 12. The check-box answers rest on round 1's page images, which I did not render again.
    readings statute: "No statute is supplied; ..." with the chart and plan reading. other: the section 415 quote. Laid out the same way as us-de:liheap-plan-income-checklist.
    example The Case 12 household, with the correct result under each reading
    pe_us.follows gap-fill, an allowed value and the same as the other Delaware manual-versus-plan item
    pe_us.code de_liheap_cooling_eligible.py, a tracked file that holds the deciding line
    pe_us.prs Add Delaware LIHEAP summer cooling electric benefit eligibility #10762
    state ruled, with no record (should 1)
    note The ruling sentence, plus an accurate comparison with the checklist ruling

    No marker is added, which is right at this step. The body and the code comment now describe the same choice as the candidate.

  • Sources read for this round.

    • Manual PDF pages 21-22 (303.2 A; item 3 is on p. 22), p. 32 (section 415) and p. 100 (the chart, FINAL, 2/24/2015).
    • FY2026 plan p. 12 (item 3.3 row labels) and FY2027 plan p. 11 (the same rows).
    • The FY2023 HHS profile (11,431 households served; cooling 10,038).
  • Comments and the source-conflict ratchet (checked with grep, using the guard's conflict-comment pattern; no Python run). No comment line in the three variable files or the two parameter files matches. No Delaware LIHEAP file is in KNOWN_UNMARKED on main. The test file is outside the folders the guard scans.

  • Mixed-state populations. The commit adds no keyed lookup. de_liheap_eligible is gated to Delaware like the flag, so a unit in another state reads false.

  • Registry. The note matches the code: households "that buy their heating or pass the income test with a cooling cost", with a member 60 or older, under 6 or disabled. It claims no verified year.

  • National total. Main now holds gov.hhs.liheap.regular_payments (Add a national LIHEAP total, an Illinois regular heating payment and LIHEAP cooling registry notes #10730). The flag is boolean and stays out of it. Add a national LIHEAP total, an Illinois regular heating payment and LIHEAP cooling registry notes #10730's test_liheap_total_sums_every_registered_state_payment skips registry variables that are not floats, so by my reading the merged tree passes it.

Axiom

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

  • The issue is OPEN and labelled pe-parity. It was updated at 20:03 UTC on 2026-11-12 and names head 2908ce8c4d.
  • The required output matches the head term for term: heating_type not UNSPECIFIED, a targeted member, and either de_liheap_eligible or de_liheap_income_eligible with has_cooling_expense.
  • Companion test 11 is YAML Case 13, with a hand derivation from manual pp. 21-22 and 100.
  • Interpretation 9 now gives the cooling cost as the route for a household that does not buy its heating, and no longer has the "every state's" sentence. The one remaining "every state" phrase is in interpretation 8, about heating_type as a required input. It was there at round 2 and is not the sentence round 2 raised.
  • Interpretation 7 names the candidate as "ruled 2026-11-12". It needs the same change as the note under should 1.
  • Two CI sentences are out of date (suggestion 2).

CI

All 40 checks pass at 2908ce8c4d (run 43296491059, started 20:03 UTC and finished 21:20 UTC on 2026-11-12). Nothing is pending and nothing failed.

  • The Quick Feedback job ran de_liheap_cooling_eligible.yaml on its own (13 passed) and the whole Delaware test folder (510 passed).
  • The three changed variable files have 100% coverage (54 statements, none missed).
  • The author did not run tests locally, and neither did I, so this run is the evidence for every expectation above.

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, to the record only. All three round-2 items are fixed in substance: the flag now uses the preferred formula, so a household that buys its heating qualifies without a cooling cost (Case 13 pins it); the heating-bill choice is a candidate with every field; and the stale path in us-de:liheap-income-floor-vs-smi-limit is corrected.

The new candidate us-de:liheap-cooling-heating-bill says state: ruled ("Ruled 2026-11-12: follow the plan and the SCAP chart"), but no ruling is on record: the note names no one and links nothing, and this PR, issue #10761 and rulespec-us#2175 hold no comment recording it. Please either have the ruling posted where it can be linked and put the role and the link in the note, as other ruled entries do, or set state: unreviewed until it exists (Should Address 1). The reading itself is sound, and I agree with it. No code change is needed either way.

Two optional suggestions follow. CI is green at 2908ce8c4d.

@hua7450

hua7450 commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator Author

Ruling by the project lead, 2026-11-12: us-de:liheap-cooling-heating-bill

For the Delaware Summer Cooling Assistance electric benefit, follow the manual's SCAP eligibility chart ("Purchase Source of Heating or Cooling", PDF page 100) and plan item 3.3. Manual section 415's heating-bill requirement for "cooling electric" (PDF page 32) is not followed.

The manual is split between section 415 and its own chart, and the plan's cooling answers side with the chart. So a household that buys its heating qualifies, and so does one that passes the income test and pays for cooling, including a public-housing tenant with heat in the rent (Case 12).

…didate

Name the project lead and link the ruling record in the note of
us-de:liheap-cooling-heating-bill, add the FY2027 plan's item 3.3 as a source,
and say in the question that the plan sets no different cooling policy for
renters.

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 3615979844:

No code or test changed.

@hua7450
hua7450 requested a review from DTrim99 November 12, 2026 22:13
@DTrim99

DTrim99 commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator

PR Review (round 4): Add Delaware LIHEAP summer cooling electric benefit eligibility

Reviewed at head 3615979844 (round 3 was at 2908ce8c4d). There is one fix commit since round 3 and no merge of main. It changes one file, source_conflicts/candidates.yaml (8 lines added, 4 removed). It changes no formula, parameter, test or expectation. I ran no tests and no Python for this round. Each result below says whether it rests on reading the head, the PR thread, a source document or the CI run at this head.

Summary

The round-3 should is closed:

  • Record. The project lead's ruling on us-de:liheap-cooling-heating-bill is now on record in a dated comment on this PR.
  • Note. The candidate's note names the role and links that comment, in the same form as the other ruled entries in the file.

Both round-3 suggestions were taken. The commit changes no result for any household.

CI is green at this head (38 of 38 checks), including the Delaware LIHEAP tests and the source-conflict guard tests. The branch merges cleanly with current main and with each open LIHEAP cooling sibling. The candidate id is unique in the merged tree.

0 critical, 0 should address, 0 suggestions.

Prior findings (round 3)

Finding Status Evidence
Should 1: us-de:liheap-cooling-heating-bill said state: ruled with no ruling on record Fixed: the ruling is recorded and linked Record. The comment is #issuecomment-6837369871. It was posted at 22:13 UTC on 2026-11-12, and the GitHub API shows it has not been edited. It reads: "Ruling by the project lead, 2026-11-12: us-de:liheap-cooling-heating-bill For the Delaware Summer Cooling Assistance electric benefit, follow the manual's SCAP eligibility chart ("Purchase Source of Heating or Cooling", PDF page 100) and plan item 3.3. Manual section 415's heating-bill requirement for "cooling electric" (PDF page 32) is not followed." It also gives the reason and the Case 12 household. Note. Lines 2426-2428 at the head now read: "Ruled 2026-11-12 by the project lead; the ruling record is #10762 (comment). Follow the plan and the SCAP chart." Form. This matches the other ruled entries, such as "Ruled by the project lead, 2026-11-02: #10640 (comment)". The record was posted from the author's account. That is also true of the #10640 record, which six entries already cite. Consistency. The record, the candidate (question, readings, example, follows: gap-fill), the body line "(ruled 2026-11-12)" and interpretation 7 of rulespec-us#2175 all describe the same choice. Checked by reading.
Suggestion 1: add a 2027 plan source; reword the question Taken Source. Lines 2406-2408 add "Delaware FY2027 LIHEAP State Plan, item 3.3, PDF page 11". The link returns the 517,753-byte PDF. The text of PDF page 11 holds "3.3 Check the appropriate boxes below and describe the policies for each" and the rows "Renters?", "Renters Living in subsidized housing?" and "Renters with utilities included in the rent?". The years.to of 2027 now has a plan source. I did not render the check boxes again this round; their answers rest on round 1's page images. Question. Lines 2396-2398 now say the purchased-source test is what "the manual's SCAP chart provides (plan item 3.3 sets no different cooling policy for renters)". This agrees with readings.statute.
Suggestion 2: two out-of-date CI sentences in rulespec-us#2175 Taken The issue now says round 3 "reviewed 2908ce8c4d, where all 13 cases passed in CI (run 43296491059)". It also says "All 13 passed in CI at 2908ce8c4d (run 43296491059); this head changes only the source-conflict record". Both are accurate. Checked by reading the issue body.

New findings

Critical (must fix)

None.

Should address

None.

Suggestions

None.

Verified

  • Scope of the fix commit (checked with git diff between the two heads).
    • Only source_conflicts/candidates.yaml changes, and only inside us-de:liheap-cooling-heating-bill: the question, one added source and the note.
    • No formula, parameter, test or expectation changes. Every round-3 hand check therefore still holds unchanged.
    • There are no new or changed expectations to hand-check.
  • Results by household (by reading). The commit cannot move any result, because no file the model loads changed. CI ran the same 13 cooling cases and the 510 Delaware tests green at this head.
  • Source-conflict guard (from the CI log).
    • Python shard 4 ran test_source_conflicts.py at this head, and every test in it passed. That includes test_candidate_fields, test_candidates_have_unique_well_formed_ids, test_candidates_are_not_yet_registered, test_candidates_are_public and test_conflict_sounding_comments_do_not_grow.
    • No guard ties state: ruled to a record, so the record itself was checked by reading (table above).
    • No code comment changed, so the comment ratchet and KNOWN_UNMARKED are unaffected.
  • Ruling record (checked with the GitHub API).
    • The PR thread now holds comments from the codecov bot, the author and me.
    • The ruling comment carries the date, the candidate id, the decision, the reason and the household it decides.
    • The note's link resolves to that comment.

Axiom

axiom: TheAxiomFoundation/rulespec-us#2175 queued is still valid. Checked by reading the issue.

  • The issue is OPEN and labelled pe-parity. It was updated at 22:13 UTC on 2026-11-12.
  • It names head 3615979844 as both the PR head and the branch head.
  • Matches the head. No formula changed since round 3, so the required output and the 11 companion tests still match the head term for term.
  • Ruling. Interpretation 7 now reads "ruled 2026-11-12 by the project lead: Add Delaware LIHEAP summer cooling electric benefit eligibility #10762 (comment)".
  • CI sentences. Both cite the round-3 run at 2908ce8c4d and say this head changes only the source-conflict record. That is accurate. The run at this head (43317881687) has since passed too.

CI

All 38 checks pass at 3615979844. This is run 43317881687, a pull_request run for this head. It started at 22:13 UTC and finished at 23:27 UTC on 2026-11-12. Nothing is pending and nothing failed.

  • Delaware tests. The Quick Feedback job ran de_liheap_cooling_eligible.yaml on its own (13 passed) and the whole Delaware test folder (510 passed).
  • Coverage. The three Delaware LIHEAP variable files have 100% coverage (54 statements, none missed).
  • Guard tests. Python shard 4 passed 2,596 tests with 10 skipped, the source-conflict guards among them.
  • Merge base. CI tested the head merged into main at e711331df7. Main has changed 89 files since then. None of them is in source_conflicts/, the code-health tests, the Delaware tree, a LIHEAP folder or programs.yaml.

Branch

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. The round-3 item is closed: the project lead's ruling on us-de:liheap-cooling-heating-bill is recorded in a dated comment on this PR, and the candidate's note names the role and links it, as the other ruled entries do. Both suggestions are taken, the commit changes no formula or expectation, CI is green at 3615979844, and the branch merges cleanly with main and with the open cooling siblings.

@hua7450
hua7450 merged commit 295530f into main Nov 13, 2026
38 checks passed
@hua7450
hua7450 deleted the de-liheap-cooling branch November 13, 2026 19:26
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 Delaware LIHEAP summer cooling electric benefit eligibility

2 participants