Add L2 anchor semantics (initial/uniform/design); fix the flaky refit ESS test - #309
Merged
Conversation
The l2_lambda penalty divides by a reference weight vector whose choice decides which way the penalty pulls: under mass conservation its constrained optimum is w ∝ anchor², so anchoring at heterogeneous starting weights concentrates rather than spreads. The post-L0 refit starts from the selection stage's concentrated weights, which made a refit-stage penalty (the refit_l2_lambda knob shipped in #283) collapse ESS at production scale (8,408 -> 1,057 at lambda=1e-3 on the 337k-record US surface) instead of raising it. - calibrate() gains l2_anchor ("initial" | "uniform"): "uniform" divides by the mean starting weight, making the penalty a direct 1/ESS control regardless of the starting distribution. An explicit l2_anchor_weights vector is the harness seam for anchors the frame cannot express. - refit_l0_selection/calibrate_l0_refit gain "design": anchor the refit at the pre-selection initial weights of surviving records ("stay near the survey design"), derived from the selection result. At a fresh selection "design" collapses to "initial". refit_l2_anchor follows the refit_epochs inherit-or-override pattern; invalid anchors fail before the expensive selection stage. - Direction contract pinned where the effect clears the noise floor by orders of magnitude: from heterogeneous starts (ESS 29.3 of 160), the initial anchor drives ESS below 0.6x start while uniform drives it above 1.4x, at healthy loss. - Fixes #307: the refit threading test asserted an ESS direction on a near-converged fixture where the mass projection cancels the penalty's near-proportional push, leaving the comparison at the run-to-run nondeterminism noise floor (and the direction itself is anchor- and regime-dependent). The threading contract is now pinned via recorded solver options — exactly what the original hardcoded l2_lambda=0.0 bug would have violated — with the behavioral direction living in the anchor test above. Closes #307. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 4, 2026
MaxGhenis
added a commit
that referenced
this pull request
Jul 4, 2026
PR #309 already fixes #307, and does so at the root cause: it replaces the noisy ESS-direction assertion with the threading contract (recorded solver options) plus n_nonzero equality, and moves the behavioral direction to a new anchor test in a regime where it clears the noise floor. #309 further shows the ESS direction this branch's epsilon fix asserted actually INVERTS at production scale (an initial-anchored refit penalty lowers ESS on the 337k surface), so a measured-epsilon margin on the near-uniform fixture would pin a wrong direction. Restoring test_solve.py to origin/main so this PR is #272-only and does not conflict with #309 on this file. 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.
Closes #307. Follow-up to #283; experimental evidence in #285 (full results comment incoming).
Why
The
l2_lambdapenalty divides by a reference vector, and that choice decides which way the penalty pulls: undermass="conserve"its constrained optimum is w ∝ anchor². Anchored at heterogeneous starting weights the penalty concentrates rather than spreads. The post-L0 refit starts from the selection stage's concentrated calibrated weights, so therefit_l2_lambdaknob shipped in #283 is a trap at its default anchor: on the full 337k-record US surface a refit penalty of λ=1e-3 collapsed ESS from 8,408 to 1,057 instead of raising it (see #285 sweep data).What
calibrate(..., l2_anchor="initial"|"uniform")—"uniform"divides by the mean starting weight, making the penalty a direct 1/ESS control from any starting distribution.l2_anchor_weightsis the explicit-vector seam for anchors the frame can't express, recorded in options with a free-form provenance label.refit_l0_selection/calibrate_l0_refitgain"design": anchor the refit at the pre-selection initial weights of surviving records ("stay near the survey design") — derived from the selection result, no extra inputs. At a fresh selection"design"collapses to"initial".refit_l2_anchorfollows therefit_epochsinherit-or-override pattern; invalid anchors fail before the expensive selection stage.The #307 fix
test_refit_l0_selection_threads_l2_lambda_to_refitasserted an ESS direction between penalized and free refits on a near-converged fixture — a regime where the mass-conservation projection cancels the penalty's near-proportional push, leaving the comparison at the ~1e-5 nondeterminism noise floor (and the direction premise itself inverts at production scale, per the above). Per the issue's own guidance, no padded tolerance: the threading contract is now pinned via recorded solver options — exactly what the original hardcodedl2_lambda=0.0bug would have violated — and the behavioral direction lives in the anchor test, in a regime where it's real. Verified stable across repeated runs.Tests
Full suite: 1,343 passed / 47 skipped on current main;
ruff checkclean. New: anchor direction contract, explicit-anchor exact-equivalence with presets, validation (labels, shapes, positivity, fail-before-selection), two-stage inherit/override provenance including"design".🤖 Generated with Claude Code