Back to home@Wisper-beep

dsh-runbox

Isolated execution substrate for DeepSeek Harness (dsh): run agent shell / fs / process / terminal / jobs inside disposable containers.

Stars
0
Language
TypeScript
Created
Sep 11, 2026
Updated
Sep 11, 2026

Introduction

dsh-runbox

DeepSeek Harness 的隔离执行地基:把 agent 的 shell、文件、进程、终端与后台任务,从宿主本地搬进一次性容器里执行。

An isolated execution substrate for DeepSeek Harness (dsh).

容器化、可丢弃、有资源与网络边界、执行过程可审计。

当前状态

未可用的开发预览。 地基、Docker 后端与 shell 前台执行已落地,并在真实容器上验证通过;其余 provider 按里程碑推进中。

里程碑内容状态
M0官方 seam 契约、monorepo 骨架、CI、最小插件加载✅ 已完成
M1Docker 箱生命周期;shell 前台执行✅ 已在 CI 真机验证
M2subprocess / fs provider、强制执行度上报未开始
M3后台进程、terminal / jobs provider、会话级生命周期未开始
M4Web UI(设置 / 状态 / 审计)、网络与资源策略未开始
M5Podman / WSL2 / microVM / SSH 第二后端、一致性测试套件未开始

各包当前状态:

状态
@dsh-runbox/core可用:后端注册表、箱契约、策略翻译、fail-closed 选择
@dsh-runbox/backend-docker可用:端点候选探测 + 完整箱生命周期(建 / 执行 / 停 / 删 / 列)
@dsh-runbox/provider-shell前台执行可用;后台进程与 danger-full-access 明确报错
@dsh-runbox/provider-subprocess占位,顺延至 M2
@dsh-runbox/provider-fs占位,待 M2
@dsh-runbox/sandbox-bridge占位,待 M2
@dsh-runbox/provider-jobs占位,待 M3
@dsh-runbox/provider-terminal占位,待 M3
@dsh-runbox/ui占位,待 M4

占位包被调用时抛 RunboxNotImplementedError不会静默空转——一个"什么都不做也不报错"的 provider 会让上层误以为隔离已经生效。

用途

为什么需要它

DeepSeek Harness 官方文档 docs/subsystems/sandbox.zh.md 写道:

「容器、microVM 和远程执行是完整能力 seam 的同级实现,而非 ctx.sandbox 的提供方。」

官方把这三类点名为预期扩展形态,但尚未实现;社区侧同样是空的(对 npm 上 4646 个 dsh-plugin 做密度探测,容器化执行后端的有效实现为 0,podman 为 0,Windows 沙箱原语为 0。见 research/gap-report.md)。

它做什么

  • 真实边界read-only / workspace-write 由容器挂载标志在挂载命名空间层面强制,不是应用层的自觉。
  • 可丢弃、可复现:每个会话一个箱子,跑完即弃;环境由镜像定义。
  • 零改上层:实现的是官方 capability seam,审批、权限、成本、审计等既有插件无需改动即可获得隔离能力。
  • 失败即拒绝:容器不可用时抛 SandboxUnavailableError,绝不静默回落到宿主执行。

架构

dsh 上层(无需改动)
  agent-loop · tool-bash · tool-fs · tool-terminal · tool-jobs · 审批 / 权限
        │  只认 seam,不认实现
dsh-runbox
  core       后端注册表 · 会话与箱绑定 · 策略翻译 · fail-closed · 审计 · 孤儿回收
  providers  subprocess │ fs │ shell │ terminal │ jobs
  backends   docker / podman │ wsl2 │ microVM │ ssh        ← 同一接口,可插拔
  ui         设置卡 · 状态面板 · 审计时间线
        │  Engine API(npipe / unix socket)
一次性容器:只读 rootfs + tmpfs · 工作区同路径挂载 · cgroup 限额 · 默认无网络

包划分

职责
core后端注册表、箱契约、SandboxMode → 围栏配置翻译、fail-closed 选择、审计
backend-dockerDocker / Podman Engine API 后端(不依赖 docker CLI)
provider-subprocessctx.subprocess 实现:spawn 进箱、stdio、退出码、进程树终止
provider-fsctx.fs 实现:读写与编辑路由进箱,遵守工作区边界
provider-shellctx.shell 实现:箱内 bash 执行器
provider-terminalctx.terminals 后端:箱内持久 PTY
provider-jobsctx.jobs 实现:后台任务登记与回收
sandbox-bridge逐调用沙箱模式 → 箱围栏配置,并上报强制执行度
conformance验收门禁:加载、注册可逆、fail-closed
uiWeb 设置卡、箱状态面板、审计时间线

关键机制

契约门禁。 provider-* 包继承官方抽象 seam 类(如 ShellExecutor)。官方 rc 版本一旦改签名,npm run build 直接失败——dsh 处于 developer preview 且明说会有破坏性变更,这是最可靠的一根安全绳。

fail-closed。 后端选择逐个探测,全部不可用时抛 BackendUnavailableError。代码里不存在"降级为不隔离"的分支,并有测试守着。

执行世界一致。 官方要求 ctx.fsctx.subprocess 共享同一个执行世界,因此 fs.processPath() 交给子进程的路径在箱内必须可打开——两者成对替换,工作区在箱内挂载到与宿主相同的路径。

注册即可逆。 所有注册都走 Cordis 的 ctx.effect,返回注销函数,热卸载不留残余。

使用

环境要求

  • Node.js ≥ 22
  • Docker 或 Podman(M1 起需要;用于承载箱)

安装

git clone https://github.com/Wisper-beep/dsh-runbox.git
cd dsh-runbox
npm ci --legacy-peer-deps

--legacy-peer-deps 是必须的,原因见已知问题

在 dsh 中加载

# 核心地基(必需)
dsh plugin --profile web add @dsh-runbox/core

# Docker 后端
dsh plugin --profile web add @dsh-runbox/backend-docker

# 执行层(M1 起可用)
dsh plugin --profile web add @dsh-runbox/provider-shell
dsh plugin --profile web add @dsh-runbox/provider-subprocess

加载 provider 即接管对应能力。每个 context 只能有一个实现,因此挂上 provider-shell 后不应再挂官方的 bash-local

验证

npm run build   # tsc -b:同时是类型检查与构建
npm test        # 含 M0 加载门禁、fail-closed、策略翻译、引擎探测

开发

packages/    十个包,见上表
docs/        01-选题提案.md(论证与设计)| 02-seam契约速览.md(官方接口要点,实现依据)
research/    生态调研证据:4646 插件快照、空白核验、可复现脚本
scripts/     fetch-seam-contracts.py(拉官方类型契约)| scaffold-packages.mjs(生成包骨架)

常用命令:

npm run build        # 类型检查 + 构建(= 契约门禁)
npm test             # 单元与门禁测试
npm run seams:pull   # 拉取官方 seam 类型契约 → reference/dsh-seams/(不入库)

reference/dsh-seams/ 是官方包的解包产物(第三方代码,MIT),可用脚本随时重建,因此不提交。契约稳定后应把版本号写回 scripts/fetch-seam-contracts.pyMANIFEST 锁定。

契约要点见 docs/02-seam契约速览.md

已知问题

1. npm ci 必须带 --legacy-peer-deps

官方 seam 包的 peer 闭包包含一个未发布到 npm 的包:@deepseek-ai/dsh-type-meta(registry 返回 404),npm 的 peer 自动安装会因此中断整个 install。仓库根 .npmrc 已固定该行为。类型层面由 skipLibCheck 兜住,运行时的真实实例由宿主 dsh 提供;上游补发该包后即可移除。

2. 需要 Linux 容器引擎。

Windows 容器引擎不支持只读 rootfs(invalid option: read-only mode is not supported for Windows containers),因此兑现不了承诺的文件效果围栏。create() 会先读 /infoOSType,非 Linux 直接抛 UnsupportedModeError 并说明怎么办,而不是降级成可写 rootfs 的假隔离。

3. 契约门禁是编译期的。

它能证明签名一致,不能证明行为一致。行为一致性由 packages/conformancebackend-docker 的集成用例覆盖——后者在真实容器里建箱、执行、验证宿主无副作用、验证只读真的拒绝写入;引擎不具备时整组跳过而不是失败。

许可

MIT,与 DeepSeek Harness 保持一致。