DeepSeek Harness Hub
← 返回列表

沙箱误杀修复补丁XyTT2N2bTc/dsh-sandbox-nonwidening-fix

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
未验证

修复全权限下工具调用被沙箱判定误杀的问题

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/27 · 已提供中文文档

修复 DeepSeek Harness 在模型于完全访问权限下附加冗余的 sandbox_permissions 时终止工具调用的问题(沙箱提权并非严格更宽)。提供源码补丁 + 故障安全式 node_modules 热修复。参考 deepseek-ai/deepseek-harness 讨论 468。

综合分
28.7
GitHub 分
28.7
用户评分
★ Stars
1
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add XyTT2N2bTc/dsh-sandbox-nonwidening-fix
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

dsh-sandbox-nonwidening-fix

修复 DeepSeek Harness 在模型冗余携带 sandbox_permissions 时误杀整个 tool call 的问题,报错原文:
sandbox escalation to "workspace-write" is not strictly wider than this call's current "danger-full-access" mode
对应上游讨论:deepseek-ai/deepseek-harness#468(最初现象报告:#340)。截至本仓库发布,上游尚无官方修复。

English README: README.md

你是否需要它?

如果你的 DSH 会话中,本应成功的工具调用反复出现以下任一错误:

Error: sandbox escalation to "workspace-write" is not strictly wider than this call's current "danger-full-access" mode
Error: invalid justification: expected a non-empty sentence

且符合以下任意一条,这个仓库就是为你准备的:

| 典型场景 | 是否命中 |
| --- | --- |
| 会话已是 Full access(danger-full-access),工具却仍报"权限"错误 | ✅ 经典案例 |
| 模型经 OpenAI 兼容 provider 接入,习惯性在工具调用里携带 sandbox_permissions(常带 justification) | ✅ 已知触发条件 |
| 实测出现该问题的模型:GPT-5.6-Luna(本仓库作者本地实测确认)、GPT-5.6 Terra 等(#468 评论) | ✅ |
| 已经试过用系统提示 / AGENTS.md 规则禁止模型发送这些参数,但无效 | ✅ prompt 层面无法缓解——参数附加发生在模型的 tool-call 参数生成阶段,不受指令约束 |
| 怀疑是 API 中转(代理)导致 | ❌ 已排除——本地直连与中转环境产生完全相同的报错;问题 = 模型行为 × harness 判定逻辑,与请求链路无关 |

每次被拦截都是一次浪费的往返;模型还常常因此放弃重试、或向你报告"Full access 没生效"。下面的修复只消除这种误杀,不放松任何真实的权限边界。

根因(30 秒版)

1. @deepseek-ai/dsh-sandbox 用"严格更宽阶梯"(WIDER_MODES)判定每一次 sandbox_permissions 请求;danger-full-access 没有更宽的目标,于是 Full access 下任何请求——哪怕是冗余的——都会抛错。
2. 工具 schema 无论会话当前模式如何都全局广告升级字段,模型因此持续产出这些参数。
3. GPT 系等模型几乎在每个受限调用上都防御性携带这对参数,有时 justification 还是空串,触发第二条校验错误。

带源码行号的完整分析见 discussion #468。

修复语义

非扩大请求(目标 ≤ 当前模式)从「致命错误」改为「幂等放行」:

| 请求模式 vs 当前模式 | 修复前 | 修复后 |
| --- | --- | --- |
| 真扩大(如 read-only → workspace-write) | 弹审批后按新宽模式执行 | 不变 |
| 与当前相同(如 full access → full access) | ❌ 整个调用被拦截 | ✅ 按当前模式直接执行,不弹审批 |
| 低于当前 | ❌ 整个调用被拦截 | ✅ 直接执行,绝不降权 |
| 无法识别的字符串(如 "sudo-mode") | 报错拒绝 | 仍然 fail-closed,且错误文案列出合法模式 |
| 未挂沙箱的组合却带了字段 | 报错(not available in this composition) | 保持不变(有意的 fail-closed) |

四条保证:

* 非扩大请求永不弹审批;
* 永不把调用降到当前模式以下;
* 永不绕过审批获得更宽权限——真扩大仍走既有用户审批通道;
* 无法识别的目标保持 fail-closed。

开发期已用代码执行过完整行为矩阵:相等→当前模式、full access 下更低请求→不降权、真扩大→正常授予、未知模式→仍拒绝。

快速开始

方式 A — 源码 patch(推荐:以源码 checkout 运行 DSH 的用户)

git clone https://github.com/XyTT2N2bTc/dsh-sandbox-nonwidening-fix.git
cd /path/to/deepseek-harness        # 你的 DSH 源码目录
git apply --check /path/to/dsh-sandbox-nonwidening-fix/patches/0001-.patch \
&& git apply /path/to/dsh-sandbox-nonwidening-fix/patches/0001-.patch

或使用辅助脚本(base 变动时自动退避到三方合并):

sh /path/to/dsh-sandbox-nonwidening-fix/scripts/apply-patch.sh /path/to/deepseek-harness
Windows:
pwsh -File /path/to/dsh-sandbox-nonwidening-fix/scripts/apply-patch.ps1 -Repo /path/to/deepseek-harness

patch 只触及 packages/sandbox/sandbox、packages/shell/tool-bash、packages/shell/tool-pwsh、packages/fs/tool-fs(源码 + 测试)。基线提交:b150a551b8(release/dsh-0.1.1-rc.2);更新的 base 可由 git apply -3 处理。

方式 A 还能一并消除空 justification 报错(invalid justification: expected a non-empty sentence)——配对校验在各工具包内被移到了幂等短路之后。

方式 B — 已安装发行版热修(无需源码)

原地修补唯一一个已安装文件:@deepseek-ai/dsh-sandbox/lib/index.js。零依赖(Node ≥ 18):

node scripts/hotfix-node-modules.mjs                            # 自动发现安装位置
node scripts/hotfix-node-modules.mjs ~/dsh/runner/node_modules   # 也支持显式路径

脚本是 fail-safe 的:锚点文本不是恰好出现一次就拒绝写入;写前自动备份(index.js.bak-dsh-nonwidening-fix.);重复运行是 no-op;随时还原:

node scripts/hotfix-node-modules.mjs --restore

之后重启运行中的 DSH 会话/服务,让补丁模块重新加载。

范围说明:方式 B 单独只消除 not strictly wider 拦截;空 justification 的配对报错位于工具包层,需方式 A 才能消除。

兼容性

* accpowered/dsh-auto-review 的 core-patch 0001:功能正交(它为 LLM 自动审批增加内存态 action 字段);文本上两者都改 escalation.ts,叠加时可能需要 -3 合并。热修路线与它完全兼容。
* xiaohj233/dsh-compat-shims(sandbox-schema-shim):互补的 schema 层方案(Full access 下对模型隐藏这两个字段)。可以共存;本修复额外兜底了"参数已经发出来"的调用。
* #468 评论中的一行式热改(如 if (effectiveMode === 'danger-full-access') return …)只覆盖单一组合;本修复覆盖所有非扩大组合、绝不降权、未知模式仍 fail-closed。

测试情况

* 源码 patch:deepseek-harness @ b150a551b8(0.1.1-rc.2)——oxlint 0 错误、host tsc -b 通过、vitest 151/151 通过(dsh-sandbox、dsh-tool-fs、dsh-tool-pwsh;更新过的测试覆盖幂等、永不降权、未知目标 fail-closed、空 justification 等场景)。
* 热修:针对 npm 发布产物 @deepseek-ai/dsh-sandbox@0.0.1-rc.1 做过端到端验证——dry-run / 打补丁 / 幂等重跑 / 还原 / 语法检查 / 行为矩阵全部通过。
* 真实安装端到端已验证:GPT-5.6-Luna 经本地直连 OpenAI 兼容 provider,热修前精确复现报错调用(与 #468 报告一致),热修后同一模型的受限调用干净执行——并据此确认与中转无关。修复前的行为矩阵与修复后的真实模型运行共同覆盖两侧。

已知边界

* tool-bash 测试套件依赖真实 POSIX shell,上游配置在 Windows 上有意排除,故本地未跑(Linux CI 会覆盖);bash/pwsh 解析器互为镜像,pwsh 套件全绿。
* 上游未来若改变 bundle 形态,热修脚本会因锚点消失而拒绝写入,不会盲改。

FAQ

我已经开了 Full access,为什么还提示权限不足?
这不代表 Full access 失效。是模型附带了一个冗余的 sandbox_permissions,DSH 把这个无害参数当成了非法降级尝试并拦截。这正是 #468 记录的误读,也是本修复消除的对象。

能不能直接告诉模型别发这些参数?
#468 的报告与本仓库实测结论一致:prompt 规则和 AGENTS.md 不能可靠阻止,因为参数附加发生在 tool-call 参数生成阶段。修 harness 侧的拦截才是可靠路径。

这会不会削弱沙箱安全?
不会。真扩大仍需用户批准;除既有批准路径外,任何执行都不会高于当前策略;未知目标依旧 fail-closed。修复只是不再把「冗余」请求当成致命错误。

上游修了吗?
撰写本文时没有——#468 有复现与分析,但没有合并的变更。本仓库的 patch 结构便于 rebase / cherry-pick 回上游。

致谢

感谢 #468 的报告者与评论者(跨平台跨模型的复现证据、一行式洞察线索、schema-shim 与 auto-review 路线)——本仓库把分析沉淀为一个完整、经过测试、可独立使用的修复。

许可

MIT

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

同作者(XyTT2N2bTc)的其他插件

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群