← 返回列表
未验证
一个 DeepSeek Harness 捆绑包,它会拒绝那些按映像名称、通配符、进程组或未经过滤的枚举来终止进程的…
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/25 · 已提供中文文档
DeepSeek Harness 插件,拒绝执行按映像名称、通配符、进程组或未经过滤的枚举来终止进程的 shell 命令——即关闭 DSH GUI 窗口的清理操作。
综合分
30.7
GitHub 分
30.7
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add CetOeil/dsh-process-guard该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
信任档位:已验证本站已于 0 天前真实安装成功(L4 · 真实安装)
- 是什么
- dsh 原生插件 · vision
- 装得上吗
- 本站已真实安装成功(L4 · 真实安装,非静态推断)
- 安全吗
- 本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
- 还在维护吗
- 活跃:最近一次提交在 0 天前
档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →
🟢实装验证通过· 2026/9/26
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/26(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
由 DeepSeek 最新模型翻译生成dsh-process-guard
一个 DeepSeek Harness 捆绑包,它会拒绝那些按映像名称、通配符、进程组或未经过滤的枚举来终止进程的 shell 命令——正是这种故障模式会在回合进行到一半时关闭 Harness GUI 窗口。
DSH Web GUI 是运行在 http://127.0.0.1:3080 上的浏览器客户端,而 harness 服务器是一个 node 进程。因此 Get-Process chrome | Stop-Process -Force 会杀死 harness 自身的主机进程。此插件会在每个 shell 工具调用运行之前对其进行检查,并拒绝这种形态,同时不干预显式指定 PID 的终止操作和 -PassThru 句柄终止操作。
Error: process-guard: blocked - this terminates "chrome", "msedge" after selecting
it by image name. That image may host the DSH GUI (http://127.0.0.1:3080), harness,
or terminal, so killing it can close the UI and interrupt the session. Kill only a
process you started: $p = Start-Process ... -PassThru; if (-not $p.WaitForExit(25000))
{ $p.Kill() }; or target a known PID with -Id.
此插件存在的起因
2026-09-18,一个运行无头 Chrome 截图验证的会话在两次尝试之间用一刀切的终止命令进行清理:
Get-Process chrome,msedge -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
该命令终止了机器上的每一个 Chrome 进程——包括承载 DSH Web GUI 的那个。窗口消失了,客户端连接中断,harness 将该回合记录为 interrupted,工具结果为“outcome unknown”。稍后一条通过正常升级提示获得批准的命令,以同样的一刀切终止开始并结束,在批准被记录约三秒后产生了相同的结果。批准只是偶然因素:它是让命令得以运行的关卡,而非原因。
审计追踪显示了一个 approval/asked,但没有匹配的 approval/decided,随后是 turn/end … interrupted,而 harness 服务器本身从未崩溃——这正是为什么需要在工具路径上设置防护,而不是在其他地方修复。docs/DESIGN.md 记录了完整的推理过程。
它的作用
| 命令 | 判定 |
|---|---|
| Get-Process chrome \| Stop-Process -Force | 拒绝(protected-image-kill) |
| Stop-Process -Name msedge、taskkill /IM chrome.exe /F、killall chrome、pkill -f chrome | 拒绝 |
| Get-Process node \| Stop-Process -Force、Stop-Process -Name WindowsTerminal | 拒绝 |
| Get-Process \| Stop-Process -Force、Stop-Process -Name ''、taskkill /F /IM 、kill -9 0 | 拒绝(一刀切选择) |
| spps -Name chrome、wmic … call terminate、Get-CimInstance Win32_Process -Filter "Name='chrome.exe'" \| Invoke-CimMethod -MethodName Terminate | 拒绝 |
| sudo killall chrome、time pkill chrome、nohup killall chrome、xargs killall、FOO=1 killall chrome | 拒绝(包装器会运行该命令) |
| for f in ; do killall chrome; done、if [ -f x ]; then killall chrome; fi | 拒绝(关键字开始一条命令) |
| Invoke-Expression "Stop-Process -Name chrome"、cmd /c "taskkill /IM /F"、zsh -c 'killall chrome'、python -c "os.system('killall chrome')"、字面量 -EncodedCommand | 拒绝(indirect-execution) |
| Stop-Process -Id 42、kill 4711 | 允许(explicit-pid) |
| $p = Start-Process chrome -PassThru; … $p.Kill() | 允许(你自己拥有的句柄) |
| $p = Get-Process chrome; $p.Kill()、$p = Get-Process chrome; $p \| % { $_.Kill() } | 拒绝(按名称选出的对象会跨语句被追踪) |
| $x = 'chrome'; Stop-Process -Name $x | 拒绝(字面量映像名通过变量仍保持不变) |
| Get-Process chrome \| Where-Object { $_.CommandLine -like '--headless' } \| Stop-Process | 默认拒绝;仅在 safeFilterAllows: true 时允许 |
| Get-Process notepad \| Stop-Process | 允许(选中的是未受保护的映像,而非笼统枚举) |
| Stop-Process -Name notepad | 允许(不是受保护的映像) |
| Write-Output "Stop-Process -Name chrome" | 允许(文本,而非调用) |
| Write-Output "$(Get-Date) Stop-Process -Name chrome" | 允许(只有替换会运行,且它不是 kill) |
| find . -name ".log" -exec grep -l chrome {} \; | 允许(这里的 -name 是 find 的,不是进程选择器) |
它还会贡献一段简短的系统提示词小节来陈述该规则,这样模型在遇到拒绝之前就知道这一约束。
安装
dsh plugin --profile web add dsh-process-guard
dsh plugin 会在 profile 内转发给 pnpm,然后把该包追加到
dsh.profile.bundles,因为该包声明了 dsh.bundle.patch。确认
该层已组合,然后重启 dsh web:
dsh --profile web --dump-config # look for a "# == dsh-process-guard" layer
从检出目录安装时,改为安装该目录,而不是注册表名称:
dsh plugin --profile web add /path/to/dsh-process-guard
git URL 也可以,而且无需构建:仓库根目录就是该包。
dsh plugin --profile web add git+https://github.com/CetOeil/dsh-process-guard.git
该插件没有运行时依赖,因此安装无需构建步骤,
也无需 pnpm allowBuilds 授权。它要求一个其 dsh-tools
暴露 ctx.tools.guard() 的 harness;此版本已针对 dsh 0.1.5-rc.3 验证,
记录为 engines.dsh。请将该字段视为文档,而非门禁:
npm 和 pnpm 只评估标准的 node/npm 引擎键,而 node-semver
无法表达“X 或以上的任意预发布版本”——预发布比较器只接受
其自身版本元组的预发布版本,这就是为什么声明的范围显式列出了
0.1.5-rc.1。强制执行的门禁是运行时检查:在没有
ctx.tools.guard() 的主机上,该插件会在加载时抛出错误,而不是留下一个
看似启用但实际无效的防护。
关于 pnpm 12 的一个行为,在版本发布后的头几天值得了解:它的供应链发布年龄门控会把刚发布的版本视为过新。在默认的非严格模式下,pnpm 会自行记录该例外(配置文件 pnpm-workspace.yaml 中的 minimumReleaseAgeExclude),安装继续进行;而在 minimumReleaseAgeStrict: true 时,它会停在一个提示处。无论哪种方式,上面的 git 安装都不受影响。
配置
默认值就是安全值;随附的 cordis.patch.yml 有意不设置任何 config: 块。通过将对应行复制到你自己的配置文件 cordis.patch.yml 中来覆盖键(参见 examples/override.cordis.patch.yml):
- id: process-guard
name: dsh-process-guard
config:
mode: ask # 'deny'(默认)通过 ctx.tools.guard() 路由
additionalTools: [remote_shell]
additionalProtectedImages: [custombrowser]
safeFilterAllows: false # 默认:要求 PID 或自有进程句柄
announce: true # 添加系统提示部分
enabled: true
| 键 | 默认值 | 含义 |
|---|---|---|
| enabled | true | 设为 false 可完全禁用检查。 |
| tools | 常见 shell 工具名称 | 替换列表,其中的工具的 command 参数会被检查。 |
| additionalTools | [] | 添加到默认列表的工具名称。 |
| protectedImages | 跨平台浏览器 + harness/终端宿主 | 替换列表,其中的镜像绝不能按名称终止。 |
| additionalProtectedImages | [] | 添加到内置保护列表的镜像名称。 |
| mode | deny | deny 阻止调用;ask 则将其发送到审批提示。 |
| safeFilterAllows | false | 选择启用正向的 CommandLine -like/-match '--headless' 或 --user-data-dir 例外。取反或 -or 过滤器仍会被阻止。 |
| announce | true | 贡献系统提示部分。 |
使用 additionalTools 和 additionalProtectedImages 进行常规扩展;tools 和 protectedImages 会有意替换其默认值。未知键、拼写错误的布尔值、无效的数组条目以及空的安全列表都会被报告并回退到安全值,因此拼写错误不会悄悄削弱防护。
mode: deny 通过 ctx.tools.guard() 强制执行,它是单调的——没有其他防护可以强制允许一个被此防护拒绝的调用。mode: ask 则注册一个 tools/pre-execute 监听器,让你在显示原因的情况下自行决定。
验证其是否有效
1. 让 agent 运行 Stop-Process -Name chrome。它必须返回
Error: process-guard: blocked - …,并且不得生成任何 pwsh 进程。
2. 让它运行 Stop-Process -Id ——这必须仍然有效。
3. 加载时,插件还会写入一条宿主日志条目,process-guard: deny mode on
[pwsh, bash, terminal, …]; protected images: chrome, …。它会写入
harness 日志,不一定写入你的终端:cordis 不附带控制台
导出器,因此将上面两项行为检查视为验证。
本仓库中的本地检查:
npm run check # tests + bundle + listing readiness + exact npm artifact
npm test # matcher corpus + plugin registration
npm run test:no-isolation # constrained sandboxes that block piped children
npm run verify:market # the README install command the hub looks for, plus manual steps
阻止管道子进程的沙箱(npm test 会为每个测试文件生成一个进程,而 npm run verify:package 会将 npm pack 作为子进程运行)会因与本包无关的原因破坏 npm run check。在那里使用 npm run test:no-isolation,并分别运行三个验证脚本;只有 verify:package 需要更宽的权限。
限制——在信任它之前请先阅读
这是一个行为安全网,而非安全边界。 它是对命令文本的静态启发式检查,以下情况可绕过它:
- 生成或单独存储的命令——在一次工具调用中编写并在下一次调用中执行的脚本、从磁盘或网络读取的命令,或在运行时由字符串片段拼装而成的 kill。因此 Stop-Process -Name (Get-Content names.txt) 是被允许的。字面量 PowerShell -EncodedCommand 载荷会被解码并检查,而保存在变量中的字面量映像名称会被解析。
- 被检查工具之外的任何内容——未来的进程管理工具、MCP 服务器,或自行调用 shell 的技能。随附的 cordis 代理预设挂载了 cordis_define / cordis_run,它们执行宿主 JavaScript 而从不调用 pwsh 或 bash;在那里编写的 kill 不会被检查。
- 远程执行——ssh host killall chrome 在另一台机器上运行,无法关闭本机的 GUI,因此不会被拒绝。
- 重命名或复制的二进制文件——针对不在 protectedImages 中的映像名称的 kill。
- 未建模的进程 API——直接原生调用、未来的 shell 原语,或匹配器中缺失的平台约定。包装器覆盖范围是一个显式列表(sudo、time、nohup、xargs、busybox、……),而不是关于哪些程序会执行其参数的通用模型。
它确实覆盖的是现实中的失败情况:代理伸手去执行显而易见的基于名称的清理。将拒绝视为使用更窄命令的信号,而不是证明无法运行任何破坏性命令。
禁用或移除
dsh plugin --profile web remove dsh-process-guard
或者在你的配置文件 cordis.patch.yml 中热禁用而不卸载:
- id: process-guard
disabled: true
这与通用权限插件的关系
本插件刻意保持狭窄,值得明确它处于什么位置。通用 DSH 权限插件是存在的,而且很好;但它们都不了解进程。
| 插件 | 它门控的内容 | 进程终止 |
|---|---|---|
| dsh-permission-rules | 声明式、由用户编写的允许/拒绝/询问规则,外加一套随附的高风险基线:rm -rf /、mkfs、对设备执行 dd、chmod -R 777、setuid 位、shutdown/reboot、git push --force、git reset --hard、curl \| sh、fork 炸弹、敏感路径 | 无规则,无概念 |
| safety-net / Barricade | 针对 fs/、git/、shell/、interp/、sys/ 的 41 条内置规则——破坏性文件系统与仓库操作 | 无规则,无概念 |
| 本插件 | 按映像名称、通配符、进程组或未过滤枚举来选定进程终止 | 这正是全部意义所在 |
两个邻近插件都挂接 tools/pre-execute 瀑布流。本插件也可以使用那个接缝(mode: ask),但它的默认方式是 ctx.tools.guard(),这是单调的——任何后续的守卫或监听器都无法强制允许一个已被另一个守卫拒绝的调用。关于该性质为何对安全规则至关重要,见 docs/DESIGN.md §2。
它们相互组合而非冲突:守卫阶段在 tools/pre-execute 瀑布流之后运行,因此通用权限插件先做决定,而本插件仍然保有自己的否决权。
诚实的告诫在于机制,而非覆盖范围。Barricade 的 POSIX 词法分析器、分段器和包装器解包比本插件的文本匹配器更强大,而 docs/DESIGN.md §7 承认后者只是一种启发式方法。如果某个通用闸门有朝一日获得了具备主机拓扑知识的进程终止族,它就能覆盖本插件。在那之前,这里真正独特的东西是领域知识——即 chrome、msedge、firefox、node、pwsh、conhost 和 WindowsTerminal 属于 DSH 宿主进程树,以及一刀切式的选定与指名选定同样危险。
相关文档
- docs/DESIGN.md — 守卫为何位于工具路径上、为何不放在沙箱接缝处,以及已知绕过方式的完整列表。
- docs/PUBLISHING.md — 经核实的 dsh-plugin.org 上架要求与发布检查清单。
- docs/agents-md-snippet.md — 以散文形式表述的同一条规则,适合偏好 AGENTS.md 指令而非插件的用户(或希望两层兼用者)。
- SECURITY.md — 本插件不防范哪些情况,以及应报告什么。
贡献
npm run check # tests, bundle contract, listing readiness, packed-file audit
两条规则让匹配器保持诚实:每条新增的拒绝规则都需要在 test/matcher.test.js 中有一个语料用例,并且每条新增规则都需要至少一个允许用例,以证明它不会吞掉合法命令。docs/DESIGN.md §5 解释了匹配器所依赖的双视图掩码和命令位置检查。
发布
发布工作流在 GitHub Release 上发布,其标签与 v 完全匹配,使用可信发布(OIDC)——任何地方都不存储 npm 令牌。在 npmjs.com 上配置该包的可信发布者(GitHub Actions、本仓库、工作流 publish.yml),然后发布一个 release;该
工作流会完成其余部分,证明也会随之生成。
有两个细节让这一切得以成立,而两者都很容易出错:
- actions/setup-node 不得设置 registry-url。它会写入一个包含 NODE_AUTH_TOKEN 占位符的 .npmrc,而该占位符会覆盖 npm 原生的 OIDC 交换——随后任务会在认证时失败,而受信任发布者实际上没有任何问题。
- 该任务需要 id-token: write(已设置)以及发布命令上的 --provenance,这正是驱动该交换的机制。
从工作站手动发布时没有证明——--provenance 是云 CI 功能(根据 npm publish --help,“当从受支持的云 CI/CD 系统发布时”)——而且它需要一种 npm 正在逐步淘汰的凭据,因此优先使用发布路径:
npm run check
npm publish --access public
0.2.1 是这一切的例外:受信任发布无法发布包的初始*版本,因此首次发布改用细粒度访问令牌。有关其中涉及的令牌陷阱,请参阅 docs/PUBLISHING.md §5。
在准备此包时,npm 名称 dsh-process-guard 尚未被占用。
在 dsh-plugin.org 上列出是自动的,无需提交拉取请求:该中心会定期扫描带有 dsh-plugin 主题的公共 GitHub 仓库,然后逐一人工审核。其四项明确要求是:公共仓库、该主题、包含 dsh plugin --profile web add 的 README,以及 apply(ctx) 导出。
npm run verify:market 负责安装命令——这是其他任何东西都无法覆盖的要求——并打印出它无法从此处检查的两个 GitHub 侧步骤。契约的清单部分是 npm run verify,而 apply(ctx) 导出无需检查:test/plugin.test.js 按名称导入它,因此丢失它会导致 npm test 失败。完整检查清单请参阅 docs/PUBLISHING.md。
精选的 awesome-dsh-plugin 列表是一个单独的注册表,采用拉取请求流程;它是可选的。其 CI 要求仓库至少存在一天,并且条目必须是单个文件 data/plugins/CetOeil__dsh-process-guard.yml:
url: https://github.com/CetOeil/dsh-process-guard
name: CetOeil/dsh-process-guard
category: security
description:
en: Blocks DSH shell calls that terminate protected browser, terminal, or harness processes by image name, wildcard, process group, or unfiltered enumeration.
许可证
MIT——请参阅 LICENSE。