PolicyEngine / PolicyEngine/policyengine-us
SNAP work requirements: complete sanction modeling semantics
- Dominant language
- Python
- Stars
- 162
- Forks
- 212
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 97
Description
Follow-up to #8862 / #8961.
## Problem
#8961 added `is_snap_work_registration_noncompliant` (person-level input, default false) as a hook for modeling work-registration sanctions under 7 CFR 273.7(f). The hook disqualifies the individual correctly, but three sanction semantics are simplified or missing when the hook is used:
1. **Income treatment.** A member sanctioned under 7 CFR 273.7 has their income counted **in full** per 7 CFR 273.11(c)(1); only ABAWD time-limit ineligibles are prorated per 273.11(c)(2). The model applies `snap_work_requirement_income_proration_fraction` (proration) to all work-requirement-ineligible members. Harmless in the baseline (only ABAWD failures occur), but wrong for sanction reforms. The simplification is documented in that variable's `documentation`.
2. **Household-level sanction (state option).** Under 7 U.S.C. 2015(d)(1)(B) and 7 CFR 273.7(f)(5), a state may disqualify the entire household when the **head of household** fails to comply, for the lesser of the individual's disqualification period or 180 days. Not modeled; no state adoption parameters exist.
3. **Sanction durations.** 7 CFR 273.7(f)(2) minimum sanction periods (1/3/6 months by occurrence, plus state options up to permanent) are not represented; the hook is a per-month boolean with no duration logic.
## Proposed scope
- Route sanctioned members (hook true, ABAWD-pass) through full income counting per 273.11(c)(1), keeping proration for ABAWD time-limit ineligibles.
- Optionally add head-of-household household-sanction parameters (state adoption list + 180-day cap) gated off in the baseline.
- Document that durations are the caller's responsibility when setting the monthly hook, or add duration support.
## Acceptance criteria
- With the hook set on an earner, SNAP counts that member's income in full while still removing them from `snap_unit_size`.
- Baseline results are unchanged.
- If the household sanction option is added, it applies only via explicit state parameters and only to head-of-household failures.
Contributor guide
Research direction
Start by tracing `is_snap_work_registration_noncompliant` and `snap_work_requirement_income_proration_fraction` through the SNAP model; the issue does not name files or tests. Confirm that sanctioned earners have income counted in full while leaving `snap_unit_size` unchanged, baseline results remain unchanged, and any household sanction is controlled only by explicit state parameters and the head-of-household condition.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100