Derive hours-worked inputs from ASEC reported hours#293
Conversation
Add a hours_worked source stage (manifest entry, runtime handler, frame transform, release gate, builder wiring) following the immigration template. Direct-maps measured ASEC variables (HRSWK, A_HRS1, WKSWORK), heals the published constant-40 landmine, and hands weekly-hours ownership off from org_wages. Closes #242; unblocks #248.
237a841 to
7c797c4
Compare
|
Rebased onto current main ( Beyond conflict resolution, one intended change: dropped the now-stale Conflict resolutions were all additive interleaves with main's newly merged take-up (#315) and eCPS-parity (#316) wiring: both gate sets now run in sequence in Local verification: full 🤖 Generated with Claude Code |
Add a snap_take_up source stage (manifest entry, runtime handler, frame transform, release gate, builder wiring) following the immigration and hours templates. Reported SPM_SNAPSUB recipients always take up; non-reporters fill via seeded stable-identity draws to the cited FNS 0.82 participation rate. Heals the published all-True landmine. Closes #243; second half of #248 alongside #293.
Summary
Closes #242; unblocks the SNAP work-requirements exposure channel tracked in #248.
The published dataset either omits
weekly_hours_worked_before_lsror ships it constant at the engine's 40-hour default, so PolicyEngine-US treats everyone as working 40 hours/week — SNAP's 30-hour general and 20-hour ABAWD tests pass universally and work-requirement reforms score ~zero through the hours channel.This adds a
hours_workedsource stage following the #266 (immigration) template: manifest entry + shared runtime handler + frame transform + release gate + builder wiring.What it does
Direct mappings of measured ASEC variables — identical to the retired enhanced-CPS pipeline, so parity is by construction, nothing imputed:
weekly_hours_worked_before_lsr←HRSWK(usual weekly hours last year; 0 for non-workers)hours_worked_last_week←A_HRS1weeks_worked←WKSWORKclipped to [0, 52]Ownership handoff: the
org_wagesmanifest entry no longer claimsweekly_hours_worked_before_lsr— it never produced it (the retired pipeline sourced weekly hours from ASECHRSWKdirectly, not from the ORG fit) — and consumes hours as predictors instead.Healing behavior: the frame transform is idempotent when the hours surface carries signal, and recomputes from raw columns when weekly hours are constant — the published constant-40 landmine is repaired, not trusted.
Release gate (
hours_worked_signal): weighted positive-hours share must land in [0.35, 0.62] (CPS ~50% of all persons worked last year) and mean weekly hours among workers in [30, 45] (BLS ~38.5). Threaded through release gate failures, calibration diagnostics, and both manifests, mirroring the immigration gate. The L0 refit export now requires all three columns nonconstant.Verification
Documented semantics caveat
SNAP's ABAWD standard is a monthly 80-hour test;
HRSWKis an annual usual-hours measure. A person who worked half the year at 40 hrs/week carries 40 here. This matches how the retired pipeline fed the engine and is stated in the stage notes — week-by-week volatility is not observable in the CPS and is out of scope. The full ORG labor-market fit (tier 2) is tracked in #291.Merge-order note
After this merges, the
weekly_hours_worked_before_lsrreviewed exclusion in #286's degenerate-input gate becomes stale and should be removed (the gate will then permanently enforce non-degenerate hours). If #286 merges first, that's a one-line follow-up here; if this merges first, I'll drop the exclusion in #286.🤖 Generated with Claude Code