API reference

Events

The run event stream — alineod lifecycle events, forwarded harness events, heartbeats, and reconnection.

curl -N localhost:4600/runs/r_3f9a1c20/events

GET /runs/:runId/events is a Server-Sent Events stream carrying the entire run: alineod's own lifecycle events and the harness events of every agent in the run. Every event's data is JSON with an agentId field (null for run-level events).

id: 7
event: agent.steered
data: {"agentId":"a_c01d9e3a","message":"Focus only on src/auth."}

Lifecycle events

These are always persisted to the ledger and carry an id.

EventFieldsWhen
run.startedrunId, closeWhenA run is created.
run.closedreasonThe run finalized and its sandboxes were released. reason is explicit (a DELETE) or quiescent (closeWhen: "quiescent").
agent.spawnedparentAgentId, runId, specName, depth, spawnIndex, sandboxId, waitFor, promptAn agent is accepted. sandboxId is null until provisioned.
agent.provisionedsandboxIdThe agent's sandbox exists and its harness is reachable.
agent.restoredoldSandboxId, checkpointTurnThe agent's sandbox was gone and a fresh one replaced it, right after agent.provisioned. checkpointTurn is the turn restored from, or null when there was no checkpoint and the session came back blank.
agent.state_changedfrom, to, reason, pausedByA state transition, e.g. spawning → provisioning (deps-settled) or running → paused (operator).
agent.steeredmessage, scope, roster, deliveredAsA steer message was accepted. roster and deliveredAs are set for a subtree steer.
handle.settledoutcome, resultRefThe agent's result is available.
agent.endedoutcome, endedAt, error, errorCodeThe agent finished, failed, was stopped, or was lost.
budget.denieddimension (spawnDepth | maxAgents), remainingA spawn under this agent was refused by a budget.
agent.releasedreasonA finished agent's open sandbox was closed (stop / delete), or a fork landed after its spawn was stopped. Its outcome is unchanged.
wait.resolvedmode, outcome, selected, settled, pendingA held spawn's waitFor resolved. depfail / deadline end the child without forking.
wait.blockedblockedOnA held spawn is still waiting on a dependency that's paused.
run.quiescentmemberCount, asOfThe subtree rooted at this agent just finished, while someone was waiting on it.
notify.registeredon, wakeThis agent subscribed to be told when the agents in on finish.
inbox.queuedkind, aboutAgentId, outcome, resultRef, excerpt, again, textA notification (or a queued subtree steer) is waiting for this agent.
inbox.deliveredseqs, as (steer | turn | prompt)Queued items were delivered.
inbox.droppedseqs, reasonQueued items were dropped because the recipient closed.
agent.turn_retriederror, errorCode, attempt, maxAttempts, delayMsA turn failed on a transient provider error (429 or 5xx) and is being re-sent after a backoff. Not counted as a failure.
agent.turn_failederror, errorCode, consecutiveFailuresA turn failed — recorded before the supervision policy decides what happens next.
agent.supervision_neededreason (ask | retries-exhausted | circuit-tripped), error, errorCodeThe agent is blocked, waiting on a prompt (retry) or a stop.
agent.turn_interrupted—On boot, the agent was found mid-turn: that turn died with the previous alineod process or with its container.
agent.checkpointedturn, snapshotRef, remoteRef?, uploadError?A turn checkpoint was written, after a turn that finished cleanly on a spec with "checkpoint": true. remoteRef is the copy in the backup bucket; without it the checkpoint is on this machine only, and uploadError says why when an upload was tried.
agent.admission_queuedcapacityNo provisioning slot was free, so the fork is held. Only emitted when a real wait happens.
agent.admission_granted—A held provisioning request got its slot.
agent.admission_timeoutwaitedMsA held provisioning request got no slot within ALINEOD_ADMISSION_TIMEOUT_MS and failed.

Harness events

Each agent's stream events (the SDK's AgentEvent) are forwarded onto the run stream under their own type names, tagged with the agentId that produced them.

Persisted — carry an id and are replayed on reconnect:

session.started, session.ended, turn.started, turn.ended, tool.started, tool.ended, compaction.started, compaction.ended, permission.requested, permission.resolved, retry.started, retry.ended, extension.error

Ephemeral — no id, never replayed: everything else, including high-volume message.updated deltas and tool.updated.

Reconnecting

Send the last id you received as Last-Event-ID:

curl -N localhost:4600/runs/r_3f9a1c20/events -H 'Last-Event-ID: 128'

alineod replays every persisted event after that seq from the ledger, then switches to live events. Ephemeral events emitted while you were disconnected are lost; persisted events are not.

To start from a known snapshot, read GET /runs/:runId and use its asOf as Last-Event-ID.

Heartbeats

A comment line is sent every 10 seconds so proxies and clients don't treat a quiet run as a dead connection.

Slow consumers

If a client stops reading, alineod drops ephemeral events for that connection first. If it falls behind by 500 persisted events in a row, the connection is closed — reconnect with Last-Event-ID to continue with nothing missed.