Add release-gate preflight: catch statically-knowable gate failures without a solve#436
Merged
Conversation
…ithout a solve Build M release attempts 9/10/11 each burned ~2h of calibration to surface ONE gate-group failure that was already determined by the inputs — the base pool values, the frozen selection, and the target/coverage registry — and needed no weight solve to see. This preflight recovers those signals in minutes so a release launch is not the first place a knowable defect is caught. `tools/preflight_us_release_gates.py` + `release_gate_preflight.py` run four checks, each mirroring a live release gate but evaluated pre-solve, reusing the release tool's own register, band math, and materialization algebra rather than re-declaring constants: 1. Selection carryover — the frozen selection-source manifest maps cleanly onto the base pool (the frozen-support recovery contract). 2. Zero-support preview — compiled positive fiscal targets whose materialized support is ~0 under the selection at base weights (direct-column targets checked via the calibrate constraint compiler; engine-derived measures marked not statically checkable). 3. Export-mass parity risk — each export-mass column's pool mass at base weights vs its reference band, honoring US_EXPORT_INPUT_MASS_REVIEWED_EXCLUSIONS. 4. Smoke-probe support audit — every reform-coverage probe leaf's pool vs selected nonzero support and pool sign-leg decomposition; a leaf with pool support but zero selected support FAILs (populace#434 keogh class); a thin selection or a signed leaf whose net contradicts expected_sign is AT-RISK (populace#432 farm class). Reports PASS/FAIL/AT-RISK with measured numbers; exit 1 on FAIL, 2 on AT-RISK, 0 clean. Synthetic-fixture tests exercise each check's FAIL and PASS paths (including the keogh and parity-risk classes) and run in the normal pytest suite with no policyengine-us and no real H5. README documents when to run it. 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.
Why
Build M release attempts 9/10/11 each burned ~2 hours of calibration to
surface one gate-group failure that was already determined by the inputs —
the base pool values, the frozen selection, and the target/coverage registry —
and needed no weight solve to see. This preflight recovers those signals in
minutes (the real run below takes ~22s) so a release launch is not the
first place a knowable defect is caught.
tools/preflight_us_release_gates.py+packages/populace-build/src/populace/build/us_runtime/release_gate_preflight.pyrun four checks, each mirroring a live release gate but evaluated pre-solve,
and each reusing the release tool's own register / band math / materialization
algebra rather than re-declaring constants (
input_mass_parity_gate,US_EXPORT_INPUT_MASS_REVIEWED_EXCLUSIONS,_engine_input_variables,build_constraint_matrix,base_selection_mask,us_release_reform_coverage_probes).The four failure classes this would have caught this week, each with the real number
(a) Zero-support on thin cells —
f(base values, selection, registry), nosolve. A compiled positive fiscal target whose materialized support under the
frozen selection is ~0 at base weights stays a structural zero after the solve.
Build M's
--zero-support-exclusionsregister already lists 27 suchsource_record_idcells (e.g.irs_soi.ty2022.historic_table_2.state_agi.al.under_1.taxable_interest_amount);the harness reproduces the release
zero_supportgate's exact condition(
initial_estimate ≈ final_estimate ≈ 0,atol=1e-9) on direct-column targetsand marks engine-derived measures not statically checkable rather than passing
them silently.
(b) Export-mass parity drift — predictable from pool mass vs the reference
band at base weights.
rental_income's pool mass was already below the bandfloor pre-solve: reference $432.87B, ±50% band [$216.44B, $649.31B],
Build M sparse export $90.70B — below the floor, so a correctly-calibrated
column cannot pass. The harness computes each column's pool mass at base weights
against its band and honors the reviewed-exclusions register: on the real frame
it shows all 6 exclusions (
rental_income,charitable_non_cash_donations,partnership_self_employment_net_earnings,miscellaneous_income,estate_income,non_sch_d_capital_gains) as excluded, and flags 5 othercolumns out of band at base weights for review.
(c) Reform-coverage smoke structural zeros — a probe input leaf with no
selection support, computed as a set intersection in seconds.
keogh_distributionscarries $148.97M across exactly 13 carrier householdsin the base pool; the pre-swap rmloss100 selection expressed only 4 of 13
(populace#434). The harness confirms the
buildm_keogh_swap_selection_sourcefix landed — 13 pool / 13 selected, $148,970,986.92 — and would have FAILed
the pre-swap selection (pool support, zero selected) before a release run.
(d) Sign-structure defects — pool leg decomposition vs the source
instrument.
farm_operations_incomeis imputed net +$10.37B (positive leg+$34.84B / negative leg −$24.47B, 6577 pool carriers) where Schedule F
is nationally loss-heavy, contradicting the
qbi_farm_operations_income_exclusionprobe's declared
expected_sign="negative". The harness flags it AT-RISK(same class as
partnership_self_employment_net_earnings's +$47.71B/−$48.06Bnear-cancellation, populace#432) until the base-rebuild fix lands.
Real run (read-only against the Build M artifacts)
As expected: keogh supported 13/13; farm sign-structure AT-RISK until the
populace#432-class fix rebuilds the base; rental/charitable/partnership parity
rows excluded.
Tests & CI
Synthetic-fixture tests (
packages/populace-build/tests/test_us_release_gate_preflight.py,18 tests) exercise each check's FAIL and PASS paths — including the keogh class
(leaf with pool support absent from selection) and the parity-risk class (pool
mass below band floor). They run in the normal
uv run pytestsuite with nopolicyengine-us and no real H5; no CI job needs the real base H5. A mutation
check confirms deleting a check's logic breaks its test.
uvx ruff@0.15.16 checkformatclean.Exit codes: 1 on any FAIL, 2 on AT-RISK only, 0 clean.
🤖 Generated with Claude Code