# Architecture (/brain/docs/architecture)

Brain sits between your application and the systems that do the work. Your application talks to Brain, Brain runs a harness for each active session, and the harness's tool calls go to implementations you authorize. This page follows one message through Brain, then explains how Brain stores and recovers sessions and which component owns what.

## How a message flows [#how-a-message-flows]

<Steps>
<Step>
### Your backend sends a message [#your-backend-sends-a-message]

Your backend sends a message to a session with an API token. Brain checks the token, records the message in the session's history, and queues it. Each session runs one turn at a time, and further messages wait in order.
</Step>

<Step>
### The harness runs the turn [#the-harness-runs-the-turn]

Brain starts the session's harness, or reuses the one already running. The harness, such as Pi, builds prompts, calls the model provider, manages context, and decides when the turn is finished. It runs with only the provider credentials it needs.
</Step>

<Step>
### Brain calls your tools [#brain-calls-your-tools]

When the model calls a tool, the harness hands the call to Brain. Brain checks that the tool is enabled for the session, records the call, validates the arguments, and dispatches it to your implementation together with the session's identity. Brain records the result and returns it to the harness.
</Step>

<Step>
### Brain streams events [#brain-streams-events]

As the turn runs, Brain records each event in the session's history and streams it to connected clients, along with live progress such as partial messages and tool progress.
</Step>

<Step>
### Brain saves a checkpoint [#brain-saves-a-checkpoint]

When the turn completes, Brain records a checkpoint: the position in the session's history and the harness's own state. If you configure external storage, Brain uploads the checkpoint in the background.
</Step>
</Steps>

## How Brain stores and recovers sessions [#how-brain-stores-and-recovers-sessions]

Each server keeps its sessions on local disk, so a running turn never waits on remote storage. External storage is optional. When you configure it, Brain copies each session's history and checkpoints there in the background, and any server with access to that storage can load the session.

When a request names a session that the server doesn't have, Brain loads the session's latest checkpoint from external storage. The loaded session waits for you to resume it before it runs again. You can also force an upload, check upload progress, or restore a specific checkpoint.

<Callout type="warn" title="Unsynced data">
If a machine fails before a background upload finishes, only the events since the last completed upload are lost. Restoring from external storage always lands on the latest complete checkpoint.
</Callout>

After a restart, Brain loads each session from local disk the next time a request uses it. A session whose turn was running when Brain stopped comes back interrupted; resume it to continue. See [Persistence & recovery](/brain/docs/guides/persistence) to configure storage and hand a session to another server.

## Who owns what [#who-owns-what]

| Component | Owns |
| --- | --- |
| **Brain** | The API, authentication and tenant isolation, message queueing, event streaming, tool calls, session storage, checkpoint uploads, and telemetry. |
| **Harness** | Model requests, prompts, context management, and its own session state. |
| **Tool service** | Tool execution, sandboxes, external jobs, human approvals, retries, and resource cleanup. |
| **Host platform** | End-user authentication, routing each session to a single server, scaling, and failover. |

## How errors are handled [#how-errors-are-handled]

Brain separates three kinds of errors, so a failure in one layer doesn't look like a failure in another:

- **Request errors:** Brain rejects an invalid request and leaves the session unchanged.
- **Tool failures:** Denials, errors, timeouts, and dropped connections return to the model as tool results, so it can react. Brain sends each tool call at most once; your tool service owns retries and cleanup.
- **Execution failures:** A model provider error, a harness crash, or a failed disk write stops the turn and reports a session error. The session stays stopped until you resume it.

## Design principles [#design-principles]

- **Keep the core small:** Harnesses own inference and context; applications install tools and own approvals.
- **Fail explicitly:** Tool errors become tool results, and Brain errors stop the affected turn. Missing or damaged state returns an error instead of silently starting a fresh session.
- **Bound every queue:** Message queues, event streams, and storage retries all have limits. At capacity, Brain turns away new work instead of slowing down running turns, and health checks and stream keepalives never call the model.

## Storage details [#storage-details]

You don't need these details to use Brain. They show how Brain keeps the guarantees above.

- **Local state:** SQLite stores each session's record, including its owner and configuration. Append-only files store the session's event history and the harness's native state.
- **External checkpoints:** A background worker uploads the event history and the harness's native files as immutable 64 KiB blocks to a local directory, Amazon S3, Cloudflare R2, or Google Cloud Storage. A checkpoint becomes visible only after all of its blocks are in place, and later checkpoints reuse blocks that are already uploaded.
- **Session index:** An optional, eventually consistent PostgreSQL index lets any server find sessions stored by the others.

[Persistence & recovery](/brain/docs/guides/persistence) covers storage configuration, flushes, and handoff. [Harness adapters](/brain/docs/adapters/harness) explains how Brain runs a harness, and the ADR below records the design decisions.

## Design references [#design-references]

- [ADR 0001: Local-first ephemeral session server](https://github.com/aexhq/brain/blob/main/docs/adr/0001-local-first-session-server.md)
- [Roadmap](/brain/docs/roadmap)
- [Implementation plan](https://github.com/aexhq/brain/blob/main/docs/implementation-plan.md)

## Next steps [#next-steps]

<Cards>
  <Card icon={<MessagesSquare />} title="Session lifecycle" href="/docs/guides/sessions">Send messages, stream events, and handle interruptions.</Card>
  <Card icon={<Database />} title="Persistence & recovery" href="/docs/guides/persistence">Configure external checkpoints and move sessions between servers.</Card>
  <Card icon={<Puzzle />} title="Adapters" href="/docs/adapters">Add a harness or a storage backend through small Go interfaces.</Card>
</Cards>
