Skip to content

Add Tennessee LIHEAP regular energy assistance - #10430

Open
hua7450 wants to merge 2 commits into
mainfrom
tn-liheap-wave1d
Open

hua7450 wants to merge 2 commits into
mainfrom
tn-liheap-wave1d

Conversation

@hua7450

@hua7450 hua7450 commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Adds Tennessee LIHEAP regular energy assistance for FY2026 and FY2027, administered by the Tennessee Housing Development Agency (THDA). Tennessee pays one benefit per program year from a single matrix (applied as heating from October through May and as cooling from June through September). The model counts citizens and qualified noncitizens in household size (other members' income still counts), tests gross countable income against the income limit with the federal 110% poverty floor, divides total annual energy cost by income to get an energy burden rounded half up to four decimals, and reads the matrix amount by size group, income group and burden column: $174 to $750 in FY2026 and $300 to $800 in FY2027. In FY2026, propane households receive at least $500, the manual's minimum propane payment.

Fixes #10420

Regulatory authority

Eligibility

Requirement Source How modeled
Tennessee residence Plan defined_for = StateCode.TN
At least one citizen or qualified noncitizen Manual p.17-18 tn_liheap_household_size sums is_citizen_or_legal_immigrant; size 0 is ineligible
Income at or below the limit Plan 2.1; Manual p.24; 2027 plan p.9 and manual p.27 FY2026: 60% of SMI for every size (liheap_smi_limit). FY2027: 60% of SMI for sizes 1-8 and 150% of the 2026 poverty guideline, rounded down, for sizes 9 and over
Federal 110% poverty floor 42 U.S.C. 8624(b)(2)(B) Binds from size 15 in FY2026
Active energy account or energy in rent Manual p.32-33 has_heating_expense or heat_expense_included_in_rent; NONE ineligible, UNSPECIFIED only with heat in rent
Subsidized housing Manual p.32-33 No adjustment: own-name bills are processed as filed, PHA overages are entered as bills

Countable income

Item Source How modeled
Earned income Manual p.27-28; Plan 1.9 Wages and net self-employment, each floored at zero, for members 18 and older who are not tax-unit dependents (the plan excludes minors' earnings; the manual excludes earnings of dependents 18 and older and of dependents in school)
Unearned income Manual p.27 SSI, TANF (Families First, take-up gated), general assistance, railroad, unemployment, strike benefits, workers' compensation, veterans, child support, alimony, regular outside support (financial_assistance), pensions and annuities, military retirement (with survivor annuities), survivor and disability benefits, dividends, rental and estate income, net gambling winnings
Social Security Manual p.27; Plan 1.9 Net of medicare_part_b_premium, floored at zero per person
Interest Manual p.27 Counted in full only above $200 a year per person; the withdrawal condition has no input and is assumed
Not counted Manual p.28 Capital gains, bank withdrawals, retirement-account (IRA, 401(k)) withdrawals (the manual names neither as income; treated like bank withdrawals), sale proceeds, tax refunds, gifts and lump-sum inheritances, one-time insurance, SNAP, foster care, utility allowances

Benefit

  • Energy burden = total annual energy bills (electricity, gas, propane, fuel oil and kerosene, wood, coal, other) divided by annual countable income, rounded half up to four decimals as in the manual's example that rounds 0.0878822197 to 8.79% (p.31-32), so a burden of exactly 0.12145 starts the 0.1215 column. Columns start at 0, 0.0510, 0.0672, 0.0828, 0.0998, 0.1215, 0.1529, 0.2182 and 1.0000. Zero income uses the last column.
  • Size groups 1-2, 3-5, 6-8 and 9 or more (the FY2027 matrix runs the last group to 16; FY2026 households above 12 use the same group).
  • Income groups A-C: FY2026 tops are 71%, 87% and 117% of the 2025 guideline, rounded to cents, which reproduce all 36 printed tops; FY2027 uses the tops printed in LI-12 for sizes 1-16 (larger households use the size-16 row), because they do not follow one rate (size 12 group A, for example). Group D runs to the income limit.
  • Propane: the FY2026 manual sets a $500 minimum payment when a benefit is applied to propane (p.25); propane-heated households are assumed to apply it there. The draft FY2027 manual drops the minimum.
  • No supplement (priority points no longer set amounts, workshop p.23) and no bill cap.

Not modeled and source notes

Item Source Treatment
Energy cost a landlord attributes to a tenant (heat in rent) Manual p.32 No input. These households are eligible and their burden counts only separately billed energy, so their column is a lower bound
30-day income and 12-month energy history Manual p.8, 29-30 Annual amounts stand in
Black Lung $20 disregard, royalties, severance, adoption assistance, training stipends, military allotments, irregular income Manual p.27 No existing inputs
SSN refusal, prior-year LIHEAP credit, waitlist and priority order Manual p.13, 17-18, 33 Not represented; the model returns the entitlement
FY2027 LI-12 ceilings for sizes 13-16 ($125,910-$150,660) LI-12 p.4 Below the stated 150% rule ($126,180-$151,740); the rule is used
Printed FY2026 size 8 ceiling $85,064.50 and size 6 copies of $81,336 Matrix; workshop The 60% SMI rule gives $85,064 and $81,366
Crisis assistance and weatherization Manual Out of scope

FY2027 relies on the posted LI-12 matrix while THDA's FY2027 plan (status Saved) and manual are drafts; the program page still announces the 2025-26 season. Earlier years are unverified estimates through parameter backfilling.

Microsimulation: heating_type and the per-fuel bills are not in current datasets; callers must supply them.

Test plan

49 YAML cases in 4 files (not re-run locally after the review fixes; CI validates them):

  • limits for FY2026 sizes 1, 8 and 13 and FY2027 sizes 8, 9 and 13, the exact-limit boundary and the size-15 floor, and NONE or UNSPECIFIED fuel that stays ineligible even with a heating expense;

  • countable income: a 17-year-old, an 18-year-old non-dependent and an adult dependent, Social Security net of Part B, interest at $200 and $201, child support, gambling, TANF, SSI and outside support;

  • half-up rounding of a burden of exactly 0.12145 onto the 0.1215 column, zero income, income-group edges in FY2026 (including income exactly at a printed top) and at printed FY2027 tops, size groups, a size-13 household in each year, a size-9 FY2027 household eligible only under the 150% rule, the propane minimum in FY2026 and none in FY2027, heat in rent.

  • YAML tests with expected values from the plans, matrices and manual

  • ruff format

  • Changelog fragment in changelog.d/

  • CI passes

axiom: TheAxiomFoundation/rulespec-us#1891 queued

🤖 Generated with Claude Code

hua7450 and others added 2 commits October 23, 2026 18:11
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	policyengine_us/programs.yaml
@codecov

codecov Bot commented Oct 23, 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 (5ddb74f).
⚠️ Report is 649 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main    #10430   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         5    +1     
  Lines           76       119   +43     
  Branches         2         4    +2     
=========================================
+ Hits            76       119   +43     
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.

@DTrim99

DTrim99 commented Oct 27, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Add Tennessee LIHEAP regular energy assistance

PR #10430 (author: hua7450), head 5ddb74f1cc. This is a first review. The PR adds Tennessee's LIHEAP regular assistance, run by the Tennessee Housing Development Agency (THDA), for FY2026 and FY2027 (model years 2026 and 2027). It includes:

  • 19 parameter files and 5 variables (no new inputs);
  • 4 test files (49 cases);
  • a programs.yaml entry (coverage line and state block);
  • a changelog fragment.

The PR has no reviews and no comments apart from Codecov. It touches no partner test file.

Path prefixes:

  • P/ = policyengine_us/parameters/gov/states/tn/thda/liheap/
  • V/ = policyengine_us/variables/gov/states/tn/thda/liheap/
  • T/ = policyengine_us/tests/policy/baseline/gov/states/tn/thda/liheap/

Sources read for this review:

Summary

What is right. The tables, limits and benefit mechanics are encoded correctly:

  • Matrices. All 144 encoded cells (4 size groups by 4 income groups by 9 columns) match the 2026 matrix and LI-12 for both years. Rows are identical within the size groups 1-2, 3-5, 6-8 and 9 and over, as the PR says. The plans' $174/$750 and $300/$800 equal the lowest and highest cells.
  • Income groups. For FY2026, 71%, 87% and 117% of the 2025 guideline, rounded to cents, reproduce the printed tops (spot-checked for sizes 1, 2, 3 and 12). For FY2027, all 48 printed tops for sizes 1-16 are transcribed exactly, including the odd size-4 group B top of $28,710.51.
  • Limits. For FY2026, 60% of SMI (four-person $61,641) reproduces every printed ceiling for sizes 1-12; the matrix's $85,064.50 for size 8 is off by 50 cents. For FY2027, 60% of SMI for sizes 1-8 and 150% of the 2026 guideline for sizes 9-12 reproduce LI-12. Both draft-plan versions list 150% for sizes 9-15, and the draft manual lists sizes 9-16.
  • Federal floor. The 110% floor uses the lagged guideline and a strict <. It binds from size 15 in FY2026, and both sides of it are tested.
  • Burden. Total bills over income, rounded half up to four decimals, select the right column, and zero income takes column 9.
  • Income rules.
    • Earned income is gross, and minors' and adult dependents' earnings are excluded (plan 1.9; manual p. 28).
    • Losses are floored per source and per person.
    • Interest counts only above $200, and gambling winnings count net.
    • TANF counts through the take-up-gated tanf.
    • Mixed-status members are excluded from size, but their income counts (pp. 17-18).
  • Tests and CI. I hand-checked 18 expectations below, and CI passed all 49 cases.
  • Guards. Integrate modeled state unemployment insurance into income flows #9558, Count military SBP annuities in state benefit income lists #10317, the Count each Social Security benefit once in Pennsylvania CCW countable income #10408 pattern and the Tie source-conflict markers to the register shared with Axiom #10287 ratchet all pass on the merged tree. The NH Add New Hampshire state supplementation for 2026 #10156 key pattern is safe.

There are no critical findings and three should-address items:

  • S1. Active account. Eligibility requires a bill for the primary heating fuel and excludes NONE. Tennessee requires only an active energy account and applies the same benefit as cooling assistance. A no-heat household with an electric bill gets $0 instead of $445, and eligibility Case 5 pins the $0.
  • S2. Medicare premiums. Only the Part B premium is netted, and only from Social Security. The manual nets "Medicare premiums" from Social Security, pensions and VA benefits. A railroad retiree whose Part B is withheld from the RRB annuity is counted gross: $0 instead of $250 in the example below.
  • S3. Untested entries. 18 of the 23 income-source entries and 4 of the 7 energy-cost entries never take a positive value in a test, and the size-16 table clip has no case.

There are also five suggestions:

  • G1: retirement-account withdrawals and the plan's "Retirement / pension benefits" box.
  • G2: record the source choices as backlog candidates.
  • G3: base the propane minimum on a propane bill.
  • G4: small documentation fixes.
  • G5: backfilled pre-FY2026 years.

Status.

  • CI: 29 pass and 3 skipping (a superseded run).
  • Branch: 2 commits ahead of main and 60 behind. The only conflict is the programs.yaml coverage line (branch note).

Critical (must fix)

None.

Should address

S1. Eligibility requires a primary-heating-fuel bill and excludes NONE, but Tennessee requires only an active energy account and pays the same benefit as cooling assistance

  • Where:
    • V/eligibility/tn_liheap_eligible.py:34 sets responsible = has_heating_expense | heat_in_rent. On main, has_heating_expense is true only when "the primary heating fuel's bill is positive", so an electric bill counts only if electricity is the heating fuel.
    • Lines 44-46 (fuel_qualifies) exclude NONE outright, and exclude UNSPECIFIED unless heat is in the rent.
    • T/eligibility/tn_liheap_eligible.yaml Case 5 (line 114) gives a NONE household a $1,680 electric bill and pins it ineligible. Case 7 (line 155) does the same for UNSPECIFIED.
  • Sources:
    • Eligibility. Manual 2.18 (2026 p. 33): "Applicants without an energy burden (i.e., those who do not have an active energy account) are not eligible". An "Active Account" is "A current utility account that reflects billing and usage" (p. 8). No fuel requirement appears.
    • One benefit, heating or cooling.
      • Manual p. 35: "Heating Assistance is applied from October through May. Cooling Assistance is applied from June through September."
      • The FY2026 plan runs a cooling component (item 1.1, p. 4, May 1 to September 30). Section 3 (pp. 10-11) gives it the same 60% SMI limit and the same $174-$750 benefits.
      • The draft 2027 manual (p. 18): "Each approved household must apply their energy assistance benefit to one (1) utility, (primary source of heating or cooling)."
    • Burden. The burden uses "all energy usage (electric, gas, propane, etc.)" (p. 8). The matrix has no fuel dimension, so the fuel matters only for the FY2026 propane minimum.
  • Effect (hand-traced; 2026, a single adult aged 40 with wages of $15,080 and a $1,680 electric bill). The rule's award is the same in each case: burden 1,680 / 15,080 = 0.111406, rounded to 0.1114, gives column 5. $15,080 is group C (13,615.51-18,310.50), and sizes 1-2 group C column 5 is $445.
    • (a) No heating (NONE), the facts of Case 5. Head: fuel_qualifies is false, so $0. Rule: an active electric account, so $445, applied as cooling or to the electric account.
    • (b) Wood heat from gathered wood (wood_expense 0) and the electric bill. Head: has_heating_expense reads only the wood bill, so $0. Rule: $445.
    • (c) UNSPECIFIED with the electric bill, the facts of Case 7. Head: $0. The wave has accepted UNSPECIFIED at $0 where a program needs the fuel. Tennessee's award does not need it, so I recommend the same fix, but this finding rests on (a) and (b).
  • Precedent. Arizona LIHEAP (Add Arizona LIHEAP Standard benefit #10293, merged) keeps NONE eligible "because the benefit covers cooling". New Mexico (Add New Mexico LIHEAP regular heating assistance #10431 S1, cooling-only households at $0) and Maine (Add Maine HEAP Fuel Assistance #10437 S3, a fuel gate the rule does not impose) were both rated should.
  • Severity: should. This is a wrong result in a claimed year with existing inputs, and a test pins it.
  • Fix:
    • Define an energy cost from energy_cost_sources (for example, a tn_liheap_energy_cost variable that tn_liheap also reads). Set responsible = (energy_cost > 0) | heat_in_rent.
    • Drop the NONE and UNSPECIFIED clauses. A no-heat household with no bill and no heat in rent stays ineligible through the energy-cost test.
    • Re-pin eligibility Cases 5 and 7, and add case (b).
    • Update the body's eligibility row, the comment at lines 31-43, and Axiom interpretation 8 and companion test 9(a)-(b).

S2. Medicare premiums are netted only as Part B, and only from Social Security; the manual nets Medicare premiums from Social Security, pensions and VA benefits

  • Where:
    • V/income/tn_liheap_countable_income.py:36-43 computes max_(social_security - medicare_part_b_premium, 0) per person.
    • railroad_benefits, pension_income, military_retirement_income and veterans_benefits are summed gross from P/income/sources/unearned.yaml.
    • The body ("Net of medicare_part_b_premium") and Axiom interpretation 13 ("premiums withheld from pensions or VA benefits ... are not subtracted") describe this, but neither cites a source for the narrowing.
  • Sources:
    • Manual 2.13 (2026 p. 27; draft 2027 p. 29, the same words): "Net income from Social Security, pensions (private and government, including military retirement pay), and VA benefits (excluding Medicare premiums, overpayment recovery, or garnishment payments)". The same page lists "railroad retirement" beside Social Security among the regular payments.
    • Plan 1.9 (FY2026 p. 6 and the FY2027 draft): SSA benefits "Excluding MediCare deduction".
    • RRB withholding. The RRB's 2026 release says the monthly Part B premium "will be taken out of your monthly Social Security or Railroad Retirement Board (RRB) benefit automatically". For a railroad annuitant, the premium comes out of the RRB check, which the head never nets.
    • "Medicare premiums" is general. The wave precedent says Part A matters where the rule covers "Medicare premiums" generally. medicare_part_a_premium is on main, and Arizona LIHEAP (Add Arizona LIHEAP Standard benefit #10293, merged) subtracts both premiums.
  • Effect (hand-traced; 2026, a single person aged 70 with railroad_benefits of $33,000, medicare_part_b_premium of $2,434.80 (the input Case 5 uses), no Social Security and a $1,680 electric bill):
    • Head: countable income 33,000 + max(0 − 2,434.80, 0) = 33,000, above the 32,053 limit and the 17,215 floor, so $0.
    • Rule: 33,000 − 2,434.80 = 30,565.20 is eligible and in group D. Burden 1,680 / 30,565.20 = 0.054965, rounded to 0.0550, gives column 2: $250.
    • Away from the limit, the overstatement of $2,434.80 a year can still move the income group or burden column.
  • Severity: should, as in the wave's Medicare-netting precedents (VA Add Virginia EAP Fuel Assistance (LIHEAP regular heating) #10303, AZ Add Arizona LIHEAP Standard benefit #10293, IA Add Iowa LIHEAP regular heating assistance #10292). The PR nets part of what the state's rule nets, and the gap is material for RRB annuitants.
  • Fix:
    • Per person, take social_security, railroad_benefits, pension_income, military_retirement_income and veterans_benefits out of the plain sum. Count max(their total − medicare_part_a_premium − medicare_part_b_premium, 0) instead, and remove those entries from the unearned list.
    • Case 5 is unchanged, because its second person has no other income.
    • Add the RRB case above and a Part A case.
    • Update the body and Axiom interpretation 13.

S3. 18 of the 23 income-source entries, 4 of the 7 energy-cost entries and the size-16 table clip have no test that would fail if they were dropped

  • Where: P/income/sources/earned.yaml:9-13, P/income/sources/unearned.yaml:4-28, P/payment/energy_cost_sources.yaml and V/tn_liheap.py:79.
  • Untested entries. No case gives these a positive value:
    • Earned (3 of 5): sstb_self_employment_income and farm_operations_income never appear. partnership_s_corp_income appears only as −$1,500 (countable Case 1), which floors to 0, the same result as dropping it.
    • Unearned (15 of 18):
      • general_assistance, railroad_benefits, total_unemployment_compensation, strike_benefits and workers_compensation;
      • veterans_benefits, alimony_income, pension_income, military_retirement_income, survivor_benefits and disability_benefits;
      • ordinary_dividend_income, farm_rent_income and estate_income;
      • rental_income, which appears only as −$1,800.
    • Energy cost (4 of 7): fuel_oil_expense, wood_expense, coal_expense and other_heating_fuel_expense never appear. Axiom companion test 9(f) describes a fuel-oil award that the YAML does not have.
  • Tested:
    • Sources: wages, self_employment_income, ssi, child_support_received and financial_assistance, plus Social Security, interest, gambling and tanf outside the lists.
    • Floors: the earned and unearned per-source floors are pinned (Case 1 expects 18,080, not 14,780), and so are the Social Security and gambling per-person floors (Cases 5 and 8).
    • Bills: electricity, gas and propane.
  • Branch. clip(size, 1, max_table_size) sends FY2027 households above 16 to the size-16 row. No case has 17 members, so removing the upper clip (which would raise a missing-key error) fails nothing.
  • Severity: should, as in Add Maine HEAP Fuel Assistance #10437 S4, Add Vermont Seasonal Fuel Assistance #10436 S2, Add Nevada Energy Assistance Program Fixed Annual Credit #10432 S1 and Add Wisconsin WHEAP regular heating benefit #10434 S1 (the mutation rule).
  • Fix:
    • Add one countable-income case that gives every listed source a distinct positive amount. Enter unemployment_compensation and military_retirement_pay_survivors so the two totals are exercised.
    • Add a burden case with fuel oil, wood, coal and other bills.
    • Add a 17-person FY2027 case.
    • Add the new cases to the rulespec-us#1891 companion tests.

Suggestions

G1. Retirement-account withdrawals.

  • The head. P/income/sources/unearned.yaml:31-35 and countable Case 7 exclude IRA and 401(k) withdrawals "like bank withdrawals".
  • The sources.
    • Plan 1.9 checks "Retirement / pension benefits" as countable (FY2026 p. 6; the FY2027 draft too).
    • Manual p. 9 defines household income as "Total annual gross cash receipts from all household members, before taxes, excluding amounts listed in the LIHEAP State Plan".
    • The exclusion names only "Withdrawals from a bank account" (p. 28).
  • Why it is only a suggestion. The PR's reading follows the older Census money-income convention ("assets drawn down"), and the Maine and Add Louisiana LIHEAP regular heating assistance #10429 siblings were accepted with the same exclusion.
  • Effect (a single retiree aged 70: Social Security $12,000, Part B $2,434.80, IRA withdrawals $20,000, electricity $1,680):
    • Head: 9,565.20 is group A; burden 0.1756 gives column 7: $710.
    • Counting the withdrawals: 29,565.20 is group D; 0.0568 gives column 2: $250.
  • Fix: ask THDA, count retirement_distributions, or record the choice as a backlog candidate (G2).

G2. Record the source choices as backlog candidates.

G3. Base the FY2026 propane minimum on a propane bill.

  • The rule. Manual p. 25: "where an approved applicant receives a benefit under $500, but the home uses propane as a deliverable fuel, the applicant will have the option to apply their benefit to propane". The text says "uses", not "primary".
  • The head. V/tn_liheap.py:90-92 keys the minimum on heating_type == PROPANE, which misses two cases:
    • (i) Propane but not propane heat. An electric-heat household with a propane bill (for a range or water heater) could apply its benefit to propane. Wages $20,000, electricity $1,000 and propane $200 give column 2, group D: the head pays $250, against $500.
    • (ii) Propane heat in the rent. A tenant with propane heat included in the rent and no propane account of its own gets $500 in the head. The matrix amount is $174 (wages $15,080, column 1, group C).
  • Fix: use bottled_gas_expense > 0, or document both assumptions.

G4. Small documentation fixes.

  • (a) Seasons.
    • The plans. Item 1.1 of both plans (p. 4) runs heating from October 1 to April 30 and cooling from May 1 to September 30.
    • The manual. Page 35 says October-May and June-September.
    • The head. The tn_liheap documentation and the body use the manual's months. Cite both, or use the plan's.
  • (b) Interest. The body applies the $200 threshold "per person", but the manual says neither per person nor per household. State the basis.
  • (c) Newer plan file. A newer accessible copy of the FY2027 draft plan (LIHEAP_DETAILED-MODEL-PLAN-LIHEAP_10_01_2026-002.pdf, 57 pages, also status Saved) is posted. It has the same 2.1 table and the same $300/$800 benefits, so re-citing it is optional.
  • (d) Mixed-state case. An optional two-state case would pin item 15 (see Verified).

G5. Earlier years.

  • The head. Every parameter starts on 2025-10-01, so model years before 2026 backfill FY2026 values. The registry and the body correctly claim only 2026-2027.
  • The old program. Before FY2026, Tennessee used a priority-points matrix (the FY2025 matrix, "Priority Points and Benefit Levels Matrices"; workshop p. 23: "Priority Points will no longer determine placement or benefit amount"). So backfilled results do not approximate the old program.
  • Fix: none needed (NJ S3 precedent). Optionally say so in the documentation.

Verified correct

Hand-checked expectations (18, all match the head):

Test Hand computation Expected
tn_liheap Case 1 top A 15,650 × 0.71 = 11,111.50 (income at top, group A); 1,680 / 11,111.50 = 0.1512, column 6 560
tn_liheap Case 2 11,111.51, group B; 0.1512, column 6 555
tn_liheap Case 4 18,310.51 > 15,650 × 1.17, group D; 2,580 / 18,310.51 = 0.1409, column 6 540
tn_liheap Case 5 2,429 / 20,000 = 0.12145, rounded half up to 0.1215, column 6, group D 540
tn_liheap Case 6 1,018.80 / 20,000 = 0.05094, 0.0509, column 1 174
tn_liheap Case 7 zero income: column 9, group A 750
tn_liheap Case 10 size 6, top A 43,150 × 0.71 = 30,636.50; 2,280 / 30,160 = 0.0756, column 3; sizes 6-8 A 565
tn_liheap Case 11 size 13, guideline 81,650: tops 57,971.50 and 71,035.50, so 68,000 is group B; 0.06, column 2; 9+ B 525
tn_liheap Case 12 1,200 / 20,000 = 0.06, column 2, group D 250; max(250, 500) 500
tn_liheap Case 13 2,880 / 15,080 = 0.1910, column 7, group C 700 ≥ 500 700
tn_liheap Case 17 (2027) size 4, printed B top 28,710.51 (income at top, group B); 2,600 / 28,710.51 = 0.0906, column 4; sizes 3-5 B 505
tn_liheap Case 18 (2027) size 13, printed tops 59,597.50 and 73,027.50, so 70,000 is group B; 0.06, column 2; 9+ B 605
tn_liheap Case 20 size 3, top C 26,650 × 1.17 = 31,180.50 (rounded to cents, group C); 2,880 / 31,180.50 = 0.0924, column 4; sizes 3-5 C 400
tn_liheap Case 21 (2027) size 9: 1.5 × 61,400 = 92,100; 60% SMI 63,196 × 1.41 = 89,106; C top 71,838.50, so group D; 0.0467, column 1 92,100 / 540
eligibility Cases 3 and 4 limit floor(61,641 × 1.59) = 98,009; floor (15,650 + 5,500 × 14) × 1.1 = 101,915; 101,914 < 101,915 but 101,915 is not true / false
income limit Case 6 (2027) 1.5 × (15,960 + 5,680 × 12) = 126,180 126,180
countable Case 5 (24,000 − 2,434.80) + max(1,800 − 2,434.80, 0) 21,565.20
countable Case 11 994 × 12 + 1,200 13,128

Batch checks:

  • 1. Plan and manual first. All cells, tops and limits were checked as above. The FY2026 and FY2027 timing (October 1 parameter dates; model year = federal FY) is right.
    • FY2027 values. They come from the posted LI-12, whose $300/$800 range equals both draft-plan versions' item 2.6, and the stated 9-and-over rule appears in both drafts. The registry's verified_years: "2026-2027" is backed by published values (contrast Add Vermont Seasonal Fuel Assistance #10436 S3).
  • 2. Income.
  • 3. Backdating. Only 2026-2027 are claimed (see G5).
  • 4. Arrangements.
    • Housing. Heat in rent is eligible and gets the separately billed burden (documented lower bound). Subsidized tenants meet no added condition (2.18).
    • Eligibility rules. There is no categorical eligibility (plan 1.4, "No"), no asset test and no supplement.
    • Fuel. See S1.
  • 5. Tests. Periods are plain. The edges are covered: the exact limit, the floor on both sides, income at printed tops, the rounding tie and sizes 1, 2, 3, 6, 8, 9, 13 and 15.
  • 6. Descriptions. All 19 follow the house template.
  • 7. References. Every anchor I opened shows its value:
    • 2026 manual: p. 8 (Child, Annual Average), p. 9 (Household Income), pp. 17-18 (mixed status), p. 24 (2.10), p. 25 (propane), pp. 27-28 (2.13), pp. 31-32 (2.17) and p. 34 (Benefit Levels).
    • Plans: the FY2026 plan's pp. 5-7 (1.8-1.9), p. 8 (2.1) and p. 9 (2.5-2.6); the FY2027 draft's p. 9 (2.1) and p. 12 (2.5-2.6).
    • Draft 2027 manual: p. 18 (deliverable fuels), p. 27 (2.10), p. 29 (2.13) and p. 30 (exclusions).
    • Workshop: pp. 28-30.
    • Form. Multi-page titles use #page a-b or #page a,b, and the variable tuples carry # PDF pages comments.
  • 8. Wiring. The programs.yaml entry is complete. No merged LIHEAP state feeds a household aggregate, so none is needed. Every variable is gated by StateCode.TN or tn_liheap_eligible.
  • 11, Integrate modeled state unemployment insurance into income flows #9558. The list reads total_unemployment_compensation.
  • 12. IIJA. There is no IIJA supplement.
  • 13. Mutation. See S3. Every eligibility and benefit branch other than the size-16 clip is pinned: both uses_fpg_rates branches, the propane minimum in both years, zero income, size 0 and the floor.
  • 14. Health premiums. Tennessee deducts none from wages, and neither does the head.
  • 15, NH Add New Hampshire state supplementation for 2026 #10156. For non-residents, tn_liheap_household_size is 0, but every key stays valid:
    • size_group.calc(0) is 1;
    • clip(size, 1, 16) keeps the table row valid;
    • the column comes from a bracket calc or amounts[-1];
    • fpg and liheap_smi_limit use size arithmetically, not as a key.
  • 16, Wire military retirement pay and survivors into federal and state tax (#10181) #10182. The list reads military_retirement_income.
  • 17. State SSP. Tennessee "does not provide optional supplementation" (SSA), and main has no tn_ssp. SSI is counted, so nothing is missing.
  • Federal floor. 42 U.S.C. 8624(b)(2)(B) is applied with the 2025 guideline in FY2026 and the 2026 guideline in FY2027.
  • Count each Social Security benefit once in Pennsylvania CCW countable income #10408 pattern. social_security is read once, in Python, and no list names it or a component. survivor_benefits and disability_benefits are non-Social Security inputs.
  • Changelog. A top-level changelog.d/tn-liheap-wave1d.added.md.

Axiom line assessment

axiom: TheAxiomFoundation/rulespec-us#1891 queued is valid.

  • The issue. It is OPEN and labelled pe-parity, and it is dispatch-ready: proposed module paths, corpus citations and status, verbatim source text, required outputs and companion tests computed from the matrices, plans and manual.
  • The blocker. There is no reviewed oracle revision; the workshop deck, the draft FY2027 manual and plan, and the IM are missing from the corpus; and billed runs need approval.
  • The match. It describes head 5ddb74f1cc and the 49 cases (21/10/7/11), with total_unemployment_compensation and military_retirement_income in the unearned list.
  • After the fixes. Refresh the head SHA and case counts; interpretation 8 and companion test 9(a)-(b) (S1); interpretation 13 and companion test 12(b) (S2); the new companion tests (S3, including the fuel-oil award 9(f) already described); and interpretation 10 if G3 is taken.

CI status

gh pr checks 10430 at head 5ddb74f1cc: 29 pass and 3 skipping (the superseded run 40032341205). Run 40032551559 covers the head:

  • Coverage. All baseline and contrib shards, the guard tests, the household partner suite, microsimulation and Codecov pass.
  • Failures. None.

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: 0 critical, 3 should (fuel-bill eligibility excludes households Tennessee serves; Medicare premium netting narrower than manual 2.13; untested income sources and branches). Full report in the comment above.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Tennessee LIHEAP regular heating assistance

2 participants