Tool execution is not a function call
From discovery and pre-policy through monotonic guards, around execution, post-policy, and an immutable final result
pre → guards → execute → post → finalize → resultWhy can a later plugin not re-allow a dangerous call already denied upstream?
A tool call crosses customs: declaration, admission, inspection, transport, arrival processing, and final receipt are separate authority points. No stage may undo a hard prohibition already in force.
Mechanism
tools/pre-execute may allow, deny, or ask; ask enters ctx.approval. Monotonic guards then deny or abstain with protected identity.
tools/execute wraps dispatch; post-execute may replace results. The registry normalizes JSON, ToolDefinition.finalizeContent enforces last content-only invariants, and tools/result observes the frozen outcome.
Log call first
UI and audit first see the model's raw arguments.
What extensions must preserve
- Every tool/call eventually maps to one authoritative tool/result
- A guard denial cannot be undone downstream
- tools/result observes the frozen final outcome
The tempting wrong turns
- ×Embedding permission logic inside one tool handler
- ×Mutating outcomes inside tools/result
- ×Letting policy exceptions bypass checks
Do not trust the conclusion—verify it
These anchors are pinned to official deepseek-harness@47f9438; account for later breaking changes when reading current upstream.
Pause for ten seconds before revealing
How do tools/post-execute and ToolDefinition.finalizeContent differ?
The pipeline defines control points. Next we place approval and permission presets into them.