安装
在 DeepSeek Harness 里通过 dsh-market 安装
dsh plugin --profile web add dshmarket
或使用命令行
dsh plugin --profile web add github:apex-mochen/dsh-sandbox-arg-guard
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络。请先审阅源码,并尽量锁定 commit(github:owner/repo#sha)。
README
让「同级或更窄的 sandbox_permissions」不再让工具调用直接失败。
会升级的工具(pwsh、bash、write、edit)都广告完整的 sandbox_permissions 枚举,但 DSH 只
接受严格更宽于当前生效级别的请求。模型反射式地带上这个参数时,往往会填它已经在的那个级别,
于是调用在执行前就被拒。本插件在这一条拒绝上把同一个调用去掉该参数重投一次,让模型本来想做
的事真的发生。
⚠️ 上游修复已收窄本插件的适用范围(2026-09-19)
「同级」这一半在 DSH
0.1.6-alpha.2已被修复,不再需要本插件。 提交61c548e2(fix(sandbox): accept repeated effective permission modes,PR #4326)在packages/sandbox/sandbox/src/escalation.ts:155加了if (mode === effectiveMode) return effectiveMode——我在master上亲自核实过。重复当前生效级别现在被静默接受。剩下的是:更窄或不受支持的目标仍然抛错(
:159-160,同样的文案)。本插件覆盖的正是这一半: 去掉那个参数后,模型本来想做的调用照样执行。重投的安全性依据不变——抛错依然发生在任何执行之前。下面各节记录的是 0.1.2-rc.1 上的原始复现(含同级的 A/B),我把它保留为那个版本的准确记录, 而不是改写成像是现状。更新说明与已核实的上游代码见 EVIDENCE.md。 更窄目标这一半尚未在
0.1.6-alpha.2上重测。
它防的是什么
packages/sandbox/sandbox/src/escalation.ts:159-164:
// Strict widening is an EXECUTION check against the call's effective mode —
// deliberately not a schema constraint (the enum is the closed target
// vocabulary; the effective mode is per-call truth).
if (!(WIDER_MODES[effectiveMode] ?? []).includes(mode as SandboxMode)) {
throw new Error(`sandbox escalation to "${mode}" is not strictly wider than this call's current "${effectiveMode}" mode`)
}
所以schema 没法告诉模型"对这一次调用来说哪些值合法"——枚举是封闭的目标词表,而生效级别是每次 调用的事实。模型填错一个字段,换来的是:
Error: sandbox escalation to "workspace-write" is not strictly wider than this call's current "workspace-write" mode
什么都不会执行。这是社区核实清单 discussion #6520 的第 1 条,也是那份清单里报障最多的一条:8 个直接相关讨论,外加 3 个同族。
它做什么
只注册一个 tools/execute waterfall 监听器,next() 只调一次并原样返回它的结果。仅当结果正是
那一条文档化拒绝、且参数里确实带了升级字段时,才把同一个调用去掉 sandbox_permissions 与
justification 重投一次。
为什么重投是安全的——escalation.ts:143-152 写明了顺序:
Resolve a sandbox-escalation request BEFORE anything executes … the tool registry turns the throw into the call's isError result, and nothing has run. A non-widening request never prompts a human.
拒绝发生在任何工作之前,所以"去掉那个多余字段后重投"不可能重复产生副作用。重投也在结构上不可能 成环:改过的参数里已经没有升级字段,无法再次匹配这条拒绝。
为什么只能用这条缝:tools/pre-execute 与 agent/pre-step 都是返回决策(allow/ask/deny)
的 waterfall,不能改写参数;只有 tools/execute 的返回值就是执行结果,且 ToolRuntime.execute(input)
是公开方法、入参可自行构造,因此监听器可以重投一个修正过的调用。
已验证
同一份桩、同一个工具调用,BEFORE / AFTER 取自真实落盘会话,原始输出见 EVIDENCE.md:
| 无插件 | 装插件 | |
|---|---|---|
tool/result |
Error: sandbox escalation to "workspace-write" is not strictly wider … |
PROBE-EXECUTED |
isError |
true |
false |
| 命令是否真的跑了 | 没有 | 跑了 |
两种情况下的会话里都只有一个 tool/call 和一个 tool/result:重投没有变成第二次可见调用,
命令也没有被执行两次。
安装
dsh plugin --profile web add github:apex-mochen/dsh-sandbox-arg-guard
装完重启该 profile。
配置
- id: dsh-sandbox-arg-guard
config:
verbose: false # 每次修复都打日志
enabled: true # 设 false 可保留安装但停用
它刻意不做的
- 只管这一条拒绝。审批被拒、真实的权限失败、工具自身的错误一律原样放行(
test/smoke.mjs有断言)。 - 绝不重投两次。第二次重投在结构上不可达,并有断言守住。
- 失败即放行。修正后的调用如果根本发不出去,用户看到的是 DSH 原本那条准确的错误。
- 零依赖。单文件、只用 Node 内置能力,不启动进程、不读写文件、不发网络请求。
这是权宜之计,不是 core 修复
治本在 DSH 侧:要么让广告出去的枚举相对于生效级别,要么把"更窄的请求"当作无事发生而不是报错。
源码注释显示现在的形态是刻意设计,所以本插件只在用户可见行为上补住这个缺口,不改动 core。
DSH 目前不接受外部 PR(CONTRIBUTING.md),插件是够得着的那条缝。
兼容性
- DSH
0.1.x(peer:@deepseek-ai/cordis ^4.0.1) - Node.js 20+
- 只注册一个 waterfall 监听器(
tools/execute),不贡献任何工具
许可
MIT
评论
评论存放在 GitHub Discussions。用 GitHub 账号登录后可发表评论或点表情。