Skip to content

[Proposal] 社区插件 api-sdk RFC 文档 v0.1 #24

Description

@hikariming

类型

信息

问题与证据

经过昨天讨论得出的总结形成 01 版本文档

希望得到的结果

dsh 社区插件互操作标准 v0.1 设计稿

——提交 dsh 官方审阅版

字段 内容
日期 2026-08-17
状态 社区 Draft。这是社区讨论稿,不是官方标准,也不自称官方标准
来源 community#23 首轮 RFC + 13 条评论的第二轮讨论 + dsh-community-fabric 中的 4 份 Draft RFC 与逐条处置记录
本文性质 上述约 3000 行讨论材料的提炼。只保留 v0.1 决定 + 对官方的具体请求;完整论证见原文链接

一页摘要

问题。 dsh 插件生态在快速膨胀:awesome 目录快照已收录 3,809 个插件仓库。对其中 12 个代表性开源插件的源码调研显示,多数插件依赖源码 patch、内部函数或私有 service 探测实现功能——上游一更新即批量失效;GUI / Web UI / TUI 各宿主插件互不兼容,且用户在安装前无法判断兼容性,只能装上炸了才知道。

社区做了什么。 生态内主要插件作者、三端宿主维护者与分发渠道进行了两轮公开讨论(issue #23,13 条实质评论),收敛出一套四层互操作模型和一个刻意做小的 v0.1:

插件代码 ──只依赖──▶ Fabric SDK / 稳定 contract
                        ▼
              Capability Broker(校验、协商、授权、生命周期、资源归属)
                        ▼
              版本化 DSH Adapter(唯一允许吸收上游变化的层)
                        ▼
              官方 dsh / Cordis runtime(不要求任何修改)

v0.1 是什么(五句话)。 一个静态 JSON manifest(dsh-plugin.json)+ 机器可读的宿主能力描述(Host Descriptor);一个纯函数的 required/optional 能力协商器;一套顺序确定的激活/停用生命周期;三项低风险 capability(storage.localcommands、不可修改的 messages.observe 观察事件);以及可在 headless 环境运行的一致性测试。没有沙箱承诺、没有可修改拦截、没有插件间 service、没有跨端 UI——这些全部显式延期为独立 RFC。

对官方的请求(详见 §5): ① 核心观察点变更的 changelog 提前标注;② dsh-plugin.json 文件名与命名空间的不冲突确认;③ 以任意深度参与标准治理。明确不请求: 修改内核、立即采纳、移除现有 Cordis / plugin / profile 加载路径。


1. 问题与证据

三类结构性问题(详细数据见插件需求调研):

  1. 实现耦合。 抽样的 12 个插件中,多数通过源码 patch、monkey patch、内部事件名或 ctx.get() 反射探测实现功能。这不是插件作者的错——官方接缝缺失时他们别无选择——但结果是每次上游更新都在生态里引发一轮批量炸裂。历史已经演过一次:早期社区 loader 在官方引入统一注册方式后一夜全废。
  2. 兼容信息缺失。 manifest 只有包名和 patch 文件列表,宿主、市场和启动器都无法在执行代码前判断:这个插件需要图形界面吗?要读会话吗?要联网吗?能在 TUI 上跑吗?12 个样本中 9 个同时需要 Host 和 Client 双 face——跨 face 是常态而非特例,但目前没有任何声明机制。
  3. 组合不确定。 多插件修改同一行为时没有声明、顺序和冲突规则,实际仲裁者是"谁后加载谁赢"。分发渠道被迫用整包锁版本对抗接口不稳定。

2. 两轮讨论收敛出的六条设计原则

第二轮讨论(13 条评论)对首轮 RFC 做了大量修正,全部修正收敛为以下原则。每条都有具体反例支撑,出处见附录 A。

  1. 静态可分析。 manifest 是包根目录的静态 JSON,禁止运行代码生成;宿主加载时不从网络取 schema。工具无需执行插件代码即可完成发现、校验和协商。
  2. 五类声明不混淆。 requires(依赖什么)、permissions(申请什么授权)、provides(能实现什么 service)、contributes(贡献什么静态元数据)、subscriptions(订阅什么事件)是五种语义,不能压进一个泛化的 capabilities 容器。v0.1 schema 只接受已有具体 contract 的前者四类子集,并拒绝 providesrequires.services(组合规则未定前不开口子)。
  3. 协商 + 诚实降级。 required 缺失 → 安装/激活前明确拒载并说明原因;optional 缺失 → 走声明过的降级路径。市场展示五种状态且不得互相升级:声明兼容 / 等待授权 / 已实测 / 不兼容 / 未知。"声明兼容"永远不等于"已实测",更不等于"安全"。
  4. 信任分档,capability 不是沙箱。 v0.1 为 trusted-in-process 档位:同进程受信任的 Node.js 插件在技术上可以绕过 ctx 直接调用系统接口。capability 声明服务于兼容判断、用户授权和审计,不构成安全边界,宿主必须显著公示这一点。真正的隔离执行档位(进程/realm 隔离、受控 IPC)是独立的后续 RFC。
  5. 上游变化收敛到 Adapter,fail closed。 插件只依赖 Fabric contract;版本化 DSH Adapter 是唯一允许 import 上游 runtime 的层。上游不再暴露某项能力所需的观察点时,Adapter 必须下线对应 capability 并报告原因,不能用私有 patch 猜测语义返回"看起来成功"的近似结果。运行时方法替换类技术(如 dsh-neoforge mixin PoC)只能作为固定版本的 Adapter 实验存在,其私有 target 永远不进入插件可见的 API。
  6. 确定性与可归属。 加载顺序永远不是冲突仲裁机制。所有标准注册经过 Broker 归属到具体插件的具体一次激活(activation instance),并记入最小 effect ledger——诊断时能回答"这个 command / 面板 / 残留资源是谁创建的、停用后清理了没有"。

3. v0.1 精确范围

v0.1 的原则是:每一项进入范围的能力都必须同时具备 schema、fixture 和 headless 一致性测试;给不出测试的能力一律延期。

3.1 交付物

# 交付物 说明
1 dsh-plugin.json Manifest Schema 包根目录静态 JSON;顶层 $schema 必填。特意不叫 plugin.json——该文件名已被 Agent Plugins Specification 占用,一个包可同时携带两份文件支持两套生态
2 Host Descriptor Schema 宿主机器可读自述:API 版本、实现的 capability 精确条目、执行环境与信任档位、平台
3 Capability / Event Registry 机器可读、带不可变 schema hash 的权威注册表;实现方不得从 RFC 正文自行发明"等价"名称;私有扩展用组织命名空间(x-org.example.*
4 能力协商器 纯函数:manifest × Host Descriptor → 兼容/拒载/待授权判定,不依赖 dsh 即可测试
5 生命周期 contract discover → validate → negotiate → authorize → activating → active → deactivating → disposed;以 runtime generation 为 scope 的 eager activation(v0.1 无按需激活);正常关闭 best-effort deactivate,插件清理必须设计为可重复
6 三项 capability storage.local(插件私有持久化);commands(仅 flat action leaf:一个全局 ID 对应一个 handler,无 command tree / 交互式 prompt / 流式输出);messages.observe不可修改的消息观察事件,带版本化 envelope:eventId、scope 内单调序号、privacyClass、裁剪摘要、不可变 payload)
7 Broker + 最小 effect ledger 注册归属 + append-only 转移记录(create / bind / replace / release / cleanup-failed),默认不写入消息正文与 secret
8 Conformance 套件 合法/非法 fixtures + headless 测试:协商、授权拒绝、激活顺序、异常捕获、重复激活、清理

3.2 版本模型

六个版本维度不得混为一个字段:插件自身 version / manifestVersion(结构)/ apiVersion(要求的 Host API 范围)/ capability & event contract 版本 / 宿主产品版本 / SDK 发布版本。v0 阶段按"minor 可能 breaking"的实验规则明确标注,不伪装稳定 1.x

3.3 验收标准

v0.1 从 Draft 晋级需要:至少两个独立宿主产品/集成(可共享同一个版本化 DSH Adapter,但 integration 与 descriptor 证据独立)与三个示例插件完成同一组 headless 场景。任何单一实现(包括 fabric 参考实现)都不是标准本身;一个行为只有写进规范文本 + fixtures + 一致性测试才算 contract。

宿主只能声称"通过 v0.1 Host conformance",插件只能声称"通过 v0.1 plugin validation"——都不能表述为"安全插件"或"官方认证"。

4. 明确不在 v0.1 的内容

以下每一项都在第二轮讨论中被确认"方向有价值,但硬塞进 v0.1 会埋雷",已拆为独立 Draft RFC 分别审查,不会暗中扩大 v0.1:

延期项 一句话原因 归属
可修改 / 可取消的 before-* 事件 多插件顺序、合并、timeout、回滚、隐私裁剪、审计一个都没定义;给 listener 起个 before 名字不解决任何问题 后续独立 RFC
Runtime / Presentation / Control / Transport 分层、command tree、短期交互消息 Remote SSH 反例证明 isRemote / hostType 字段是错误抽象:执行位置、界面能力、授权方是三个独立维度;presentation capability 必须逐次调用快照传递 RFC 0002
插件间 service(provides / requires.services)与确定性组合 需要先定义 provider cardinality、用户选择、冲突计划、健康与替换;否则又回到"加载顺序仲裁" RFC 0003
安装影响预览、验证报告、完整溯源 证据必须分级(declared / resolved / decided / observed / tested / attested)且绑定不可变 artifact digest,防止市场把"格式检查通过"展示成"安全" RFC 0004
按需激活 第二套生命周期 + 首次并发竞态 + 延迟失败,先用 eager activation 拿到可验证的基线 后续基于测量提案
隔离执行 / 沙箱 见原则 4;没有隔离证据的宿主不得声称权限被技术强制 后续独立 RFC
跨端声明式 UI(ui.panel.basic 之外)、net.* / fs.* / 会话写入 敏感能力需要各自的授权 UX、scope 与资源限制 contract 各自独立 RFC
市场认证、lockfile / 组合包规范、迁移工具 属于 packaging / distribution 层 后续提案
运行时 mixin(dsh-neoforge PoC) 有价值的冲突检测与清理证据,但 manifest 永不携带可执行 mixin 指令,私有 target 永不成为可移植 API Adapter 实验,长期封顶

5. 与 dsh 官方的关系

5.1 我们不请求什么

  1. 不请求修改内核或立即采纳本标准。 标准在社区侧先跑通;官方现有的 package manifest、Cordis service、slot、profile 组合机制原样继续工作。
  2. 不请求移除或冻结任何现有加载路径。 Fabric-managed 插件走标准入口,非 Fabric 插件与内置扩展在迁移期是明确的产品边界,不受影响。
  3. 不代表官方发声。 所有文档均标注"社区标准、非官方";一致性表述有明确边界(§3.3)。

5.2 我们请求什么

  1. 观察点变更的可见性。 Adapter 是整个体系里唯一吸收上游变化的层,它需要的不是"上游别变",而是"变了能知道"。请求:session / message / tool 调用等核心业务事件的观察点发生变更或移除时,在 changelog 或 release note 中标注。这是成本最低、对生态稳定性收益最大的一项。
  2. 命名空间确认。 请求确认:包根目录 dsh-plugin.json 文件名、dsh-* capability 命名前缀不与官方现有或近期规划冲突;Capability / Event Registry 中为官方保留命名空间(未来官方能力可直接以一等身份入驻)。
  3. 参与治理,深度自选。 治理 RFC(RFC 0000:评审期、决策方式、异议流程、breaking change 与弃用窗口)正在起草。官方可以以观察员、评审者或共同维护者任意身份参与;也欢迎对 v0.1 的三项 capability 选择与 messages.observe 的 payload 字段边界直接给意见——这是当前最需要官方视角的两个具体问题。

5.3 对官方的价值

  • 3,809 个插件仓库背后的 patch 与内部接口依赖,目前每一次都由官方更新"背锅"。互操作层落地后,上游迭代的生态阻力显著下降——兼容压力从"官方 vs 所有插件"变为"Adapter 一个点"。
  • 兼容信息静态化后,市场与启动器能在安装前给用户明确预期,"装上就炸"类负面体验不再归因于 dsh 本体。
  • 标准由社区治理并承担维护成本;官方在任意时点采纳的成本都很低(映射一层 Adapter),且不采纳也不受损。

6. 落地计划

阶段 内容 状态
Phase 0 标准基础 治理 RFC 0000;Manifest / Host Descriptor Schema;Registry;fixtures;纯函数协商器;headless 测试骨架 文档就绪,schema 冻结中
Phase 1 受信任参考 Adapter 单一 Node.js 宿主环境;完整生命周期;Broker 归属 + 最小 ledger fabric 侧启动(dsh 与 fabric 启动解耦已在进行)
Phase 2 事件与最小贡献点 messages.observe + storage.local + flat commands;故障 / 重复 ID / 取消 / 关闭 fixtures;两宿主 × 三插件互操作证据 三端维护者已认领 integration

参考实现与全部文档:dsh-community-fabric(MIT)。新评论不会静默改写 Draft;变更先过 RFC 审查,再更新处置记录,反馈链路闭合可追溯。


附录 A:第二轮讨论(issue #23 评论)处置摘要

完整逐条记录见意见审查文档。摘要:

意见 处置 落点
plugin.json 与 Agent Plugins 规范冲突 已采纳 改名 dsh-plugin.json
借鉴 K8s 的 type metadata / 带版本 service 限定采纳 六维版本模型,不照搬整套 resource 语义
patch 震荡与可信验证需求 已采纳 RFC 0004 证据分级;格式检查 ≠ 安全
多 Panel Web UI 的 URL state 不属于可移植核心 归 Web Presentation capability,不强加给 TUI
安装前影响预览 + 运行时溯源 已采纳 RFC 0004:影响报告 / 验证报告 / effect ledger
dsh-neoforge 运行时 mixin PoC Adapter 实验 证据有价值;私有 target 不进插件 API
静态验证 / registry / contribution ID / 迁移信息 限定采纳 RFC 0001:静态 JSON、权威 registry、确定性 ID
dsh-TUI 认领早期一致性实现 限定采纳 欢迎证据;但实现不能自我认证,before-* 仍不进 v0.1
Remote SSH 反例 / command tree / invocation capability 独立 RFC RFC 0002 五概念分层
Reference Host 与可 attach 拓扑 限定采纳 RFC 0002 定义分层与 conformance,不指定唯一产品架构
依赖锁定与可复现性 独立 RFC RFC 0004 记录不可变 artifact;lockfile / modpack 归 packaging 提案
requires / provides / contributes 确定性组合 已采纳 RFC 0003:cardinality、选择、冲突计划;加载顺序非仲裁

注:"已采纳"表示被当前 Draft 文档采纳,不表示 issue #23 参与者已形成正式共识——正式共识由治理流程产生。

附录 B:原文索引

涉及资产与授权

受影响群体及安全、权利、速度风险

替代方案、可逆性与回滚

利益冲突

建议负责人和复审日

公开记录

  • 我理解相关控制者确认前它可能始终只是提案。

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposalCommunity governance proposal / 社区治理提案

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions