---
title: Architecture
description: The settled architecture and why each property is load-bearing.
sidebar:
  label: Overview
  order: 1
---

UseAgent's architecture rests on a short set of settled decisions. Each one is
a commitment the rest of the system leans on: verification is evidence-based,
state is an event log, engines are replaceable adapters, and every run is an
isolated actor.

## The four properties

<CardGroup cols={2}>
  <Card title="Verify-gated" icon="shield-check">
    Verification is an evidence discipline, not self-grading: a conformance
    suite, environment-gated live proofs, and evidence recorded in the event
    log. Destructive gateway operations gate on a durable human approval lane
    with one-shot capabilities. A runtime verify stage on run completion is a
    design goal, not current behavior.
  </Card>
  <Card title="Event-sourced" icon="git-commit-horizontal">
    The run and step log in Postgres is the source of truth. State is the reduction
    of an ordered, durable event sequence, so runs replay and survive restarts.
  </Card>
  <Card title="Replaceable-engine" icon="plug">
    The inner loop is rented behind a neutral adapter. Codex, Claude, and OpenCode
    are interchangeable at the contract boundary.
  </Card>
  <Card title="Actors" icon="box">
    Each thread is an isolated actor with its own sandbox and working directory,
    held on a per-thread lease. Each run is one turn inside it, driven from
    outside by the harness.
  </Card>
</CardGroup>

## The harness lives outside the sandbox

This is the decision everything else follows from. The backend is the harness:
the event log, the workers, the SSE fan-out, org scoping, and knowledge all live
on the trusted side. The sandbox runs the engine and the work. The UI renders the
log, never a live process.

<div style={{ background: "#ffffff", border: "1px solid #ebebeb", borderRadius: "12px", padding: "12px" }}>
  <img
    src="/docs/diagrams/system-architecture.svg"
    alt="System architecture: the Next 16 browser UI reaches the Bun + Hono backend through the /api rewrite; runs/routes.ts accepts the run, worker.ts appends runs and steps to Postgres (the source of truth) and dispatches the turn to the thread's engine session in a Daytona sandbox; engine output flows back as provider events and SSE streams the event log to the browser."
    style={{ width: "100%", display: "block" }}
  />
</div>

*One turn end to end: the harness (routes, worker, SSE fan-out, Postgres) stays on
the trusted side of the dashed line; only the engine and its work run inside the
Daytona sandbox.*

The consequences are concrete:

- A run **survives a backend restart**, because its truth is the log, not a
  process' memory.
- Three different engines render through **one UI contract**, because their
  native output is durably stored first, then translated into one
  provider-neutral canonical schema by a post-finalize outbox worker, and
  canonical events are persisted before they are published to subscribers.
- A sandbox holds no **platform credentials**: privileged work goes through the
  [gateway](/concepts/gateway-tools-and-approvals), reached only with a
  short-lived signed run token. Org-configured secrets are intentionally
  injected for the engine's own tooling and surfaced in the timeline as a
  names-only `secrets.injected` marker.

:::note
Several tempting alternatives were evaluated and set aside: running the harness
inside the sandbox, building a bespoke inner agent loop, and embedding an
engine's own web UI. Each was rejected for recorded reasons. The architecture is
deliberately thin.
:::

## Where to go next

- [Request flow](/architecture/request-flow) traces one turn from prompt to
  rendered timeline.
- [Realtime and canonicalization](/architecture/realtime) covers the streams and
  the single-backend constraint.
- [Shared packages](/architecture/shared-packages) are the contracts that keep the
  frontend and backend honest.
