Skip to main content
Nimbus middleware is the product wedge: a Bayesian personalization head for frozen neural / foundation embeddings. Encoders stay external. Apps consume thin BrainState outputs. One-liner: anything that maps trials to embeddings plugs in; Nimbus owns personalization, uncertainty gating, and cheap online updates — not the trunk.
Product takeaway (Paper 1): ship one Personalizer; treat fine-tune as a priced escape hatch, not the default integration path. Use the head where embedding capacity exists; stay cal-only when clean already wins.
One API across many trunks: frozen trunk epochs to embeddings, Personalizer Bayesian head, app state intent + uncertainty One Personalizer API across trunks — from the Universal Personalizer manuscript (Paper 1). Core: L0 / Bayesian head / linear probe / full FT (severe · n=40) Why the hatch stays priced: across classical trunks, stream Personalizer (L1) recovers most of the L0→L3 gain and usually beats a matched linear probe — details on Evidence.

Ladder legend (plain language)

Blue rec % on the figure = how much of the L0→L3 accuracy gain L1 recovers: (acc_L1 − acc_L0) / (acc_L3 − acc_L0). ≥FT means L1 matches or beats L3. How the Paper 1 / 1b numbers were produced (datasets, bandpass, session split, synthetic stress): Evidence → How the experiments work.
Classical CSP / bandpower / Riemann features still work. Use Personalizer(encoder=None) or the standalone heads (NimbusLDA, …) documented under Models.

Start here

Encoder contract

wrap → Personalizer → save/load rules.

BrainState

App-facing intents, presets, and bridges.

Evidence

Head vs probe vs FT, LDA/QDA/Softmax, REVE, transfer map.

Python Quickstart

Fit a Personalizer in a few minutes.

Minimal example

Integrator checklist

  1. When to adapt — use the thin helper with a user-supplied threshold (not an automatic multi-level cascade):
Policy: stay on the current head when clean; stream-update (partial_fit) when shift clears tau; full fine-tune stays a manual escape hatch. See Evidence.
  1. Trial gate (different signal)preset="research" / "consumer"; inspect BrainState.rejected, need_more_data, uncertainty. See BrainState.
  2. Head stability — after online updates, use calibration_sufficient on an unlabeled pool.
  3. Encoder swap — freeze trunk; match embedding_dim; never pass logits as embeddings; keep model_id consistent across save / load. See Encoder contract.

Next read

Encoder contract

Wrap rules and save/load.

BrainState

App-facing intents and presets.

API Reference

Personalizer and middleware symbols.

Heads / Models

LDA, QDA, Softmax, STS.