Repository navigation
v0.39.0 route B 回归:私有执行器未隔离 shell 服务,导致 bash 工具消失 #19
Description
问题摘要
v0.39.0 的 route B 重构保留了官方 PowerShell 执行器,但创建「私有」Git Bash 执行器时只新建了 Cordis 子插件 fiber,没有隔离 shell 服务命名空间。因此真实父类构造器仍尝试注册根作用域已经存在的 shell,立即报重复服务错误,插件自有 bash 工具尚未注册就中断。
这是执行器注册链的回归,不是 Git Bash 路径不存在,也不是工具发现列表漏展示。
受影响基线和现场环境
- 插件:v0.39.0,上游提交
9a72b07。 - 系统:Windows,已安装 Git for Windows,插件启动日志确认路径解析成功。
- 桌面壳:DSH NEXT 2.0.17-next。
- 目标进程实际加载的
@deepseek-ai/dshCore:0.2.1-alpha.2。 - 同一宿主域的
@deepseek-ai/cordis:4.0.5-alpha.1。 - 现场 Profile:desktop。默认不启用 Git Bash preset 变体,依赖行内工具补位。
- 隔离复现使用 Node 24.13.0,加载上述宿主的真实服务包。
预期 / 实际
预期:官方 PowerShell 执行器保留,私有 Git Bash 执行器使用独立 shell 服务槽;Windows 官方 preset 的 agent 能看到并执行插件自有 bash。pwshTool 默认关闭时仅隐藏 pwsh,开启时 pwsh 仍执行真正 PowerShell。
实际:Git Bash 解析成功,但构造私有执行器失败,bash 不进入工具注册表。FastCtx、路径映射等独立能力仍可能成功启动,因此「插件其他部分正常」不能证明 bash 已注册。
启动日志证据(已脱敏)
2026-10-13 11:55:10,Asia/Hong_Kong,当前宿主进程记录:
[gitbash-shell] bash resolution (boot): Git Bash resolved from the default source: .../Git/bin/bash.exe
[gitbash-shell] inline tool patch armed (own bash tool over a private Git Bash executor; official pwsh executor untouched)
Error: service "shell" has been registered at <SandboxPwshExecutor>
at new Service (.../@deepseek-ai/cordis/lib/index.js:1782)
at new ShellExecutor (.../@deepseek-ai/dsh-shell/lib/index.js:85)
at new LocalBashExecutor (.../@deepseek-ai/dsh-bash-local/lib/index.js:78)
at new SandboxBashExecutor (.../@deepseek-ai/dsh-bash-sandbox/lib/index.js:47)
at new GitBashSandboxExecutor (.../dsh-gitbash-shell/src/shell.js:136)
[gitbash-shell] own bash tool activation failed for this agent: service "shell" has been registered at <SandboxPwshExecutor>
复现步骤
- 在 Windows 上使用已加载官方
SandboxPwshExecutor的目标 DSH 宿主,安装 v0.39.0。 - 确认 Git for Windows 可被解析;保留默认
variantPresets: false。 - 创建使用官方工具面的 agent,使其初始工具面有 pwsh、无 bash。
- 等待插件的行内补位,观察重复
shell服务错误以及 bash 不可见。
底层关系可直接用真实 Cordis 复现:
import { Context, Service } from '@deepseek-ai/cordis'
const root = new Context()
root.provide('shell', { kind: 'official-pwsh' })
await root.plugin((child) => {
new Service(child, 'shell') // 报重复注册 shell 服务
})子 fiber 的生命周期/副作用所有权与服务隔离是两回事,ctx.plugin() 本身不会改变继承的服务 isolation key。
根因定位
src/inline-tools.js的loadBash()使用createScope(ctx)。- 在该 scope 内通过
plugin(GitBashSandboxExecutor)挂载继承类。 ShellExecutor构造器硬性调用super(ctx, 'shell'),Service随即注册服务。- 普通子 scope 与父级共享
shellisolation key;官方 PowerShell 已占据同一 key。 - 构造失败发生在
createBashToolModule()及每-agent bash 注册之前,所以工具发现机制无法显示一个根本没有注册的工具。
另有后续读取授权问题:空 scope 并没有声明 shell 注入,隔离之后直接读 executorScope.ctx.shell 仍会报 without inject。工具就绪检查的 scope.ctx.tools 也会在不继承 tools 访问授权的上下文中中断。单纯补 isolate() 而不修正读取面是不完整修复。
修复原则
- 只对
shell使用ctx.isolate('shell'),不隔离/替换subprocess、sandbox、sandboxPolicy等宿主依赖。 - 保留 Cordis 官方类插件挂载,仍应用真实 Config、volatile 字段及 static inject。
- 通过受支持的显式
get('shell')/get('tools')读取服务,不依赖空 scope 未声明的属性访问授权。 - 失败时释放 scope,成功/失败均清理挂载计时器。
- 不重新禁用官方执行器、不修改 bundle patch、不改变 shell 执行/沙箱/后台任务协议。
验证与覆盖边界
修复分支新增真实 Cordis 生命周期回归及可复跑的已安装宿主 preview;运行方式与边界记录在分支的 tests/README.md。
本机已验证:
- 旧的普通子 scope 路径在真实宿主类链上重现同一重复服务错误。
- 固定后 bash 出现在真实 ToolRuntime 的 per-agent schema 中,不污染全局工具面。
- bash 执行
command -v bash、uname -s和 sentinel;uname 为MINGW32_NT-*/MINGW64_NT-*,退出码 0。 - pwsh 开启时,原官方执行器仍能执行
Get-Process。 - pwsh 默认关闭时,bash 可调用而 pwsh 隐藏。
- 卸载行内 patch 后,bash 消失、pwsh 恢复、原 shell provider 保持不变。
- 完整本地测试 127/127 通过;打包 dry-run、语法检查及 diff 检查通过。
preview 使用真实宿主包、真实进程做无头运行时验证;policy/session/working-directory 接线为夹具,覆盖 danger-full-access。完整 GUI、预设选择器、PTY、后台任务和受限模式不在本次测试覆盖范围内。
修复分支增加 Windows/Linux × Node 22/24 的非发布 CI;最终提交 095940f 的四个组合均已通过:CI 运行记录。
首轮 CI 还暴露了两项既有 error-content 测试误嵌套导致 Node 22 取消测试的问题;修复分支将它们恢复为独立测试,保留全部断言和 Node 22 矩阵。首轮失败与追加修正均有提交/CI 记录,没有通过减少覆盖来取得绿灯。
修复分支:KouzakiUmi/dsh-gitbash-shell · fix/private-gitbash-executor-isolation。修复 PR 将关联本 issue。
2026-10-13 后续全面审查与修复
原服务隔离问题已由 PR #20 合并解决,并随 v0.39.1 发布;本记录保持已完成状态。 新一轮确认的功能/逻辑回归由独立的 后续 PR #22 承载,不属于原 PR 的已合并内容。
后续提交:6b26ded,基于当前上游 521be01,完整保留 v0.39.1 的私有服务隔离与 #21 glob real-array 修复,不更改已发布版本号。
确认并修复 16 项既有问题:
- 三个 Windows 全工具 Git Bash 变体实际走根 PowerShell,现接同一私有 bash 补位通道;minimal persistent 不改。
- 存活 agent 的 pwsh 动态工具面、异步导入/挂载跨卸载的失效工具残留、jobs 卸载后前台 bash 不恢复。
- 两个受控模块解析降级分支:plain definition 的嵌套 required schema 非法;审批 helper 缺失导致会话 standing policy 丢失。未声称生产正在发生导入失败。
- preset register/unregister 的卸载竞态,以及动态关闭变体后部署默认悬空;只迁移部署默认,不迁移钉住会话。
- better-sidebar 动态恢复与手选保护;run_code 关键字后正则的误翻译,保守整份 no-op。
- FastCtx execution 方言门控、spawn error Promise、MCP isError 失败面,以及并发发现/懒连接丢失所有权。
- 设置卡 Hook 数变化、工具链进度轮询单次暂态错误后永久停止。
保留根官方 PowerShell、route B 纯新增 patch、成功 FastCtx 全文回显、Windows 明示 unconfined 取舍,以及 autoTerminalShell OFF 只停止未来写入的独立语义。无新增依赖、功能、兼容下限调整、发布或安装动作。
本次实际验证
- 完整测试:156/156,0 fail / 0 cancelled / 0 skipped。
- 实际 Core 无头 preview:14/14,0 fail / 0 cancelled / 0 skipped。
- 语法、diff 和打包 dry-run:通过。
- 本提交 CI 38356641905:Windows/Linux × Node 22/24 四组合全部成功,不是引用原提交的旧 CI。
- 目标实际宿主为 Core 0.2.1-alpha.2、Cordis 4.0.5-alpha.1;普通可移植测试使用锁定 Cordis 4.0.4。Grok 修复后只读反证未发现确定遗漏。
真实 Windows 进程验证 Git Bash uname/sentinel 与原官方 PowerShell,新增真实 Core API 回归同时含内存 subprocess、延迟注册和受控 MCP 传输。UI/并发连接使用确定性夹具;不等同于完整 Electron GUI、生产 PresetTree、真 MCP exe 并发或受限模式端到端验收。详细触发链、修复与分层覆盖见 PR #22。
Activity
chore(v0.39.1): release — private-executor isolation (#19/#20) + gb_g…
KannaKuron commentedon Oct 13, 2026
已修复并随 v0.39.1 发布。
PR #20 已 squash 合并(521be01 所在主线)。这份报告的质量非常出色——根因定位(
Service构造链的 isolation key)、最小修复原则(只隔离shell、其余宿主依赖原样继承)、真实 Cordis 生命周期回归、以及已安装宿主上的无头 runtime preview($0.2.1-alpha.2+ Cordis4.0.5-alpha.1),正是本插件需要的验证层级。两处既有测试结构问题(Node 22 嵌套测试取消、minimal PTY 平台恢复时机)也一并修正且未削弱任何断言。课程已记入 CHANGELOG 与 AGENTS §4l:子 fiber 只隔离副作用所有权,不隔离服务命名空间——「私有 scope 不注册全局服务」这个假设是 route B 的设计错误,此类链路必须用真实 cordis Context 验证(现在
tests/private-executor.mjs已锁)。再次感谢。