跳到正文
dsh-market 浏览插件 GitHub EN

apex-mochen/dsh-sandbox-arg-guard

让「同级或更窄的 sandbox_permissions」不再让工具调用直接失败。会升级的工具(pwsh、bash、write、edit)都广告完整的 sandbox_permissions 枚举,但 DSH 只接受严格更宽于当前生效级别的请求——其源码自称这是「deliberately not a schema constraint」。于是反射式带上该参数的模型往往填它已经在的那个级别,调用在执行前就死掉:"sandbox escalation to \"workspace-write\" is not strictly wider than this call's current \"workspace-write\" mode",某些模型还会为此烧掉一整轮重试。本插件只注册一个 tools/execute waterfall 监听器,且仅在那一条文档化拒绝上、且参数里确实带了升级字段时,把同一个调用去掉该参数重投一次。安全性由 DSH 自己的文档保证:拒绝发生在任何执行之前("nothing has run"),且改过的参数无法再次匹配,因此重投在结构上不成环。已端到端复现并验证——改造前 isError 为 true 且命令从未执行;改造后拿到命令的真实输出、isError 为 false,会话里只有一个 tool/call 与一个 tool/result。零依赖。

Star 数 ★ 0 分类 安全与权限 收录于 2026-09-18

安装

在 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

内容来自项目 README(GitHub)↗

评论

评论存放在 GitHub Discussions。用 GitHub 账号登录后可发表评论或点表情。