# Tool Execution Pipeline
This graph shows where policy, hooks, sandboxing, filesystem guards, result rewriting, and UI rendering fit without changing the loop. The key extension points are the `tools/pre-execute`, `tools/execute`, and `tools/post-execute` waterfalls.
```mermaid
flowchart TD
model["Assistant message contains tool-call block"]
toolCall["Session event: tool/call
logged before execution"]
presentCall["UI pending card
presentCall(args)"]
pre["tools/pre-execute waterfall
hooks, permission, sandbox"]
denied["deny or ask
tool body skipped"]
around["tools/execute waterfall
timeout, retry, metrics (around dispatch)"]
toolBody["Registered tool execute() body"]
fsGate["fs/write-intent or fs/edit-intent
tool-fs mutations only"]
owned["Tool-owned session events
todo/write, fs/observed, hook/invoked, hook/result"]
post["tools/post-execute waterfall
accept, block, replace, add context"]
context["Buffered additionalContext
context/message after all tool results"]
toolResult["Session event: tool/result
single model-facing outcome"]
presentResult["UI completed card
presentResult(args, result)"]
model --> toolCall
toolCall --> presentCall
toolCall --> pre
pre -->|allow| around
around --> toolBody
pre -->|deny or ask| denied
denied --> post
toolBody --> fsGate
fsGate --> toolBody
toolBody --> owned
toolBody --> around
around --> post
post --> context
post --> toolResult
toolResult --> presentResult
```
Filesystem read-before-edit checks live below `tool-fs` on the `fs/*` event gate; hook bridges and future permission prompts live on the generic pre/post tool waterfalls; and around-dispatch concerns like the tool-call timeout policy (`@deepseek-ai/dsh-timeout-policy`) wrap core dispatch on `tools/execute`. That split lets the same hooks observe bash, fs, web, todo, and subagent calls without coupling those tools to one policy service.
Maintenance mode: curated Mermaid flow; exact tool schemas and event signatures live in generated catalogs.