Skip to content

Add Nebraska LIHEAP regular heating assistance - #9723

Open
hua7450 wants to merge 11 commits into
PolicyEngine:mainfrom
hua7450:ne-liheap
Open

hua7450 wants to merge 11 commits into
PolicyEngine:mainfrom
hua7450:ne-liheap

Conversation

@hua7450

@hua7450 hua7450 commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Adds partial FY2026 regular heating assistance for Nebraska. The annual result represents the heating season ending in the modeled year. For example, a single-person household with $18,000 in wages and a gas heating bill passes the $23,475 gross-income limit, then receives a $550 single-family payment after the 20% earned-income disregard.

Merged shared FPG helper PR #9731 is now included from main. This state calls that helper for lagged guidelines; rates, household-size caps, and rounding remain in state code. The helper and Massachusetts refactor are no longer part of this PR’s diff.

Year convention: undated formulas follow the model’s existing parameter backfilling, consistent with Kansas. Earlier years use the earliest available state schedule with period-specific federal guidelines and the state’s guideline lag where applicable; these are unverified historical estimates. The registry records verified_years: "2026"; backfilling does not extend verified coverage. Dated formulas are reserved for sourced policy changes.

  • Uses 150% of the shared 2025 federal poverty guidelines for FY2026, reproducing Nebraska's published annual limits without Kansas's monthly rounding. Payment income bands stop growing at six people; eligibility limits continue growing.
  • Reuses existing heating/fuel inputs, SNAP income-source parameters, child-earner exclusions, and immigration-status eligibility. Existing net self-employment income, including sstb_self_employment_income and farm_operations_income, is counted without another business-expense deduction; each earned source is floored at zero. Adds only the authorized state-specific ne_liheap_dwelling_type input.
  • Covers the four single-family payment columns and the multifamily all-fuel column, including their exact income boundaries. SINGLE_FAMILY and MULTI_FAMILY follow 476 NAC 1-004.16 and 1-004.11; multifamily includes apartments with separate bills and communal arrangements with shared bills. If dwelling type is omitted, the model retains its single-family fallback, so callers should report the actual type. Registers the state as partial. No federal benefit aggregate is changed.

Household and immigration basis

476 NAC 1-004.09 defines the household by shared residential energy purchasing; the SPM unit approximates that economic unit. Under 476 NAC 2-002.02, a member failing the incorporated citizenship/residency requirements “must be excluded from a household.” Section 2-002.01 separately incorporates SNAP income treatment. 476 NAC chapter 1 (12-26-2020), pages 1–2 and chapter 2 (06-26-2022), page 1

This state's SNAP cross-reference is explicit. Nebraska DHHS's OBBBA FAQ, Q12, says LIHEAP “follows the SNAP rules regarding citizenship eligibility, per 476 NAC 2.002.02.” The model therefore retains the SNAP immigration-status variable, including its FY2026 exclusion of refugee/asylee status alone; it does not apply SNAP work or student eligibility tests. Since the merge of main, the shared variable also applies the SNAP qualified-alien waiting period and its exceptions; COFA status and case-specific recertification timing remain limitations, not verified eligibility determinations. DHHS OBBBA FAQ, Q12, page 3

475 NAC 3-002.06(A) states: “The pro rata share is calculated by dividing the countable income evenly among the household members, including the ineligible member.” Subsection (B) excludes that member from benefit/income-test size. The model retains eligible members' income in full and counts each excluded member's income times eligible size / total size. This applies to both earnings and unearned income; unit-level receipts lack a payer-level allocation. 475 NAC chapter 3, section 002.06(A)–(B), text in effect for FY2026, pages 47–48

Economic-vulnerability modeling assumption: Economic vulnerability under 476 NAC 1-004.06 and 2-002(A) is assumed for all households rather than separately verified. Heating responsibility is satisfied by positive heating expenses, or by heat included in rent for households outside subsidized housing. Therefore, an otherwise eligible market-rate renter with heat_expense_included_in_rent: true and heating_expense: 0 receives the scheduled benefit. For example, a one-person multifamily household with $18,000 of wages receives $300 after the earned-income disregard. A household in subsidized housing (receives_housing_assistance or is_in_public_housing) needs a positive heating expense, because FY2026 plan Section 2.3 (page 9) conditions those renters on being responsible for part of the heating; with heat in rent and no separate heating cost it is ineligible. Section 2.3 also says renters with utilities included in the rent must be responsible for a portion of the heating; the model treats market-rate heat-in-rent renters as responsible, resting on 476 NAC 3-002.02 (12-26-2020), page 1, which lets DHHS pay a household directly only if utilities are included in rent, and on plan sections 1.1 (page 5) and 9.1 (page 25), which list such households among those paid directly. The income test still applies; a household reporting neither heating expenses nor heat in rent remains ineligible. The market-rate treatment is a modeling assumption, not a claim that Nebraska waives its legal vulnerability requirement. No new input or actual-expense cap is added. The legal household definition includes energy paid through rent.

Other limitations: Corn shares the natural-gas/electricity/coal payment column, as documented in code; no separate schedule or fuel input is added. The existing fuel enum cannot distinguish corn within OTHER, so unsupported/unspecified single-family fuel values still return zero, including for an eligible heat-in-rent renter who reports neither fuel nor dwelling type; no fallback fuel is assumed. Multifamily uses the published all-fuel column. Code comments also record the SPM-unit and annual-income approximations, detailed immigration and disqualification gaps, business-record deduction alternatives, special farm-loss offsets requiring gross-receipts and tax-return evidence, and unverified discretionary heating supplements. These are coverage gaps, not new legal eligibility restrictions.

Heating only. Cooling, crisis assistance, weatherization, and equipment assistance are excluded.

Sources (original official publications):

Validation: 77 Nebraska YAML cases cover every modeled payment cell, dwelling and fuel treatment, income boundaries, the six-person band cap, household proration, farm and business income, historical backfilling, and mixed-state calculations. The first review-fix commit (39cd98794a) repointed the state-plan and 475/476 NAC citations to edition-pinned copies, quoted both section 2.3 sentences, and added the market-rate heat-in-rent and seven-person boundary cases. The second gives every multi-page reference a single page in the link with the pages named beside it, cites 476 NAC 3-002.02 and the 2025 poverty guideline notice directly, inlines the YAML anchors in the integration file, moves the earned income sources into a list parameter, notes that later years carry the FY2026 amounts forward, and places Nebraska alphabetically in the registry; it changes no value or formula. CI validates the current head.

Microsimulation: the datasets carry no heating type and no fuel bills, and eligibility needs a heating bill, so population totals are $0 until both are in the microdata. The default heating type is tracked separately in #9754; callers must send heating_type with the matching fuel bill.

axiom: TheAxiomFoundation/rulespec-us#1464 queued

@codecov

codecov Bot commented Sep 30, 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 (72c88ea).
⚠️ Report is 131 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #9723   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         8    +4     
  Lines           76       135   +59     
  Branches         2         1    -1     
=========================================
+ Hits            76       135   +59     
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 5 commits September 30, 2026 19:59
…bility

- Count sstb_self_employment_income in earned income, floored at zero per source
- Require a positive heating expense for subsidized-housing households with heat
  in rent (plan section 2.3); market-rate renters stay eligible
- State plainly that an unspecified single-family fuel is paid $0
- Add tests for SSTB income, subsidized heat-in-rent households, proration with
  TANF and the refugee/asylee household-size exclusion; send heating_type
  explicitly in every eligibility or payment case

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@hua7450
hua7450 marked this pull request as ready for review October 1, 2026 19:12
@hua7450
hua7450 requested a review from DTrim99 October 1, 2026 19:12
@DTrim99

DTrim99 commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator

Program Review

PR #9723: Nebraska LIHEAP regular heating assistance (@hua7450), head 89582437c7. The PR has 27 files: 9 parameters, 8 variables, 8 test files (75 cases), a changelog fragment and programs.yaml.

Result: 0 critical, 6 should address, 14 suggestions.

  • All 39 parameter values match the FY2026 Guidance Document.
  • The core formula follows Guidance p. 2 and 476 NAC 2-002: a 150% FPG gross test on the 2025 guideline, then a 20% earned disregard applied after the gross test, right-closed tiers at 70/100/130% FPG, payment bands capped at size 6, and four single-family fuel columns plus a multifamily all-fuel column.
  • None of the findings changes an eligibility or payment outcome against an unambiguous source.

Source Documents

Branch Status

The PR branch is 10 commits behind main and 6 ahead (merge base d254a343d4). Consider rebasing before merging. The review was scoped to the PR's actual changes, and staleness did not affect findings.

  • The 10 commits on main change 52 files. None of them is among the PR's 27 files.
  • programs.yaml is unchanged on main since the merge base, and git merge-tree reports a clean merge.
  • One shared variable the PR reads has changed on main. This is informational, not a finding:
    • Apply the SNAP five-year waiting period and its exceptions to lawful permanent residents #9661 merged on 2026-10-01 at 14:08 UTC, after this PR's CI run at 05:24 UTC. It adds the SNAP qualified-alien waiting period (8 USC 1612(a)(2)(L); 7 CFR 273.4(a)(6)(iii)) to is_snap_immigration_status_eligible.
    • ne_liheap_household_size, ne_liheap_gross_income and ne_liheap_earned_income read that variable.
    • years_since_us_entry defaults to 5, so the two lawful permanent residents in ne_liheap_household_size.yaml Case 2 still count. No PR test result changes.
    • After a rebase, NE LIHEAP inherits the waiting period and its exceptions. That is consistent with 476 NAC 2-002.02 and FAQ Q12.
    • Two statements would then be out of date: the comment at ne_liheap_household_size.py:19-20 ("cannot resolve waiting periods/exceptions") and the PR body's "The shared variable does not model waiting periods and their exceptions".

Critical (Must Fix)

None.

  • All 39 parameter values match the FY2026 Guidance pp. 1-2. The 20 payment amounts were reconfirmed at 600 dpi.
  • The eligibility and payment formulas follow 476 NAC 2-002 and Guidance p. 2.
  • There are no hard-coded policy values, no TODOs and no entity mismatches.
  • Every formula variable has tests, and no test is non-functional (all absolute_error_margin values are 0.01).
  • CI passes 37/37.

Should Address

  1. The axiom parity line uses n/a for a new program.

    • Where: The last line of the PR body: axiom: n/a: rulespec-us does not have this program yet; it should be added as a follow-up.
    • Rule: CONTRIBUTING.md "Axiom parity" says every policy change must also be correct in rulespec-us, and "That covers a new program". A rulespec module that does not exist yet is the queued case.
    • What a queued issue needs: a dispatch-ready rulespec-us issue labelled pe-parity, with:
      • the module path (us-ne/...);
      • the corpus citation (476 NAC 2-002; FY2026 Guidance pp. 1-2);
      • the verbatim law;
      • the required outputs;
      • companion tests that reuse the YAML tests' external expected values.
    • Fix: Open that issue and change the line to axiom: <issue URL> queued.
    • Source: CONTRIBUTING.md#axiom-parity. The law to encode is at Guidance p. 1, Guidance p. 2 and 476 NAC 2 p. 1.
  2. The state-plan reference now serves the FFY2027 plan.

    • Where: policyengine_us/variables/gov/states/ne/dhhs/liheap/ne_liheap_eligible.py:12, ne_liheap_eligible.yaml:60, integration.yaml:253, and the PR body ("Nebraska FY2026 state plan ... pages 7, 9-10", #page=7,9,10).
    • Problem: The dhhs URL now returns the FFY2027 plan. Its p. 1 shows a report period of 10/01/2026-09/30/2027, and its p. 10 cites "Guidance Document 10.01.2026".
    • Why not critical: Section 2.3 on p. 9 states the same rule in both editions, so the reference still supports the code. Only the edition no longer matches the "FY2026" label.
    • Stable alternative: The ACF copy of the FY2026 plan has the same page numbers. The PR already cites it at ne_liheap_earned_income.py:12 and ne_liheap_gross_income.py:12.
    • Fix: Point the three references and the PR body to NE_Plan_2026.pdf p. 9, or to p. 7 and p. 10 where those pages apply.
    • Current target: FFY2027 plan p. 1.
  3. The 475 NAC 3-002.04(B)(i) citation points to text that has since been renumbered.

    • Where: ne_liheap_earned_income.py:26 (reference at :13), ne_liheap_earned_income.yaml:1-3 and integration.yaml:217-218. All link to the live viewer rules.nebraska.gov/rules?agencyId=37&titleId=230.
    • Prior text: "For each source of self-employment" was 3-002.04(B)(i) in the text effective 2024-09-17 to 2026-07-28. That text covered the FY2026 heating season.
    • Current text: In the text effective 2026-07-28, which the viewer serves, (B)(i) is "Income calculation with tax returns". Per-source treatment is now in (B)(iii), and the farm-loss offset is in (B)(iv).
    • Impact: The substance is unchanged for the PR, and 3-002.06 is unchanged.
    • Why the viewer causes this: The viewer is an 803-byte JavaScript shell. It cannot carry #page= and always serves the current text.
    • Fix: Cite the edition-pinned historical chapter PDF: 475 NAC 3 (09-17-2024) p. 44 for 3-002.04(B)(i), and p. 47 for 3-002.06. Alternatively, switch to the current (B)(iii)/(B)(iv) numbering and update the farm-offset cross-reference.
    • Related: The same viewer link at ne_liheap_gross_income.py:13 and ne_liheap_gross_income.yaml:4 (3-002.06 proration) can use the p. 47 link.
    • The repo already uses this file-API pattern in parameters/gov/states/ne/dhhs/child_care_subsidy/income/sources/earned.yaml.
  4. Heat-in-rent market-rate renters: the plan 2.3 summary is incomplete and the legal basis is not cited.

    • Where: ne_liheap_eligible.py:17-25 and :32, ne_liheap_eligible.yaml:57-59 (header for Cases 6-9), integration.yaml:251-252, and programs.yaml:840.
    • Source: FY2026 plan sec. 2.3 has both "Yes" boxes checked:
      • "For subsidized housing, the household must be responsible for a portion of the heating payment to be eligible for heating."
      • "For renters with utilities included in the rent, the household must be responsible for a portion of the heating."
    • Problem: The test comments describe 2.3 as only the subsidized rule.
    • Why the PR's treatment is defensible: The PR treats market-rate heat-in-rent renters as responsible, and documents that choice. Three sources support it, and none of them is cited:
      • 476 NAC 3-002.02: the Department may pay a household directly "if utilities are included in rent".
      • Plan 9.1 (p. 25) lists "Households whose utilities are included in rent but still meet economic vulnerability".
      • Plan 1.1 (p. 5) refers to "An economically vulnerable household's utilities are included in rent".
    • Fix:
      • (i) Quote both 2.3 sentences in the test comments.
      • (ii) Cite 476 NAC 3-002.02 and plan 9.1 and 1.1 in the comment at ne_liheap_eligible.py:17-18.
      • (iii) Add an end-to-end payment case for a market-rate, single-family, heat-in-rent household with a known fuel and a $0 bill. Example: NATURAL_GAS, gas_expense 0, heat_expense_included_in_rent true, $18,000 wages, expected $550. ne_liheap_eligible.yaml Case 9 (line 104) checks eligibility only, with UNSPECIFIED fuel, and integration.yaml Case 7 is multifamily.
    • Bias if DHHS requires every utilities-in-rent renter to show a heating portion: eligibility is overstated for market-rate heat-in-rent renters.
    • Source: FY2026 plan p. 9, p. 25 and p. 5.
  5. No test pins payment_size_limit = 6, so a cap of 5 passes every test.

    • Where: parameters/gov/states/ne/dhhs/liheap/payment_size_limit.yaml:3, ne_liheap.py:27, and ne_liheap.yaml:312 (Case 29, the only payment test above size 3).

    • Problem: Case 29 uses size 7 and $31,000. It gives Tier 2 ($580) with a cap of 6 (ratio 0.718), and also with a cap of 5 (ratio 0.823). The test catches a missing cap but not an off-by-one cap.

    • Source: The size-6+ footnote on Guidance p. 2 gives the exact cutoffs.

    • Fix: Add a vectorized case at size 7 (or 6), with no earnings and propane fuel, using these incomes:

      Income Expected Note
      30,205 $850 A cap of 5 gives 30,205 / 37,650 = 0.802, Tier 2, $580
      30,205.01 $580
      43,150 $580
      43,150.01 $330
      56,095 $330
      56,095.01 $165
    • Source: Guidance p. 2.

  6. Microsim defaults and inputs (bias direction and size). These are reported under the microsim-default rule, without prescribing a default value.

    • Dwelling-type default: ne_liheap_dwelling_type defaults to SINGLE_FAMILY (ne_liheap_dwelling_type.py:13). Multifamily households with a supported fuel therefore receive single-family amounts.
      • Bias: upward, by $11 to $670 per affected household.
      • Tier 1 pays $700-$1,050 single-family against $380 multifamily. Tier 4 pays $165-$280 against $154.
    • Heating inputs: No producer of heating_type, the per-fuel expenses or heat_expense_included_in_rent was found in the local policyengine-us-data or populace checkouts. If production microdata also lacks them:
    • Economic vulnerability: It is assumed rather than tested (ne_liheap_eligible.py:19-20).
      • Bias: upward. The sources do not allow its size to be quantified.
      • This assumption is already documented.
    • Valid remedies: (a) populate the inputs in the dataset; (b) document the microsim limitation in the programs.yaml notes or the variable documentation; (c) accept the bias if it is quantified and small.
    • Source: The single-family and multifamily columns are on Guidance p. 2.

Suggestions

  1. The size-6+ footnote says "gross countable income".

    • Where: ne_liheap.py:22 and :25-34.
    • Source conflict: The footnote on Guidance p. 2 states the size-6+ tier cutoffs in "gross countable income". The same page bases payments on "income after the disregard is applied", with no size exception, and plan 1.9 (p. 7) does the same.
    • Why the PR's reading holds: The footnote is identical on the cooling table (p. 3) and in the 07/18/2026 edition. Its Tier 4 ceiling is the gross eligibility limit.
    • Suggested action: Add a comment acknowledging the footnote.
    • Bias if DHHS applies the footnote literally: households of 6 or more with earnings are overpaid by up to one tier.
    • Source: Guidance p. 2 and FY2026 plan p. 7.
  2. SOLAR and OTHER (which includes corn) households are eligible but paid $0.

    • Where: ne_liheap.py:39-46 and :65; ne_liheap.yaml:268 (Case 25) and :279 (Case 26).
    • SOLAR: The canonical heating_expense maps SOLAR to the electricity bill. A single-family SOLAR household with an electric bill therefore passes the responsibility test but receives $0.
    • Corn: Corn is paid in the "Natural Gas / Electricity / Coal / Corn" column, but the fuel enum folds it into OTHER.
    • Both are documented limitations.
    • Suggested action: Consider mapping SOLAR to the utility column (DC LIHEAP falls back to its electricity row), and reconsider OTHER.
    • Bias: downward.
    • Source: Guidance p. 2.
  3. The proration logic is duplicated.

    • Where: ne_liheap_earned_income.py:19-25 and ne_liheap_gross_income.py:21-25 compute the same included/fraction/share.
    • Suggested action: Consider a single person-level ne_liheap_income_counted_share variable that both files read.
    • Why not reuse SNAP's helper: snap_income_counted_share also zeroes out ineligible students and uses snap_unit_size. 476 NAC 2-002.02 and 2-002.03 exclude only citizenship or residency failures and disqualifications.
    • Source: 475 NAC 3-002.06, p. 47.
  4. A local name collides with an existing variable.

    • Where: ne_liheap_eligible.py:27, has_heating_expense = spm_unit("heating_expense", period) > 0.
    • Problem: The repo variable has_heating_expense returns (bill > 0) & ~heat_in_rent. The local name has different semantics, which ne_liheap_eligible.yaml Case 8 (line 90) and integration.yaml Case 10 rely on: a heat-in-rent household with a bill counts as responsible.
    • Suggested action: Rename the local (e.g. pays_heating_bill).
    • Source: FY2026 plan p. 9.
  5. Test-file header references.

    • List fragments: #page=1,2 appears on line 2 of the integration, ne_liheap, ne_liheap_eligible, ne_liheap_fpg, ne_liheap_household_size and ne_liheap_income_eligible YAMLs. The PR body also uses #page=1,2,3,4,5 and #page=7,9,10. The PDF page= parameter takes a single page, so viewers open only the first.
    • Headers that do not cover their cases: ne_liheap_eligible.yaml:1-2 and ne_liheap_household_size.yaml:1-2 cite the Guidance income and heating tables, but their cases test other rules:
      • heating responsibility (476 NAC 1-004.09 and 2-002; plan 2.3);
      • immigration-based size reduction and proration (476 NAC 2-002.02/.03; 475 NAC 3-002.06).
    • Suggested action: Use one page per link, and cite the rules each file tests.
    • Source: Guidance p. 1 and FAQ p. 3.
  6. FY2027 has been in effect since 2026-10-01.

    • Where: ne_liheap.py:11-14, programs.yaml:840 and the tests.
    • Payment matrix: Period 2027 carries the FY2026 payment matrix forward. The FY2027 Guidance Document returns 404, and the FY2027 plan restates only $154 / $1,050 (p. 10).
    • Income limits: The FY2027 limits on the DHHS page ($23,940, plus $8,520 per additional member) equal 1.5 times the repo's 2026 FPG (15,960 / 5,680), so the one-year lag can be verified.
    • Suggested action:
      • Note in ne_liheap.documentation and the registry notes that later years carry FY2026 amounts forward unverified.
      • Add period-2027 cases: ne_liheap_fpg = 15,960, and ne_liheap_income_eligible at 23,940 (true) and 23,941 (false).
    • Source: FFY2027 plan p. 10 and the DHHS Energy Assistance page.
  7. programs.yaml conflicts with the sibling PRs, and their ordering is inconsistent.

  8. Reference hardening.

    • 476 NAC viewer links: ne_liheap_eligible.py:11, ne_liheap_household_size.py:10 and ne_liheap_dwelling_type.py:23 can use edition-pinned chapter PDFs:
    • income_limit.yaml:8-10: Add 476 NAC 2-002.01 ("may not exceed 150% of the federal poverty level"), which also supports the inclusive <=.
    • ne_liheap_income_eligible.py:10: Add Guidance #page=2, where "at or below 150%" appears. Page 1 has only the table.
    • fpg_year_lag.yaml:8-10: The one-year lag is inferred from $23,475 = 1.5 times the 2025 guideline. Add the 2025 HHS poverty guidelines notice so readers can check the inference.
  9. ne_liheap.yaml Case 30 does not isolate the disregard.

    • Where: ne_liheap.yaml:323.
    • Problem: Gross and earned income are both $20,000. The ratio is 16,000 / 15,650 = 1.022 with the disregard and 20,000 / 15,650 = 1.278 without it. Both are Tier 3 ($400), so the case passes with no disregard at all.
    • The disregard is covered elsewhere (integration Case 1 and gross_income Case 1).
    • Suggested action: Use $17,000. That gives 13,600 / 15,650 = 0.869, Tier 2, $550 with the disregard, against 1.086, Tier 3, $400 without it.
    • Source: Guidance p. 2.
  10. The earned-income source list is inline.

    • Where: ne_liheap_earned_income.py:33-38 sums employment_income, self_employment_income, sstb_self_employment_income and farm_operations_income, each floored at zero.
    • Precedent: NE keeps such lists as parameters (gov.states.ne.dhhs.child_care_subsidy.income.sources.earned).
    • Suggested action: Add a gov.states.ne.dhhs.liheap.income.sources.earned list, summed with a per-source max_(..., 0). That keeps the flooring and makes the list reviewable.
    • military_service_income is omitted, as it is in SNAP's earned list, so this gap is inherited, not new.
    • Source: FY2026 plan p. 7.
  11. The payment-band FPG has redundant guards.

    • Where: ne_liheap.py:33-34.
    • Problem: clip(size, 1, ...) already keeps payment_fpg at or above FPG(1), which is positive. defined_for = "ne_liheap_eligible" also requires size > 0. So where(size > 0, ...) and max_(payment_fpg, 1) never take effect.
    • Suggested action: Drop both lines, or move lines 26-34 into a ne_liheap_payment_fpg variable that tests can assert directly. That would also help with Should Address 5.
    • Source: Guidance p. 2.
  12. This adds another state-specific dwelling input.

    • Where: ne_liheap_dwelling_type.py:4-6 and :9-13.
    • Existing inputs: DC has dc_liheap_housing_type with the same SINGLE_FAMILY / MULTI_FAMILY enum, defaulting to MULTI_FAMILY. Sibling Add Indiana EAP regular heating assistance #9728 adds an Indiana dwelling input with a mobile-home option.
    • The PR body notes that the NE input was authorized.
    • Suggested action: Consider a follow-up issue for a shared structure-type input, or at least align the suffix (_housing_type vs _dwelling_type).
    • Source: Guidance p. 2 (single-family vs multifamily columns).
  13. Test hygiene.

    • Names that describe the wrong thing:
      • ne_liheap.yaml:191 (Case 18) says "10955" but tests 10,955.01.
      • :202 and :213 (Cases 19-20) test x.01 values, not the closed upper boundary.
      • :224 (Case 21) tests negative income clamped to zero but is named "closed upper tier boundary".
      • ne_liheap_fpg.yaml:4 says "1 members".
    • Inert inputs: ne_liheap_eligible.yaml:21 and :113 set pre_subsidy_rent, which no NE formula reads.
    • Overrides of a formula variable: ne_liheap_eligible.yaml:20, :31 and :52, and integration.yaml:200, set heating_expense: 0 as an input. With UNSPECIFIED fuel the canonical formula already returns 0, so asserting it as an output would exercise the real path.
    • Mixed styles: integration.yaml uses YAML anchors in Cases 1-6 and inline lists in Cases 7-10.
  14. Parameter description verbs.

    • Where: earned_income_disregard.yaml:1 ("disregards", with two clauses) and payment_size_limit.yaml:1 ("caps").
    • Both verbs are outside the canonical list (limits / provides / sets / excludes / deducts / uses), though both are common in the repo.
    • Example: "Nebraska excludes this share of gross countable earned income when determining regular heating payments under the Low Income Home Energy Assistance Program."
    • Source: Guidance p. 2.

PDF Audit Summary

Category Count
Confirmed correct 39 of 39 parameter values (9 files)
Mismatches (code-path confirmed + visually verified) 0
Mismatches rejected (code-path cleared) 0
Unmodeled items 5 (cooling, Guidance p. 3; crisis; furnace/equipment, plan p. 10; supplemental heating payments, plan p. 5; corn inside OTHER, Guidance p. 2). All are out of scope or documented in programs.yaml
Pre-existing issues 0
Parameter file Values Source page Match
income_limit.yaml 1.5 Guidance p. 1 1/1
fpg_year_lag.yaml 1 ($23,475 = 1.5 x 2025 FPG of 15,650) Guidance p. 1 1/1
earned_income_disregard.yaml 0.2 Guidance p. 2 1/1
payment_size_limit.yaml 6 Guidance p. 2 1/1
payment/oil.yaml 1,050 / 650 / 350 / 175; thresholds 0.7 / 1 / 1.3 Guidance p. 2 7/7
payment/wood.yaml 800 / 600 / 350 / 175; thresholds 0.7 / 1 / 1.3 Guidance p. 2 7/7
payment/propane.yaml 850 / 580 / 330 / 165; thresholds 0.7 / 1 / 1.3 Guidance p. 2 7/7
payment/utility.yaml 700 / 550 / 400 / 280; thresholds 0.7 / 1 / 1.3 Guidance p. 2 7/7
payment/multifamily.yaml 380 / 300 / 220 / 154; thresholds 0.7 / 1 / 1.3 Guidance p. 2 7/7

Derived checks:

  • All 20 printed tier boundaries for sizes 1-5 equal 0.7 / 1.0 / 1.3 / 1.5 times the 2025 FPG.
  • The 8 printed income limits and the per-member increment equal 1.5 times the 2025 FPG.
  • The effective date 2025-10-01 matches "Effective 10/1/25 through 9/30/26".
  • The one-year lag reproduces the FY2027 DHHS limits.
  • The $154 minimum and $1,050 maximum match plan sec. 2.6 (p. 10).

Page-reference check:

  • Guidance #page=1 (4 refs) and #page=2 (9 refs) are correct.
  • ACF plan #page=7 and FAQ #page=3 are correct.
  • The dhhs plan #page=9 now points to the wrong edition (Should Address 2).
  • The 475 NAC viewer citation has drifted (Should Address 3).
  • The #page=1,2 list fragments are non-standard (Suggestion 5).

Validation Summary

Check Result
Regulatory Accuracy 0 mismatches; 1 should address (4); 3 suggestions (1, 2, 6)
Reference Quality 2 should address (2, 3); 2 suggestions (5, 8)
Code Patterns 0 critical or should address; 5 suggestions (3, 4, 10, 11, 12)
Formatting (params & vars) 1 suggestion (14)
Test Coverage 1 should address (5), plus a payment case in Should Address 4; 2 suggestions (9, 13), plus 2027 cases in Suggestion 6
Microsim Defaults 1 should address (6)
Process (axiom, changelog, registry) 1 should address (1); 1 suggestion (7); changelog fragment changelog.d/ne-liheap.added.md present
PDF Value Audit 0 mismatches / 39 confirmed
CI Status Passing (37/37; run 36819650903 on head 89582437c7)

Review Severity: REQUEST_CHANGES

There are 0 critical issues and 6 should-address items. APPROVE requires 0 critical and 0 should-address.

Next Steps

  • To auto-fix issues: /fix-pr 9723.
  • Should Address 1: open the pe-parity rulespec-us issue and change the axiom line to queued.
  • Should Address 2-3: repoint the state-plan references to the ACF FY2026 plan, and the 475 NAC citations to the edition-pinned historical chapter PDF.
  • Should Address 4: correct the plan 2.3 summary, cite 476 NAC 3-002.02 and plan 9.1 / 1.1, and add the single-family heat-in-rent payment case.
  • Should Address 5: add the size-7 boundary case that pins the size-6 cap.
  • Should Address 6: document or quantify the microsim effects of the dwelling default and the missing heating inputs.
  • Rebase on main. Then update the waiting-period statements at ne_liheap_household_size.py:19-20 and in the PR body (see Branch Status), and re-run CI.
  • Coordinate the programs.yaml coverage line with Add Kansas LIEAP regular heating assistance #9663 and Add Kentucky LIHEAP regular heating assistance #9725-Add Indiana EAP regular heating assistance #9728.

@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 per the program review above (#9723 (comment)): 0 critical, 6 should-address items, 14 suggestions. All 39 audited parameter values match the FY2026 sources. Run /fix-pr 9723 or address the should-address list.

hua7450 and others added 2 commits October 1, 2026 17:41
…nt sourcing and boundary tests

- Cite the ACF copy of the FY2026 state plan instead of the DHHS URL that now serves the FFY2027 plan
- Cite the edition-pinned 475 NAC chapter 3 and 476 NAC chapters 1 and 2 PDFs instead of the live viewer
- Quote both plan section 2.3 sentences and cite 476 NAC 3-002.02 and plan sections 1.1 and 9.1 for market-rate heat-in-rent renters
- Add a single-family heat-in-rent payment case and a seven-person case that pins the six-person payment cap
- Rename the local heating-bill flag, drop two redundant guards, note the size-6+ footnote wording, re-word two descriptions
- Fix test headers, case names and inert inputs; make Case 30 depend on the earned-income disregard
- Shorten the registry note

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@hua7450

hua7450 commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks, @DTrim99. Pushed 39cd987 plus a merge of main (head dec8b6d):

  • Should 2: the state-plan references point to the ACF FY2026 copy (same pages); the DHHS URL does serve the FFY2027 plan now.
  • Should 3: 475 NAC is cited by the edition-pinned chapter 3 PDF (pages 44 and 47), and 476 NAC chapters 1 and 2 by their pinned chapter PDFs.
  • Should 4: both section 2.3 sentences are quoted, 476 NAC 3-002.02 and plan sections 1.1 and 9.1 are cited, and integration Case 11 pays the market-rate single-family heat-in-rent household $550.
  • Should 5: ne_liheap.yaml Case 34 pins the six-person cap at your six incomes.
  • Also done: suggestions 1, 4, 8, 9, 11, 13 and 14, the file headers from suggestion 5, and the waiting-period wording after the merge.

Replies:

  • Should 1: the rulespec-us issue is being filed; the axiom line will change to queued once it exists.
  • Should 6: the missing heating inputs are handled by changing the default heating_type to electricity in a separate PR. The dwelling default is the convention across all state LIHEAP programs, with callers expected to report the type. Economic vulnerability stays documented as an assumption.
  • Suggestion 2: the payment table has no solar column, so solar stays at $0 as a documented limitation.
  • Suggestion 5, combined anchors: one link per source, with the pages named in the title, same as on Kansas.
  • Suggestions 3 and 10 (refactors), 6 (FY2027 cases) and 12 (a shared dwelling input) are left for separate decisions; 7 is for merge time.

@hua7450
hua7450 requested a review from DTrim99 October 1, 2026 21:42
@DTrim99

DTrim99 commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator

Program Review — Round 2

PR #9723: Nebraska LIHEAP regular heating assistance (@hua7450). Round 1 reviewed head 89582437c7. This round reviews head dec8b6d6c7: commit 39cd98794a ("Address review items ...") plus a merge of main. The PR still has 27 files: 9 parameters, 8 variables, 8 test files, a changelog fragment and programs.yaml. It now has 77 test cases, up from 75: integration 11, ne_liheap 34, earned_income 3, eligible 9, fpg 12, gross_income 2, household_size 2, income_eligible 4.

Result: 0 critical, 2 should address remaining, 7 suggestions.

  • Four of the six round-1 should items are fixed (2, 3, 4 and 5).
  • The axiom line still reads n/a, although the rulespec-us issue now exists.
  • The microsim heating-input gap is deferred to a separate PR that could not be found and is not tracked anywhere.
  • No parameter value changed. All three changed or new test expectations match the FY2026 Guidance table, rechecked against the page PNG.

Status of round-1 should-address items

# Round-1 item Verdict Evidence
1 Axiom line n/a for a new program NOT FIXED rulespec-us#1464 was opened on 2026-10-01 at 21:50 UTC and is labelled pe-parity. The PR body's last line is still axiom: n/a: rulespec-us does not have this program yet; it should be added as a follow-up. See Should Address 1.
2 State-plan reference serves the FFY2027 plan FIXED No dhhs.ne.gov/Documents/LIHEAP%20State%20Plan.pdf reference remains in the PR files. ne_liheap_eligible.py:14, ne_liheap_eligible.yaml:6,68, integration.yaml:255,337 and the PR body cite the ACF FY2026 copy (Rev. 1, 10/01/2025-09/30/2026). The pages were confirmed in its text: sec. 1.1 on p. 5, sec. 2.3 on p. 9, sec. 9.1 on p. 25.
3 475 NAC 3-002.04(B)(i) cited through the live viewer, which now serves renumbered text FIXED ne_liheap_earned_income.py:13, ne_liheap_gross_income.py:13, ne_liheap_earned_income.yaml:4, ne_liheap_gross_income.yaml:4, ne_liheap_household_size.yaml:5 and integration.yaml:220 cite the edition-pinned 475 NAC 3 (09-17-2024) PDF. In the downloaded PDF, p. 44 has 3-002.04(B)(i) "Averaged self-employment income ... for each source of self-employment", and p. 47 begins 3-002.06 and (A). The 476 NAC viewer links were also replaced with pinned chapter PDFs. No rules.nebraska.gov/rules? link remains.
4 Heat-in-rent: the plan 2.3 summary was incomplete and the legal basis uncited FIXED (i) Both sec. 2.3 sentences are quoted at ne_liheap_eligible.py:19-23 and ne_liheap_eligible.yaml:60-67. (ii) 476 NAC 3-002.02 is cited at ne_liheap_eligible.py:13,27-29; the Cornell LII text reads "Only if utilities are included in rent ... may the Department pay a household directly", amended effective 12/26/2020. Plan 1.1 (p. 5) and 9.1 (p. 25) are also cited. (iii) integration.yaml:331-370 (Case 11) covers a market-rate single-family NATURAL_GAS heat-in-rent household with gas_expense 0 and $18,000 wages, which receives $550. Check: 14,400 / 15,650 = 0.920, between the $10,955 and $15,650 rows, so Tier 2, which pays $550 in the gas column (Guidance p. 2).
5 No test pins payment_size_limit = 6 FIXED ne_liheap.yaml:391-406 (Case 34): size 7, PROPANE, incomes 30,205 / 30,205.01 / 43,150 / 43,150.01 / 56,095 / 56,095.01, expected [850, 580, 580, 330, 330, 165]. This matches the Guidance p. 2 size-6+ footnote and the propane column (850/580/330/165), confirmed on the page PNG. A cap of 5 gives 30,205 / 37,650 = 0.802, which is Tier 2 ($580). No cap gives 30,205.01 / 48,650 = 0.621, which is Tier 1 ($850). Either way the case fails. In IEEE doubles, 30,205 / 43,150 equals the double for 0.7 and 56,095 / 43,150 equals the double for 1.3, so the closed boundaries hold.
6 Microsim defaults and inputs NOT FIXED (in part) Two parts are ACCEPTED-AS-RATIONALE. The dwelling default is documented at ne_liheap_dwelling_type.py:16-22 and in the PR body, and callers are expected to report the type. Economic vulnerability is documented at ne_liheap_eligible.py:24-25, in the PR body and in the changelog. The heating-input gap is NOT FIXED: the deferral to "a separate PR" is not tracked. See Should Address 2.

Verification of claimed suggestion fixes

Round-1 suggestion Status Evidence
1. Size-6+ footnote comment Fixed ne_liheap.py:26-29
2. SOLAR/OTHER paid $0 Accepted as a documented limitation The payment table has no solar column. The limitation is documented at ne_liheap.py:45-49 and in the PR body; the registry note no longer mentions it (Suggestion 2).
4. Local name collides with has_heating_expense Fixed Renamed pays_heating_bill, with an explanatory comment (ne_liheap_eligible.py:34-36)
5. Test-file headers Headers fixed; list anchors not adopted ne_liheap_eligible.yaml:1-6 and ne_liheap_household_size.yaml:1-5 now cite the rules they test. For the comma-list anchors, see Suggestion 1.
8. Reference hardening Fixed; one remainder 476 NAC ch. 1 and ch. 2 now use pinned PDFs. Anchors checked: ch. 1 p. 1 has 1-004.06 and 1-004.09; ch. 1 p. 2 has 1-004.11 and 1-004.16; ch. 2 p. 1 has 2-002 and 2-002.01 to 2-002.03. income_limit.yaml:11-12 adds 2-002.01. ne_liheap_income_eligible.py:11 adds Guidance p. 2. fpg_year_lag.yaml:11-12 links an index page rather than the notice itself (Suggestion 5).
9. Case 30 does not isolate the disregard Fixed ne_liheap.yaml:323-335 now uses $17,000. With the disregard, 13,600 / 15,650 = 0.869, Tier 2, $550. Without it, 17,000 / 15,650 = 1.086, Tier 3, $400.
11. Redundant guards Fixed, and safe ne_liheap.py:37 divides by payment_fpg directly. fpg() returns first_person + additional_person * (size - 1), and clip(size, 1, 6) keeps size at 1 or more, so the divisor is always at least the one-person guideline, which is positive.
13. Test hygiene Mostly fixed Fixed: the names of Cases 18-21 (ne_liheap.yaml:191,202,213,224) and "1 member" (ne_liheap_fpg.yaml:4); the inert pre_subsidy_rent inputs were removed; heating_expense moved from input to output (ne_liheap_eligible.yaml:25,35,56, integration.yaml:211). Still open: the mixed YAML styles (Suggestion 3).
14. Parameter description verbs Fixed earned_income_disregard.yaml:1 ("excludes"), payment_size_limit.yaml:1 ("limits")
Branch status: waiting-period wording Fixed ne_liheap_household_size.py:19-21 and the PR body. At this head, is_snap_immigration_status_eligible applies meets_snap_qualified_alien_waiting_period.
3, 10, 12 (refactors), 6 (FY2027), 7 (merge time) Deferred See Suggestions 6 and 7

Delta regression check

  • Parameters: No values changed. Only the descriptions (earned_income_disregard.yaml:1, payment_size_limit.yaml:1) and references (income_limit.yaml, fpg_year_lag.yaml) were edited. All 39 values still match the FY2026 Guidance pp. 1-2.
  • Test expectations: Case 30 changed from 400 to 550, and Case 34 and integration Case 11 are new. All three were re-derived from the Guidance p. 2 table and footnote (PNG confirmed). The heating_expense: 0 outputs for UNSPECIFIED fuel follow from the default=0 branch of heating_expense. CI runs all 77 cases.
  • Code: The only formula change is the guard removal at ne_liheap.py:37 (safe, see above). The local rename does not change behaviour.
  • New citations: Each was opened and checked.
    • 475 NAC 3 (09-17-2024): pp. 44 and 47 as above. 3-002.06(B) continues onto p. 48.
    • 476 NAC 1 (12-26-2020), chapter id 1746: pp. 1-2.
    • 476 NAC 2 (06-26-2022), chapter id 1747: p. 1.
    • ACF FY2026 plan: pp. 5, 9 and 25.
    • Cornell LII 476 NAC 3-002: section 002.02.
    • The ASPE prior-guidelines page.
  • Heat-in-rent sourcing: This is now accurate to the sources. Sec. 2.3 states both conditions. 3-002.02 lets DHHS pay the household directly only when utilities are in rent. Plan 1.1 (issuing supplemental payments to the household) and 9.1 (exceptions to paying the provider) both name "economically vulnerable" households whose utilities are included in rent. The market-rate treatment remains a labelled modeling assumption.
  • Registry note: It was shortened at programs.yaml:840 (Suggestion 2).

Critical (Must Fix)

None.

Should Address (remaining)

  1. The axiom line is still n/a (round-1 Should 1).

    • Where: The last line of the PR body.
    • Status: TheAxiomFoundation/rulespec-us#1464, "Encode Nebraska LIHEAP with PolicyEngine oracle coverage", is open and labelled pe-parity. It was created 8 minutes after the author's reply. The PR body has not been updated to reference it.
    • Rule: CLAUDE.md "Axiom Parity" says "A queued rulespec-us issue must be dispatch-ready and labelled pe-parity. It needs the module path and corpus citation, the verbatim law, the required outputs, and companion tests from the same external source as your YAML tests." CONTRIBUTING.md#axiom-parity adds: "Reuse your YAML test's external expected values as the companion tests."
    • Gaps in empty issue #1464 against that definition:
      • PR Add Nebraska LIHEAP regular heating assistance #9723 is not linked. The issue says "The PR URL, exact scope, policy periods, and eventual merged commit still need to be linked".
      • There is no module path beyond "under us-ne/".
      • It links two corpus manifests but does not cite the provisions (476 NAC 2-002 and 2-002.01; Guidance pp. 1-2).
      • There is no verbatim law, no list of required outputs, and no companion tests.
    • Fix:
      • Change the line to axiom: https://github.com/TheAxiomFoundation/rulespec-us/issues/1464 queued.
      • Add the missing items to empty issue #1464. Candidate companion cases, each hand-derived from the Guidance table:
        • Size 1, $18,000 wages, gas: $550.
        • Size 1, $17,000 wages: $550 (Tier 2 only because of the disregard).
        • Size 7, propane: $850 at $30,205 and $580 at $30,205.01.
        • Size 1, gross $23,475 is eligible and $23,475.01 is not.
  2. The microsim heating-input gap is deferred without tracking (round-1 Should 6, remaining part).

    • Where: ne_liheap_eligible.py:36-41 (responsible = pays_heating_bill | (heat_in_rent & ~subsidized)), programs.yaml:840, and the PR body.
    • Status: The author's reply says "the missing heating inputs are handled by changing the default heating_type to electricity in a separate PR."
      • A search of PolicyEngine/policyengine-us PRs and issues (heating-related titles created since 2026-09-20, and "heating_type") found no such PR or issue.
      • Neither the PR body nor the registry note mentions the microsim effect.
      • The registry note that described the program's assumptions was shortened in 39cd98794a.
    • Why the gap persists: #9284 reports that none of the heating and utility input columns appear in microcosm's certified US export. In microsim, therefore:
      • heating_expense is 0 and heat_expense_included_in_rent is false for every record.
      • responsible is false for every record.
      • ne_liheap is $0 for every NE SPM unit, a downward bias of 100% of modeled program cost.
      • ne_liheap feeds no benefit aggregate, so net income and poverty outputs are unaffected.
    • On the proposed remedy: With an ELECTRICITY default, heating_expense reads pre_subsidy_electricity_expense (heating_expense.py). That variable is a plain input with no formula, and the local populace build spec has no producer for it. Unless the microdata supplies that column, the default change alone would leave NE microsim at $0.
    • Fix (any one):

Suggestions

  1. Comma-list page anchors (round-1 Suggestion 5, not adopted, and extended by the delta).

    • Where: There are 10 occurrences in PR files, plus #page=1,2, #page=5,7,9,10,25, #page=44,47 and #page=1,2,3,4,5 in the PR body. The PR files:
      • #page=5,9,25: ne_liheap_eligible.py:14, integration.yaml:337, ne_liheap_eligible.yaml:68
      • #page=44,47: ne_liheap_earned_income.py:13
      • #page=1,2: ne_liheap_income_eligible.py:11, income_limit.yaml:10, and line 2 of the integration, ne_liheap, ne_liheap_fpg and ne_liheap_income_eligible YAMLs
    • The author's position: "one link per source, with the pages named in the title, same as on Kansas."
    • Assessment:
      • Naming the pages in the title works where a title exists, as in income_limit.yaml:9.
      • The variable reference tuples and the test-comment URLs have no title.
      • The PDF #page= open parameter takes a single page, so viewers open only the first listed page.
      • main has 0 #page=N,M anchors against 11,328 single-page anchors. The Kansas precedent (Add Kansas LIEAP regular heating assistance #9663) is an unmerged PR by the same author.
    • Suggested action: Use one URL per page in the bare-URL references.
    • Minor: 475 NAC 3-002.06(B) is on p. 48 of the pinned PDF; p. 47 has the heading and (A).
  2. The registry note no longer lists the modeling assumptions.

    • Where: programs.yaml:840.
    • Previous note: It listed assumed economic vulnerability, heat-in-rent acceptance for market-rate renters, the single-family default, $0 for single-family UNSPECIFIED/OTHER/SOLAR/NONE fuel, backfilled pre-FY2026 years, and the excluded equipment assistance.
    • New note: "FY2026 regular heating only, with the single-family and multifamily schedules and the earned-income disregard. Crisis, cooling and weatherization assistance are out of scope."
    • Why it matters: These facts remain in code comments and the PR body. The registry, however, is what /us/metadata serves to the coverage page, and sibling entries list unmodeled items (e.g. TX, programs.yaml:832).
    • Suggested action: Restore a short assumptions/not-modeled clause. That clause could also carry the microsim note from Should Address 2.
  3. The integration file still mixes YAML styles (round-1 Suggestion 13, remainder).

    • Where: integration.yaml.
    • Detail: Cases 1-6 use dumped anchors (members: &id001 / *id001, lines 16-174). Cases 7-11 use inline lists.
  4. Optional: cite 476 NAC 3-002.02 through the pinned chapter PDF for consistency.

    • Where: ne_liheap_eligible.py:13, integration.yaml:338 and ne_liheap_eligible.yaml:69 use Cornell LII. The text there is correct.
    • Detail: Chapters 1 and 2 use edition-pinned rules.nebraska.gov PDFs. The same form exists for chapter 3: 476 NAC 3 (12-26-2020) p. 1. It has 4 pages, with 3-002.02 on p. 1.
  5. fpg_year_lag.yaml:11-12 links the ASPE index of all prior notices.

    • Detail: The 2025 notice itself is at FR Doc. 2025-01377, the link ASPE uses.
    • Suggested action: Link the notice directly so readers can check the $15,650 / $5,500 inference.
  6. FY2027 has been in effect since 2026-10-01 (round-1 Suggestion 6, deferred).

    • Where: ne_liheap.py:11-14 and programs.yaml:840.
    • Detail: Period 2027 carries the FY2026 matrix forward. The FY2027 Guidance Document still returns 404 as of 2026-10-01. The evergreen Guidance is unchanged since 2026-07-17.
    • Suggested action: A one-line note in ne_liheap.documentation that later years carry FY2026 amounts forward unverified would make that explicit. The income limits already reproduce the FY2027 DHHS figures through the one-year lag.
  7. Other round-1 suggestions left for separate decisions. No action is needed in this PR:

CI

  • Passing: 37/37 checks on head dec8b6d6c7 (run 36930335741), including all baseline and contrib shards, microsimulation, lint, changelog and codecov patch/project.
  • The PR head has not moved past dec8b6d6c7.
  • The branch is 0 commits behind main (fbe24ad1b3) and 8 ahead.

Review Severity: REQUEST_CHANGES

There are 0 critical issues and 2 remaining should-address items (round-1 items 1 and 6). Items 2-5 are fixed, and the dwelling-default and economic-vulnerability parts of item 6 are accepted as rationale. APPROVE requires 0 critical and 0 remaining should-address items.

Next Steps

  • Should Address 1: change the axiom line to axiom: https://github.com/TheAxiomFoundation/rulespec-us/issues/1464 queued. Add the PR link, module path, provision citations, verbatim law, outputs and companion cases to empty issue #1464.
  • Should Address 2: link the separate heating_type PR or a tracking issue in the PR body, or add the microsim note to programs.yaml:840 or ne_liheap.documentation.
  • Optional: Suggestions 1-5.

@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 (#9723 (comment)): 4 of 6 round-1 should items fixed (plan link, pinned 475 NAC citations, heat-in-rent sourcing, size-cap test). Remaining: update the axiom line to queued with rulespec-us#1464 (and make that issue dispatch-ready), and track the heating_type default follow-up in the PR body or code docs. No value regressions; the new size-7 boundary test matches Guidance p. 2.

hua7450 and others added 2 commits October 2, 2026 12:35
Give every multi-page reference a single page in the link, with the pages
named beside it. Cite 476 NAC 3-002.02 through the pinned chapter PDF and
the 2025 poverty guideline notice directly. Move the earned income sources
into a list parameter, inline the YAML anchors in the integration test,
note that later years carry the FY2026 amounts forward, and place Nebraska
alphabetically in the registry.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@hua7450

hua7450 commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the second round. Fixes are in 73aa59057a, followed by a merge of main (head 3d36e886d9). Nothing was run locally; CI validates.

Should-address

  1. Axiom line. Now axiom: TheAxiomFoundation/rulespec-us#1464 queued. The gaps you list in that issue are being filled on the rulespec side.
  2. Microsimulation heating inputs. Tracked in Default heating_type to electricity and remove the UNSPECIFIED-gated state heating adapters #9754 (default heating_type to electricity and remove the UNSPECIFIED-gated adapters). It affects API partners, so it is separate work and does not block the state PRs. The PR body now links it. Callers must send heating_type with the matching fuel bill.

Suggestions

  • 1: fixed, and my earlier position on this was wrong. Every reference has one page in the link, with the pages named in the title or in a comment above the URL; test comments follow the same form. 475 NAC 3-002.06 is now cited as pages 47-48.
  • 3: the dumped YAML anchors in integration.yaml are inline lists.
  • 4: 476 NAC 3-002.02 is cited through the pinned chapter 3 PDF, page 1.
  • 5: fpg_year_lag.yaml links the January 17, 2025 Federal Register notice, page 1.
  • 6: ne_liheap documentation says later years carry the FY2026 amounts forward.
  • Round-1 suggestion 10: the earned income sources are now a list parameter (earned_income_sources.yaml); results are unchanged.
  • Round-1 suggestion 7: Nebraska now sits alphabetically between IL and TX, on the coverage line and in the list; the sibling PRs follow the same rule.
  • 2: not taken. Registry notes stay short; the assumptions are in the PR body and code comments.
  • Round-1 suggestions 3 and 12 (shared proration variable, shared dwelling input): not in this PR.

@hua7450
hua7450 requested a review from DTrim99 October 2, 2026 16:37
@DTrim99

DTrim99 commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

Program Review — Round 3

PR #9723: Nebraska LIHEAP regular heating assistance (@hua7450). Round 2 reviewed head dec8b6d6c7. This round reviews head 3d36e886d9: fix commit 73aa59057a ("Address second Nebraska LIHEAP review") plus a merge of main. The PR now has 28 files, one more than before: the new parameter earned_income_sources.yaml. It still has 77 test cases, none with a changed expectation: integration 11, ne_liheap 34, earned_income 3, eligible 9, fpg 12, gross_income 2, household_size 2, income_eligible 4.

Result: 0 critical, 1 should address remaining, 2 suggestions.

Status of round-2 should-address items

# Round-2 item Verdict Evidence
1 Axiom line should be queued with rulespec-us#1464, and #1464 must be dispatch-ready NOT FIXED (PR side done; issue side open) The PR body's last line is now axiom: TheAxiomFoundation/rulespec-us#1464 queued, which is the right form. rulespec-us#1464 is open and labelled pe-parity. However, its updatedAt equals its createdAt (2026-10-01T21:50:11Z) and it has 0 comments, so none of the gaps listed in round 2 has been filled. The body still says "The PR URL, exact scope, policy periods, and eventual merged commit still need to be linked". See Should Address 1.
2 Microsim heating-input deferral must be tracked FIXED #9754, "Default heating_type to electricity and remove the UNSPECIFIED-gated state heating adapters", was opened on 2026-10-02 at 15:41 UTC by the PR author. The PR body's new Microsimulation paragraph links it and says population totals are $0 for now. That meets the round-2 fix ("open ... a tracking issue, and link it in the PR body"). One wording point remains (Suggestion 1).

Verification of claimed suggestion fixes

Suggestion Status Evidence
R2-1: comma-list page anchors Fixed None of the 28 PR files or the PR body has a #page=N,M or #page=N-M anchor. Every rules.nebraska.gov, dhhs.ne.gov, liheapch.acf.gov and govinfo.gov link has a single page. Multi-page references name their pages in a title or a comment: income_limit.yaml:9, ne_liheap_income_eligible.py:11, ne_liheap_earned_income.py:13, ne_liheap_gross_income.py:13, ne_liheap_eligible.py:13,15, and line 1 of the integration, ne_liheap, ne_liheap_fpg and ne_liheap_income_eligible YAMLs. 475 NAC 3-002.06 is now cited as pages 47-48 (ne_liheap_earned_income.py:13, ne_liheap_gross_income.py:13, PR body).
R2-3: mixed YAML styles in integration.yaml Fixed No &id/*id anchors remain. Cases 1-6 now use members: [person1] or [person1, person2], the same members as before, which matches Cases 7-11.
R2-4: cite 476 NAC 3-002.02 through the pinned PDF Fixed ne_liheap_eligible.py:14, integration.yaml:330, ne_liheap_eligible.yaml:69. In the downloaded 476 NAC 3 (12-26-2020) PDF, page 1 shows "Effective Date: 12/26/2020" and "002.02 HOUSEHOLD. Only if utilities are included in rent or if a provider ... the Department pay a household directly." No Cornell LII link remains.
R2-5: link the 2025 poverty-guideline notice directly Fixed fpg_year_lag.yaml:11-12 now links FR Doc. 2025-01377. Page 1 of the downloaded PDF has the 48-state table: "1 ... $15,650" and "add $5,500 for each additional person". The title's figures match.
R2-6: say that later years carry FY2026 forward Fixed ne_liheap.py:11-15: "Later years carry the FY2026 amounts forward until a new schedule is added."
R1-10: inline earned-source list Fixed earned_income_sources.yaml:3-10 lists the same four sources as the old inline sum: employment_income, self_employment_income, sstb_self_employment_income, farm_operations_income. The loop at ne_liheap_earned_income.py:35-38 still floors each source at zero, so results are unchanged. The list starts on 2025-10-01. backdate_parameters (tools/parameters.py:16-30, called at system.py:145) backdates every parameter with a values_list to 2015-01-01, so pre-FY2026 periods still resolve.
R1-7: programs.yaml ordering Fixed programs.yaml:805 reads OR, DC, Riverside County, MA, IL, NE, TX. The NE entry (programs.yaml:826-833) now comes before TX (:834). The TX block is byte-identical to the base (7d2a2d7eee).
R2-2: registry note lists no assumptions Declined by the author The author's rationale is that registry notes stay short and the assumptions are in the PR body and code comments. The PR body now also carries the microsim note. Not raised again.
R1-3, R1-12: shared proration and dwelling input Left out of this PR No action is needed in this PR.

Delta regression check

  • Parameters
    • One new file, earned_income_sources.yaml. Its metadata is complete: a one-sentence description, unit: list, period: year, a label, and two titled references.
    • The other nine files have no value changes. Only income_limit.yaml:10 (the href anchor) and fpg_year_lag.yaml:11-12 (the reference) were edited.
    • All 39 payment and limit values are as verified against the Guidance pp. 1-2 PNGs in round 2.
  • Test expectations
    • None changed. The delta to the test files only edits the page anchors in comment headers and the members: syntax in integration.yaml.
    • All counts per file are unchanged.
  • Code
    • The one formula edit is the loop refactor in ne_liheap_earned_income.py, which behaves the same as before.
    • ne_liheap.py changed only its documentation. Four variables changed only their reference tuples and comments.
  • Merge of main
    • It brings SNAP ABAWD waiver-area and work-requirement changes. NE LIHEAP reads only SNAP income-source parameters, snap_countable_earner and is_snap_immigration_status_eligible. None of these changed in the merge.
    • main is 1 commit ahead of the PR base and touches none of the PR's paths.
  • New citations: Each was opened and checked.
    • FR Doc. 2025-01377, p. 1, and 476 NAC 3 (12-26-2020), p. 1: as above.
    • 475 NAC 3 (09-17-2024), p. 44: confirmed in round 2.
    • FY2026 plan, p. 7, cited by the new parameter: see Suggestion 2.

Critical (Must Fix)

None.

Should Address (remaining)

  1. rulespec-us#1464 is not dispatch-ready, so the queued claim is not yet met (round-2 Should 1).
    • Where: The last line of the PR body (axiom: TheAxiomFoundation/rulespec-us#1464 queued) and rulespec-us#1464.
    • Rule: CLAUDE.md "Axiom Parity" says "A queued rulespec-us issue must be dispatch-ready and labelled pe-parity. It needs the module path and corpus citation, the verbatim law, the required outputs, and companion tests from the same external source as your YAML tests." CONTRIBUTING.md#axiom-parity adds: "Reuse your YAML test's external expected values as the companion tests."
    • Status:
      • The label is present.
      • The author's reply says "The gaps you list in that issue are being filled on the rulespec side." The issue body has not been edited since creation (updatedAt 2026-10-01T21:50:11Z) and has no comments.
      • The PR author also opened empty issue #1464, so the body can be edited directly.
    • Still missing from empty issue #1464:
      • A link to PR Add Nebraska LIHEAP regular heating assistance #9723. The issue says the PR URL "still need[s] to be linked".
      • A module path beyond "under us-ne/".
      • Provision-level corpus citations. The issue links two manifests but cites no provisions. The provisions include 476 NAC 2-002 and 2-002.01, Guidance pp. 1-2 (income limits and the heating matrix), and the 475 NAC 3-002.04(B)(i) and 3-002.06 rules that 2-002.01 incorporates.
      • The operative text, quoted verbatim.
      • The required outputs, e.g. regular heating payment, eligibility, and the gross-income test.
      • Companion tests with expected values from the Guidance table.
    • Fix:
      • Edit the empty issue #1464 body to add the items above. rulespec-us#1416 shows the expected form.
      • Candidate companion cases, each hand-derived from the Guidance pp. 1-2 table rather than from policyengine-us output:
        • Size 1, $18,000 wages, gas, single-family: $550.
        • Size 1, $17,000 wages: $550 (Tier 2 only because of the 20% disregard).
        • Size 7, propane: $850 at $30,205 and $580 at $30,205.01.
        • Size 1: gross $23,475 is eligible and $23,475.01 is not.
      • The PR-side line needs no further change.

Suggestions

  1. The PR body implies the heating_type default change alone will lift Nebraska above $0.

  2. The new parameter cites the state-plan page after the one with the earned-income checkboxes.

    • Where: earned_income_sources.yaml:18-19 ("Nebraska FY2026 state plan, Section 1.9, page 7", #page=7).
    • Detail:
      • On the FY2026 plan's page 6 (PNG confirmed), section 1.9 begins and the checked "Wages" and "Self - Employment Income" boxes appear. These are the sources the parameter lists.
      • Page 7 holds the rest of the income checklist and the narrative on 475 NAC treatment and the 20% disregard.
    • Suggested action: Use #page=6 with "Section 1.9, pages 6-7" in the title. The bare page-7 references on ne_liheap_earned_income.py:12 and ne_liheap_gross_income.py:12 can stay, since page 7 carries the SNAP-rule incorporation those variables rely on.

CI

Head 3d36e886d9, run 37035031885, as of about 18:17 UTC on 2026-10-02. 22 pass, 1 fail, 14 pending (12 in progress and 2 queued).

  • Fail: Full Suite - Baseline (ssa-usda) (job 110932650716). This is a runner kill, not a PR failure.
    • The log ends with "make: *** [Makefile:142: test-yaml-no-structural-other-usda] Terminated", then "The runner has received a shutdown signal", then "Process completed with exit code 143".
    • Batch 1 had produced no output for 760 s before the kill. The log has no assertion failures or F results.
    • This shard runs the gov/ssa and gov/usda YAML tests. The PR changes no file there.
    • A re-run is needed for a green board.
  • Nebraska tests:
    • Quick Feedback (Selective Tests + Coverage) passed, and it ran all 77 NE cases (11 + 34 + 3 + 9 + 12 + 2 + 2 + 4, all .).
    • Also passed: codecov/patch and codecov/project, Microsimulation, Household API Partners, Lint, Check changelog fragment, the four smoke-import jobs, Baseline rest-a/rest-b/states-shard-4, Contrib states-shard-4/other-shard-3, and Full Suite - Rest.
  • Pending:
    • Baseline: states-shard-1/2/3, irs, household, reform, contrib-hhs.
    • Contrib: states-shard-1/2/3, other-shard-1/2a/2b, congress.
  • Merge state: MERGEABLE. The status is BLOCKED only because a review is pending.

Review Severity: REQUEST_CHANGES

There are 0 critical issues and 1 remaining should-address item: rulespec-us#1464 must be dispatch-ready to back the queued line. Round-2 Should 2 is fixed through #9754, and every claimed suggestion fix was verified. The ssa-usda failure is a runner kill unrelated to the PR's files and would not block APPROVE by itself. APPROVE requires 0 critical and 0 remaining should-address items.

Next Steps

  • Should Address 1: add to empty issue #1464 the PR link, module path, provision citations, verbatim law, required outputs and companion cases taken from the Guidance table.
  • Optional: Suggestions 1-2.
  • Re-run the ssa-usda shard, and let the 14 pending checks finish.

@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 3 (#9723 (comment)): the heating-default follow-up is now tracked and no value regressions were found. One item remains: rulespec-us#1464 is labelled pe-parity but not yet dispatch-ready (no PR link, module path, provision citations, verbatim law, outputs or companion tests), which the CLAUDE.md axiom-parity rule requires for a queued line. The ssa-usda CI failure is a runner kill unrelated to this PR's files; re-run triggered.

…into ne-liheap

# Conflicts:
#	policyengine_us/programs.yaml
@hua7450

hua7450 commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for round 3. Head is now 72c88eac15: the previous head plus a merge of main, which brings in the CI batching from #9758. No Nebraska code changed in this push.

Should-address 1, rulespec-us#1464. Filled in on 2026-10-02. The issue now has the PR link, scope and policy period; eight proposed module paths, each mapped to its corpus citation path or marked for ingest (the plan and the guidance document are in the corpus; 476 NAC chapters 1 to 3 are not, and 475 NAC chapter 3 is there only as the renumbered July 2026 edition); the regulation, plan and guidance text quoted verbatim, including the full heating payment table and the size 6 or more footnote; a required-outputs table; eleven companion cases derived by hand from the guidance tables, including the size 7 propane boundaries ($30,205 / $30,205.01 / $43,150 / $43,150.01 / $56,095 / $56,095.01) and the one-person limit at $23,475 and $23,476; and the interpretations (market-rate heat in rent, the footnote's "gross countable income" wording, self-employment, student earnings).

Suggestion 1. Reworded in the PR body: totals stay at $0 until both a heating type and a fuel bill are in the microdata, and #9754 covers the heating type only.

Suggestion 2. Left as is for now.

Tests were not run locally; CI runs them.

@hua7450
hua7450 requested a review from DTrim99 October 3, 2026 02:10

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.

2 participants