Repository navigation
Add Wyoming LIHEAP regular heating assistance - #10346
Conversation
One added changelog fragment for the new program and a one- or two-sentence programs.yaml note; limitations stay in code comments and the PR body. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # policyengine_us/programs.yaml
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10346 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 4 6 +2
Lines 76 121 +45
Branches 2 2
=========================================
+ Hits 76 121 +45
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
PR Review: Add Wyoming LIHEAP regular heating assistancePR #10346 (author: hua7450), head
The PR has no reviews and no comments apart from Codecov. It touches no partner test file. Path prefixes:
Sources read for this review:
SummaryWhat is right. Most of the program is encoded carefully:
There are two critical findings:
There are five should-address items:
There are also six suggestions:
Status.
Critical (must fix)C1. The entitlement-band edges contradict the printed Table 1 at every printed band start, and 30 test expectations pin the wrong amounts
C2. A single floor puts the FY2026 limits for sizes 8-11 $1 above HHS's mandatory figures, and a test pins the wrong value
Should addressS1.
|
| Test | Hand computation | Expected |
|---|---|---|
wy_lieap Case 1 (coal, ratio 0) |
525 × .8 = 420 − ROUND(42) | 378 |
wy_lieap Case 2 (coal, .25) |
393.75 − ROUND(39.375) = 393.75 − 39 | 354.75 |
wy_lieap Case 15 (coal, .95) |
52.5 − ROUND(5.25) | 47.5 |
wy_lieap Case 17 (oil, 0) |
2,112 − 211 | 1,901 |
wy_lieap Case 25 (oil, .60) |
1,056 − ROUND(105.6) = 1,056 − 106 | 950 |
wy_lieap Cases 33-47 (electricity) |
1,712.997 × f − ROUND(0.1 × base), all 15 recomputed (e.g. .80: 1,370.3976 − 137) | 1,233.3976 ... 154.2997 |
wy_lieap Cases 49-63 (gas) |
1,550.85 × f − ROUND(0.1 × base), all 15 recomputed (e.g. .15: 232.6275 − 23) | 1,116.68 ... 139.085 |
wy_lieap Case 66 (propane, .75) |
975 − ROUND(97.5) = 975 − 98 | 877 |
wy_lieap Case 82 (wood, .75) |
918.75 − ROUND(91.875) = 918.75 − 92 | 826.75 |
wy_lieap Case 97 (oil, exactly .21) |
head band .80; Table 1 row .21-.25 gives 1,782 (C1) | 1,901 |
wy_lieap Case 125 (oil, exactly 1.00) |
head band .10; Table 1 "1.00 +" gives 0 (C1) | 238 |
wy_lieap Case 129 |
adjusted 1,901 ≥ 10, then min(1,901, 9) | 9 |
wy_lieap Case 143 |
12,000 − 2,400 = 9,600 (minor, POWER and support received excluded); 9,600 / 46,853 = .2049, .80 | 1,901 |
wy_lieap Case 144 |
60,000 − 21,150 = 38,850; .8292, .15; 232.6275 − 23 | 209.6275 |
wy_lieap Case 145 |
size 1 (citizen child); 20,000 / 35,829 = .5582, .45; 236.25 − 24 | 212.25 |
wy_lieap Case 146 |
372 (> 360) + 200 + 0 (gifts at 360) = 572; electricity 1,233.3976 capped at the bill | 1,000 |
wy_lieap Case 147 |
[209.6275; size 0; propane 936 passes the cutoff, capped at 9; CO] | [209.6275, 0, 9, 0] |
wy_lieap Case 151 |
guideline 15,650 + 16 × 5,500 = 103,650; floor 114,015; limit 68,902 × 1.65 = 113,688; 113,900 / 114,015 = .999, .10 | [238, 0] |
wy_lieap Case 152 |
36,000 > 35,829 and > 17,215 | 0 |
wy_lieap Case 154 |
37,000 − 202.90 × 12 = 34,565.20; .9647, .10; 155.085 − 16 | 139.085 |
| income limit Cases 2-7 | 114,837 × {.312, .408, .504, .600, .696, .792}, floored | 35,829 ... 90,950 |
| income limit Case 8 | 68,902 × 1.35 = 93,017.7 (HHS $93,017) | 93,017 |
| income limit Case 9 | HHS $95,084 (C2) | 95,085 |
| income limit Cases 10-14 (2027) | floor(114,932 × .6) = 68,959 × {.52 ... 1.16} = handout | 35,858 ... 79,992 |
| countable Case 17 | 1,000 + 500 + 2,000 + 3,000 + 400 + 300 + 2,000 + 100 + 800 + 900 + 700 + 200 | 11,900 |
| countable Cases 13 and 18 | 30,000 − 15,650; 60,000 − 21,150 | 14,350; 38,850 |
Batch checks:
- 1. Plan and matrix.
- Matrix. All 96 visible Table 1 cells reconcile with the workbook formulas.
- Limits. The 60% of SMI table matches for sizes 1-6, and the handout matches for 2027 sizes 1-5. See C2 for sizes 8-11.
- Timing. The component runs October 1, 2025 to September 30, 2026 (plan 1.1 and SF-424 p. 2), and the parameters start on 2025-10-01.
- Registry.
verified_years: "2026"is backed by the FY2026 matrix and SMI table.
- 2. Income.
- Gross. The plan checks gross income (1.8). The rules define earned income as "total before deductions" (3(w)), so Document disjoint health premium inputs and correct consumer treatment #10046 premiums are rightly not deducted.
- Social Security. It is counted net of the computed Part B premium, which matches "Medicare deducted from SSA" (8(a)(ii)(U)) and plan 1.9 "Excluding MediCare deduction".
- Part A. Premium Part A is rarely withheld from Social Security, because beneficiaries usually have premium-free Part A. Leaving it out matches the Iowa precedent for check-withheld rules.
- RRB. For railroad annuitants the Part B premium comes out of the RRB check, which the rule ("from SSA") does not exempt.
- Losses. They are floored per source and per person, and support paid is floored against the payer's earnings.
- Period. Annual amounts stand in for monthly amounts, as documented.
- 3. Backdating. Only 2026 is claimed. 2027 and earlier years are documented as estimates (G4).
- 4. Arrangements.
- Eligibility rules. There is no categorical eligibility (plan 1.4 "No") and no asset test (2.3 "No").
- Renters. Subsidized renters are unaffected (10(e)), which Case 140 pins. Heat in rent is covered in S2.
- NONE and UNSPECIFIED.
NONEis not vulnerable.UNSPECIFIEDpays $0, which the wave accepts. - The $10 cutoff. It is applied before the cost cap (Cases 129-131 pin the order). It cannot bind in FY2026, because the smallest scheduled award is $47.50.
- 5. Tests. Periods are plain. The exact limit (eligibility Cases 1-2), the floor on both sides, sizes 0-8, mixed states (Cases 142 and 147) and cent-level ceilings are covered.
- 6. Descriptions. All 12 follow the house template with the state's program name, as South Dakota's LIEAP does.
- 7. References. Plan anchors p. 2 (funding period), p. 5 (1.9), p. 6 (SSA/Medicare and minor boxes), p. 8 (2.1) and p. 38 (17.3) show their values. The statute's
#page 34-35title is well formed. See S4 for the rules links. - 8. Wiring.
- Registry. The
programs.yamlblock is complete. - Aggregate. No merged LIHEAP state feeds a household aggregate, so none is needed.
- Gating. All variables are gated by
StateCode.WYorwy_lieap_eligible.
- Registry. The
- 11, Integrate modeled state unemployment insurance into income flows #9558. The list reads
total_unemployment_compensation, and no Python reads the raw input. - 12. IIJA. There is no supplement.
- 13. Mutation. See S3 and C1. Every other branch is pinned: the floor denominator (Case 151 would pay $0 with the SMI denominator), the age cut, the thresholds and the veterans exclusion.
- 14. Health premiums. None are deducted, which is right for the gross rule.
- 15, NH Add New Hampshire state supplementation for 2026 #10156. Nothing state-gated is used as a key:
wy_lieap_household_sizeis used only arithmetically (fpg(max_(size, 1)),smi(size)).p.fuel_cost[heating_type]has all 11HeatingTypekeys.- Case 147 runs Wyoming and Colorado units together.
- 16, Wire military retirement pay and survivors into federal and state tax (#10181) #10182 / Count military SBP annuities in state benefit income lists #10317.
military_retirement_incomeis used (Cases 152-153). - 17. State SSP.
wy_sspis exempt under 8(a)(ii)(U), so omitting it is right (G2). - Count each Social Security benefit once in Pennsylvania CCW countable income #10408 pattern.
social_securityis read once, in Python, and no list names a component.survivor_benefits("other than Social Security") anddisability_benefitsare non-SSA inputs. - Federal floor. 42 U.S.C. 8624(b)(2)(B) is applied with the 2025 guideline and a strict "less than".
- Changelog.
changelog.d/wy-liheap-wave2b.added.mdis a top-level fragment. - Local runs. None. CI ran all five Wyoming YAML files green in the baseline state shards at this head, and the findings above rest on hand traces and source arithmetic.
Axiom line assessment
axiom: TheAxiomFoundation/rulespec-us#1906 queued is valid.
- The issue. It is OPEN and labelled
pe-parity. It is dispatch-ready: module paths, corpus citations and status, verbatim rule, plan, statute and matrix text, required outputs, and companion tests derived from the workbook and sources. - The blocker. The rules, workbook, SMI tables, handout and memo are missing from the corpus; the signed release has not been checked; there is no reviewed oracle revision; and billed runs need approval.
- The match. It describes head
5c968f998band the 198 cases (154/22/14/5/3), withtotal_unemployment_compensationandmilitary_retirement_incomein the lists. - After the fixes, refresh:
- interpretation 1, companion test 4 and the benefit row (C1);
- interpretation 5 and the limit row (C2);
- interpretation 9 (S1);
- interpretation 12 (S2);
- the new companion tests (S3);
- interpretation 4 (S5);
- interpretation 13 (G2);
- the head SHA and case counts.
CI status
gh pr checks 10346 at head 5c968f998b, re-checked at the end of this review: 33 pass, 3 skipping (the superseded run 40055719714) and 1 failure.
- The failure. "Contrib tests / Full Suite - Contrib (states-shard-1)" failed after 50m1s (run 40056568351, job 120765973202).
- The job's annotation reads: "The hosted runner lost communication with the server". The test step has no conclusion, and the log was never uploaded.
- The job timeout is 60 minutes, so this was not a timeout. It is an infrastructure failure (a lost runner, possibly starved).
- The PR adds no contrib tests or reforms. The same shard passed on sibling runs, for example Add Tennessee LIHEAP regular energy assistance #10430's run 40032551559.
- This is not a finding. Re-run the job.
- Coverage. All other baseline and contrib shards, the guard tests, the partner suite, microsimulation, Python shards and Codecov pass.
Branch status
-
Distance. 9 commits ahead of
main(including two merges ofmain, the last at5c968f998b) and 57 behind currentmain. GitHub reportsCONFLICTING. -
Merge check.
git merge-tree --write-tree PolicyEngine/main 5c968f998breports two conflicted files:programs.yaml: the LIHEAPcoverage:line, wheremainadded AZ, IA and VA, and the WY block, which sits next tomain's new VA block. Keep both and add WY tomain's line. This PR does touch the coverage line.source_conflicts/candidates.yaml: the WY CCAP note thatmainrewrote (Point the NM-WY source-conflict candidates at their code on main #10352) sits next to the two new WY LIEAP candidates. Keepmain's note and the PR's entries (G6).
Both are sibling and
mainadjacency conflicts, so this is a branch note only. -
Guards on the merged tree:
- Tie source-conflict markers to the register shared with Axiom #10287 ratchet. No added comment in the PR's parameter or variable files matches the conflict-comment pattern.
- Integrate modeled state unemployment insurance into income flows #9558 and Count military SBP annuities in state benefit income lists #10317. Both guards pass.
- Count each Social Security benefit once in Pennsylvania CCW countable income #10408 pattern. No component double count.
- Inputs. Nothing the PR reads (
heating_expense,medicare_part_b_premium,social_security, the SMI and guideline parameters) changed onmainin a way that affects the 2026 tests. The guideline-uprating change (Uprate poverty guidelines over the 9902(2) interval and fix the Trustees wage base #10453) affects only unpublished years.
Verdict: REQUEST_CHANGES
DTrim99
left a comment
There was a problem hiding this comment.
Requesting changes: 2 critical (benefit-band edges contradict Table 1 at every printed band start; FY2026 income limits for sizes 8-11 are $1 above HHS's figures), 5 should. Full report in the comment above.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # policyengine_us/programs.yaml # source_conflicts/candidates.yaml
|
Thanks for the review, David. The fixes are in 5403e87, and 459fa26 merges current main.
The PR body and TheAxiomFoundation/rulespec-us#1906 are updated for 459fa26. I did not run the tests locally, so CI will check them. |
PR Review (round 2): Add Wyoming LIHEAP regular heating assistancePR #10346 (author: hua7450), head
The author's reply addresses every item. The PR now has 203 YAML cases ( Path prefixes:
SummaryAll 13 prior findings are resolved. Every critical and should fix is pinned by a test that fails without it:
No new critical or should findings. I hand-checked every new or changed expectation (32 values), and all of them match. The fix commit opens no unpinned branch and adds no comment that trips the #10287 ratchet. Merge resolutions. Both hand-resolved blocks are correct:
Two suggestions remain:
Status.
Prior findings
New findingsCriticalNone. Should addressNone. SuggestionsN1. The new plan-versus-rules candidate is
N2. Stale "not run" lines.
VerifiedHand-checked new and changed expectations (all match the head):
The renamed cases (98-126 even, 148 and 150) keep their round-1 values, and those values are right under the new rule: a cent below a start stays in the preceding row, and a cent above stays in the row. The candidate examples ($238 at size 17; $34,000 within $35,829) and the body's opening example ($9,600 / $46,853 = .205, so .80 and $1,901) are consistent with the head. Regression and new-branch checks:
Batch checks (unchanged from round 1 unless noted):
Axiom
CI status
Branch
Verdict: APPROVE |
DTrim99
left a comment
There was a problem hiding this comment.
Approving round 2: 0 critical, 0 should. Both criticals and all five shoulds are fixed and pinned. Full report in the comment above.
# Conflicts: # policyengine_us/programs.yaml
Adds Wyoming's Low Income Energy Assistance Program (LIEAP) regular heating benefit for FY2026. The model counts U.S. citizens and qualified noncitizens for household size, counts the earnings of members 18 and over less child support paid plus all members' unearned income, with Social Security net of the Medicare Part B premium, tests the total against 60% of state median income (SMI) with the federal protection for income below 110% of the poverty guideline, and pays a share of the FY2026 fuel cost standard for the household's primary heating fuel. The share falls from 80% to 10% as income approaches the limit and is zero at the limit; the model withholds 10% of that amount, rounded to whole dollars, pays nothing when the remainder is below $10 and otherwise pays the remainder up to the heating bill, or the whole remainder when heat is included in rent and no bill is reported. In FY2026, a two-person household with a 40-year-old who earns $12,000 and pays $2,400 of child support and a 17-year-old who is not a full-time student and earns $6,000, heating with fuel oil that costs $3,000 for the season, receives $1,901: the 17-year-old's wages, $3,000 of child support received and $6,000 of POWER cash assistance (Wyoming's TANF program) are excluded, so countable income is $12,000 - $2,400 = $9,600; against the two-person limit of $46,853 (60% of SMI, rounded down), $9,600 / $46,853 = 0.205 falls in the "0 - .20" row of the benefit table, below the 0.21 start of the next row, which pays 80% of the $2,640 fuel oil standard, $2,112; and $2,112 - $211 holdback (10% of $2,112, rounded) = $1,901, below the $3,000 bill.
Fixes #10340
Regulatory authority
Eligibility
defined_for = StateCode.WY; winter presence is not observedwy_lieap_household_sizeaddsis_citizen_or_legal_immigrantover the SPM unit, a modeling assumption. Other members' income still counts with no further proration, and a unit with no counted member is ineligible.wy_lieap_income_limitcalls the sharedliheap_smi_limithelper, which rounds 60% of the four-person SMI down to whole dollars ($68,902 in FY2026), multiplies it by the size percentage and rounds down again. HHS states the order of these steps but not the rounding. The tests pin the HHS FY2026 amounts for one to eight and ten people ($35,829 to $95,084, and $99,218) and the 2026-2027 handout limits for one to five. Income equal to the limit qualifies.wy_lieap_eligiblealso accepts income strictly below 110% ofwy_lieap_fpg, the poverty guideline with a one-year lag (the 2025 guideline for FY2026) at the counted size, rounded to cents, reusinggov.hhs.liheap.fpg_floor. In FY2026 the floor exceeds the SMI limit only for 17 or more counted members: 110% x $103,650 = $114,015 against $113,688. The model follows the statute;source_conflicts/candidates.yamllists this asus-wy:lieap-income-floor-vs-smi-limit.heating_expenseabove zero for the primaryheating_type, orheat_expense_included_in_rent. Rule 8(b)(i)(B) makes a household vulnerable when its rent includes a prorated heating cost, and rule 3(kk) allows the energy purchase to be in the form of rent.receives_housing_assistancedoes not change the award. A household whose heat is included in rent and that reports no heating bill receives the standard formula for its fuel, with no cost cap (see Benefit).heating_typeNONE and UNSPECIFIED have a $0 standard and pay nothing; callers must sendheating_type(#9754).Countable income
child_support_expenseis subtracted from the payer's own earnings, floored at zero, never from unearned income or another member's earnings. The input does not show whether the support is court ordered or paid monthly.military_retirement_income), retirement distributions, railroad retirement, survivor benefits other than Social Security, unemployment compensation (total_unemployment_compensation), workers' compensation, disability benefits, general assistance, alimony, rental and farm rental income, estate and trust income and ordinary dividends, each floored at zerosocial_securityless that person's computedmedicare_part_b_premium, floored at zero, so a premium larger than the benefit does not reduce other income. The premium is zero for a person not enrolled in Part B and excludes any share a Medicare Savings Program pays.financial_assistancecounted in full when above $30 a month ($360 a year)veterans_benefitsacross the SPM unit, less one exclusion equal to 100% of the household-size poverty guideline (the 2025 guideline in FY2026). Only the excess counts, and an unused exclusion does not offset other income. Total VA income stands in for service-connected disability benefits.wy_ssp, Wyoming's $20 monthly State Supplemental Payment, which rule 8(a)(ii)(U) exempts as "The optional State Medicaid Supplement Benefit" (M1804 ties the payment to federal Medicaid match)Benefit
heating_expensereads a kerosene bill asfuel_oil_expense. Solar takes the electricity standard, becauseheating_expensereads a solar home's bill as its electricity bill. Other fuels take the wood standard, the closest published worksheet. NONE and UNSPECIFIED pay $0.=ROUND(D22*0.1,0)on the Heating Oil worksheet). The award keeps the workbook's unrounded remainder, for example $1,712.997 x 0.80 = $1,370.3976 less $137 = $1,233.3976 for electricity. The hidden 5% and 15% holdback tables on the coal, heating oil, propane and wood worksheets are not used, and the model does not release the holdback.heating_expensewhen the household reports a bill, so a primary fuel cost below $10 is paid in full. A household whose heat is included in rent and that reports no bill receives the payable amount uncapped, because rule 10(e) pays renters on the standard benefit formula: a single adult with $20,000 of wages whose gas heat is included in rent receives $1,550.85 x 0.45 = $697.8825 less the $70 holdback, $627.8825.Years covered
The registry entry records
verified_years: "2026". FY2027 benefits are not modeled. For model year 2027, the income limits match the 2026-2027 handout for one to five people ($35,858 for one person), but the model applies the FY2026 fuel standards and fractions. The FY2027 draft plan (section 2.6, page 9) estimates benefits from $50 to $2,252, against $48 to $1,901 for FY2026, and no FY2027 benefit matrix is posted on the LIHEAP Clearinghouse. Model-year 2027 awards are therefore unverified estimates; the draft's maximum is $351 (18%) above the FY2026 maximum. Years before 2026 are also unverified estimates.Not modeled and source conflicts
veterans_benefits. Section 8(a)(ii)(S) exempts service-connected disability benefits, including dependent and spouse benefits, up to 100% of poverty and does not say how to divide the exclusion among several recipients. The proxy also exempts other VA income up to the guideline, which can understate countable income.source_conflicts/candidates.yamlrecords these five choices asus-wy:lieap-plan-vs-rules-income-items(state: open).source_conflicts/candidates.yamllists this reading asus-wy:lieap-income-limit-statute-lesser-of, withfollows: statute.heating_expense, which restores the cap.wy_lieap_countable_incomedirectly when these adjustments are known.Test plan
policyengine_us/tests/policy/baseline/gov/states/wy/dfs/lieap/(wy_lieap.yaml156,wy_lieap_countable_income.yaml24,wy_lieap_income_limit.yaml15,wy_lieap_eligible.yaml5,wy_lieap_household_size.yaml3). Cases 1 to 96 ofwy_lieap.yamlreproduce every visible Table 1 benefit on the six fuel worksheets. Cases 148 to 150 set one-person FY2026 wages a cent below, exactly at and a cent above every printed row start; in Case 149 each start takes its own row, from $1,782 at 0.21 to $0 at the $35,829 limit. The income-limit cases match the HHS FY2026 table for one to eight and ten people ($95,084 for eight, $99,218 for ten) and the 2026-2027 handout for one to five. At zero income, Cases 135 to 137 pay kerosene, solar and other fuels $1,901, $1,233.3976 and $882 on the fuel oil, electricity and wood standards. Case 155 pays a single adult with $20,000 of wages and a $1,500 kerosene bill $1,069 (0.45 of the $2,640 standard, less $119), and Case 156 pays the same adult $627.8825 when gas heat is included in rent and no bill is reported. Countable-income Case 23 gives self-employment, SSTB, farm operations, partnership or S corporation, workers' compensation, disability and estate income distinct amounts ($11,800 in total), and Case 24 shows that a $2,434.80 Part B premium above $1,000 of Social Security leaves $10,000 of wages counted in full.wy_lieap.yamlCase 153 counts a $40,000 military Survivor Benefit Plan annuity, above the $35,829 one-person limit. Case 154 counts $37,000 of Social Security less the $2,434.80 Part B premium ($202.90 x 12), $34,565.20, which is within the $35,829 limit and above 0.86 of it, so it pays 10% of the $1,550.85 natural gas standard: $155.085 - $16 holdback = $139.085. The other expected values are hand computed; mostwy_lieap.yamlcases show the arithmetic in a comment. CI passed the five Wyoming files at5c968f998b; the review fixes in 5403e87 were not run locally, and CI runs the full suite.# Source conflict <jurisdiction>:<id>marker: pending.source_conflicts/candidates.yamlrecords three backlog items: the W.S. 42-2-501(c) reading (us-wy:lieap-income-limit-statute-lesser-of) and the federal-floor reading (us-wy:lieap-income-floor-vs-smi-limit), bothfollows: statuteand unreviewed, and the plan-versus-rules income choices (us-wy:lieap-plan-vs-rules-income-items,state: open). This PR adds no rulespec-us register entry and no marker yet.make formatchangelog.d/axiom: TheAxiomFoundation/rulespec-us#1906 queued
🤖 Generated with Claude Code