dsh-governor
Behavioural supervision for DeepSeek Harness agents: retry storms, reasoning-budget burn, and a backstop that survives host suspend.
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 23, 2026
- Updated
- Aug 23, 2026
Introduction
dsh-governor
Behavioural supervision for DeepSeek Harness agents. It watches a running agent for the failure shapes that waste money quietly: retry storms, reasoning-budget burn, and sessions that outlive their backstop.
Status: phase 2. Observation is the default and still changes nothing. Enforcement is
opt-in via mode: 'enforce', because a supervisor that intervenes before you have seen its
findings on your own traffic is one you will not trust.
Why these three detectors
They are not guesses. Each one exists because a naive version of it failed against real traffic across five providers, and the fix is baked in here from the start.
Retry storms, by ratio rather than consecutive runs
Counting "three identical failures in a window" misreads a flaky provider as a stuck agent.
Four scattered 503s across twelve otherwise-productive steps is a vendor having a bad
afternoon, and pausing there costs the user a working session.
Requiring strict consecutiveness fails the other way: a storm that thinks between attempts is still a storm.
RetryStormDetector requires the repeated failure signature to occupy at least half the
window. Both shapes are covered, and the flaky-provider case is a permanent test.
Output tokens billed, no visible text
Reasoning models spend the completion budget on hidden thinking first. When the cap is consumed before any answer is emitted, the provider returns a truncation reason and an empty body. Measured across five providers, two returned zero characters while billing the full budget, at both a 16-token and a 200-token cap.
This is invisible to text-based supervision by construction. Repetition, oscillation and distress detectors all read the output text, and there is no text to read. Only token accounting sees it.
The harness makes this easier to catch than most runtimes do. llm/stream separates
text-delta from reasoning-delta and carries TokenUsage, so the detector can report
why the answer is empty rather than only that it is: "200 output tokens billed, no visible
text; the budget went to reasoning (72 chars of hidden thinking)".
A backstop that survives a closed laptop lid
performance.now() is monotonic, which is right for measuring work, but it stops advancing
while the host is suspended. A watchdog built on it alone silently never fires across a
sleep. Wall-clock sees suspended time but can jump backwards under NTP correction.
DualClock takes the larger of the two. Firing slightly early is a much better failure than
never firing.
This one was found the hard way: a 1813-second run sailed past an 1800-second backstop because step one happened on a laptop with the lid shut.
The ladder
Findings raise a score, clean steps decay it, and only the upper rungs touch the agent.
| rung | observe | enforce |
|---|---|---|
ok | nothing | nothing |
notice | logs at info | nothing |
pause | logs at warn | agent/pre-step returns reject; tool calls return ask |
stop | logs at warn | agent/pre-step returns reject; tool calls return deny |
The ask rung is the useful one. It hands the decision to a human instead of choosing
between letting a suspect run continue and killing it outright, and the harness supports it
natively through PreToolDecision.
Presets gentle, standard and paranoid move the thresholds. These numbers are
starting points, not measurements. Governor's were tuned against replayed sessions; these
have not been, and you should expect to adjust them for your own traffic. The backstop is weighted so
that it reaches stop immediately under every preset, since it is the floor that exists to
catch everything the other detectors miss, including bugs in the detectors.
Install
npm install dsh-governor
# cordis.yml
- name: 'dsh-governor'
config:
mode: 'observe' # 'enforce' to let the upper rungs intervene
preset: 'standard' # gentle | standard | paranoid
backstopMs: 1800000
A note on peer versions
The @deepseek-ai packages currently publish inconsistent latest dist-tags: at the time
of writing dsh-tools and dsh-llm resolve latest to 0.0.1-rc.1 while 0.1.1-rc.2 is
published, and that old version peers on an ancient dsh-agent. Pin the set explicitly:
npm i @deepseek-ai/cordis@4.0.1 @deepseek-ai/dsh-agent@0.1.1-rc.2 \
@deepseek-ai/dsh-llm@0.1.1-rc.2 @deepseek-ai/dsh-tools@0.1.1-rc.2
Development
npm run typecheck # tsc --strict, skipLibCheck off, against the real dsh declarations
npm test # node:test via tsx
Roadmap
Phase 2: the escalation ladder.Done.Phase 3: integration tests.Done: 7 of them drive a real CordisContext.- Next: publish, once the preset thresholds have been tuned against real sessions.
Provenance
The detectors are ported from Governor, part of the Sheepdog trilogy, where they were measured against five providers rather than designed against fixtures. The false-positive guard, the empty-output detector and the dual clock all exist because the obvious version was wrong in a way that only showed up on live traffic.
License
MIT