Skip to content

Add SNAP release acceptance validation#413

Draft
daphnehanse11 wants to merge 4 commits into
mainfrom
codex/snap-release-acceptance
Draft

Add SNAP release acceptance validation#413
daphnehanse11 wants to merge 4 commits into
mainfrom
codex/snap-release-acceptance

Conversation

@daphnehanse11

Copy link
Copy Markdown
Collaborator

Summary

  • add a post-build SNAP acceptance report covering the 51 state household-caseload targets, 51 state benefit totals, the state take-up surface, county/state FIPS consistency, and Alaska borough/census-area coverage
  • package USDA FNS FY2022 eligible-person participation rates and report modeled state participation as an advisory comparison only
  • add a CLI for validating a release candidate and focused tests for every required gate
  • promote irs_soi.form_w2_social_security_tips back into the compiled fiscal target set now that the current Ledger feed supplies it

Fresh-feed recertification

I composed a current FY2024 US Ledger feed plus the required FY2022/FY2023 support facts:

  • Ledger commit: 57f1198
  • rows: 49,691
  • SHA-256: 4f85c03bb4b5ef13912789b20762240b9f7a97f6465e96c5fb3e734d32736774
  • target compilation: 5,690 specs, including 51 state snap_households rows and 51 state snap_total rows

The currently published Build J release is not SNAP-certifiable against that feed:

  • core release gates: pass
  • county coverage: pass (51 states, no missing/invalid FIPS, 28 Alaska county-equivalent FIPS)
  • household caseload fit: fail (29 states exceed 10%; maximum absolute miss 93.0%)
  • benefit total fit: fail (CA, DC, IL, LA, NM, and TX exceed 10%; maximum absolute miss 35.7%)
  • California eligibility saturation: 3.129 million target households versus 2.382 million modeled eligible units
  • FY2022 eligible-person participation advisory: 20 states exceed 10 percentage points; modeled national rate 93.7% versus the published 88%

Build J predates the state take-up stage, so its caseload audit uses post-calibration release weights and the current external FY2024 targets. It is an audit of the published artifact, not a reconstruction of its stage-time assignment gate.

Release blocker

I also attempted a no-bypass rebuild from current main. A fresh release candidate cannot be reproduced honestly from the published artifacts: the final H5 strips construction-only inputs including raw H_TENURE, while Build J's construction base/target-frame checkpoint and exact ACS donor were not published. I stopped rather than invent household tenure. Nothing was published and latest.json was not changed.

The highest-impact next artifact is therefore the exact construction base/target-frame checkpoint (plus its exact ACS donor), followed by fixing the modeled SNAP eligibility surface exposed by California and the other saturated states.

Tests

  • uv run ruff check ...
  • uv run pytest packages/populace-build/tests/test_us_snap_release_acceptance.py packages/populace-build/tests/test_release_target_parity.py packages/populace-build/tests/test_us_fiscal_targets.py -q

@daphnehanse11 daphnehanse11 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed against today's Build K run (populace-us-2024-buildk-snapval-1fe5fc4-20260713T171826Z, first certified build with the #371/#376 caseload surface — context in #419). This PR independently converges on several of the same findings, and the acceptance harness is exactly the right idea. One blocking issue, one split request.

What this addresses (keep all of it)

  • The acceptance report + CLI is the regression check #419 asks for (its "proposed fixes" item 3), with better structure than the ad-hoc scorecard used for Build J/K: per-state gates, missing/duplicate-state checks, AK borough coverage, focused tests.
  • The "release blocker" finding (H_TENURE stripped; construction base/checkpoint unpublished) independently corroborates #412 and adds a concrete new instance — worth cross-linking there.
  • FY2022 participation rates as advisory-only is doctrine-clean and the 93.7%-vs-88% national gap points the same direction as #419's eligibility-surface finding.

Blocking: the fit gates certify calibration, not the release

us_snap_state_target_fit_gate reads final_estimate vs target from calibration_diagnostics.json — the calibrated column. Build K demonstrates why that's insufficient for a gate named "release acceptance": its calibrated caseload fit is 52/52 within 10%, while snap > 0 simulated from its exported h5 (what every downstream PE-US user computes) is 23/52 outside 10% (AK +563%). Mechanism in #419: the take-up stage derives fill rates on pre-mass-repair weights, and the export drops eligibility-narrowing inputs the build frame carried, so the pinned column doesn't reproduce from the artifact. Either add an artifact-simulated caseload gate (the participation validation already opens the h5, so the plumbing exists) or rename/document these gates as calibration-fit checks. As written, a release could pass acceptance while shipping 5× caseload error in some states — the exact failure the harness exists to catch. Also worth pinning the measure semantics (FNS average-monthly households vs annual snap>0) either way — the #371 persons-mapping lesson.

Split request: the tips promotion

Promoting irs_soi.form_w2_social_security_tips to compiled is directionally right but for the wrong stated reason, and it belongs in its own PR:

  • The body says "now that the current Ledger feed supplies it" — the feed always carried the amount; the fence was about model support (structural-zero tip_income). The correct promotion basis is that the sipp_tips source stage + us_sipp_tips_signal_gate are now wired on main.
  • The diff deletes the fence wholesale rather than recording the promotion evidence (#405 fences every entry for exactly this reason).
  • It's unverified at release scale (the rebuild aborted at H_TENURE). The signal + zero-support gates make failure loud rather than silent, but a promotion that's never survived a build shouldn't ride along in an acceptance-harness PR.

Coordination note: any fresh feed (this PR's 57f1198 bundle, or the Build K bundle) compiles ~16 separate-CHIP state targets that v8's zeros never compiled, and they have zero support on the sparse frame — a build with this feed hits the zero-support gate unless it carries the 40-cell exclusion list from Build K (see #411 and the Build K notes in #419).

🤖 Generated with Claude Code

…caseload gate (#419)

Fixes CI: snap_fy2022_participation_rates.json was shipped undeclared in
country_package.json, failing the package-manifest gates.

Adds us_snap_artifact_caseload_gate, wired into the assembled acceptance
verdict as a required check: simulate engine snap > 0 per state from the
shipped H5 (MicroSeries weights) and bound every miss against the same
FNS snap_households targets the build calibrated to. The calibrated-column
fit gate alone certifies the solver, not the artifact — populace#419
measured a release with 52/52 calibrated caseload fit whose shipped
dataset misses 23/52 states (AK +563%). Semantics recorded in the gate
payload (average-monthly stock target vs annual engine participation).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s env)

The wheels CI installs bare wheels without the us extra; tables is
optional there by design. Matches the test_demographics.py convention.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@daphnehanse11

Copy link
Copy Markdown
Collaborator Author

Correction to my review's blocking rationale: the "23/52 artifact divergence" I cited was a measurement artifact in my own audit script (state via map_to-division; details in the #419 resolution comment). Measured with this PR's person-linkage mapping, Build K's artifact fits 51/51 caseload targets (worst CA −8.9%) — the calibrated and artifact views agree. The artifact-caseload gate added here remains the right check (it's how the artifact/measurement distinction gets made mechanically, and it passes honest releases); the CA-saturation/eligibility-undercount finding in this PR's body is the part that stays open. The tips-promotion split request stands.

🤖 Generated with Claude Code

@daphnehanse11 daphnehanse11 requested a review from MaxGhenis July 14, 2026 12: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.

1 participant