Repository navigation
Conversation
- Encode FY2025: base amounts $1,000/$750/$550/$400 and the large-household rule (greater of 60% SMI and 150% FPG, bands keyed to FPG percentages); FY2025 rounds the SMI limit half up, FY2026 truncates like the HHS table. - Count military and railroad retirement; floor each income source at zero; count gambling net of losses, capped at winnings. - Count all income, earnings included, of members 18 and older and of 16- and 17-year-olds who are not full-time students (manual 1200.01D, followed over plan item 1.9). - Read take-up-gated tanf instead of fl_tca for income and categorical eligibility. - Shorten the registry note, fix the coverage-line order, the household-size page and the changelog line; use add() for the disabled check. - Add period-2025, income-source, band-cutoff and take-up cases; tidy tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # policyengine_us/programs.yaml
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9969 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 4 6 +2
Lines 76 126 +50
Branches 2 3 +1
=========================================
+ Hits 76 126 +50
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…n rent An UNSPECIFIED heating type now qualifies only when heat is included in rent. Document the manual conflicts on large-household income limits, heat in rent and the undocumented-applicant rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # policyengine_us/programs.yaml
One reference entry per source; single-page citations keep the page only in the href; multi-page titles end with a quoted #page list and the href opens the first cited page; variable references use '# PDF pages ...' comments above multi-page hrefs (CLAUDE.md, PolicyEngine/policyengine-us PR 10009). Reference lines only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Calls liheap_smi_limit from PR 10019 instead of repeating the HHS floor-then-floor calculation. Limits are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR Review: Add Florida LIHEAP regular heating assistancePR #9969: Add Florida LIHEAP regular heating assistance (author: hua7450, head Scope: Florida's LIHEAP Home Energy Benefit for the heating season. FloridaCommerce (formerly the Department of Economic Opportunity) runs it through local agencies and, since FY2026, a statewide portal. The PR covers:
Crisis, cooling, weatherization, equipment, automatic enrollment and the FY2025 means-tested veterans route are out of scope. The PR changes 31 files: 17 parameters, 6 variables, 6 test files (61 cases), Overall: the FY2025 and FY2026 policy values are right for households of up to 12 people.
There is one critical finding:
The three should-address items:
All 61 cases pass locally at the head and on the merged tree. The model outputs quoted below were reproduced by running the head code. Values that a proposed fix or a published table implies are hand computations and are labelled as such. The S3 claims were confirmed by mutating the code and rerunning the PR's tests. Path prefixes used below:
Line numbers refer to head Source Documents
Critical (Must Fix)C1. From 15 people, the FY2026 limit falls below the federal 110%-of-poverty floor, so protected households get $0
Should AddressS1. Size 13: the limit and the bands come from different readings of one printed row
S2. Six parameter descriptions fall outside the house template, and two describe a rule the head no longer hasAll 17 descriptions name the program, and 16 end with "under the Low Income Home Energy Assistance Program." The template's verbs are limits, provides, sets, excludes, deducts and uses. These six do not fit:
S3. Two small pieces of logic have no test that would fail if they brokeEach mutation below, applied to the head on its own, still passes all 61 cases.
Two control mutations confirm the method: dropping the eligibility size gate fails
Consistency: #9967 S3, #9972 S3, #9968 S2 and #9975 S4 rated untested logic SHOULD. SuggestionsG1. Backfilled FY2023-FY2024: two small changes would reproduce FY2024 exactly
G2. FY2027: the draft plan is published and supports the PR's choices
G3. Income-definition notes
G4. References polish
G5. Code clarity in the size-13 machinery
G6. Test hygiene
G7. PR body and issue housekeeping
Verified correct
Checklist results (LIHEAP wave 2a)
CI status28 of 28 checks pass at Branch status
Axiom line
Next steps
1 critical and 3 should-address findings, plus 7 suggestions. Verdict: REQUEST_CHANGES |
DTrim99
left a comment
There was a problem hiding this comment.
Requesting changes for 1 critical and 3 should items; details in the full report above. Every printed cell of the FY2026 (sizes 1–12) and FY2025 (sizes 1–20) matrices reproduces, as do the bases and additions. Income treatment matches the manual, all 61 tests pass, and CI is green. There's no #9558 conflict (Florida excludes unemployment). Critical 1: from 15 people up, the FY2026 limit (60% of SMI) falls below the federal floor of 110% of poverty in 42 USC 8624(b)(2)(B) (plan p45, contract G(8)e). Example: 15 people with $100,000 get $0 at head, but they're protected ($101,915 floor) and should get $200. (1) Size 13 takes its limit from the 60% rule but its bands from the printed 100%-SMI row, so 13-person households fall out of step with sizes 12 and 14. (2) Six parameter descriptions are off the house template. (3) Logic that passes every test even when broken on purpose: the size-0 income-limit mask and the bill term in the non-rent responsibility branch.
- C1: From 15 people the FY2026 limit (60% of SMI) is below the federal 110%-of-poverty floor, so protected househol - S1: Size 13 takes its limit from the 60% rule but its bands from the printed 100%-SMI row - S2: Six parameter descriptions fall outside the house template; two describe a student-status rule the head no lon - S3: Two small pieces of logic have no test that would fail if they broke Also applies the in-scope suggestions. Tests not run locally; CI validates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for the review. Fixes pushed in f2f6f3f. The branch also merges upstream/main (PRs 9558 and 10046). Florida counts no unemployment compensation and deducts no premiums, so neither changes Florida results. The new and rewritten expected values come from hand arithmetic, and CI runs the tests.
|
PavelMakarchuk
left a comment
There was a problem hiding this comment.
Approving. The round-1 critical (C1, the 110% FPG floor) and S1-S3 are resolved, the size-13 reading is the only one within the federal ceiling, and CI is green. S4 (exact-cent floor boundary) and S5 (link anchor) are small and non-blocking. Please apply them together with #9968, because gov/hhs/liheap/fpg_floor.yaml must stay byte-identical across both PRs to avoid a merge conflict.
Program Review
IDs: C = critical, S = should address, G = suggestion. C1, S1-S3 and G1-G7 carry over from the round-1 review (DTrim99). S4-S5 and G8-G17 are new in this round.
Paths: 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/, H/ = policyengine_us/parameters/gov/hhs/liheap/. Line numbers refer to the reviewed head.
Source Documents
- PDF: Florida FY2026 LIHEAP State Plan (49 pages)
- PDF: Florida FFY2026 LIHEAP Payment Matrix (Heat-Cool) (1 page)
- PDF: Florida draft FFY2027 LIHEAP Model Plan (43 pages; file page = printed page + 1)
- PDF: Palm Beach County item 3E-2, Amendment One to FloridaCommerce agreement E2249 (19 pages; file page = printed page + 2)
- PDF: Florida LIHEAP Policies and Procedures Manual, effective May 27, 2022 (73 pages)
- PDF: Florida FY2025 LIHEAP State Plan (52 pages)
- HTML: 42 U.S.C. 8624(b)(2)(B), HHS LIHEAP IM 2025-02, HHS LIHEAP IM 2026-01, Florida LIHEAP portal FAQ
- Year: FY2025 (period 2025) and FY2026 (period 2026) are claimed. Period 2027 is an unverified carry-forward that now cites the draft FFY2027 plan.
- Scope: Incremental — changes since the prior review, plus unresolved prior findings
- Reviewed head SHA:
f2f6f3f706b764649b6cf8e08b8e6826e4358952 - Mode: incremental from
7c5688f9ec8f2bda6cc42c6560838bff4f90ab16
Branch Status
- 13 commits ahead of
mainand 38 behind (merge base9560e7f183); merges cleanly. The staleness did not affect any finding (informational). Theprograms.yamlCalifornia SSP hunk is merge noise frommain. H/fpg_floor.yamlis byte-identical to the file that sibling #9968 (Georgia) adds, and identical add/add changes merge in either order. Apply S5 to both PRs so the file stays identical, and the S4 rounding toga_liheap_eligible.pytoo.
Critical (Must Fix)
None. C1 is fixed (see Prior Findings).
Should Address
S4. Income of exactly 110% of the guideline passes the floor's strict "less than"
- Defect:
92_650 * 1.1evaluates to101915.00000000001in float64, soincome < guideline * p_hhs.fpg_flooradmits income equal to the floor. Reproduced at head (period 2026, no receipt): 15 people with exactly $101,915 are eligible for $200; the correct result is $0 (the limit is $98,320). The same happens for 16 people at $107,965, 17 people at $114,015, and in period 2027 (95,480 × 1.1 = 105,028.00000000001). - Where:
V/eligibility/fl_liheap_eligible.py:39.T/fl_liheap.yamlCase 25 (lines 842-859) tests $101,914.99 and $101,915.01 only, so the<→<=mutation survives. The guideline lag is already pinned (row 4 fails with lag 0). - Evidence: 42 U.S.C. 8624(b)(2)(B) protects income "less than 110 percent of the poverty level". The FY2026 plan assurances and contract G(8)e use the same words.
- Fix:
- Compare with a cent-rounded floor, for example
income < np.round(guideline * p_hhs.fpg_floor, 2). - Add a size-15 row at exactly
101_915that expectsfl_liheap_eligible: falseandfl_liheap: 0. - Make the same change in #9968 (
ga_liheap_eligible.py:35).
- Compare with a cent-rounded floor, for example
- Severity: validators split SHOULD / SUGGESTION; SHOULD, as on #9968, because it is missing boundary rounding in otherwise correct logic.
S5. The 42 U.S.C. 8624 links do not point to (b)(2)(B)
- Defect: three references open the whole section, not the cited paragraph.
- Where:
H/fpg_floor.yaml:11(the only reference of the new shared parameter),V/eligibility/fl_liheap_eligible.py:12andV/eligibility/fl_liheap_income_limit.py:19. - Evidence: LII publishes the anchor
#b_2_B(name="b_2_B"in the page source). The reference standard gives this bare URL as its "too vague" example. Inparameters/at this head, 354 Cornell U.S.C. hrefs carry an anchor and 69 do not. - Fix: use
https://www.law.cornell.edu/uscode/text/42/8624#b_2_Bin all three places. Make the same change toH/fpg_floor.yamlin #9968. - Severity: validators split SHOULD / SUGGESTION; SHOULD, as on #9968, because the link does not open on the corroborating text.
Suggestions
- G8. Plan item 2.6 against the payment matrix. This is a documented source conflict, not a defect: code-path and 600-dpi checks confirm that FY2026 plan item 2.6 prints $400 / $1,350 while period 2026 pays $200 / $700, but the operative FFY2026 matrix, draft FFY2027 item 2.6 (file page 9), contract D(10)b and manual Part 200 Q.4 (page 9) support the repo, and
V/fl_liheap.py:79-81records it. Add the same note toP/payment/base_amount.yaml:2-4. Change the header atT/fl_liheap.yaml:1to cite the matrix, not plan page 9, for the 350 / 300 / 250 / 200 bases. - G9.
P/eligibility/fpg_year_lag.yamlnow sets the guideline year of the federal floor but cites only the FY2025 matrix. Add HHS LIHEAP IM 2025-02 (2025 guidelines mandatory in FY2026) and IM 2026-01 (2026 guidelines mandatory in FY2027) there or atV/eligibility/fl_liheap_eligible.py:36-38. No value changes. Optionally add 42 U.S.C. 8622(8) ("poverty level") and a Pub. L. 103-252 §306(a) wording note toH/fpg_floor.yaml(both PRs). - G10.
V/eligibility/fl_liheap_eligible.py:17-18: G(8)e (the 110% clause) is on file page 13, but the href opens page 12, which ends with the contrary G(8)c. Split it into#page=12(G(7)c, G(8)a) and#page=13(G(8)e). - G11.
P/income/sources/unearned.yaml:45-46: the manual href moved from#page=49(1200.01, countable income) to#page=39(household composition), and the title holds a page range. Split it into a 1200.01 entry (#page=49) and a 900.02B / 900.03B(1) entry (#page=39). - G12.
V/eligibility/fl_liheap_eligible.py:53-59relies on FY2025 plan item 2.3 (pages 8-9), but the reference tuple has no FY2025 plan. AddFL_Plan_2025.pdf#page=8with# PDF pages 8-9. - G13. Wording:
P/income/sources/earned.yaml:1andunearned.yaml:1repeat theadult_agevalue ("18"); "adult members" will not go stale. TheP/payment/base_amount.yaml:29title could add "(estimated minimum $200, maximum $700)". Use "Section" consistently (smi_rate.yaml:17,base_amount.yaml:29). - G14. Source-conflict notes: name contract G(7)d and G(8)c in the comment at
V/eligibility/fl_liheap_income_limit.py:34-51(G(1) and D(10)b defer to the matrix). Mention the size-13 departure in the Floridaprograms.yamlnote. Mention the G(8)a "whichever is lower" rule atV/eligibility/fl_liheap_eligible.py:26-32. - G15. Tests: add a size-14 row ($60,000 → $300; limit $96,465) and a 15-person floor case built from people (2 adults with $100,000, 13 children, one aged 5 or younger → $350). Optional: a period-2027 floor case (limit $103,148, floor $105,028) and an
integration.yamlas in the IL, KS, KY and OR folders. Fix the copied header atT/eligibility/fl_liheap_categorically_eligible.yaml:1. - G16. Code tidiness: three variables compute the same lagged guideline (
fl_liheap_eligible.py:35,fl_liheap_income_limit.py:52-53,fl_liheap.py:25-32); anfl_liheap_fpgintermediate is optional. The long source-conflict comments could move to parameter comments. - G17. Follow-up, out of scope: no merged LIHEAP state applies the 110% floor. An issue could adopt
gov.hhs.liheap.fpg_floorin other states whose limit is 60% of SMI alone.
Investigated and cleared
- Contract G(7)d / G(8)c against the 60%-SMI limit: rejected. Plan item 2.1 and the matrix govern; G(1) and D(10)b defer to the matrix.
- Printed size-13 row ($157,686) and portal FAQ $13,141: rejected. The row is 100% of SMI, contradicts the matrix footnote and exceeds the federal ceiling ($122,475); the PR documents the departure.
- Contract G(1) "National Poverty Guidelines" against the SMI bands: consistent. G(1) defers to the matrix and sets no values.
Prior Findings
| ID | Finding | Status |
|---|---|---|
| C1 | FY2026 limit below the 110%-FPG floor from 15 people | RESOLVED: H/fpg_floor.yaml (1.1), floor test at V/eligibility/fl_liheap_eligible.py:39, Case 25. Exact-boundary edge is S4 |
| S1 | Size-13 limit and bands from different readings | RESOLVED: 60% of SMI for both ($94,610; 47,305 / 66,227 / 80,419); override and published_band_* deleted with no dangling references; Case 24 rewritten |
| S2 | Six off-template descriptions, two stale | RESOLVED: five rewritten, sixth file deleted (nit in G13) |
| S3 | Size-0 limit mask and bill term untested | RESOLVED: size Case 2 asserts limit 0; bill term dropped and pinned by eligible Case 7 |
| G1 | FY2023-FY2024 backfill rounding and size split | STILL OPEN, declined by author (out of scope; years unclaimed) |
| G2 | Cite the draft FFY2027 plan | RESOLVED (smi_rate.yaml #page=8, base_amount.yaml #page=9, PR body) |
| G3 | Monthly test, unemployment FAQ, fl_oss rationale |
RESOLVED |
| G4 | Page-reference polish | RESOLVED |
| G5 | Size-13 sentinel and 2027 carry-forward | RESOLVED via S1 |
| G6 | Test hygiene | RESOLVED (student flags 82 → 7; one copied header remains, G15) |
| G7 | PR body and rulespec-us#1534 | RESOLVED for the PR body; #1534 not re-checked |
PDF Audit Summary
| Category | Count |
|---|---|
| Changed values confirmed against the PDFs | 24 |
| Mismatches raised | 3 |
| Confirmed by code path and visual check | 1 (G8, documented source conflict) |
| Rejected at code path | 2 |
| Cross-references checked | 1 (consistent) |
| External and cross-reference requests | 6, all resolved |
| Missing from repo / missing from PDF | 4 / 3 (documentation and documented estimates) |
| Changed page references | 22 correct, 0 wrong (5 unchanged neighbors also correct) |
| Pages rendered | 133 (112 full-document, 17 at 300 dpi, 4 at 600 dpi) |
Validation Summary
| Check | Result |
|---|---|
| CI | 27 of 27 checks pass at f2f6f3f706 |
| Local tests | 63 of 63 Florida cases pass at head |
| Regulatory | Pass: the floor follows 8624(b)(2)(B) and the HHS guideline year; the size-13 reading is the only one within the federal ceiling; float edge in S4 |
| References | 0 missing, 0 non-corroborating, 0 wrong sections or pages; anchor in S5 |
| Code patterns | Pass: no hard-coded values, federal parameter under gov/hhs/liheap, ruff clean |
| Test coverage | Every formula variable tested; one surviving mutation (S4) |
| Hand arithmetic | Eligible Case 7, size Case 2 and Cases 24-25 recomputed: correct |
| Branch | 13 ahead, 38 behind; merges cleanly |
Review Severity: COMMENT
No critical findings remain. S4 and S5 are small, non-blocking fixes; apply both here and in #9968.
Next Steps
To auto-fix issues: run the fix-pr workflow for this PR.
|
FYI: #10279 now carries |
Adds a partial Florida LIHEAP regular heating model using FY2025 and FY2026 schedules. The model tests countable income against the heating maximum income value or waives the test for households receiving SNAP, Temporary Cash Assistance (TCA) or SSI, places the household in one of four income bands, and adds fixed amounts for elderly, disabled and young-child members. In FY2026, a one-person household with $16,078 of wages and natural gas heat receives $350; in FY2025, a one-person household with $10,000 of wages receives $1,000.
Fixes #9960
The current application excludes all minors’ income, regardless of student status. FY2026 size 13 uses 60% of state median income for both the limit ($94,610) and the band cutoffs ($47,305 / $66,227 / $80,419), like every other size. Households with income below 110% of the poverty guideline stay income-eligible under 42 U.S.C. 8624(b)(2)(B); in FY2026 this floor exceeds the limit from 15 people, so 15 people with $100,000 receive $200. The registry no longer claims complete verified years.
Policy verification remains partial: the executed contract conflicts with the accepted heating plan and current matrix on large-household eligibility; the size-13 row follows the 60% rule and departs from the printed matrix row and the portal; above-matrix awards for categorical or floor-protected households remain estimates; and the current minor-income rule has no confirmed effective date for FY2025 backfilling.
Regulatory authority
42 U.S.C. 8624(b)(2)(B)
FY2026 LIHEAP State Plan, sections 1.1, 1.4–1.10, 2.1–2.6 and assurances #page 4-9,45
FY2025 LIHEAP State Plan, sections 1.4–1.9, 2.1, 2.3 and benefit levels #page 5-10
Draft FFY2027 LIHEAP State Plan, sections 1.1, 1.9, 2.1, 2.4 and 2.6 #page 4-6,8-9
Florida LIHEAP Policies and Procedures Manual, May 27, 2022 #page 4,8-9,23-24,39-43,47-51
FY2026 LIHEAP Payment Matrix, effective October 1, 2025
FY2025 LIHEAP Payment Matrix, "Updated FY 2024/2025"
FY2026 LIHEAP income eligibility by component, Florida heating column
Florida state median income for FFY 2025
Florida state median income for FFY 2026
Current statewide LIHEAP application, monthly household income
State-endorsed LIHEAP portal FAQ
Executed LIHEAP amendment, effective October 2025, Attachment A-2 sections D10b, G8a, G8c and G8e #page 9,12-13
Original LIHEAP umbrella agreement, sections 6C-D, 21 and 33A #page 9,19,29
Eligibility
defined_for = StateCode.FLis_citizen_or_legal_immigrant, with no SNAP waiting bar. A household with no qualified member is ineligible, and its income limit is $0. Ineligible members' income counts in full.liheap_smi_limithelper (#10019), which truncates to whole dollars as in the federal table. One person: $30,588 (FY2025), $32,155 (FY2026); nine people in FY2025: $87,150; 13 people in FY2026: $94,610. The limit is inclusive.fpg_year_lag), as the FY2025 limit does, so FY2026 uses the 2025 guideline. The rate is the shared federal parametergov.hhs.liheap.fpg_floor(1.1). In FY2026 the floor exceeds 60% of state median income from 15 people: $101,915 against $98,320 for 15, and $107,965 against $100,175 for 16. FY2025 limits are at least 150% of the same guideline, so the floor never binds there. With the January 2026 guidelines, the FY2026 crossover would start at 14 people ($98,780 against $96,465).snap,tanforssiamount for any member waives the income test, including a child's SSI that is excluded from income. Each of these variables applies take-up, andtanfincludesfl_tca, so TCA a household does not take up does not qualify it. Receipt does not waive residence, qualified membership or heating responsibility.has_heating_expensequalifies; it defaults to true when the primary fuel's bill is positive, and an explicit false is respected even with a bill. Heat included in unsubsidized rent qualifies. A household with housing assistance or in public housing whose rent includes heat needs a positive residual heating charge.heating_typeNONE is ineligible. An unspecifiedheating_typequalifies only with heat included in rent; with a direct bill or reported obligation it pays $0.Countable income
max(gambling_winnings − gambling_losses, 0)per person, so losses offset only winnings.tanfaggregate, which includesfl_tca, once per household.fl_oss) is not counted: it pays residents of assisted living facilities, adult family-care homes and mental health residential treatment facilities, whom the manual excludes from LIHEAP households.Benefit
Years covered
A calendar-year period reads the parameters in force on January 1. Formulas are undated; the unsupported
verified_yearsfield has been removed. The table describes represented schedules, not fully verified policy years. Other years are unverified backfilled estimates. The draft FFY2027 plan (hearing August 31, 2026) keeps 60% of SMI for sizes 1–8 and 9 or more (item 2.1) and estimates a $200 minimum and $700 maximum benefit (item 2.6). No FY2027 matrix is published, so period 2027 carries the FY2026 rules with the FFY2027 median ($108,122) as an unverified estimate.Not modeled and source conflicts
heating_typeNONE and an electric bill gets $0 here but could receive the once-a-year benefit in the cooling season.Microsimulation: the microsimulation datasets carry no heating inputs, so population totals are about $0 until #9754 lands. Callers must send
heating_typewith the matching fuel bill.Test plan
63 YAML cases in 6 files cover:
has_heating_expensefalse despite a gas bill (ineligible), an unspecified fuel with a reported obligation ($0) and with heat in rent ($350), fuel neutrality and a mixed-state population;All 61 earlier cases passed locally at 7c5688f. Expected values for the new and rewritten cases come from hand arithmetic on the matrix, plans and 2025 poverty guidelines. No case was run locally at this head; CI validates them.
make formatpassed. These tests include the stated estimates and do not resolve the material source gaps above.make formatchangelog.d/axiom: TheAxiomFoundation/rulespec-us#1534 queued
🤖 Generated with Claude Code