Agent discipline guard for DeepSeek Harness: four gates enforced at the harness boundary — loop circuit-breaker, token-cost fuse, route-switch warning, plan approval — where prompt-level reminders can't reach, so an agent can no longer burn a weekly quota in minutes; one-click 🛡 chip, hot-reloadable thresholds, and presets from invisible-but-armored to warn-only.
Install
# from a prebuilt release tarball
dsh plugin --profile web add "https://github.com/haozheou/dsh-discipline-guard/releases/download/v1.0.0/dsh-discipline-guard-1.0.0.tgz"
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:haozheou/dsh-discipline-guard
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Your agent burned through a weekly token quota in 3 minutes — while politely telling you it was "almost done". This plugin stops it at the harness boundary, where text-based reminders can't reach.
Prompt-level "please don't repeat yourself" reminders are advisory: a determined (or confused) model walks straight through them. dsh-discipline-guard is not a prompt. It hooks the harness waterfall (tools/pre-execute, agent/pre-step, session/event) and refuses dispatches, blocks turns, and pops native approval cards — the model cannot argue with the tool pipeline never running.
The four gates
| # | Gate | Default | What it does |
|---|---|---|---|
| ① | Loop breaker | on | Counts identical tool+arguments calls per agent. 2nd repetition → visible warning injected; 4th → the call is denied before dispatch (2 consecutive failures trips it even faster). Any new user message releases it. |
| ② | Cost fuse | on, fail-closed | Meters every step from real usage data (input tokens net of cache, cache-hit rate, per-turn cumulative). Typical token-plan pattern — huge full-price resend with ~0% cache hits — gets a warning first; a repeat violation in the same turn hard-stops the turn. Reply 继续/放行/别停/照常 (or continue) to release one turn. |
| ③ | Route watcher | on | When the session switches model endpoints with a long history, injects a one-time warning: the new endpoint may re-bill your whole context at full price. |
| ④ | Plan gate | off | Opt-in: the first write/execute tool call of each user turn routes through the native approval card. One approval covers the turn. |
Every gate is individually switchable with its own thresholds, and every listener is fail-open internally: a bug in the guard can never brick the harness it protects. Money-class gates are fail-closed by design: they stop and wait for you.
Control surfaces
- Main UI: a 🛡 chip in the session header — one click arms/disarms everything (the escape hatch must never be buried).
- Settings → Discipline Guard(纪律卫士): per-gate switches, thresholds, and three presets:
off— everything disableddaily(default) — tuned for cached routes (deepseek-style: 1–5K net input/step will never trip it) while capping an uncached runaway at ~500K tokens/turn instead of millionswild— warns but never interrupts; for experimental heavy work
- Settings namespace
discipline-guardin~/.dsh/settings.yaml, hot-reloaded — no restart needed after the first install.
Typical release flow (the guard never decides for you)
gate trips → you look → worth it? → reply 「继续」 → the rest of the turn runs free
not worth it? → you stopped a fire in one turn
One nuance on purpose: replying anything resets the loop breaker; the release words only waive the current turn. The next turn starts a fresh ledger — the guard never accumulates grudges, and never quietly forgets.
Install
Requires DSH with the web profile (client UI is web-only for now; the host gates work everywhere).
A. Via plugin market (once listed)
Open DSH → Plugins market → search "discipline guard" → install.
B. Manual install
Add the plugin to your profile (~/.dsh/profiles/<profile>/package.json):
{
"dependencies": {
"dsh-discipline-guard": "github:haozheou/dsh-discipline-guard"
},
"dsh": {
"profile": {
"bundles": [
// ... your existing bundles ...
"dsh-discipline-guard" // ← add this line
]
}
}
}
Then pnpm install in the profile directory and restart DSH. The bundle's own cordis.patch.yml mounts the plugin row automatically.
Thresholds: how to tune
Measured baselines (per step, net-billable input):
- cached route (deepseek-style): 1–5K tokens, ~97% cache hits → daily defaults never fire
- uncached "token plan" route: the entire context re-billed every step → that is what ② exists to cap
| If your workload… | adjust |
|---|---|
| gets stopped while doing legitimate long work | raise costTurnBudget (500K → 800K+) |
| runs on a route where caching is broken | that is exactly the pattern ② exists to cap — check the context size, not the thresholds |
| polls tools on purpose (job waiting etc.) | add them to loopExclude |
The incident replay test: 16 steps × 360K full-price resend = 5.74M tokens in 3 minutes → with daily defaults, execution stops at ~550K (≈90% saved), mid-run, with a visible reason.
One switch: "cached" vs "no-cache" route
The cost fuse normally infers an uncached full-price resend from the measured cache-hit rate (auto). If you know which endpoint you're on, you can tell the guard directly and it evaluates more precisely, without guessing from numbers:
cached(has cache) — e.g. deepseek official with prompt caching. The fuse no longer flags a single low cache-hit step (cold-start / brand-new long topic can also hit low), keeping only the per-turn budget hard cap. This is the "never fires" daily baseline.nocache(no cache) — e.g. token-plan / "套餐" endpoints that re-bill the whole context each step. The fuse gets strict: any step with net input ≥costRequestInputMaxand context ≥costContextMincounts as a full-price resend, with no cache-hit-rate precondition.auto(default) — keep the original inference based on cache-hit rate.
Find it under Settings → Discipline Guard → ② Cost fuse → 当前路由缓存判定 (three-way toggle). Hot-reloaded, no restart.
Caution: labeling a truly
nocacheroute ascachedremoves the full-price-resend guard (only the turn budget remains as a backstop). Mark routes truthfully.
Known limitations
- Client UI (chip + settings page) targets the web profile; desktop profile gets host gates only (config via
settings.yamldirectly). - Cost metering is per-turn/per-session; parallel sub-agents' usage is metered per agent, session aggregate in v2.
- Coexists with the built-in
repeat-tool-reminder(advisory at 3/5/8 repetitions). If the double notices annoy you, disable the built-in one.
Credits
- Loop-chain canonicalization pattern borrowed (in spirit) from DSH's built-in
repeat-tool-reminder. - Built on Cordis / DeepSeek Harness plugin APIs:
tools/pre-execute,tools/post-execute,agent/pre-step,session/event,approval,dsh-settings.
MIT © haozheou
中文文档见 README.zh.md。
Links
More in this category
bowenliang123/dsh-context★ 2079
DSH context insight panel: Context dashboard + /context command + Context browser — one-stop context lifecycle management with categorized composition, content details, evolution trends, compaction/injection events, and stats.
Han-1413141/dsh-cost-meter★ 408
Per-session and daily API cost, budget with usage %, official balance, history dashboard, and one-click official price sync with peak/off-peak pricing.
wssfk12138/dsh-damage-pulse★ 263
Tracks DeepSeek token usage, per-call and session costs, and account balance with cache-aware charge animations in the DSH Web UI.
zh667/TokenLedger★ 202
Sidebar usage panel that attributes tokens to the relay site that served each request, read from your existing provider config: today/month/all-time totals, per-site and per-model breakdowns, a year activity heatmap, and New API / Sub2API / DeepSeek balances.
Ychris12138/dsh-usage-stats★ 172
Multi-provider usage dashboard with provider/model token breakdowns, calendar drill-downs, account balances, and OpenCode Go / Z.ai subscription quota tracking.
PolinniZhong/dsh-personal-center★ 118
Personal center for DeepSeek Harness: cross-session usage statistics, per-model cost estimation, global custom instructions, a global font-size adjuster, a data-driven desktop pet with bitmap & vector skins, and a conversation status overview, all local and offline.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.