Skip to main content
This guide covers upgrading from nimbus-bci 0.6.x or 0.7.x to 0.8.x.
Verify your installed version:

One-Hop Upgrade Summary

Nothing in 0.7 or 0.8 breaks existing saved profiles or bundles from 0.6. Profile artifacts and session bundles continue to load. The upgrade introduces new guardrails, deployment contracts, and an opt-in safety layer:

1. Unconditional Change: Hardened adapt_pseudo

In 0.6, adapt_pseudo had its entropy and epistemic uncertainty gates disabled by default (None). In 0.8.0+, defaults are hardened:
  • Entropy gate: Defaults to 0.60⋅log⁡2(K)0.60 \cdot \log_2(K) bits (class-count-aware).
  • Epistemic gate: Defaults to 0.450.45 (normalized scale).
  • Cumulative update cap: max_pseudo_updates=200 cumulative updates per session.
  • Fail-closed posture: If your model lacks Monte Carlo sampling (no epistemic score), adapt_pseudo now refuses with AdaptationRefusedError rather than self-training unguided.
For multiclass problems (K≥4K \ge 4), the default epistemic threshold of 0.450.45 may need re-tuning for your specific uncertainty scale.

2. Opt-in Online Safety Layer (nimbus_bci.safety)

To govern adaptation pacing, label spend, and rollback, supply safety=SafetyConfig(...) to Personalizer:
  • When configured, partial_fit, adapt_pseudo, adapt_trunk, and adapt_async consult the governor first and raise AdaptationRefusedError when a limit binds.
  • Enforcement is session-scoped: save() and load() do not persist safety counters. Attach a fresh SafetyConfig when loading a profile.
  • Details: Online Safety Layer.

3. Head Snapshot and Rollback

Capture byte-exact frozen snapshots of the head to undo problematic online updates:

4. Precomputed Embeddings (x_kind="embeddings")

If your pipeline serves precomputed embeddings (e.g. from an inference server or feature store):
  • encoder.encode() is never called.
  • Trunk adaptation (adapt_trunk, adapt_async, fit_tent) and Riemannian reference tracking cannot operate on precomputed embeddings and raise PersonalizerInputError.
  • Contract roundtrips through profile metadata (export_profile() / from_profile()).

5. Joint Gate Calibration (fit_calibrated)

In 0.6, fit_calibrated calibrated confidence thresholds in isolation. When K>2K > 2, the independent entropy ceiling (0.75⋅log⁡2K0.75 \cdot \log_2 K) silently lowered the realized accept rate below the target (e.g., target 70% realized only 57–64%). In 0.8:
  • Thresholds are computed within the validation subset passing the entropy ceiling.
  • gate_calibration_.achieved_accept reports the true realized joint rate.
  • If fewer trials pass the entropy ceiling than requested, a UserWarning reports the maximum achievable accept rate honestly.

6. Balanced Accuracy for Rare Targets

For rare-target paradigms (such as P300 spellers or RSVP), raw accuracy is distorted by class imbalance. 0.8 includes macro-averaged recall by default:

7. Direct Construction Syntax

Direct construction should pass decision=DecisionConfig(preset=...) rather than passing preset= directly to Personalizer:

Next Read

Online Safety Layer

Full guide to budgets, governors, monitors, and rollback

Changelog 0.8

Detailed release notes for 0.7 and 0.8

Encoder Contract

Updated encoder and precomputed embeddings rules

API Reference

Complete API signatures