Skip to content

Pay the Florida LIHEAP Home Energy benefit to cooling-only households - #10740

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

hua7450 merged 5 commits into
mainfrom
fl-liheap-cooling

Conversation

@hua7450

@hua7450 hua7450 commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

Pays Florida's regular LIHEAP Home Energy benefit to households that pay their own electricity bill for cooling, including homes without heating and subsidized tenants with heat in the rent.

Fixes #10739

What and why

Florida pays "One non-crisis benefit per 12 month period" (Fla. Admin. Code R. 73C-26.022(2)(a)). The household must be "responsible for paying the home energy cost", with electricity listed among the energy types (R. 73C-26.022(6)). The manual defines home energy as "The source of heating or cooling in a residential dwelling" (200 P, p. 8) and sets the amount from the matrix, "not the actual energy bill" (700.01, p. 23). The FY2026 plan runs heating from October 1, 2025 to March 31, 2026 and cooling from April 1 to September 30, 2026 (item 1.1). Both seasons fall in FFY2026 and draw on one award. On main, fl_liheap_eligible requires a heating fuel and a heating obligation, so a household whose only energy cost is cooling got $0.

fl_liheap_eligible keeps the existing heating route and adds:

cooling_only = (heating_type != UNSPECIFIED) & has_cooling_expense & (pre_subsidy_electricity_expense > 0)

An applicant responsible for all or part of its home heating and cooling costs is eligible (700.01 E, p. 23; 900.08 A, p. 43). So any reported heating type qualifies when the household pays its own electricity bill for cooling. That includes a home without heating and a subsidized tenant with heat in the rent. This follows Florida's text rather than the all-state cooling-only definition, which covers only heating_type NONE.

The award is the unchanged fuel-neutral matrix amount: the base by income band, plus the elderly, disabled and young-child additions. The variable labels, including fl_liheap_income_limit, now say "home energy" in place of "heating". The registry note says the benefit also covers households that pay their own electricity bill for cooling.

Test plan

Tests were not run locally. CI is their first run and starts when this PR leaves draft.

  • YAML tests with expected values from the FY2026 matrix ("HOME ENERGY BENEFITS AND POVERTY LEVELS", effective October 1, 2025). Eight new cases, no existing case edited:
    • Eligibility:
      • A cooling-only household is eligible. It is ineligible with income of $35,360 above the $32,155 limit and no categorical receipt, with a $0 electricity bill, or with UNSPECIFIED fuel.
      • Two gas-heated households with no heating obligation are eligible when they pay for cooling: one in subsidized housing with heat in the rent, one with gas outside the rent.
    • Payment:
      • A single parent earning $29,120 with children aged 7 and 3 gets $450: the $300 base for size 3 in band 2 plus $150 for the young child.
      • A household with no heating and no cooling cost gets $0.
      • A subsidized single adult with gas heat in the rent earning $14,820 who pays for cooling gets the $350 band 1 base (14,820 ≤ 50% of 32,155).
    • Inputs: wages use Florida's $14.00 minimum wage, as in the existing tests. The electricity bill of $1,873 is EIA's 2024 Florida average of $156.09 a month.
  • Source-conflict register: two backlog entries updated, with no formula change.
    • us-fl:liheap-energy-in-unsubsidized-rent now cites Fla. Admin. Code R. 73C-26.023(4), "The applicant is not eligible for assistance if home energy costs are totally included in the rent and the applicant has no obligation to pay any portion of the energy costs", and is marked open. The heating route on main pays heat in unsubsidized rent under manual 900.01 A; the cooling route here requires the household's own bill, as the rule reads.
    • us-fl:liheap-fy2026-payment-range now covers the Home Energy benefit for heating or cooling and cites plan item 3.6 (p. 11), whose $400 minimum the $350 cooling case falls below. The code follows the matrix (manual 200 Q.4).
    • The eligibility reference now cites R. 73C-26.023, and the cooling route's comment names subsection (4).
  • make format (ruff)
  • Changelog fragment in changelog.d/

Not modeled

  • Who stays at $0: UNSPECIFIED does not open the cooling route. A no-heat household whose electricity is wholly in unsubsidized rent, with no obligation of its own, gets $0, as R. 73C-26.023(4) provides; the heating route still pays gas heat in unsubsidized rent under manual 900.01 A, which the open backlog entry asks to rule on.
  • Large households: cooling-only households use the heating limit, 60% of SMI for every size. The Clearinghouse lists 150% FPG for cooling households of 10 or more; an annual award cannot carry a limit that depends on the season of application.
  • FY2027: the plan's $200-$900 range and $100 high-energy-burden supplement are a heating follow-up.

axiom: TheAxiomFoundation/rulespec-us#2182 queued

🤖 Generated with Claude Code

hua7450 and others added 4 commits November 8, 2026 22:01
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An applicant responsible for all or part of its heating and cooling costs
is eligible (manual 700.01 E and 1100.08 A), so a household with any
reported heating type, including subsidized tenants with heat in the rent,
qualifies when it pays its own electricity bill for cooling. Relabel the
income limit as a home energy limit and add eligibility and benefit cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 (977ce4a).
⚠️ Report is 159 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main    #10740   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         3    +2     
  Lines           37        85   +48     
  Branches         0         1    +1     
=========================================
+ Hits            37        85   +48     
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 the Florida LIHEAP Home Energy benefit to cooling-only households

PR #10740 (author: hua7450). This review covers head b21dd83720: four commits on top of main at 935b24ff4f, 7 files, +244/−8.

Path prefixes:

  • V/ = policyengine_us/variables/gov/states/fl/commerce/liheap/
  • P/ = policyengine_us/parameters/gov/states/fl/commerce/liheap/
  • T/ = policyengine_us/tests/policy/baseline/gov/states/fl/commerce/liheap/

Line numbers refer to b21dd83720.

Summary

The change is one new term in fl_liheap_eligible and three label edits. I read the rule, the manual, the FY2025, FY2026 and FY2027 plans and both matrices before the code, and the code agrees with them:

  • Florida does pay its regular benefit for cooling. The rule allows "One non-crisis benefit per 12 month period", the manual defines home energy as heating or cooling, and both plans run a cooling component from April 1 to September 30.
  • The amount is right. Florida prints one Home Energy matrix for both seasons, with no fuel or season column. The award formula is unchanged and looks up nothing by heating type.
  • The wider condition is sourced. The new term is not limited to homes without heating. It also pays a heated home that fails the heating route: a subsidized tenant with heat in the rent, and a home with no heating obligation. The manual and the FY2025 plan pay both when the household pays part of its heating and cooling costs.
  • No double payment, and nobody loses. The two routes are joined by or into one eligibility flag and one award. Every household that qualified on main still qualifies with the same amount.

All eight new cases check by hand, every new term has a case that would fail without it, and CI is green at the head.

There is one should item. It is about the source-conflict record, not the formula. The body says the register is "not applicable" and that an "existing marker" covers the plan's payment range. Florida has no marker. Its conflicts are backlog items, and this PR's reading touches two of them. The larger one is energy included in unsubsidized rent: the formula now follows the manual on the heating route and the opposite outcome on the cooling route, and the record omits Fla. Admin. Code R. 73C-26.023(4), the rule that speaks to it directly.

Six suggestions follow. None blocks.

Critical (must fix)

None.

Should address

1. Update the Florida source-conflict backlog; the body's "not applicable" is not right.

  • Where:
    • source_conflicts/candidates.yaml:2486-2512 (us-fl:liheap-energy-in-unsubsidized-rent) and :2513-2547 (us-fl:liheap-fy2026-payment-range).
    • V/eligibility/fl_liheap_eligible.py:59-70 (the heating route's rent branch) and :77-89 (the new cooling route).
    • PR body, test plan: "Source-conflict register: not applicable. The existing marker covers the plan's $400-$1,350 range".
  • No marker exists. No Florida file carries a # Source conflict us-fl:... line. The three Florida variable files and P/payment/base_amount.yaml hold unmarked prose comments (one each in KNOWN_UNMARKED), and the conflicts are seven backlog items. CONTRIBUTING.md ("Source conflicts", step 1) says a PR that takes such a reading records it, and "If the backlog already lists the conflict, it updates that item instead."
  • (a) Energy in unsubsidized rent. Three texts bear on it:
    • Fla. Admin. Code R. 73C-26.023(4) (amended 4-25-17): "The applicant is not eligible for assistance if home energy costs are totally included in the rent and the applicant has no obligation to pay any portion of the energy costs." It is not limited to subsidized housing.
    • Manual 900.01 A (p. 39): "Have either an obligation to pay a utility bill directly to a utility company or non-subsidized rent that includes utilities."
    • Manual 1100.04 B(1) (p. 47): the landlord states that "Home energy costs are not included in their rent."
  • What the record says. It lists only the two manual passages, says "No statute is supplied", and notes that PE-US follows 900.01 A. This PR cites the neighbouring R. 73C-26.022 but not 73C-26.023.
  • What the head does. Take two unsubsidized renters in 2026, each one adult aged 40 with $14,820 of wages, with all energy in the rent and no bill of their own:
    • A, gas heat in the rent (heating_type: NATURAL_GAS, heat_expense_included_in_rent: true): eligible through ~subsidized at line 68, $350.
    • B, no heating, cooling in the rent (heating_type: NONE, no electricity bill): $0.
    • Manual 900.01 A pays both $350. R. 73C-26.023(4) pays neither. The head pays A and not B, so one formula now follows both readings.
  • Why it matters. The body lists B under "Not modeled" as a missing input. Under the rule it is the right result, and A is the open question. CONTRIBUTING.md treats regulations as law and ranks law above a manual, so the record needs the rule before anyone can rule on it.
  • (b) The FY2026 payment range. The record's question reads "regular heating payments" and cites only plan item 2.6 (p. 9). Cooling item 3.6 (p. 11) prints the same "Minimum Benefit $400 Maximum Benefit $1,350". The household in T/fl_liheap.yaml Case 31 now gets $350 on the cooling route, below that printed minimum. Following the matrix is right (manual 200 Q.4, p. 9), but the record should name item 3.6.
  • Fix (no formula change needed in this PR):
    • In us-fl:liheap-energy-in-unsubsidized-rent, add R. 73C-26.023(4) as a regulation source and replace "No statute is supplied". Say that the heating route follows 900.01 A and the cooling route requires the household's own bill. Set state: open so the heating-route reading gets a ruling.
    • In us-fl:liheap-fy2026-payment-range, widen the question to the Home Energy benefit and add plan item 3.6, p. 11.
    • Add the R. 73C-26.023 link to the fl_liheap_eligible reference tuple (lines 11-22) and name subsection (4) in the comment at lines 77-84.
    • Rewrite the body's source-conflict line and the unsubsidized-rent row under "Not modeled".
    • Leave KNOWN_UNMARKED alone. The counts stay at 1 for all four Florida files as long as no new conflict-sounding comment line is added.

Suggestions

1. A subsidized tenant with heat in the rent and an unknown fuel still gets $0.

  • Where: V/eligibility/fl_liheap_eligible.py:85-89. The cooling route requires heating_type != UNSPECIFIED with no rent exception. The heating route three lines up (74-76) accepts UNSPECIFIED when heat is in the rent, and T/fl_liheap.yaml Case 22 pays that household.
  • The rule: manual 700.01 E (p. 23): "If the applicant is responsible for all or part of their home heating and cooling costs, then the applicant is eligible for a Home Energy Benefit with no deductions at the same level as other applicants."
  • Household: the Case 31 tenant (one adult, $14,820, receives_housing_assistance: true, heat in the rent, cooling cost, $1,873 electricity bill) with heating_type: UNSPECIFIED in place of NATURAL_GAS. Expected $350; the head gives $0. The heating_type documentation says UNSPECIFIED is "the right value when heat is included in rent and the fuel is unknown".
  • Why only a suggestion: UNSPECIFIED paying $0 is the convention across the LIHEAP states (Default heating_type to electricity and remove the UNSPECIFIED-gated state heating adapters #9754), and the body lists UNSPECIFIED under "Who stays at $0".
  • Fix, if taken: use (heating_type != types.UNSPECIFIED) | heat_in_rent in the cooling term and add the row to Case 12. Otherwise say in the body and changelog that the subsidized tenant must name the building's fuel.

2. Tighten three citations.

  • Scope of 700.01 E and 900.08. Both are subsidized-housing provisions. The comment at fl_liheap_eligible.py:79-81 and the header of eligibility Case 12 (T/eligibility/fl_liheap_eligible.yaml:426-432) use them for every household, including the unsubsidized second row of Case 12. For that row the authority is 900.01 A (p. 39), 1100.04 A (p. 47) and R. 73C-26.022(6).
  • 900.08 A or C. 900.08 A (p. 43) is the exclusion ("totally included in their rent"); 900.08 C states the eligibility "with no deductions". Citing both is clearer.
  • Plan pages. The FY2026 plan comment at line 14 reads # PDF pages 4-5, 8, 45. The cooling items this PR rests on (3.1 to 3.6) are on pages 10-11.

3. Nine parameter files still say "heating".

The three variable labels now say "home energy", which matches the matrix title. These descriptions or labels still say "heating": P/payment/base_amount.yaml, supplement.yaml, income_band_fraction.yaml, income_band_fpg_rate.yaml, child_max_age.yaml, elderly_min_age.yaml, and P/eligibility/smi_rate.yaml, fpg_rate.yaml, fpg_year_lag.yaml. For example, base_amount.yaml:1 reads "Florida provides this base regular heating payment by income band". Renaming them here or in a follow-up keeps the tree consistent.

4. Optional tests that the queued issue already specifies.

rulespec-us#2182 lists three companion tests as "new case", with no PolicyEngine case behind them:

  • the exact limit on the cooling route ($32,155 gives $200; $32,155.01 gives $0);
  • categorical receipt on the cooling route (SNAP with $100,000 of wages gives $200);
  • an FY2025 cooling-only household (aged 67, $18,000 of Social Security: $750 + $100 = $850).

All eight new cases are period 2026, while the registry note claims FY2025-FY2026. The formula has no year branch, so this is optional, but one 2025 case would back the claim.

5. Follow-ups outside this PR.

  • FY2027. The accepted FY2027 plan is now on the Clearinghouse. Heating item 2.4 (p. 9) prints an elderly addition of $250, and cooling item 3.4 (p. 12) prints $100. Both sections print a $200 to $900 range and a new $100 high-energy-burden addition. If the FY2027 matrix confirms different heating and cooling additions, the award will need to know which route applied. P/payment/base_amount.yaml:6-8 still cites the draft plan's $200 to $700. No FY2027 matrix is published (both Clearinghouse file names return 404), so the body's deferral is sound.
  • R. 73C-26.023(5)(d). The same rule sets the income limit at "150 percent of the federally established poverty income guidelines". The two income-limit backlog items (us-fl:liheap-income-limit-manual-sections, us-fl:liheap-large-household-contract-limit) do not cite it. This PR does not touch the limit.

6. Refresh three lines of rulespec-us#2182. See the axiom section.

Verified correct

The ten questions.

  1. Regular benefit for cooling: yes, in both claimed years.
    • R. 73C-26.022(2)(a): "One non-crisis benefit per 12 month period". Subsection (6): "The household must provide proof that it is responsible for paying the home energy cost. Fuel or energy types include electricity, fuel oil, kerosene, wood, natural gas, liquid propane or liquid propane gas." Both quotes in the body are exact. The official page gives the same history (amended 4-25-17).
    • Manual 200 P (p. 8): "Home Energy – The source of heating or cooling in a residential dwelling." Exact. Page 33 lists the assistance type as "Home Energy (Heating or Cooling)".
    • FY2026 plan item 1.1 (p. 4): heating 10/01/2025 to 03/31/2026, cooling 04/01/2026 to 09/30/2026. The FY2025 plan (p. 4) has the same seasons a year earlier.
    • The plan, the manual and the rule agree on this point. No conflict arises on whether cooling is paid.
  2. Amount.
    • One matrix. The FY2026 file is titled "HOME ENERGY BENEFITS AND POVERTY LEVELS", "effective October 1, 2025", with one set of bases ($350, $300, $250, $200) and additions ($100, $100, $150). The FY2025 matrix has the same layout. Neither has a fuel, season or cooling column.
    • Plan. FY2026 cooling item 3.4 (p. 11) lists the matrix's additions: $100, $100 and $150. Item 3.5 checks income, household size and "Other" (the vulnerable-member additions); fuel type and individual bill are unchecked (read from the page image). Items 2.6 and 3.6 print the same range.
    • No bill cap. Manual 700.01 C (p. 23): the amount uses the matrix, "not the actual energy bill". Exact.
    • No fuel key. V/fl_liheap.py is unchanged apart from its label. base_amount[band] reads a select that is always 1 to 4, so a home with heating_type NONE reaches no missing key.
  3. Width of the condition, term by term.
    • heating_type != UNSPECIFIED: the Default heating_type to electricity and remove the UNSPECIFIED-gated state heating adapters #9754 convention. See Suggestion 1 for the one case where it bites.
    • has_cooling_expense: a home with no heating has a home energy cost only if it cools (200 P).
    • pre_subsidy_electricity_expense > 0: stands for the bill that proves the obligation (900.01 A; 1100.04 A, p. 47; rule (6)).
    • A heated home that fails the heating route. Two kinds pass the cooling route, and the sources pay both:
      • A subsidized tenant with heat in the rent who pays for cooling. Manual 900.08 A (p. 43) excludes a subsidized tenant only when "their home heating and cooling costs are totally included in their rent and they have no obligation to pay any portion of the costs". 700.01 E and 900.08 C pay the rest "with no deductions at the same level as other applicants". FY2025 plan item 3.3 B (p. 11) says the same, and so does R. 73C-26.023(4).
      • A home with a fuel but no heating obligation (an explicit has_heating_expense: false, or a zero bill for the primary fuel) that pays an electricity bill for cooling. It has "an obligation to pay a utility bill directly to a utility company" (900.01 A).
    • Subsidized tenants with all energy in the rent stay at $0. With no cooling cost or no electricity bill, both routes fail. That matches 900.08 A.
    • Tenants with a utility allowance. 900.08 B subtracts the housing energy subsidy "For Crisis Assistance Only". The Home Energy benefit has no deduction (900.08 C), and the model applies none. The FY2027 plan (p. 11) adds that a utility account in the household's name, or an allowance letter when the landlord holds the account, proves responsibility.
    • The FY2026 plan answers No to differing policies for renters, subsidized renters and utilities in rent, in both the heating and cooling sections (pp. 8 and 10, read from the page images).
  4. One benefit per 12 months.
    • The return at lines 90-94 is (size > 0) & (income_eligible | categorical) & ((responsible & fuel_qualifies) | cooling_only). main had the same expression without | cooling_only, so the new set contains the old one.
    • fl_liheap multiplies one award by one flag. A household with both costs gets one award.
    • No existing Florida case sets has_cooling_expense, so none changes. The Florida tree passes in CI.
  5. Changed expectations: none. Eight cases are added and none is edited.
  6. Mutation check. Every new term is pinned:
    • the route itself: eligibility Case 8;
    • the income gate on the route: Case 9;
    • pre_subsidy_electricity_expense > 0: Case 10;
    • != UNSPECIFIED: Case 11;
    • not limited to NONE: Case 12, both rows;
    • has_cooling_expense: fl_liheap.yaml Case 30.
  7. Keys and non-residents. The new term reads two plain inputs and uses no parameter key. Nothing state-gated is used as a key. The Microsimulation job passes.
  8. Periods. has_cooling_expense, pre_subsidy_electricity_expense and heating_type are annual, like the variable. The PR adds no add() call.
  9. Registry. programs.yaml:1167 says the benefit covers heating "and also households that pay their own electricity bill for cooling", and drops "cooling" from the out-of-scope list. That matches the code. The entry has no verified_years.
  10. National list. gov.hhs.liheap.regular_payments is not on main. Add a national LIHEAP total, an Illinois regular heating payment and LIHEAP cooling registry notes #10730 adds it and already lists fl_liheap, so nothing is needed here.

Income limit for cooling households. Plan items 2.1 and 3.1 print the same table (60% of state median income, sizes 1 to 9), and contract G(8)c (p. 12) sets one limit "For Cooling/Heating and Crisis assistance". Only the Clearinghouse summary table says "For Cooling and Crisis: 150 FPG for households with 10+ members". Using the heating limit follows the plan and the matrix. The open item us-fl:liheap-large-household-contract-limit already covers the contract wording.

Hand checks. FY2026 limits come from the matrix: $32,155 for one person and $51,943 for three. Band tops are $16,078 for one person and $25,972 and $36,360 for three.

Case Inputs Working Expected
Eligibility 8 NONE, cooling, $1,873 bill, wages $14,820 14,820 ≤ 32,155; cooling route open true
Eligibility 9 same, wages $35,360 (17 × 2,080) 35,360 > 32,155 and above the floor, 1.1 × 15,650 = 17,215; no SNAP, TCA or SSI false
Eligibility 10 same as 8, bill $0 no bill; NONE fails the heating route false
Eligibility 11 UNSPECIFIED, heat not in rent both routes need a known fuel false
Eligibility 12, row 1 subsidized, gas heat in rent, gas bill $0, cooling, $1,873 heating route: subsidized with no heating expense fails; cooling route open true
Eligibility 12, row 2 gas bill $1,200 outside rent, has_heating_expense false, cooling, $1,873 heating route fails on the explicit false; cooling route open true
fl_liheap 29 ages 31, 7, 3; wages $29,120 (14 × 2,080); NONE, cooling size 3; 25,972 < 29,120 ≤ 36,360, band 2: $300; child aged 3: + $150 true, $450
fl_liheap 30 NONE, no cooling cost, $1,873 bill no home energy cost false, $0
fl_liheap 31 subsidized, gas heat in rent, cooling, wages $14,820 14,820 ≤ 16,078, band 1: $350; no additions true, $350
  • Inputs. $14,820 is 20 × (39 × 14 + 13 × 15). The $1,873 electricity bill is 12 × $156.09, EIA's 2024 Florida average monthly residential bill (Table 5A).

Other checks.

Axiom line assessment

Valid: axiom: TheAxiomFoundation/rulespec-us#2182 queued.

  • State. Fix NYC CDCC age restriction unit #2182 is open, labelled pe-parity, created 2026-11-12, and names head b21dd83720.
  • Dispatch-ready. It has module paths with corpus status, verbatim rule, manual, plan and matrix text, three required outputs, and eleven companion tests derived by hand from the sources.
  • Matches the head. The cooling term, the unchanged award, the case counts (80 in 7 files; 12 and 31 in the two changed files) and the scope all match.
  • Three lines to refresh (Suggestion 6):
    • Interpretation 13 says the branch cites 1100.08 A, page 43. The head and the body cite 900.08 A; the last commit fixed it.
    • Interpretation 4 says the body states that cooling costs in rent have no input. The body says the PR does not read tenant_pays_utilities.
    • "They have not yet passed in CI at this head" is now out of date.
  • After the should item: interpretation 7 says "No candidates.yaml entry is specific to cooling". Update it, and add R. 73C-26.023(4) to the source table, once the backlog items change.

CI status

39 pass, 0 failed, 0 pending (run 43154245891 on head b21dd83720, pull_request, 2026-11-12 04:21 to 05:55 UTC). Three workflow-level entries show as skipped duplicates. I re-checked gh pr checks 10740 at the end of this review.

  • Quick Feedback ran the two changed test files at the head: fl_liheap_eligible.yaml 12 passed and fl_liheap.yaml 31 passed. Its third location passed 383 cases.
  • Also passed: PR validation (guard tests, lint, changelog), Household API Partners, Microsimulation, all 10 Rest shards, all 11 Baseline shards, all 9 Contrib shards, Package and compatibility, and codecov patch and project.

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, to the source-conflict record and not to the formula. The body says the register is "not applicable" and that an existing marker covers the plan's range, but no Florida file carries a marker, and this PR's reading touches two backlog items. The larger one is us-fl:liheap-energy-in-unsubsidized-rent: the formula now pays a renter with gas heat in unsubsidized rent ($350) and not one with cooling in unsubsidized rent ($0), and the record omits Fla. Admin. Code R. 73C-26.023(4), which speaks to it directly. Please update both backlog items and the body line (Should Address 1 in the report above).

The formula itself checks out: Florida pays one Home Energy benefit for heating or cooling from one matrix, the wider cooling route is sourced, nobody who qualified on main changes, and every new term is pinned by a test. The six suggestions are optional. CI is green at b21dd83720.

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

hua7450 commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks, David. Recorded, with no formula change, in 977ce4aaae:

  • us-fl:liheap-energy-in-unsubsidized-rent now cites R. 73C-26.023(4) as a regulation, replaces "No statute is supplied" with the rule's text, says the heating route follows 900.01 A while the cooling route requires the household's own bill, adds an example and is set to open for a ruling on the heating route.
  • us-fl:liheap-fy2026-payment-range now covers the Home Energy benefit and cites plan item 3.6 (p. 11).
  • fl_liheap_eligible cites R. 73C-26.023, and the cooling comment names subsection (4). The body's register line and the unsubsidized-rent row are rewritten. KNOWN_UNMARKED is unchanged.

@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 the Florida LIHEAP Home Energy benefit to cooling-only households

PR #10740 (author: hua7450). This round covers head 977ce4aaae: one commit, "Record Florida rule 73C-26.023(4) in the source-conflict backlog", on top of the head reviewed in round 1 (b21dd83720). The PR is now 8 files, +272/−21.

Line numbers refer to 977ce4aaae.

Summary

The fix commit is a record change only, and it does what round 1 asked.

  • The should item is fixed. Both Florida backlog items now carry the missing source, the PR's reading and the PR's link. us-fl:liheap-energy-in-unsubsidized-rent cites Fla. Admin. Code R. 73C-26.023(4) as a regulation and is open for a ruling on the heating route. us-fl:liheap-fy2026-payment-range covers the Home Energy benefit for heating or cooling and names plan item 3.6.
  • Every quote matches its source. I re-read the rule, plan pages 9 and 11, the manual pages and the matrix.
  • No formula or expectation changed. The commit edits one reference line and three comment lines in fl_liheap_eligible.py and the two backlog items. No test, parameter, registry or changelog file changed.
  • The source-conflict guard still passes. fl_liheap_eligible.py still has one conflict-sounding comment line, equal to its KNOWN_UNMARKED count. The backlog file parses with no duplicate id on the tree merged with main.
  • CI is green at the head, 39 of 39 checks.

No critical or should item is open. Two optional suggestions on the wording of the record follow.

Prior findings

Finding Status Evidence
Should 1. Update the Florida source-conflict backlog; the body's "not applicable" is not right Fixed Record checked field by field under "Verified" below. source_conflicts/candidates.yaml:2486-2522 and :2523-2559; fl_liheap_eligible.py:14 and :85-87; PR body test plan and "Not modeled". A backlog record has no test of its own, so the check is the record, its sources and the guard.
Suggestion 1. A subsidized tenant with heat in the rent and an unknown fuel still gets $0 Not taken (optional) The cooling term is unchanged. The body still lists UNSPECIFIED under "Who stays at $0".
Suggestion 2. Tighten three citations Not taken (optional) The comment at fl_liheap_eligible.py:81-82 and the plan page comment at line 15 are unchanged.
Suggestion 3. Nine parameter files still say "heating" Not taken (optional) No parameter file is in the diff.
Suggestion 4. Optional tests that the queued issue specifies Not taken (optional) No test file changed.
Suggestion 5. Follow-ups outside this PR Outside this PR The body keeps FY2027 as a heating follow-up.
Suggestion 6. Refresh three lines of rulespec-us#2182 Partly taken (optional) The issue names the new head and interpretation 4 is rewritten. See the axiom section for the lines that are still old.

New findings

Critical (must fix)

None.

Should address

None.

Suggestions

1. pe_us.follows still reads unknown on the unsubsidized-rent item.

  • Where: source_conflicts/candidates.yaml:2513.
  • What: The item's note now says exactly what the code follows: the heating route follows manual 900.01 A, and the cooling route follows R. 73C-26.023(4). The field still says unknown. The file's legend offers conflicting-source for code that follows the other source against the law-side reading, and twelve other open items use it.
  • Fix, if taken: set follows: conflicting-source, since the heating route is the reading put up for a ruling. Leaving unknown is acceptable if one value cannot cover both routes; the note carries the detail either way.

2. Two wording points in the record.

  • Plan citation, candidates.yaml:2533-2534. The citation reads "FY2026 LIHEAP State Plan items 2.6 (heating) and 3.6 (cooling) #page 9,11" with one link ending #page=9. Item 3.6 is on page 11 and has no link of its own, and the neighbouring items write pages as "p.9". Two guidance sources, one per page (#page=9 and #page=11), would let a reader open each item directly.
  • Example, candidates.yaml:2509-2511. "the same renter with no heating and cooling in the rent" can be read two ways. "with no heating, and with cooling included in the rent" is clearer.

Verified

What changed (from git diff of the two heads, which I ran).

  • The fix commit touches two files, +29/−14: source_conflicts/candidates.yaml (+25/−13) and fl_liheap_eligible.py (+4/−1).
  • That accounts for the PR totals. Files go from 7 to 8 because candidates.yaml is new to the PR. Deletions go from 8 to 21: the 13 backlog lines that were rewritten. The fourteenth deleted line is a comment line the PR had added itself, so against main it is one fewer addition, not a deletion: 244 + 29 − 1 = 272.
  • In fl_liheap_eligible.py the only changes are the new reference at line 14 and the comment at lines 85-87. The cooling_only expression and the return are the same as at round 1.
  • The diff between the two heads is empty for the tests, the parameters, programs.yaml and the changelog. No expectation changed.

us-fl:liheap-energy-in-unsubsidized-rent, field by field (read at the head; structure also checked by the guard, see below).

Field At the head Check
id, program, years unchanged; liheap; 2025 to 2026, federal fiscal The rule dates from 4-25-17 and covers both years.
question "Is a Florida household whose energy costs are wholly included in unsubsidized rent, with no obligation of its own, eligible for LIHEAP?" States the conflict the three texts raise.
sources regulation R. 73C-26.023(4); manual 900.01A (p. 39) and 100.01 (p. 4); manual 1100.04B(1) (p. 47) Three sources, valid kinds. Both documents open at the links given.
readings.statute quotes the rule and adds the 1100.04B(1) landlord statement The quote is exact (see below). The opening words "No statute is supplied" stay, as in other items that rest on a regulation; they are accurate, since the text is a rule.
readings.other 900.01A and 100.01 allow "non-subsidized rent that includes utilities" and payment to the landlord Exact, pages 39 and 4.
example renter aged 40, $14,820 of wages: $350 under 900.01A and $0 under the rule, for heat in the rent and for cooling in the rent Right by hand: size 1, 14,820 ≤ 16,078, band 1, base $350, no additions.
pe_us.follows unknown Valid value. See Suggestion 1.
pe_us.code fl_liheap_eligible.py The file exists and holds both routes.
pe_us.prs #9969 and #10740 Both in the required form.
state open As round 1 asked.
note heating route follows 900.01A and 100.01; cooling route requires the household's own electricity bill, "as R. 73C-26.023(4) reads"; a ruling is needed on the heating route Matches the formula by hand trace (below).

us-fl:liheap-fy2026-payment-range, the changed fields.

Field At the head Check
question "Does Florida's FY2026 Home Energy benefit, for heating or cooling, range from the plan's estimated $400 to $1,350 or from the October 2025 payment matrix's $200 to $700?" Widened as asked. The matrix prints "$350 (up to $700)" down to "$200 (up to $550)".
sources[0] plan items 2.6 (heating) and 3.6 (cooling), pages 9 and 11 Both items print the range (below). See Suggestion 2 for the format.
readings.other "Plan items 2.6 and 3.6 print the FY2025 estimates, a $400 minimum and a $1,350 maximum." The FY2025 plan prints the same two figures in its items 2.6 and 3.6.
pe_us.prs #9969 and #10740 Added.
note the cooling route "can pay $350, below the printed $400 minimum" fl_liheap.yaml Case 31 pays $350 on the cooling route.
state, follows unreviewed, unknown Unchanged; round 1 did not ask for a change.

Quotes against the sources (each read from the document).

  • Fla. Admin. Code R. 73C-26.023(4): "The applicant is not eligible for assistance if home energy costs are totally included in the rent and the applicant has no obligation to pay any portion of the energy costs." Exact. The page's history line reads "Amended 4-25-17".
  • FY2026 plan, item 2.6 (p. 9): "Minimum Benefit $400 Maximum Benefit $1,350".
  • FY2026 plan, item 3.6 (p. 11): "Minimum Benefit $400 Maximum Benefit $1,350".
  • Manual 900.01 A (p. 39): "Have either an obligation to pay a utility bill directly to a utility company or non-subsidized rent that includes utilities."
  • Manual 1100.04 B(1) (p. 47): "Home energy costs are not included in their rent."
  • Manual 100.01 (p. 4): payment goes "to the energy vendor or landlord (if utilities are included in the rent)". Manual 200 Q.4 (p. 9): "Must follow the current benefit payment matrix provided by DEO."

The note against the formula (hand trace of fl_liheap_eligible.py at the head).

  • Renter A, gas heat in unsubsidized rent, no bill. heat_in_rent is true and the unit is not subsidized, so responsible is true at line 69. NATURAL_GAS passes fuel_qualifies. Eligible, $350. This is the 900.01 A reading.
  • Renter B, no heating, cooling in the rent, no electricity bill. NONE fails fuel_qualifies. cooling_only needs pre_subsidy_electricity_expense > 0 at line 91, so it is false. $0. This is the rule's reading.
  • The record, the body and the comment at lines 85-87 all describe exactly this.

Tests behind each reading (by reading the tests; both files pass in CI at this head).

  • Heating route: eligibility Case 4, first household (unsubsidized, heat in the rent, no heating bill) expects true.
  • Cooling route: eligibility Case 10 (no heating, cooling cost, $0 electricity bill) expects false.
  • The $350 below the plan minimum: fl_liheap.yaml Case 31.

Source-conflict guard (#10287) on the tree merged with main.

  • By reading the pattern. The three new comment lines are "... UNSPECIFIED does not. Cooling", "wholly in the rent with no obligation of its own pays nothing, as" and "R. 73C-26.023(4) provides." None contains "source conflict", "discrepancy", "contrary to", "in practice", "conflicts with" or a "manual says" form. The nearest alternative needs the word law, statute, code, regulation or rule directly before "says", "states" or "provides", and then "but", "while", "whereas" or "however" within 80 characters. Here "provides" follows the citation "(4)" and ends the sentence, so it does not match.
  • By a run. I called the guard's own functions on the head merged with main at fb00590f7a. The four Florida LIHEAP files each count 1, equal to their KNOWN_UNMARKED lines. The only matching line in fl_liheap_eligible.py is line 60, the existing "Source conflict: manual 900.01A ..." comment. test_conflict_sounding_comments_do_not_grow, test_candidate_fields, test_candidates_have_unique_well_formed_ids, test_candidates_are_public, test_candidates_are_not_yet_registered and the marker and pin tests all passed. One tokenizer self-test in that file depends on the Python version and did not pass on my older interpreter; it passes in CI and does not read the PR's files.
  • In CI. Rest (Python shard 2) ran test_source_conflicts.py on the merge of this head into main and passed every test in it, including the ratchet and the backlog tests.
  • Backlog file on the newest main. main added three Missouri items after that run (Let Missouri aged, blind and disabled people who don't receive SSI spend down #10629). I parsed the file from the head merged with main at 24939d2701: 432 items, 432 distinct ids, both Florida items intact. That commit touches no Florida file and not the guard.
  • KNOWN_UNMARKED is unchanged, as the author says.

Reference. The new link in the fl_liheap_eligible reference tuple (line 14) resolves and shows subsection (4). The reference-URL code-health tests passed in Rest (Python shard 1).

Body. The test-plan line now reads "two backlog entries updated, with no formula change" and lists both items. The "Who stays at $0" row says the no-heat household with electricity wholly in unsubsidized rent gets $0 "as R. 73C-26.023(4) provides", and that the heating route still pays gas heat in unsubsidized rent under manual 900.01 A, "which the open backlog entry asks to rule on". The body, the backlog item and the queued issue say the same thing.

Other main-side guards. The commit touches no income list, so #9558, #10317 and #10408 are unaffected. The partner-contract check added to main since round 1 (#10813) reads the partner test folder, which this PR does not touch.

Axiom

Valid: axiom: TheAxiomFoundation/rulespec-us#2182 queued.

  • State. Fix NYC CDCC age restriction unit #2182 is open and labelled pe-parity. It was last edited on 2026-11-12 at 17:10 UTC, with the fix commit.
  • Names the new head. 977ce4aaae appears in the objective and under "PolicyEngine implementation".
  • Matches the fix. Interpretation 4 is now "Energy wholly in unsubsidized rent (open; candidate us-fl:liheap-energy-in-unsubsidized-rent)". It gives the rule, the two manual passages, the $0 on the cooling route and the open ruling on the heating route. Interpretation 9 names plan items 2.6 and 3.6 and us-fl:liheap-fy2026-payment-range.
  • Lines still old (optional; the rest of round 1's Suggestion 6):
    • Interpretation 13 still says the branch cites 1100.08 A. The head cites 900.08 A.
    • "The PR has no review yet" and "They have not yet passed in CI at this head" are out of date. CI is green at this head.
    • The module table, the verbatim source text and the ingest checklist name only R. 73C-26.022. Interpretation 4 relies on R. 73C-26.023(4), and the "Variables" line says the formula file gained "a rule 73C-26.022 reference" when it now cites both rules.
    • Interpretation 7 still ends "No candidates.yaml entry is specific to cooling", although the payment-range item now names the cooling route.

CI

39 pass, 0 failed, 0 pending (run 43266430082, pull_request, 2026-11-12 17:09 to 18:17 UTC, on the merge of head 977ce4aaae into main at ac1962ca4f). I re-checked gh pr checks 10740 at 18:18 UTC, at the end of this review.

  • The PR's own tests ran and passed at this head. Quick Feedback: fl_liheap_eligible.yaml 12 passed, fl_liheap.yaml 31 passed, and a wider selection that includes all seven Florida LIHEAP test files, 383 passed.
  • The guard ran and passed. Rest (Python shard 2) holds test_source_conflicts.py.
  • Also passed: PR validation, Household API Partners, Microsimulation, all 10 Rest shards, all 11 Baseline shards, all 9 Contrib shards, Package and compatibility, and codecov patch and project.
  • I ran no PolicyEngine tests locally. My only runs were the guard's functions and the backlog parse on the merged trees, described above.

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 fix commit is a record change only and does what round 1 asked: us-fl:liheap-energy-in-unsubsidized-rent now cites R. 73C-26.023(4) as a regulation and is open for a ruling on the heating route, us-fl:liheap-fy2026-payment-range covers the Home Energy benefit and names plan item 3.6, and the description says the same. Every quote matches its source, no formula or expectation changed, and the source-conflict guard still passes on the tree merged with main.

Two optional wording suggestions on the record are in the report above. CI is green at 977ce4aaae.

@hua7450
hua7450 merged commit 181c697 into main Nov 12, 2026
39 checks passed
@hua7450
hua7450 deleted the fl-liheap-cooling branch November 12, 2026 18:48
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 Florida LIHEAP Home Energy benefit for cooling-only households

2 participants