fix(weights): canonical sanitize_and_renormalize and compose_sample_weights
Derived from independent dual-oracle mathematical specification with
proofs (mean=1 invariant, drop preservation, idempotency, collapse
degradation chain).
sanitize_and_renormalize:
- Fix latent bug: fallback path with non-empty drop_mask returned ones
zeroed at drop_mask but did not renormalize, breaking the mean=1
contract. The fallback now renormalizes so mean(out) == 1 holds on
surviving rows.
- Replace .copy()+mutation with np.where for drop_mask application.
compose_sample_weights:
- Replace the post-compose combined.sum() guard (which duplicated the
predicate sanitize_and_renormalize re-evaluates internally) with a
single survivor-aware predicate covering drop_mask | ~isfinite | <=0
in one pass. The check is the explicit branch point for the base-
weights fallback when the label-weighted product collapses on
surviving rows; this preserves the recency signal and the label-
derived drop_mask instead of degrading to uniform.
- Warn when nonzero/n falls below SPARSE_TRAINING_MASS_THRESHOLD (5%,
module-level constant) so operators can spot the sparse-training
regime that pivot-only weights produce on long series with few pivots.
QuickAdapterV3._log_strategy_configuration:
- Warn at startup when label_smoothing.method is 'smm' or 'savgol'
(with polyorder>=2) combined with a non-'none' label_weighting
strategy, since these kernels can collapse a sparse weight signal
and trip the all-rows-dropped guard.