Skip to content

Add Georgia LIHEAP regular heating assistance - #9968

Open
hua7450 wants to merge 16 commits into
mainfrom
ga-liheap
Open

hua7450 wants to merge 16 commits into
mainfrom
ga-liheap

Conversation

@hua7450

@hua7450 hua7450 commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Adds Georgia's LIHEAP regular heating assistance for FY2025 and FY2026. The model tests income against 60% of state median income, places eligible households in Level I or Level II by the published lower-income cutoffs, and pays the fixed amount for the primary heating fuel. Federal law bars excluding a household on income below 110% of the poverty guideline (42 U.S.C. 8624(b)(2)(B)). Georgia's 60% limit, including its printed size-16 rows, falls below that floor from household size 16, so the model keeps a household of 16 or more eligible above the 60% limit when its income is below 110% of its poverty guideline. The model rounds that floor to the cent, so income exactly at 110% does not qualify. Unsubsidized renters whose rent includes all utilities and who report no electric bill receive the lowest award for their income level. Renters with heat in rent who are billed for electricity receive the amount for their main heating fuel, paid to the electric vendor, with or without a subsidy and whatever tenant_pays_utilities says. In FY2026, a one-person household with $12,000 of wages and electric heat receives the Level I electric amount, $500. In FY2025, a one-person household with $13,000 of wages is above the $12,995 Level I cutoff and receives $400.

Fixes #9959

Regulatory authority

The January 2022 manual is the newest Georgia LIHEAP income manual located. The current PAMMS export contains administrative chapters 100–800, not a replacement for income chapter 1200. The contemporaneous FY2022 plan already contains the cash-gift checkbox disagreement, so the detailed manual is used for cash contributions and gifts. Annual income approximates the application-month assessment.

Eligibility

Requirement Source How modeled
Georgia residence — defined_for = StateCode.GA
Household size excludes nonqualified noncitizens Manual pages 51–52 and 62; PAMMS chapter 100, page 4; DFCS LIHEAP page Counts members with is_citizen_or_legal_immigrant, with no SNAP waiting bars. A household with no qualified member is ineligible. Nonqualified adults' income counts in full. PAMMS chapter 100 ("Be US citizens or lawfully admitted immigrant") and the DFCS LIHEAP page ("The applicant needs to be a U.S. citizen or legally admitted immigrant") support counting lawful immigrants.
Income at or below 60% of state median income, or below 110% of the poverty guideline FY2026 plan section 2.1, page 8; FY2025 and FY2026 matrices, step 1; 42 U.S.C. 8624(b)(2)(B); FY2025 and FY2026 plans, assurance 2 (page 43); LIHEAP IM 2025-02 and IM 2024-02, Attachment 2 Calls the shared liheap_smi_limit helper (#10019): floors 60% of the four-person state median income, applies the federal size factor and floors again. This order reproduces all 16 FY2026 limits and the FY2025 limits tested for sizes 1, 4 and 16 ($33,038, $63,535 and $102,926); the sources do not state the order. One person in FY2026: $34,549. The limit is inclusive. Income below 110% of the poverty guideline also qualifies, through the shared federal parameter gov.hhs.liheap.fpg_floor (1.1), whose file is identical to the copy in #10279. As in #10279, the model rounds the floor to the cent, so income exactly at 110% does not qualify ("less than 110 percent"). Georgia assures this floor in both plans (page 43). Georgia's limit uses no poverty guideline, so the model uses the one HHS makes mandatory for the fiscal year (fpg_year_lag 1: the 2025 guidelines in FY2026, the 2024 guidelines in FY2025 and the 2026 guidelines in the carried-forward 2027 estimate). The printed size-16 limits, $107,634 (FY2026) and $102,926 (FY2025), are below 110% of poverty ($107,965 and $105,336), so the floor applies from size 16 and governs over the printed row. A protected household above the 60% limit gets the Level II amount, and ga_liheap_income_limit still reproduces the printed table.
Energy burden Manual pages 3–4, 50, 57, 82 and 89; PAMMS chapter 100, page 4 A household qualifies with its own heating obligation (has_heating_expense) or a positive primary-fuel bill, including when heat is in rent or the household receives a housing subsidy. Unsubsidized rent that includes all utilities (heat in rent, tenant_pays_utilities false, positive rent, no housing assistance or public housing) qualifies with no bill. A renter with heat in rent, rent above $0 and a positive pre_subsidy_electricity_expense qualifies with or without a housing subsidy and whatever tenant_pays_utilities says (manual page 89, third row: "Paid to electric vendor because gas usage is indeterminate"; page 4: subsidized renters qualify when "their utility bill is in their name"; page 57: subsidized households whose rent includes utilities are ineligible only if they "cannot verify an energy burden"). For payment this route takes precedence over the all-utilities route, so the same inputs get the same award with or without a subsidy. The model reads page 82's ineligibility for subsidized housing where "the rent includes utilities" as rent that covers every utility, which a separate electric bill rules out. Heat in rent with none of these does not qualify, and a bill for a fuel other than the primary fuel does not establish the burden (PAMMS chapter 100: "a vendor bill/statement for the main heating source"). heating_type NONE is ineligible.
Categorical eligibility Manual Not applied; every household takes the ordinary income test (see below).

Countable income

Item Source How modeled
Members under 18 Manual section 1200.2, page 62 Excludes all income of members under 18.
Wages and business income Manual sections 1200.6–1200.7, pages 64–66 Counts wages and net self-employment, SSTB, farm operations and partnership/S-corporation income. Floors each source at zero, so a business loss offsets nothing.
Other income Manual section 1200.7, pages 65–69, and application item 12, page 83; FY2026 plan section 1.9, pages 5–7 Counts unemployment through total_unemployment_compensation (the reported amount, or modeled state unemployment insurance when none is reported; the model has no Georgia unemployment insurance program, so the reported amount counts), SSI, pensions, military retirement pay, railroad retirement (gross), survivor benefits, veterans benefits, disability benefits, workers' compensation, strike benefits, General Assistance, rental and farm rental income, dividends, capital gains, gambling winnings, alimony and child support. Floors each source at zero, so capital, rental and farm losses offset nothing.
Social Security net of the Medicare premium FY2025 and FY2026 plans section 1.9, page 6 ("Excluding MediCare deduction"); manual section 1200.7, page 69 Counts max(social_security − medicare_part_b_premium, 0) per adult.
Interest Manual section 1200.7, pages 66 and 69 Subtracts the first $25 a month ($300 a year) once from the household's adult interest. The manual does not say whether the disregard repeats per person or per account.
TANF FY2026 plan section 1.9, page 6 Counts the take-up-gated tanf aggregate, which includes ga_tanf, once per household.
Lottery winnings Manual section 1200.7, page 66 Counts gambling_winnings, the closest input; it also covers non-lottery gambling (see source conflicts).
Cash gifts and contributions Manual section 1200.7, page 65 Counts adults’ cash support through the existing financial_assistance input; receipts of members under 18 are excluded.

Benefit

Primary heating fuel Level I Level II
Electricity $500 $400
Natural gas $660 $560
Fuel oil $810 $710
Propane $680 $580
Wood $500 $400
  • The FY2025 and FY2026 matrices print the same amounts. Level I cutoffs are inclusive: one person $12,995 (FY2025) and $13,589 (FY2026); four people $24,355 and $25,469; sixteen people $40,485 and $42,336. Households above size 16 use the size-16 cutoff.
  • Every printed Level I amount equals the Level II amount plus $100 on both matrices. The model stores the Level II column and the $100 difference, an inferred pattern that reproduces all ten printed cells.
  • An unsubsidized renter whose rent includes all utilities and who reports no electric bill is paid directly at the lowest award for the income level, $500 in Level I or $400 in Level II (FY2026 plan page 30; manual page 89), including when the fuel is unspecified. A reported electric bill puts the renter on the electric-vendor route below, even when tenant_pays_utilities is false, so an unspecified main fuel then pays $0.
  • A renter with heat in rent who is billed for electricity is paid the amount for the main heating fuel, to the electric vendor (manual pages 4 and 89). The FY2024 matrix explains the asterisk on "main heating fuel type*": "The main fuel type is not always where the benefit is applied", so a natural gas household that applies its benefit to an electric bill receives the natural gas amount. A one-person household with natural gas heat in rent, a $1,200 electric bill and $12,000 of wages receives $660 in FY2026, with or without a housing subsidy and whatever tenant_pays_utilities says. An unspecified main fuel pays $0 on this route.
  • Kerosene, coal, solar, other and unspecified fuels have no matrix column; ordinary vendor payments for them are $0.
  • The reported bill does not cap the payment.
  • PAMMS chapter 100 (page 5) still prints benefits of "a minimum of $350 and maximum of $400" with a senior maximum. FY2026 plan item 16.1 (page 30) says Georgia updated the benefit matrix to remove the senior rule, so the model follows the matrix.

Years covered

Model year Program year One-person income limit One-person Level I cutoff
2025 FY2025, from October 1, 2024 $33,038 $12,995
2026 FY2026, from October 1, 2025 $34,549 $13,589

A calendar-year period reads the parameters in force on January 1. Formulas are undated and verified_years is "2025-2026". Other years are unverified backfilled estimates; no adopted FY2027 table was found, only a draft plan. The 110% poverty floor applies from size 16 in FY2025 and FY2026, and from size 17 in the carried-forward 2027 estimate.

Not modeled and source conflicts

Item Source Model treatment
Categorical eligibility for households receiving only public assistance Manual Requires every member's receipt and assistance-only income and resources; aggregate TANF and SNAP inputs cannot establish those facts.
Utility account credits of $1,000 or more and administrative household exclusions Manual Not identified; the selected heating account is assumed to meet them.
Level I cutoff above household size 16 FY2026 matrix, step 1 Uses the size-16 cutoff as a provisional value.
Printed size-16 income limit below the federal floor FY2025 matrix step 1, size 16 ($102,926); FY2026 matrix step 1, size 16 ($107,634); 42 U.S.C. 8624(b)(2)(B); FY2025 and FY2026 plans, assurance 2 (page 43) Both plans assure that Georgia "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". The floor governs: a size-16 household qualifies below $105,336 (FY2025) or $107,965 (FY2026). ga_liheap_income_limit keeps the printed table.
Kerosene, coal, solar, other and unspecified fuels on vendor payments FY2026 matrix, step 2 Pay $0 as a coverage gap (#9754 for unspecified fuel).
Other direct payments to the applicant FY2026 plan item 16.1 (page 30); manual page 89 (fourth and seventh rows), page 4 and section 1300.2 (page 70) Plan item 16.1 pays the lowest award when the benefit goes to the applicant. The manual also pays the applicant directly when utilities are paid to "the landlord or trailer park owner" and when the energy supplier has no vendor agreement or is not on the Approved Vendor List; subsidized tenants who pay "a landlord for utility costs" are paid directly or through the electric supplier. No input identifies these households; the model pays them the main-fuel amount when they report a bill.
Roomer and boarder allowances, mortgage-sale contracts and stipends Manual section 1200.7 Not handled.
Roomers, boarders, foster-child elections and group quarters Manual pages 51–52 Not identified; the SPM unit approximates the household.
Lawful noncitizens in household size Manual sections 101.2 (page 3), 1100.3 (page 50) and 1100.5 a (page 51) against 1100.14 (page 57) and the glossary (page 76) The manual conflicts with itself: page 57 lists "Applicants where ALL household members are non-U.S. citizens" as ineligible, and the glossary leaves non-citizens out of the size while counting their income. The model follows the eligibility sections: lawful immigrants count in the size, undocumented members do not, and a household of lawful immigrants can qualify.
Crisis, cooling, weatherization and equipment assistance — Out of scope.
Topic FY2026 plan Manual and model
Lottery winnings Section 1.9 (page 6) leaves one-time lump sums such as winnings from lotteries unchecked The January 2022 manual, section 1200.7 (page 66), includes "Lottery Winnings". The model follows the manual and counts gambling_winnings, which also covers non-lottery gambling.
Cash gifts Section 1.9 (page 6) leaves cash gifts unchecked The manual, section 1200.7 (page 65), includes "Contribution/Cash Gift"; the model counts adults’ receipts through financial_assistance. The contemporaneous FY2022 plan already has the same unchecked checkbox, so it does not establish a later exclusion. The detailed income manual is followed.
Disability payments and workers' compensation Section 1.9 (page 6) leaves "Insurance payments made directly to the insured" unchecked The manual, section 1200.7, includes "Disability Payment" (page 65) and "Workers Compensation" (page 68). The model follows the manual and counts both.
Subsidized renters and utilities in rent Section 2.3 (page 8) answers No to "additional/differing eligibility policies" for "Renters Living in subsidized housing?" and "Renters with utilities included in the rent?" The manual applies energy-burden rules to both (pages 4, 57, 82 and 89), for example "Subsidized housing residents whose fuel cost is included in their rental payment are not eligible for assistance unless the applicant can verify an energy burden" (page 4). The model follows the manual.

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

62 YAML cases in 6 files cover:

  • all 16 FY2026 income limits, FY2025 limits for sizes 1, 4 and 16, a mixed Georgia and Alabama array, and a $0 limit for a unit with no qualified member;
  • all 16 FY2026 Level I cutoffs, FY2025 cutoffs for sizes 1, 4 and 16, and sizes 17 and 25 at the size-16 cutoff;
  • all five priced fuels at both levels, a small bill that does not cap the award, and no heat;
  • each energy-burden route: a primary bill with heat in rent with and without a subsidy, an obligation with no bill, an unrelated utility bill, all utilities in unsubsidized rent (including unspecified fuel and each requirement that fails it), and heat in rent with an electric bill, with and without a subsidy, by main fuel, income level and missing rent or bill;
  • renters with heat in rent, tenant_pays_utilities false and a $1,200 electric bill: natural gas pays $660 and $560 to an unsubsidized renter with $12,000 and $24,000 of wages and $660 to a subsidized renter, an unsubsidized renter with an unspecified main fuel is eligible at $0, and the subsidized renter without the bill is ineligible;
  • the under-18 boundary at 17 and 18, nonqualified adult income, the $300 interest boundary, TANF counted once and with and without take-up, Social Security net of the Part B premium and its floor, military and gross railroad retirement, and self-employment, capital, rental and farm losses;
  • the eight remaining adult sources (unemployment, veterans' benefits, disability, workers' compensation, strike benefits, General Assistance, alimony and child support) at $100 to $800 each, $3,600 in total;
  • unemployment compensation at Georgia's $365 maximum weekly benefit amount (WBA), up to the 14 x WBA maximum benefit (14 x $365 = $5,110; USDOL, January 2026), which moves a one-person household with $12,000 of wages from the $500 Level I electric award to the $400 Level II award;
  • the FY2025 Level I cutoff in a final award and a 17-person household;
  • a 17-person household whose four adults earn Georgia's median wages for cashiers and for fast food and counter workers (BLS OEWS, May 2025), $111,980 in total: above the $109,627 limit and below the $114,015 poverty floor, so it receives Level II natural gas, $560. With one adult undocumented, the Georgia size falls to 16 (SPM size 17) and the floor to $107,965, so the same $111,980 makes the household ineligible;
  • threshold edges at the federal poverty floor, with income entered directly: size 16 is eligible at $107,964.99 and ineligible at $107,965 in FY2026 (limit $107,634), and eligible at $105,335.99 and ineligible at $105,336 in FY2025 (limit $102,926). Two ineligible rows would qualify without the guideline lag: size 17 at $115,000 in FY2026 (floor $114,015; $117,524 with the 2026 guidelines) and size 16 at $106,000 in FY2025 (floor $105,336; $107,965 with the 2025 guidelines);
  • adult cash contributions, excluded minor gifts, and FY2025/FY2026 final benefits at $12,000, $24,000 and $36,000 of cash support.

Every eligibility and payment case specifies heating_type. The isolated household-size, income and income-limit cases set no heating inputs, which those variables do not read; income Case 8 keeps heating_type because it also asserts the matrix amount. Expected values come from hand arithmetic on the sources. The current head was not run locally; CI validates it.

  • 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#1533 queued

🤖 Generated with Claude Code

hua7450 and others added 6 commits October 3, 2026 19:49
…income

- Add the published FY2025 Level I income cutoffs for sizes 1-16.
- Make renters whose heat is in rent and who are billed for electric
  eligible (manual p89 row 3; p4 for subsidized renters with the bill in
  their name), paid the matrix amount for the main heating fuel.
- Count Social Security net of the Medicare Part B premium; count military
  and railroad retirement; floor each income source at zero; read
  take-up-gated tanf instead of ga_tanf.
- Shorten the registry note; set verified_years to 2025-2026.
- Add period-2025, heat-in-rent, income-source and branch cases; tidy test
  comments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The manual's income table (section 1200.7) includes lottery winnings and
cash gifts; plan section 1.9 leaves both unchecked. Follow the manual:
count gambling_winnings as the closest input for lottery winnings, and note
that cash gifts have no input. Also note the same plan-versus-manual
conflict for disability payments and workers' compensation, which the
manual counts (pages 65 and 68) and the model already follows.

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 (c60610f).
⚠️ Report is 541 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #9968   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         7    +3     
  Lines           76       111   +35     
  Branches         2         1    -1     
=========================================
+ Hits            76       111   +35     
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
Quote manual 1100.14 (page 57) and the glossary (page 76) against 101.2, 1100.3 and 1100.5 a; the code keeps counting lawful immigrants in the size.

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. Also cite manual section 1100.4 (not 1100.5 a) for the undocumented-adults sentence in the household-size comment.

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 Georgia LIHEAP regular heating assistance

PR #9968: Add Georgia LIHEAP regular heating assistance (author: hua7450, head 50aaa0096e)

Scope: Georgia's LIHEAP regular heating assistance, run by DFCS through Community Action Agencies, for FY2025 and FY2026. 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, which counts members 18 and over, with Social Security net of the Part B premium, a $25-a-month interest disregard and per-source loss floors;
  • the income limit at 60% of state median income, through the shared liheap_smi_limit helper;
  • the Benefit Matrix: Level I or Level II by the printed cutoffs for sizes 1-16 in FY2025 and FY2026, and the step 2 amount for five fuels;
  • the energy-burden test, including heat in rent and subsidized housing; the lowest award for unsubsidized renters whose rent includes all utilities (plan item 16.1); and the main-fuel award, paid to the electric vendor, for heat-in-rent renters billed for electricity.

Cooling, crisis, weatherization, categorical eligibility and the $1,000 account-credit screen are out of scope. The PR changes 24 files: 9 parameters, 6 variables plus a helper module, 6 test files (54 cases), programs.yaml and a changelog fragment. Every parameter has a single 2025-10-01 value except the Level I cutoffs (2024-10-01 and 2025-10-01). The tests use periods 2026 and 2025, and the registry lists verified_years: "2025-2026".

Overall: the FY2025 and FY2026 policy values are right.

  • All 10 step 2 amounts and all 32 printed Level I cutoffs (16 per year) match the two matrices, and all 32 printed income limits reproduce with the HHS floor-then-floor method.
  • The income rules follow the manual's Include/Exclude table. Social Security is counted net of the Part B premium, which is right for Georgia: plan item 1.9 checks "Excluding MediCare deduction" in the FY2022, FY2025 and FY2026 plans and the FY2027 draft, and the manual excludes "Health Premiums" (p69). That is the counterpart of Alabama's "Including" box, read as gross in Add Alabama LIHEAP regular heating assistance #9967.
  • The heat-in-rent routes follow the manual's energy burden table (p89) and plan item 16.1. A note on the FY2024 matrix, which the PR does not cite, backs the main-fuel amount on the electric route (G3).
  • The plan-versus-manual choices (lottery winnings, cash gifts, disability and workers' compensation) are documented and defensible: the FY2022 plan, which covers the program year in which the manual was revised, already leaves the same boxes unchecked.

There are no critical findings. The three should-address items:

  • S1: a merge blocker from main's Integrate modeled state unemployment insurance into income flows #9558. The person source list reads the raw unemployment_compensation input, so main's new code-health guard fails on the merged tree. Georgia has no modeled unemployment insurance yet, so no household value changes today.
  • S2: eight of the 24 person income sources are never nonzero in any test, including two that the PR defends against the plan, and two smaller pieces of logic are also unpinned.
  • S3: six parameter descriptions fall outside the house template.

All 54 cases pass locally at the head and on the merged tree. The model outputs quoted below were reproduced by running the head code, or the merged tree for S1. Values that a proposed fix or an earlier year's schedule would produce are hand computations and are labelled as such. The untested-logic claims in S2 were confirmed by mutating the code and rerunning the PR's tests.

Path prefixes used below:

  • P/ = policyengine_us/parameters/gov/states/ga/dfcs/liheap/
  • V/ = policyengine_us/variables/gov/states/ga/dfcs/liheap/
  • T/ = policyengine_us/tests/policy/baseline/gov/states/ga/dfcs/liheap/
  • M = Georgia LIHEAP Policy Manual, revised January 2022 (PDF page = printed page)

Line numbers refer to head 50aaa0096e.

Source Documents

# Document Link Use
1 FY2026 Georgia LIHEAP State Plan (47 pp, report period 10/01/2025-09/30/2026, "Submission Accepted by CO") GA_Plan_2026.pdf 1.1 dates (p4); 1.4 Yes, 1.8 Gross Income, 1.9 (p5-7); 2.1 60% SMI, 2.2-2.3 (p8); 2.5 with the $1,000 credit rule, 2.6 $400 / $810 (p9); 16.1 lowest benefit for direct payment (p30). The text layer lacks the checkbox states, so the rendered pages were read
2 FY2025 plan (Revision #2) GA_Plan_2025.pdf 1.9 "Excluding MediCare deduction", cash gifts and lottery unchecked (p6); 2.1 (p8); 2.6 $400 / $810 (p9); the same 16.1 sentence (p30)
3 FY2022-FY2024 plans FY2022, FY2023, FY2024 FY2022 1.9 boxes (p6); 2.6 ranges $350-$450, $350-$500 and $400-$810 (p9); FY2024 16.1 (p30)
4 Draft FY2027 plan (report period 10/01/2026-09/30/2027, status "Saved") DFCS download Heating 12/01/2026-07/31/2027 (p4); the same 1.9 boxes (p6); 60% SMI (p8); $400 / $810 (p9); the same 16.1 sentence (p30). It has no matrix
5 M (89 pp) GA_PolicyManual_2023.pdf 101.2 (p3-4); 1100.3-1100.5 (p50-52); 1100.12, 1100.14 (p56-57); 1200.1-1200.7 (p62-69); 1300.2 (p70); glossary (p75-76); application items (p81-85); energy burden table (p89). The Include/Exclude columns were read from the rendered pages
6 FY2026 and FY2025 Benefit Matrices (1 p each) FY2026, FY2025 Step 1 Level I and Level II ranges for sizes 1-16; step 2 heating amounts
7 FY2024 Benefit Matrix and FY2023 Eligibility Guidelines (1 p each) FY2024, FY2023 Not cited in the PR. FY2024: the same step 2 amounts, Level I tops of $11,687-$36,411, and the "*Important! The main fuel type is not always where the benefit is applied" note (G1, G3). FY2023: flat $450 / $350 / $500 for all fuels (G1)
8 DFCS PAMMS LIHEAP export (dated 2026-10-07) liheap.pdf Chapter 100 (effective October 2020): the three requirements and "vendor bill/statement for the main heating source" (p4); the stale "$350 ... $400" benefit text (p5). It holds chapters 100-800 only, with no income chapter
9 DFCS LIHEAP page (modified 2026-09-28) dfcs.georgia.gov FY2027 heating opens December 1 for residents 65 and older or homebound and January 2 for everyone; "U.S. citizen or legally admitted immigrant"; the $1,000 credit rule

Critical (Must Fix)

None.

Should Address

S1. Merge blocker: after merging main, the person source list reads the reported-only unemployment_compensation, so main's guard fails

  • Where: P/income/sources/person.yaml:13 (- unemployment_compensation).
  • What changed on main: Integrate modeled state unemployment insurance into income flows #9558 (merged 2026-10-13, after this PR's last push) added total_unemployment_compensation, which uses the reported amount when present and otherwise the modeled state unemployment insurance programs. It moved every income-source list under parameters/ to the total, including the merged LIHEAP lists (for example nj/dca/liheap/income/sources/unearned.yaml:4), and added policyengine_us/tests/code_health/test_unemployment_compensation_readers.py, which fails on any raw list entry.
  • Reproduced on the git merge-tree result of main 8ae01aa3cb and this head: test_parameter_source_lists_do_not_read_raw_unemployment_compensation fails with one violation, parameters/gov/states/ga/dfcs/liheap/income/sources/person.yaml:13. The file's other three tests pass, and the PR's 54 cases still pass on that tree.
  • Source: M 1200.7, p. 67 includes "Unemployment Compensation" ("Unearned benefits received from the Department of Labor by unemployed persons"), and plan 1.9, p. 6 checks "Unemployment insurance". Neither separates reported from modeled amounts.
  • Impact: main models unemployment insurance for AL, NJ, NY, OK, PA and UT only (gov.states.household.modeled_state_unemployment_compensation), so for Georgia households total_unemployment_compensation equals the reported amount and no value changes today. The guard still blocks the merge, and the raw entry would silently drop Georgia UI once it is modeled.
  • Why should, not critical: the head is correct against its base and CI is green. git merge-tree shows a clean textual merge, but this has to change before merge (as Add Alabama LIHEAP regular heating assistance #9967 S1 and Add Rhode Island LIHEAP regular heating assistance #9972 S1).
  • Fix: replace the entry with total_unemployment_compensation, add a case with nonzero unemployment compensation (the S2 case covers it), and update rulespec-us#1533's input list, which names unemployment_compensation.

S2. Eight income sources and two smaller 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 54 cases.

  1. Eight person sources. unemployment_compensation (line 13, which S1 replaces), veterans_benefits (26), disability_benefits (31), workers_compensation (32), strike_benefits (33), general_assistance (34), alimony_income (48) and child_support_received (49) in P/income/sources/person.yaml are never nonzero in any test, so deleting all eight passes.
    • Three are deliberate choices. The PR counts disability_benefits and workers_compensation per M p65 ("Disability Payment") and p68 ("Workers Compensation"), against plan 1.9's unchecked "Insurance payments made directly to the insured". general_assistance is a checked plan category. The PR body's conflict table defends the first two, but no case pins them.
    • Pin all eight with one case: an adult with $100 of unemployment compensation, $200 of veterans' benefits, $300 of disability benefits, $400 of workers' compensation, $500 of strike benefits, $600 of general assistance, $700 of alimony and $800 of child support. Reproduced at head: ga_liheap_income 3,600, and with electric heat ga_liheap $500. The same case fails under the mutation, since none of its income would count.
  2. The tenant_pays_utilities conjunct of the electric-vendor route (V/eligibility/_ga_liheap_housing.py:38). It separates that route from the all-utilities-in-rent route. For unsubsidized renters both routes make the household eligible and the direct route sets the amount, so the conjunct matters only for subsidized renters. No case has a subsidized renter with tenant_pays_utilities false and an electric bill, so replacing the conjunct with True passes all 54 cases.
    • Reproduced at head: a subsidized renter with $12,000 of wages, natural gas heat in rent, rent $3,000, tenant_pays_utilities false and a $1,200 electric bill is ineligible. That case fails under the mutation; by the formula the household becomes eligible for the natural gas Level I amount, $660 (hand-computed).
    • The input is unusual: the tenant_pays_utilities documentation says to set it false "when utilities are included in rent", yet the household reports an electric bill. Either pin the current result with that case, or drop the conjunct, since a positive electric bill already shows that "their utility bill is in their name" (M p4).
  3. The size-0 mask on the income limit (V/eligibility/ga_liheap_income_limit.py:23, where(size > 0, limit, 0)). Returning the unmasked limit passes all 54 cases. Without the mask, a unit with no qualified member gets the size-1 limit: the HHS size factor at size 0 is 0.52, so floor(66,441 x 0.52) = $34,549 (hand-computed). Eligibility still gates on size > 0, which T/eligibility/ga_liheap_eligible.yaml Case 2 pins, so only the limit variable changes. No case asserts the limit for a size-0 unit. Add ga_liheap_income_limit: 0 to T/ga_liheap_household_size.yaml Case 2 (reproduced at head: 0; that assertion fails under the mutation).

By inspection, the other branches are pinned: each energy-burden arm, each conjunct of the all-utilities-in-rent route (T/eligibility/ga_liheap_eligible.yaml Case 7 changes one at a time), the eligibility size gate, both NONE checks, the 32 Level I boundaries, the size-16 cap, the per-source floors, the Social Security net and floor, the interest disregard and mask, and the TANF read. Two control mutations confirm the method: dropping the electric route's heat-in-rent conjunct fails T/ga_liheap.yaml Case 14, and dropping heating_type != NONE fails T/eligibility/ga_liheap_eligible.yaml Cases 4 and 7. Consistency: #9967 S3 and #9972 S3 rated untested logic SHOULD, and #9745 G7 suggested the all-sources case.

S3. Six parameter descriptions fall outside the house template

All nine descriptions end with "under the Low Income Home Energy Assistance Program." with nothing after it, which is right. The template's verbs are limits, provides, sets, excludes, deducts and uses. Six descriptions use other verbs:

File:line Current Suggested
P/income/minimum_age.yaml:1 "counts household members' income starting at this age" "Georgia excludes the income of household members below this age under the Low Income Home Energy Assistance Program."
P/income/monthly_interest_disregard.yaml:1 "disregards this amount of monthly interest income" "Georgia excludes this amount of monthly interest income under the ..."
P/income/sources/household.yaml:1 "counts these household benefits once" "Georgia uses these household-level benefits as countable income under the ..."
P/income/sources/person.yaml:1 "counts these income sources of adult household members" "Georgia uses these sources as countable income of adult household members under the ..."
P/payment/lower_income_uplift.yaml:1 "increases the heating payment by this amount for households in income Level I" "Georgia provides this additional heating payment to households in income Level I under the ..."
P/payment/maximum_table_size.yaml:1 "publishes Level I income thresholds through this household size" "Georgia sets Level I income thresholds through this household size under the ..."

The other three fit: smi_rate and lower_income_limit (limits) and base_amount (provides). Consistency: #9967 S4, #9972 S4 and #9745 S6.

Suggestions

G1. Backfilled years: FY2024 is published and could be claimed; FY2023 and earlier paid a different schedule

  • Every single-dated parameter carries back to every earlier period, and the Level I cutoffs carry the FY2025 values back. The registry claims only 2025-2026 and the PR body calls other years "unverified backfilled estimates", so this is a suggestion (checklist item 3).
  • FY2024 differs only in the cutoffs:
    • The FY2024 matrix prints the same ten step 2 amounts and Level I tops of $11,687 / 15,283 / 18,879 / 21,904 / 26,072 / 29,668 / 30,342 / 31,016 / 31,691 / 32,365 / 33,039 / 33,713 / 34,388 / 35,062 / 35,736 / 36,411.
    • The FY2024 plan has the same $400 / $810 range (p9) and the lowest-benefit sentence (p30).
    • The limits reproduce from the repo's FY2024 median, $95,238: floor(floor(95,238 x 0.6) x 0.52) = 29,713, the printed "$29713".
    • Reproduced: period 2024, one adult with $12,000 of wages and electric heat gets limit 29,713 and an award of $500. FY2024's size-1 Level I range is "$0 - $11687", so FY2024 paid $400 (hand-computed).
    • Add a 2023-10-01 entry for each size and set verified_years: "2024-2026".
  • FY2023 and earlier paid a different schedule. The FY2023 guidelines pay "Level I $450", "Level II $350" and "Level III (vulnerable population) $500" (households with a member aged 60 or over), "for All Fuel Types".
    • Reproduced: period 2023, one adult with $12,000 of wages and natural gas heat gets $660 at age 40 and at age 70. FY2023 paid $450 and $500. The limit, 28,058, does match FY2023's "$28,058".
    • Either gate payments before FY2024 (merged NJ uses eligibility/in_effect.yaml), or keep the documented backfill.
  • Also cite the FY2025 documents where FY2025 values come from the 2025-10-01 entry by backward extrapolation. P/payment/base_amount.yaml, P/payment/lower_income_uplift.yaml and P/payment/maximum_table_size.yaml cite only the FY2026 matrix, and P/eligibility/smi_rate.yaml cites only the FY2026 plan. The FY2025 matrix and the FY2025 plan, p. 8 show the same values for the claimed FY2025.

G2. Fuels and routes that are eligible but paid $0

  • Reproduced at head (period 2026, $12,000 of wages and a $1,200 bill for the fuel): KEROSENE, COAL and SOLAR each give ga_liheap_eligible: true and ga_liheap: 0.
    • KEROSENE: heating_expense reads fuel_oil_expense for it, so the matrix's "OIL" row is the natural column.
    • SOLAR: heating_expense reads the electric bill ("Solar-primary homes are assumed grid-tied with electric supplemental heat"), so the ELECTRIC row fits.
  • UNSPECIFIED on the electric-vendor route is eligible but gets $0 (T/ga_liheap.yaml Case 16, unit 4). The heating_type documentation calls UNSPECIFIED "the right value when heat is included in rent and the fuel is unknown", so it is the usual input for a renter on that route. Either pay a defined amount when the fuel is unknown (for example the ELECTRIC amount, since the payment goes to the electric vendor), or make eligibility match the $0.
  • The PR documents these as coverage gaps. Add a # See #9754 note at V/payment/ga_liheap_matrix_amount.py:46 (Add New Jersey LIHEAP regular heating assistance #9745 G1, Add Alabama LIHEAP regular heating assistance #9967 G2).

G3. Cite the FY2024 matrix note and the current DFCS documents

  • The FY2024 matrix explains the asterisk on "main heating fuel type*": "*Important! The main fuel type is not always where the benefit is applied. Example: A household is in the Level 1 income range. They heat their home with Natural Gas, and bring in both a Gas and Electric bill. Since they heat their home with Natural Gas , the household is eligible for a Natural Gas benefit -- even if they opt to apply all of their benefit toward their electric bill." The FY2025 and FY2026 sheets keep the asterisk but drop the note.
    • That backs paying the main-fuel amount on the electric-vendor route (V/eligibility/_ga_liheap_housing.py:20-41, V/payment/ga_liheap_matrix_amount.py:48-58). Cite it there and in the PR body. rulespec-us#1533 interpretation 6 says neither sheet prints a footnote.
  • PAMMS chapter 100, p. 4 (export dated 2026-10-07) is the current DFCS text of M section 100.
    • "Be US citizens or lawfully admitted immigrant" supports the household-size reading over M p57's "Applicants where ALL household members are non-U.S. citizens". The DFCS LIHEAP page also says "The applicant needs to be a U.S. citizen or legally admitted immigrant."
    • "Applicants who receive a vendor bill/statement for the main heating source are eligible for assistance" supports T/eligibility/ga_liheap_eligible.yaml Case 5, where an unrelated bill does not count. M p4 says only "from their energy source".
    • The same chapter still prints "a minimum of $350 and maximum of $400", with a senior maximum (p5). Plan 16.1 (p30) says the updated matrix removed the senior rule, so the matrix governs. Say so in the PR body.

G4. Encode the printed Level I column, and consider exposing the two routes as variables

  • P/payment/base_amount.yaml stores Level II, and P/payment/lower_income_uplift.yaml adds $100 for Level I. That reproduces all ten printed cells, but the sheets print two columns, not a rule. np.minimum.reduce(base_amounts) (V/payment/ga_liheap_matrix_amount.py:56) also gives the right Level I lowest amount only while the gap is the same for every fuel. Encoding the printed Level I column (a level-by-fuel breakdown) removes both assumptions (Correct the qualified_business_income variable formula #1533 interpretation 5).
  • The two routes in V/eligibility/_ga_liheap_housing.py are helper functions, so no YAML case can assert them. Boolean variables would let the route cases assert the route directly. This is optional.

G5. PR body: other direct-pay cases, a conflict-table row and small corrections

  • Plan 16.1 pays "the lowest benefit amount" whenever "the benefit goes directly to the applicant". Besides rent that includes all utilities, M pays the applicant directly in three more cases:
    • utilities paid to "the landlord or trailer park owner" (p89 row 4);
    • subsidized tenants who pay "a landlord for utility costs" (p89 row 7, "Direct pay to applicant (999) or to electric supplier");
    • households "whose energy suppliers have not signed a vendor supplier agreement" (p4; 1300.2, p70).
      No input identifies them, and the model pays the main-fuel amount when they report a bill. Add a row to the not-modeled table; rulespec-us#1533 interpretation 7 already has it.
  • Add a conflict-table row: plan 2.3, p. 8 answers "No" for "Renters Living in subsidized housing?" and "Renters with utilities included in the rent?", while M applies energy-burden rules to both (p4, p57, p82, p89). Add Alabama LIHEAP regular heating assistance #9967 G6 and Add Rhode Island LIHEAP regular heating assistance #9972 G6 made the same point.
  • "Every case specifies heating_type" is not quite right: T/income/ga_liheap_income.yaml Case 14 (line 463) has none. rulespec-us#1533 says so correctly.
  • Plan item 1.9 continues on p7 (stipends, foster-care funds, AmeriCorps payments, reimbursements and "Other", all unchecked). The title at P/income/sources/person.yaml:57 ("#page 5-6") and the # PDF pages 5-6 comment at V/income/ga_liheap_income.py:15 could read 5-7. Every encoded category is on pp. 5-6, so this is polish.

G6. Test hygiene, FY2027 and issue housekeeping

  • hud_utility_allowance: 0 appears nine times in T/ga_liheap_household_size.yaml and T/income/ga_liheap_income.yaml, but no Georgia variable reads it. The isolated limit and income tests also set fuels and bills that those variables never read, and the matrix-amount tests set fuel bills that ga_liheap_matrix_amount never reads.
  • FY2027: the draft plan keeps 60% SMI, $400 / $810 and the 16.1 sentence, and DFCS has not published an FY2027 matrix. Period 2027 therefore carries the FY2026 cutoffs (reproduced: one-person limit $35,916 from the FFY2027 median, and $500 at $12,000 of wages). The printed cutoffs track about 23.6% of the four-person median times the size factor (see Verified correct), so the FY2027 cutoffs will probably rise; on that pattern the size-1 top would be about $14,127 (a hand projection, not a published value). Add the FY2027 matrix when DFCS publishes it.
  • rulespec-us#1533 still calls the PR "open as a draft".

Verified correct

  • Matrix (FY2026, FY2025):
    • Step 2 amounts: ELECTRIC $500 / $400, NATURAL GAS $660 / $560, OIL $810 / $710, PROPANE $680 / $580, WOOD $500 / $400. Level I is Level II plus $100 for every fuel, and plan 2.6's $400-$810 range matches.
    • Step 1: all 16 Level I tops in each year ($13,589 ... $42,336 and $12,995 ... $40,485), inclusive. Sizes above 16 use size 16, which the PR documents as provisional.
    • The printed tops track floor(four-person SMI x 0.236 x size factor), with 0.23 at size 4, in all 32 FY2025-FY2026 cells and 13 of the 16 FY2024 cells. The odd size-4 value therefore recurs every year, and keeping the printed table, with the PR's comment, is right.
  • Limits: all 16 FY2026 limits (34,549 ... 107,634) and all 16 FY2025 limits (33,038 ... 102,926) reproduce as floor(floor(0.6 x SMI) x size factor), with four-person SMIs of $110,736 and $105,893. The limit is inclusive ("at or below", M p50; T/eligibility/ga_liheap_eligible.yaml Case 1).
  • Timing: heating runs 12/01/2025-07/31/2026 (plan 1.1, p4), so period 2026 (January 1, 2026) reads FY2026 and period 2025 reads FY2025.
  • Income (plan 1.8 gross; M 1200.1-1200.7, p. 62-69):
    • Members under 18 are excluded entirely (p62), and nonqualified adults' income counts (p51, p62).
    • Every listed source has a basis in the Include column (rendered pages) or in plan 1.9: capital gains, alimony, child support, contribution/cash gift, disability payment and dividends (p65); farm income, interest, lottery winnings, pension and rental income (p66); RSDI, strike benefits, SSI, TANF, unemployment compensation, veterans' benefits and wages (p67); workers' compensation (p68); self-employment (1200.6, p64); general assistance and retirement benefits (plan 1.9). SNAP, tax refunds, HUD utility allowances and LIHEAP are excluded and not listed.
    • Social Security is counted net of Part B (plan 1.9 "Excluding MediCare deduction"; M p69 "Health Premiums") and floored at zero. Railroad retirement is gross.
    • Interest: "The first $25.00 in interest is disregarded" (p66), and interest "amounting to $25.00 or less per month" is excluded (p69). Applying it once per household is a documented reading.
    • Losses are floored per source. TANF comes through the take-up-gated tanf. financial_assistance ("Cash financial assistance from friends or relatives outside the household") matches "Contribution/ Cash Gift".
  • Household: size counts citizens and the 8 U.S.C. 1641 qualified statuses. Undocumented adults' income counts and they are left out of the size (M 1100.4, p51; 1100.5 b note, p52). DACA is not on the p51 list.
  • Eligibility:
    • Georgia residence. No asset test (plan 2.3 No).
    • Categorical eligibility (plan 1.4 Yes; M 1100.12) is not applied, which is harmless: a household whose only income is SSI, TANF or SNAP is far below 60% SMI, and plan 1.6 says the benefit is the same.
    • Energy burden:
      • the household's own obligation or a bill for the primary fuel qualifies (M p3, p50, p4);
      • unsubsidized rent that includes all utilities qualifies (p89 row 2);
      • heat in rent with an electric bill qualifies with or without a subsidy (p89 row 3; p4 "if their utility bill is in their name");
      • subsidized heat in rent with no bill fails (p57, p82, p89 row 5);
      • NONE fails.
  • Payment:
    • Direct payment pays the level's lowest amount, $500 or $400 (plan 16.1, p30; p89 row 2 "Direct pay to Applicant (999)").
    • The electric route pays the main-fuel amount (FY2024 note, G3).
    • No bill cap: plan 2.5 leaves "Individual bill" unchecked.
  • Code patterns:
    • No hard-coded values. defined_for = StateCode.GA on five variables, and ga_liheap is gated by ga_liheap_eligible.
    • Vectorized formulas. All 9 parameters are read, and the shared liheap_smi_limit helper is reused.
    • Mixed Georgia and Alabama arrays mask correctly.
  • Tests:
    • 54 of 54 pass locally at head (policyengine-core 3.32.29) and on the merged tree. Periods are plain.
    • Hand-checked against the matrices, plans and manual:
      • T/ga_liheap.yaml Cases 1, 4, 9-17 and 19;
      • income Cases 1-6, 9 and 12;
      • all 32 Level I boundary pairs and all 10 fuel cells;
      • all 16 FY2026 limits and the three FY2025 limits;
      • household size Case 1.
  • Changelog: changelog.d/ga-liheap.added.md is top level and typed added.

Checklist results (LIHEAP wave 2a)

  1. State plan and manual first: pass. I read the accepted FY2026 and FY2025 plans (rendered checkboxes), the FY2022-FY2024 plans, the FY2027 draft, M (rendered Include/Exclude columns and energy burden table), the FY2023-FY2026 matrices, the PAMMS export and the DFCS page. I verified every encoded amount, cutoff, limit and route.
  2. Income definition: pass at head. Gross income per plan 1.8 and M 1200.7; Social Security net of Part B per plan 1.9 and M p69; losses floored per source; annual income standing in for the monthly test. After rebase the list must read total_unemployment_compensation (S1).
  3. Backdating: FY2025 is claimed and correct. FY2024 is published with different cutoffs, and FY2023 used a different schedule; both are unclaimed and documented (G1). No FY2027 matrix is published (G6).
  4. Household and arrangement rules: pass on subsidized and public housing, heat in rent (both routes), renters, categorical eligibility (a harmless omission) and the elderly priority (timing only). Eligible-but-$0 fuels are in G2; the other direct-pay cases are in G5.
  5. Tests: 54 cases, more than 8 hand-checked. Limits for sizes 1-16, cutoffs for sizes 1-16 with one-cent pairs, the limit edge and plain periods are covered. Gaps are in S2.
  6. Parameter descriptions: six fall outside the template (S3). There are no trailing clauses.
  7. References: pass. Every anchor is a file page that shows the value, and multi-page titles use #page 66,69, #page 62-69,83 and #page 5-6 (item 1.9 runs onto p7, G5).
  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 TANF's.
  9. Axiom: valid queued line. rulespec-us#1533 is open, labelled pe-parity, dispatch-ready and current to 50aaa0096e. It needs updates for S1-S2 (see below).
  10. Branch and CI: all checks are green at head. 12 ahead and 82 behind main. No textual conflicts, but main's UI guard fails on the merged tree (S1).
  11. Integrate modeled state unemployment insurance into income flows #9558: S1. No modeled Georgia UI exists, so the effect today is the guard failure only.
  12. IIJA and FY2027: no IIJA supplement. None of the FY2022-FY2026 plans, the FY2027 draft or M mentions one, and the matrices print one amount per fuel and level. The FY2027 draft keeps 60% SMI, $400-$810 and the 16.1 sentence (G6).
  13. Mutation check: S2. Two control mutations fail as expected.

CI status

28 of 28 checks pass at 50aaa0096e (gh pr checks 9968, 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#1533 queued: valid format, and the issue meets the bar.

  • rulespec-us#1533 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-ga/ module paths with corpus status;
    • verbatim manual, plan, matrix and HHS text;
    • required outputs for all 6 variables;
    • 15 companion tests derived from the matrices, plans, manual and HHS tables ("None is taken from policyengine-us output").
  • It describes head 50aaa0096e correctly, including the electric route (interpretation 6), the $0 fuels (9), the plan-manual conflicts (10), the household-size conflict (16) and the carried-forward years (20).
  • Updates needed when the fixes land:
    • the input list and a UI case (S1);
    • the new source and branch cases (S2);
    • the FY2024 note for interpretation 6 (G3);
    • the stale "open as a draft".

Next steps

  1. S1: rebase onto main, switch P/income/sources/person.yaml:13 to total_unemployment_compensation, and add a case with unemployment compensation.
  2. S2: add the all-sources case, the subsidized electric-route case and the size-0 limit assertion.
  3. S3: align the six descriptions.
  4. Optionally address G1-G6, then refresh the PR body and rulespec-us#1533 and re-request review.

0 critical and 3 should-address findings, plus 6 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 3 should items; details in the full report above. The FY2026 values check out: all 10 step-2 amounts, all 32 Level I cutoffs and all 32 income limits (60% SMI, floor then floor). Social Security net of Part B is right for Georgia, and the direct-pay and electric-vendor awards follow the manual and plan. All 54 tests pass and CI is green. (1) Merge blocker from main's #9558: the guard fails on the merged tree at income/sources/person.yaml:13, which lists the raw unemployment_compensation. (2) Logic that passes every test even when broken on purpose: 8 of the 24 person income sources are never set to a nonzero value (including disability, workers' comp and general assistance), along with the electric route's tenant_pays_utilities condition and the size-0 income-limit mask. (3) Six parameter descriptions are off the house template.

hua7450 and others added 2 commits October 15, 2026 15:13
- S1: Merge blocker: the person source list reads the raw unemployment_compensation, so main's #9558 guard fails
- S2: Eight income sources and two smaller pieces of logic are not pinned by any test
- S3: Six parameter descriptions fall outside the house template
- REC-C: Federal 110%-of-poverty floor (coordinator recommendation C; not raised by David for GA)

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

  • S1: I merged upstream/main (PRs 9558 and 10046), and income/sources/person.yaml now lists total_unemployment_compensation; no Georgia LIHEAP formula or parameter reads the raw input. ga_liheap.yaml Case 21 adds $5,110 of unemployment compensation (Georgia's $365 maximum weekly benefit for 14 weeks, USDOL January 2026) to $12,000 of wages: income $17,110, Level II electric, $400 (the award without it is $500).
  • S2: (1) Income Case 15 sets your eight sources to $100 through $800 and expects $3,600. (2) I took your second option and dropped the tenant_pays_utilities conjunct: a positive electric bill is the bill "in their name" (manual p. 4), and the docstring reads page 82's "rent includes utilities" as rent covering every utility. Eligibility Case 9 pins your household at $660 with the $1,200 electric bill and ineligible without it; no existing expected value changes. (3) The size-0 assertion is ga_liheap_income_limit.yaml Case 4 ($0), in the limit's own test file rather than household-size Case 2.
  • S3: The six descriptions now use your suggested wording.
  • G1: Partly done. base_amount, lower_income_uplift and maximum_table_size now cite the FY2025 matrix, and smi_rate cites FY2025 plan item 2.1 (p. 8). Claiming FY2024 and gating or encoding FY2023: history is out of scope for this PR, so verified_years stays "2025-2026" and earlier years stay documented as unverified estimates.
  • G2: Partly done. The ga_liheap_matrix_amount comment now points to Default heating_type to electricity and remove the UNSPECIFIED-gated state heating adapters #9754 for the unspecified default. Kerosene, coal and solar, and unspecified fuel on the electric route, stay eligible at $0: heating_type is a required input, no Georgia source maps those fuels to a matrix row, and the electric route pays the main fuel's amount, which an unknown fuel lacks. These households meet the manual's energy-burden test, so the model keeps them eligible and documents the $0 as a coverage gap.
  • G3: Done. The FY2024 matrix note now backs the electric route in _ga_liheap_housing.py, ga_liheap_matrix_amount and the PR body. PAMMS chapter 100 (p. 4) backs the household-size reading, together with the DFCS page, and the main-heating-source bill rule in ga_liheap_eligible. The PR body says PAMMS p. 5 still prints $350-$400 with a senior maximum and that plan 16.1 (p. 30) makes the matrix govern.
  • G4: Kept Level II plus the $100 uplift, which reproduces all ten printed cells in both claimed years. lower_income_uplift.yaml now labels it an inferred pattern, and the ga_liheap_matrix_amount comment notes that the lowest-award shortcut relies on the same uplift for every fuel. I left the routes as helpers to avoid two more variables; eligibility Cases 7-9 and ga_liheap.yaml Cases 14, 16 and 17 pin them.
  • G5: Done. The PR body adds the not-modeled row for the other direct-pay cases (p. 89 rows 4 and 7, p. 4, and 1300.2 on p. 70) and the plan item 2.3 (p. 8) conflict row, which ga_liheap_eligible also notes. The heating_type sentence now covers eligibility and payment cases, and the item 1.9 title and comment read pages 5-7.
  • G6: Partly done. The isolated size, income, limit and matrix cases no longer set hud_utility_allowance or fuels and bills their variables do not read (income Case 8 keeps heating_type for the matrix amount, and matrix Case 3 keeps its $50 gas bill). FY2027 is unchanged: DFCS has published no FY2027 matrix and the draft plan keeps 60% SMI, $400-$810 and the 16.1 sentence, so period 2027 stays a documented carried-forward estimate.
  • Federal poverty floor: Separately from your review, eligibility now applies 42 U.S.C. 8624(b)(2)(B) through the shared gov.hhs.liheap.fpg_floor (1.1) and a Georgia fpg_year_lag of 1 (the guidelines HHS makes mandatory for the fiscal year). Georgia's 60% SMI limit falls below 110% of poverty from size 16 ($102,926 against $105,336 in FY2025; $107,634 against $107,965 in FY2026), and ga_liheap_income_limit still reproduces the printed table. ga_liheap.yaml Case 22 has 17 people whose four adults earn Georgia's median wages for cashiers and for fast food and counter workers, $111,980 in total: above the $109,627 limit and below the $114,015 floor, so it receives Level II natural gas, $560.
  • LIHEAP wave 2a: encode Georgia LIHEAP regular heating assistance TheAxiomFoundation/rulespec-us#1533 is refreshed to this head, including the "open as a draft" status line.

@hua7450
hua7450 requested a review from DTrim99 October 15, 2026 21:08

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

Program Review

IDs: C = critical, S = should address, G = suggestion. S1-S3 and G1-G6 carry over from the prior review at 50aaa0096e; S4-S7 and G7-G16 are new in this round.

Source Documents

Paths: P/ = policyengine_us/parameters/gov/states/ga/dfcs/liheap/, V/ = policyengine_us/variables/gov/states/ga/dfcs/liheap/, T/ = policyengine_us/tests/policy/baseline/gov/states/ga/dfcs/liheap/. Line numbers refer to b36ba40f71.

Branch Status

  • 14 commits ahead of main and 38 behind (merge base 9560e7f183). The branch merges cleanly with main, with no conflicts.
  • Staleness did not affect any finding. This is informational only.
  • Sibling #9969 (FL) adds a byte-identical gov/hhs/liheap/fpg_floor.yaml. Identical adds merge cleanly, but any fix to that file (S7) must be applied to both PRs.

Critical (Must Fix)

None.

Should Address

S4. The same contradictory inputs get different awards, depending on the subsidy status (new; caused by the S2 fix)

  • Where: V/eligibility/_ga_liheap_housing.py:42-46 (the electric-vendor route no longer checks tenant_pays_utilities; the direct route at :11-17 still does), V/payment/ga_liheap_matrix_amount.py:57-62, T/ga_liheap.yaml:603-634 (Case 17), T/eligibility/ga_liheap_eligible.yaml:171-204 (Case 9).
  • Defect: take a renter with natural gas heat in rent, tenant_pays_utilities false and a $1,200 electric bill (period 2026). Unsubsidized, the flag governs and the award is $500 / $400 at $12,000 / $24,000 of wages (Case 17). Subsidized, the bill governs and the award is $660 / $560 (Case 9). Reproduced at head.
  • Evidence: the new docstring (_ga_liheap_housing.py:29-31) says a separate electric bill rules out rent "covering every utility". M p89 row 3, "Heat costs included in rent and applicant is billed directly for electric (non-subsidized)", is paid to the electric vendor. Row 2 (all utilities in rent) is "Direct pay to Applicant (999)". By the PR's own reading, Case 17 is row 3, not row 2. The PR body says the $660 applies "with or without a housing subsidy", which is true only when tenant_pays_utilities is true. The subsidized half has good support: M p4, PAMMS p4 and M p57 (1100.14: ineligible only if they "cannot verify an energy burden").
  • Fix: use one rule for both housing types. Recommended: in ga_liheap_matrix_amount, use direct_payment & ~ga_liheap_has_electric_vendor_route(spm_unit, period). Then only Case 17 changes, to $660 / $560. If you keep Case 17, document why the flag governs only for unsubsidized renters. Cite M p57 in the docstring for Case 9.
  • Rated should-address, not critical: only a contradictory input pair, which no source addresses, triggers it. Household calculations only ($160).

S5. The 110% poverty floor admits income of exactly 110% because of a floating-point error

  • Where: V/eligibility/ga_liheap_eligible.py:35 (income < p_hhs.fpg_floor * guideline).
  • Defect: in float64, 1.1 × 98,150 = 107,965.00000000001 and 1.1 × 95,760 = 105,336.00000000001. Reproduced at head: a size-16 household with exactly $107,965 (FY2026) or $105,336 (FY2025) is eligible, $560. Sizes 14-19 show the same excess.
  • Evidence: 42 U.S.C. 8624(b)(2)(B) protects only income "less than 110 percent". HHS prints whole-dollar 110% amounts (IM 2025-02 Att. 2, p1).
  • Fix: compare against a rounded floor, for example np.round(p_hhs.fpg_floor * guideline, 2). Then add the exact-floor test from S6.
  • Rated should-address under the rounding rule, because it changes eligibility only at the exact cent.

S6. The floor tests detect only removal of the floor; the year lag, rate and strict boundary are not tested

  • Where: T/ga_liheap.yaml:744-801 (Case 22, size 17, FY2026, $111,980), the only floor case; P/eligibility/fpg_year_lag.yaml:6.
  • Defect: Case 22 still passes with fpg_year_lag 0 (floor $117,524; reproduced: eligible, $560). It also passes with any fpg_floor from 1.0804 to 2.2076, and with <= in place of <. No period-2025 case reaches the floor.
  • Evidence: the lag is the property that matters. IM 2025-02 Att. 2, p1 makes the 2025 guidelines "mandatory use in FY26"; IM 2024-02 Att. 2, p1 does the same for 2024 and FY25.
  • Fix: add an array case to T/eligibility/ga_liheap_eligible.yaml (GA, electric heat, $1,200 bill, size and income as inputs):
    • FY2026, size 16: $107,634 true (inclusive limit), $107,964 true (floor), $107,966 false. Add $107,965 false after the S5 fix.
    • FY2026, size 17: $115,000 false. Lag 0 would make it true.
    • FY2025, size 16: $104,000 true and $106,000 false (lag 0 makes $106,000 true).
    • Update the "Size 16 is not tested" comment at T/ga_liheap.yaml:757-758.

S7. The 42 U.S.C. 8624 links do not go to subsection (b)(2)(B)

  • Where: policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml:11 and V/eligibility/ga_liheap_eligible.py:21 link to https://www.law.cornell.edu/uscode/text/42/8624.
  • Evidence: the title names 42 U.S.C. 8624(b)(2)(B) and the value 1.1 is correct, but the reader must scroll the whole section.
  • Fix: use https://www.law.cornell.edu/uscode/text/42/8624#b_2_B. Make the same change in #9969's copy.
  • Rated should-address (reference validator) over suggestion (code validator): anchored Cornell links outnumber bare ones 270 to 61 in parameters/.

Suggestions

  • G7. P/eligibility/fpg_year_lag.yaml encodes an HHS rule, not a Georgia rule. Consider a shared floor helper beside liheap_smi_limit, or a ga_liheap_fpg variable so that Case 22 can assert the $114,015 floor. MS LIHEAP probably hits the floor from size 11 (follow-up).
  • G8. Cite Georgia's own assurance of the floor (FY2026 plan p43; FY2025 plan p43) in ga_liheap_eligible and in the PR body.
  • G9. P/eligibility/smi_rate.yaml and P/payment/{base_amount,lower_income_uplift,maximum_table_size}.yaml cite FY2025 sources but start on 2025-10-01; date them 2024-10-01 (no output change).
  • G10. State in _ga_liheap_housing.py:32-34 that the FY2024 note is carried forward: the FY2025 and FY2026 sheets keep the asterisk but print no note. Add the FY2025 matrix to the ga_liheap_matrix_amount reference tuple (:14-19).
  • G11. The PAMMS export is regenerated. Note "chapter 100, PDF page 4, export dated 2026-10-16" beside the URL (ga_liheap_eligible.py:20, ga_liheap_household_size.py:13).
  • G12. In fpg_year_lag.yaml, use the full IM identifiers and cite the IM 2025-02 main page for the October 1 adoption date.
  • G13. Add URLs for the USDOL UI provisions (T/ga_liheap.yaml:705-712) and BLS OEWS May 2025 (:745-748). Change "maximum of 14 weeks" to "the 14 × WBA maximum benefit".
  • G14. Three titles still contain page ranges (P/income/monthly_interest_disregard.yaml:9, P/income/sources/person.yaml:55 and :57). Use one reference per page, with pages only in href.
  • G15. changelog.d/ga-liheap.added.md does not mention the shared federal parameter gov.hhs.liheap.fpg_floor.
  • G16. No test pins the floor's household size (qualified members only). Add a mixed-status case: Georgia size 16, SPM size 17, $110,000 gives false.

Prior Findings

ID Finding Status
S1 Person source list read raw unemployment_compensation RESOLVED: P/income/sources/person.yaml:13; Case 21 ($17,110, $400)
S2 Eight sources, the electric-route conjunct and the size-0 mask had no tests RESOLVED: income Case 15 ($3,600); conjunct dropped, eligible Case 9; limit Case 4 ($0). The conjunct change caused S4
S3 Six descriptions off template RESOLVED
G1 Claim FY2024, gate FY2023, cite FY2025 STILL OPEN: FY2025 citations added; claim and gate declined by author; dating in G9
G2 Kerosene, coal, solar and unspecified fuel eligible but paid $0 STILL OPEN, declined by author: #9754 note added; no case pins the $0
G3 Cite FY2024 note, PAMMS, DFCS page; PR body on PAMMS $350-$400 RESOLVED (carry-forward caveat in G10)
G4 Encode the Level I column; expose routes as variables STILL OPEN, declined by author; inference documented
G5 PR body rows, heating_type sentence, pp. 5-7 RESOLVED; one new body sentence is wrong (S4)
G6 Test hygiene, FY2027, rulespec status Hygiene and status RESOLVED; FY2027 STILL OPEN, declined by author (no FY2027 matrix exists)

PDF Audit Summary

Category Count
Changed values or claims confirmed correct 120 (34 items), plus 8 AK/HI guideline values
Page anchors and page lists confirmed correct 39 of 39
External documents matched 2 (FY2024 note; FY2026 size 15-16 limits)
Confirmed mismatches (code path and visual) 0
Investigated and cleared 2

Investigated and cleared:

  • PAMMS p5 "$350 ... $400" with a senior maximum: the matrices and plan items 2.6 (p9) and 16.1 (p30), which removes the senior rule, govern. Documented in the PR body.
  • Size-16 eligibility above the printed $102,926 / $107,634: 42 U.S.C. 8624(b)(2)(B), which Georgia assures (plan p43), governs. Documented. The exact-boundary defect is S5.

Validation Summary

Check Result
CI 27 of 27 pass at b36ba40f71
Regulatory 0 critical; S4, S5. Floor value, start date and lag direction correct
References None missing; all corroborate; S7
Code patterns No hard-coded values; fpg() and liheap_smi_limit reused; periods and entities correct
Tests 59 cases (5 new) pass; no expected value changed; S6
Prior findings 5 resolved, 4 still open (all suggestions)

Review Severity: COMMENT

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

  • S4: Applied your recommended fix. ga_liheap_matrix_amount now uses direct_payment & ~ga_liheap_has_electric_vendor_route(spm_unit, period), so a renter with heat in rent and a positive electric bill is paid on the electric-vendor route (manual p. 89, row 3), with or without a subsidy and whatever tenant_pays_utilities says. ga_liheap.yaml Case 17 now expects $660 and $560 (was $500 and $400) and adds a third household: unspecified fuel with the same inputs is eligible at $0, the electric-route amount for an unknown main fuel (the old precedence paid it the $500 lowest award). The electric-route docstring cites manual p. 57 (1100.14, "cannot verify an energy burden"), a sweep found no other case with these inputs, and the PR body sentence now holds for both flag values.
  • S5: The floor is now np.round(guideline * p_hhs.fpg_floor, 2), compared with income < floor, as in Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279. A size-16 household at exactly $107,965 (FY2026) or $105,336 (FY2025) is now ineligible, and eligibility Cases 10 and 11 pin both boundaries.
  • S6: Added your rows as two labelled threshold-edge cases in eligibility/ga_liheap_eligible.yaml, with household size and income as inputs. Case 10 (FY2026) expects true, true, false, false for size 16 at $107,634, $107,964.99, $107,965 and $107,966, and false for size 17 at $115,000 (lag 0 would give a $117,524 floor and true). Case 11 (FY2025) expects true, true, false, false for size 16 at $104,000, $105,335.99, $105,336 and $106,000 (lag 0 would give a $107,965 floor and make $106,000 true). Together they pin the 1.1 rate to the cent, the strict < and fpg_year_lag 1, and the Case 22 "Size 16 is not tested" comment now points to them.
  • S7: gov/hhs/liheap/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, href ending #b_2_B), and the ga_liheap_eligible reference and the PR body link carry the same anchor. Add Florida LIHEAP regular heating assistance #9969 gets the same file, so the three adds stay identical.
  • G7: Deferred. The shared floor helper (and a federal lag parameter) will come in a follow-up refactor PR once these PRs and Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 merge; until then each state keeps its own fpg_year_lag, as Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 does. I did not add a ga_liheap_fpg wrapper variable: eligibility Cases 10 and 11 pin the floor to the cent ($107,965 and $105,336), and Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 applies Mississippi's floor.
  • G8: ga_liheap_eligible now cites assurance 2 on p. 43 of both plans, and the floor comment says Georgia assures the floor, so it governs over the printed size-16 rows ($102,926 and $107,634) while ga_liheap_income_limit keeps the printed table. The PR body adds p. 43 to both plan entries and the income row, plus a conflict row for the printed size-16 limits.
  • G9: smi_rate, base_amount, lower_income_uplift and maximum_table_size now start on 2024-10-01, matching the FY2025 sources they cite. No output changes.
  • G10: The electric-route docstring in _ga_liheap_housing.py now says the FY2025 and FY2026 matrices keep the asterisk on "main heating fuel type*" but print no note, so the FY2024 note is carried forward. ga_liheap_matrix_amount adds the FY2025 matrix to its reference tuple.
  • G11: Both PAMMS hrefs (ga_liheap_eligible and ga_liheap_household_size) now carry the comment "PAMMS chapter 100, export dated 2026-10-16." The page stays only in the href fragment (#page=4), as the repository's reference convention requires for a single page.
  • G12: Partly done. fpg_year_lag.yaml now lists one entry per IM with the full identifiers, in Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279's order and wording: IM 2024-02 Attachment 2 (FY25), IM 2025-02 Attachment 2 (FY26) and IM 2026-01 (FY27, for the carried-forward 2027 estimate), and its comment covers all three years. I did not add the IM 2025-02 main page, because Attachment 2 already says "mandatory use in FY26" (from October 1, 2025) and the titles stay identical across the floor PRs.
  • G13: Case 21 now links the USDOL January 2026 provisions (https://oui.doleta.gov/unemploy/content/sigpros/2020-2029/January2026.pdf#page=2) and reads "up to the 14 x WBA maximum benefit amount". Case 22 links BLS OEWS May 2025 for Georgia (https://data.bls.gov/oes/#/area/1300000/2025); I re-checked both medians ($29,070 and $26,920) through the BLS API. Only comments changed.
  • G14: Kept. The repository's reference convention in CLAUDE.md (Document the reference page-citation convention #10009) uses one entry per source document, with the href on the first cited page and the pages at the end of a quoted title, and does not allow per-page entries. All three titles (#page 66,69, #page 62-69,83 and #page 5-7) follow it.
  • G15: changelog.d/ga-liheap.added.md now names the federal 110% poverty guideline floor and gov.hhs.liheap.fpg_floor. It does not call the parameter new, since Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 may merge first.
  • G16: Added eligibility Case 12: the Case 22 household with one adult undocumented, so the SPM size is 17 and the Georgia size 16. That adult's income still counts (manual 1100.4, p. 51), so $111,980 exceeds both the size-16 limit ($107,634) and the size-16 floor ($107,965) and the household is ineligible; a floor at the SPM size ($114,015) would admit it. I kept the sourced OEWS wages in place of $110,000.
  • G1 (prior): Still declined. Claiming FY2024 or gating FY2023 is history, which is out of scope for this PR, so verified_years stays "2025-2026"; G9 now dates the FY2025-cited parameters.
  • G2 (prior): Still declined. heating_type is a required input, and no Georgia source maps kerosene, coal or solar to a priced column, so they stay eligible at $0 as a documented coverage gap (Default heating_type to electricity and remove the UNSPECIFIED-gated state heating adapters #9754 tracks the default). Unspecified fuel at $0 on the electric route is pinned by ga_liheap.yaml Case 16 household 4 and the new Case 17 household 3.
  • G4 (prior): Still declined. Level II plus the $100 uplift reproduces all ten printed cells in both claimed years, and the routes stay helper functions to avoid two wrapper variables; eligibility Cases 7-9 and ga_liheap.yaml Cases 14, 16 and 17 pin them.
  • G6 (prior): FY2027 is still declined. DFCS has published no FY2027 matrix, only a draft plan, so period 2027 stays a documented carried-forward estimate.
  • LIHEAP wave 2a: encode Georgia LIHEAP regular heating assistance TheAxiomFoundation/rulespec-us#1533 is refreshed to match.

Thanks also for checking the PAMMS $350-$400 text and the size-16 eligibility above the printed limits.

@DTrim99

DTrim99 commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

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

PR #9968 (author: hua7450). This round reviews head c60610f7f7; round 1 reviewed 50aaa0096e. Four commits and one outside review came in between:

Neither merge had a hand-resolved conflict. The only Georgia-relevant file either merge touched is the programs.yaml coverage line, which comes through unchanged.

Path prefixes, as in round 1: P/ = policyengine_us/parameters/gov/states/ga/dfcs/liheap/, V/ = policyengine_us/variables/gov/states/ga/dfcs/liheap/, T/ = policyengine_us/tests/policy/baseline/gov/states/ga/dfcs/liheap/. Line numbers refer to c60610f7f7.

Summary

Ziming fixed all three round-1 should items:

  • S1. The person list reads total_unemployment_compensation. Main's guard passes at the head, and ga_liheap.yaml Case 21 adds $5,110 of UI, which moves the award from $500 to $400.
  • S2.
    • Income Case 15 sets all eight unpinned sources at $100–$800 each.
    • He took my second option for the electric route: he dropped the tenant_pays_utilities conjunct. Eligibility Case 9 pins it.
    • Income-limit Case 4 asserts $0 at size 0.
  • S3. All six descriptions use the suggested wording.

Of the six suggestions:

  • Fixed: G3 and G5.
  • Partly fixed, rest declined with reasons I accept:
  • Declined (accepted): G4. The inferred $100 uplift is now labelled as inferred.

His second commit also fixes Pavel's four should items:

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: 8 new cases, 1 changed case, and 24 cases whose unread inputs were removed. CI is 29/29 green at the head. The branch is 16 ahead of main and 17 behind, and merges cleanly.

Prior findings status

Finding Status Evidence
S1: the person list read the raw unemployment_compensation, so main's #9558 guard failed on the merged tree Fixed The list. P/income/sources/person.yaml:13 reads total_unemployment_compensation, and no Georgia LIHEAP file reads the raw input. The guard. All four test_unemployment_compensation_readers.py tests pass at the head (Rest shard-1). The case. ga_liheap.yaml Case 21 gives 12,000 + 5,110 = 17,110, above the 13,589 Level I top, so Level II electric $400. Without the UI it would be $500. Georgia has no modeled UI, so the reported amount passes through. The issue. rulespec-us#1533's input list now names the total.
S2: eight sources, the electric route's tenant_pays_utilities conjunct and the size-0 mask had no test that would fail Fixed (1) Sources. Income Case 15 gives each source a distinct amount, $100–$800, for a total of 3,600, so dropping any one changes the total. (2) Conjunct. He took my second option and dropped it (V/eligibility/_ga_liheap_housing.py:50-54). Eligibility Case 9 gives a subsidized renter with tenant_pays_utilities false eligibility and $660 with the $1,200 bill, and ineligibility without it. Restoring the conjunct fails that case. The change opened Pavel's S4, which is now fixed (below). (3) Mask. Income-limit Case 4 asserts 0 at size 0. Unmasked, it would be floor(66,441 × 0.52) = 34,549.
S3: six descriptions used verbs outside the template Fixed All six use the suggested wording (excludes ×2, uses ×2, provides, sets). All ten Georgia descriptions end at "under the Low Income Home Energy Assistance Program."
G1: claim FY2024, gate FY2023, cite FY2025 documents Citations fixed; claim declined (accepted) Citations. base_amount, lower_income_uplift and maximum_table_size cite the FY2025 matrix, and smi_rate cites FY2025 plan 2.1 (p. 8). All four now start on 2024-10-01 (Pavel's G9), with no output change. The claim. verified_years stays "2025-2026", and the body calls other years unverified estimates. The decline matches #9967 G1.
G2: kerosene, coal, solar and unspecified fuel eligible but paid $0 Note added; kept by design (accepted) Disclosure. V/payment/ga_liheap_matrix_amount.py:70-73 cites #9754, and the body's not-modeled table lists the gap. Tests. The $0 on the electric route is now pinned by ga_liheap.yaml Case 16 household 4 and Case 17 household 3. Consistency. It matches #9967 G2.
G3: cite the FY2024 matrix note, PAMMS and the DFCS page; the body on PAMMS $350–$400 Fixed The FY2024 note. The _ga_liheap_housing.py docstring and the body quote "The main fuel type is not always where the benefit is applied". The docstring adds that the FY2025 and FY2026 sheets keep the asterisk but drop the note (Pavel's G10). PAMMS and DFCS. PAMMS ch. 100 p. 4 and the DFCS page back the household size, and PAMMS backs the main-heating-source bill rule. The body says PAMMS p. 5 still prints $350–$400 and that plan 16.1 (p. 30) makes the matrix govern.
G4: encode the printed Level I column; expose the routes as variables Declined (accepted) The uplift. P/payment/lower_income_uplift.yaml:2-4 now labels the $100 as an inferred pattern ("Encode the printed Level I column if a matrix breaks the pattern"). The matrix-amount comment states the same-uplift assumption behind the lowest award. Both reproduce all ten printed cells in both claimed years. The routes. They stay helpers, and eligibility Cases 7–9 and ga_liheap.yaml Cases 14, 16 and 17 pin them.
G5: body rows for other direct-pay cases and plan 2.3, the heating_type sentence, pp. 5–7 Fixed The rows. The body adds the other direct-pay row (p. 89 rows 4 and 7, p. 4, 1300.2 on p. 70) and the plan 2.3 conflict row. ga_liheap_eligible.py:51-54 also notes plan 2.3. The sentence now covers eligibility and payment cases only, which is accurate. Page ranges. The item 1.9 title (P/income/sources/person.yaml:57) and the V/income/ga_liheap_income.py:15 comment read 5–7.
G6: test hygiene, FY2027, issue housekeeping Hygiene and issue fixed; FY2027 declined (accepted) Hygiene. No hud_utility_allowance remains, and the isolated size, income, limit and matrix cases set no unread fuels or bills. Two exceptions are deliberate: income Case 8 keeps heating_type for its matrix assertion, and matrix Case 3 keeps the $50 gas bill. FY2027. On 2026-10-20 the Clearinghouse returns 404 for a Georgia FY2027 matrix and plan. The DFCS LIHEAP page (modified 2026-09-28) links only the draft FFY27 plan, so the carried-forward 2027 estimate stays documented. The issue. #1533 no longer says "open as a draft".

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

  • S4 (same inputs, different award by subsidy).
    • The fix. V/payment/ga_liheap_matrix_amount.py:60-63 sets direct_payment = direct_route & ~electric_vendor. A heat-in-rent renter with an electric bill is therefore paid the main-fuel amount, with or without a subsidy.
    • The tests. ga_liheap.yaml Case 17 now expects $660 and $560 (it was $500 and $400), plus an UNSPECIFIED household at $0.
    • Sources and disclosure. The docstring cites manual p. 57. The body's "with or without a subsidy and whatever tenant_pays_utilities says" sentence now holds.
    • Against the manual. Manual p. 89 row 3 ("Heat costs included in rent and applicant is billed directly for electric") reads "Paid to electric vendor because gas usage is indeterminate", which supports the fix.
  • S5 (floating-point floor). V/eligibility/ga_liheap_eligible.py:40 uses np.round(guideline * p_hhs.fpg_floor, 2) with a strict <, the same line as merged MS, NJ, OR and DC.
  • S6 (floor tests). Eligibility Cases 10 and 11 pin the rate, the strict boundary and the lag (see Verified). The Case 22 comment now points to them.
  • S7 (anchor). Both 8624 links end #b_2_B, and fpg_floor.yaml is identical to main's.

Of his suggestions:

  • Done:
    • G8: the p. 43 assurance in ga_liheap_eligible and the body.
    • G9 and G10 (above).
    • G11: the PAMMS export date beside both hrefs.
    • G13: the USDOL and BLS URLs and the 14 × WBA wording.
    • G15: the changelog names gov.hhs.liheap.fpg_floor.
    • G16: eligibility Case 12.
  • Partly done: G12. The full IM identifiers are given and IM 2026-01 is added. The IM 2025-02 main page is not added, because Attachment 2 already says "mandatory use in FY26".
  • Deferred: G7, a shared floor helper. Per-state fpg_year_lag matches how Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279 left MS, NE and the rest.
  • Declined, correctly: G14, per-page references. CLAUDE.md "Parameter and variable references" requires one entry per source document, with multi-page titles such as #page 66,69. The three titles follow that.

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/person.yaml:21 lists military_retirement_pay (with survivor_benefits at line 25).
  • 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 does not include the new input.
  • The rule counts these payments. Manual 1200.7 includes "Pension — Unearned payment received regularly as a retirement benefit" (p. 66) and "Annuity" (p. 65). FY2026 plan 1.9 lists "Retirement / pension benefits" (p. 6).
  • Effect on the merged tree (worked out from the code, not run). Take a surviving spouse with $36,000 a year of SBP annuity entered in military_retirement_pay_survivors, natural gas heat with a $1,200 bill, and no other income, in 2026:
    • Merged tree: countable income is $0, so Level I natural gas, $660.
    • Counting the annuity: $36,000 is above the $34,549 limit, so $0, as in ga_liheap.yaml Case 12 household 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 income Case 15, or add a separate case.
    • Update the Inputs line of rulespec-us#1533.

Verified

  • Mutation check (item 13), reasoned from the tests and code at the head:
    • New floor logic in ga_liheap_eligible:
      • The rate. Eligibility Case 10 brackets it to the cent: 107,964.99 is true and 107,965 is false.
      • The strict <. Case 10 row 3 (107,965) and Case 11 row 3 (105,336).
      • The rounding. Without it, 1.1 × 98,150 = 107,965.00000000001 admits row 3. A ceiling would give 107,966, which also admits it.
      • fpg_year_lag 1. Case 10 row 5 (lag 0 gives 117,524, so true) and Case 11 row 4 (lag 0 gives 107,965, so true).
      • The | floor arm. ga_liheap.yaml Case 22 and Case 11 row 1.
      • Georgia size, not SPM size. Eligibility Case 12, where the SPM size would give a 114,015 floor, so true.
    • Route precedence.
      • & ~electric_vendor: ga_liheap.yaml Case 17 ($660, not $500).
      • Restoring tenant_pays_utilities on the electric route: eligibility Case 9 and ga_liheap.yaml Case 17.
      • The direct route's own ~tenant_pays_utilities: still pinned by eligibility Case 7 column 2, which has no electric bill.
    • The size-0 limit mask: income-limit Case 4.
    • Each income source: income Cases 1 and 15 plus the round-1 cases.
    • Unchanged since round 1: the other branches. Round 1 confirmed them by mutation runs, and the code around them has not changed.
  • State-gated keys (item 15, NH Add New Hampshire state supplementation for 2026 #10156).
    • The pattern is present. ga_liheap_household_size is an int gated to Georgia with default 0. p.lower_income_limit[lookup_size] reads it as a key (breakdown range(1, 17)).
    • Core runs the formula on every row. policyengine-core evaluates a defined_for formula on the whole population and then applies np.where(mask, ...), so non-Georgia rows reach the lookup with size 0.
    • The guard and its test. clip(size, 1, p.maximum_table_size) covers it. ga_liheap.yaml Case 5 ([GA, GA, GA, AL], asserting ga_liheap) evaluates ga_liheap_matrix_amount on the Alabama row, so removing the lower clip would raise there.
    • The new floor. fpg(size, state_group, ...) uses size only in arithmetic, and state_group is always a valid key. Eligibility Case 6 [GA, AL] runs it.
  • Integrate modeled state unemployment insurance into income flows #9558 (item 11). The guard's four tests pass at the head, and no Georgia file reads raw unemployment_compensation.
  • 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).
    • No premium deduction for wages. Manual p. 69's only premium exclusion is "Health Premiums — Premiums (amount spent on premiums paid by Social Security received by Medicare)", which the PR applies as Social Security net of medicare_part_b_premium. Georgia has no pay-stub premium deduction.
    • Gross wages. Wages come from employment_income, not ssi_earned_income, so Document disjoint health premium inputs and correct consumer treatment #10046 does not reach Georgia LIHEAP.
  • Federal 110% floor (42 U.S.C. 8624(b)(2)(B)).
    • Georgia assures it. "may not exclude a household ... if such income is less than 110 percent of the poverty level" (FY2026 plan p. 43).
    • Where it binds. The printed 60% limit falls below the floor from size 16:
      • FY2025: 102,926 against 105,336;
      • FY2026: 107,634 against 107,965;
      • size 15 does not bind: 101,020 against 99,418 (FY2025), and 105,641 against 101,915 (FY2026).
    • The carried-forward 2027 estimate binds from size 17.
    • Guidelines. The lagged guidelines (2024 for FY2025, 2025 for FY2026) are the HHS-mandatory ones (IM 2024-02 and IM 2025-02, Attachment 2).
    • Implementation. The floor line matches Apply the federal 110% poverty floor to state LIHEAP programs (DC, MA, MS, NJ, OR) #10279's MS and the merged NJ, OR and DC eligibility variables. ga_liheap_income_limit keeps the printed table, and the body has a conflict row for the printed size-16 limits.
  • IIJA and FY2027 (item 12). No IIJA supplement in any Georgia plan or matrix, as in round 1. No FY2027 matrix is published (see G6).
  • Other main commits since the head's merge base (17).
  • New and changed expectations, checked by hand.
    • FY2026: four-person 60% amount floor(110,736 × 0.6) = 66,441. Size factors 1.62 (size 16) and 1.65 (size 17).
    • 2025 guidelines: $15,650 + $5,500 per additional person.
    • 2024 guidelines: $15,060 + $5,380.
    • ga_liheap.yaml:
      • Case 17 (changed): heat in rent, rent 9,600, bill 1,200, so the electric route for all three households: eligible [true, true, true]. 12,000 ≤ 13,589 gives natural gas 560 + 100 = 660. 24,000 gives 560. UNSPECIFIED has no column, so 0. Heating expense is 0 for gas with no gas bill and for UNSPECIFIED.
      • Case 21 (new): 12,000 + 5,110 = 17,110. That is above 13,589 and within 34,549, so Level II electric 400.
      • Case 22 (new): 2 × 29,070 + 2 × 26,920 = 111,980, size 17. The limit is floor(66,441 × 1.65 = 109,627.65) = 109,627 and the floor is 1.1 × 103,650 = 114,015, so eligible. The size-16 Level I top is 42,336, so Level II natural gas 560, with heating expense 1,800.
    • ga_liheap_eligible.yaml:
      • Case 9 (new): subsidized, heat in rent, tenant_pays_utilities false.
        • With the bill: the electric route makes it eligible, and the subsidy blocks the direct route, so 560 + 100 = 660.
        • Without it: no route and no primary bill, so false and 0.
      • Case 10 (new): limits 107,634 ×4 and 109,627. Size-16 floor 1.1 × 98,150 = 107,965. That gives [107,634 ≤ limit: true; 107,964.99 < floor: true; 107,965: false; 107,966: false]. Size 17 at 115,000 is above 109,627 and at least 114,015, so false.
      • Case 11 (new): limit floor(floor(105,893 × 0.6) × 1.62) = floor(63,535 × 1.62) = 102,926. Floor 1.1 × 95,760 = 105,336. That gives [104,000: true; 105,335.99: true; 105,336: false; 106,000: false].
      • Case 12 (new): SPM size 17, Georgia size 16 (undocumented adult left out, manual 1100.4 p. 51), and income 111,980 (that adult's wages count). The limit is 107,634 and the floor 107,965, so false.
    • ga_liheap_income_limit.yaml Case 4 (new): size 0 gives 0.
    • ga_liheap_income.yaml Case 15 (new): 100 + 200 + ... + 800 = 3,600. Unemployment comes through total_unemployment_compensation, which equals the reported 100.
    • Changed inputs, unchanged outputs:
      • Removed inputs: heating inputs and hud_utility_allowance.
      • The cases: household-size Cases 1–2, income Cases 1–13, income-limit Cases 1–3, and matrix Cases 1–4, 6 and 7.
      • None of those variables reads them. Size adds is_citizen_or_legal_immigrant. Income reads the income sources. The limit reads size and state. The matrix amount reads heating_type, size, income and the route inputs, which default to no route.
      • Income Case 8 keeps heating_type, and its $500 needs no bill.
  • Inputs not checked. I didn't check the USDOL UI provisions ($365 WBA, 14 × WBA) or the BLS OEWS medians ($29,070 and $26,920). They are inputs only, and every expectation follows from them.
  • Wiring.
    • Registry. The programs.yaml entry and coverage line are unchanged since round 1 (partial, verified_years: "2025-2026").
    • Aggregates. Georgia is in no aggregate, which matches the merged LIHEAP states.
    • Gating. defined_for = StateCode.GA is on five variables, and ga_liheap is gated by ga_liheap_eligible.
    • Changelog. changelog.d/ga-liheap.added.md is top level and typed added, and now names the floor parameter.
  • 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 since round 1. The new floor rests on 42 U.S.C. 8624(b)(2)(B) and plan p. 43 (re-read). Manual pp. 57, 65–69 and 89 were re-read for S4, item 14 and Suggestion 1.
  2. Income definition: pass. Gross wages; Social Security net of Part B per plan 1.9 and manual p. 69; per-source floors; the Integrate modeled state unemployment insurance into income flows #9558 total. 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. FY2025-cited files now start 2024-10-01. FY2024 and FY2023 are unclaimed and declined. No FY2027 table is published.
  4. Household and arrangement rules: pass. Subsidized and unsubsidized heat-in-rent renters with an electric bill now get one award (Pavel's S4). Every route is pinned.
  5. Tests: pass. 62 cases in 6 files, with every new or changed expectation checked by hand. Periods are plain. The floor edges are pinned to the cent in both claimed years.
  6. Descriptions: pass. All ten Georgia descriptions follow the template.
  7. References: pass.
    • Multi-page titles use #page 66,69, #page 62-69,83 and #page 5-7.
    • Variable tuples use # PDF pages comments.
    • The 8624 links are anchored.
  8. Wiring: pass. Registry, no aggregate (as in the siblings), defined_for gating, and no take-up beyond TANF's.
  9. Axiom: valid queued line. Correct the qualified_business_income variable formula #1533 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: fixed. The guard passes.
  12. IIJA / FY2027: not applicable (no supplement). No FY2027 matrix is published; the draft plan keeps 60% SMI and $400–$810.
  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. Only the Medicare premium on Social Security is excluded; wages are gross employment_income.
  15. State-gated index defaults: guarded. The size is clipped to 1, and the GA/AL ga_liheap.yaml Case 5 pins it.
  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#1533 queued.

  • Issue state.
    • Correct the qualified_business_income variable formula #1533 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 Georgia LIHEAP module: us-ga/policies/dfcs/ holds only medicaid, snap and tanf. So queued is still the right form.
  • Dispatch-ready. It has:
    • module paths with corpus status;
    • the verbatim manual, plan, matrix, HHS and statute text;
    • six required outputs;
    • companion tests 1–19, hand-derived from the matrices, HHS tables, plans, 42 U.S.C. 8624 and the manual, and mapped to PE cases.
  • Matches the head c60610f7f7:
    • Cases: 62 cases in 6 files, listed per file.
    • Eligibility: round(1.1 × guideline, 2) with guideline year = model year − 1 at the Georgia size, and the electric route "subsidized or not, whatever tenant_pays_utilities says".
    • Matrix amount: the electric route takes precedence over the all-utilities route (UNSPECIFIED: $0).
    • Inputs: they name total_unemployment_compensation.
    • Companion tests 16–19 match Case 22, eligibility Cases 10–12, Case 21 and income Case 15.
  • The only update it would need is the Inputs line, if Suggestion 1 is taken.

CI status

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

  • Quick Feedback ran all six Georgia LIHEAP files at the head: 12 + 4 + 22 + 2 + 15 + 7 = 62 passed. The whole Georgia tree also passed (477).
  • Rest (Python, shard-1) passed the Integrate modeled state unemployment insurance into income flows #9558 guard's four tests and test_members_are_state_gated.
  • 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: all three should-address items from round 1 are fixed (#9558 reader, income and limit test coverage, descriptions), and Pavel's S4-S7 are fixed too. One open suggestion about #10182 survivor annuities. Full report in the comment above.

This branch has not been deployed

No deployments
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 Georgia LIHEAP regular heating assistance

3 participants