Back to home@JoaquinDG

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.

rungobserveenforce
oknothingnothing
noticelogs at infonothing
pauselogs at warnagent/pre-step returns reject; tool calls return ask
stoplogs at warnagent/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 Cordis Context.
  • 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