Skip to main content
The protocol is stated as Protocol classes, so “conforming” is something a type checker can verify. Nothing in boltzmann.protocol is implemented — those are the operations an implementation provides; the SDK provides the types they exchange, the identities they compute, and the invariants they must not break.

The protocol surface

The surface is split because read and extend are separable, and most consumers only read. Every one is runtime_checkable:
A read-only client that satisfies BrainReader is conforming. It does not have to pretend to support writes it will refuse. Conforming to BoltzmannProtocol is not required.

What you plug in

Where the paper leaves something to the implementation — ranking, fusion, index engines, cascade depth, retention thresholds — so does this SDK.

CandidateProposer

Interprets a source and proposes typed blocks. Implemented by the caller, never here — it is the only place interpretation enters.

QueryPlanner

Turns a declarative query into a verified Evidence Bundle. Ranking and index selection are explicitly implementation-defined.
Without one, the brain falls back to boltzmann.query.scan — a deliberately simple term scan that is correct and unranked, not a retrieval engine.

Index

A derived view over a module’s composition. Which engine backs an index is the implementation’s choice, so none ships here.
build receives the module’s whole readable composition on every write, not the increment — it is a rebuild, so an index that accumulates must clear or deduplicate. The content reader is for blocks that name their datum rather than carrying it: a canonical block is a digest, a media type and a size, with nothing to index until you read the bytes. Ask the block what it names and read that:
ContentReader is deliberately narrower than BlockStore — no put_bytes, no tombstone, no delete. An index is a derived view and has no business writing. A BlockStore satisfies it structurally, so supplying one costs nothing.
An index that reports rebuildable = False must also satisfy TravellingIndex, because no client can regenerate it — it ships with its module.
model_tag is what stops a consumer from mixing two representation spaces: a vector index built by another model is refused on pull rather than silently ranked against yours.
A query never names an index. open_index exists for tooling that inspects or rebuilds a brain, not for retrieval.

Validator

One check applied to a candidate before it can be committed.
The seven checks in DEFAULT_VALIDATORS are described in Ingestion.

Others

Invariants made structural

The paper states these as rules. Here they are errors, each with a test:
  • A Candidate is not a Block and has no block_id — an unvalidated proposal has no identity, so it cannot be committed by accident.
  • ProcessingTask refuses to let a model propose canonical or provenance blocks.
  • Module exposes no write method; deriving returns a new module.
  • EvidenceBundle has no answer field. Not omitted — absent by design.
  • Composition.drop() on the episodic module raises, and no policy can permit it.
  • RetentionPolicy.record_removals is a property that is always True — no configuration turns auditability off.
  • A float in a payload fails at construction.

Exceptions

Every error derives from BoltzmannError, in six families: