A first agent
Conceptually, an agent is a name plus a recipe. The name is how operators identify it in the console and the API; the recipe is the ordered set of steps it takes when it runs. A minimal one looks like this:agent.json
The mental model: scheduled session
Think of an agent as a scheduled session against the runtime. When the trigger fires, the platform opens a session for the agent, authenticates it as a workspace-scoped principal, and feeds it the steps in order. Each step runs inside the same isolation boundary as a normal page request — the agent reads from the same workspace database, dispatches the same capabilities, hits the same rate limits. Two properties fall out of that shape:- An agent has no privileges beyond the workspace. It cannot reach another workspace’s data; it cannot mint a token for itself; it cannot bypass policy. The same boundaries that hold for a human caller hold for the agent’s session.
- Every step is auditable. Reads and writes both append to the workspace’s audit log under the agent’s principal. The log records what the agent looked at, not only what it changed.
What an agent can do
An agent’s recipe is built from a small set of agent capabilities. They split into reads (gather context without changing state) and writes (dispatch a side effect or change state). The split between reads and writes is the basis for the approval system below — writes are the steps that get gated.Triggers
An agent fires on a trigger. Triggers are declarative and live on the agent definition; you do not write listener code. A single agent can declare multiple triggers. The runtime opens a separate session per fired trigger, so two concurrent triggers do not race against each other’s state.Sessions, runs, and replay
A run is one execution of the agent’s recipe. The runtime gives each run a stable id, a session token scoped to that run, and a position cursor that advances as steps complete. If the session is disconnected mid-run — a deploy, a transient network failure — the run resumes from the cursor on reconnect rather than restarting from step one. Steps that already wrote are not re-dispatched; the runtime knows because the audit chain already recorded the result. This matters for two reasons:Approval gates
Writes can be gated. A step markedrequires_approval does not dispatch when the run reaches it — instead, the runtime opens an approval record, pauses the session, and waits. An operator approves or denies; the run continues or stops accordingly.
The decision is recorded in the run’s audit chain alongside the principal who made it. That is the surface a workspace owner uses to answer “did anyone authorize this?” after the fact.