Keep the SSI take-up flag informative under universal saturation#423
Merged
Conversation
Build M's first sparse run failed the SSI take-up gate with a constant universal-True output. The restored disability battery (is_blind, is_disabled — engine-default False on every prior base) correctly put SSI candidates in all three SSA age bands; every band's candidate capacity fell short of its SSA recipient target; the count-matching ratio degenerated to 1.0; and the reform-domain Bernoulli then flagged the entire pool. Build J only ever had aged candidates, so the same code path flagged just the 65+ band and the share landed in range by accident. The count-matching ratio is a meaningful reform propensity only while it subsamples. Under saturation, fall back to the observed take-up rate among today's candidates (reporter mass over candidate capacity): a household made eligible by a reform takes up at the rate today's modeled eligibles are observed reporting. Current-law recipiency is unchanged in both regimes — only candidates are ever paid, and the saturated branch still selects every candidate. The substantive gap the gate surfaced — modeled SSI candidate mass far below SSA's 7.4M recipients, the same undercount visible in the local artifact's SSI measurement — is a modeling issue tracked separately; this change makes the take-up stage honest about it instead of degenerate. 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.
Build M's sparse run failed the SSI take-up gate:
takes_up_ssi_if_eligiblecame out True for the entire pool (constant; weighted share 1.0 on both channels). Diagnosis credit: the Build M runner agent, whose decomposition falsified the resource/SCF suspects (byte-identical across bases), localized the kill to_assign_sources, and produced the per-band table.Mechanism. The assigner draws a population-wide reform propensity
Bernoulli(min(target/capacity, 1)), then count-calibrates candidates. The restored disability battery (is_blind,is_disabled— engine-default False on every prior base) correctly created SSI candidates in all three SSA age bands; every band saturated (candidate capacity ≪ SSA target); the ratio degenerated to 1.0; Bernoulli(1.0) flagged everyone. Build J passed by accident — zero non-aged candidates meant only the 65+ band flagged, and 17.3% happened to sit in range.Fix. Under saturation the reform-domain propensity falls back to the observed take-up rate among today's candidates (reporter mass / candidate capacity) — "a reform-newly-eligible household takes up at the rate today's modeled eligibles are observed reporting." Current-law recipiency is untouched in both regimes: only candidates are ever paid, and the saturated branch still selects every candidate. The subsampling regime is byte-identical to before.
Verification. New test saturates all three bands and pins: candidates fully selected, output non-constant, gate passes — fails on the old code, passes on the fix. Full SSI/take-up/contract suites green (65 tests); CI-version ruff clean.
The substantive finding underneath — modeled SSI candidate mass (~2M scaled) far below SSA's 7,404,820 recipients, the same undercount as the local artifact's SSI measurement — is a launch-documented modeling limitation for architecture week, not something this stage can repair; the gate now stays honest about it instead of degenerate.
🤖 Generated with Claude Code