Skip to content

v0.39.0 route B 回归:私有执行器未隔离 shell 服务,导致 bash 工具消失 #19

Closed

Description

@KouzakiUmi

问题摘要

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/dsh Core: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>

复现步骤

  1. 在 Windows 上使用已加载官方 SandboxPwshExecutor 的目标 DSH 宿主,安装 v0.39.0。
  2. 确认 Git for Windows 可被解析;保留默认 variantPresets: false。
  3. 创建使用官方工具面的 agent,使其初始工具面有 pwsh、无 bash。
  4. 等待插件的行内补位,观察重复 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。

根因定位

  1. src/inline-tools.js 的 loadBash() 使用 createScope(ctx)。
  2. 在该 scope 内通过 plugin(GitBashSandboxExecutor) 挂载继承类。
  3. ShellExecutor 构造器硬性调用 super(ctx, 'shell'),Service 随即注册服务。
  4. 普通子 scope 与父级共享 shell isolation key;官方 PowerShell 已占据同一 key。
  5. 构造失败发生在 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

  1. KannaKuron commented on Oct 13, 2026

    @KannaKuron
    Owner

    已修复并随 v0.39.1 发布。

    PR #20 已 squash 合并(521be01 所在主线)。这份报告的质量非常出色——根因定位(Service 构造链的 isolation key)、最小修复原则(只隔离 shell、其余宿主依赖原样继承)、真实 Cordis 生命周期回归、以及已安装宿主上的无头 runtime preview($0.2.1-alpha.2 + Cordis 4.0.5-alpha.1),正是本插件需要的验证层级。两处既有测试结构问题(Node 22 嵌套测试取消、minimal PTY 平台恢复时机)也一并修正且未削弱任何断言。

    课程已记入 CHANGELOG 与 AGENTS §4l:子 fiber 只隔离副作用所有权,不隔离服务命名空间——「私有 scope 不注册全局服务」这个假设是 route B 的设计错误,此类链路必须用真实 cordis Context 验证(现在 tests/private-executor.mjs 已锁)。

    再次感谢。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions