Skip to content

SNAP work requirements applied as household-wide disqualification instead of per-person exclusion #8139

@CalebPena

Description

@CalebPena

Summary

meets_snap_work_requirements disqualifies the entire SPM unit whenever any single member fails their per-person work-requirement check. Under 7 CFR 273.7(f)(1) (general work requirements) and 7 CFR 273.24(b) (ABAWD time limit), the default rule is individual disqualification — the non-compliant person is excluded from the SNAP unit, but the remaining members continue to receive SNAP with income/resources prorated per 7 CFR 273.11(c)(2).

There is a narrow state-optional exception at 7 CFR 273.7(f)(5) permitting household-wide disqualification when the head of household fails a general work requirement, elected by only 8 jurisdictions and bounded in multiple ways. The current code's universal "any member fails → household denied" behavior matches no jurisdiction.

This is the same structural bug class as #8133 (ineligible-student / immigration filters) and the parent-exception issue: per-person exclusions being applied as household-wide disqualifications instead of as individual unit exclusions.

Location

policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.py:29-34

meets_work_requirements_person = where(
    no_dependent_child,
    abawd_work_requirements & general_work_requirements,
    general_work_requirements,
)
return spm_unit.sum(~meets_work_requirements_person) == 0

The sum(~passes) == 0 aggregation is equivalent to "all members pass." Any single non-compliant member denies the household. This flows into is_snap_eligible via & work_requirements_eligibility.

Regulatory framework

Default rule: individual disqualification

7 CFR 273.7(f)(1) — general work requirements:

"A nonexempt individual who refuses or fails without good cause to comply with SNAP work requirements is ineligible to participate in SNAP."

Disqualification applies to the individual; remaining members continue to receive SNAP.

7 CFR 273.24(b) — ABAWD time limit:

"Individuals are not eligible to participate in SNAP as a member of any household if the individual received SNAP benefits for more than three countable months during any three-year period..."

7 CFR 273.24(b)(4) directs income/resources of the ineligible individual to be handled under § 273.11(c)(2) — prorated, with the eligible members' portion budgeted. ABAWD disqualification has no HoH option — it is always individual.

Narrow state option: 7 CFR 273.7(f)(5)

"If the individual who becomes ineligible under paragraph (f)(1) of this section is the head of a household, the State agency, at its option, may disqualify the entire household from SNAP participation" for "a period that does not exceed the lesser of: (A) The duration of the ineligibility of the noncompliant individual... or (B) 180 days."

Four conditions, all of which must hold:

  1. State option — states must affirmatively elect in their SNAP state plan.
  2. Head of household only — a non-HoH member failing does NOT trigger whole-household denial.
  3. General work requirement only — ABAWD failures (273.24) have no HoH option.
  4. Time-limited punitive period — ≤180 days, not a permanent eligibility bar.

State-by-state adoption (USDA FNS SNAP State Options Report, 16th Edition, June 2024, page 20)

Disqualify only the individual (45 jurisdictions — default rule):

AL, AK, AR, CA, CO, CT, DE, DC, GA, GU, HI, ID, IL, IN, IA, KS, KY, LA, ME, MD, MI, MO, MT, NE, NV, NH, NJ, NM, NY, NC, ND, OH, OK, OR, PA, RI, SC, SD, TN, UT, VT, WA, WV, WI, WY

Disqualify entire household if HoH fails general work requirements (8 jurisdictions):

AZ, FL, MA, MN, MS, TX, VA, VI

HR1 / OBBBA (effective 2025-11-01) does not change this framework

HR1 expanded who is subject to SNAP work requirements:

  • General work requirement age: 18–59 → 18–64
  • ABAWD age ceiling raised
  • Parent-of-dependent exemption narrowed (child <18 → child <14)
  • Removed exemptions: homeless, veterans, former foster youth (phased)
  • Added exemptions: Indian / Urban Indian / California Indian (per IHCIA)
  • Waiver eligibility tightened to areas with unemployment >10%

HR1 did not alter the individual-vs-household disqualification framework or the 7 CFR 273.7(f)(5) state-option structure. The bug persists under both pre-HR1 and post-HR1 rules.

Why the current code is wrong in every jurisdiction

The current behavior — "any member fails either general or ABAWD → whole household denied" — over-applies 273.7(f)(5) across four dimensions:

Aspect 273.7(f)(5) Current code
Trigger HoH fails Any member fails
Work-requirement type General only Both general and ABAWD
State coverage 8 jurisdictions that elect All states
Duration ≤180 days, punitive period Permanent / continuous
  • In the 45 non-electing jurisdictions: any work-requirement failure should be individual per 273.7(f)(1) or 273.24(b). Code denies whole household. ❌
  • In the 8 electing jurisdictions (AZ, FL, MA, MN, MS, TX, VA, VI): code denies when non-HoH fails (not allowed under 273.7(f)(5)), when anyone fails ABAWD (no HoH option for 273.24), and without the 180-day cap. ❌
  • HR1 impact: because HR1 expanded the subject population without changing consequence rules, the microsim bias from this bug grew post-2025-11-01.

Reproducing scenario

Two working-age adults, no dependents:

  • Adult A: 35, works 40 hrs/wk — passes general (30 hr/wk) and ABAWD (80 hr/month).
  • Adult B: 30, not working, not disabled, no exemption — fails.

Current output:

Variable Value
meets_snap_general_work_requirements [A, B] [True, False]
meets_snap_abawd_work_requirements [A, B] [True, False]
meets_snap_work_requirements (SPM unit) [False]

Per default regulation (all 45 non-electing jurisdictions; CA in this test): Adult B is individually disqualified, Adult A continues to receive SNAP as a 1-person household with income prorated under 273.11(c)(2).

Reproduction (tested)

"""
Reproduction: SNAP work requirements applied as household-wide
disqualification instead of per-person exclusion.

Tested against policyengine_us master (commit 7f30058e5f).
"""

from policyengine_us import Simulation


def build_situation() -> dict:
    """Two working-age adults, no dependents, in California (individual-
    disqualification state).

    Adult A works 40 hrs/week -> passes general (30 hr/wk) and ABAWD.
    Adult B does not work, not disabled, not exempt -> fails.

    All other per-person exclusion inputs (students, immigration, TANF)
    zeroed out so the only possible disqualification is work-related.
    """
    return {
        "people": {
            "adult_a": {
                "age": {"2024": 35},
                "is_tax_unit_head": {"2024": True},
                "weekly_hours_worked_before_lsr": {"2024": 40},
                "is_disabled": {"2024": False},
                "is_federal_work_study_participant": {"2024": False},
                "is_snap_higher_ed_student": {"2024": False},
                "tanf_person": {"2024": 0},
                "is_pregnant": {"2024": False},
                "is_veteran": {"2024": False},
                "is_incapable_of_self_care": {"2024": False},
            },
            "adult_b": {
                "age": {"2024": 30},
                "is_tax_unit_spouse": {"2024": True},
                "weekly_hours_worked_before_lsr": {"2024": 0},
                "is_disabled": {"2024": False},
                "is_federal_work_study_participant": {"2024": False},
                "is_snap_higher_ed_student": {"2024": False},
                "tanf_person": {"2024": 0},
                "is_pregnant": {"2024": False},
                "is_veteran": {"2024": False},
                "is_incapable_of_self_care": {"2024": False},
            },
        },
        "families": {"fam": {"members": ["adult_a", "adult_b"]}},
        "marital_units": {"mu": {"members": ["adult_a", "adult_b"]}},
        "tax_units": {"tu": {"members": ["adult_a", "adult_b"]}},
        "spm_units": {"spm": {"members": ["adult_a", "adult_b"]}},
        "households": {
            "hh": {
                "members": ["adult_a", "adult_b"],
                "state_code": {"2024": "CA"},
            }
        },
    }


sim = Simulation(situation=build_situation())

general = sim.calculate("meets_snap_general_work_requirements", "2024-01").tolist()
abawd = sim.calculate("meets_snap_abawd_work_requirements", "2024-01").tolist()
unit = sim.calculate("meets_snap_work_requirements", "2024-01").tolist()

print(f"meets_snap_general_work_requirements [A, B] = {general}")
print(f"meets_snap_abawd_work_requirements   [A, B] = {abawd}")
print(f"meets_snap_work_requirements (SPM unit)     = {unit}")

Actual output

meets_snap_general_work_requirements [A, B] = [True, False]
meets_snap_abawd_work_requirements   [A, B] = [True, False]
meets_snap_work_requirements (SPM unit)     = [False]   ← BUG

Expected output (California, individual-disqualification jurisdiction)

meets_snap_work_requirements (SPM unit) = [True]

Adult B is individually disqualified and excluded from the SNAP unit for benefit calculation; Adult A continues as an eligible household member.

Recommended fix

Option A — Default to individual disqualification everywhere (recommended first pass)

Replace the universal-quantifier aggregation with an existential one:

meets_work_requirements_person = where(
    no_dependent_child,
    abawd_work_requirements & general_work_requirements,
    general_work_requirements,
)
return spm_unit.any(meets_work_requirements_person)

Option B — State-parameterized, fully accurate

Add a new parameter at policyengine_us/parameters/gov/usda/snap/work_requirements/hoh_household_disqualification_option.yaml:

description: >
  Whether the state has elected the option under 7 CFR 273.7(f)(5) to
  disqualify the entire SNAP household when the head of household fails
  to comply with general work requirements. Per USDA FNS SNAP State
  Options Report, 16th Edition (June 2024), page 20.
AZ: {2024-06-01: true}
FL: {2024-06-01: true}
MA: {2024-06-01: true}
MN: {2024-06-01: true}
MS: {2024-06-01: true}
TX: {2024-06-01: true}
VA: {2024-06-01: true}
VI: {2024-06-01: true}
# All other jurisdictions default to false.
metadata:
  unit: bool
  label: SNAP HoH household disqualification option (7 CFR 273.7(f)(5))
  breakdown: [state_code]
  reference:
    - title: USDA FNS SNAP State Options Report, 16th Edition (June 2024) — Option to Disqualify the Entire Household (p. 20)
      href: https://fns-prod.azureedge.us/sites/default/files/resource-files/snap-16th-state-options-report-june24.pdf#page=22
    - title: 7 CFR 273.7(f)(5) — Disqualification of individual
      href: https://www.law.cornell.edu/cfr/text/7/273.7

Then in meets_snap_work_requirements.py:

is_hoh = person("is_tax_unit_head", period)  # proxy for SNAP HoH
state_using_hoh_option = spm_unit.household(
    "state_using_snap_hoh_work_disqualification", period
)
hoh_fails_general = is_hoh & ~general_work_requirements  # not ABAWD
hoh_triggers_household_denial = (
    state_using_hoh_option & spm_unit.any(hoh_fails_general)
)
any_member_passes = spm_unit.any(meets_work_requirements_person)
return any_member_passes & ~hoh_triggers_household_denial

Caveats for Option B:

  • ABAWD failures (273.24) never trigger household-wide denial, so this logic applies only to general work requirements.
  • The 180-day cap on the HoH disqualification isn't captured at a monthly snapshot — a simplification.
  • SNAP HoH ≠ tax unit head in all cases; is_tax_unit_head is a reasonable microsim proxy.

Impact

Overstates SNAP disqualification in the microsimulation. Any multi-adult household where one adult individually fails a work-requirement check is wrongly denied SNAP entirely — most commonly affecting:

  • Couples where one spouse works and the other is non-working but not in an exempt category.
  • Multi-generational households with a non-working adult (18–64, post-HR1) living with a working parent or sibling.

Under HR1's expanded scope (age ceiling 64, narrower child exemption, fewer categorical exemptions), the at-risk population grew substantially, so the microsim bias from this bug grew correspondingly.

Suggested tests

Add YAML tests under policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/:

  1. CA (individual-disqualification state), two adults, one passes, one fails → unit eligible.
  2. CA, two adults, both fail → unit ineligible (no eligible member).
  3. CA, two adults, both pass → unit eligible (regression guard).
  4. CA, adult + minor child, child exempt (<16), adult passes → unit eligible.
  5. CA, adult + minor child, child exempt (<16), adult fails → unit ineligible (no eligible adult).
  6. (If Option B implemented) TX (HoH-option state), HoH fails general work requirement → unit ineligible.
  7. (If Option B implemented) TX, non-HoH fails general work requirement, HoH passes → unit eligible.
  8. (If Option B implemented) TX, HoH fails ABAWD only → unit eligible (HoH option doesn't cover ABAWD).

Related

Labels

bug, snap

Sources

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsnapSupplemental Nutrition Assistance Program

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions