# Agent Turn And Step Lifecycle
This sequence is the visual companion to [architecture.md](architecture.md#default-loop-lifecycle). 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
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->>Hooks: agent/pre-step waterfall
Hooks-->>Driver: authoritative reject or enter(messages)
alt proposed step rejected or pre-step failed
Driver-->>Driver: claimed batch stays removed, no turn opens
else enter proposed step
Driver->>Session: turn/start
Driver->>Session: step/start
Driver->>Session: user/message per entered message
Driver->>Prompt: system-prompt/assemble waterfall
Driver->>LLM: agent/request waterfall, then llm/stream waterfall
LLM-->>Driver: StreamChunk*
Driver->>Session: assistant/chunk*
Session-->>SDK: session/event assistant/chunk*
alt final adapter or terminal in-band request failure
Driver->>Session: step/end
Driver->>Hooks: agent/request-error waterfall
Hooks-->>Driver: return retry action or preserve the original error
else model request succeeded
Driver->>Session: assistant/message
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
Driver->>Session: turn/end
end
Driver-->>SDK: agent/status idle
```
The `assistant/message` event records every successful provider call, including content-less and `max-tokens` finishes. Empty content stays out of derived history, while the durable event keeps usage and `sourceEventSeqs` listing the exact `assistant/chunk` events, including an explicit empty list.
`dsh-compact-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 works between the closed failed step and failed turn close, and opens a fresh retry turn only when pruning or summarization advances the surface replacement generation; otherwise the original request error remains authoritative.
The returned `agent/pre-step` decision is authoritative; listeners wrapping `next()` preserve downstream messages unless replacement is intentional. Steering and injected context pass through the same waterfall after a later boundary claims their next-step batch.
SDK users that need replayable transcript data should consume `session/event`; `agent/*` is the live coordination surface for queue/status, prompt interception, request shaping, steering, continuation, and errors.
Maintenance mode: curated Mermaid sequence; exact event signatures live in the generated Cordis catalog.