Where to put spend guardrails in DeepSeek Harness
Published 16 August 2026
An agent that discovers its budget from the monthly invoice does not have a budget. It has a postmortem. The useful question about any harness is where you can stand in the loop and say no, and DeepSeek Harness answers that with two named waterfall extension points.
First, the shape of the loop
The harness uses a turn and step model. A step is one model request plus the tool calls it produces. A turn contains zero or more steps. The flow for a turn runs roughly: input claim, prompt assembly, agent/pre-step, LLM stream, tool execution, step completion, then turn closure.
Two event streams run alongside each other. session/event carries durable replay facts — chunks, messages, tool calls, results. agent/* carries live coordination signals — status, inbox, request interception. Guardrails belong in the second; accounting belongs in the first.
Interception point 1: agent/pre-step
This is the checkpoint before the model request goes out. The docs state that the returned agent/pre-step decision is authoritative, and that listeners wrapping next() preserve downstream messages unless replacement is intentional. That is the property that makes it usable as a budget gate: a listener can reject a proposed step, or modify it, and the decision stands.
What belongs here:
- Per-turn step caps. The runaway-agent failure mode is a turn that never converges. A hard step ceiling turns an unbounded bill into a bounded one.
- Cumulative token budgets. Sum usage from the session log so far; refuse the next step past the threshold.
- Model downshifting. Rewrite the step to a cheaper route once a turn has burned past a soft threshold, rather than refusing outright.
- Context-size limits. Prompt assembly happens before this hook, so the assembled request is visible and measurable at this point.
Interception point 2: tools/pre-execute
Tool execution is a three-phase pipeline. The tools/pre-execute waterfall runs first, monotonic guards run next, and only then does the tool body execute — sandboxed, with filesystem gatekeeping. Afterwards a post-execute waterfall can accept, block, replace, or add context to the result, and ToolDefinition.finalizeContent enforces content invariants synchronously.
The permission layer is deliberately asymmetric. Registered monotonic guards deny or abstain, with identity protected — they never grant. If a guard denies, or if ctx.approval's one-shot prompt is absent or unanswerable, the result is denial and the tool body is skipped. Failure closed, not open.
Filesystem mutations are separately gated: only fs/write-intent or fs/edit-intent tool-fs mutations pass. Writes are not an incidental side effect of a tool running.
What the pipeline records
Three session events give you the audit trail: tool/call before execution, tool/code-dispatch for sub-calls, and tool/result as the final authoritative outcome. Sub-calls being separately recorded matters — a single model-visible tool call that fans out internally does not hide its fan-out.
A practical guardrail set
| Control | Hook | Stops |
|---|---|---|
| Max steps per turn | agent/pre-step | Non-converging loops |
| Cumulative token ceiling | agent/pre-step | Slow-burn overspend |
| Route downshift past threshold | agent/pre-step | Frontier pricing on cheap work |
| Tool allow-list by cost class | Monotonic guard | Expensive tools in cheap contexts |
| Subprocess and network denial | ctx.sandbox policy | Unmetered egress |
| Write-intent gating | ctx.fs seam | Unreviewed mutations |
The caveat
DeepSeek Harness is in developer preview and its own README warns of compatibility-breaking changes. These hook names and semantics are the ones documented today; treat guardrail plugins built against them as code you will revisit, and pin the version you built against.
Related
- The DeepSeek Harness session log as a cost record — the data the guardrails read.
- DeepSeek Harness: what "everything is a plugin" buys you — why guards are plugins too.
- Agent spend guardrails — the provider-agnostic version.
- The true cost of coding agents — what runaway loops actually cost.
Want this applied to your own LLM spend? FinOps LLM runs a free audit of your AI costs and shows where the savings are. Book free audit →
FAQ
Where can you enforce spend policy in DeepSeek Harness?
Two waterfall extension points. agent/pre-step runs before a model request is issued and its returned decision is authoritative. tools/pre-execute runs before any tool body executes, ahead of the monotonic permission guards.
What is a waterfall hook in DeepSeek Harness?
A waterfall is an ordered chain of listeners where each must call next() to delegate downstream. Listeners that wrap next() preserve downstream messages unless replacement is intentional, so a guard can inspect, modify, or short-circuit a step.
What is a monotonic guard?
A monotonic guard evaluates tool permissions without modifying them: it can deny or abstain but never grant. Guards run after the tools/pre-execute waterfall, and if a guard denies or approval is unanswerable the tool body is skipped.