Repository navigation
Fail the US housing gate on rent outside renter households, and zero it in the CPS draw - #1529
Merged
Merged
Conversation
us_housing_inputs_signal_gate counted positive pre_subsidy_rent outside renter households (positive_rent_nonrenter) but passed regardless. A base built before #1444 carries rent on the wrong heads, and with_us_housing_inputs returns a frame unchanged when the gate passes, so such a base kept its misplaced rent. The gate now fails on any such rent: the c0513db support base (66,623 such people) fails and the base rebuilt at 9434c50 (none) passes. Tests: the old test that allowed the rent now expects the failure; a replay of the pre-#1444 placement fails the gate and gets its rent drawn again; property tests check the count against a brute-force count, flag exactly the draws person order moves off renters, and pass correctly drawn rent under any person order. Re-pinned with tools/repin_us_spec_engine_contracts.py: the seed map and seed protocol digests, the spec_sha256 vectors and us-f0-coverage.json. Part of #1446 (step 2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The gate fails positive rent on anyone in an owner or no-cash-rent household and passes rent moved between two renter households' heads. The docstrings now say so. They move the attested source hashes, so the repinner rewrote seed_map, seed_protocol, two spec_sha256 pins and the coverage report. Part of #1446 (step 2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shared QRF's zero-or-positive classifier gives every head a small chance of positive rent, owners included. With the housing gate now failing rent outside renter households, a leaked draw would stop a support-base rebuild. On the Route A pre-clone frame (168,852 heads, 53,055 renter heads), seeds 1 to 7 each put rent on one to four owner or no-cash-rent heads, and seed 0 on none. impute_us_pre_subsidy_rent still draws for every head, so renters' draws stay unchanged, and then sets rent to zero outside renter households. For seeds 0 to 7 on that frame, renter draws match the old ones exactly, every other head gets zero, and the gate passes. The kernel source moved, so the spec-engine pins move again (two repinner passes, as in #1530). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
November 6, 2026 04:19
Contributor
Author
|
Merged at head bad73e4 with a merge commit (3f7cfc1). GPT-6.1 Sol reviewed that head through Subfleet (job 20261105-225819-pr1529-rereview) and approved it; an earlier Opus review at fdc785a requested the zeroing this head adds. Every check passed on the latest run, and no one requested changes. Sol's sandbox could not run pytest, so the local test and mutation counts in the body come from this session's runs. #1446 step 3 stays open for rent on ACS owners, and #1530 tracks the repinner's second pass. 🤖 Generated with Claude Code |
MaxGhenis
added a commit
that referenced
this pull request
Nov 6, 2026
Populace US means to differ from Census where it fixes CPS errors, so the note now measures differences from Table 18 and no longer treats them as misses: - The title and opening say so, and name the question: separating intended corrections from noise and bugs. "Systematic error" becomes a systematic shift, and "state-specific error" becomes state-specific variation. - "What would fix it" becomes "What we would change", and says a smaller gap alone does not make a better file. - The rent sections now record what landed. #1444 fixed the assignment, #1529 made the gate fail on rent outside renter households (the test the note named no longer exists), and no published file carries the fix yet. PolicyEngine/child-poverty-impact-dashboard#127 has left draft. No figure changes: a token comparison of the old and new text finds only punctuation differences. ACS-local figures stay on hold for the fill-0 rerun. Co-Authored-By: Claude Opus 5.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.
Part of #1446 (step 2).
us_housing_inputs_signal_gatenow fails when anyone outside a renter household carries positivepre_subsidy_rent. Until now the gate counted these people (positive_rent_nonrenter) and passed anyway.impute_us_pre_subsidy_rentnow gives heads of owner and no-cash-rent households zero rent, so the CPS rent draw passes the stricter gate.Why the gate fails this rent
#1444 fixed rent placement:
impute_us_pre_subsidy_rentdrew rent in household order and wrote it to heads in person order, so heads received other households' rent.with_us_housing_inputsreturns a frame unchanged when the gate passes, and the gate passed misplaced rent, so a base built before the fix kept it.The Route A support bases from before and after #1444 hold the same 907,863 people and differ only in
person.pre_subsidy_rent. Each build writes the gate's counts tobase_populace_us_2024_puf_support.summary.json:positive_rent_nonrenterpositive_rent_nonheadWith this change the first base fails the gate and the second passes.
Why the draw zeroes rent outside renter households
The ACS rent model draws for every CPS head, with tenure among its predictors. The shared QRF's zero-or-positive classifier gives each owner and no-cash-rent head a small chance of positive rent. On the Route A pre-clone frame (168,852 heads, 53,055 of them in renter households), the draw on main put rent on these heads outside renter households:
Under the stricter gate, seeds 1 to 7 would each stop a support-base rebuild. The draw still runs for every head and then sets rent to zero outside renter households, so renters keep their draws. For seeds 0 to 7 on that frame, everyone in a renter household keeps main's draw, everyone else gets zero, and
with_us_housing_inputspasses the gate. Route A's support base at 9434c50 used seed 0, and at seed 0 main's draw put rent on no one outside a renter household.Where the gate runs
tools/build_us_puf_support_base.pychecks it before support cloning. When it fails, the builder draws rent again from the ACS donor that--acs-h5names, and without that flag the build stops. If the gate fails again after PUF-support imputation, the build stops.tools/build_us_fiscal_refresh_release.pychecks the base frame and raisesRuntimeErrorwith no redraw, so a release from a base that predates Place each ACS rent draw on its own household's head #1444 stops at the housing gate. The Route A release dry run reads the 9434c50 base through--base-h5, and that base passes.with_us_housing_inputswhen it prepares source inputs, so it draws such rent again.Limits
pre_subsidy_rentfromtransfer_acs_inputs, which fits its own QRF on the donor and draws with the same sign classifier, and nothing afterwards sets owners' rent to zero. Published ACS rows put rent on 30% of ACS owners (State child SPM rates: next steps from the November trace #1446). A fiscal refresh that takes its base from--pool-manifestchecks ACS rows, so any such rent stops it at this gate until State child SPM rates: next steps from the November trace #1446 step 3 zeroes owners' rent after the transfer. That arm already fails the gate's tenure check on main when ACS households keepOWNED_OUTRIGHT, whichacs_inputs.pyassigns to ACS tenure code 2.Invariants
packages/microcosm-build/tests/engine_free/us/test_us_housing_inputs.pychecks these properties:with_us_housing_inputspasses the gate (Hypothesis, 40 examples).positive rent outside renter households: 1.With rent written in person order on a reversed person table, it fails with 4, andwith_us_housing_inputsdraws that rent again onto households 1 to 4.Removing the gate's new failure line fails four of these tests, and removing the zeroing line fails three others.
Locally
test_us_housing_inputs.py,test_spec_engine_loader.pyandtest_spec_engine_coverage_tool.pypass (40 tests), andruff check ., both repinner--checkmodes andtools/spec_engine_coverage.py --checkexit 0.test_us_multispine_pool_tool.pyneedspolicyengine_us, so the engine-us CI job runs it.Re-pin
The change moves attested kernel source, so
tools/repin_us_spec_engine_contracts.pyrewroteseed_map,seed_protocol, twospec_sha256pins anddocs/evidence/spec-engine/us-f0-coverage.json. The bundle generator needs the US engine and did not run locally; the engine-us CI job runs the bundle tests. One repinner pass leavescovered_item_countat 40 intest_spec_engine_coverage_tool.py, and a second pass restores 41 (#1530).axiom: n/a: build-pipeline gate, no policy rule changes
🤖 Generated with Claude Code