Files
Agent-System-Documents/docs/proposals/2026-10-08-ext-c1-c7-rdm-shared-contracts.md
T
weichen 9995552152 Propose the C1-C7 base extension package for RDM shared contracts
Why: U0 (merged in RDM) rules that domain logic stays downstream and the base needs seven minimal generic capabilities; the formal four-element applications are the only legal path to base changes.
Evidence: All current-state citations re-verified at Dev 34a2bbe (backend fe7c245); RDM requirement source pinned at RDM main ca72cfc.
Impact: New proposal doc + one INDEX row; no code, no surface change in this PR.
Refs: RDM U0 proposal section 5 / ruling D1; extension-compat-policy; phase-plan section 3.3.
2026-10-08 14:44:56 +00:00

13 KiB
Raw Blame History

EXT 申请包 · C1–C7:RDM 多人共享契约的基座最小扩展(EXT-6…EXT-12)

项目 内容
状态 proposed(2026-10-08);owner:weichen;任务:Dev feature/ext-c1-c7-applications
性质 扩展点申请包(extension-compat-policy 流程第 2 步:基座侧评审)。本文只立申请,不实施;各 EXT 实现另立任务卡
需求依据 RDM 仓 U0 主记录 docs/proposals/2026-10-08-U0-baseline-and-shared-contracts.md §5 契约 C1–C7(RDM main ca72cfc 已合入,含 D1–D9 裁定);来源=用户 2026-10-08 会话批准的 U0 实施计划
现状证据 均为 SELF·源码级,引用对象:Dev 34a2bbe(backend gitlink fe7c245);RDM pin backend cb26e4c(v0.1.0)相同结论者已注明。运行态 NOT_RUN
编号 按既有序列(EXT-1/3/4/5 在案)顺延 EXT-6…EXT-12;最终编号以受理评审为准

0. 总则

  • 推荐路线(U0 裁定 D1,修订 V2.1 草稿 J-09「基座不改动」):领域规则(成员、角色、三权、 发布状态)住 RDM 下游仓;基座只补通用、无领域词汇的最小扩展面。每条申请遵守 INV-2: 基座代码与 diff 不出现 RDM 领域字样,全部以「资源授权/受管配置/投影过滤」等通用语义表述。
  • 事实依据(为何纯下游组合不出来):基座一切资源访问按 owner 硬边界 (internal/store/projects.go:22-34),EXT-1 Host 强制 owner 归属且无知识删除/更新 (pkg/extension/host.go:43-46、internal/app/hostcaps.go:101)。RDM 增加成员表不能改变 基座过滤;给每人复制知识库被 U0 §4 明确禁止。
  • SurfaceVersion 影响:EXT-6/7/9 触及 pkg/extension 导出面(Registry/Options/Host 方法), 属加法变更——按 extension-compat-policy 升 SurfaceVersion(2.0.0-experimental 内加法, surface.txt 同步);EXT-8/10/11/12 为 internal/HTTP 行为扩展,不动导出面。
  • 分期建议(对齐 U0 §10):EXT-8(授权适配器)与 EXT-9(索引发布)为序 4「项目范围与 授权基础」的硬前置;EXT-6/EXT-12 支撑序 4–5;EXT-7/EXT-10 可随后。EXT-8 建议最先评审。
  • 通用默认不变量:每条扩展的缺省行为=现状(未注册/未配置时与今日基座完全一致), RDM 产品部署显式启用;通用基座与既有下游不受影响。

1. EXT-6(←C1)可信身份:账号停用与会话吊销

  • 场景:RDM R01 唯一管理员移交后旧凭证须立即失效;成员移除同理。现状基座账号只有 创建/改密/列表(internal/server/accounts.go:184-261),无停用语义,撤销账号后其 API key 与会话仍有效到自然过期。
  • 期望公开面:①POST /api/admin/users/{owner}/disable|enable(requireAdmin 保护); ②users 表加 disabled 布尔(迁移,default false);③认证链(API key 校验与会话校验, internal/server/auth.go:29-64)与 requireAdmin 拒绝 disabled 账号并吊销其在途会话。 「全局唯一管理员」由 RDM 产品策略约束(部署约定+台账),不强制基座单管理员。
  • 为何组合不出:无任何现有端点或设置键能改变账号认证状态;RDM 无法经 EXT-1 Host 触达 认证层(Host 无账号域能力,也不应有一—属平台面)。
  • 兼容方式:纯加法(新端点+新列 default false);未停用=现状。SurfaceVersion 不变 (不动 pkg/extension)。
  • 验收:停用后该账号 API key 与 cookie 即刻 401;管理员功能不受影响;启用可恢复。

2. EXT-7(←C2)受管系统配置:最终生效值受策略约束

  • 场景:RDM R01——模型端点/密钥、工具上限、系统插件由管理员控制;个人偏好保留。现状 设置链 defaults → system(启动注入) → user → project(internal/settings/settings.go:131-147), user/project 可覆盖一切;system 层不落库且组合根只注入 dataDir (internal/app/app.go:130)——只藏设置页或只禁今后写入都处理不了既有覆盖。
  • 期望公开面:①extension.Options 增受管注入:ManagedSettings map[string]any(键集+ 值,由宿主二进制启动注入);②设置服务按受管键集跳过 user/project 覆盖(Effective 尊重 策略);③受控键的 user/project 写入返回结构化拒绝并附依据;④GET /api/settings 标注 哪些键受管。RDM 在自有二进制 main 里以管理员配置注入。
  • 为何组合不出:Options 无注入口;SetSystemOverride 是组合根私有;下游无法让 Effective 忽略 user/project 的既有覆盖。
  • 兼容方式:ManagedSettings 缺省 nil=现状(无受管键,行为不变);pkg/extension Options 加字段=导出面加法,SurfaceVersion 与 surface.txt 同步升。
  • 验收:预置 user 覆盖的受控键,注入策略后生效值=受管值;普通用户写受控键被拒且 GET /api/settings 可解释;未受管键的个人偏好不受影响。

3. EXT-8(←C4)资源授权适配器:项目共享的读取通道 ⭐关键路径

  • 场景:RDM R03/R04/R05——成员 B 依 RDM 成员表读取成员 A 提交的项目资料(工件原件、 检索、引用、下载、图查询);撤销后停止。现状一切资源入口按 owner 过滤 (internal/store/projects.go:22-34;工件/知识/卡片同理),Host 读取族同样强制本人 owner(pkg/extension/host.go:43-46)。
  • 期望公开面:①基座提供授权适配器注册点(HTTP 组合根):RegisterResourceAuthorizer( func(owner, resourceProjectID core.ID) (allow bool, err error)) 形态的进程内回调,经 extension.Options 或 Registry 注入(具体挂点评审定);②资源入口(项目/工件/知识检索/ 卡片读取的 HTTP 层与 Host 读取族)在 owner 自有判定未命中时回调适配器:返回 true 则按 「项目共享」放行,false/未注册=现状 NotFound(不泄露存在性);③适配器只回答布尔, 不接触基座内部状态;④放行日志入审计(owner×resource×decision)。
  • 为何组合不出:owner 过滤在 SQL 层硬编码;无任何回调或配置可改变跨 owner 可见性; 回环 HTTP 模拟他人身份被认证中间件阻止(V1.1 教训,10 号方案已证)。
  • 兼容方式:未注册适配器=现状零差异;回调失败按拒绝(fail-closed)。pkg/extension 加法→SurfaceVersion 升。注意:本 EXT 使基座首次具备跨 owner 授权读取语义,评审须 重点核对回调契约的最小性(仅 owner×projectID 两参,不透出对象细粒度——细粒度由 RDM 在自己的命令层做)。
  • 验收:同项目两人+另一项目一人(RDM 成员表桩):共享资源四入口(原件/检索/引用/下载) 一致放行;跨项目与替换引用拒绝且 NotFound 不泄露;撤销成员后新访问立即拒绝;审计可查。

4. EXT-9(←C5)索引发布与撤销:留存 ≠ 可检索

  • 场景:RDM R07——存疑资料确认前不得进入任何正式检索;发布有稳定版本、撤销即时生效。 现状基座上传端点在下游相关性判定之前即写检索索引 (internal/server/server.go:1039-1046;RDM pin 相同);Host 知识面只有 KnowledgeWrite(强制 owner),无删除/更新(pkg/extension/host.go:43-46)。
  • 期望公开面:①基座上传预索引开关(Options 或项目设置键 uploads.autoIndex,缺省 true=现状;RDM 部署关闭,索引决定移交其命令层);②Host 增 KnowledgeDelete(owner, sourcePrefix string, versions …) / KnowledgeUpdate(或等价发布令牌语义:写入带稳定 PublishID,删除按 PublishID 幂等);③删除仅作用于插件来源(Source 前缀 plugin:<id>),公共 manual 来源不可被插件删。
  • 为何组合不出:检索索引无删除面;上传索引行为硬编码;RDM 无法撤回已入索引的存疑内容。
  • 兼容方式:开关缺省现状;Host 删除方法为导出面加法(surface.txt/SurfaceVersion 同步)。
  • 验收:相关/存疑/拒绝三份样本:仅获准发布版本可检索;重试不重复建索引;撤销后检索与 上下文注入立即停止(含 Host 读取族);manual 来源不可删。

5. EXT-10(←C3)分发前校验钩子与会话归属

  • 场景:RDM R18——对话/按钮/卡片/API 四入口同源且对象-会话-项目关联可校验;旧卡片/ 重复确认不得操作新版本。现状 POST /api/commands/{id} 不校验 conversationId 归属 (internal/server/server.go:823-836),确认卡锚定客户端自报会话 (internal/cmdbus/cmdbus.go:294-316);插件命令注册不写 slash 别名,对话入口不可达 rdm.*(cmdbus.go:145-153,v0.1.0 与 main 同——阶段总案 §2.3 已登记)。
  • 期望公开面:①分发前校验钩子:RegisterDispatchGuard(func(owner, conversationID string) error)(未注册=现状放行;RDM 注入「会话属该项目且属于该 owner」判定);② RegisterPluginCommand 增可选 slash 别名参数(或 manifest 字段),对话入口 /rdm.* 可解析;③别名与 intents 命中路由到插件命令的打通(阶段总案既有缺口,并入本 EXT 或 单列由评审定)。
  • 为何组合不出:execCommand 对 conversationId 零校验也无回调点;slash 表只由内置与 用户命令登记写入(cmdbus.go:109-127),插件路径不写。
  • 兼容方式:钩子/别名均缺省=现状;internal 行为扩展为主(Registry 签名若变则属 pkg/extension 加法,SurfaceVersion 升)。
  • 验收:伪造他人会话/项目引用的命令被拒;/rdm.ping 在对话入口可达且回执与按钮入口 同源(同一审计信封);陈旧卡片确认不生效(既有 ErrNotAwaiting 之上叠加对象版本校验)。

6. EXT-11(←C6)按 owner 重建受限 Host:后台任务恢复

  • 场景:RDM R10/R21——慢任务跨重启不丢不重;撤权后不越权续跑。现状 RDM 慢通道是进程 内存队列并把分发时 Host 句柄留在队列(RDM internal/rdmapp/slow.go:53,66,重启即丢、 撤权不重验);基座任务台账仅记账(pkg/extension/host.go:48-50)。
  • 期望公开面:基座侧缺口小——提供「按 owner+pluginID 构造受限 Host」的公开工厂 (如 extension.NewScopedHost(owner, pluginID) 形态或 Registry 上的查询),供下游在 恢复任务时重建执行上下文;任务体、输入版本、幂等与重验策略由 RDM 自管(U0 §7)。 不序列化旧 Host——重建受限上下文,天然以当前权限为准(配合 EXT-8 的授权适配器, 撤权即拒绝)。
  • 为何组合不出:inprocHost 是 internal 类型按分发请求私有构造 (internal/app/compiled.go:42);下游无任何入口可在分发期之外获得合法句柄。
  • 兼容方式:纯加法工厂函数;不改变分发期语义。pkg/extension 加法→SurfaceVersion 升。
  • 验收:下游以工厂重建的 Host 执行读/写,owner 作用域与分发期一致;重启后同任务不重复 执行(RDM 侧幂等)+ 撤权后重建 Host 的读取被适配器拒绝。

7. EXT-12(←C7)卡片/事件投影过滤:私人事件与公共投影分离

  • 场景:RDM R04/R18——私人会话卡不得进项目公共流;公共投影只含获准发布的状态;撤权 后重放不泄露。现状会话卡全量镜像到项目频道(internal/cardsvc/cardsvc.go:41-60, 注释自述「全量镜像换取口径简单」)——单 owner 下无害,多人项目即隐私泄露路径。
  • 期望公开面:卡片镜像策略可配置:①按卡属性过滤(kind/来源)的内置开关,或②复用 EXT-8 适配器语义的投影可见性回调(func(owner, card) bool)——评审择一,倾向①最小。 RDM 部署关闭会话卡镜像,只用项目级卡承载公共投影。
  • 为何组合不出:emitCard 镜像逻辑硬编码;无配置面。
  • 兼容方式:缺省=现状全量镜像;internal/设置键扩展,不动导出面。
  • 验收:关闭镜像后会话卡仅出现在本人会话流;项目流只含项目级卡;既有单用户部署行为 不变;SSE 重放遵循同一过滤。

8. 不在本申请包(显式排除)

  • 需求条目化/模板/法规双通道/三权流程等 RDM 领域能力(U0 §2 R08–R16)——全部住下游。
  • 飞书渠道 EXT-3:既有在案申请,节奏不变(MS4 前)。
  • 命令审计跨租户修复:不是扩展,是缺陷修复,已另行(Backend PR #104 + Dev PR #262)。

9. 受理建议

EXT 前置的 U0 序 建议评审优先级 SurfaceVersion
EXT-8 授权适配器 序 4 硬前置 P0 最先 升(加法)
EXT-9 索引发布/撤销 序 4 硬前置 P0 升(加法)
EXT-6 账号停用 序 4–5 P1 不变
EXT-11 Host 工厂 序 4 P1 升(加法)
EXT-10 分发守卫/别名 序 3 剩余半边(基座侧) P1 视形状
EXT-7 受管配置 序 4–5(R01) P2 升(加法)
EXT-12 投影过滤 序 5 P2 不变

每条受理后按 extension-compat-policy 走「基座任务卡实现→发版→RDM 升钉」;预计随 v0.2.0 之后的 v0.3.x 分批落地(对齐 RDM 阶段总案 §3.3 与风险 R-5)。