Recalibrate SNAP take-up per state to FNS household caseloads#376
Open
daphnehanse11 wants to merge 1 commit into
Open
Recalibrate SNAP take-up per state to FNS household caseloads#376daphnehanse11 wants to merge 1 commit into
daphnehanse11 wants to merge 1 commit into
Conversation
The snap_take_up stage (#294) anchors take-up on reported ASEC receipt and fills non-reporters to the national FNS participation rate. CPS SNAP receipt underreporting is strongly state-dependent, so the national fill starves the worst-underreporting states of taker households no reweighting can recover: the buildi-sparse release undershoots ten state benefit targets by 7-43% while a feasibility audit shows every state but California reachable under the weight cap, and state taker-household counts err from -38% to +325% against FNS caseloads (#372). Add a snap_state_take_up stage following the medicaid_take_up pattern (#331) at SPM-unit grain: reported recipients always take up; the fill draws at an in-build state rate (FNS average-monthly household count over weighted modeled-eligible units, an assignment prior, never cited as provenance) and is greedily calibrated to the FNS FY2024 state counts among eligible non-anchored units. The targets are the same snap_households rows the weight-calibration targets compile from, so the seed and the calibration objective agree. Saturation is recorded, not failed; a release gate enforces anchor preservation, per-state count fidelity within unit-weight granularity, full state target coverage, and the universal-take-up landmine. Persons caseloads stay untargeted: the SNAP assistance unit is often a subset of the SPM unit, so member counts overcount FNS participants by roughly half. Implements #372; stacked on the #371 caseload-target compilation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #372. Stacked on #371 (base branch is
snap-caseload-targets) — the take-up calibration consumes the same compiledsnap_householdstarget specs that PR adds, so the seed and the weight-calibration objective agree by construction.Why
#294's national-rate fill bakes in CPS state underreporting: the buildi-sparse release undershoots ten state SNAP benefit targets by 7–43% while a per-record feasibility audit shows every state but California reachable under the 5× weight cap, and state taker-household counts err from −38% to +325% against FNS caseloads (full numbers in #372 and the #371 preview comment). The states that are short cannot be fixed by reweighting — they lack taker households; this stage supplies them.
What
A
snap_state_take_upsource stage following themedicaid_take_uppattern (#331) at SPM-unit grain, using the shared binary-assignment ops (#338):SPM_SNAPSUB > 0) always take up, identical to the national stage's anchor.calibrate_binary_assignmentgreedily calibrates among eligible non-anchored units so each unsaturated state hits its FNS FY2024 count within unit-weight granularity.The national
snap_take_upstage remains as the prior; this stage recomputes the final surface after target compilation (it needsis_snap_eligiblefrom the engine and the compiled targets, mirroring the Medicaid builder placement).Deliberate carry-overs from the Medicaid stage: off-domain units keep a draw-based propensity (no hard-coded zero reform response), and saturation is recorded rather than failed (CA's ceiling is 1.05× its caseload — an eligibility-undercount symptom, not an assignment bug). Persons caseloads stay untargeted: the SNAP assistance unit is often a subset of the SPM unit, so member counts overcount FNS participants ~50% (see #371's second commit).
Gates and diagnostics
us_snap_state_take_up_gate(release-blocking): every state must carry an FNS target; anchors must survive calibration in every state (unit-level check); unsaturated states must land on their count withinmax(2%, one unit weight); positive count with zero eligible weight fails as an eligibility-feed collapse; caseload==eligibility with a reachable floor below it fails as the universal-take-up landmine.us_snap_state_take_up.jsonrelease artifact + staging telemetry: per-state eligible/anchored/caseload weights, targets, saturation, plus national rollup.out_of_scopefor Bernoulli seeding (it keeps a sourced national rate, whichcount_calibratedforbids) withscope_ownerupdated to name this stage as the final surface owner.Tests
test_us_snap_state_take_up.py(14 tests): manifest declaration, anchor derivation from raw subsidy, state fill-rate prior, exact count calibration in unsaturated states, saturation, anchor survival under downward pressure, empty-target refusal, and gate failure modes (missing state target, eligibility collapse, dropped anchor, count miss, universal-take-up landmine).populace-buildsuite passes (517 tests).🤖 Generated with Claude Code