# Agent Turn And Step Lifecycle This sequence is the visual companion to [architecture.md](architecture.md#turn-flow). It keeps durable replay facts on `session/event` and live control/status on `agent/*`. ```mermaid sequenceDiagram participant User participant Agent participant Driver participant Hooks as hook listeners participant Prompt as ctx.systemPrompt participant LLM as ctx.llm participant Tools as ctx.tools participant Session participant SDK as UI or SDK listener User->>Agent: followup(content) Agent-->>SDK: agent/inbox/spliced Agent-->>SDK: agent/inbox/inserted { message } Agent->>Driver: queued work wakes driver Driver-->>SDK: agent/status running Driver->>Session: turn/start Note over Agent,Driver: claim pending next-step input plus one queued prompt Driver-->>SDK: agent/inbox/spliced pure deletion Driver-->>SDK: agent/inbox/claimed { message, turn } per message Driver->>Prompt: system-prompt/assemble waterfall Driver->>Hooks: agent/pre-step waterfall Hooks-->>Driver: authoritative reject or enter(messages) alt proposed step rejected, first batch empty, or pre-step failed Driver-->>Driver: claimed batch stays removed, the open turn spends no step else enter proposed step Driver->>Session: step/start Driver->>Hooks: agent/request waterfall Driver->>LLM: prepareCall(config, signal) Note over Driver,LLM: cancellation during either async phase commits neither system nor users Note over Driver,Session: synchronous admission using the prepared call capability Driver->>Session: system/message ordered per-node reconciliation Driver->>Session: user/message per entered message Driver->>Session: request/header and request/context as needed Driver->>Driver: derive and freeze request from the log Driver->>LLM: bound prepared call through llm/stream waterfall LLM-->>Driver: StreamChunk* Driver-->>SDK: agent/assistant-stream chunk* alt final adapter or terminal in-band request failure Driver->>Session: assistant/attempt Driver-->>SDK: agent/assistant-stream committed end Driver->>Hooks: agent/request-error waterfall Hooks-->>Driver: return retry action or preserve the original error Note over Driver,LLM: retry in the open step: prepare and reconcile the same rendered assembly without repeating pre-step or users else model request succeeded Driver->>Session: assistant/message Driver-->>SDK: agent/assistant-stream committed end Driver->>Tools: classify pending call by executionMode loop barriers and bounded rolling pool, reclassify before start opt call starts Driver->>Session: tool/call Driver->>Tools: ordered pre, concurrent execute Tools-->>Session: tool-owned events when applicable end opt next model-order result ready Driver->>Tools: ordered post Driver->>Session: tool/result end end Driver->>Session: step/end opt natural stop and next-step inbox empty Driver->>Hooks: agent/turn-stopping serial terminal checkpoint end opt next-step input is pending Driver-->>Driver: claim pending next-step input Driver-->>SDK: agent/inbox/claimed { message, turn } per message Driver->>Hooks: agent/pre-step waterfall Hooks-->>Driver: authoritative reject or enter(messages) end end end Driver->>Session: turn/end Driver-->>SDK: agent/status idle ``` The `assistant/message` event records every successful provider call, including content-less and `max-tokens` finishes, and embeds the exact compact timed stream. Empty content stays out of derived history. A failed, retried, cancelled, or stream-error attempt that reaches settlement without a surface message records its stream as `assistant/attempt`. Live `agent/assistant-stream` chunk frames are transient; replay reads either durable settlement, and a hard process loss before settlement leaves no durable attempt stream. `dsh-compaction-basic` uses `agent/pre-step` for pressure before request derivation and `agent/request-error` only for canonical context overflow. Once either trigger qualifies, optional tool-result pruning runs before summary selection. Recovery runs within the open step and retries only when pruning or summarization advances the surface replacement generation; otherwise the original request error remains authoritative. Each retry prepares its call and reconciles the retained rendered assembly before request derivation, without repeating assembly, pre-step, or user admission. The returned `agent/pre-step` decision is authoritative; listeners wrapping `next()` preserve downstream messages and `startsRequestSeries` unless replacement is intentional. Steering and injected context pass through the same waterfall after a later claim operation takes their next-step batch. SDK users that need replayable transcript data should consume `session/event`; `agent/*` is the live coordination API for queue/status, prompt interception, request construction, steering, continuation, and errors. Maintenance mode: curated Mermaid sequence; exact event signatures live in the generated Cordis catalog.