Migrating to v0.50#
The v0.50 release is the SPEC 7 rng parameter adoption, the
follow-up to v0.49’s _rng.py scaffold. Every Tier-1 public function
that consumes a NumPy RNG now exposes a canonical rng: RNGLike | SeedLike | None parameter per Scientific Python SPEC
7. Bodies normalize
via np.random.default_rng(rng).
If you’re jumping from v0.48 (or earlier) and have not migrated through
v0.49, read migration/v0.49.md first.
What’s BREAKING at v0.50#
22 Tier-1 function signatures renamed: seed: int = X /
random_state: int | None → rng: RNGLike | SeedLike | None = X.
Defaults preserved (still deterministic-by-default).
Affected functions#
bootstrap.py(7 public + 1 private):bootstrap_ci,paired_bootstrap_diff,paired_bootstrap_ece_diff,paired_bootstrap_op_point_diff,paired_mde,block_bootstrap_on_folds,cross_validate_metric,_bootstrap_t_ci.metrics.py:expected_calibration_error_debiased.thresholds.py:selected_operating_point+_bootstrap_threshold_metric_cis.analysis.py:bootstrap_metric_from_predictions,paired_diff_from_prediction_refs.harness.py(6 sites):evaluate,evaluate_scorer_on_slice,_bootstrap_auc_ci,_evaluate_scores,_compute_paired_diffs,_score_all_slices.scorecards.py:scorecard,_evaluate_spec.stacking.py:LogisticStacker.random_state→LogisticStacker.rngclass-field rename (sklearn pass-through derives int at the boundary).
Migration recipe#
Before:
bootstrap_ci(y, scores, pr_auc, seed=42)
LogisticStacker(random_state=7)
After:
bootstrap_ci(y, scores, pr_auc, rng=42)
LogisticStacker(rng=7)
Bit-for-bit reproducibility is preserved when migrating seed=42 →
rng=42 (int seed is SeedLike; np.random.default_rng(42) is the
canonical normalization).
Config schema (Tier-2 additive)#
evaluate() config dict key "seed" → "rng". Generator-typed input
serializes as repr(rng); int/None serialize as-is (backward-compatible
for prior int-seed usage).
Exceptions to SPEC 7 (KEPT seed: — documented in STYLE.md §3a + ADR 0004 D4)#
seeds.set_global_seeds(seed: int)— global-state setter, not per-function RNG.adversarial.pydataclass fields + functional wrappers — use Python stdlibrandom.Random(seed), not NumPy.splits.pySplitter dataclass class-fields (HoldoutSplitter.seed,StratifiedKFoldSplitter.seed, etc.) — configuration storage, not a user-facing RNG parameter.loaders.py:903YAML config schema key — declarative; renaming would break consumer YAMLs.
Known issues addressed in v0.51#
The v0.50.0 ship discovered (via Round 8 audit) that the SPEC 7
contract has implementation gaps when callers pass Generator-typed
input. v0.51 fixes these: see migration/v0.51.md for the
spawn_seed_sequences state-respecting fix (R8-C4b) and the
_score_all_slices boundary-spawn refactor (R8-C4a).