> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nimbusbci.com/llms.txt
> Use this file to discover all available pages before exploring further.

# BrainState

> App-facing BrainState fields, decision presets, and bridges from BatchResult / StreamingResult / upstream probabilities.

`BrainState` is the app-facing output. Key fields:

| Field | Meaning |
| - | - |
| `intent` | Top semantic label (from `classes`) |
| `confidence` | Top-class posterior mass |
| `posterior` | Full class → probability map |
| `uncertainty` | Fused uncertainty used for gating |
| `alternatives` | Other `IntentHypothesis` entries |
| `need_more_data` | Ask for more evidence / calibration |
| `rejected` / `rejection_reason` | Decision gate outcome |
| `embedding` | Optional embedding snapshot |
| `user_id` / `model_id` / `paradigm` | Provenance stamps |

Use `BrainState.to_dict()` for JSON-friendly export (`brain_state_version` is currently `1`).

## Trial gate vs adapt recommendation

These are **different** signals:

| Signal | API | Question |
| - | - | - |
| **Trial gate** | `rejected`, `need_more_data`, presets | Accept this intent for the app? |
| **Adapt gateway** | `Personalizer.adapt(...)` / `partial_fit` | Update the head / transform / trunk? |
| **Adapt recommendation** | `Personalizer.recommend_adapt(..., tau=...)` → `AdaptDecision` | Spend labels on a stream update? |

Prefer `Personalizer.adapt(...)` as the label-agnostic adaptation gateway (head update, unsupervised transform alignment, or trunk PEFT). `recommend_adapt` remains a thin mean-shift helper against a user-supplied `tau` (L0 stay vs L1 stream update only). It does **not** auto-escalate to affine maps or full fine-tune. Optional session metadata:

```python theme={null}
dec = adapter.recommend_adapt(X_stream, tau=0.25)
states = adapter.predict(X_eval)
for s in states:
    s.extras.update(dec.to_extras())  # should_adapt, adapt_score, adapt_tau, …
```

After `Personalizer.load`, pass `X_ref=` (calibration embeddings are not serialized).

## Decision presets

| Preset | Intent |
| - | - |
| `strict` | Stricter gating; prefer `need_more_data` / reject when unsure (deployment default via `for_deployment`) |
| `permissive` | Lower confidence bar; more accepts (research / classical defaults) |
| `aggressive` | Lowest bar — accept almost everything |

<Warning>
  **0.6 rename:** `"research"` → `"strict"`, `"consumer"` → `"permissive"`. Old strings raise `ValueError`.
</Warning>

Uncertainty fusion: `BrainState.uncertainty` is `max(normalized_entropy, upstream)` when upstream is set. Gating checks entropy and upstream thresholds independently.

Optional `mc_samples>=2` on `Personalizer` draws posterior samples and sets normalized epistemic uncertainty (BALD / log2 K) as `Prediction.uncertainty`. MAP intent and confidence still use closed-form `predict_proba`. Breakdown bits land in `BrainState.extras` (`total_entropy_bits`, `aleatoric_bits`, `epistemic_bits`).

## Dual API & bridges

| Object | Audience | Role |
| - | - | - |
| `BatchResult` | researchers, benches | Posteriors, entropy, Mahalanobis, ECE, ITR sweeps |
| `BrainState` | apps, devices | Intent, confidence, uncertainty, alternatives, `need_more_data` |

```python theme={null}
from nimbus_bci import (
    predict_batch,
    brain_states_from_batch,
    brain_state_from_streaming_result,
)

# Research batch → app states
states = brain_states_from_batch(predict_batch(clf, X), classes=["left", "right"])

# StreamingSession final → BrainState
state = brain_state_from_streaming_result(final, classes=["left", "right"])
```

Upstream probabilities only (no head required):

```python theme={null}
from nimbus_bci import Prediction, decide

state = decide(
    Prediction(classes=["left", "right"], probabilities=[0.7, 0.3], uncertainty=0.2),
    preset="strict",
    user_id="subject_001",
)
```

See also [Python Streaming Inference](/python-sdk/streaming-inference) for the streaming bridge in context.

## Next Read

<CardGroup cols={2}>
  <Card title="Encoder contract" icon="plug" href="/personalizer/encoder-contract" />

  <Card title="Evidence" icon="chart-line" href="/personalizer/evidence" />

  <Card title="Overview" icon="layers" href="/personalizer/overview" />

  <Card title="Streaming" icon="activity" href="/python-sdk/streaming-inference" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.