Repository navigation
Conversation
us/source_stages.json declares the wealth stage's carry as head_carry with condition is_household_head (P_SEQ == 1, the CPS reference person), and the housing stages use that flag. The runtime selector instead took the lowest A_LINENO. They disagree in 243 of the certified frame's 57,240 households; on the 2024 income year, where A_EXPRRP is observed, is_household_head is the reference person in every household and the line rule misses 73. household_head_carrier_mask (sipp_financial_assets) now uses the flag where it marks exactly one person in a household and falls back to the lowest line, then row order, otherwise; scf_wealth's _household_head_mask calls it, so both halves of the blend carry the same person. Re-pins the attested digests the change moves: seed protocol and seed map, the synthetic and real US spec goldens, and the coverage receipt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Only true booleans and nonzero numbers flag a head; strings such as "False" or "" never do. - Flags are counted within the same groups the lowest-line fallback sorts, so a missing household id is its own household in both rules. - New blend-plus-gate test with the declared head on line 2: all three leaves land on the head, other members hold zero, and the gate's blend-audit checks agree. - Re-pins the seed protocol and map, synthetic and US spec goldens, and the coverage receipt for the new source bytes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Independent review (GPT-6.1 Sol) of
|
MaxGhenis
marked this pull request as ready for review
October 12, 2026 10:59
This was referenced Oct 12, 2026
Main changed the US spec-engine pins in the same four files this branch re-pinned: us-f0-coverage.json, inventory_coverage.py and the two pin tests. The merge takes main's side in all four, and the next commit recomputes the pins with tools/repin_us_spec_engine_contracts.py. Git merged everything else without conflicts; main has no commits that touch scf_wealth.py, sipp_financial_assets.py or test_us_scf_wealth.py since the branch point. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After the merge, main's pins no longer match this branch's scf_wealth.py and sipp_financial_assets.py bytes. tools/repin_us_spec_engine_contracts.py recomputes them: - EXPECTED_HASHES seed_map and seed_protocol, and the matching rows in us-f0-coverage.json; - the synthetic loader golden and the real US spec_sha256 (915d29b0...). tools/spec_engine_coverage.py reports 42,394/42,394 configuration fields and 41/41 inventory checks. The repinner's first pass also rewrote the coverage test's covered_item_count from 41 to 40, because it reads that count from a report built against the stale seed hashes. A second pass, run once the hashes matched, restored 41 and changed nothing else. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The re-pin rewrote the seed_map and seed_protocol values and dropped the comment that names this PR among the changes that move them. One comment line now records it beside the other PRs that moved both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
I'm handing this PR to the Microcosm hub (session
|
This branch has not been deployed
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.
Part of #1215 (the selector that contradicts its own declaration; the ownership problem stays open there).
The mismatch
us/source_stages.jsondeclares the wealth stage's carry ashead_carrywithcondition: is_household_head.relationship_inputs.pysetsis_household_headfromP_SEQ == 1, the CPS reference person, and the housing stages use it as the head. The runtime selector (scf_wealth._household_head_mask, and its SIPP twinsipp_financial_assets._household_head_mask) took the lowestA_LINENOinstead, and a test pinned that rule.On the certified
populace-us-2024-spm-20260909the two rules disagree in 243 of 57,240 households. In the 2024 income year, the one vintage whose CPS file reportsA_EXPRRP(the 2022 and 2023 frames synthesize it from line 1),is_household_headpicks the reference person in every household, and the lowest-line rule misses 73. For example, in household 884 (#1215), the 71-year-old wife on line 1 carries $17,500 and the line-2 reference person carries nothing.Change
sipp_financial_assets.household_head_carrier_maskpicks one carrier per household. Whereis_household_headmarks exactly one person in the household, it takes that person. Otherwise (no flag column, or zero or several flagged people), it falls back to the lowestA_LINENO, then row order, as before. It reads missing flag values as False and returns an empty mask for an empty frame.scf_wealth._household_head_maskcalls it, so the SCF and SIPP halves, and the SCF-wealth gate's audit check, use the same person.#1215's larger problem stays open: one household-level vector still sits on one person, and fixing it takes a change of draw unit and a validation pass.
Invariants
Hypothesis tests each of these with 100 examples:
Example tests pin that the flag beats a lower line number, that zero or two flags fall back to the lowest line, that both halves return the same mask, and that the selector handles nullable-boolean flags with NA and an empty frame. The existing
test_household_head_mask_is_one_per_household_at_lowest_line(no flag column) still passes unchanged.Deliberate re-pins
The seed protocol attests the source bytes of seeded stage modules, so editing them moves these pins. On main at
3f46d5958,tools/repin_us_spec_engine_contracts.pyrecomputes them:EXPECTED_HASHES["seed_protocol"]5840ac6c…ff533e432297573840bbae497370efe3e7cafed5c2c571db029208d10722035a7470EXPECTED_HASHES["seed_map"]fa48af06…6b375f8b7c620abee639d31f3dd50ed61e9c9a0daad89b8b4886d485b71d5cb882bdspec_sha256golden5b39d83c…d36eddb925d9603cd269c358f46ff433d5c4adf67991aa17782331a23c0b55767a05spec_sha256(engine-workflow test)4ccbd017…38b2915d29b0a5419d8e9ff4c9945fb5a92fb18576440dbbbcef2a7680546cfc4441tools/spec_engine_coverage.pyregeneratesdocs/evidence/spec-engine/us-f0-coverage.jsonand reports 42,394/42,394 configuration fields and 41/41 inventory checks. The PR changes no RNG rule, seed or QRF target.Effect
Future builds only. The 243 households' vectors move to their reference person, and both the asset draws and the household net-worth draw condition on that person's predictors (the net-worth QRF reads the same head mask). A frame that already carries an old blend audit can pass through the stage unchanged (the stage's healing rule), so a reused in-memory frame keeps the old carrier; canonical builds draw fresh. The PR runs no release or build.
Release-build rule
docs/us-release-build-rule.mdasks a pull request "large enough to change how the dataset is built" to carry a from-scratch build and certification receipt from its own tree before it merges. This PR changes which person carries the asset vectors in future builds, and it carries no such receipt. d2781 asks whether its tests may stand in for that run on the terms of d2647 and d2729: the next certified US build on main would become this PR's from-scratch run.Verification
At
eff5d8343, which merges main at3f46d5958and re-pins:test_us_scf_wealth.py,test_us_sipp_financial_assets.pyand the multispine constants test pass (68 tests).ruff check .,tools/ci_test_plan.py verifyandverify-workflow, andtools/graph_acceptance_burndown.py --verifypass.tools/repin_us_spec_engine_contracts.py --checktimed out in its 300 s clean-worker import while host load sat near 150. The reviewer recomputed all four pins from the head's bytes instead, and CI's engine-us job runs the coverage test.5932199a5restores a comment above the seed pins and changes nothing else; the loader tests pass at it (10 tests).At
db53b5f6b, the engine-free US and shared suites passed (-n 4), with the telemetry subprocess test deselected locally because it hangs on this host; CI runs it.Review
0b15232c2with nits, whichdb53b5f6bfixes, and a second review approved the delta todb53b5f6b.db53b5f6b..5932199a5with nits. It recomputed all four pins from the head's bytes, and reproduced main's pins from main's bytes as a control. It flagged a dropped Liquid assets sit on the lowest-line person, against the stage's declared is_household_head carry; 13.1M SSI-relevant adults test at $0 resources by construction #1215 comment, which5932199a5restores, the repinner's two-pass count, which Repinner needs two passes to pin covered_item_count #1530 tracks, and main's lowest-line education-debt selector, which Liquid assets sit on the lowest-line person, against the stage's declared is_household_head carry; 13.1M SSI-relevant adults test at $0 resources by construction #1215 now records.axiom: n/a: microdata construction only; no policy rule changes.
🤖 Generated with Claude Code