Skip to content

Add West Virginia LIEAP regular heating assistance - #10618

Open
hua7450 wants to merge 10 commits into
mainfrom
wv-liheap-wave2c
Open

hua7450 wants to merge 10 commits into
mainfrom
wv-liheap-wave2c

Conversation

@hua7450

@hua7450 hua7450 commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Adds West Virginia's Low Income Energy Assistance Program (LIEAP) regular heating payment for FY2026 and FY2027, run by the Department of Human Services (DoHS), Bureau for Family Assistance, under chapter 21 of the Income Maintenance Manual (IMM). The model counts citizens and legal immigrants in the assistance group and every member's gross income except the manual's exclusions, which include Social Security (RSDI) and SSI. The limit is 60% of state median income for one to seven members and 150% of the prior-year poverty guideline from eight ($2,454 a month for one person in FY2026, $2,550 in FY2027). The manual prints that limit rounded to the whole dollar a month, and the model stops it at the unrounded annual amount, the federal ceiling in 42 U.S.C. 8624(b)(2)(B). The payment is the Appendix A base amount for the group's size and monthly income row ($160 for one person in the first row, $5 less per row, $5 more per member) times a fuel factor (1.750 electricity, 1.198 natural gas, 1.089 propane, fuel oil, kerosene, wood and coal), rounded to the cent: $70.79 to $446.25.

Fixes #10617

Regulatory authority

Eligibility

Requirement Source How modeled
West Virginia residence IMM 21.3.1.D.1 defined_for = StateCode.WV
Qualified members 21.3.1.B; 21.3.1.D.2 SPM unit as the assistance group; size sums is_citizen_or_legal_immigrant; size 0 is ineligible
Income at or below the limit 21.3.1.A; plan 2.1, 2.4; chapter 4 Appendix A; 42 U.S.C. 8624(b)(2)(B) 60% of SMI for sizes 1-7 (four-person SMI $94,396 in FY2026, $98,088 in FY2027), 150% of the prior-year guideline from 8; monthly limit rounded to the dollar, times 12, capped at the unrounded annual amount, against annual income; inclusive
No categorical bypass 21.3.1.A; 21.4.9.A; FY2027 plan 1.4 SNAP, TANF or SSI receipt does not lift the income test
Heating responsibility 21.3.1.C, C.2, C.3, C.6 has_heating_expense: a positive bill for the named fuel, heat not in rent; callers may set it for a heating charge stated in rent or electricity that runs self-cut wood; subsidized tenants who pay heat directly qualify

Countable income

Item Source How modeled
Whose income 21.3.1.A.3; 21.3.1.D.2 Every member, any age, counted in size or not; each source floored at zero per member, so a rental or business loss cannot cancel another receipt
Business income 21.3.1.A, A.3 Net self-employment, SSTB, farm, partnership and S-corporation, and estate income; no second 20% deduction
Other sources 21.3.1.A.3 Wages and active-duty basic pay (military_basic_pay), unemployment (total_unemployment_compensation), strike benefits, pensions, military retirement (military_retirement_income, with Survivor Benefit Plan annuities), railroad retirement (railroad_benefits), retirement-account distributions, non-Social Security survivor benefits, general assistance, rental and farm rental income, alimony, child support received, interest, dividends, veterans benefits, workers' compensation, disability benefits, outside cash help (financial_assistance), recurring miscellaneous receipts (miscellaneous_income, the only input able to carry contract, mineral-rights, jury-duty or settlement receipts)
WV WORKS 21.3.1.A.3 Take-up-gated tanf, once per household
Not counted A.4 (earlier edition), A.5 (update 881) Social Security Administration RSDI and SSI, so no Medicare premium question arises; student aid, SNAP and the other listed exclusions; capital gains, gambling and life-insurance proceeds as nonrecurring lump sums

Benefit

Item Source How modeled
Income row Appendix A (pages 1772-1773; 1775-1776) Annual income / 12; first row whose printed upper bound is at least that amount (right=True)
Base amount Appendix A $160 + $5 x (size - 1 - row index); sizes 1-20
Fuel factor 21.4.11.B 1.750 electricity; 1.198 natural gas; 1.089 propane, fuel oil, kerosene, wood, coal; none for SOLAR, OTHER, NONE, UNSPECIFIED
Payment 21.4.11.B table Base x factor once, rounded half up to the cent; no bill cap and no reduction for partial responsibility

Source priority and modeling notes

  • Income test and income sources. The manual governs over the plan. Section 21.3.1.A denies any group above the ceiling, and 21.4.9.A verifies a working member's income even when another member receives SSI, so FY2026 plan item 1.4's TANF, SSI and SNAP categorical eligibility does not lift the test (candidate us-wv:liheap-plan-categorical-eligibility). FY2027 plan item 1.4 answers No. The manual counts all sources except its list, so the model counts general assistance, TANF, cash help, VA benefits and minors' earnings, which plan item 1.9 leaves unchecked (the FY2027 plan checks a child's earnings), and excludes nonrecurring lump sums, which 1.9 checks (candidate us-wv:liheap-plan-income-and-benefit-items). The exclusion names only Social Security Administration benefits, so railroad retirement, paid by the Railroad Retirement Board, counts. Board of Review decisions apply 21.3.1.A to a SNAP recipient whose income went unverified (25-BOR-1354, pages 3-4) and with the $4,720 four-person limit (26-BOR-1570, page 4).
  • VA benefits. The December 18, 2025 DoHS announcement says "Social Security & Veterans Benefits Excluded", and item 1.9 of both plans (page 7) leaves "Veterans Administration (VA) benefits" unchecked. Both manual editions name one VA exclusion: "Veterans Affairs (VA) Aid and Attendance payments." The model follows the manual and counts veterans_benefits in full, since the input cannot separate Aid and Attendance. Both editions are later than the announcement (the earlier PDF was created July 27, 2026, and update 881 takes effect October 1, 2026), and the fact sheets and agency pages do not repeat its line. A veteran with $30,000 in VA benefits and no other income receives $0 under the manual and would receive $280 under the announcement (candidate us-wv:liheap-veterans-benefits, unreviewed).
  • Benefit variables. Plan item 2.5 (page 11) checks "Individual bill", "Energy burden" and "Energy need", and item 1.6 (page 5) bases levels on "income, household size, cost of energy, and fuel type". Update 881 (page 1757) bases them on "the income, the number of persons in the AG, and the type of energy used". The model follows the manual and reads no bill amount or burden (candidate us-wv:liheap-plan-income-and-benefit-items).
  • Limit rounding. The plan sets the rates; the manual and agency print whole-dollar monthly limits. Rounding the monthly amount to the nearest dollar is an inferred convention, not a stated rule. It reproduces every limit the manual prints for sizes 1-10 in both years and FY2027's size 11 ($8,385 + $710 = $9,095). The 60% SMI branch reuses the shared liheap_smi_limit.
  • Federal ceiling. 42 U.S.C. 8624(b)(2)(B) limits assistance to households with income at or below the greater of 150% of the poverty level and 60% of SMI, and West Virginia's unrounded amount equals that maximum at every size 1-20 in both years. A monthly limit that rounds up sits $1 to $5 a year above it at FY2026 sizes 3, 4, 5, 7 and even sizes 8-20 and at FY2027 sizes 2, 3, 6 and 7, so the model stops at the unrounded amount (candidate us-wv:liheap-income-limit-above-federal-ceiling, following the statute). A three-person FY2026 group with $47,578 receives $0, where the printed $3,965 x 12 = $47,580 would pay $253.75 (wv_lieap.yaml Case 11).
  • Printed limit differences. For FY2026 sizes 11-20 the annual limits run from $105,972 ($8,831 a month, the chart's row top; 150% of $70,650 is $105,975) to $180,225 ($15,018.75 a month). Adding $688 per member to the ten-person $8,144 gives $8,832 through $15,024, above 150% of the guideline. For FY2027 size 8 the manual, the agency page and the fact sheet print $6,965 (150% of $55,720 / 12; page and fact sheet checked 2026-11-03). The FY2026 fact sheet prints $6,372, $6,769 and $6,590 for sizes 6-8, against the manual's $6,230, $6,372 and $6,769. Some chart cells sit above a size's limit (FY2027's size-12 cell in the $9,806-$10,160 row against a $9,805 limit; each chart's size-20 $60 row); the limit governs.
  • Chart rows. The first two rows overlap ($0-$2,077 and $1,078-$2,454 in FY2026) and whole-dollar rows leave cent gaps. The printed upper bounds act as continuous ceilings without rounding income, and every other bound stays as printed. That includes FY2027's fifth row ending at $3,427, which looks like a misprint: the midpoint of $3,335 and $4,120 is $3,727.50, and the matching FY2026 row is a midpoint. A three-person group at $3,428-$3,727 receives a base of $145 where the midpoint would give $150. The FY2026 chart carries a stale "FY 2025 INCOME LEVELS" heading, but its row tops equal the FY2026 limits.
  • Base and factor. The base formula reproduces all 840 occupied cells of the two charts exactly; it compresses the table and is not used beyond it. Section 21.4.11.B describes "the base amount plus the incremental amount", but the printed product table shows base x factor as the payment, and the model follows the table. Half-up cents reproduce the printed $147.02 (135 x 1.089) and $70.79 (65 x 1.089).
  • Heating responsibility. Heat in rent or housing assistance alone cannot establish responsibility, and no subsidized tenant is excluded outright. A $0 for heat bundled in rent without the responsibility fact, above 20 members, or for SOLAR, OTHER or UNSPECIFIED heating means no modeled award, not a legal denial; NONE reports no heating. The model pays a zero-income bill holder in both years (wv_lieap.yaml Case 1); it has no input for the FY2026 C.7 third-party payer, whom that edition treats as invulnerable.

The registry entry is partial with verified_years: "2026-2027"; earlier years are unverified backfilled estimates.

Not modeled

Item Source Treatment
Groups above 20 members; SOLAR and OTHER heating Appendix A; 21.4.11.B No printed column or factor; $0
Fixed versus movable dwellings 21.3.1.C.1; plan 2.5 No input
Zero-income group whose bill another person pays C.7 (FY2026: invulnerable); A.4 and C.7 in update 881 Not distinguished
Application-month income, pay-frequency conversion, 20% gross-receipts deduction 21.3.1.A.1-A.3 Annual / 12; net business inputs
One-time mineral-rights and royalty receipts, foster care, child support arrearages, work-study and CNCS wages, reimbursements A.3-A.4; plan 1.9 No separate inputs; miscellaneous_income reads as recurring
Surcharges, a documented rent increase, portable-heater and alternate-fuel approval, members already paid as part of another group (whose income also leaves this group), one payment per season 21.3.1.B, C.2, C.5, E Not represented
Households with more than one SPM unit 21.3.1.B ("all household members are considered one AG") The SPM unit stands in for the assistance group, as across the all-state LIHEAP effort, so each unit gets its own size, income test and payment. Two unrelated adults with $24,000 each and one bill receive $280; the manual would deny one group of 2 at $4,000 a month
Supplemental payments; repayment offsets Update 881 pages 1735, 1768; plan page 12 No amount or input
Emergency LIEAP, cooling, repair or replacement, weatherization, 20% utility discount Plan 1.1; BFA LIEAP page Out of scope

Microsimulation: heating_type, the per-fuel bills and the heat-in-rent fact behind has_heating_expense are not in current datasets; callers must supply them.

Test plan

42 YAML cases in 5 files. CI passed the 40 earlier cases at the previous head, fcdbc7f779. The 2026-11-03 review fixes, which change the limit expectations and add wv_lieap.yaml Cases 11 and 12, and the merge of main at 6145ad4513 have not run locally, and CI validates them.

  • wv_lieap.yaml (12): every heating type at zero income; both years' first two rows and one-person ceiling to the cent; FY2027's $3,427 row; adjacent eleven-person rows; the $147.02 half cent; 20 members at the ceiling and 21 members; direct, subsidized, missing and heat-in-rent costs; a stated rent charge and self-cut wood; a mixed-status group through to the payment; the federal ceiling at FY2026 sizes 3 and 8 and FY2027 size 3.

  • wv_lieap_income_limit.yaml (5): FY2026 and FY2027 limits for sizes 1-11 under the federal ceiling, one multi-unit case per year, the 7/8 switch by qualified members, and an Ohio household.

  • wv_lieap_income_eligible.yaml (4): inclusive ceilings, SNAP, TANF or SSI receipt above the ceiling, unqualified members' income, a zero limit at zero qualified size.

  • wv_lieap_countable_income.yaml (16): minors' and unqualified members' earnings, each listed source including military basic pay, railroad retirement and miscellaneous income, the exclusions, nonrecurring proceeds, per-source loss floors, unemployment and WV WORKS receipt.

  • wv_lieap_household_size.yaml (5): qualified and unqualified members.

  • YAML tests with expected values from the IMM charts, product table and income tables, the agency guidelines, and the HHS SMI and poverty-guideline tables

  • Source-conflict register entry for a statute reading: the federal ceiling is backlog entry us-wv:liheap-income-limit-above-federal-ceiling in source_conflicts/candidates.yaml; no # Source conflict marker until it is registered. Three source choices with no statute reading are also candidates: us-wv:liheap-plan-categorical-eligibility, us-wv:liheap-plan-income-and-benefit-items and us-wv:liheap-veterans-benefits

  • make format

  • Changelog fragment in changelog.d/

  • CI passes

axiom: TheAxiomFoundation/rulespec-us#1998 queued

🤖 Generated with Claude Code

@codecov

codecov Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (b540912) to head (b90a7e0).
⚠️ Report is 95 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main    #10618   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         5    +4     
  Lines           54        82   +28     
  Branches         0         1    +1     
=========================================
+ Hits            54        82   +28     
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.

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

DTrim99 commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Add West Virginia LIEAP regular heating assistance

Summary

PR #10618 (author: hua7450), head fcdbc7f779. This is a first review. The PR adds West Virginia's regular heating LIEAP payment for FY2026 and FY2027:

  • 10 parameters and 5 variables under gov.states.wv.dhhr.lieap;
  • 5 test files with 40 cases;
  • a programs.yaml entry plus WV on the LIHEAP coverage line;
  • a changelog fragment.

There are no reviews yet, and the only comment is Codecov's.

The rules research matches the code closely. I worked from four sources:

  • both Income Maintenance Manual editions (chapter 21 and chapter 4 Appendix A);
  • the FY2026 accepted plan and the FY2027 submitted plan;
  • HHS's FY2026 and FY2027 SMI tables;
  • the BFA LIEAP page and fact sheet.

What I checked:

  • Chart transcription. I parsed both Appendix A charts. All 80 printed row tops equal the income_band thresholds, and the base formula $160 + $5 x (size - 1 - row) reproduces all 840 printed cells.
  • Fuel factors and limits. The fuel factors and the half-up cents match 21.4.11.B. The limits reproduce every figure the manual prints.
  • Income. The income definition follows 21.3.1.A: all sources count, minus the exclusion list, with no deductions.

One critical finding. The state's whole-dollar monthly limits are slightly above the federal ceiling of 42 U.S.C. 8624(b)(2)(B) at several household sizes in both claimed years, and the head follows them. This is the North Dakota #10342 C1 pattern.

Two should-address items:

  • military_basic_pay is missing from the income list.
  • One zero-size guard in the limit has no test.

Four suggestions. CI is green (36/36), and the merge with main is clean.

Critical

C1. The income test admits households above the 42 U.S.C. 8624(b)(2)(B) ceiling in both claimed years.

Where. policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_limit.py:31-36. The variable takes liheap_smi_limit or 150% of the lagged guideline, rounds the monthly amount to the nearest dollar and multiplies by 12. wv_lieap_income_eligible then admits income up to that figure.

What goes wrong. Rounding up reproduces West Virginia's printed limits, but at several sizes it lifts the limit above the federal maximum.

The law. Payments may go only to households "with incomes which do not exceed the greater of (i) an amount equal to 150 percent of the poverty level for such State; or (ii) an amount equal to 60 percent of the State median income" (42 U.S.C. 8624(b)(2)(B)). HHS publishes the size-adjusted 60% amounts as "Mandatory Use in LIHEAP for FY26" (IM 2025-02 Attachment 4). For West Virginia:

  • FY2026: 29,451, 38,513, 47,575, 56,637, 65,698 and 74,760 for sizes 1 to 6 (page 3), and 76,459 for size 7 (page 6).
  • FY2027: 30,603, 40,019, 49,435, 58,852, 68,268 and 77,684 for sizes 1 to 6 (page 3), and 79,450 for size 7 (page 6) (FY2027 Attachment 4).

From size 8 on, 150% of the guideline is the larger amount.

Year Size Head's annual limit Federal maximum Excess
FY2026 3 47,580 (3,965 x 12) 47,575 (60% SMI) $5
FY2026 4 56,640 56,637 $3
FY2026 5 65,700 65,698 $2
FY2026 7 76,464 76,459 $5
FY2026 8, 10, 12, 14, 16, 18, 20 6,768.75 → 6,769 x 12 = 81,228; likewise for the other even sizes 1.5 x 54,150 = 81,225; likewise for the other even sizes $3 each
FY2027 2 40,020 40,019 $1
FY2027 3 49,440 49,435 $5
FY2027 6 77,688 77,684 $4
FY2027 7 79,452 79,450 $2

At the even FY2026 sizes from 8 up, 150% of the 2025 guideline ends in $0.75 a month, so rounding goes up. FY2027's 2026 guideline gives whole dollars, so sizes 8 and up are exact.

Hand examples:

  • FY2026, three people, electric heat, wages $47,578 ($3,964.83 a month). The head finds the unit eligible: 47,578 ≤ 47,580. The income sits in row 5, whose top is $3,965, so the base is 160 + 5 x (3 - 1 - 5) = $145. The head pays $253.75. The federal maximum is $47,575, so the result should be $0.
  • FY2026, eight people, wages $81,227 ($6,768.92 a month). The unit falls in row 15, so the base is 160 + 5 x (8 - 1 - 15) = $120. The head pays $210 with electric heat; the ceiling is $81,225.
  • FY2027, three people, $49,438. The unit falls in row 5 (the $3,428-$4,120 row), the base is $145, and the head pays $253.75; the ceiling is $49,435.

Precedent. This is the North Dakota #10342 C1 pattern: printed 60% SMI limits $2 to $12 above Attachment 4 were critical. The accepted fix capped every band at the federal maximum and recorded a follows: statute candidate (us-nd:liheap-table-above-federal-ceiling). CLAUDE.md's source rule points the same way: where a statute conflicts with a manual, follow the statute and record the choice.

Fix:

  • Cap the limit at max(liheap_smi_limit(size, state, gov.hhs.liheap.smi_limit, …), gov.hhs.liheap.fpg_limit x fpg(size, group, …, year_lag=p.fpg_year_lag)). Both federal parameters are already on main. The cap can live in wv_lieap_income_limit, or the printed limit can stay as it is and wv_lieap_income_eligible can check the cap separately.
  • Pin the cap. Add cases at the three examples above; each expects ineligible and $0.
  • Update the expectations. Revise wv_lieap_income_limit.yaml Cases 1 and 2 for the affected sizes, or assert the printed figures and the capped eligibility separately.
  • Record the choice. Add a us-wv: candidate with follows: statute, and mark the deciding line # Source conflict us-wv:<id>.
  • Settle the +$688 question. For FY2026 sizes 11 to 20, the manual's "+$688" figures (8,832 for 11, through 15,024 for 20) and the head's rounded figures at even sizes both sit above 150% of the guideline. The cap therefore settles that too. The body's "N/A: no statute reading is involved" line then needs updating.

Should address

S1. military_basic_pay is not counted.

Where. policyengine_us/parameters/gov/states/wv/dhhr/lieap/income/sources.yaml:4. The list counts employment_income but not military_basic_pay, which on main is a separate person input. employment_income does not include it.

Rule. 21.3.1.A.3: "All sources of income are considered in determining income eligibility" (update 881, page 1727; earlier edition page 1726). Plan item 1.9 checks "Wages". Active-duty basic pay is wages, and it is not on the A.5 exclusion list.

Example. One person has $36,000 of basic pay entered as military_basic_pay, with electric heat, in FY2026:

  • The head counts $0 and pays $280.
  • Under the manual, $3,000 a month is above the $2,454 limit, so the application is denied.

Precedent. This is the wave's omitted-source pattern (military pay in UT, AK and PA). IA #10292, UT, ND, NV #10432 and AK list military_basic_pay beside employment_income.

Fix.

  • Add military_basic_pay after employment_income, with the comment those states use (enter basic pay in one of the two inputs, not both).
  • Give it a distinct amount in a countable-income case, for example $500 in Case 2, giving 12,700.
  • Update the body and the Axiom issue's source list (26 sources).

S2. The zero-size guard in the limit is unpinned.

Where. policyengine_us/variables/gov/states/wv/dhhr/lieap/wv_lieap_income_limit.py:36 returns where(size > 0, monthly * MONTHS_IN_YEAR, 0).

Why no test catches its removal. Without the guard, a West Virginia unit with no qualified members gets a $29,448 limit, because smi_size_factor at size 0 is the one-person 0.52. Yet every test still passes:

  • No case asserts wv_lieap_income_limit for such a unit. The only zero values come from the Ohio rows, which defined_for zeroes.
  • wv_lieap_income_eligible separately requires size > 0.

The wave's mutation rule treats an unpinned guard as should-address (UT #10344 r3 N1, two unpinned zero-standard guards).

Fix. Either change is enough:

  • Add wv_lieap_income_limit: 0 to wv_lieap_household_size.yaml Case 3, or to wv_lieap_income_eligible.yaml Case 1, whose third row has no qualified member.
  • Delete the guard as redundant with the eligibility check.

Suggestions

G1. Record the plan-against-manual choices in source_conflicts/candidates.yaml.

The body says no candidate applies. Yet the head makes the same kind of choices that siblings recorded as us-la:liheap-plan-income-checklist and us-mn:liheap-plan-income-checklist (follows: gap-fill, state: ruled; MN #10433 G3):

  • Categorical eligibility. FY2026 plan item 1.4 answers "Yes" for TANF, SSI and SNAP heating (page 5). The head applies the income test to everyone, under 21.3.1.A, the 21.4.9.A SSI example and 25-BOR-1354, which upheld a denial for a SNAP recipient whose self-employment income was not verified.
  • Plan item 1.9 (pages 6-7). It leaves general assistance, TANF, cash gifts, VA benefits and (in FY2026) a child's earnings unchecked, yet the head counts them all. It checks one-time lump sums, which the head excludes under A.3.
  • VA benefits. DoHS's December 18, 2025 announcement says "*Social Security & Veterans Benefits Excluded". Both manual editions exclude only "Veterans Affairs (VA) Aid and Attendance payments", and the head counts veterans_benefits. The body explains this well, but it is the clearest agency-against-manual split and belongs in the register.
  • Plan item 2.5 checks individual bill, energy burden and energy need; the head follows 21.4.11.B.

G2. Cite the FY2027 plan.

DoHS links a submitted FY2027 Detailed Model Plan (report period 10/01/2026 to 09/30/2027) from the LIEAP page. The PR cites only FY2026. The FY2027 plan:

  • Confirms the FY2027 rates. It keeps 60% of SMI from size 1 and 150% of the guideline from size 8 (item 2.1, page 9; item 2.4, page 12). The smi_rate, fpg_rate and smi_max_household_size files cite only the FY2026 plan, though they also drive FY2027.
  • Supports the no-bypass reading. It changes item 1.4 to "No" for TANF, SSI and SNAP (page 5). That supports the head's choice for FY2027 and narrows the conflict in G1 to FY2026.
  • Matches the manual on minors. It now checks "Earned income of a child under the age of 18" (page 7).
  • States the benefit range. Its item 2.6 text says "LIHEAP levels are $1.00 to $446.25" (page 13), matching the head's range.

Add it as a second reference and reflect it in the body and the Axiom issue.

G3. Housekeeping.

  • Agency page and fact sheet. As served on 2026-11-02, the BFA LIEAP page and the FY2027 fact sheet print $6,965 for eight people, matching the manual. The body's "over the $6,695 on the agency page and fact sheet" and Axiom interpretation 7 are now stale.
  • Test status. The test plan says the newest cases "have not run" and leaves "CI passes" unchecked, but CI passed on this head.
  • Limit comment. wv_lieap_income_limit.py:33-34 says adding a rounded increment "diverges from the manual at 11". The +$688 increment is the manual's own figure: 21.3.1.A names the chapter 4 Appendix A chart, and that chart and Appendix D print it. What the increment departs from is the Appendix A payment chart and 150% of the guideline.
  • Test header. In wv_lieap_income_limit.yaml, line 1 ("earlier IMM gives size 11") and line 10 need the same correction. Most of this is rewritten by the C1 fix anyway.

G4. Floor the compressed base.

wv_lieap.py:25-27 says income eligibility confines sizes 1 to 20 to occupied cells. That holds for the baseline in FY2026 and FY2027: I checked that each size's limit is at or below the top of its last printed row. It stops holding in two cases:

  • Under a reform to smi_rate or fpg_rate. With fpg_rate 2.0, an eight-person FY2026 unit at $9,000 a month lands in row 22, a blank cell, and gets base $85.
  • In later years. FPG-based limits rise while the FY2027 chart is carried forward.

At extreme rates the base goes negative. With smi_rate 4.0, one person at $16,000 a month reaches row 40, so the base is -40 and the payment is -$70. A max_(base, 0) floor, or capping the row at 2 x size - 1, would keep the formula safe.

Verified correct

  • Payment chart. Both charts' 40 row tops match income_band.yaml exactly, including:

    • the overlapping printed first rows ("$1,078"/"$1,158");
    • FY2027's $3,336-$3,427 and $3,428-$4,120 rows, which are printed consistently in both the "To" and "From" columns, so following them is right;
    • the irregular larger-family rows (FY2026 $12,270-$12,956; FY2027 $9,096-$9,805).

    Each column runs contiguously to size 20, and every one of the 840 cells equals 160 + 5 x (size - 1 - row). The right=True lookup is pinned by wv_lieap.yaml Cases 2 and 3 (exactly $2,077 gives $280; $2,077.25 gives $271.25).

  • Benefit range. In both claimed years every eligible unit lands on a printed cell. The minimum is $65 x 1.089 = $70.79 (size 20, row 38) and the maximum is $255 x 1.75 = $446.25. No baseline path goes negative.

  • Fuel factors (21.4.11.B, update 881 pages 1757-1758; earlier edition pages 1754-1755). The factors are 1.198 (natural gas), 1.089 (LPG, coal, wood, fuel oil and kerosene) and 1.750 (electricity). The printed product table is base x factor, so the head follows the table over "base amount plus the incremental amount". The mill-then-half-up rounding gives $147.02 and $70.79, as printed. Plain np.round would give $147.01, so Cases 6 and 7 tell the two apart.

  • Limits.

    • SMI. gov.hhs.smi.amount WV is $94,396 (2025-10-01) and $98,088 (2026-10-01), equal to Attachment 4.
    • Guidelines. They are lagged one year: 2025 for FY2026 and 2026 for FY2027 ($15,960 + $5,680).
    • Printed figures. The monthly rounding reproduces chapter 4 Appendix A and Appendix D for sizes 1 to 10 in both editions (earlier page 406; update 881 page 405), and FY2027's 8,385 + 710 = 9,095.
    • 7/8 switch. The switch is counted in qualified members (wv_lieap_income_limit.yaml Cases 3 and 4).
    • Floor. Every limit is far above the 110% floor.
  • Income. The definition follows 21.3.1.A (update 881 pages 1726-1729):

    • gross income with no deductions;
    • all sources count;
    • the A.5 exclusions (RSDI, SSI, SNAP, student aid, WIC, WIOA, tax refunds) are not read;
    • nonrecurring lump sums are excluded;
    • railroad retirement counts as an RRB benefit, consistent with main's Count railroad retirement annuities as SSI unearned income #10534 definition of railroad_benefits as gross RRB benefits.

    Each member's sources are floored at zero separately. Medicare netting does not arise, because RSDI is excluded and no deductions apply. Using net business inputs in place of the 20% gross-receipts deduction is documented.

  • Assistance group. Size counts is_citizen_or_legal_immigrant (8 U.S.C. 1641 qualified noncitizens), while every member's income counts (21.3.1.B and D.2). The SPM unit standing in for the household is the wave convention and is documented.

  • Heating responsibility (21.3.1.C, C.2, C.3 and C.6):

    • a positive bill for the primary fuel, with heat not in rent, qualifies, and subsidized tenants who pay directly qualify;
    • heat in rent alone gets $0;
    • a stated rent charge or self-cut wood can be supplied through has_heating_expense.

    UNSPECIFIED pays $0 (the Default heating_type to electricity and remove the UNSPECIFIED-gated state heating adapters #9754 convention). SOLAR and OTHER pay $0 because the 21.4.11.B table has no factor for them. Both are documented.

  • Tests and mutation. All 25 listed sources and tanf carry distinct nonzero amounts, so dropping any one changes an expectation. The exclusions, the per-source floors, the size-20 gate, the heating gate, each fuel branch and the default, the inclusive ceilings, the 7/8 branch, the guideline lag and the half-up monthly rounding are all pinned. The one exception is S2.

  • Item 17. main has no wv_ssp, and the manual excludes SSI, so this does not apply.

  • NH Add New Hampshire state supplementation for 2026 #10156 pattern. The pattern is safe. The size feeds only arithmetic and the shared helpers, which index by state code and guideline group, not by size. The Ohio and Virginia rows in the same simulations, in all five files, pass in CI.

  • main-side guards:

  • Wiring and housekeeping:

    • the defined_for gating is in place, and the programs.yaml entry has verified_years: "2026-2027", backed by both manual editions;
    • there is no household aggregate, consistent with the merged siblings;
    • every parameter description ends "under the Low Income Energy Assistance Program";
    • every #page= anchor I opened shows its value: plan pages 9 and 11, and manual pages 1725-1728, 1749, 1754-1755, 1772-1773 and 1777, and 1726-1729, 1752, 1757-1758, 1775-1776 and 1779;
    • the changelog fragment is top-level added;
    • no partner test file is touched.

Hand-checked expectations (15):

Case Arithmetic Expected
wv_lieap 1 Size 1, row 0, base 160: x 1.75 = 280; x 1.198 = 191.68; x 1.089 = 174.24; SOLAR and OTHER have bills but factor 0; UNSPECIFIED and NONE have no bill 280, 191.68, 174.24 x 5, 0 x 4 ✓
wv_lieap 2 24,924 / 12 = 2,077 is row 0 (280); 2,077.25, 2,077.50, 2,078 and 2,454 are row 1 (155 x 1.75 = 271.25); 29,448.12 is above 29,448 280, 271.25 x 4, 0 ✓
wv_lieap 4 FY2027, size 3: 3,400 is above 3,335, so row 4 and base 150, x 1.089 = 163.35; 3,430 is above 3,427, so row 5 and base 145, 157.905, rounded 157.91 163.35, 157.91 ✓
wv_lieap 5 Size 11: 8,477 is row 20, base 110 x 1.75 = 192.50; 8,480 is row 21, base 105, 183.75; limit 1.5 x 70,650 / 12 = 8,831.25, rounded 8,831 192.5, 183.75 ✓
wv_lieap 6 Size 5: 5,300 is row 9, base 160 + 5 x (4 - 9) = 135; 135 x 1.089 = 147.015, rounded 147.02 147.02 ✓
wv_lieap 7 Size 20 at 15,019 is row 38, base 65, 70.785, rounded 70.79; size 21 is above the table 70.79, 0 ✓
wv_lieap 10 Size 1 (the noncitizen is not counted); 24,000 / 12 = 2,000 is row 0, 280; limit 29,448 1; 29,448; 280 ✓
income_limit 1 floor(0.6 x 94,396) = 56,637; x .52/.68/.84/1/1.16/1.32/1.35, floored, / 12, rounded: 2,454, 3,209, 3,965, 4,720, 5,475, 6,230, 6,372; 1.5 x 2025 guideline / 12: 6,768.75, 7,456.25, 8,143.75, 8,831.25, rounded 29,448 … 105,972 ✓ (the head's arithmetic; see C1)
income_limit 2 floor(0.6 x 98,088) = 58,852, giving 2,550, 3,335, 4,120, 4,904, 5,689, 6,474, 6,621; 1.5 x (15,960 + 5,680(n-1)) / 12 = 6,965, 7,675, 8,385, 9,095 30,600 … 109,140 ✓ (see C1)
income_eligible 4 $36,000 against 29,448 (one qualified member) and 38,508 (two) false, true ✓
countable 2 2,400 + 300 + 600 + 700 + 400 + 900 + 300 + 300 + 800 + 1,000 + 900 + 1,100 + 1,200 + 1,300 12,200 ✓
countable 3 Pensions 3,700 + distributions 6,640 + survivor 500; RSDI excluded 10,840 ✓
countable 12 12,000 + modeled UI 6,000; 12,000 + 1,200; 12,000 + max(-100, 0) 18,000; 13,200; 12,000 ✓
countable 14 WV WORKS size-2 payment standard $480 x 12 = 5,760 for the participant; 0 for the nonparticipant 5,760; 0 ✓
countable 15 Railroad 20,000 counts; RSDI 6,000 excluded 20,000 ✓

Axiom line assessment

axiom: TheAxiomFoundation/rulespec-us#1998 queued.

State of the issue. The issue is OPEN, labelled pe-parity, and was updated 2026-11-02 17:01 UTC.

  • Dispatch-ready. It gives module paths and corpus citations, and quotes the manual, plan, IM 2025-02/2026-01 and Federal Register text verbatim. It sets required outputs for all five variables and 16 companion tests drawn from the manual, the SMI tables and the guidelines.
  • Matches the head. It names 22c87de9d1, and the PR's own files are identical at fcdbc7f779, which only merges main. Its 25 sources, 40 cases and payment formula match.

Updates needed with the fixes:

  • C1: the cap, a statute interpretation, and companion cases at the printed limits. Interpretation 7 currently accepts the rounded figures.
  • S1: military_basic_pay, giving 26 sources.
  • G2: the FY2027 plan, including item 1.4 "No".
  • G3: the agency page and fact sheet now print $6,965.

CI status

gh pr checks 10618 at head fcdbc7f779 (run 41500846205, pull_request, started 2026-11-02 18:28 UTC; it includes main through 4bfc548de3). I re-checked it at the end of this review: 36 pass, none pending or failing.

Coverage includes:

  • all Baseline shards, including the four state shards that run the West Virginia YAML;
  • all Contrib shards;
  • Rest Python shards 1-7 and Microsimulation;
  • Household API Partners, PR validation, Package and compatibility, and Quick Feedback;
  • Codecov (patch and project).

Branch status

Verdict: REQUEST_CHANGES

@DTrim99 DTrim99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Requesting changes: 1 critical (rounding the monthly limits up puts them above the 42 USC 8624(b)(2)(B) ceiling at several sizes in FY2026 and FY2027; cap at the federal maximum as in North Dakota #10342), 2 should (military basic pay not counted; the zero-size limit guard is untested). Full report in the comment above.

hua7450 and others added 2 commits November 3, 2026 16:44
- Stop a monthly limit that rounds up at the federal ceiling in
  42 U.S.C. 8624(b)(2)(B).
- Count military_basic_pay and pin the zero-size limit.
- Cite the FY2027 plan on the limit rates.
- Record four source choices in the source-conflict candidates.

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

hua7450 commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks, David. b90a7e0726 handles your findings except G4, and merges main at 6145ad4513. I didn't run the tests locally, so CI is the first run of these changes.

Finding Result What changed
C1 federal ceiling Applied wv_lieap_income_limit is now min_(rounded monthly x 12, annual). wv_lieap.yaml Cases 11 and 12 pin your three examples with a passing amount beside each, limit expectations are updated, and us-wv:liheap-income-limit-above-federal-ceiling records it with follows: statute. This also settles the +$688 question.
S1 military basic pay Applied military_basic_pay follows employment_income, making 26 sources. Countable income Case 2 gives $12,700.
S2 zero-size guard Applied by pinning wv_lieap_income_eligible.yaml Case 1 now asserts the zero limit, and the guard stays.
G1 source choices Applied Added us-wv:liheap-plan-categorical-eligibility and us-wv:liheap-plan-income-and-benefit-items, both ruled, and us-wv:liheap-veterans-benefits, unreviewed because the manual-over-plan ruling doesn't cover an agency announcement.
G2 FY2027 plan Applied Cited on smi_rate, fpg_rate, smi_max_household_size and the limit variable, and in the PR body and the Axiom issue.
G3 housekeeping Applied The limit comment and test header are reworded. The body and TheAxiomFoundation/rulespec-us#1998 now give $6,965 for eight; I rechecked the agency page and fact sheet on 2026-11-03. The test plan now says CI passed the 40 earlier cases at fcdbc7f779.
G4 floor the base Declined Your review confirms that no baseline path reaches a blank cell in either verified year. Only a reform of smi_rate or fpg_rate, or a later carried-forward year, gets there. No baseline YAML case could pin the floor, so it would be the kind of unpinned guard S2 flags. I narrowed the wv_lieap.py comment to "In both verified years" so it no longer overstates the claim.

On C1, I capped at the state's own unrounded amount instead of your max(liheap_smi_limit, fpg_limit x guideline) expression. By hand, the two match at every size from 1 to 20 in both years, so the numbers are the same and the formula reads no new parameters. They differ only under a reform of West Virginia's own rates, where the cap follows the reformed rate. The cap binds at FY2026 sizes 3, 4, 5, 7 and even sizes 8-20, and at FY2027 sizes 2, 3, 6 and 7, matching your table.

wv_lieap.yaml Case 7 sat at the printed $180,228, so it moved to $180,225; the payment is still $70.79. As in South Carolina, none of the four candidates has a # Source conflict marker until it is registered.

@hua7450
hua7450 requested a review from DTrim99 November 3, 2026 21:53

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 West Virginia LIEAP regular heating assistance

2 participants