Skip to content

Apply federal SNAP heat-and-eat SUA restriction in all states - #10033

Merged
hua7450 merged 11 commits into
mainfrom
hub-pb-snap-heat-eat-1009
Oct 12, 2026
Merged

hua7450 merged 11 commits into
mainfrom
hub-pb-snap-heat-eat-1009

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Households without an elderly or disabled SNAP member still receive the heating/cooling Standard Utility Allowance through the modeled state heat-and-eat flag. This PR applies the federal restriction to that deemed eligibility path in every heat-and-eat state. Actual heating/cooling expenses continue to qualify independently, and other utility bills retain the existing LUA/IUA paths.

This generalizes #9374 and #9610, which cover California. The outside contributor's branch is unchanged.

Legal basis and methodology

  • P.L. 119-21 section 10103(a) amended 7 U.S.C. 2014(e)(6)(C)(iv)(I) to require an elderly or disabled member for energy-assistance-based SUA eligibility.
  • The August 29, 2025 USDA FNS implementation memo states that the restriction took effect July 4, 2025. It applies immediately at initial certification and at least by the next recertification for ongoing households. November 1 is the end of the QC variance exclusion, not the federal effective date.
  • The parameter retains the legal July 4 date. SNAP evaluates monthly policy at month start, so July uses the July 1 rule and August 2025 is the first affected full month. The model approximates enacted entitlement, rather than individual certification dates or state administrative rollout.
  • The existing SNAP-qualified membership predicate excludes ineligible co-residents, consistent with 7 CFR 273.1(b)(7). The audited module used the broader SPM-unit predicate and restricted its patch to 2026; this implements the permanent federal provision and uses the existing SNAP household definition.
  • No new household input is needed. The state-option parameter and variable remain intact; only the deemed eligibility leg is gated. Existing assumptions about heat-and-eat payment receipt remain unchanged. A modeled heat-and-eat flag is not evidence that a particular test household actually received an H-EAT payment.
  • Existing federal whole-dollar net-income and contribution rounding remains unchanged; states may elect alternative rounding procedures.

PolicyBench regressions

Cell State Annual SNAP before Annual SNAP after
080 PA $3,600 $3,270
100 MT $8,637 $7,002

The YAML households preserve the snapshot scenario facts and established takeup defaults. Wages, hours worked and capital gains use the leaf aliases applied by the US Simulation adapter, which the Core YAML builder bypasses; this also supplies Montana TANF with the reported wages. A general disability input alone does not establish USDA disability status in either case.

Round 4 scope and baseline calculations

The two independent California corrections have been split out. #10065 owns excluding SNAP from CARE/FERA countable income in both existing dated lists, covering every modeled calendar year. #10036 owns the California Modified Categorical Eligibility / BBCE net-income correction for every household size. This PR restores the CPUC parameter and test paths and the California MCE / BBCE net-test paths to current main. Its changelog and regression scope now cover only the federal heat-and-eat restriction and its consequences under main's existing California rules.

The Massachusetts integration changes remain federal regressions. Both households contain people aged 35, 33 and 8, with no utility costs or disability circumstances. Their former SUA came from the modeled heat-and-eat proxy. Actual H-EAT receipt is not established: the tests also omit shelter costs, which DTA's H-EAT eligibility rules require. They correctly receive $0 SUA under the restriction:

  • Immigration integration Case 3: counted earnings are $2,000 × 2/3 = $1,333.33. With the 20% earned-income deduction and $209 standard deduction, net income is $857.67, rounded to $858. SNAP is $546 − ceil(30% × $858) = $288. The former modeled SUA produced a $485.17 shelter deduction, rounded net income of $373, and SNAP of $434.
  • Ineligible-members integration Case 4: counted earnings are $2,000. Net income is $2,000 − $400 − $209 = $1,391. SNAP is $546 − ceil(30% × $1,391) = $128. The former modeled SUA produced a $218.50 shelter deduction, rounded net income of $1,173, and SNAP of $194.

Their immigration and income-counting assertions remain intact. Both remain within Massachusetts's 200% categorical gross-income standard; SUA changes their allotments, not their categorical eligibility.

The California child-support case is recomputed using main's California eligibility rules. Gross income is ($36,275.59 − $5,200)/12 = $2,589.63. The full-wage 20% earnings deduction remains $604.59 under 7 CFR 273.9(d)(2). Net income before shelter is $2,589.63 − $604.59 − $209 = $1,776.04. Rent of $880 is below half-net income of $888.02, so no shelter deduction applies and net income rounds to $1,776. Main's net-income screen therefore denies categorical eligibility and SNAP, giving $0. The legally correct California MCE treatment, including the one/two-person minimum and larger-household issuance-table allotments, belongs to #10036. The three California-specific MCE regression scenarios (one-person minimum, two-person minimum, and failing gross-income test) are removed from this PR's federal heat-and-eat fixture and deferred to #10036's scope. #10036 already covers the exact one-person case and other failing-gross scenarios; the specific two-person $40,000 scenario is retained as untracked handoff evidence. No edits to either split PR are made here.

Validation and invariants

This follow-up starts at Ziming's partner-approved head 15f8d0cd62d50eb3d29bc734898fffef3657a421. It replaces the 53-jurisdiction, 1,113-household Python differential grid with policy YAML, preserving the monthly effective-date, membership, heating-expense, and fallback cases. Round 4 does not change partner test files or pinned expectations.

Federal regression coverage includes:

  • Michigan's non-elderly/non-disabled household with two non-heating bills receives IUA ($300 in January 2026), because Michigan has no LUA.
  • Two Pennsylvania SPM units share one household: the unit with a 60-year-old receives SUA ($857), while the other receives NONE ($0).
  • Eight households compare restricted heat-and-eat outcomes with matched expense-only controls for NONE, phone IUA, Pennsylvania LUA, and Michigan IUA, checking types and amounts in August 2025 and January 2026.
  • An inline YAML parameter reform restores the former rule for seven representative households, including actual heating, elderly and SSDI exceptions, and non-deeming Texas. It checks state-option flags, SNAP-qualified membership, types, and amounts across July/August 2025 and January 2026.

The July/August YAML boundary remains. Heating and SSDI cases assert January 2026 allowance amounts. Generic reform/baseline and cache-isolation behavior remains covered by existing Core simulation tests.

Only one small Python test remains: it uses Core's public parameter-file loader to check July 3 is unrestricted and July 4 is restricted. YAML cannot assert raw parameter values at exact legal dates. The test constructs no additional country model or simulation.

Round 4 validation: One isolated parameter-boundary Python test passed locally. Three successive single-file child-support YAML attempts were interrupted during country initialization before pytest output (approximately 61, 31, and 49 minutes); the remaining queued YAML files were not launched. No local YAML passing count is claimed. The current-head CI run passed every baseline, contrib, reform, and Household API Partners job, plus PR validation, package compatibility, and the existing microsimulation CI job. Its SSA-USDA job passed 1,693 tests, including the recomputed child-support case and both retained federal PolicyBench regressions; Household API Partners passed 623 tests. The remaining Python Rest CI job is still pending. Local test attempts used one file per foreground process, one at a time. No heavy-run or lock wrapper, folder run, full suite, or microsimulation was launched in this workspace. The parameter-only pytest command used --noconftest --confcutdir=policyengine_us/tests/core to avoid importing the country package through ancestor collection. make format, Ruff lint, and git diff --check passed. The restored paths have no diff against main, and round 4 has no diff in partner expected-value files against the original PR head. Earlier round-3 counts and CI results validated the mixed California/federal tree and do not establish validation of this separated head.

The Python file remains in the existing Rest core group, and the YAML cases remain in the existing USDA batches. No jobs, matrix entries, or runner concurrency are added. Changelog: a fixed fragment records the federal heat-and-eat SUA restriction.

Partner contract tests (updated with approval)

This PR changes 22 partner contract cases (33 expected values) in five files under tests/policy/baseline/partners/. Each move comes from the heat-and-eat restriction: the households have no elderly or disabled member and no heating or cooling expense of their own, so they lose the deemed SUA.

  • amplifi/2026.yaml: case B annual SNAP goes from $1,917 to $1,506.
  • analytics_coverage/edge_cases/federal/nutrition/snap/ca.yaml and ma.yaml: three cases.
  • analytics_coverage/signatures/ca.yaml and federal.yaml: 18 cases. Eleven of them lose SNAP eligibility, because the smaller shelter deduction raises net income above the net standard that the model applies to California non-elderly, non-disabled BBCE households.

@hua7450 owns partner-test changes (Max, 2026-10-09). He answered yes to all three partner-test questions, notified Amplifi and the partners behind the federal signature file, and pushed the pin update in 15f8d0cd62. The full table is in the hub's comment on this PR.

axiom: 7-USC-2014(e)(6)(C)(iv)(I) TheAxiomFoundation/rulespec-us#1622 queued

Hub microsimulation impact — re-run required

Pending: the hub must re-run the impact comparison on the final round-4 head against current main. Earlier microsimulation numbers included the California corrections and are superseded; they must not be interpreted as the impact of this federal-only PR. The former numerical table has been removed.

Run 2025 and 2026 comparisons for at least snap, snap_standard_utility_allowance, snap_utility_allowance, and household_net_income, plus is_snap_eligible, household_benefits, state_income_tax, and income_tax as eligibility, benefit and tax controls. Report weighted sums and changed-record counts. The hub's CI and microsimulation gates apply.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

@hua7450 Max asked the US hub to hand you the API partner notification for this PR.

What changes. This PR applies P.L. 119-21 section 10103(a). It amended 7 U.S.C. 2014(e)(6)(C)(iv)(I) so that energy assistance confers the heating and cooling SUA only on households with an elderly or disabled member. In the model's always-SUA (heat-and-eat) states, a household with neither such a member nor its own heating or cooling expense now gets the LUA, the IUA or no allowance, depending on its other utility bills.

Partner tests. 22 of 623 cases under tests/policy/baseline/partners/ change. All 22 pass on main (4e54d42) and fail at this head (cdce303); the other 601 pass on both.

File Case Output Main This PR
amplifi/2026.yaml amplifi_2026_case_b (2026) snap 1917.0 1506.0
analytics_coverage/edge_cases/federal/nutrition/snap/ca.yaml snap_ca_head_immigration_refugee_cfap_transition (ca) snap 2172.0 2160.0
analytics_coverage/edge_cases/federal/nutrition/snap/ca.yaml snap_ca_head_immigration_undocumented_calworks_interaction (ca) snap 3009.0 2613.0
analytics_coverage/edge_cases/federal/nutrition/snap/ma.yaml snap_ma_head_immigration_undocumented_count_all_state (ma) snap 3825.0 2553.0
analytics_coverage/signatures/ca.yaml signature_29 (8 reqs) snap 7956.0 7722.0
analytics_coverage/signatures/ca.yaml signature_43 (6 reqs) snap 7956.0 7722.0
analytics_coverage/signatures/ca.yaml signature_44 (6 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/ca.yaml signature_46 (6 reqs) snap 7956.0 7722.0
analytics_coverage/signatures/ca.yaml signature_59 (4 reqs) snap 7956.0 7722.0
analytics_coverage/signatures/ca.yaml signature_60 (4 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/ca.yaml signature_61 (4 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/ca.yaml signature_64 (4 reqs, +1 dupes) snap 7956.0 7722.0
analytics_coverage/signatures/ca.yaml signature_79 (4 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/federal.yaml signature_126 (2 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/federal.yaml signature_138 (1 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/federal.yaml signature_139 (1 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/federal.yaml signature_143 (1 reqs) snap 5802.0 4659.0
analytics_coverage/signatures/federal.yaml signature_144 (1 reqs) snap 5802.0 4659.0
analytics_coverage/signatures/federal.yaml signature_151 (1 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/federal.yaml signature_159 (1 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/federal.yaml signature_177 (1 reqs) is_snap_eligible 1.0 0.0
analytics_coverage/signatures/federal.yaml signature_179 (1 reqs) is_snap_eligible 1.0 0.0

For example, Amplifi case_b (Los Angeles, one parent with children aged 2 and 4, utilities included in rent) drops from the $663 monthly SUA to the $20 individual utility allowance for its phone bill. That removes its excess shelter deduction, so its January 2026 SNAP falls from $153 to $119 a month.

The 11 is_snap_eligible cases flip because the smaller shelter deduction raises net income above the federal net standard. The model applies that net test to California BBCE households without an elderly or disabled member (gov.hhs.tanf.non_cash.income_limit.net_applies.non_hheod, CA true), so these households lose both normal and categorical eligibility. The federal signature file runs under the California default because state_code_str doesn't backfill the state_code enum; production does the same.

Approval. On 2026-10-09 Max ran the partner three-question gate and approved updating all 22 pins.

Ask. Please notify Amplifi and the partners whose request signatures are in analytics_coverage/signatures/federal.yaml, then reply here once they've been told. The hub will push the pin update to this branch, but won't mark the PR ready or merge it until you confirm.

@MaxGhenis
MaxGhenis requested a review from hua7450 October 9, 2026 18:05
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

@hua7450 Max has delegated the partner-test go for this PR to you (2026-10-09). I've requested your review; please approve or request changes here.

Partner case. amplifi/2026.yaml, amplifi_2026_case_b: 2026 SNAP is $1,917 on main and $1,506 at this head (cdce303). The other 21 changed cases, all in the analytics_coverage SNAP edge-case and signature files, are in the table in my earlier comment above.

Model change. P.L. 119-21 section 10103(a), via 7 U.S.C. 2014(e)(6)(C)(iv)(I): energy assistance now confers the heating and cooling SUA only on households with an elderly or disabled member. This PR applies that in every state the model treats as heat-and-eat.

The three partner-test questions (policyengine-us CLAUDE.md):

  1. Are you sure you want to edit this test file?
  2. Have you notified a team member about this change?
  3. Have you notified the API partner about this change?

The hub is updating the 22 pins on this branch to the values above. Nothing merges until you approve, and the hub's usual gates also apply: CI, independent review and the microsimulation impact.

- Update 33 values in 22 partner contract cases (Amplifi, CA and federal
  signatures, CA/MA SNAP edge cases). The 11 eligibility flips also take
  snap to 0. Approved through the partner-test gate; partners notified.
- Remove the FNS memo URL, which now returns 404, from the parameter and
  variable references.
- Replace per-year input keys in heat_and_eat/snap.yaml with plain values
  and standard case/person naming; inputs and results are unchanged.

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

hua7450 commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Partner tests updated, partners notified

I've notified Amplifi and the federal-signature partners, and I answered yes to all three partner-test questions. I pushed the pin update in 15f8d0c, so no separate pin push is needed.

Changes in 15f8d0c

  • Partner pins: 22 cases, 33 values. The table above lists only the first failure per case. The 11 eligibility flips also take snap from 3,729 to 0. No other outputs change, and the full partner suite passes locally.
  • Dead link: removed the FNS memo URL, which returns 404, from the parameter and the variable.
  • heat_and_eat/snap.yaml: replaced the per-year '2026': input keys with plain values. Results are unchanged.

Suggestion: replace tests/core/test_snap_heat_and_eat.py with YAML. It took 353 seconds locally, about 2.5× the whole core group. The formula has no per-state logic, so the 53-state grid adds little, and the YAML cases already cover most of its checks. I'd add two cases to the existing snap_utility_allowance_type.yaml instead:

  • an MI household with no elderly or disabled member and two non-heating bills, which gets IUA (no LUA in MI);
  • two PA SPM units in one case, one with a 60-year-old member and one without, which get SUA and NONE.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

@hua7450 A heads-up on the 11 eligibility flips in this PR's partner pins.

They come from a separate model error, not from the heat-and-eat rule. The model applies a net income test to California's BBCE (CalFresh Modified Categorical Eligibility), and California has none. CDSS ACL 12-62 (example 5), ACL 13-32, ACL 14-56 and ACL 15-42 each say an MCE household of three or more gets the issuance-table allotment "even if the household's net income exceeds the maximum amount allowable".

#10036 (draft) removes that test. With its flags on this PR's model, the 11 households stay eligible with a smaller annual benefit:

Cases main this PR's pins with #10036
CA signature_44, 60, 61, 79; federal signature_151 $3,729 $0 $1,416
federal signature_126, 179 $3,729 $0 $1,959
federal signature_138, 139, 159, 177 $3,729 $0 $1,341

The other 11 pins here don't change. #10036 also makes 13 partner cases that are ineligible today eligible; its body has the table.

So the partner notice may need a correction: these households lose part of their benefit, not eligibility. #10036 is going to the US + core hub and will need the partner-test gate too.

@MaxGhenis
MaxGhenis marked this pull request as ready for review October 10, 2026 08:14
@hua7450
hua7450 merged commit 01478e0 into main Oct 12, 2026
27 checks passed
@hua7450
hua7450 deleted the hub-pb-snap-heat-eat-1009 branch October 12, 2026 03:24
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