A run is one execution.
A top-level run starts a run tree identified by rootRunId. A nested run keeps that same rootRunId and has its own runId. Events in the tree are ordered by sequence, strictly increasing and contiguous for that root.
A run is in exactly one state: running, paused, finished, error, or cancelled. stopRequested is a flag, not another state. A paused run resumes before it can finish.
A run cannot emit a terminal while it still owns an open child run, tool call, interrupt, pause, or a profile-defined blocking aggregate. The backend closes, cancels, or fails that work first.
run.stop.requested sets the flag. After that, the backend does not start new child runs or tool calls for that run. Silence, or a dropped connection, is not a terminal.
A pause is a durable stop in the work, not an error. resumeMode is automatic or command.
Each run may bind one clientExecutorId, chosen before run.started and recorded on that event. A nested run defaults to the parent’s executor, and still records its own binding. Omission means no client executor. The binding does not change after the run starts. If none is selected, the backend does not start a tool with executor=client.
An interrupt belongs to one paused run and one pause cycle (waitId). At most one open blocking interrupt per run. Nested runs may each have their own.
A tool call belongs to exactly one run. Its executor is backend or client.