fix(training): repair W2 residual-momentum leak-free read + leakfree starvation observability (L4469 CF3)#232
Merged
Merged
Conversation
…starvation observability (L4469 CF3) Bug B (the crash): the W2 residual-momentum standalone leak-free read re-ran the scorer on `X_resid_mom_raw[canonical_finite_mask]`, but `X_resid_mom_raw` is FULL-training length N while `canonical_finite_mask` is OOS length — a boolean-index shape mismatch (IndexError) that dumped the read into status="error" and blocked the W2 promotion verdict. Each OOS row already carries `residual_momentum_score`, the SAME scorer output computed leak-free on the test slice at fold time (meta_trainer ~L1516), so the fix pulls the stored per-row value (mirroring the W2.3 factor_momentum_ratio idiom) — identical in value, OOS-aligned, and matched row-for-row to meta_y / _rm_dates. Bug A (not a bug — observability): the single-path leak-free meta IC returns n_folds=0 while canonical-label coverage is thin (an expanding purged+embargoed WF needs ~min_test+forward_days+test_size unique dates to clear one fold; CPCV is the data-efficient working read meanwhile). The graceful `insufficient_folds` sentinel already prevents a crash; this adds `n_unique_dates` to both returns so the manifest shows starvation vs a real defect. No fold-forcing (no-shortcuts default) — self-heals as coverage grows (~Aug). Tests: n_unique_dates surfaced on the starved path; regression guard documenting the full-length-array-masked-by-OOS-mask IndexError and the OOS-aligned stored-row idiom. Suite green (test_leakfree_meta_ic + test_meta_trainer_residual_momentum_gate, 26 passed). Co-Authored-By: Claude Opus 4.8 (1M context) <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.
What
Closes the two W2/W1 observe-read defects called out in ROADMAP L4469 CF3 ("fix the two broken observe reads"). The reads are OBSERVE-mode (gate nothing) but block the W2 promotion verdict and muddy the leak-free battery the champion/challenger arc reads.
Bug B — the real crash (
meta_trainer.pyW2 read)The residual-momentum standalone leak-free read re-ran the scorer on
X_resid_mom_raw[canonical_finite_mask].X_resid_mom_rawis full-training length N;canonical_finite_maskis OOS length → boolean-index shape mismatch (IndexError) → the read fell intostatus="error"every run.Fix: each OOS row already stores
residual_momentum_score— the same scorer output, computed leak-free on the test slice at fold time (~L1516,predict_array(X_resid_mom_raw[te])[local_idx]). Pull the stored per-row value (mirrors the W2.3factor_momentum_ratioidiom just below it): identical in value, correctly OOS-aligned, matched row-for-row tometa_y/_rm_dates.Bug A — not a defect, made diagnosable (
leakfree_meta_ic.py)The single-path leak-free meta IC returns
n_folds=0while canonical-label coverage is thin — an expanding purged+embargoed WF needs ~min_test + forward_days + test_sizeunique dates to clear even one fold, and CPCV is the data-efficient working read meanwhile. The gracefulinsufficient_foldssentinel already prevents a crash. This addsn_unique_datesto both returns so the manifest shows starvation vs a real defect instead of leaving it to be guessed. No fold-forcing (no-shortcuts default) — self-heals as coverage grows (~Aug).Why this way
n_folds=0is pure date-starvation.Tests
test_starvation_reports_unique_date_count—n_unique_datespresent on the starved path.TestW2LeakfreeReadShape— documents the full-length-array-masked-by-OOS-maskIndexErrorand asserts the stored-row idiom is OOS-aligned.test_leakfree_meta_ic.py+test_meta_trainer_residual_momentum_gate.py: 26 passed.OBSERVE-only; gates nothing; live ensemble + inference path unchanged.
🤖 Generated with Claude Code