fix(e2b): harden remote adapter boundaries
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-27-e2b-remote-runtime-poc.md
|
||||
2026-07-27-e2b-remote-runtime-poc.md: a713cca3fd9e7ee11a2c487bf6ed2c3a205dc502
|
||||
2026-07-27-e2b-remote-runtime-poc.zh.md: 7afd54f72622d51a3d71719b3b4975ccd7f83e3a
|
||||
2026-07-27-e2b-remote-runtime-poc.md: efb91fc166f36dc8fb047d686e8cd82d93b9af6a
|
||||
2026-07-27-e2b-remote-runtime-poc.zh.md: eb14cccc284d38cdc5cc704512b6899621a9a840
|
||||
|
||||
@@ -18,7 +18,7 @@ The E2B integration is an opt-in provider-composition POC. Its six E2B-specific
|
||||
- `@deepseek-ai/dsh-fs-e2b` implements `ctx.fs` over that sandbox's Filesystem API.
|
||||
- `@deepseek-ai/dsh-subprocess-e2b` implements `ctx.subprocess` over E2B Commands and remote Linux process groups.
|
||||
- `@deepseek-ai/dsh-pty-e2b` registers an E2B byte-PTY backend on `ctx.pty` while the existing registry retains exact-Agent ownership.
|
||||
- `@deepseek-ai/dsh-lsp-e2b` registers configured remote language servers on `ctx.lsp`, reads source through E2B Filesystem APIs, and runs servers through `dsh-subprocess-e2b`.
|
||||
- `@deepseek-ai/dsh-lsp-e2b` registers configured remote language servers on `ctx.lsp`, reads source through a bounded no-follow helper in E2B, and runs servers through `dsh-subprocess-e2b`.
|
||||
- `@deepseek-ai/dsh-code-runtime-e2b` registers `ctx.codeRuntime`, runs each model program in a fresh remote worker, and dispatches binding functions in the host process.
|
||||
- The existing `@deepseek-ai/dsh-bash-local` remains the Bash implementation because it delegates all process mechanics to `ctx.subprocess`.
|
||||
|
||||
@@ -28,11 +28,11 @@ The providers reuse the PTY, LSP, Code Runtime, and subprocess seams without cha
|
||||
|
||||
## POC boundary
|
||||
|
||||
E2B owns the mutable filesystem, command and Bash processes, PTY shell and foreground process groups, language-server processes and source reads, the Code Runtime runner and worker, and adapter-private files under `.dsh-e2b`.
|
||||
E2B owns the mutable filesystem, command and Bash processes, PTY shell and terminal-session process groups, language-server processes and source reads, the Code Runtime launcher, controller, and worker, and adapter-private files under `.dsh-e2b`.
|
||||
|
||||
The host owns Cordis and plugin objects, the agent loop, agent/session/goal state, session logs and persistence, LLM calls, prompts and tools, authority decisions, skills, subagent orchestration, PTY buffers and readiness state, LSP JSON-RPC ids/queues/protocol state, Code Runtime type stripping/output accounting/binding dispatch, and E2B SDK/network orchestration. The overlay does not upload, mount, or synchronize the host workspace; identical cwd strings name independent host and remote directories.
|
||||
|
||||
Byte-sensitive protocols use the narrowest adapter required by E2B's callback shapes. PTY consumes the SDK's byte callback directly. LSP and Code Runtime install dependency-free remote helpers that encode raw payloads as validated newline-delimited base64 JSON, keeping E2B's decoded command callbacks on an ASCII transport.
|
||||
Byte-sensitive protocols use the narrowest adapter required by E2B's callback shapes. PTY consumes the SDK's byte callback directly. LSP installs a bounded remote source reader, while Code Runtime keeps framed stdout in a launcher process isolated from the controller and worker descriptors. Their dependency-free helpers encode protocol payloads as validated newline-delimited base64 JSON, keeping E2B's decoded command callbacks on an ASCII transport.
|
||||
|
||||
Retaining a sandbox preserves remote files and unmanaged remote state only. Reconnect does not reconstruct host PTY sessions, buffers, process handles, LSP connections or requests, code workers, binding calls, timers, output cursors, or locks. Managed groups terminate and join when their provider disposes before the shared owner pauses, leaves, or kills the sandbox.
|
||||
|
||||
@@ -40,9 +40,9 @@ The POC has no session-persistence backend, template builder, volume, snapshot,
|
||||
|
||||
## Verification
|
||||
|
||||
Focused package suites pin owner lifecycle cleanup, filesystem semantics, subprocess process groups, configuration and publication rollback, byte framing and multibyte boundaries, PTY readiness/signals, LSP transport and source containment, Code Runtime bindings, hostile traffic, output limits, timeout/abort ordering, disposal to quiescence, and package-owned invariant registrations. Adjacent local-backend suites pin the shared PTY utilities and the LSP cross-namespace `processId` behavior.
|
||||
Focused package suites pin owner lifecycle cleanup, filesystem semantics and commit metadata, subprocess process groups, configuration and verified publication rollback, byte framing and multibyte boundaries, PTY readiness/signals/default-environment scrubbing/terminal-session cleanup, stable bounded LSP source reads, Code Runtime binding and descriptor isolation, worker-pipe draining, hostile traffic, output limits, timeout/abort ordering, disposal to quiescence, and package-owned invariant registrations. Adjacent local-backend suites pin the shared PTY utilities and the LSP cross-namespace `processId` behavior.
|
||||
|
||||
A credential-gated Loader composition creates one real E2B sandbox and exercises FS-to-Bash and Bash-to-FS visibility, multibyte PTY output and `SIGINT`, multibyte LSP hover and definition results, Code Runtime host bindings and typed rejection under mutation of adapter-captured intrinsics, wall timeout, abort, runner cleanup, host-workspace isolation, and final sandbox deletion. The same scenario runs through source imports and built package exports.
|
||||
A credential-gated Loader composition creates real E2B sandboxes and exercises FS-to-Bash and Bash-to-FS visibility, process-publication rollback, bounded spill output, PTY default-secret scrubbing and process-tree cleanup, stable bounded LSP source reads, Code Runtime host bindings and descriptor-isolated output accounting, wall timeout, abort, runner cleanup, host-workspace isolation, and final sandbox deletion. The same composition runs through source imports and built package exports.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
@@ -66,4 +66,4 @@ A credential-gated Loader composition creates one real E2B sandbox and exercises
|
||||
|
||||
The small composition demonstrates that existing capability seams can move an agent's mutable coding world off-host without changing the loop or model-facing tool packages. `sandboxId` plus pause/leave permits manual remote-file retention for experiments, while kill remains the demo's cleanup policy.
|
||||
|
||||
The providers are not interchangeable with local backends for every consumer: remote startup cannot synchronously expose a PID, E2B retains complete command output in SDK memory, ordinary command callbacks are not byte-faithful, signal attribution is partly inferred, and reconnect cannot restore handles or protocol state. PTY uses E2B's byte API; LSP and Code Runtime add validated ASCII framing where protocol bytes matter. Remote process/spill artifacts accumulate in a retained sandbox, Code programs share a JavaScript realm with Node worker internals, and a process that deliberately escapes a captured remote process group does not become reconnectable or owned. These gaps remain documented POC constraints rather than compatibility shims or new cross-cutting abstractions.
|
||||
The providers are not interchangeable with local backends for every consumer: remote startup cannot synchronously expose a PID, E2B retains complete command output in SDK memory, ordinary command callbacks are not byte-faithful, signal attribution is partly inferred, and reconnect cannot restore handles or protocol state. PTY uses E2B's byte API; LSP and Code Runtime add validated ASCII framing where protocol bytes matter. Remote process/spill artifacts accumulate in a retained sandbox, Code programs share a JavaScript realm with Node worker internals, and a process that deliberately escapes a managed process group or PTY session does not become reconnectable or owned. These gaps remain documented POC constraints rather than compatibility shims or new cross-cutting abstractions.
|
||||
|
||||
@@ -18,7 +18,7 @@ E2B 集成是一个选择性启用的提供方组合 POC。它的 6 个 E2B 专
|
||||
- `@deepseek-ai/dsh-fs-e2b` 在该沙箱的 Filesystem API 之上实现 `ctx.fs`。
|
||||
- `@deepseek-ai/dsh-subprocess-e2b` 在 E2B Commands 和远程 Linux 进程组之上实现 `ctx.subprocess`。
|
||||
- `@deepseek-ai/dsh-pty-e2b` 在 `ctx.pty` 上注册 E2B 字节 PTY 后端,并把精确的 Agent 所有权保留在现有注册表中。
|
||||
- `@deepseek-ai/dsh-lsp-e2b` 在 `ctx.lsp` 上注册已配置的远程语言服务器,通过 E2B Filesystem API 读取源代码,并通过 `dsh-subprocess-e2b` 运行服务器。
|
||||
- `@deepseek-ai/dsh-lsp-e2b` 在 `ctx.lsp` 上注册已配置的远程语言服务器,通过 E2B 内有界且不跟随链接的辅助程序读取源代码,并通过 `dsh-subprocess-e2b` 运行服务器。
|
||||
- `@deepseek-ai/dsh-code-runtime-e2b` 注册 `ctx.codeRuntime`,在全新的远程 worker 中运行每个模型程序,并在宿主进程中分发绑定函数。
|
||||
- 现有的 `@deepseek-ai/dsh-bash-local` 继续作为 Bash 实现,因为它把所有进程机制委托给 `ctx.subprocess`。
|
||||
|
||||
@@ -28,11 +28,11 @@ E2B 集成是一个选择性启用的提供方组合 POC。它的 6 个 E2B 专
|
||||
|
||||
## POC 边界
|
||||
|
||||
E2B 拥有可变文件系统、命令和 Bash 进程、PTY shell 与前台进程组、语言服务器进程及源码读取、Code Runtime 运行器和 worker,以及 `.dsh-e2b` 下的适配器私有文件。
|
||||
E2B 拥有可变文件系统、命令和 Bash 进程、PTY shell 与终端会话进程组、语言服务器进程及源码读取、Code Runtime launcher、controller 和 worker,以及 `.dsh-e2b` 下的适配器私有文件。
|
||||
|
||||
宿主拥有 Cordis 与插件对象、agent loop、agent/会话/goal 状态、会话日志及持久化、LLM(大语言模型)调用、提示词与工具、权限决策、skill(技能)、subagent 编排、PTY 缓冲与就绪状态、LSP JSON-RPC id/队列/协议状态、Code Runtime 类型剥离/输出计量/绑定分发,以及 E2B SDK/网络编排。该 overlay 不会上传、挂载或同步宿主工作区;拼写相同的 cwd 字符串分别指向彼此独立的宿主与远程目录。
|
||||
|
||||
对字节敏感的协议只使用适配 E2B 回调形状所需的最窄适配器。PTY 直接消费 SDK 的字节回调。LSP 与 Code Runtime 会安装无依赖的远程辅助程序,把原始载荷编码为经过验证、以换行分隔的 base64 JSON,并通过 ASCII 传输承载 E2B 已解码的命令回调。
|
||||
对字节敏感的协议只使用适配 E2B 回调形状所需的最窄适配器。PTY 直接消费 SDK 的字节回调。LSP 会安装一个有界的远程源码读取器;Code Runtime 则把分帧 stdout 保留在与 controller 和 worker 描述符隔离的 launcher 进程内。它们的无依赖辅助程序会把协议载荷编码为经过验证、以换行分隔的 base64 JSON,并通过 ASCII 传输承载 E2B 已解码的命令回调。
|
||||
|
||||
保留沙箱只会保存远程文件与未受管的远程状态。重新连接不会重建宿主 PTY 会话、缓冲、进程句柄、LSP 连接或请求、代码 worker、绑定调用、定时器、输出游标或锁。受管进程组会在所属提供方 dispose(资源释放)时终止并等待退出,之后共享所有者才会暂停、脱离或终止沙箱。
|
||||
|
||||
@@ -40,9 +40,9 @@ E2B 拥有可变文件系统、命令和 Bash 进程、PTY shell 与前台进程
|
||||
|
||||
## 验证
|
||||
|
||||
聚焦包测试套件固定所有者生命周期清理、文件系统语义、进程管理的进程组、配置与发布回滚、字节分帧与多字节边界、PTY 就绪状态/信号、LSP 传输与源码路径约束、Code Runtime 绑定、恶意通信、输出上限、超时/中止顺序、等待完全停稳的资源释放,以及包自有不变式注册。相邻本地后端测试套件固定共享 PTY 工具函数,以及 LSP 跨命名空间 `processId` 行为。
|
||||
聚焦包测试套件固定所有者生命周期清理、文件系统语义与提交元数据、进程管理的进程组、配置与经过验证的发布回滚、字节分帧与多字节边界、PTY 就绪状态/信号/默认环境清理/终端会话清理、稳定且有界的 LSP 源码读取、Code Runtime 绑定与描述符隔离、worker 管道排空、恶意通信、输出上限、超时/中止顺序、等待完全停稳的资源释放,以及包自有不变式注册。相邻本地后端测试套件固定共享 PTY 工具函数,以及 LSP 跨命名空间 `processId` 行为。
|
||||
|
||||
凭据门控的 Loader 组合会创建一个真实 E2B 沙箱,并演练 FS-to-Bash 与 Bash-to-FS 可见性、多字节 PTY 输出和 `SIGINT`、多字节 LSP 悬停与定义结果、Code Runtime 宿主绑定,以及适配器已捕获 intrinsic 被修改时的类型化 reject、墙钟超时、中止、运行器清理、宿主工作区隔离,以及最终删除沙箱。同一场景分别通过源代码导入与已构建包导出运行。
|
||||
凭据门控的 Loader 组合会创建真实 E2B 沙箱,并演练 FS-to-Bash 与 Bash-to-FS 可见性、进程发布回滚、有界 spill 输出、PTY 默认秘密清理与进程树清理、稳定且有界的 LSP 源码读取、Code Runtime 宿主绑定与描述符隔离的输出记账、墙钟超时、中止、runner 清理、宿主工作区隔离,以及最终删除沙箱。同一组合分别通过源代码导入与已构建包导出运行。
|
||||
|
||||
## 曾考虑的替代方案
|
||||
|
||||
@@ -66,4 +66,4 @@ E2B 拥有可变文件系统、命令和 Bash 进程、PTY shell 与前台进程
|
||||
|
||||
这个小型组合证明,现有功能 seam 可以把 agent 的可变 coding 环境移出宿主,而无需改变循环或面向模型的工具包。`sandboxId` 与 `pause`/`leave` 允许实验手动保留远程文件,演示仍以 `kill` 作为清理策略。
|
||||
|
||||
这些提供方并不能对所有消费方与本地后端互换:远程启动无法同步公开 PID,E2B 会在 SDK 内存中保留完整命令输出,普通命令回调并非字节保真,信号归因部分依靠推断,重新连接也无法恢复句柄或协议状态。PTY 使用 E2B 的字节 API;LSP 与 Code Runtime 则在必须保真处理协议字节之处增加经过验证的 ASCII 分帧。保留沙箱后会累积远程进程/spill 产物,模型程序与 Node worker 内部机制共享一个 JavaScript realm,有意逃离已捕获远程进程组的进程也不会因此变得可重新连接或由该组合管理。这些缺口作为 POC 约束明确记录,而不会引入兼容垫片或新的跨领域抽象。
|
||||
这些提供方并不能对所有消费方与本地后端互换:远程启动无法同步公开 PID,E2B 会在 SDK 内存中保留完整命令输出,普通命令回调并非字节保真,信号归因部分依靠推断,重新连接也无法恢复句柄或协议状态。PTY 使用 E2B 的字节 API;LSP 与 Code Runtime 则在必须保真处理协议字节之处增加经过验证的 ASCII 分帧。保留沙箱后会累积远程进程/spill 产物,模型程序与 Node worker 内部机制共享一个 JavaScript realm,有意逃离受管理进程组或 PTY 会话的进程也不会因此变得可重新连接或由该组合管理。这些缺口作为 POC 约束明确记录,而不会引入兼容垫片或新的跨领域抽象。
|
||||
|
||||
Reference in New Issue
Block a user