# Framework Architecture

> Understand Agent, Engine, Session, the TurnBackend entry point, and how in-process and Platform execution share one kernel.

Source: <https://everruns.com/docs/framework/architecture/>

Everruns has one turn model and two ways to execute it. Either way a session is an actor whose state is its event log, and a lease keeps one runner on it. A library application uses the concrete `everruns::Engine`, whose sessions run in process. The Everruns Platform runs them on workers: the server marks a session runnable, and a worker leases it and runs the whole turn. Every path converges on the same `everruns-core` (`engine` feature) Input/Reason/Act state machine.

![Framework execution architecture: the Framework app and the Platform server start turns through the TurnBackend entry point in everruns-core; the Framework's ActorRunner (the in-process backend plus a session lease) drives the core::engine kernel directly, while on the Platform the server's ActorTurnBackend marks a session runnable in session\_actors and a worker's actor\_runtime leases it over gRPC and drives the same kernel for one whole turn, resumed by folding the session log; the generic everruns-durable engine over an in-memory or PostgreSQL store carries background tasks.](https://everruns.com/docs/_astro/architecture.CK47iAGy_CeBiS.svg)

## Public Framework objects

| Object        | Responsibility                                                                                                 |
| ------------- | -------------------------------------------------------------------------------------------------------------- |
| `Agent`       | Immutable behavior: instructions, model and provider, tools, capabilities, files, and lifecycle hooks          |
| `Engine`      | Concrete process-local owner of Agent snapshots, session identity, backends, history, and resume authority     |
| `Session`     | First-class, engine-bound conversation used for turns, steering, events, cancellation, inspection, and history |
| `Environment` | Session resources, including one exact backend-owned workspace head and typed extensions                       |

New Framework code creates and resumes sessions through an Engine:

```rust
use everruns::{Agent, Engine, OpenAI};


let agent = Agent::builder()
    .instructions("Answer concisely.")
    .provider(OpenAI::from_env()?)
    .model("gpt-6.1-sol")
    .build()?;


let engine = Engine::new();
let session = engine.create(agent);
let session_id = session.session_id();
let turn = session.send_and_wait("Begin.").await?;
assert!(turn.success);


drop(session);
let resumed = engine.resume(session_id).await?;
assert_eq!(resumed.session_id(), session_id);
```

## Two execution paths, one kernel

A host hands each turn to a `TurnBackend`, the turn entry point in `everruns-core` (`host` feature) that starts, cancels, and observes a session’s turns. The backend decides only where the planned steps run and what survives a crash; it never plans the turn itself.

* **In process, as an actor.** `InProcessBackend` runs the turn on the task that awaits it, through `InProcessRuntime`. Every `everruns::Engine` session runs on `ActorRunner`, which wraps it and holds the session’s lease while a turn runs, so two processes sharing a local data directory never run one session at once (see [One process runs a session at a time](https://everruns.com/docs/framework/sessions/#one-process-runs-a-session-at-a-time)). Dropping the turn’s future stops it; a turn a restart cut off resumes from the event log.
* **On workers (Platform).** The Platform server persists each input and starts the turn from it through the same trait, on its `ActorTurnBackend`, which marks the session runnable in the transaction that stored the input. A worker leases the session over gRPC and runs the whole turn with the same loop the in-process runtime uses, renewing the lease while it runs. When a worker dies, its lease expires and another worker resumes the turn from the session’s event log: recorded results stand, and a call cut off mid-run is rerun only when its tool declares that safe.

A caller either hands the backend input to record (`TurnInput::Message`, `TurnInput::ToolResults`) or names input it already recorded through its own store (`TurnInput::StoredMessage`, `TurnInput::RecordedToolResults`). Every backend serves the stored forms, so a host that persists input itself starts and continues turns the way the Platform server does.

`everruns-durable` is a generic core the Platform uses for background work: a task queue, an event log, signals, a worker registry and pool, a dead letter queue, circuit breakers, and schedules, with an in-memory store and a PostgreSQL store. It knows nothing about agents or turns. `everruns-durable-engine`, which runs a turn as queued, checkpointed steps on it, remains a published experimental backend.

Neither path owns a private copy of the turn algorithm. `everruns-core` (`engine` feature) owns the `Execution` contract, `TurnExecution` state, Input/Reason/Act atoms, phase ordering, and effect production, and its host module owns the turn loop and the log fold that resumes a turn. Each path only selects where the turn runs and which lease keeps it single.

## Choose a recovery boundary

* **Volatile Framework:** `Engine::new()` is offline and database-free. The creating Engine can resume a dropped Session, but process exit loses it.
* **Local crash-durable Framework:** `LocalConfig` stores canonical events and session identity locally. Rebuild the trusted Agent configuration, attach it to a new Engine, and resume by typed `SessionId`.
* **Distributed durable Platform:** server and workers keep each session’s event log in PostgreSQL and lease sessions to workers, so a turn recovers across process or worker loss. Applications call it through the remote API or SDKs rather than configuring the facade Engine.

See [Persistence](https://everruns.com/docs/framework/sessions/#persistence) and [Session History and Resume](https://everruns.com/docs/framework/sessions/#history-and-resume) for the exact application lifecycle.

## Extension boundaries

Normal applications depend on `everruns`. `everruns::Engine` is concrete and is not implemented by applications. Provider integrations implement the open `ChatDriver` boundary, while canonical storage hosts can implement `EventLog`/`EventReader` through `everruns-core` (`host` feature).

An application that is itself an execution host may compose `everruns_core::engine::Execution` with `everruns-core` (`host` feature) or `everruns-durable-engine`, or implement `TurnBackend` for its own backend. Both interfaces are experimental. That is an advanced deployment boundary: preserve event ordering, workspace isolation, credential separation, cancellation, and committed effect semantics. Start with [Custom Backends](https://everruns.com/docs/framework/custom-backends/) before crossing it.