Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions docs/architecture/opencode-plugin-surface-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@

| OpenCode 能力 | P0 处理 | BitFun 承接位置 | 处理方式 |
|---|---|---|---|
| `opencode.json` plugin 配置 | 可作为兼容输入进入 P0 | OpenCode 适配层 -> BitFun 插件来源只读视图 | 只读扫描,生成 provenance、manifest、hash、诊断和候选来源 |
| `.opencode/plugins/*.js|ts` | 可作为兼容输入进入 P0 | OpenCode 适配层 | 只识别文件形态和能力声明,不直接执行 |
| 全局插件目录 | 可作为兼容输入进入 P0 | OpenCode 适配层 | 只读导入;不继承 OpenCode 启用顺序 |
| 受管包内的 `opencode.json` | P0 只读解释 | BitFun 受管包 -> OpenCode 适配层 | 只读取清单声明并校验的内容;不安装或执行 npm 插件 |
| 受管包内的 `.opencode/plugins/*.js|ts` | P0 只读解释 | BitFun 受管包 -> OpenCode 适配层 | 只识别能力声明,不直接执行 |
| 用户已有 `opencode.json` 或项目 `.opencode` 目录 | 当前未实现 | 未来独立导入流程 | 转换为受管包后再进入适配层,不直接扫描 |
| 全局插件目录 | 后续可选导入来源 | 独立导入流程 | 转换为受管包;不继承 OpenCode 启用顺序 |
| npm 插件列表 | P0 可诊断,执行属于后续 | OpenCode 适配层 | 只产出来源和 unsupported / projection-only 诊断 |
| custom tool | 是,最小候选能力 | 扩展贡献接口 -> 工具 ABI | 映射为提供方候选(`ProviderCandidate`);进入最终工具链路前必须走权限和工具快照 |
| permission hook | 是,候选能力 | 权限/副作用子接口 | 只能产生候选确认或诊断;不能直接批准 |
Expand Down Expand Up @@ -57,24 +58,25 @@
| `runtime-ports` plugin contract | 已有主机 ABI、只读视图、候选项、权限提示、诊断和隔离类型;公开符号较多但已受脚本预算约束 | 不继续新增泛描述符;公开符号必须声明接口切面、消费方和验证目标 |
| `plugin-runtime-host` | 已有受控 host 边界、deadline、幂等、隔离和 restart 清理路径 | 继续保持窄方法集;P0-C.1 来源接口不得直接泄漏主机 ABI |
| `product-domains/plugin_source` | 定义生态无关的版本 1 包清单、来源标识、工作区信任记录和 epoch 规则 | `adapter` 仅为不透明标识;不得加入生态入口规则、文件系统、安装或主机行为 |
| `services-integrations/plugin_source` | 校验用户级和项目级 BitFun 目录中的全部声明文件,安全替换工作区信任记录 | 不解释 `.opencode` 布局,不扫描外部生态目录,不执行插件,不增加通用 registry/manager 接口 |
| `services-integrations/plugin_source` | 校验用户级和项目级 BitFun 目录中的全部声明文件,安全替换工作区信任记录,并为选定包生成固定内容输入 | 不解释 `.opencode` 布局,不扫描外部生态目录,不执行插件,不增加通用 registry/manager 接口 |
| `bitfun-core/plugin_source` | 注入产品目录并向 CLI 保留来源与诊断兼容接口 | 不实现文件扫描、锁、持久化或生态解析 |
| `bitfun-cli plugins` | 当前来源审核接口的产品消费方,支持 `list/approve-source/deny/revoke`;`doctor` 汇总严重来源错误 | `SourceApproved` 不得宣称能力已批准、包已启用或可执行,不承担安装复制和卸载 |
| `opencode-adapter` | 提供来源发现、诊断只读视图和受信任 custom tool 候选映射;未建立信任或暂不支持的能力返回诊断或 `unsupported` 状态 | 当前只验证适配器到 Plugin Runtime Host 的候选链路;生产组装接入须独立评审 |
| `opencode-adapter` | 消费固定内容的受管包输入,提供诊断只读视图和 custom tool 映射;未激活或暂不支持的能力返回诊断或 `unsupported` 状态 | 不拥有目录发现;生产组装和激活接入须独立评审 |
| `events` | 已有产品事件清单 | 需要在真实插件事件消费前定义可订阅子集,不新增插件专用事件模型 |
| `tool-contracts` | 已有动态工具提供方和工具快照 | custom tool 映射必须复用它,不新增插件专用工具 ABI |

`opencode-adapter` 当前规则:

- 通过 `load_opencode_workspace_adapter` 接入 Plugin Runtime Host,并接收产品来源/策略侧生成的 `PluginSourceRef` 来源快照和信任 epoch
- 信任快照的 epoch 必须与本次 read/dispatch epoch 一致,否则只返回诊断,不产生受信任候选
- 唯一产品组装根调用公开工厂并把返回的适配器注入 Plugin Runtime Host;工厂只接收来源服务生成的受管包输入
- `SourceApproved` 仅表示包内容已经用户审核,适配器必须保持未激活状态,不得生成受信任候选
- GUI、TUI/CLI、Web 等产品入口只消费能力服务接口、插件只读视图、诊断和稳定状态词。
- 适配器不执行 JS/TS、不安装 npm、不依赖用户本机 `opencode`。
- 当前源码探测只识别测试覆盖的 `export const` 和同一行 `name: tool({` 声明形式,不提供完整 JS/TS 语法兼容;没有可识别入口的包和已识别但不支持的 hook 必须返回诊断,其他语法不属于本阶段兼容范围。

当前受管包规则:

- 包清单文件为 `bitfun.plugin.json`;版本 1 的 `adapter` 是小写不透明标识。只有清单声明并通过哈希校验的文件进入来源标识和后续适配器访问范围。
- `.opencode/plugins/*.js|ts` 只在 OpenCode 适配层中解释,不是产品域或来源模块规则,也不是对用户 OpenCode 配置目录的直接扫描
- `.opencode/plugins/*.js|ts` 只在 OpenCode 适配层中解释;文件必须先进入受管包清单并通过来源服务校验,不得由公开适配入口直接扫描用户 OpenCode 配置目录
- 包内容变化后旧来源审核失效,新来源标识回到 `Unknown`;损坏的信任文件按失败处理且不自动覆盖。
- P0-C.2 不得把 `SourceApproved` 直接映射为 Host 的 `Trusted`;首次激活需展示适配器、入口、能力和副作用并重新确认。
- P0-C.1 没有生产 Host 绑定和 JS/TS 执行能力。
Expand Down
29 changes: 24 additions & 5 deletions docs/architecture/plugin-runtime-host-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ P0-C.1 只证明 BitFun 可以识别、校验和审核受管包;P0-C.2 才覆

## 4. OpenCode 适配边界

OpenCode 适配层是主机内部的兼容适配层。它读取 OpenCode 配置和插件文件,输出 BitFun 主机接口对象或诊断。
OpenCode 适配层是主机内部的兼容适配层。它只解释来源服务提供的固定受管包内容,输出 BitFun 主机接口对象或诊断。

| OpenCode 输入 | BitFun 输出 | 当前边界 |
|---|---|---|
| `opencode.json` plugin 配置 | 导入 provenance、manifest、hash、诊断、候选 BitFun 来源 | 可选导入,不执行 |
| `.opencode/plugins/*.js|ts` | 候选来源、配置诊断、能力诊断 | 不直接加载为权威状态 |
| 全局插件目录 | 候选来源和冲突诊断 | 不继承 OpenCode 启用顺序 |
| 受管包内的 `opencode.json` | 配置诊断和 npm 插件只读状态 | 不安装或执行 npm 插件 |
| 受管包内的 `.opencode/plugins/*.js|ts` | 候选来源、配置诊断、能力诊断 | 不直接加载为权威状态 |
| 用户已有项目或全局 OpenCode 目录 | 当前无输出 | 未来必须经独立导入流程转换为受管包 |
| custom tool | `PluginEffectCandidatePayload::ProviderCandidate` | 进入最终工具链路前必须走工具 ABI 和权限门禁 |
| permission hook | `PluginPermissionGate::PermissionRequired` 或诊断 | 不能直接批准 |
| `tool.execute.before/after` | 当前阶段诊断或 status-only | 不改写工具输入或结果 |
Expand Down Expand Up @@ -168,7 +168,26 @@ P0-C.1 只读取两个 BitFun 受管目录:用户数据目录的 `plugins` 和
- 具体文件系统校验和信任持久化归 `services-integrations/plugin_source`,`bitfun-core/plugin_source` 只注入产品目录并保留兼容接口。
- 产品路径初始化失败或全局路径管理器已降级到临时目录时,来源列表、审核和 `doctor` 必须返回错误,不得在临时目录中创建信任记录。
- 产品域的 `SourceApproved` 只确认来源内容,不依赖 Host ABI,也不得直接映射为 Host 的 `Trusted`。P0-C.2 首次激活必须展示适配器、入口、能力和副作用并重新确认。
- P0-C.2 加载器不得复用 CLI 扫描结果直接执行文件;绑定前必须把清单声明文件重新校验并固定为不可变快照,dispatch 前还必须校验来源标识、激活确认和 Host 信任 epoch。
- 来源服务按包重新校验清单、声明文件和哈希,并返回固定内容的包输入。OpenCode 适配器不得根据包路径再次访问文件系统,也不得直接扫描工作区或用户 OpenCode 目录。
- 来源服务只为当前 `SourceApproved` 的包返回固定内容输入;输入不携带来源审核状态或审核 epoch。适配器始终按未激活状态处理,当前只读 Host 链路不得产生 custom tool 候选。后续激活流程必须重新确认入口、能力和副作用,并独立定义 Host 信任及其 epoch。
- 单个来源服务实例串行生成固定内容输入;扫描和稳定性复核共享同一字节与时间预算,返回前再次确认信任 epoch、目标来源身份和 `SourceApproved` 状态。固定输入构造同时限制文件数量、单文件大小、包总量和声明文件集合。

```mermaid
sequenceDiagram
participant Assembly as 产品组装
participant Source as 受管包来源服务
participant Adapter as OpenCode 适配器
participant Host as 插件运行时主机

Assembly->>Source: 读取指定包
Source->>Source: 重新校验清单、文件边界与哈希
Source-->>Assembly: 固定内容的包输入
Assembly->>Adapter: 创建只读适配器
Assembly->>Host: PluginRuntimeHost::new(adapter)
Host->>Adapter: read / dispatch
Adapter-->>Host: 来源、诊断和未激活状态
Note over Adapter,Host: 不执行 JS/TS,不产生工具候选
```

## 7. 验证要求

Expand Down
36 changes: 23 additions & 13 deletions docs/architecture/product-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ flowchart TB

P0 的目标不是复制完整 OpenCode 运行时,也不是导入用户已有 OpenCode 安装。P0 只验证一条 BitFun 主导的 OpenCode-compatible 插件路径。

当前 P0-C.1 只建立包识别、完整性校验、工作区信任和 CLI 诊断,不执行插件:
P0-C.1 已建立包识别、完整性校验、工作区信任和 CLI 诊断,不执行插件:

1. 用户级包和项目级包只从 BitFun 受管目录发现;工作区同 ID 来源优先且不得回退到用户级包。
2. `bitfun.plugin.json` 只定义生态无关的包来源标识、适配器标识和文件哈希;具体生态入口由对应适配器解释。
3. `bitfun-cli plugins` 提供来源审核和诊断;`SourceApproved` 只确认当前来源内容,不表示能力已批准、已启用或可执行,完整性错误由 `bitfun-cli doctor` 返回失败。
4. 当前来源接口未绑定生产插件主机,不执行 JS/TS,不注册最终工具。目录、清单和持久化规则见 [`plugin-runtime-host-design.md`](plugin-runtime-host-design.md#6-目录与来源原则)。
4. 来源接口尚未绑定生产插件主机,不执行 JS/TS,不注册最终工具。目录、清单和持久化规则见 [`plugin-runtime-host-design.md`](plugin-runtime-host-design.md#6-目录与来源原则)。

归属边界:`product-domains/plugin_source` 定义纯数据和信任规则,`services-integrations/plugin_source` 负责文件系统校验、锁和持久化,`bitfun-core/plugin_source` 仅注入产品目录并保留 CLI 兼容接口。

Expand All @@ -141,11 +141,16 @@ flowchart LR
UserRoot["用户级 BitFun 插件目录"] --> Discovery["包发现与完整性校验"]
WorkspaceRoot["项目级 .bitfun/plugins"] --> Discovery
Manifest["bitfun.plugin.json"] --> Discovery
Discovery --> Snapshot["来源与诊断接口"]
Trust["工作区信任存储"] --> Snapshot
CLI["CLI 插件管理与 doctor"] --> Snapshot
Discovery --> SourceView["来源与诊断接口"]
Trust["工作区信任存储"] --> SourceView
CLI["CLI 插件管理与 doctor"] --> SourceView
CLI --> Trust
Snapshot -.->|后续生产绑定| Host["插件运行时主机"]
SourceView -->|按包重新校验| PackageInput["不可变包输入"]
PackageInput --> Adapter["OpenCode 适配器"]
Assembly["产品组装根"] -->|创建| Adapter
Adapter -->|注入| Host["插件运行时主机"]
Host -->|封装 client| RuntimeBinding["PluginRuntimeBinding"]
RuntimeBinding --> AgentRuntime["Agent Runtime"]
```

当前实现与后续能力边界:
Expand All @@ -154,31 +159,36 @@ flowchart LR
|---|---|---|
| 用户级、项目级包 | 从两个 BitFun 受管目录发现并校验 | 安装复制、更新、卸载和组织策略 |
| 随产品携带包 | 未建立独立扫描根 | 由构建配置、安装器和产品组装提供来源后接入同一校验接口 |
| OpenCode 兼容内容 | 包清单可声明 `opencode_compatible`,来源模块只验证清单声明文件 | OpenCode 适配器解释包内布局;外部目录需独立导入流程 |
| OpenCode 兼容内容 | 包清单可声明 `opencode_compatible`;来源模块重新校验并固定声明文件,适配器只解释该输入 | 外部目录需经独立导入流程转换为受管包 |
| 来源审核 | 工作区 `SourceApproved`、`Denied`、`Revoked`;内容变化使旧审核失效,新来源标识回到 `Unknown` | 首次激活能力审核、组织策略、签名和撤销列表 |
| 插件运行 | 不执行 JS/TS,不注册最终工具 | 通过 `PluginRuntimeBinding` 接入主机,再完成工具 ABI 消费路径 |
| 插件运行 | 不执行 JS/TS,不注册最终工具 | 产品组装创建适配器和 Host,再通过 `PluginRuntimeBinding` 注入 Agent Runtime |

OpenCode 适配接入规则:

- OpenCode 适配器通过插件运行时主机暴露来源只读视图、诊断和受信任 custom tool 候选映射。
- 信任输入复用既有 `PluginSourceRef` 来源快照,并携带产品来源/策略侧生成的信任 epoch;信任 epoch 必须与本次 read/dispatch epoch 一致。
- OpenCode 适配器的公开入口只接收来源服务重新校验并固定的受管包输入,不直接扫描工作区或用户 OpenCode 目录。
- 来源服务只为当前 `SourceApproved` 的包生成固定内容输入;输入只包含来源标识、清单和声明文件内容,不把来源审核状态或审核 epoch 传入 Host。
- 固定内容输入只保证结构、大小和哈希自洽,不作为审核凭据。生产组装必须从来源服务取得输入;即使其他进程内调用方构造了有效输入,适配器仍只能返回未激活状态。
- Host 来源 URI 使用来源模块生成的路径摘要区分用户级包、项目级包和后续其他来源,不暴露原始本地路径。
- OpenCode 适配器始终按未激活状态处理该输入,只能暴露来源只读视图和诊断;激活确认产生独立的 Host 信任后,才允许映射 custom tool 候选。
- 当前源码探测只识别经过测试的单行声明形式,不是完整 JS/TS 解析器;空包或没有任何受支持入口的包必须返回诊断,其他 JS/TS 语法不属于本阶段兼容范围。
- 未支持或信任不足的能力必须返回诊断或 `unsupported` 状态,不得因外部插件内容导致运行时崩溃。
- 生产产品组装接入必须通过 `PluginRuntimeBinding` 注册适配器,并在同一变更中同步边界脚本、主机路径测试和启用/降级策略。
- 后续生产接入由唯一的产品组装根调用具体适配器工厂,将适配器注入 Host,再把 Host client 封装为 `PluginRuntimeBinding`;同一变更必须同步边界脚本、主机路径测试和启用/降级策略。
- GUI、TUI/CLI、Web 等产品入口只消费能力服务接口、插件只读视图、诊断和稳定状态词,不直接依赖 OpenCode 适配器内部类型或插件主机内部 ABI。

信任 epoch 与生命周期:

- 来源审核 epoch 由 BitFun 来源与信任模块维护。审核、拒绝、撤销、已有记录的来源标识或哈希变化都会推进 epoch;重复写入相同决定不推进 epoch。信任文件重建时使用新的随机初始值,避免旧 epoch 被重复使用。
- 发现的新来源默认为 `Unknown`;CLI 只允许对当前工作区已发现且 id 唯一的包写入 `SourceApproved`、`Denied` 或 `Revoked`。
- 损坏、版本未知或记录冲突的信任文件按失败处理;适配器和主机不得写信任状态。
- `SourceApproved` 不得直接映射为 Host 的 `Trusted`。P0-C.2 首次激活必须展示适配器、入口、能力和副作用并重新确认;只有该确认产生的 Host 信任且 epoch 匹配时才可生成 custom tool 候选
- `SourceApproved` 不得直接映射为 Host 的 `Trusted`。来源审核 epoch 只属于来源存储;P0-C.2 首次激活必须展示适配器、入口、能力和副作用,并由激活归属模块定义独立的 Host 信任及其 epoch。
- `ProjectionOnly` 在候选路径中表示插件代码没有被执行、最终效果没有提交;它允许主机返回受权限门禁保护的候选项和诊断,不表示插件运行时已经可执行。

OpenCode 能力映射:

| OpenCode 能力 | BitFun P0 处理 | 不允许 |
|---|---|---|
| project/global plugin config | 可选导入源,产出 provenance、manifest、hash、诊断和候选 BitFun 来源 | 作为 BitFun 主配置或直接决定启用状态 |
| 受管包内的 `opencode.json` | 当前只读解释配置和 npm 插件声明,返回诊断 | 安装或执行 npm 插件、直接决定启用状态 |
| 用户已有 project/global plugin config | 当前未实现;未来由独立导入流程转换为受管包 | 由适配器直接扫描、作为 BitFun 主配置 |
| custom tools | 映射为工具提供方候选,最终走工具 ABI | 新增插件专用工具模型 |
| permission hooks | 映射为权限候选或需要确认的诊断 | 插件直接批准、拒绝或写审计 |
| events / SSE | 订阅 BitFun 公开事件清单的受控子集 | 读取内部 session、turn、tool 或 UI 状态 |
Expand Down
Loading
Loading