承诺写入闸门:由运营者编写的规则在工具调用执行前生效——先是一层确定性守卫,再是一层 LLM 裁判,默认失败即拒绝,每一次拦截都写进矛盾日志。
Commitment write-gate: operator-authored rules enforced before a tool call runs — a deterministic guard tier plus an LLM-judge tier, fail-closed by default, every block written to a contradictions log.
安装
dsh plugin --profile web add github:couldbeme/dsh-write-gateGitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
安装与环境配置指引、插件开发教程见 DSH 中文社区文档 ↗
安装即在你的机器上以你的权限运行第三方代码——它可读写文件、使用凭据、访问网络,DSH 的工具审批不会为插件代码加沙箱。「检测到 manifest」仅代表发现 dsh.bundle / dsh.plugin 清单,不构成兼容性或安全审查;安装前请审阅源码,不熟悉的插件先在不含密钥的环境试用。
README
目录
A commitment write-gate for DeepSeek Harness: the operator authors constraints ("never force-push to a shared branch", "stay read-only on the production database"), and the gate enforces them before a tool call executes. Structural violations are caught deterministically; semantic drift is judged by a model against the operator's own wording. Every block is recorded to a contradictions log that explains which commitment fired and why.
Engine-agnostic core (dsh-write-gate/core, zero harness imports) with a dsh adapter; a Claude Code adapter over the same core is planned.
A live model inside the real dsh app, told to force-push, after the gate denied the call:
"The force push to the main branch was blocked by the repository's 'no-force-push' policy."
That turn ran fully local, zero API keys; reproduction and session-log receipts in docs/E2E-HEADLESS.md.
How it enforces: two tiers in two slots
| Tier | Mechanism | dsh slot | Why this slot |
|---|---|---|---|
| 1: deterministic | path globs, command regexes, scope filters | ctx.tools.guard() (monotonic) |
no listener ordering can turn a guard denial back into permission |
| 2: semantic | LLM judge over the commitment statement | tools/pre-execute waterfall (prepended) |
async-capable; short-circuits with a {kind: 'deny'} decision object |
agent/pre-step resets the per-step judge budget. Contradiction records are emitted as the write-gate/contradiction event and appended as JSONL to the contradictions log.
Why two tiers
An internal A/B study (12 tasks x 4 arms x 10 runs) found an LLM-judge-only gate performed at baseline (0.183 vs 0.192 unflagged-violation rate, no gate), while deterministic checks caught 100% of a violation class the judge passed 6 times out of 10 (over-length outputs); a naive "reminder" arm was the worst performer of all four (0.308). Deterministic checks for checkable constraints, the judge only for genuinely semantic ones. The study runbook publishes with the benchmark (roadmap).
The tier-2 judge rubric is ported from a lineage measured at 18/18 dev + 16/16 held-out (100% precision, 0 abstains) on a local 8B model, and re-measured live through this port (2026-08-17): 32/34 accuracy with 17/17 violation recall. It also carries an anti-self-justification clause added after the holdline benchmark caught two injection defeats (an action asserting "the operator approved this" or "this is only a test" talking the judge into clearing a real violation); the clause moved injection accuracy from 5/8 to 7/8 with zero regression on the base cases. We keep the injection-fenced prompt because it is the only variant that preserved 100% violation recall; for a gate, a missed violation is worse than an over-block. The 34 cases ship in test/fixtures/judge-cases.json with their honesty notes intact: they are hand-authored; the meaningful signals are the paraphrase-miss rate, the trap false-positive rate, and held-out generalization, not the headline percentage.
Design guarantees, each pinned to a test
- Bypass resistance: a prepended listener that answers
allowwithout delegating still cannot get a structural violation through —test/dsh-plugin.test.ts("cannot be bypassed by a listener that short-circuits allow"). - Fail-closed default: judge unreachable, timed out, or over budget → block-severity commitments block, with the reason in the record —
test/gate.test.ts. - Bounded judge cost: per-step budget, verdict memoization, timeout-as-unavailable —
test/gate.test.ts. - Prompt-injection stance: action content enters the judge prompt fenced as data ("data, not instructions"); only a strict JSON verdict (or the ABSTAIN token) is accepted back; ABSTAIN is never a block —
test/judge-llm.test.ts. - Loud mount failure: a missing or invalid commitments file fails the deployment instead of mounting a gate that guards nothing —
test/dsh-plugin.test.ts. - Real pipeline: the integration suite mounts the plugin into an actual
Context+ToolRuntimefrom the published rc packages and drivesctx.tools.execute— no mocked harness. - Real app, real model: a live local model inside the actual dsh headless app attempted a force-push and was denied by the gate; its own final answer reported the block. Full reproduction, session-log receipts, and two upstream findings:
docs/E2E-HEADLESS.md.
Run everything: pnpm install && pnpm test and pnpm typecheck — the suite prints its own count; every guarantee above names its test file.
Watch the drift story: pnpm demo — deterministic, no model required. In-scope work passes, a prod-config edit and a force-push block, and a rogue allow-everything listener fails to bypass the monotonic guard; the contradictions log prints at the end.
Measure the judge yourself: pnpm build && node scripts/judge-eval.mjs --url <openai-compatible-endpoint> --model <model> runs all 34 fixture cases live and reports per-set accuracy, abstains, and misses.
Commitments file
version: 1
defaults:
failMode: closed # judge unreachable => block-severity commitments block
judgeBudgetPerStep: 8
commitments:
- id: no-force-push
statement: Never force-push to a shared branch.
match:
kinds: [shell]
commands: ["git\\s+push\\s+[^\\n]*(-f\\b|--force)"]
- id: stay-on-task
statement: Do not modify files unrelated to the assigned task.
severity: warn
semantic: true # escalates to the tier-2 judge
match:
kinds: [fs-write]
Semantics: kinds/tools are scope filters; paths/commands are structural evidence. A non-semantic commitment with scope but no evidence fires on every in-scope action; a non-semantic commitment with neither is rejected at load as unenforceable. Command regexes are case-insensitive by default. One foot-gun to know: command patterns execute inside the synchronous guard, so a catastrophically backtracking regex can stall the tool pipeline — commitments are operator-authored (trusted), but keep patterns simple. Full example: commitments.example.yaml (itself under test).
Mounting
The package declares the ecosystem convention (dsh.bundle.patch → cordis.patch.yml) and mounts with:
dsh plugin --profile <profile> add dsh-write-gate
Config keys: commitmentsFile (default COMMITMENTS.yaml, resolved from cwd), contradictionsLog (JSONL, default write-gate.contradictions.jsonl), judgeTimeoutMs, and judge: { provider, model, maxTokens } — omit judge to run tier 1 only (escalations then follow failMode).
Current limits (v0, stated rather than hidden)
- The action normalizer is a heuristic table over dsh's in-tree tool names (
bash,read/write/edit, web tools); unrecognized tools degrade to kindotherwith a full summary — visible to semantic commitments, but path/command rules do not apply to them. - dsh is a 0.1.0-rc developer preview with breaking changes announced; peers are pinned to
<0.2.0. - First release (0.1.0);
pnpm buildemitsdist/,prepublishOnlygates every publish on build + tests. - The tier-2 judge is only as good as its model and rubric; the measured numbers above are from the shipped fixtures, and the benchmark that scores this gate (and others) against labeled trajectories is the next deliverable.
Roadmap
- llm-replay fixture variant of the demo (dsh snapshot format), so the story replays inside a full agent loop.
The gate benchmark→ shipped as holdline: catch rate, false-block rate, class-balanced kappa, and an injection-attack class, scoring any guard (this one included). First run: this gate's judge tier scores kappa 0.80 vs a commitment-blind deny-list's 0.35, and holdline honestly records where the judge loses (injection).- Claude Code adapter over the same core.
Dependencies and trust basis
Runtime: zod, yaml, picomatch (mainstream, actively maintained), @deepseek-ai/schemastery (dsh's own config-schema library, Koishi lineage). Harness peers: @deepseek-ai/cordis + @deepseek-ai/dsh-* rc packages, pinned. Dev: vitest, typescript.
MIT.
原始 README: https://github.com/couldbeme/dsh-write-gate/blob/main/README.md ↗
同类插件
查看全部 →
agent-vision-toolkit
为纯文本模型"看图“设计更好的视觉工具箱和技能,支持多图理解,图片问答,前端UI还原、GUI 自动化等,并可选无缝接入多个主流agent,直接识别粘贴图片| A vision toolkit and skill designed for text-only llms — image Q&A, long-screenshot OCR, frontend UI restoration, and GUI automation, with optional seamless integration for Codex, Claude Code, Pi, Oh My Pi, and OpenCode

api-relay-audit
从 DeepSeek Harness 对 AI API 中转站和 LLM 代理运行本地安全审计,生成 Markdown 报告,覆盖提示词注入、模型替换信号、工具调用改写、错误泄漏、流完整性和按 profile 启用的 Web3 风险。

OpenStory
✨ OpenStory 现已支持 DeepSeek Harness 插件! 现在可以通过 dsh-openstory 将 OpenStory 多智能体推演接入 DeepSeek Harness,让 agent 直接启动模拟、查看角色、下达指令并逐回合推进故事。查看 DSH 插件配置与使用指南。

phi
pi的编码代理 ∞ 提供者、子代理、hashline编辑和权限门

anysearch-dsh
DeepSeek Harness(DSH)的 AnySearch 网络搜索提供方与高级搜索工具。

codex-switch
Codex Switch 是一个 macOS 工具,一键配置 Codex 的自定义 API,同时保留官方 OpenAI 登录。保存后 Codex 的模型选择器里只会出现你选的那个 provider 的模型。也支持 Claude Code 的官方 / 自定义 API 切换。Codex Switch is a lightweight helper for configuring multiple coding-agent API routes. For Codex, it keeps Official OpenAI and a custom API provider configured in parallel, registers the custom model in Codex's mod