Derive hours-worked inputs from ASEC reported hours#293
Draft
daphnehanse11 wants to merge 2 commits into
Draft
Conversation
The published dataset either omits weekly_hours_worked_before_lsr or ships it constant at the engine's 40-hour default, so PolicyEngine-US treats every person as working 40 hours per week and SNAP's 30-hour general and 20-hour ABAWD work requirements pass universally — reform exposure through the hours channel is erased (populace #242, #248). Add a hours_worked source stage that maps three measured CPS ASEC person variables onto the PolicyEngine input names, identical to the retired enhanced-CPS pipeline's mappings so parity is by construction: weekly_hours_worked_before_lsr from HRSWK, hours_worked_last_week from A_HRS1, and weeks_worked from WKSWORK clipped to [0, 52]. Nothing is imputed. The org_wages manifest entry no longer claims weekly hours — it never produced them; the retired pipeline sourced them from ASEC directly — and consumes them as predictors instead. The frame transform is idempotent when the surface carries signal and recomputes from raw columns when weekly hours are constant, healing the published constant-40 landmine rather than trusting it. A release gate requires a plausible worked distribution: weighted positive-hours share within [0.35, 0.62] (CPS ~50%) and mean weekly hours among workers within [30, 45] (BLS ~38.5). The fiscal refresh builder runs the stage after immigration inputs and threads the gate result through release gate failures, calibration diagnostics, and both manifests; the L0 refit export requires all three columns nonconstant. Verified against the current 572,780-person base: worked share 0.512, mean weekly hours among workers 37.3, gate green. Closes #242 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
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