One vocabulary

Five jobs. One package.

There is no separate memory product, no separate observability product and no separate tooling vocabulary. pip install cosmonapse gives you every term on this page. What differs between them is not where they ship from but what they are for: agreeing on a format, doing work, connecting that work to the bus, being called, and being watched.

Genesis and Prism are tools built over this vocabulary rather than additions to it. Genesis lays these primitives out on a canvas and writes them into your project; Prism reads them off the bus. Neither introduces a concept you would have to learn twice.

The contract

Agree on a format, or nothing else works.

What every part of the system agrees on before it can say anything.

Cosmonapse Core

Signal
Envelope
A single message crossing the Synapse, and the only thing Cosmonapse guarantees. Two components that produce valid Signals can always interoperate, whatever language each is written in. Every Signal carries its own id, a trace_id, and the parent_id of whatever caused it, so causality is in the envelope rather than reconstructed later.
Synapse
Channel · transport
The transport all Signals cross, and a swappable one: MemorySynapse for tests, DevSynapse for local multi-process work, NatsSynapse or KafkaSynapse in production. Your components do not know which is underneath them - the scale path is a URL change. Capability-routed TASKs publish on cosmonapse.<ns>.TASK.routed with queue groups, so the broker delivers each one exactly once within a matching capability profile.
Namespace
Isolation boundary
Every Signal is published under a namespace, and a Dendrite serves exactly one. Two namespaces on the same broker never see each other's traffic, so a staging system and a production system can share infrastructure without sharing a bus. A running system is addressed everywhere - the CLI, Prism, Genesis - as a Synapse URL plus a namespace.
The participants

Neurons think. Engrams remember. Effectors act. Receptors listen.

The four kinds of thing a Signal can be addressed to. The division of labour between them is the whole design.

Cosmonapse Core

Neuron
Thinks · LLM provider · async function
The thinking layer, behind a pure-function interface: it receives (input, context), returns output, and knows nothing about the protocol. The Neuron(source=...) factory wraps OpenAI, Anthropic, HuggingFace, Groq, Mistral, Together, OpenRouter or Ollama - or a plain async function - behind that one callable. A Neuron decides; it never opens a file, calls an API or spawns a subprocess. A tool is not a Neuron, and neither is an HTTP API.
Engram
Remembers · memory backend
Shared memory as a participant on the bus rather than a library you import, which is why memory access shows up in a trace like everything else. A backend either subclasses Engram or is built from decorators with Engram.serve(engram_id=...). InMemory, SQLite and Postgres ship today, and a backend failure rides the reply instead of raising a separate ERROR.
Effector
Acts · tool · MCP server
The action layer, modelled deliberately on Engram: same addressing (effector_id or effector_kind), same mounting (dendrite.attach_effector), same rule that failures ride the reply. It services TOOL_CALL and answers with TOOL_RESULT, so a failing tool never terminates the parent TASK. An MCP server is an Effector. Cosmonapse does not build your tools - dispatch tables, MCP sessions, subprocesses and sandboxing stay your code.
Receptor
Listens · the outside edge
An interface primitive: outside world → TASK → outside world. CliReceptor turns a typed command into a dispatch and derives its argparse surface and REPL from the function signature; ApiReceptor exposes one HTTP endpoint across all three dispatch modes; ChatReceptor handles one turn per dispatch with a served page. A Receptor is caller-side and adds no new Signal types, so a request that arrived from a terminal is indistinguishable on the wire from one dispatched by a Neuron.
The connective tissue

One component touches the bus. Exactly one.

What joins a participant to the bus - and what deliberately keeps it away from it.

Cosmonapse Core

Axon
Agent-side tool
The only piece of Cosmonapse that lives inside the Neuron's process. It wraps the Neuron function, validates its output into a Signal (AGENT_OUTPUT, CLARIFICATION, PERMISSION or ERROR), and hands it to the Dendrite - the Neuron itself never touches the protocol. Axon(effectors=[...], tool_standard='hermes'|'claude'|'codex') is also where a model's native tool-call dialect is recognised and turned into a TOOL_CALL.
Dendrite
Synapse-side connector
The only component that touches the Synapse. It hosts Axons, owns routing decisions, exposes the aggregate of its Axons' capabilities, and emits REGISTER / HEARTBEAT / DEREGISTER for each one. Its role is orchestrator (may dispatch TASKs) or worker (hosts Axons only) - and workers are guarded, so they can serve TASKs and bid in capability routing but cannot emit orchestration signals.
Brain
Team of agents
A collection of participants sharing one Synapse and namespace. Brain is an organising idea rather than a class you instantiate: in a project it is the brain.py that attaches everything and calls Dendrite.run(). It is the unit teams reach for when grouping components by capability or domain.
The verbs

Three calls cover dispatch and memory.

What you actually call. Three primitives cover dispatch and memory.

Cosmonapse Core

Pathway
Per-trace event handle
Returned by dendrite.dispatch(...). One primitive with three consumption shapes: await pw.wait() for sequential request/reply, @pw.on(SignalType.X) for reactive trace-scoped callbacks, and async for sig in pw for streaming. Pathway(scope="terminal") filters to FINAL / ERROR / CLARIFICATION only - the decentralised pattern where the caller wakes only for events that need attention. observe_pathway(trace_id) opens one in observer role to watch a trace someone else started.
Recall
Read path · RECALL signal
Reads bound memory before a Neuron acts. The Axon emits RECALL; the Engram replies RECALLED carrying hits. EngramClient.recall() is the in-Neuron API, and a Neuron that declares a recall= parameter gets the helper injected by its Axon. With Engram.serve(), the return value of @on_recall becomes the hits.
Imprint
Write path · IMPRINT signal
Durable writes to bound memory. The Axon emits IMPRINT; the Engram replies IMPRINTED carrying a receipt. Operations are add, append, merge, upsert and delete. With Engram.serve(), @on_imprint runs the write and its return value becomes the receipt - distinct from @engram.host.on_imprint_signal, which only observes writes the Dendrite has already serviced.
The read-only seat

Watch everything. Take nothing.

How anything watches the system without becoming part of it.

Cosmonapse Core

Doppler
Non-competing subscriber
Not a class but a stance on the bus: a subscriber that joins no queue group. Every ordinary consumer competes for a message, so exactly one of them gets it; a Doppler competes for nothing, so it sees every Signal and can never take work away from a participant. That single property is what makes observability safe to attach to a running system - and it is what Prism is built on. cosmo prism --tail streams the same feed to stdout.
How they fit together

A Brain in motion.

A Brain is a set of participants sharing one Synapse and one Namespace. Each is reached through a Dendrite - the only component that touches the Synapse - which carries Signals between them and exposes the orchestration primitives for whoever needs them.

Four kinds of participant hang off that Synapse, and the division of labour is the whole design: Neurons think, Engrams remember, Effectors act, Receptors listen. A Neuron is a pure function that decides; when it decides to act, it emits a TOOL_CALL and an Effector answers with a TOOL_RESULT. That is where tools and MCP servers live - an MCP server is an Effector, not a Neuron. Effector is modelled on Engram deliberately: same addressing, same mounting, and the same rule that a backend failure rides the reply rather than raising a separate ERROR and killing the TASK.

Persistent state lives in an Engram, written via Imprint and read via Recall - both of them Signals on the same bus, which is why a memory read is visible in a trace. Requests from outside arrive through a Receptor, which turns a command, an HTTP call or a chat turn into the same TASK an orchestrator would have dispatched. It adds no new wire types, so nothing downstream has to know the difference.

Nothing in that picture is a supervisor. A Pathway is a handle on one trace, not a controller of it: whoever dispatched can await a terminal Signal, subscribe to events on that trace, or stream them - and can walk away entirely, because the work proceeds whether or not anyone is listening.

Receptor - CLI · HTTP · chat
A person, a scheduled job or another system arrives here. The Receptor turns the request into a root TASK Signal and dispatches it through an orchestrator Dendrite.
Dendrite - synapse-side connector + orchestration
Receives the TASK. Routes it to the attached Axon matching the target neuron_id, or to whoever matches the requested capabilities. Emits FINAL when done. Every Dendrite can orchestrate - there is no separate Cortex class.
Neuron - LLM provider · async function
Receives (input, context). Returns a plain dict. The Neuron factory wraps any provider - OpenAI, Anthropic, HuggingFace, Groq, Ollama - or a plain async function, knowing nothing about the Synapse, envelopes or trace IDs.
Effector - tools · MCP servers · side effects
Services TOOL_CALL, replies TOOL_RESULT. When a Neuron decides to act, its Axon recognises the model’s native tool-call dialect and the call is dispatched to the bound Effector, whose result is fed back on the same trace. Tool errors ride the TOOL_RESULT, so a failing tool never terminates the TASK.
Engram - Recall · Imprint
Persistent shared state, written by Imprint and queried by Recall. Both are Signals, so both appear in the trace beside the reasoning that needed them.

A Doppler sits beside this whole picture rather than inside it. It subscribes to the Synapse without joining a queue group, so it competes for nothing and sees every Signal flow past. Prism is that stream rendered in a browser; cosmo prism --tail is the same stream on stdout. Neither is privileged - anything willing to speak the envelope can take the same seat.

Resolution & retry

How a Pathway resolves - and retries.

Every dispatch opens a Pathway - a per-trace handle scoped to one trace_id. In the request/reply shape, the Dendrite owns the whole arc: it dispatches the TASK, waits for the first terminal Signal, then closes the Pathway. A Pathway resolves the moment a terminal arrives - a FINAL (success), an ERROR, or an interactive CLARIFICATION / PERMISSION the caller must answer. With scope: "terminal" only those are delivered; with scope: "all" the cognition stream (THOUGHT_DELTA, PLAN, TOOL_CALL…) flows past first and the terminal still closes it.

A Pathway is considered stuck in three cases: no terminal arrives within timeout_s (a timeout on the wait), the Pathway closes before any terminal (a PathwayClosedError, e.g. the worker died), or it resolves to an ERROR flagged recoverable. A FINAL, AGENT_OUTPUT, CLARIFICATION, or PERMISSION is never “stuck” - each is a result or a decision the caller must handle, not something to retry behind their back.

Retry is a declarative policy - a RetryStrategy - handed to dispatch_and_wait(retry=…) or run_with_retry(…). It controls how many attempts to make, the per-attempt timeout, the backoff between tries, and the predicate that decides whether a given outcome is worth retrying. Because retry transparently re-dispatches, it only fits the request/reply shape: the streaming shapes (dispatch / dispatch_and_subscribe) hand the live Pathway back to the caller, so retrying there would orphan their subscriptions - wrap those in a resilient-pathway pattern instead.

The subtle part is what happens to the abandoned attempt. By default each retry runs on a fresh trace, and before launching it the Dendrite broadcasts a STOP on the old trace. STOP is cooperative cancellation: every Dendrite hosting work on that trace cancels its in-flight Neuron call and Engram I/O, and - when rollback_on_retry is set - replays that trace’s per-trace saga journal in reverse to undo half-finished Engram writes, then acks with STOPPED. This is what stops a stalled worker from continuing to run (and keep writing memory) behind a retry that has already moved on. Rollback reverses Engram state only - a side effect a Neuron caused in the outside world (a sent email, an external write) is reversed only if that Neuron registered its own compensator.

1 · Dispatch & wait
Open a Pathway on a fresh trace, dispatch the TASK, and await the first terminal Signal within timeout_s.
2 · Evaluate the outcome
If the outcome is terminal-and-final (FINAL / AGENT_OUTPUT / CLARIFICATION / PERMISSION), return it. If it is a timeout, an early close, or a recoverable ERROR - and attempts remain - retry.
3 · Preempt the abandoned attempt
Broadcast STOP on the old trace. Hosts cancel in-flight work, optionally roll back Engram writes via the saga journal, and ack with STOPPED.
4 · Back off & re-dispatch
Sleep backoff(attempt), fire the optional on_retry hook, and loop with a new trace until a non-retryable outcome or attempts are exhausted.

See STOP / STOPPED in the envelope spec, and RetryStrategy / run_with_retry in the SDK reference.

Glossary cheatsheet

Every term, and what it is called elsewhere.

Cosmonapse termConventional termOne-line
The contractWhat every part of the system agrees on before it can say anything.
SignalEnvelopeA single message crossing the Synapse, and the only thing Cosmonapse guarantees.
SynapseChannel · transportThe transport all Signals cross, and a swappable one: MemorySynapse for tests, DevSynapse for local multi-process work, NatsSynapse or KafkaSynapse in production.
NamespaceIsolation boundaryEvery Signal is published under a namespace, and a Dendrite serves exactly one.
The participantsThe four kinds of thing a Signal can be addressed to. The division of labour between them is the whole design.
NeuronThinks · LLM provider · async functionThe thinking layer, behind a pure-function interface: it receives (input, context), returns output, and knows nothing about the protocol.
EngramRemembers · memory backendShared memory as a participant on the bus rather than a library you import, which is why memory access shows up in a trace like everything else.
EffectorActs · tool · MCP serverThe action layer, modelled deliberately on Engram: same addressing (effector_id or effector_kind), same mounting (dendrite.attach_effector), same rule that failures ride the reply.
ReceptorListens · the outside edgeAn interface primitive: outside world → TASK → outside world.
The connective tissueWhat joins a participant to the bus - and what deliberately keeps it away from it.
AxonAgent-side toolThe only piece of Cosmonapse that lives inside the Neuron's process.
DendriteSynapse-side connectorThe only component that touches the Synapse.
BrainTeam of agentsA collection of participants sharing one Synapse and namespace.
The verbsWhat you actually call. Three primitives cover dispatch and memory.
PathwayPer-trace event handleReturned by dendrite.dispatch(...).
RecallRead path · RECALL signalReads bound memory before a Neuron acts.
ImprintWrite path · IMPRINT signalDurable writes to bound memory.
The read-only seatHow anything watches the system without becoming part of it.
DopplerNon-competing subscriberNot a class but a stance on the bus: a subscriber that joins no queue group.

All 14 terms ship in Cosmonapse Core today. Cortex is kept as a back-compat alias for Dendrite; new code should use Dendrite directly. Axon remains part of the Core runtime but is largely an implementation detail - applications interact with Dendrites, Neurons and Receptors. Names that appear on the roadmap but nowhere in the SDK are deliberately kept off this page.