docs: add OpenCode ext-host IPC bridge design - #1758
Conversation
limityan
left a comment
There was a problem hiding this comment.
基于当前 PR head 1d53f54a1 和最新 main@2848b58b7 复核后,这份设计目前还不适合合并。主要问题不是协议细节尚未补全,而是执行入口、运行时职责和安全边界与主线现有设计存在冲突:
-
插件可能绕过现有确认流程执行。 文档让
Session::create从 workspace 配置直接启动 Host 并加载插件,但请求中没有已确认的来源、内容摘要和实际执行机器。插件又可以访问文件、网络和子进程。这样打开一个带配置的项目就可能执行尚未批准的代码,Remote workspace 还可能错误地回落到本机。应由现有来源与安全控制面先完成发现、确认和内容校验,Runtime 只接收已经批准的插件;远程执行不可用时应明确拒绝,不能本机回落。 -
新增
ExtHostBinding/bitfun-ext-host-bridge形成了第二条 Plugin Runtime 主链。 最新主线已经明确:调用可靠性由PluginRuntimeClient负责,OpenCode 语义由 adapter 转换,进程、IPC 和物理健康由 services 负责,Tool/Hook/Permission 等现有模块负责最终判断和状态提交。当前方案又在 bridge 中管理启动、连接、超时、取消、背压、Hook、Tool 和 instance,会产生两套激活、恢复与贡献状态。请复用现有PluginRuntimeClient → Adapter → Services → Plugin Host链路,只在确有缺口的位置补窄接口。 -
协议无法在仓库内复核。 文档把作者机器上的
C:\Users\27931\...\PROTOCOL.md称为唯一事实来源,但仓库中没有对应协议、schema 或 Rust/Bun 共用测试数据;plugin-runtime-host-design.md等链接也已经失效。应提交版本化协议、schema 和跨语言 fixture,或引用固定的公开提交,并以当前plugin-runtime-design.md为上位约束。 -
多实例生命周期和双向调用还没有闭合。 同一 workspace instance 可以被多个 Session 共享,但没有使用关系或最后使用者关闭规则;状态图又把 Host 进程状态和单个 instance 状态混在一起。反向权限、认证和 HTTP 请求也缺少有限队列、独立读取/写入、过载处理和完整认证;timeout 后继续复用 instance,但取消和迟到结果处理被延期,存在死锁、跨 Session 串用和副作用失控风险。首个可执行版本必须先定义清楚 Host、instance、Session 三层生命周期,并具备期限、取消、背压、迟到结果拒绝和进程树回收。
-
长期架构文档混入了易失效的实施计划。 逐文件代码量、阶段 checklist、13–19 人天估算和约 4.4k 行预算应移到 issue 或实施计划。架构文档应集中说明当前/目标边界、职责关系、关键流程、安全约束和可验证的完成条件;同时修正“当前 adapter 仅静态预览”等已经不符合最新主线的描述。
本地检查也尚未达到文档 PR 的基本门槛:git diff --check 因尾随空格失败,pnpm run check:repo-hygiene 因本机绝对路径失败,Markdown 检查发现 3 个失效链接;GitHub 当前没有 checks,不能视为 CI 已通过。PR 还落后最新 main 28 个提交,其中包含新的 Plugin Runtime 与 worker 生命周期约束。
建议基于最新主线重新收敛设计:先确定一个经过批准的 package-plugin 最小端到端闭环,复用现有 Runtime 主链;协议和安全基础进入仓库后,再分别扩展 Hook、权限回调和其他能力。完成上述调整后再请求复审。
Add comprehensive technical design for BitFun ↔ OpenCode extension host IPC integration, covering: - Architecture positioning and crate dependency direction - Lifecycle state machine (Idle → Starting → Connected → Ready) - IPC bridge layer design (framing, codec, transport, peer) - Module structure for new bitfun-ext-host-bridge crate - Key interfaces (ExtHostBinding port, instance management) - Error handling and recovery strategy - Security considerations (token auth, loopback isolation) - 4-phase implementation plan with effort estimates - Change impact analysis (~4,376 lines across 5 crates)
1d53f54 to
230b68d
Compare
limityan
left a comment
There was a problem hiding this comment.
基于当前 PR head 230b68dc4 和最新 main@a1b5f283e 重新审查后,结论仍是 Request changes。
这次更新已经实质修复了旧版的一些问题:补充了来源审批与 activation authority、Remote fail-closed、三层生命周期、迟到结果处理、ProcessTreeChild 进程树回收,并把协议来源固定到公开提交。因此下面不再重复旧 review,而只列当前版本仍会阻塞实现或导致安全/架构回归的问题。
1. 批准摘要没有绑定最终执行的 npm 代码
问题
文档前面要求把入口、锁文件、完整依赖图和物化摘要纳入用户确认,并禁止无锁漂移;但 §4.2/§4.3 又规定 Bun Host 在可写 cacheDirectory 中安装 npm 插件,host.instance.open 示例仍传入裸 { "spec": "opencode-plugin-foo" }。
冻结的 ext-host 实现会把裸包名解析为 @latest,随后执行 bun add --ignore-scripts --exact <spec>。也就是说,用户确认的声明/manifest 摘要与最终下载、import 的包及传递依赖不是同一个经过验证的对象。
风险
包版本或传递依赖可以在确认后变化,未被批准的代码仍会在当前用户权限下获得文件、网络和子进程能力;这会直接破坏本文声称的“固定内容 + 当前 authority”安全边界。
建议方案
依赖准备服务应先解析、安装并冻结完整依赖闭包,计算最终物化摘要并让用户确认;确认后 instance.open 只能收到只读、内容寻址的本地入口,不能再让 Host 根据裸 npm spec 联网解析。如果必须由 Host 安装,则协议需要增加 prepare/attest 两阶段流程,让 Rust 在 import 前校验 Host 返回的完整依赖清单和摘要。
2. Host 的进程键和生命周期与最新主线冲突
问题
§3 把 workspace + plugin target 作为 Host/Instance 键,并由首个/末个 Session holder 启停进程。最新 plugin-runtime-design.md 已明确:workspace、session 和插件数量都不是默认物理进程键;同一 RuntimeServices 中兼容的插件和多个 workspace 默认共享 Plugin Host,session 只用于调用身份、取消和权限上下文。
风险
该模型会把进程数量放大为 workspace × target,并在 Session 归档时错误回收仍被事件订阅、后台任务或其他 Client 使用的 Host;同时会破坏共享 Host 的加载顺序、模块缓存、统一重启预算和故障传播语义。
建议方案
以 RuntimeServices 的真实插件使用、停用和进程退出控制 Host 生命周期;Session 关闭只取消该 Session 的在途调用。若确实需要按插件隔离进程,必须作为对上位设计的显式变更,给出安全收益、启动/内存数据、兼容性差异和行为等价测试,不能在 P0 落地文档中隐式改写默认模型。
3. ExtHostRuntime 与现有静态预览组合点形成第二套 owner
问题
§5.1 把 Session quiesce/resume、holder token、Host 关闭和物理清理状态全部放进 runtime-ports::ExtHostRuntime;§5.4 又让 assembly/core/plugin_runtime.rs 中一个并不存在的 Session::create 启动 Host、消费 registrations 并直接注册 Tool/Hook。
但最新代码中该 assembly 模块明确只负责选择 adapter/client 和投影候选,不注册工具、不执行插件代码;opencode-adapter/AGENTS.md 也明确要求当前 load_opencode_package_adapter 保持 static-preview only,不能直接扩展成新的受管 OpenCode 执行路径。
风险
稳定 contract 会同时承担产品 Session 生命周期和物理进程生命周期,静态预览入口也会升级成执行 authority,最终形成第二套激活、generation、恢复、贡献注册和清理状态;现有来源 owner、能力 owner、PluginRuntimeClient 与 services 进程 owner 无法保持单一权威。
建议方案
保持来源/激活事实由 source owner 管理,Tool/Hook/Permission 由各能力 owner 提交,调用可靠性由 PluginRuntimeClient 管理,进程与 IPC 由 services 管理。只新增 provider-neutral、真实 consumer 驱动的窄执行控制端口,并由 Assembly 注入;不要让 runtime-ports 或 legacy static-preview 路径拥有 Session/Host 生命周期。
4. 一个异常 Host 可以永久阻塞或直接击穿 Session 创建
问题
§5.3 的 spawn_ext_host() 对 listener.accept() 和 handshake 没有 startup deadline,也没有同时监听 child exit、cancel 或 shutdown;§5.4 的 Session::create 又同步等待所有 target,并用 ? 传播任一启动、握手或注册失败。
风险
Bun 启动后不连接即可让创建流程永久挂起;Bun 缺失或单个插件损坏则会让整个无关 Session 创建失败。这与上位设计要求的后台准备、非阻塞产品入口和单插件失败隔离相冲突。
建议方案
由 workspace/source runtime coordinator 在后台维护 target 可用性,Session 只读取轻量状态而不等待所有插件启动。每个 target 独立降级;startup 使用统一 deadline,并通过 select 同时处理 accept、handshake、child exit、取消和应用 shutdown。
5. timeout/cancel 只停止 Rust 等待,没有取消插件执行
问题
§3.6 的 tokio::select! 在 timeout 或 cancellation token 触发后直接返回,随后只从 pending map 移除 request id。协议已经提供 host.tool.cancel { instanceID, executionID },但这里没有发送;“丢弃迟到响应”也不能撤销插件已经开始的副作用。
风险
用户界面显示已取消后,插件仍可能继续写文件、访问网络或创建子进程;如果继续复用该 target,后续调用还可能观察到不可控的残留状态。
建议方案
请求模型需要携带调用类别和 executionID。Tool 超时/取消时先发送 host.tool.cancel 并有界等待确认;Host 不响应时将 target 标记为 poisoned 并回收/重启。没有 cancel RPC 的 Hook 按 generation fence 丢弃结果,并按本文其他章节已经描述的规则 recycle target。
合并前状态
- PR 当前落后
main97 个提交,其中包含refactor(plugins): clarify runtime process ownership;需要先变基再校对整篇设计。 - 最新主线已把
plugin-runtime-host-design.md替换为plugin-runtime-design.md。当前提交应用到最新主线后会留下 2 个失效 Markdown 链接和 2 处过时文本引用。 git diff --check、pnpm run check:repo-hygiene和node scripts/check-core-boundaries.mjs本地通过,但这些检查不会验证架构文档中的 owner 与安全流程。- GitHub 当前仍是
no checks reported,不能视为 CI 已通过。 - 如果要逐字复制 ext-host 协议/schema 或随产品分发 Host,还需要先明确外部仓库许可证、可复现构建、签名、升级和跨平台交付方式。
建议先基于最新主线收敛一个最小闭环:已批准的不可变 package target → 唯一 Runtime/Services 主链 → 一个真实 Tool 或稳定 Hook consumer → 可取消、可回收、可验证的 Host 调用。该闭环和固定跨语言 fixture 完成后,再扩展完整 Client、Auth、Provider 和其他 Hook。
Add comprehensive technical design for BitFun ↔ OpenCode extension host IPC integration, covering:
Summary
Fixes #
Type and Areas
Type:
Areas:
Motivation / Impact
Verification
Reviewer Notes
Checklist