Skip to content

Share one critical-target register between builder gates and the publish contract (no loss changes) - #491

Merged
MaxGhenis merged 17 commits into
mainfrom
loss-contract-alignment
Jul 22, 2026
Merged

Share one critical-target register between builder gates and the publish contract (no loss changes)#491
MaxGhenis merged 17 commits into
mainfrom
loss-contract-alignment

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Part of #462. Scope narrowed 2026-07-22 (owner decision, see #492): this PR is register alignment ONLY — the critical-row loss multiplier has been removed. Per-target calibration knobs are off the table as a matter of principle; the #462 medical decomposition (six states carry the entire national miss as support defects past the loss cap) showed the multiplier was aimed at a symptom regardless.

What this does

  1. One register, two consumers. The critical-target register moves to populace.data.us_critical_targets (dependency-light frozen data) imported by BOTH the publish contract and the release builder gates. The builder gains the requirement classes it was missing (itemized, SALT, medical) — closing the "build green, publish fails" gap that produced the Build N publish block.
  2. Behavioral equivalence, not field equality. Sol round-1 (BLOCK, report on file) found three builder-pass/publisher-reject holes: a silent irs_soi. prefix narrowing on the Table 1.4 blanket; divergent congressional-district classifiers (metadata-based vs layout/name-based); and the builder accepting relative_error: None where the publisher requires numeric. All three are fixed: the prefix narrowing is removed, both gates share one CD classifier (is_congressional_district_target, the OR-union of both sides' evidence) over the same row surface, missing recorded relative_error is a builder failure, and the anti-drift test is rewritten as a behavioral containment battery (publisher-rejected ⇒ builder-rejected, per selector class) rather than field comparison.
  3. Adjudicate the medical-dental publish tolerance to 0.25 pending the loss-contract alignment #490 adjudication carried, not reverted. This branch predated Adjudicate the medical-dental publish tolerance to 0.25 pending the loss-contract alignment #490; the shared register ports the medical 0.25 bound and its register comment verbatim. Restoration to 0.15 is now gated on fixing the six-state support defects (see the Build M live default: non_sch_d_capital_gains lands at $74.6B vs its $10.2B SOI target (+635%); Schedule-D CGD route is empty #462 decomposition), not on solver pressure.

What changed since round 1

What this deliberately does not do

  • No loss-weight changes of any kind: with the multiplier gone, _fiscal_target_loss_weights output is bit-identical to origin/main (round-1 receipt: branch-at-1.0 == main, byte-for-byte).
  • No target values or tolerances change beyond the ported Adjudicate the medical-dental publish tolerance to 0.25 pending the loss-contract alignment #490 adjudication.
  • The Table 1.4 blanket, incumbent-improvement laws, and CD-row exclusion semantics are unchanged in intent — they are now just enforced identically on both sides.

🤖 Generated with Claude Code

MaxGhenis and others added 8 commits July 22, 2026 07:03
@MaxGhenis MaxGhenis changed the title Align the builder critical register with the publish contract and give contract rows loss priority Share one critical-target register between builder gates and the publish contract (no loss changes) Jul 22, 2026
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Sol round-1: BLOCK — three HIGH builder-pass/publisher-reject holes (Table 1.4 irs_soi. prefix narrowing; divergent CD classifiers; relative_error: None accepted builder-side), anti-drift test checks fields not behavior. Full report held in the review archive; findings are the acceptance oracle for the in-flight fix lane.

Simultaneously, per the #462 medical decomposition and the #492 principle decision, the loss multiplier is removed from this PR entirely — scope is now register alignment + behavioral equivalence only. Fix lane is running; round-2 review follows before merge.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Remediation pushed (068854d..425c1ab, 7 commits): multiplier machinery fully removed (grep zero; _fiscal_target_loss_weights source-identical to main), Sol round-1 findings 1–4 fixed — prefix narrowing gone, one shared six-evidence CD classifier (is_congressional_district_target) behind both gates, missing recorded relative_error now a builder failure, anti-drift rewritten as a behavioral containment battery (incl. a guard that trips on any added conjunctive prefix). Round-1 reproductions flip: two malformed rows builder-REJECTED, the CD row symmetrically EXCLUDED by both consumers. Owner verification: 264 passed + 3 skipped incl. test_gates.py, exit 0; #490 medical block byte-identical. Sol round-2 running; merge on cross-family agreement per the standing signing/gates rule.

…xercise the improvement hard stop

Round-2 finding 1 (HIGH): gates.py used np.isclose (additive rtol+atol,
admits a 1.05e-9 stale delta at |computed|=0.1) where the publish
contract uses math.isclose — a builder-pass/publisher-reject boundary.
The builder now calls math.isclose with the contract's exact arguments,
and the joint battery pins the boundary from both sides (1.05e-9
rejected by both consumers, 0.9e-9 accepted by both).

Round-2 finding 2 (MEDIUM): the battery's hard-stop case used the
no-escape itemized requirement, short-circuiting before the improvement
branch. Relabeled it for what it actually tests, and added
allow-enabled federal-income-tax cases exactly AT the 0.25 hard stop
(passes via incumbent improvement, both sides) and just beyond it
(rejected by both sides despite improving).

Part of populace#462.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Sol round-2: BLOCK — round-1 findings 1–3 all verified PASS (including symmetric CD exclusion on the real v9.2 compile: 27,148 = 27,148, symmetric difference 0), multiplier removal verified blob-identical to main, medical block byte-identical. One new HIGH at a float boundary: gates.py used np.isclose (additive rtol+atol) where the contract uses math.isclose — a recorded relative_error stale by 1.05e-9 at |computed|=0.1 passed the builder and failed the publisher. Plus a MEDIUM: the battery's hard-stop case used the no-escape itemized requirement, so the improvement branch was never exercised.

Fixed in cd2ee64: builder now calls math.isclose with the contract's exact arguments; the joint battery pins the boundary from both sides (1.05e-9 rejected by both, 0.9e-9 accepted by both) and adds allow-enabled cases exactly at and just beyond the 0.25 improvement hard stop. Full suite green (exit 0), ruff clean. Focused Sol round-3 running on the delta; merging on its APPROVE per the cross-family-agreement rule for gate-machinery PRs.

@MaxGhenis
MaxGhenis merged commit 1e2b9b2 into main Jul 22, 2026
4 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Sol round-3: APPROVE at cd2ee64 — both round-2 findings verified resolved by direct execution through both consumers (boundary triplet 0.90/1.05/1.20e-9 agrees on both sides; the beyond-hard-stop case reaches the improvement branch in both, reporting incumbent_relative_error=2/improvement_hard_stop=0.25; no hazardous numeric-comparison divergence remains on the critical paths; medical block untouched; 159 gates tests + focused subsets green independently).

Merged on cross-family agreement (3-round Sol review + owner verification, CI 12/12) as 1e2b9b27. The builder can no longer pass what the publisher rejects — the Build N publish-block class is structurally closed. Follow-ups live at #492 (loss shape + census), #493 (stretch contract), and the #451/#462 support lanes; the register comment's stale "boosted run" restoration wording will be corrected to the support-truth condition in a follow-up touch.

MaxGhenis added a commit that referenced this pull request Jul 22, 2026
The #490 adjudication comment named 'a boosted run' as the 0.15
restoration condition — written before the #462 six-state decomposition
showed the miss is support excess sitting past the loss cap, and before
the #492 doctrine removed per-target loss boosts entirely (#491). The
condition is now what it actually is: fix the six-state carriers
(populace#481/#487), then a run holds 0.15 on truthful support.

Comment-only change; no values or semantics move.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 22, 2026
…497)

The #490 adjudication comment named 'a boosted run' as the 0.15
restoration condition — written before the #462 six-state decomposition
showed the miss is support excess sitting past the loss cap, and before
the #492 doctrine removed per-target loss boosts entirely (#491). The
condition is now what it actually is: fix the six-state carriers
(populace#481/#487), then a run holds 0.15 on truthful support.

Comment-only change; no values or semantics move.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 22, 2026
…round 1)

Blocking finding: the new stages were wired in the builder but missing
from the public plan and audit surfaces. Adds adult_care_inputs to
US_DONORS/US_STAGE_NAMES, both stages' leaves to the L0/refit export
required-person contract, the adult-care gate receipt to the monolithic
summary and staged required_signals, and the four leaves to the runtime
POST_REFERENCE_ECPS_REQUIRED_INPUTS mirror (manifest-currency drift).
is_incapable_of_self_care leaves US_DOCUMENTED_ABSENT_INPUTS: the
adult_care_inputs stage seeds it from measured ASEC PEDISDRS, which is
the direct instrument item the register entry believed absent (minimal
edit to build_us_fiscal_refresh_release.py; rebase after #491 lands).

Should-fixes: the SE signal gate now fails closed on null/non-boolean
flag values and nonfinite identity sources (astype(bool) silently read
NaN as True; NaN income silently read as not-self-employed), with tests
for both reproduced cases; the SIPP receipt is vintage-scoped (the 2018
panel's Child & Dependent Care module collected ECREPAYANYON/TDEPNDNTEXP
but the 2023 PUF - the pinned donor vintage - does not release them);
the five bare-input state/local consumers of health_insurance_premiums
are enumerated in the shipped stage notes.

Refs #451

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 22, 2026
… health ALD (#451 items 1-2)

Item 1: new adult_care_inputs stage (adult_care_post_clone) derives
is_incapable_of_self_care from the measured ASEC PEDISDRS self-care item
and assigns pre_subsidy_care_expenses via a seeded, weight-targeted,
distribution-preserving draw from the measured ASEC childcare-expense
class, restricted to tax units where IRC 21 can bind (21(b)(1)(B)/(C)
prongs, 21(d) work test with 21(d)(2) spouse deeming). Source decision
receipts (Census API dictionaries): neither ASEC 2024 nor SIPP 2023
measures in-household adult-care dollars (SIPP's TDPCAREAMT covers a
former household member), so the dollar leg is a documented
same-instrument proxy; the flag is directly measured.

Item 2: new deterministic attribute_self_employed_health_premiums
operation on the other_health_insurance_premiums release stage ships
health_insurance_premiums + is_self_employed (the engine's 162(l)
adds-chain computes the ALD; the SE-premium variable itself is
formula-owned and cannot ship). A Medicare proxy (age 65+ | SSDI>0)
keeps medical_expense_health_insurance_premiums numerically invariant.
Measured on certified N (c3e378a-20260722T010408Z): $48.09B attributed,
baseline ALD $31.24B vs the SOI 1.4 TY2023 fact $31.23B (ledger#105).

Coverage manifest: four new required leaves + two neutralization probes
(floors $1B / $40M against measured -$4.58B / -$193.3M on income_tax).
No changes to build_us_fiscal_refresh_release.py (#491 in flight) or any
calibration-loss machinery (#492 doctrine).

Refs #451

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 22, 2026
…round 1)

Blocking finding: the new stages were wired in the builder but missing
from the public plan and audit surfaces. Adds adult_care_inputs to
US_DONORS/US_STAGE_NAMES, both stages' leaves to the L0/refit export
required-person contract, the adult-care gate receipt to the monolithic
summary and staged required_signals, and the four leaves to the runtime
POST_REFERENCE_ECPS_REQUIRED_INPUTS mirror (manifest-currency drift).
is_incapable_of_self_care leaves US_DOCUMENTED_ABSENT_INPUTS: the
adult_care_inputs stage seeds it from measured ASEC PEDISDRS, which is
the direct instrument item the register entry believed absent (minimal
edit to build_us_fiscal_refresh_release.py; rebase after #491 lands).

Should-fixes: the SE signal gate now fails closed on null/non-boolean
flag values and nonfinite identity sources (astype(bool) silently read
NaN as True; NaN income silently read as not-self-employed), with tests
for both reproduced cases; the SIPP receipt is vintage-scoped (the 2018
panel's Child & Dependent Care module collected ECREPAYANYON/TDEPNDNTEXP
but the 2023 PUF - the pinned donor vintage - does not release them);
the five bare-input state/local consumers of health_insurance_premiums
are enumerated in the shipped stage notes.

Refs #451

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 22, 2026
…ttribution (#451 items 1–2) (#500)

* Base-builder imputation stages for the CDCC adult-care leg and the SE health ALD (#451 items 1-2)

Item 1: new adult_care_inputs stage (adult_care_post_clone) derives
is_incapable_of_self_care from the measured ASEC PEDISDRS self-care item
and assigns pre_subsidy_care_expenses via a seeded, weight-targeted,
distribution-preserving draw from the measured ASEC childcare-expense
class, restricted to tax units where IRC 21 can bind (21(b)(1)(B)/(C)
prongs, 21(d) work test with 21(d)(2) spouse deeming). Source decision
receipts (Census API dictionaries): neither ASEC 2024 nor SIPP 2023
measures in-household adult-care dollars (SIPP's TDPCAREAMT covers a
former household member), so the dollar leg is a documented
same-instrument proxy; the flag is directly measured.

Item 2: new deterministic attribute_self_employed_health_premiums
operation on the other_health_insurance_premiums release stage ships
health_insurance_premiums + is_self_employed (the engine's 162(l)
adds-chain computes the ALD; the SE-premium variable itself is
formula-owned and cannot ship). A Medicare proxy (age 65+ | SSDI>0)
keeps medical_expense_health_insurance_premiums numerically invariant.
Measured on certified N (c3e378a-20260722T010408Z): $48.09B attributed,
baseline ALD $31.24B vs the SOI 1.4 TY2023 fact $31.23B (ledger#105).

Coverage manifest: four new required leaves + two neutralization probes
(floors $1B / $40M against measured -$4.58B / -$193.3M on income_tax).
No changes to build_us_fiscal_refresh_release.py (#491 in flight) or any
calibration-loss machinery (#492 doctrine).

Refs #451

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Complete plan/export/audit wiring and harden the SE gate (sol review round 1)

Blocking finding: the new stages were wired in the builder but missing
from the public plan and audit surfaces. Adds adult_care_inputs to
US_DONORS/US_STAGE_NAMES, both stages' leaves to the L0/refit export
required-person contract, the adult-care gate receipt to the monolithic
summary and staged required_signals, and the four leaves to the runtime
POST_REFERENCE_ECPS_REQUIRED_INPUTS mirror (manifest-currency drift).
is_incapable_of_self_care leaves US_DOCUMENTED_ABSENT_INPUTS: the
adult_care_inputs stage seeds it from measured ASEC PEDISDRS, which is
the direct instrument item the register entry believed absent (minimal
edit to build_us_fiscal_refresh_release.py; rebase after #491 lands).

Should-fixes: the SE signal gate now fails closed on null/non-boolean
flag values and nonfinite identity sources (astype(bool) silently read
NaN as True; NaN income silently read as not-self-employed), with tests
for both reproduced cases; the SIPP receipt is vintage-scoped (the 2018
panel's Child & Dependent Care module collected ECREPAYANYON/TDEPNDNTEXP
but the 2023 PUF - the pinned donor vintage - does not release them);
the five bare-input state/local consumers of health_insurance_premiums
are enumerated in the shipped stage notes.

Refs #451

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Carry the four new required leaves in the L0/refit export test fixture

The shared npz keeps only household 20, so the new columns must stay
nonconstant on that post-selection subset for the tightened export
contract.

Refs #451

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Statute-exact deeming, 162(l)(2)(B) guard, order invariance, hardened gates (sol round 2)

Blocking fixes: the 21(d)(2) work test now computes exactly the engine's
min_head_spouse_earned binding condition (deeming never rescues a unit
whose only earner is the floor-eligible spouse; directional regression
test), extended to the measured full-time-college-student floor; the SE
attribution excludes measured employer-sponsored coverage (has_esi), the
conservative proxy for the 162(l)(2)(B) subsidized-plan month exclusion
(remeasured: $16.37B / 1,402 carriers / ALD $11.97B; the earlier $31.24B
near-match of the SOI fact was compositionally lucky and included
statutorily excluded months); the adult-care gate is now a real heal
certificate (strict bool/numeric flag validation incl. pandas-3 str
columns, PEDISDRS identity when present, carrier-must-qualify and
one-carrier-per-unit structure checks, $250k plausibility ceiling).

Should-fixes: seeded selection is invariant to person-row order (sorted
unit ids, smallest-person-id placement, shuffle test); weighted-quantile
pairing drops zero-weight donors and grids on the selected units' own
cumulative weights; person_support_channel is a required pinned source
instead of defaulting to all-ASEC; donor-universe notes state the
measured SPM-grain approximation precisely; string flags fail both SE
and adult gates; the builder failing-gate parametrization and frame-flow
assertions cover adult_care; the taxpayer-alone test asserts the
surviving unit receives the expense. 21(b)(1)(A) citation corrected.

Probe floors and reasons regenerated from the post-fix rerun on the
certified N frame: SE -$1.449B (floor $300M), CDCC adult care -$153.9M
(floor $30M).

Refs #451

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 22, 2026
Owner-gate finding on this PR: populace-calibrate here writes
schema_version 5 (the past_cap_census block) while populace-data's
contract pinned 4 and hard-rejects any other value — the next release
build would have passed its gates and then publish-failed on schema
version, the exact cross-gate disease #491 closed within the builder.

The two same-named constants cannot share code (populace-data must not
import populace-calibrate), so the builder suite — the one place that
imports both — now pins them equal (test_calibration_diagnostics_schema_lockstep).
Contract + release/contract test fixtures move to 5. Older shipped
releases (schema <= 4) remain valid history; the contract's version pin
has always meant 'what this library version publishes', per its
docstring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 22, 2026
* Past-cap census as a first-class calibration diagnostic (#492 deliverable A)

Under the capped weighted-MAPE objective, a row whose scaled miss reaches
target_loss_cap carries zero gradient: the solver can neither improve it
nor be charged for making it worse. The published Build N sparse run
measured the consequence — 17 rows that started inside the cap were pushed
past it and abandoned (the free-dumping-ground dynamic on #492) — and
nothing reported which rows the solve wrote off.

diagnostics_payload now ships a past_cap_census block: initial/final
past-cap counts, escaped (past at init, recovered), frozen (past at both
ends), pushed_out (in-cap at init, past at final), and the pushed-out row
list with each row's scaled misses, worst first. The census reads the cap
from the result options (both the calibrate shape and the score_targets
shape) and uses the loss's own scale rule max(|target|, 1). Pure
observability — no solver behavior change. Schema version 4 -> 5.

Refs #492.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Move the publish contract to diagnostics schema 5 in lockstep

Owner-gate finding on this PR: populace-calibrate here writes
schema_version 5 (the past_cap_census block) while populace-data's
contract pinned 4 and hard-rejects any other value — the next release
build would have passed its gates and then publish-failed on schema
version, the exact cross-gate disease #491 closed within the builder.

The two same-named constants cannot share code (populace-data must not
import populace-calibrate), so the builder suite — the one place that
imports both — now pins them equal (test_calibration_diagnostics_schema_lockstep).
Contract + release/contract test fixtures move to 5. Older shipped
releases (schema <= 4) remain valid history; the contract's version pin
has always meant 'what this library version publishes', per its
docstring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Past-cap means strictly past: gradient lives at the boundary

Sol confirm finding: the census used >= cap, classifying a row exactly
AT the cap as zero-gradient. torch.clamp keeps gradient at the boundary
(verified: d/dx clamp(x, max=cap) at x == cap is 1.0), so an at-cap row
still pulls in the objective. 'Past cap' now means strictly greater,
matching the census's own definition ('zero gradient'), and the test
pins the boundary row as alive.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Uppercase the lockstep test's constant aliases (Ruff N811)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant