Skip to content

Add Florida LIHEAP regular heating assistance - #9969

Merged
hua7450 merged 16 commits into
mainfrom
fl-liheap
Oct 20, 2026
Merged

hua7450 merged 16 commits into
mainfrom
fl-liheap

Conversation

@hua7450

@hua7450 hua7450 commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

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 model rounds the floor to cents and keeps the statute's strict "less than", as #10279 does, so 15 people with exactly $101,915 (110% of the guideline) are not protected. 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

Eligibility

Requirement Source How modeled
Florida residence — defined_for = StateCode.FL
Household size excludes ineligible noncitizens Manual part 900.04F, page 42 Counts members with is_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.
Income at or below the heating maximum income value FY2025 and FY2026 plans section 2.1, page 8; FY2025 and FY2026 payment matrices FY2025: the greater of 60% of state median income and 150% of the 2024 poverty guideline, which selects state median income for sizes 1–8 and the guideline for sizes 9 and up; state median income amounts round half up. FY2026: 60% of state median income for every size, including 13, from the shared liheap_smi_limit helper (#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.
Federal 110%-of-poverty floor 42 U.S.C. 8624(b)(2)(B); FY2026 plan assurances, page 45; amendment G8e, page 13; LIHEAP IM 2024-02, 2025-02 and 2026-01 Income below 110% of the poverty guideline, rounded to cents, is income-eligible even above the printed limit; income exactly at the floor is not ("less than"). The guideline uses Florida's one-year guideline lag (fpg_year_lag), as the FY2025 limit does, so FY2026 uses the 2025 guideline. LIHEAP IM 2024-02, 2025-02 and 2026-01 make each January's guidelines mandatory from the next October 1. The rate is the shared federal parameter gov.hhs.liheap.fpg_floor (1.1); the file is byte-identical to the copy in #10279, and the cent-rounded comparison matches #10279. 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). In the 2027 carry-forward the floor exceeds the limit from 15 people: $105,028 against $103,148.
Categorical income eligibility FY2026 plan sections 1.4–1.6, page 5; manual part 1200.01G(9), page 50 A positive snap, tanf or ssi amount for any member waives the income test, including a child's SSI that is excluded from income. Each of these variables applies take-up, and tanf includes fl_tca, so TCA a household does not take up does not qualify it. Receipt does not waive residence, qualified membership or heating responsibility.
Heating responsibility Manual pages 4, 23, 39, 43 and 47 Outside rent, has_heating_expense qualifies; 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_type NONE is ineligible. An unspecified heating_type qualifies only with heat included in rent; with a direct bill or reported obligation it pays $0.
No asset test FY2026 plan section 2.3, page 8 Assets are not tested.

Countable income

Item Source How modeled
Whose income counts Current statewide application, page 1; portal FAQ; FY2026 plan section 1.10, page 7 Counts earned and unearned income only from members aged 18 and older. All minors’ income is excluded, regardless of student status. The current application supersedes the older manual’s nonstudent exception. Its March 2025 PDF creation date does not establish the policy-change date, so application throughout FY2025 is an unverified backfill.
Income period Manual part 1200.03A, page 51; amendment G8a, page 12; portal FAQ Part 1200.03A and amendment G8a use 30 days of income annualized or the applicant's most current economic situation, "whichever is lower"; annual income stands in for both. The portal compares one month with monthly maximums rounded to whole dollars, which differ from the annual values by at most $6 a year: $2,680 for one person is $5 more lenient than $32,155 / 12 = $2,679.58, and $3,504 for two is $1 stricter.
Earned income FY2026 plan section 1.9, pages 5–6; manual parts 1200.01E and G(12), pages 49–50 Counts wages and net business income (self-employment, SSTB, farm operations, partnership/S-corporation). Floors each source at zero; plan section 1.8 counts gross income and manual 1200.01B counts "the gross amount of income", so a loss in one source offsets nothing.
Unearned income FY2026 plan section 1.9, pages 5–7; manual pages 49–51 Counts Social Security, SSI, pensions, military retirement pay, railroad retirement, survivor benefits, veterans benefits, workers' compensation, disability benefits, strike benefits, General Assistance, rental and farm rental income, interest, dividends, periodic estate and trust income, child support and alimony. Floors each source at zero.
Social Security FY2026 plan section 1.9, page 6 ("Including MediCare deduction"); manual page 50 Counts gross benefits; the manual adds Medicare premiums back to net checks.
Gambling and lottery winnings FY2026 plan section 1.9, page 7 ("net gambling or lottery winnings") Counts max(gambling_winnings − gambling_losses, 0) per person, so losses offset only winnings.
TCA FY2026 plan section 1.9, page 6 Counts the take-up-gated tanf aggregate, which includes fl_tca, once per household.
Excluded sources FY2025 and FY2026 plans section 1.9; portal FAQ; manual parts 900.02B (page 39) and 900.03B(1) (page 40) Unemployment compensation and cash gifts are not counted. Florida Optional State Supplementation (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

Income band FY2025 base FY2026 base
Up to 50% of the maximum income value $1,000 $350
Over 50% to 70% $750 $300
Over 70% to 85% $550 $250
Over 85% to 100% $400 $200
  • Cutoffs set as shares of the maximum income value round half up to the dollar for every size, including FY2026 size 13 ($47,305 / $66,227 / $80,419 from $94,610). For one person they are $16,078, $22,509, $27,332 and $32,155 in FY2026, and $15,294, $21,411, $26,000 and $30,588 in FY2025.
  • Where the 2024 guideline sets the FY2025 limit (sizes 9 and up), the bands are below 75%, 75–100%, over 100–125% and over 125–150% of the guideline; for nine people the cutoffs are $43,575, $58,100, $72,625 and $87,150.
  • Each household adds $100 if any member is 60 or older (FY2026 plan section 2.4, page 9; payment matrices), $100 if any member is disabled and $150 if any member is age 5 or younger (until the sixth birthday). Each addition applies once and the categories stack, so the maximum award is $700 in FY2026 and $1,350 in FY2025.
  • The payment does not depend on fuel. The reported bill does not cap it, and no HUD utility allowance is subtracted (manual page 43).
  • A categorical household, or a household protected by the 110% floor, with income above the maximum income value receives the smallest base ($200 in FY2026, $400 in FY2025) plus any additions. The sources print no band above the maximum income value; the smallest base is an estimate.

Years covered

Model year Program year Limit rule Bases
2025 FY2025, from October 1, 2024 Greater of 60% SMI and 150% of the 2024 guideline $1,000 / $750 / $550 / $400
2026 FY2026, from October 1, 2025 60% SMI for every size, with the 110% poverty floor $350 / $300 / $250 / $200

A calendar-year period reads the parameters in force on January 1. Formulas are undated; the unsupported verified_years field 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

Item Source Model treatment
Means-tested veterans programs in the FY2025 categorical list FY2025 plan sections 1.4–1.6 No input identifies them.
Work-study, royalties, mortgage and sale installments, some insurance and lump-sum receipts FY2026 plan section 1.9 Existing inputs do not isolate them.
Roomers, separate energy units, special status documents and tribal-provider assignments Manual part 900.04, pages 41–42 Not identified; the SPM unit approximates the household.
Heat in unsubsidized rent Manual parts 900.01A (page 39) and 100.01 (page 4) against part 1100.04B(1) (page 47); FY2025 plan section 2.3 (pages 8–9) Part 900.01A allows "non-subsidized rent that includes utilities" and part 100.01 pays the landlord, while part 1100.04B(1) asks for a landlord statement that "Home energy costs are not included in their rent". The model follows part 900.01A, part 100.01 and FY2025 plan item 2.3's utilities-in-rent answer (page 9). The same FY2025 item repeats the landlord statement under Renters (page 8), and the FY2026 plan answers No to all three renter rows (page 8). Landlord verification and account ownership are assumed.
Undocumented applicant Manual part 900.04A and D.1 (page 41) Part 900.04A makes a household eligible when "at least one member, preferably an adult," qualifies; part 900.04D.1 denies the application when "The applicant is an illegal alien". No input names the applicant, so a qualified member is assumed to apply.
Previous awards in the same year — One award per year is modeled; prior awards need data the inputs do not carry.
FY2026 household sizes above 12 FY2026 payment matrix The 60%-of-SMI rule and federal state median income size factors apply; no printed 60% row verifies them (size 13 prints a 100%-of-SMI row; see the source conflicts below).
Cooling-season Home Energy Benefit FY2026 plan section 1.1, page 4 (cooling April 1–September 30, 2026) Out of scope. A household with heating_type NONE and an electric bill gets $0 here but could receive the once-a-year benefit in the cooling season.
Crisis, cooling, weatherization and equipment assistance — Out of scope.
Topic Plan or federal table Operating source and model
FY2026 benefit amounts FY2026 plan section 2.6 (page 9) lists an estimated $400 minimum and $1,350 maximum benefit The October 2025 payment matrix prints bases of $350 to $200 and a $700 maximum with all additions; manual page 23 bases the payment on the matrix, and manual Part 200 Q.4 (page 9) and amendment D10b (page 9) require the current matrix. The draft FFY2027 plan (item 2.6) also estimates $200 to $700. The model follows the matrix.
Income of minors The older manual counts 16- and 17-year-old nonstudents; the plans leave minors’ earnings unchecked The state-endorsed current application and portal explicitly exclude minors’ income. The model follows these current operating sources for both earned and unearned income. The actual rule-change date remains unknown.
FY2026 size-13 limit The matrix prints $157,686 ($103,063 × 1.53, or 100% of state median income) with cutoffs at 50%, 70% and 85% of it, and the portal FAQ prints $13,141 a month for 13 people ($157,686 / 12) The matrix footnote says "Maximum Income Values are 60% of SMI", FY2026 plan item 2.1 (page 8) lists 60% for sizes 1–9, and the draft FFY2027 plan lists 60% for 9 or more. 42 U.S.C. 8624(b)(2)(B) caps eligibility at the greater of 150% of poverty ($122,475 for 13) and 60% of state median income, and the printed row exceeds that ceiling. The model applies 60% of state median income ($94,610) to both the limit and the bands, so it departs from the portal's size-13 figure.
FY2026 large households The executed October 2025 amendment G8c explicitly applies 150% of the poverty guideline to heating, cooling and crisis for sizes 9 and above, and G7d sets 150% of the poverty level for every size The accepted heating plan, the current matrix footnote, the portal's monthly table for sizes 1–12 ($7,266 for nine = $87,190 / 12) and the draft FFY2027 plan support 60% of state median income, which remains the represented operational rule; the portal's size-13 figure follows the printed 100% row (see above). Section 33A of the original umbrella agreement (page 29) ranks the Notice of Fund Availability first, then the attachments, the agreement and formal Commerce guidance. That ranking does not settle the conflict: G8c and D10b sit in the same attachment, and D10b requires the current Commerce benefit matrix (G1, page 11, also bases benefits on the state-provided matrix). The contractual inconsistency remains unresolved.

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

Test plan

72 YAML cases in 7 files cover:

  • FY2026 size-13 band tops at 60% of state median income and the next cent, plus band tops for one person, FY2026 second-band tops for sizes 8, 10 and 12, and FY2025 band tops for sizes 1 and 9;
  • all twelve printed FY2026 limits, the size-13 rule, and FY2025 limits for sizes 1, 2, 4, 6, 8, 9, 12 and 20, with inclusive ceilings in both years, and a $0 limit for a unit with no qualified member;
  • the federal 110% poverty floor for 15 people with $100,000 and 16 people with $105,000 ($200 each), and the threshold edge at $101,914.99 (protected) and exactly $101,915 (not protected) for 15 people;
  • a 15-member household of two working parents and 13 children with $100,000 of wages ($350 with the child addition);
  • 14 people at $60,000 ($300), at the $96,465 limit ($200) and one cent above it (ineligible, which pins the one-year guideline lag);
  • the 2027 carry-forward floor edge for 15 people at $105,027.99 ($200) and exactly $105,028 ($0);
  • six end-to-end FY2026 households in integration.yaml, built from the $14 Florida minimum wage, SSA's January 2026 SSI and survivor amounts and EIA's 2024 Florida average electric bill: a single parent with a young child ($450), a widow on survivor benefits ($350), a disabled SSI recipient ($450), a two-earner family of four ($250), a parent whose teenager's wages are excluded ($300) and an over-income couple ($0);
  • each addition and their stacking, a child at age 5, between the fifth and sixth birthdays and at 6, and the FY2025 $1,350 maximum;
  • categorical eligibility through SNAP, TCA and a child's SSI, TCA with and without take-up, out-of-state receipts, and the $200 estimate above the table;
  • heat in rent with and without a subsidy, a reported obligation without a bill, an explicit has_heating_expense false 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;
  • the current exclusion of all minors’ income and adult income inclusion, with final minor-income awards; excluded unemployment and gifts, gross Social Security, TCA counted once and only when taken up, ineligible members’ income, net gambling, military and railroad retirement, and loss floors across business, rental, farm rent and estate sources.

All 61 earlier cases passed locally at 7c5688f, and all 63 cases passed in a local review run at f2f6f3f. Expected values for the new and changed cases come from hand arithmetic on the matrix, plans, the 2025 and 2026 poverty guidelines and the FFY2027 state median income; integration.yaml inputs come from the Florida Constitution's minimum wage, SSA's 2026 amounts and EIA's 2024 Florida bill. No case was run locally at this head; CI validates them. make format passed. These tests include the stated estimates and do not resolve the material source gaps above.

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

axiom: TheAxiomFoundation/rulespec-us#1534 queued

🤖 Generated with Claude Code

hua7450 and others added 5 commits October 3, 2026 19:49
- 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

codecov Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codecov Report

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

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

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

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

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

hua7450 and others added 4 commits October 7, 2026 22:56
…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>
hua7450 and others added 2 commits October 11, 2026 23:45
Calls liheap_smi_limit from PR 10019 instead of repeating the HHS
floor-then-floor calculation. Limits are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hua7450
hua7450 marked this pull request as ready for review October 12, 2026 05:54
@DTrim99

DTrim99 commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Add Florida LIHEAP regular heating assistance

PR #9969: Add Florida LIHEAP regular heating assistance (author: hua7450, head 7c5688f9ec)

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:

  • household size, which counts citizens and qualified noncitizens (undocumented and DACA members are left out, but their income counts), and countable income: the gross income of members 18 and over from 23 listed sources, plus net gambling and take-up-gated TANF (Temporary Cash Assistance), with each source floored at zero;
  • the income limit: in FY2025 the greater of 60% of state median income (SMI) and 150% of the 2024 poverty guideline, and in FY2026 60% of SMI for every size through the shared liheap_smi_limit helper; SNAP, TANF or SSI receipt waives the income test;
  • the payment matrix:
    • four income bands: 50%, 70%, 85% and 100% of the maximum income value, or 75%, 100%, 125% and 150% of the guideline for FY2025 sizes 9 and up;
    • bases of $1,000 / $750 / $550 / $400 in FY2025 and $350 / $300 / $250 / $200 in FY2026, plus the printed FY2026 size-13 band cutoffs;
    • additions of $100 for a member 60 or older, $100 for a disabled member and $150 for a child 5 or younger, each once per household;
  • heating responsibility: a bill or reported obligation, heat in non-subsidized rent, or a residual charge in subsidized housing.

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), programs.yaml and a changelog fragment. Parameters are dated 2024-10-01, and four change at 2025-10-01; the size-13 bounds start at 2025-10-01. The tests use periods 2025 and 2026, and the registry lists Florida partial with no verified_years.

Overall: the FY2025 and FY2026 policy values are right for households of up to 12 people.

  • Every printed cell of both matrices reproduces: all maximum income values and band edges for sizes 1-12 in FY2026 and 1-20 in FY2025, plus the bases and additions.
    • FY2026 uses the HHS floor-then-floor order from the $103,063 median.
    • FY2025 rounds the unrounded 60% amount half up (its printed $30,588, where the HHS table prints $30,587) and derives its bands from that unrounded amount.
  • The income rules follow plan items 1.8-1.9, the manual, the current application and the portal FAQ: gross income, members 18 and over only, unemployment and cash gifts excluded, losses floored per source and net gambling.
    • Social Security counts gross. The manual's instruction to add the Medicare premium back to a net check (M 1200.01G(5)(a), p50) settles what the "Including MediCare deduction" box means for Florida.
  • The obligation and housing routes follow M 900.01A, 900.08 and 700.01E.
  • Following the FY2026 matrix over plan item 2.6's $400-$1,350 is right. The draft FFY2027 plan, which the PR does not cite, confirms both the $200-$700 range and 60% of SMI for nine or more people (G2).
  • Test coverage is strong: every listed income source is nonzero in at least one case (as in Add Ohio HEAP regular heating assistance #9975), and only two small pieces of logic survive mutation.

There is one critical finding:

  • C1: from 15 people, the FY2026 limit (60% of SMI) falls below the federal 110%-of-poverty floor in 42 USC 8624(b)(2)(B), which the accepted plan assures and the FY2026 contract restates. A protected household gets $0 instead of $200.

The three should-address items:

  • S1: the size-13 limit and bands come from different readings of one printed row, so a 13-person household gets more than a 12- or 14-person household with the same income. The state portal applies the printed row, contrary to the PR body.
  • S2: six parameter descriptions fall outside the house template, and two of them describe a student-status rule the head no longer has.
  • S3: two small pieces of logic have no test that would fail if they broke.

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:

  • P/ = policyengine_us/parameters/gov/states/fl/commerce/liheap/
  • V/ = policyengine_us/variables/gov/states/fl/commerce/liheap/
  • T/ = policyengine_us/tests/policy/baseline/gov/states/fl/commerce/liheap/
  • M = Florida LIHEAP Policies and Procedures Manual, last revised November 17, 2021, effective May 27, 2022 (73 pp; PDF page = printed page)

Line numbers refer to head 7c5688f9ec.

Source Documents

# Document Link Use
1 FY2026 Florida LIHEAP State Plan (49 pp, Revision #1, report period 10/01/2025-09/30/2026, "Submission Accepted by CO") FL_Plan_2026.pdf 1.1 heating 10/01/2025-03/31/2026 (p4); 1.4-1.6, 1.8 (p5); 1.9 (p5-7); 1.10 (p7); 2.1 60% SMI for sizes 1-9, 2.3 (p8); 2.4 additions, 2.6 $400 / $1,350 (p9); assurances with the 110% clause (p45). The text layer lacks the checkbox states, so the rendered pages were read
2 FY2025 plan (52 pp, accepted, submitted 09/25/2024) FL_Plan_2025.pdf 1.4 with veterans programs (p5); the same 1.9 boxes (p5-7); 1.10 statewide online application (p7); 2.1 SMI for sizes 1-8 and 150% of the guideline for 9 (p8); 2.3 renters and subsidized housing (p8-9); 2.6 $400 / $1,350 (p10)
3 Draft FFY2027 plan (43 pp, FloridaCommerce, funding period 10/01/2026-09/30/2027, virtual hearing 08/31/2026) draft plan Not cited in the PR. Heating 10/01/2026-03/31/2027 (p4); the same 1.4-1.9 boxes (p5-6); 2.1 60% SMI for sizes 1-8 and "9 or more", 2.3 subsidized-housing text (p8); 2.4 additions, 2.6 $200 / $700 (p9); assurances (p40). File pages; the printed footer is one lower
4 M (73 pp) FL_PolicyManual_2023.pdf 100.01 (p4); Part 200 Q (p8-9); 700.01 (p23-24); 900.01-900.08 (p39-43); 1100.03-1100.04 (p46-48); 1200.01-1200.03 (p49-51)
5 FFY2026 payment matrix (1 p, "effective October 1, 2025") FL_BenefitMatrix_Heat-Cool_2026.pdf Sizes 1-13, bases, additions, "Maximum Income Values are 60% of SMI"
6 FY2025 payment matrix (1 p, "Updated FY 2024/2025", "effective ASAP") FL_BenefitMatrix_2025.pdf SMI rows 1-8, guideline rows 9-20, bases, additions, "the greater of 60% SMI (family size 1-8) or 150% FPL (family size 9-20)"
7 FY2024 and FY2023 matrices (1 p each) FY2024, FY2023 Not cited in the PR. "Updated FY 2023/2024", effective June 5, 2023, and "Updated FY 2022/2023", effective May 1, 2022: the same bases and additions (G1)
8 Statewide application and portal FAQ application, p. 1, FAQ "Enter ALL income for household members (except minors) ... Enter GROSS amounts"; the FAQ's countable and excluded income lists; its "Max monthly income for 2025" table, $2,680 for one person to $13,141 for 13; one Home Energy award per year
9 FloridaCommerce LIHEAP page (read 2026-10-14) floridajobs.org "60% of the Florida State Median Income or 150% of Federal Poverty Level"; limits for sizes 1-8 ($32,155 ... $85,335); the link to the FFY2027 draft
10 Commerce agreement E2249, Amendment 0001 (Palm Beach County agenda copy, effective October 1, 2025) Amendment 0001, p. 12 D(10)b current matrix (p9); G(1) (p11); G(7)d, G(8)a and c (p12); G(8)e, the 110% clause (p13)
11 Clearinghouse income-eligibility table (last updated 12/15/2025) income_eligibility.htm Florida: "60 SMI" for heating, cooling and crisis; "For Cooling and Crisis: 150 FPG for households with 10+ members."
12 42 USC 8624(b)(2)(B) LII The greater of 150% of poverty and 60% of SMI as the cap; no exclusion on income below 110% of poverty

Critical (Must Fix)

C1. From 15 people, the FY2026 limit falls below the federal 110%-of-poverty floor, so protected households get $0

  • Where: V/eligibility/fl_liheap_income_limit.py:43-44 extends 60% of SMI beyond the printed table ("Larger sizes follow the federal factors without table verification"), and V/eligibility/fl_liheap_eligible.py:50 tests income only against that limit.
  • Source:
    • 42 USC 8624(b)(2)(B): "a State may not exclude a household from eligibility in a fiscal year solely on the basis of household income if such income is less than 110 percent of the poverty level for such State for such fiscal year".
    • The accepted FY2026 plan assures it (p. 45).
    • The FY2026 contract restates it (G(8)e, p. 13): "No household may be excluded solely on the basis of income if the household income is less than 110% of the poverty level."
  • Reproduced at head (period 2026): 15 people with $100,000 have a limit of $98,320 and get $0; 16 people with $105,000 have a limit of $100,175 and get $0.
  • Hand-computed: 110% of the 2025 guideline, which the model itself uses for period 2026, is 1.1 x (15,650 + 14 x 5,500) = $101,915 for 15 people and $107,965 for 16. Neither household may be excluded on income, and both fall in band 4: $200.
    • With the 2026 guidelines, published in January 2026, the floor also passes the limit at 14 people ($98,780 against $96,465).
  • Why critical: it is a wrong result in a claimed year that contradicts an explicit statute, and Florida's own accepted plan and contract repeat that statute. The reach is small (households of 15 or more, in a band a few thousand dollars wide), but the brief's definition does not depend on reach. No merged LIHEAP implementation on main applies the floor, so the gap is cross-cutting.
  • Fix: treat income below 110% of the guideline as income-eligible, for example (income <= limit) | (income < rate * guideline) with the rate as a parameter (ideally federal, so other 60%-of-SMI states can share it). Add a 15-person case expecting $200.

Should Address

S1. Size 13: the limit and the bands come from different readings of one printed row

  • Where:
    • V/eligibility/fl_liheap_income_limit.py:39-48 applies 60% of SMI, $94,610 for 13 people.
    • V/fl_liheap.py:55-62, with P/payment/published_band_size.yaml and P/payment/published_band_upper_bound.yaml:4-9, pays from the printed size-13 cutoffs.
  • Source: the FFY2026 matrix prints row 13 as $78,843 / $78,844-$110,380 / $110,381-$134,033 / $134,034-$157,686.
    • $157,686 is 100% of SMI (103,063 x 1.53), and the three cutoffs are 50%, 70% and 85% of it. The footnote reads "Maximum Income Values are 60% of SMI".
    • The PR treats the printed maximum as an anomaly for eligibility but keeps the cutoffs derived from that same maximum for payment. The result matches neither reading.
  • Reproduced at head (period 2026, gas heat, no member 60 or older, disabled or under 6):
    • At $60,000, 12 people get $300, 13 people get $350 and 14 people get $300.
    • At $100,000, 13 people are ineligible and get $0; with SNAP receipt the award is $300.
  • Hand-computed under each consistent reading:
    • Printed row in full: the 13-person household with $100,000 is eligible (limit $157,686) and in band 2, $300.
    • 60% rule in full: the bands are $47,305 / $66,227 / $80,419 (round half up of 94,610 x 0.5, 0.7 and 0.85), so $60,000 is band 2, $300, as for sizes 12 and 14.
  • The state's own portal applies the printed row. The FAQ "Max monthly income for 2025" table prints $13,141 for 13 people, which is 157,686 / 12; its other rows are the 60% amounts ($7,266 for nine = 87,190 / 12).
    • The PR body's conflict table says the plan, matrix and "state-endorsed portal corroborate 60% of state median income", and its size-13 row does not mention the portal. The author's rulespec-us#1534 does (interpretation 4).
    • The other evidence runs the other way: plan item 2.1, p. 8 lists 60% for sizes 1-9, and the FFY2027 draft lists it for "9 or more" (G2).
  • Why should, not critical: Florida's printed row contradicts its own footnote, so neither reading is confirmed against the source, and the PR documents its choice. Still, the hybrid is internally inconsistent within a claimed year, and the PR body misstates the portal's figure.
  • Fix: pick one reading of row 13 and apply it to both the limit and the bands: the printed row (which the matrix and the portal apply) or the 60% rule (which the plans state). Then correct the PR body.

S2. Six parameter descriptions fall outside the house template, and two describe a rule the head no longer has

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

File:line Current Suggested
P/eligibility/categorical_programs.yaml:1 "Florida waives the LIHEAP income test for households receiving a positive amount from any of these programs." (verb, and it does not end with the program name) "Florida uses receipt of these programs as categorical income eligibility under the Low Income Home Energy Assistance Program."
P/income/sources/earned.yaml:1 "counts these earned income sources subject to its age and student-status rule" "Florida uses these sources as earned income of members aged 18 and older under the ..."
P/income/sources/unearned.yaml:1 "counts these person-level unearned income sources subject to its age and student-status rule" "Florida uses these sources as unearned income of members aged 18 and older under the ..."
P/income/sources/household.yaml:1 "counts these household cash grants once" "Florida uses these household cash benefits as countable income under the ..."
P/payment/published_band_upper_bound.yaml:1 "publishes these regular heating payment-band upper bounds for the separately specified household size" "Florida sets these payment-band upper bounds for the separately published household size under the ..."
P/payment/supplement.yaml:1 "adds this amount once for each applicable vulnerable household category to the regular heating payment" "Florida provides this additional heating payment once for each vulnerable household category present under the ..."

S3. Two small pieces of logic have no test that would fail if they broke

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

  1. The size-0 mask on the income limit (V/eligibility/fl_liheap_income_limit.py:48, where(size > 0, limit, 0)).
    • Without it, a unit with no qualified member gets the one-person limit: smi_size_factor clips size 0 to the 52% share.
    • Reproduced: one undocumented adult has a limit of $0 at head and $32,155 under the mutation.
    • Eligibility still gates on size > 0, which T/eligibility/fl_liheap_eligible.yaml Case 3 pins, so only the limit variable changes.
    • Add fl_liheap_income_limit: 0 to T/fl_liheap_household_size.yaml Case 2, as Add Georgia LIHEAP regular heating assistance #9968 S2.3 asked for Georgia.
  2. The bill term in the non-rent responsibility branch (V/eligibility/fl_liheap_eligible.py:40, | (heating_expense > 0)).
    • has_heating_expense already defaults to "bill above zero and heat not in rent", so the term matters only when a caller sets has_heating_expense to false while reporting a bill.
    • Reproduced: one adult with $12,000 of wages, gas heat, a $1,200 gas bill and has_heating_expense: false is eligible for $350 at head and ineligible ($0) without the term.
    • The input's documentation says callers set it directly when the bill is not the heating cost, which argues for respecting an explicit false and dropping the term. Otherwise, pin the current result with that case.

Two control mutations confirm the method: dropping the eligibility size gate fails T/eligibility/fl_liheap_eligible.yaml (Case 3), and dropping the size-13 override fails T/fl_liheap.yaml (Case 24). By inspection, the rest is pinned:

  • every listed income source (all 5 earned and 18 unearned are nonzero in at least one case), TANF, the per-source floors, net gambling and its floor, and the minors' mask;
  • each categorical route and TCA take-up;
  • both truncation settings, the FY2025 guideline path and its strict first band, and the FY2026 band edges;
  • the three additions and their age boundaries;
  • heat in rent with both subsidy arms, the NONE and UNSPECIFIED checks, and the Florida gate.

Consistency: #9967 S3, #9972 S3, #9968 S2 and #9975 S4 rated untested logic SHOULD.

Suggestions

G1. Backfilled FY2023-FY2024: two small changes would reproduce FY2024 exactly

  • The FY2023 ("Updated FY 2022/2023", effective May 1, 2022) and FY2024 ("Updated FY 2023/2024", effective June 5, 2023) matrices pay the same bases and additions as FY2025. The repo's FFY2023 and FFY2024 medians reproduce their four-person 60% figures ($50,071 and $53,337). Two rules differ from the FY2025 rule the head carries back:
    • Rounding. Those matrices truncate, as FY2026 does.
      • FY2024 prints $61,870 / $70,404 / $72,004 for sizes 5-7, where the head admits up to $61,871 / $70,405 / $72,005. Reproduced: in 2024, five people with $61,871 get $400; the matrix pays $0.
      • Band tops are off too. Reproduced: five people with $43,310 get $750 (matrix band 3, $550), and six with $59,844 get $550 (matrix band 4, $400).
      • FY2023 prints $26,036 for one person; reproduced, $26,037 gets $400 at head.
    • The size split. max_(smi_limit, guideline * fpg_rate) (fl_liheap_income_limit.py:47) applies "the greater of" to every size.
      • At size 8, 150% of the guideline exceeds 60% of SMI in both years: reproduced limits of $69,945 (2023) and $75,840 (2024). The matrices print the SMI figures, $69,097 and $73,605.
      • Their footnotes ("60% SMI (family size 1-8) or 150% FPL (family size 9-20)"), FY2025 plan item 2.1, M 900.01D (p39) and contract G(8)c all describe a split by size. FY2025 is unaffected, since SMI is higher through size 8 and the guideline from 9.
  • 2023 and 2024 are unclaimed, so this is a suggestion (checklist item 3).
  • To reproduce those years, choose SMI through size 8 and the guideline from size 9, and set truncates_smi_limit true for periods before mid-2024. The FY2025 matrix PDF dates from June 2024 (Suppress MO income tax debugging print statement #1534 interpretation 16).
    • With both changes every FY2024 cell reproduces (hand-checked: all 8 SMI rows and 12 guideline rows).
    • FY2023 also reproduces, except that each guideline row's third band top is $1 lower, because 125% of every 2022 guideline amount ends in 50 cents and the matrix rounds it up.
    • The registry could then claim 2023-2024, subject to the minors'-income date.

G2. FY2027: the draft plan is published and supports the PR's choices

  • The draft FFY2027 plan, linked from the FloridaCommerce LIHEAP page, has:
    • heating from 10/01/2026 to 03/31/2027 (p4);
    • the same income boxes: unemployment insurance and a child's earned income unchecked, "Including Medicare deduction" checked (p5-6);
    • 60% of SMI for sizes 1-8 and "9 or more" (p8);
    • the same additions, and a range of $200 to $700 (p9).
  • That corroborates the FY2026 matrix over the FY2026 plan's $400-$1,350, and 60% of SMI for nine or more over contract G(8)c.
  • Period 2027 carries the FY2026 amounts with the FFY2027 median. Reproduced: one person's limit is $33,733 and $12,000 of wages gets $350. That matches the draft, though the state page still lists the FY2026 limits ($32,155 for one person) and no FY2027 matrix is published.
  • Cite the draft in the PR body and the base_amount and smi_rate comments, and replace "no adopted FY2027 plan or matrix was obtained" with its contents. Suppress MO income tax debugging print statement #1534 calls it a "2027-2028 plan"; it covers FFY2027.
  • No Florida plan from FY2023 to FY2027, matrix, manual or contract mentions an IIJA supplement (checklist item 12).

G3. Income-definition notes

  • Monthly test. The portal tests "the gross total income for the past 30 days" against rounded monthly figures. $2,680 for one person is $32,160 a year, so the annual comparison is up to about $5 stricter at the margin. For example, $32,155.01 a year is $2,679.58 a month, within $2,680, yet T/eligibility/fl_liheap_eligible.yaml Case 1 expects it to fail. Note the approximation (M 1200.03A, p51; contract G(8)a).
  • Unemployment. The FAQ lists "Unemployment compensation" and "Income of minors" under excluded income. Cite it next to the plans in the exclusion comment at P/income/sources/unearned.yaml:29.
  • fl_oss. Florida Optional State Supplementation counts in SNAP income on main but not here. Its recipients live in assisted-living or family-care settings, which M 900.02B (p39) and 900.03B(1)(b) (p40) exclude from LIHEAP households, so leaving it out is defensible; say so in the comment.

G4. References polish

  • V/eligibility/fl_liheap_eligible.py:13, # PDF pages 4, 23, 41, 43, 47, 50, omits p39 (900.01A, which the comment at line 33 cites for the heat-in-rent branch) and p48 (1100.04C).
  • V/fl_liheap_household_size.py:10 cites p42 only, but its comment rests on 900.04A and D (p41). Add # PDF pages 41-42.
  • P/payment/supplement.yaml could also cite FY2026 plan item 2.4 (p9).
  • Nothing cited is wrong. Every anchor shows its value, and multi-page titles use #page 5-6, #page 49-50 and #page 5-7.

G5. Code clarity in the size-13 machinery

  • P/payment/published_band_size.yaml:4 disables the row with 0, which matches size-0 units in FY2025 (harmless, since they are ineligible). An explicit boolean would be clearer.
  • The printed size-13 bounds also carry into 2027 unchanged while every other size moves with the FFY2027 median. By hand, in period 2027 the 60% limit for 13 people is $99,255, but the bands stay at $78,843 / $110,380 / $134,033. Resolve this with S1.

G6. Test hygiene

  • is_full_time_student is set 82 times across the six files, but no Florida variable reads it since the student rule was dropped. Keep it only where a case documents student status (countable-income Cases 7, 9 and 10).
  • The header comment of T/fl_liheap_household_size.yaml:1 ("household income and categorical-income components") is copied from the income file.
  • The isolated limit, income and size tests set heating inputs that those variables never read.

G7. PR body and issue housekeeping

  • "The PR remains draft": the PR is not a draft. rulespec-us#1534 still says "open as a draft" and that the tests "were not run in this session"; all 61 pass locally at this head.
  • Add the portal's size-13 figure (S1) and the FFY2027 draft (G2).
  • In the conflict table, note that FY2025 plan item 2.3, p. 8 repeats M 1100.04B's landlord statement ("Home energy costs are not included in their rent") under "Renters". The FY2025 plan therefore sits on both sides of the heat-in-rent conflict, not only for it ("both plans"). The FY2026 plan answers No for renters and utilities in rent.
  • Optional: the same Home Energy Benefit, once per 12 months, is paid in the cooling season (plan 1.1: 04/01/2026-09/30/2026). A household with heating_type NONE and an electric bill could receive it from April, so the NONE exclusion is a property of this heating-season model.

Verified correct

  • Matrices:
    • FY2026 (matrix):
      • the limits floor(floor(0.6 x 103,063) x factor), $32,155 ... $92,755 for sizes 1-12;
      • every band top as round half up of 50%, 70% and 85% of the limit (for example 59,734.5 to $59,735);
      • bases of $350 / $300 / $250 / $200, additions of $100 / $100 / $150, and a maximum of $700.
    • FY2025 (matrix):
      • all 8 SMI rows from 98,038 x 0.6 x factor, rounded half up, with bands from the unrounded amount (for example size 4's $49,999, not 50,000);
      • all 12 guideline rows from the 2024 guideline (band 1 below 75%, then 100%, 125% and 150%);
      • bases of $1,000 / $750 / $550 / $400. Plan 2.6's $400 / $1,350 matches.
  • Timing: heating runs from October 1 to March 31 (plans 1.1, p4), so period N reads FY N on January 1. The FY2025 matrix ("effective ASAP") predates FY2025, and the FY2026 matrix is "effective October 1, 2025".
  • Income (plan 1.8-1.9, p5-7; M 1200.01, p. 49-50; application p1; FAQ):
    • gross amounts; members 18 and over only (the application's "except minors", the FAQ's excluded "Income of minors", and plan 1.9's unchecked child's earnings);
    • nonqualified members' income counted (M 900.04F, p42; FAQ);
    • every listed source maps to a checked plan box, the "Other" line or the FAQ;
    • unemployment insurance, cash gifts and SNAP excluded;
    • Social Security gross (M 1200.01G(5)(a));
    • net business income without a second deduction (G(12)), and each source floored, so no loss offsets wages;
    • net gambling, and TCA once through the take-up-gated tanf;
    • annual income standing in for the 30-day rule (M 1200.03A).
    • Listing pension_income beside military_retirement_pay matches merged KY, OR and IN.
  • Household: citizens and qualified noncitizens (M 900.04B, p41; the FAQ's list); DACA and undocumented members excluded from size; a unit with no qualified member is ineligible (900.04A and D.2). Reading 900.04C's SNAP/SSI deeming as a documentation rule is documented (Suppress MO income tax debugging print statement #1534 interpretation 7).
  • Eligibility:
    • Florida residence and no asset test (plan 2.3).
    • Categorical receipt of SNAP, TANF or SSI waives only the income test (plan 1.4-1.6, p5; M 1200.01G(9), p50).
    • Responsibility: a bill or reported obligation, or heat in non-subsidized rent (M 900.01A, p39; 100.01, p4). Subsidized heat in rent needs a residual charge (900.08A, p43). NONE is ineligible, and UNSPECIFIED qualifies only with heat in rent.
  • Large households, sizes 9-12, FY2026: 60% of SMI is supported by plan item 2.1, the matrix, the Clearinghouse row (150% of poverty for 10+ applies to cooling and crisis only), the portal ($7,266 = 87,190 / 12 for nine) and the FFY2027 draft. That outweighs contract G(8)c, as the PR concludes.
  • Payment: from the matrix, not the bill (M 700.01C, p23); no HUD utility-allowance deduction for regular benefits (900.08B-C, p43; 700.01E); no bill cap; one award per year (Part 200 Q.1, p8; 700.01A; FAQ). Following the matrix over plan 2.6 matches Part 200 Q.4 (p9) and contract D(10)b.
  • Code patterns:
    • No hard-coded policy values. defined_for = StateCode.FL is on all six variables, and fl_liheap is gated by fl_liheap_eligible.
    • Vectorized formulas. All 17 parameters are read, and the shared liheap_smi_limit, smi and fpg helpers are reused.
    • Mixed Florida and Georgia rows mask correctly. No eligible household is paid $0, since the payment does not depend on fuel.
  • Tests:
    • 61 of 61 pass locally at head (policyengine-core 3.32.29) and on the merged tree. Periods are plain (2025, 2026).
    • Hand-checked against the matrices, plans, manual, application and FAQ:
      • T/fl_liheap.yaml Cases 1-7, 9, 12-18, 20 and 22-24 (Case 24 under the PR's reading);
      • limit Cases 1-3;
      • countable-income Cases 1, 2, 4, 10, 12, 14, 17, 19 and 20;
      • eligibility Cases 1, 4 and 6, and categorical Case 6.
  • Changelog: changelog.d/fl-liheap.added.md is top level and typed added.

Checklist results (LIHEAP wave 2a)

  1. State plan and manual first: pass, with C1 and S1. I read the following and verified every encoded cell, limit, band and route:
    • the accepted FY2026 and FY2025 plans (rendered checkboxes), the FY2023-FY2024 plans and the draft FFY2027 plan;
    • M, the FY2023-FY2026 matrices, the application, the portal FAQ, the FloridaCommerce page, contract Amendment 0001 and the Clearinghouse row.
  2. Income definition: pass.
    • Gross income; Social Security gross per plan 1.9 and M G(5)(a); losses floored per source; annual income for the 30-day rule.
    • Unemployment insurance is excluded per plan 1.9 and the FAQ, and minors' income per the application and FAQ.
  3. Backdating: FY2025 and FY2026 are represented and correct apart from C1 and S1.
    • FY2023-FY2024 are unclaimed: the bases match, but some limits and band tops are $1 off and size 8 is higher (G1).
    • The FFY2027 draft is published, consistent with the carry-forward, and not cited (G2).
  4. Household and arrangement rules: pass on subsidized and public housing, heat in rent, renters, categorical receipt with take-up, the vulnerable-household additions, and the $200-$700 and $400-$1,350 ranges. The large-household limits are C1 (15 or more) and S1 (13).
  5. Tests: 61 cases, more than 8 hand-checked.
    • Covered: FY2026 limits for sizes 1-13, FY2025 limits for sizes 1, 2, 4, 6, 8, 9, 12 and 20, band tops with one-cent pairs, the limit edge in both years, and plain periods.
    • Gaps are in S3. No case covers FY2026 sizes above 13 (C1).
  6. Parameter descriptions: six off-template, two of them stale (S2).
  7. References: pass. Polish is in G4.
  8. Wiring: pass.
    • The programs.yaml entry and coverage line are well formed. No aggregate wiring, which matches OR, NY, NJ and MD on main (none of them is in household_state_benefits).
    • defined_for gating is on every variable. No take-up beyond that of snap, tanf and ssi.
  9. Axiom: valid queued line. rulespec-us#1534 is open, labelled pe-parity, dispatch-ready and current to 7c5688f9ec. It needs updates for C1, S1 and S3 (see below).
  10. Branch and CI: all checks are green at head. 11 ahead and 82 behind main, with no textual or semantic conflicts.
  11. Integrate modeled state unemployment insurance into income flows #9558: no conflict. Florida lists no unemployment source, since the plans and FAQ exclude it. Main's guard passes on the merged tree (4 of 4), and Florida has no modeled UI.
  12. IIJA and FY2027: no IIJA supplement in any FY2023-FY2027 plan, matrix, manual or contract. The FFY2027 draft keeps 60% of SMI and $200-$700 (G2).
  13. Mutation check: S3. Two control mutations fail as expected.
  14. Health premiums after Document disjoint health premium inputs and correct consumer treatment #10046: not applicable.
    • Florida deducts no premiums and counts wages "before any deductions" (FAQ; application "GROSS amounts").
    • On main, employment_income is gross before pre-tax payroll deductions, and employer-paid premiums are neither income here nor in that input.

CI status

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

Branch status

Axiom line

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

  • rulespec-us#1534 is open and labelled pe-parity (plus enhancement), with no comments, and was last updated 2026-10-12.
  • It is dispatch-ready under the Add AMT parameters for 2020-2023 #1467 standard. It has:
    • proposed us-fl/ module paths with corpus status;
    • verbatim manual, plan, matrix, application, FAQ, contract and HHS text;
    • required outputs for all 6 variables;
    • 16 companion tests derived from the matrices, plans, manual, application, FAQ, HHS pages and guidelines ("None is taken from policyengine-us output").
  • It describes head 7c5688f9ec correctly, including the size-13 row and the portal's $13,141 (interpretation 4), the contract conflict (3), the plan-matrix conflict (5), the above-range estimate (6) and the minors' rule (8).
  • Updates needed when the fixes land:
    • the 110% floor (C1) and the size-13 decision (S1);
    • the new cases (S3);
    • the FFY2027 draft's contents and its "2027-2028" label (G2);
    • the stale "open as a draft".

Next steps

  1. C1: add the 110%-of-poverty floor and a 15-person case.
  2. S1: choose one reading of row 13 for both the limit and the bands, and correct the PR body's portal statement.
  3. S2: align the six descriptions and drop the stale student-status clause.
  4. S3: add the size-0 limit assertion, and drop or pin the bill term in the non-rent branch.
  5. Optionally address G1-G7, then refresh the PR body and rulespec-us#1534 and re-request review.

1 critical and 3 should-address findings, plus 7 suggestions.

Verdict: REQUEST_CHANGES

@DTrim99 DTrim99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Requesting changes for 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.

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

hua7450 commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

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.

  • C1: Added the shared federal parameter gov.hhs.liheap.fpg_floor (1.1) for 42 U.S.C. 8624(b)(2)(B): "a State may not exclude a household from eligibility in a fiscal year solely on the basis of household income if such income is less than 110 percent of the poverty level for such State". fl_liheap_eligible now treats income < guideline * fpg_floor as income-eligible, using the same one-year guideline lag (fpg_year_lag) as fl_liheap_income_limit. fl_liheap_income_limit is unchanged, so it still reproduces the printed matrix. Protected households above the limit fall in band 4. In the new fl_liheap.yaml Case 25, 15 people with $100,000 and 16 people with $105,000 get $200, and 15 people get $200 at $101,914.99 and $0 at $101,915.01.
  • S1: Size 13 now uses the 60% rule for both the limit and the bands. I deleted payment/published_band_size.yaml, payment/published_band_upper_bound.yaml and the override in fl_liheap.py. The limit is $94,610 with band tops of $47,305 / $66,227 / $80,419, so 13 people with $60,000 get $300, like 12 and 14 people. The matrix footnote, plan item 2.1 (sizes 1-9) and the FFY2027 draft (9 or more) all say 60%. The printed $157,686 also exceeds the federal ceiling in 8624(b)(2)(B), which is the greater of 150% of poverty ($122,475 for 13 people) and 60% of SMI. Case 24 is rewritten with 10 rows. The PR body now says that the portal's $13,141 follows the printed row and that the model departs from it.
  • S2: Adopted your wording for categorical_programs, earned, unearned, household and supplement. S1 deleted the sixth file. No Florida parameter mentions student status now.
  • S3: (1) fl_liheap_household_size.yaml Case 2 now asserts fl_liheap_income_limit: 0. (2) I dropped the bill term, so the model respects an explicit has_heating_expense: false outside rent, as NJ, MD, OR, NY, KS and NC do. The new fl_liheap_eligible.yaml Case 7 has one adult with $14,820 of wages and a $1,200 gas bill. It expects eligible with true and ineligible with false.
  • G1: Declined. History is out of scope for this PR, so years before FY2025 stay unclaimed backfilled estimates. Your truncation and size-split findings are noted for a later backdating pass.
  • G2: Cited the draft FFY2027 plan in base_amount.yaml (item 2.6, $200 to $700), in smi_rate.yaml (item 2.1, 60% for 9 or more), and in the PR body's sources and years-covered text. No values change, and period 2027 stays an unverified estimate.
  • G3: The fl_liheap_eligible comment now cites manual 1200.03A (page 51) and contract G(8)a for annualizing 30 days of income. It notes that the portal's rounded monthly maximums differ from the annual values by at most $6 a year ($2,680 for one person is $5 more lenient; $3,504 for two is $1 stricter). unearned.yaml cites the FAQ for the unemployment and gift exclusions. It also explains why fl_oss is left out (manual 900.02B, page 39; 900.03B(1), page 40).
  • G4: Added pages 39, 48 and 51 to the manual comment in fl_liheap_eligible.py. Put # PDF pages 41-42 above a #page=41 href in fl_liheap_household_size.py. Added FY2026 plan item 2.4 (page 9) to supplement.yaml.
  • G5: Resolved by S1. The 0 sentinel is gone, and in 2027 the size-13 bands follow the 2027 limit ($99,255, with band tops of $49,628 / $69,479 / $84,367).
  • G6: Removed is_full_time_student everywhere except where a case names student status (person2 in countable-income Cases 5-10 and fl_liheap.yaml Case 23). That leaves 7 lines, down from 82. I also fixed the household-size header and dropped the heating inputs from the size, limit, income and categorical component tests. No expected value changed.
  • G7: The PR body no longer says draft, and it adds the portal's size-13 figure and the FFY2027 draft. It notes that FY2025 plan item 2.3 repeats the landlord statement under Renters (page 8) beside its utilities-in-rent answer (page 9), and that the FY2026 plan answers No (page 8). The same note is in the fl_liheap_eligible.py comment. The cooling-season point is now a not-modeled row.
  • LIHEAP wave 2a: encode Florida LIHEAP regular heating assistance TheAxiomFoundation/rulespec-us#1534 is refreshed to this head.

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

Branch Status

  • 13 commits ahead of main and 38 behind (merge base 9560e7f183); merges cleanly. The staleness did not affect any finding (informational). The programs.yaml California SSP hunk is merge noise from main.
  • H/fpg_floor.yaml is 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 to ga_liheap_eligible.py too.

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.1 evaluates to 101915.00000000001 in float64, so income < guideline * p_hhs.fpg_floor admits 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.yaml Case 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:
    1. Compare with a cent-rounded floor, for example income < np.round(guideline * p_hhs.fpg_floor, 2).
    2. Add a size-15 row at exactly 101_915 that expects fl_liheap_eligible: false and fl_liheap: 0.
    3. Make the same change in #9968 (ga_liheap_eligible.py:35).
  • 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:12 and V/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. In parameters/ 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_B in all three places. Make the same change to H/fpg_floor.yaml in #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-81 records it. Add the same note to P/payment/base_amount.yaml:2-4. Change the header at T/fl_liheap.yaml:1 to cite the matrix, not plan page 9, for the 350 / 300 / 250 / 200 bases.
  • G9. P/eligibility/fpg_year_lag.yaml now 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 at V/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 to H/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-59 relies on FY2025 plan item 2.3 (pages 8-9), but the reference tuple has no FY2025 plan. Add FL_Plan_2025.pdf#page=8 with # PDF pages 8-9.
  • G13. Wording: P/income/sources/earned.yaml:1 and unearned.yaml:1 repeat the adult_age value ("18"); "adult members" will not go stale. The P/payment/base_amount.yaml:29 title 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 Florida programs.yaml note. Mention the G(8)a "whichever is lower" rule at V/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.yaml as in the IL, KS, KY and OR folders. Fix the copied header at T/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); an fl_liheap_fpg intermediate 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_floor in 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.

@PavelMakarchuk

Copy link
Copy Markdown
Collaborator

FYI: #10279 now carries policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml with the #b_2_B anchor (only that href changed: https://www.law.cornell.edu/uscode/text/42/8624#b_2_B; new blob aeb7f8c5b0). When you apply the anchor fix from the review here, use the identical file so that the add/add merges cleanly in any order.

hua7450 pushed a commit that referenced this pull request Oct 19, 2026
…, MS, NJ, OR) (#10279)

* Apply the federal 110% poverty floor to MS and OR LIHEAP

42 U.S.C. 8624(b)(2)(B) bars a state from excluding a household solely on
income below 110% of the poverty level. The 60% SMI limit falls below that
floor in Mississippi from household size 11 (FY2026-FY2027) and in Oregon
from size 19 (PY2025) or 20 (PY2026-PY2027). Both eligibility tests now
accept income below 110% of the poverty guideline that HHS makes mandatory
on October 1 of the program year (one-year lag).

Adds gov.hhs.liheap.fpg_floor, identical to the file in #9968 and #9969,
plus a poverty guideline year lag for each state.

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

* Apply the federal 110% poverty floor to DC, MA and NJ LIHEAP

The 60% SMI limits fall below 110% of the poverty guideline only for very
large households: DC from size 34 to 39 in 2022-2024, MA from size 30 to 34
and NJ from size 28 to 32 in 2022-2027. The eligibility tests now accept
income below the floor, using the one-year guideline lag. MA reuses
ma_liheap_fpg, which already lags the guideline; DC and NJ get their own
fpg_year_lag parameters.

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

* Anchor the LIHEAP floor reference to 42 U.S.C. 8624(b)(2)(B)

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

* Update the NC SA 2027 test for the announced 2027 COLA

#10225 replaced the projected 2027 SSA uprating index with the 2026Q3
CPI-W average and set the 2027 SSI federal benefit rate to $1,029. The
NC Special Assistance 2027 case still expected the old projections
($1,436 rate, $1,021.83 FBR), so the states-shard-1 suite fails on main
and on every PR. The uprated rate is now $1,448 and the payment $489.

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

* Address review: MS floor citation, IM link, exact limits, payment test

- Cite Rule 6.1 C, the printed 60% SMI table and FY2026 plan assurance (2)
  in the Mississippi floor comment; the printed table itself falls below
  the floor at sizes 11 to 20.
- Point the IM 2023-01 references to the acf.gov archive URL.
- Correct test comments that showed float32-rounded DC and MA limits.
- Add a Mississippi payment test for a household that qualifies only
  through the floor.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@hua7450

hua7450 commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the review. Fixes pushed in 3c85f5a.

  • S4: fl_liheap_eligible now rounds the floor to cents before the strict comparison, matching Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279: floor = np.round(guideline * p_hhs.fpg_floor, 2) and (income <= limit) | (income < floor). In fl_liheap.yaml Case 25, the $101,915.01 row is now exactly $101,915 for 15 people (ineligible, $0), next to $101,914.99 (eligible, $200), so a <= mutation now fails the test. Add Georgia LIHEAP regular heating assistance #9968 gets the same rounding in ga_liheap_eligible.py.

  • S5: All three 42 U.S.C. 8624 links now end in #b_2_B: in gov/hhs/liheap/fpg_floor.yaml, fl_liheap_eligible.py and fl_liheap_income_limit.py. fpg_floor.yaml is now byte-identical to the copy in Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 (blob aeb7f8c5b0). Add Georgia LIHEAP regular heating assistance #9968 and Add Ohio HEAP regular heating assistance #9975 carry the same file, so the add/add merges cleanly in any order.

  • G8: payment/base_amount.yaml now records the conflict. FY2026 plan item 2.6 (page 9) prints the FY2025 estimates ($400 minimum, $1,350 maximum), while the October 2025 matrix pays $200 to $700 with all additions. Manual Part 200 Q.4 and contract D(10)b (both page 9) require the current matrix. The fl_liheap.yaml header now cites the matrix for the 350 / 300 / 250 / 200 bases.

  • G9: eligibility/fpg_year_lag.yaml now cites LIHEAP IM 2024-02, IM 2025-02 and IM 2026-01, with the same titles and links as Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279. Its comment says that the lag also sets the floor's guideline year, and the value is unchanged. I left the optional 42 U.S.C. 8622(8) and Pub. L. 103-252 note out of fpg_floor.yaml so the file stays byte-identical to Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279.

  • G10: Partly applied. The contract stays one reference entry: a #page=12 link under # PDF pages 12-13. The repo's reference rule in CLAUDE.md requires one entry per source document and bars per-page splits. The floor comment now cites G(8)e at page 13, and the annualization comment cites G(8)a at page 12.

  • G11: Partly applied, under the same rule. The manual stays one entry: its link opens the first cited page (39) and its title ends #page 39-40,49-51. The title now names the parts on those pages: 900.02B, 900.03B(1), 1200.01 and 1200.02.

  • G12: Added the FY2025 plan to the fl_liheap_eligible references for item 2.3, as FL_Plan_2025.pdf#page=8 under # PDF pages 8-9.

  • G13: The earned.yaml and unearned.yaml descriptions now say "adult members". The FFY2027 title in base_amount.yaml adds "(estimated minimum $200, maximum $700)". Reference titles and parameter comments in the Florida parameter files now capitalize "Section".

  • G14: The fl_liheap_income_limit comment now names contract G(7)d (150% of the guideline for every size) and G(8)c (150% from 9 people). It notes that G(1) (page 11) and D(10)b (page 9) defer to the matrix, and the contract is now in the variable's references. The fl_liheap_eligible comment now quotes the "whichever is lower" rule in G(8)a and manual 1200.03A; annual income stands in for both measures. The Florida programs.yaml note now names the size-13 departure and is trimmed to two sentences; its other caveats stay in the code comments and the PR body.

  • G15: Added three cases to fl_liheap.yaml:

    • Case 26 (14 people): $60,000 pays $300, the $96,465 limit pays $200, and one cent more pays $0. This also pins the one-year lag, because the 2026 guideline would put the floor at $98,780.
    • Case 27: two parents with $100,000 and 13 children, one aged 4, receive $350 through the floor.
    • Case 28 (2027 carry-forward): the limit is $103,148 and the floor $105,028. $105,027.99 pays $200 and exactly $105,028 pays $0.

    The new integration.yaml has six FY2026 households built from the $14 Florida minimum wage, SSA's 2026 SSI and survivor amounts and EIA's 2024 Florida electric bill. I also fixed the fl_liheap_categorically_eligible.yaml header. Florida now has 72 cases in 7 files.

  • G16: Declined for now. The floor follows Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279, which calls fpg() inline. A shared lagged-guideline and floor helper is planned as a follow-up refactor after these PRs and Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 merge, and it would replace a Florida-only fl_liheap_fpg. The source-conflict comments stay next to the formulas they explain.

  • G17: Agreed; this is a follow-up outside this PR. Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 applies gov.hhs.liheap.fpg_floor to DC, MA, MS, NJ and OR, and lists Indiana, Maryland and Riverside County for a later PR.

  • G1: Still declined. History is out of scope for this PR, so FY2023-FY2024 stay unclaimed backfilled estimates.

  • G7: LIHEAP wave 2a: encode Florida LIHEAP regular heating assistance TheAxiomFoundation/rulespec-us#1534 is refreshed to match this head.

Thanks also for checking the contract G(7)d / G(8)c, size-13 and G(1) points. G14 now records the first two in the code comments and programs.yaml.

@DTrim99

DTrim99 commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

PR Review (round 2): Add Florida LIHEAP regular heating assistance

PR #9969 (author: hua7450). This round reviews head ba61f132b2; round 1 reviewed 7c5688f9ec. Four commits and one outside review came in between:

Neither merge had a hand-resolved conflict. fpg_floor.yaml is the same blob as main's (aeb7f8c5b0), so the #10279 add/add merged cleanly, and the file is no longer in the PR's diff.

Path prefixes, as in round 1:

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

Line numbers refer to ba61f132b2.

Summary

Ziming fixed the round-1 critical and all three should items:

  • C1 (110% floor). fl_liheap_eligible now treats income below 110% of the one-year-lagged guideline as income-eligible. It uses the shared gov.hhs.liheap.fpg_floor, rounds the floor to the cent and keeps the statute's strict "less than", as Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 does for MS, NJ, OR and DC.
    • I checked both claimed years.
      • FY2025: the floor can never bind. The limit is at least 150% of the same guideline for every size.
      • FY2026: the floor binds from 15 people, and the formula covers every size from 15 up.
    • Tests. Cases 25, 27 and 28 pin the rate, the cent edge, the lag and the Florida household size.
  • S1 (size 13). Size 13 now uses 60% of SMI for both the limit ($94,610) and the bands ($47,305 / $66,227 / $80,419). The override and both published_band_* parameters are gone, and the PR body now says the portal's $13,141 follows the printed row.
  • S2. All five remaining descriptions use the suggested wording; the sixth file is deleted. No Florida parameter mentions student status.
  • S3. Household-size Case 2 asserts a $0 limit. The bill term is dropped, so an explicit has_heating_expense: false is respected, and eligibility Case 7 pins it.

Of the seven suggestions, six are fixed (G2–G7). G1, backfilling FY2023–FY2024, is declined because history is out of scope. That matches #9967 and #9968, and I accept it.

His second commit also fixes Pavel's two should items: the floor is rounded to the cent, and the links are anchored.

There are no new critical or should findings. One new suggestion (checklist item 16): #10182 reached main after this head's last merge.

Batch checks:

Every new or changed expectation checks by hand: 11 new cases, 1 rewritten case, 1 new assertion, and the cases whose unread inputs were removed. CI is 29/29 green at the head. The branch is 15 ahead of main and 17 behind, and merges cleanly.

Prior findings status

Finding Status Evidence
C1: from 15 people the FY2026 limit (60% of SMI) fell below the 110%-of-poverty floor in 42 U.S.C. 8624(b)(2)(B), so protected households got $0 Fixed in every claimed year The code. V/eligibility/fl_liheap_eligible.py:38-44 computes fpg(size, state_group, period, parameters, year_lag=p.fpg_year_lag) at the Florida size, then floor = np.round(guideline * p_hhs.fpg_floor, 2) and income_eligible = (income <= limit) | (income < floor). The parameter is byte-identical to main's. FY2025 (period 2025). The limit is max_(smi_limit, guideline * 1.5) with the same lagged 2024 guideline, so it is at least 1.5 / 1.1 = 1.36 times the floor at every size. The floor never binds, and FY2025 results are unchanged. For example, at size 15 the limit is $135,570 against a floor of $99,418. FY2026 (period 2026). The floor binds from 15 people; the full table is under Verified. Tests. Case 25 gives $200 for 15 people at $100,000, 16 people at $105,000, and 15 at $101,914.99, and $0 at exactly $101,915. Case 27 builds the 15-person household from people and gets $350. Unclaimed 2027 carry-forward. It binds from 15 too, and Case 28 pins it.
S1: the size-13 limit and bands came from different readings of one printed row Fixed The parameters. P/payment/published_band_size.yaml and published_band_upper_bound.yaml are deleted, and so is the override in V/fl_liheap.py. No reference remains. The tests. T/fl_liheap.yaml Case 24 has 10 rows: [350, 300, 300, 300, 250, 250, 200, 200, 0, 200] at 47,305 / 47,305.01 / 60,000 / 66,227 / 66,227.01 / 80,419 / 80,419.01 / 94,610 / 94,610.01 / 100,000 with SNAP. So 13 people with $60,000 now get $300, like 12 and 14 people (Case 26 row 1). The rationale. He chose the 60% reading for both the limit and the bands. It is the only reading within the federal ceiling: the greater of 150% of poverty ($122,475 for 13) and 60% of SMI. The matrix footnote, plan item 2.1 and the FFY2027 draft also support it. The body now says the portal's $13,141 is 157,686 / 12 and that the model departs from it.
S2: six descriptions were off-template, two of them stale Fixed The five rewritten files. categorical_programs, earned, unearned, household and supplement use my wording. earned and unearned say "adult members" (Pavel's G13). The sixth. published_band_upper_bound is deleted. All files. All 15 Florida descriptions end at "under the Low Income Home Energy Assistance Program." No Florida parameter or variable mentions student status, apart from the countable-income comment that describes the superseded nonstudent exception.
S3: the size-0 limit mask and the bill term in the non-rent branch had no test that would fail Fixed (1) Mask. T/fl_liheap_household_size.yaml Case 2 asserts fl_liheap_income_limit: 0. Unmasked, it would be $32,155. (2) Bill term. Dropped (V/eligibility/fl_liheap_eligible.py:65-69), so the model respects an explicit has_heating_expense: false, as NJ, MD, OR and NY do. Eligibility Case 7: one adult with $14,820 of wages and a $1,200 gas bill gives [true, false]. Restoring the term fails row 2.
G1: reproduce the FY2023–FY2024 matrices (truncation and the size-8 split) Declined (accepted) History is out of scope, and the years stay unclaimed backfilled estimates. This matches #9967 G1 and #9968 G1. The body says other years are unverified, and the registry has no verified_years.
G2: cite the published draft FFY2027 plan Fixed P/eligibility/smi_rate.yaml cites item 2.1 (#page=8) and P/payment/base_amount.yaml item 2.6 (#page=9, "estimated minimum $200, maximum $700"). The body's years-covered text summarizes it. Period 2027 stays an unverified estimate.
G3: monthly test, unemployment FAQ, fl_oss Fixed Monthly test. The fl_liheap_eligible comment (lines 28-35) cites 1200.03A and G(8)a, including "whichever is lower", and bounds the portal difference at $6 a year. I checked $3,504 × 12 = 42,048, which is $1 stricter. FAQ. P/income/sources/unearned.yaml:29-35 cites it for the unemployment and gift exclusions. fl_oss. The same comment explains its exclusion via 900.02B and 900.03B(1).
G4: reference polish Fixed Manual pages. The fl_liheap_eligible manual comment reads # PDF pages 4, 23, 39, 41, 43, 47-48, 50-51. Household size. fl_liheap_household_size.py has # PDF pages 41-42 above a #page=41 href. Supplement. supplement.yaml cites FY2026 plan item 2.4 (p. 9).
G5: the size-13 sentinel and its 2027 bands Fixed via S1 The 0 sentinel is gone. In 2027 the size-13 bands follow the 2027 limit (99,255).
G6: test hygiene Fixed Student flags. is_full_time_student drops from 82 lines to 7: person2 in countable Cases 5–10 and fl_liheap.yaml Case 23, all of which name student status. Headers. The household-size and categorical headers are rewritten. Unread inputs. No heating inputs remain in the size, limit, income or categorical tests.
G7: PR body and issue housekeeping Fixed The body. It no longer says draft. It adds the portal's size-13 figure and the FFY2027 draft. It notes that FY2025 item 2.3 sits on both sides of the heat-in-rent conflict (pp. 8–9) and that the FY2026 plan answers No. The cooling-season point is a not-modeled row. The issue. rulespec-us#1534 is refreshed to ba61f132b2 and no longer says "open as a draft".

Pavel's review (between rounds). His two should items are fixed:

  • S4 (float edge). np.round(guideline * p_hhs.fpg_floor, 2) with a strict < (line 43) is the same line as ms_liheap_eligible.py:35 on main. Case 25 row 4 is now exactly 101,915, which gives false and $0. Unrounded, 92,650 × 1.1 = 101,915.00000000001 would admit it.
  • S5 (anchors). All three 8624 links end #b_2_B: fl_liheap_eligible.py:12, fl_liheap_income_limit.py:19 and the shared fpg_floor.yaml.

Of his suggestions:

  • Done:
    • G8: the plan 2.6 conflict note in base_amount.yaml:2-8 and the fl_liheap.yaml header.
    • G9: IM 2024-02, 2025-02 and 2026-01 in fpg_year_lag.yaml.
    • G12: the FY2025 plan #page=8 under # PDF pages 8-9.
    • G13: "adult members", the base-amount title, and "Section".
    • G14: contract G(7)d and G(8)c in the limit comment, G(8)a "whichever is lower", and the size-13 departure in the programs.yaml note.
    • G15: Cases 26–28, integration.yaml, and the categorical header.
  • Declined, correctly (G10, G11). He did not split the contract or manual references per page. CLAUDE.md "Parameter and variable references" requires one entry per source document. The two entries use # PDF pages 12-13 and a #page 39-40,49-51 title, which is the house form.
  • Deferred: G16, a shared lagged-guideline helper. Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 also calls fpg() inline.
  • Follow-up outside the PR: G17, other states. Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 has since applied the floor to DC, MA, MS, NJ and OR.

New findings

Critical (must fix)

None.

Should address

None.

Suggestions

1. After #10182, count military SBP survivor annuities through military_retirement_income.

  • Where: P/income/sources/unearned.yaml:11 lists military_retirement_pay (with pension_income at line 10 and survivor_benefits at line 13).
  • What changed on main: Wire military retirement pay and survivors into federal and state tax (#10181) #10182 merged on 2026-10-20, after this head's last merge at 1661d715bd.
    • At this head, military_retirement_pay is documented as "The benefits received under a United States military retirement plan, including survivor benefits".
    • On main it reads "Taxable retirement pay received by former members of the uniformed services".
    • SBP annuities now go in military_retirement_pay_survivors: "Taxable survivor annuity payments received by surviving spouses ... (such as the Survivor Benefit Plan (SBP)...)".
    • military_retirement_income adds both. pension_income (taxable plus tax-exempt pensions) does not include the new input.
  • The rule counts these payments. FY2026 plan item 1.9 (p. 6) counts retirement and pension benefits. The PR's own comment at unearned.yaml:6-9 cites it, and T/fl_liheap.yaml Case 18 counts $35,000 of military retirement pay.
  • Effect on the merged tree (worked out from the code, not run). A surviving spouse aged 50 has $35,000 a year of SBP annuity entered in military_retirement_pay_survivors. She has natural gas heat with a $1,200 bill, no other income, and no SNAP, TCA or SSI, in 2026:
    • Merged tree: countable income is $0, so band 1, $350.
    • Counting the annuity: $35,000 is above the $32,155 limit and the $17,215 floor, so $0, as in T/fl_liheap.yaml Case 18 row 1 for retirement pay.
    • The same amount in survivor_benefits ("Survivor benefits other than Social Security survivor benefits") would count. That narrows the gap, but Wire military retirement pay and survivors into federal and state tax (#10181) #10182 names the new input for SBP.
  • Why a suggestion, not should:
  • Fix, if taken here:
    • Replace the entry with military_retirement_income.
    • Add a military_retirement_pay_survivors amount to countable-income Case 18 or add a separate case.
    • Update the Inputs line of rulespec-us#1534.

Verified

  • Federal 110% floor (42 U.S.C. 8624(b)(2)(B)): the round-1 critical, year by year.
    • Florida assures it. The FY2026 plan assurances (p. 45) and contract G(8)e (p. 13) assure it.

    • Guideline year. fpg() reads gov.hhs.fpg at period minus fpg_year_lag (1). Period 2026 therefore uses the 2025 guideline ($15,650 + $5,500 per added person), and period 2025 the 2024 guideline ($15,060 + $5,380). Those are the HHS-mandatory years, per IM 2024-02 and IM 2025-02 Attachment 2. This matches Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279.

    • FY2025. fpg_rate is 1.5 from 2024-10-01, so the limit is at least 1.5 × the guideline and the floor (1.1 ×) cannot bind:

      • size 1: limit 30,588, floor 16,566;
      • size 8: limit 81,175 against a 150% amount of 79,080, floor 57,992;
      • size 20: limit 175,920, floor 129,008.
    • FY2026. fpg_rate is 0, so the limit is 60% of SMI, floor(61,837 × factor):

      Size 60% SMI limit 110% floor (2025 guideline) Floor binds
      13 94,610 89,815 no
      14 96,465 95,865 no
      15 98,320 101,915 yes
      16 100,175 107,965 yes
      17 102,031 114,015 yes
      18 103,886 120,065 yes
      19 105,741 126,115 yes
      20 107,596 132,165 yes
      • One formula for every size. The floor line has no size-specific branch, so sizes 17 and up use the same code path as the tested 15 and 16. I worked this out from the code and didn't run it.
      • Protected households are paid. Their income is above the limit, so they fall in band 4 and get $200 plus any additions (V/fl_liheap.py:63-68, a documented estimate). No protected household is paid $0.
    • 2027 carry-forward (unclaimed). floor(64,873 × 1.59) = 103,148 against 1.1 × 95,480 = 105,028, so it binds from 15. Size 14 does not bind: 101,201 against 98,780.

  • Mutation check (item 13), reasoned from the tests and code at the head:
    • The floor in fl_liheap_eligible:
      • The | (income < floor) arm. Case 25 rows 1–3, Case 27 and Case 28 row 2 would all become ineligible.
      • The strict <. Case 25 row 4 (101,915) and Case 28 row 3 (105,028).
      • The cent rounding. Without it, 101,915.00000000001 and 105,028.00000000001 would admit those same rows.
      • The 1.1 rate. Case 25 rows 3–4 bracket it to the cent.
      • The one-year lag. Lag 0 gives 2026 floors: 98,780 at size 14, which admits Case 26 row 3 (96,465.01), and 105,028 at size 15, which admits Case 25 row 4.
      • Florida size, not SPM size. Cases 25, 26 and 28 set the Florida size on one-person SPM units. An SPM-size floor would be 17,215 and fail rows 1–3 of Case 25.
    • S1. Reinstating any printed size-13 cutoff changes Case 24 rows 1–7.
    • S3. The size-0 mask is pinned by household-size Case 2, and the dropped bill term by eligibility Case 7 row 2.
    • Unchanged since round 1: the other branches. Round 1 confirmed them by mutation runs, and the code around them has not changed apart from the deleted override.
  • State-gated keys (item 15, NH Add New Hampshire state supplementation for 2026 #10156).
    • No state-gated int or enum is used as a parameter key. p.payment.base_amount[band] reads a local select(..., default=4), which is always 1–4.
    • The household size. fl_liheap_household_size goes only into arithmetic: the smi_size_factor clip and the linear fpg().
    • The other keys. state_group_str and state_code_str are always valid keys.
    • Test. T/fl_liheap.yaml Case 10 runs Florida and non-Florida rows together.
  • Integrate modeled state unemployment insurance into income flows #9558 (item 11). Florida lists no unemployment source, since the plans and FAQ exclude it. The guard's four tests pass at the head (Rest shard-1).
  • Document disjoint health premium inputs and correct consumer treatment #10046 (item 14) and the wage lessons (OK Add Oklahoma state supplementation for 2026 #10165, NH Add New Hampshire state supplementation for 2026 #10156 round 3).
  • IIJA and FY2027 (item 12).
    • IIJA. No supplement in any Florida plan, matrix, manual or contract, as in round 1.
    • FY2027 sources. On 2026-10-20 the Clearinghouse returns 404 for a Florida FY2027 plan and for both FY2027 matrix names. The draft FFY2027 plan is now cited, and period 2027 stays a documented estimate.
  • Other main commits.
  • New and changed expectations, checked by hand.
    • FY2026 inputs: four-person 60% amount floor(103,063 × 0.6) = 61,837. Band tops round half up.
    • fl_liheap.yaml:
      • Case 24 (rewritten):
        • Limit floor(61,837 × 1.53) = 94,610. Tops are 47,305; 66,227; 80,418.5, rounded to 80,419.
        • That gives [350, 300, 300, 300, 250, 250, 200, 200].
        • 94,610.01 is above the limit and the floor (89,815), so false and 0. SNAP receipt at 100,000 gives categorical eligibility and band 4: 200.
      • Case 25 (new; row 4 changed): limits 98,320 and 100,175; floors 101,915 and 107,965.
        • 100,000 and 105,000 are protected: band 4, 200.
        • 101,914.99 gives 200; exactly 101,915 gives false and 0.
      • Case 26 (new): limit 96,465 with tops 48,233, 67,526 and 81,995. The floor is 95,865, so it does not bind.
        • 60,000 is band 2, 300.
        • 96,465 is band 4, 200.
        • 96,465.01 gives false and 0.
      • Case 27 (new): 15 citizens, so size 15. Wages 60,000 + 40,000 = 100,000, which is above 98,320 and below 101,915. No SSI, SNAP or TCA, so not categorical. Band 4 is 200, plus 150 for the child aged 4: 350.
      • Case 28 (new, period 2027):
        • Limit 103,148 and floor 105,028.
        • 103,148 is within the limit: band 4, 200.
        • 105,027.99 is protected: 200.
        • 105,028 gives false and 0.
    • fl_liheap_eligible.yaml Case 7 (new): 14,820 = 20 × (39 × 14 + 13 × 15), which is within 32,155. A gas bill outside rent with has_heating_expense [true, false] gives [true, false].
    • fl_liheap_household_size.yaml Case 2 (new assertion): an undocumented adult means size 0, so the limit is 0.
    • integration.yaml (new):
      • Case 1: size 3, limit floor(61,837 × 0.84) = 51,943. 29,120 is between 25,972 and 36,360, so band 2: 300 + 150 = 450.
      • Case 2: survivor benefits 23,028 count gross. They are between 22,509 and 27,332, so band 3: 250 + 100 = 350.
      • Case 3: SSI 11,928 is categorical and within 16,078, so band 1: 350 + 100 = 450.
      • Case 4: 29,120 + 14,560 = 43,680, between 43,286 and 52,561, so band 3: 250.
      • Case 5: the son's 7,280 is excluded. 29,120 is between 21,025 and 29,434, so band 2: 300. Counting the son, 36,400 > 35,742 would give band 4.
      • Case 6: 58,240 is above 42,049 and the 23,265 floor, so false and 0.
      • All six: heating expense 1,873 and has_heating_expense true.
    • Changed inputs, unchanged outputs:
      • The cases: is_full_time_student, fuel bills and heating_type were dropped from categorical Cases 1–6, eligibility Cases 1–6, income-limit Cases 1–3, countable Cases 1–20, household-size Cases 1–2 and most fl_liheap.yaml cases.
      • No Florida variable reads the student flag. The size, income, limit and categorical variables read no heating input.
  • Inputs not checked. I didn't check SSA's $1,919 aged widow(er) average or EIA's $156.09 Florida bill. They are inputs only, and every expectation follows from them.
  • Wiring.
    • Registry. programs.yaml lists FL partial with no verified_years. The note now names the size-13 and contract departures. The registry test passes.
    • Aggregates. Florida is in no aggregate, which matches every merged LIHEAP state on main.
    • Gating. defined_for = StateCode.FL is on all six variables.
    • Changelog. changelog.d/fl-liheap.added.md is top level and typed added.
  • Partner tests. The PR touches none, and Household API Partners passes.

Checklist results (LIHEAP wave 2a)

  1. State plan and manual: pass. Encoded values are unchanged apart from size 13, which now follows the 60% rule that the footnote, plan 2.1 and the draft FFY2027 plan state. The floor rests on 8624(b)(2)(B), plan p. 45 and contract G(8)e.
  2. Income definition: pass. Gross wages and Social Security, per-source floors, net gambling, and minors excluded. Suggestion 1 covers the post-Wire military retirement pay and survivors into federal and state tax (#10181) #10182 SBP input.
  3. Backdating: pass for claimed years. FY2023–FY2024 are unclaimed and declined (G1). No FY2027 matrix is published.
  4. Household and arrangement rules: pass. An explicit no-obligation outside rent is now respected (S3). Every route is pinned.
  5. Tests: pass. 72 cases in 7 files, with every new or changed expectation checked by hand. Periods are plain. The floor edges are pinned to the cent in 2026 and 2027.
  6. Descriptions: pass. All 15 follow the template.
  7. References: pass.
    • The 8624 links are anchored.
    • Variable tuples use # PDF pages comments.
    • Multi-page titles use #page 5-7 and #page 39-40,49-51.
  8. Wiring: pass. Registry, no aggregate (as in the siblings), defined_for gating, and no take-up beyond that of snap, tanf and ssi.
  9. Axiom: valid queued line. Suppress MO income tax debugging print statement #1534 matches the head (see below).
  10. Branch and CI: 29/29 green. A clean merge with main; the siblings conflict only in programs.yaml.
  11. Integrate modeled state unemployment insurance into income flows #9558: not applicable (no unemployment source). The guard passes.
  12. IIJA / FY2027: not applicable (no supplement). The draft FFY2027 plan is cited; no FY2027 plan or matrix is published.
  13. Mutation check: pass. Every new branch is pinned, including the floor's rate, rounding, strictness, lag and household size.
  14. Document disjoint health premium inputs and correct consumer treatment #10046 health premiums: not applicable. Florida deducts no premiums and reads gross employment_income.
  15. State-gated index defaults: not present. The band comes from a defaulted select, and the size is used only in arithmetic.
  16. Wire military retirement pay and survivors into federal and state tax (#10181) #10182 survivor annuities: Suggestion 1.

Axiom line assessment

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

  • Issue state.
    • Suppress MO income tax debugging print statement #1534 is open and labelled pe-parity and enhancement. It was last updated 2026-10-19 21:03 UTC and has no comments.
    • rulespec-us main (5796861e58, 2026-10-20) has no Florida LIHEAP module: us-fl/policies/ holds only cms, dcf and income_tax. So queued is still the right form.
    • It records two blockers: the sources need ingest, and there is no reviewed PE revision yet.
  • Dispatch-ready. It has:
    • module paths with corpus citations;
    • the verbatim manual, plan, matrix, application, FAQ, contract, HHS and statute text;
    • six required outputs;
    • companion tests 1–22, hand-derived from the sources and mapped to PE cases.
  • Matches the head ba61f132b2:
    • Cases: 72 cases in 7 files, listed per file.
    • Eligibility: "strictly below 1.1 x the one-year-lagged guideline for the size rounded to cents", and "an explicit false is respected".
    • Income limit: size 13 at 60% of SMI.
    • Companion tests 16–22 match Cases 24–28, eligibility Case 7 and integration.yaml.
  • The only update it would need is the Inputs line, if Suggestion 1 is taken.

CI status

29 pass, 0 pending, 0 failed (run 39324229624 on head ba61f132b2, pull_request, 2026-10-19 21:01 UTC to 2026-10-20 02:03 UTC). I re-checked gh pr checks 9969 at the end of this review.

  • Quick Feedback ran all seven Florida LIHEAP files at the head: 6 + 7 + 3 + 28 + 2 + 20 + 6 = 72 passed. The whole Florida tree also passed (356).
  • Rest (Python, shard-1) passed:
  • Also passed: Household API Partners, Microsimulation, both Rest jobs, all 11 Baseline shards, all 9 Contrib shards, PR validation, Package and compatibility, and codecov patch and project.
  • Locally: no tests or probes were run.

Branch status

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.

Round 2: the round-1 critical (110% poverty floor) is fixed in every claimed year, and S1-S3 plus Pavel's S4-S5 are fixed. One open suggestion about #10182 survivor annuities. Full report in the comment above.

# Conflicts:
#	policyengine_us/programs.yaml
@hua7450
hua7450 merged commit 11951ba into main Oct 20, 2026
19 of 29 checks passed
@hua7450
hua7450 deleted the fl-liheap branch October 20, 2026 21:20
MaxGhenis added a commit that referenced this pull request Oct 21, 2026
…seline (#10334)

The guard (#10287) took its KNOWN_UNMARKED baseline at 0f21a63. FL LIHEAP
(#9969) and SD LIHEAP (#9974) merged before the guard did, each with
comments the ratchet reads as unmarked source conflicts, so
test_conflict_sounding_comments_do_not_grow fails on main from ce9377e.
These five files were on main when the guard landed, so they belong in the
baseline, one comment each.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
PavelMakarchuk added a commit that referenced this pull request Oct 21, 2026
…d Riverside County LIHEAP (#10281)

* Apply the federal 110% poverty floor to MS and OR LIHEAP

42 U.S.C. 8624(b)(2)(B) bars a state from excluding a household solely on
income below 110% of the poverty level. The 60% SMI limit falls below that
floor in Mississippi from household size 11 (FY2026-FY2027) and in Oregon
from size 19 (PY2025) or 20 (PY2026-PY2027). Both eligibility tests now
accept income below 110% of the poverty guideline that HHS makes mandatory
on October 1 of the program year (one-year lag).

Adds gov.hhs.liheap.fpg_floor, identical to the file in #9968 and #9969,
plus a poverty guideline year lag for each state.

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

* Apply the federal 110% poverty floor to DC, MA and NJ LIHEAP

The 60% SMI limits fall below 110% of the poverty guideline only for very
large households: DC from size 34 to 39 in 2022-2024, MA from size 30 to 34
and NJ from size 28 to 32 in 2022-2027. The eligibility tests now accept
income below the floor, using the one-year guideline lag. MA reuses
ma_liheap_fpg, which already lags the guideline; DC and NJ get their own
fpg_year_lag parameters.

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

* Anchor the LIHEAP floor reference to 42 U.S.C. 8624(b)(2)(B)

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

* Update the NC SA 2027 test for the announced 2027 COLA

#10225 replaced the projected 2027 SSA uprating index with the 2026Q3
CPI-W average and set the 2027 SSI federal benefit rate to $1,029. The
NC Special Assistance 2027 case still expected the old projections
($1,436 rate, $1,021.83 FBR), so the states-shard-1 suite fails on main
and on every PR. The uprated rate is now $1,448 and the payment $489.

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

* Address review: MS floor citation, IM link, exact limits, payment test

- Cite Rule 6.1 C, the printed 60% SMI table and FY2026 plan assurance (2)
  in the Mississippi floor comment; the printed table itself falls below
  the floor at sizes 11 to 20.
- Point the IM 2023-01 references to the acf.gov archive URL.
- Correct test comments that showed float32-rounded DC and MA limits.
- Add a Mississippi payment test for a household that qualifies only
  through the floor.

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

* Apply the federal 110% poverty floor to IN, MD and Riverside LIHEAP

The 60% SMI limits fall below 110% of the poverty guideline from
household size 15 (2025) or 16 (2026-2027) in Indiana EAP, size 29 in
Maryland MEAP (FY25-FY27), and size 20 (2025) or 21 (2026-2027) in
Riverside County LIHEAP. The eligibility tests now accept income below
the floor, with the one-year guideline lag. Maryland reuses
md_meap_fpg; Indiana and Riverside get fpg_year_lag parameters.

Stacked on #10279, which adds gov.hhs.liheap.fpg_floor.

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

* Remove the #10279 changelog fragment that main already released

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 22, 2026
…10349)

* Point the FL and SD LIHEAP conflict candidates at their code on main

#10287 wrote these candidates while #9969 (FL) and #9974 (SD) were open, so
each said its code was not on main. Both have merged. Each candidate now
lists the files that decide it, and its note says which source that code
follows, as read on main. One note changes substance: SD's merged code caps
kerosene at unpaid charges like fuel oil, following the plan and rules, not
the 2018 manual's full payment by check. The SD 2025 table candidate gets the
archived DSS page as its source.

Two FL conflicts recorded in the merged code had no candidate: the FY2026
plan's payment estimate against the October 2025 matrix, and manual part
900.01D against parts 1100.03D and 1200.01A and contract G(7)d on the income
limit.

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

* Add the FL floor and minors' income candidates; reframe the SD limits

From DTrim99's review and a Sol review of #10349.

- Two more conflicts the merged FL code records had no candidate. The first is
  the federal 110% poverty floor against the 60% SMI limit from household
  size 15 (statute against guidance; PE-US follows the statute). The second is
  minors' income: the current application and portal FAQ against manual part
  1200.01D. Every value is checked against the merged code and its tests: the
  floor case's $98,320 limit and $101,915 floor are fl_liheap.yaml's Case 27.
- The SD income-limit entries credited ARSD 67:15:01:10 with a limit formula
  it doesn't contain; it sets only the three-month income period. FY2025 is
  now the plan's 60% of SMI against the published table's 200% of the 2024
  guideline for sizes 1-3: $32,984 against $30,120 for one person, as
  table/amount.yaml records. FY2026 is DSS's 200% of the 2025 guideline
  against the plan's 60% of SMI. Its $22,013 is the model's flooring, and
  $22,014 is unrounded.
- Anchors and sources:
  - FY2026 plan item 2.1 is on page 8, not 4.
  - Contract G(8)c is on page 12, not 9.
  - The null URLs are filled from the merged code's references.
  - The FL manual-sections entry gets the plans, the matrix and the manual's
    "current matrix" page.
  - Kerosene gets plan item 9.1 and ARSD 67:15:01:43.01.
  - The FL size-13 and SD 2026 entries list the remaining deciding files.

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

* Cite the FY2025 FL LIHEAP matrix; list the floor candidate's lag and band files

Review nits from the round-2 review of #10349:
- us-fl:liheap-income-limit-manual-sections now cites the FY2025 payment
  matrix the code follows.
- us-fl:liheap-income-floor-vs-smi-limit lists fpg_year_lag.yaml and
  fl_liheap.py, which its numbers rest on, and says the band 4 base is
  the model's estimate.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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 regular heating assistance

3 participants