Compare commits

..
Author SHA1 Message Date
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
weichen 4e57196a8e Merge pull request 'Add architecture guides with worked examples' (#48) from feature/architecture-guides into main 2026-10-08 09:37:36 +00:00
2 changed files with 167 additions and 0 deletions
@@ -0,0 +1,166 @@
# 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)。
+1
View File
@@ -74,6 +74,7 @@ Dev 链接均指向对应任务 PR,可从其任务卡继续追溯组件 PR;
| [N2 实施案](2026-10-07-agent-stack-n2-plan.md) | 栈总案 N2 的六 WP:上下文、协议、工具、skills、子代理、装配 | 未单列确认状态及 owner;正文称 N2 开工 | Documents [#42](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/42) 已合入;Dev [#244](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/244) 已合入(merge `7e3ba10`),闭卡 [#247](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/247)。卡内自述六 WP 落地;本索引未重放 |
| [N3 实施案](2026-10-07-agent-stack-n3-plan.md) | 栈总案 N3:持久与可观测 | 页首未单列确认状态及 owner;正文称 N3 开工 | Documents [#43](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/43) 已合入;Dev [#248](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/248) 已合入(merge `2836a87`),闭卡 [#249](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/249)。卡内自述六 WP 落地;本索引未重放 |
| [Q2/Q3 实施案](2026-10-07-agent-stack-q2q3-plans.md) | 栈总案 Q2 拓扑与 Q3 收敛互通 | 页首未单列确认状态及 owner | Documents [#44](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/44) 已合入;Dev [#250](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/250) 采纳方案,[#251](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/251)(merge `452c00a`)与 [#253](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/253)(merge `c8ce4eb`)已合入。卡内自述 Q2/Q3 落地;本索引未重放 |
| [EXT 申请包 C1–C7](2026-10-08-ext-c1-c7-rdm-shared-contracts.md) | RDM 多人共享契约的基座最小扩展申请(EXT-6…EXT-12):身份停用/受管配置/授权适配器/索引发布/分发守卫/Host 工厂/投影过滤 | proposed;需求依据=RDM U0 主记录(D1–D9 裁定,2026-10-08 合入) | 随本提案 PR;每条现状证据为 SELF·源码级(Dev 34a2bbe/backend fe7c245),运行态 NOT_RUN;受理后逐条另立实现任务 |
原查询的 19 份原文中,14 份显式标注 owner 为 weichen。双档存储、启动配置面、跨会话读取、文件预览和
N2 实施案这五份未单列 owner,其中预览案仅写“作者:weichen + Agent”。同步新增的 N3 与 Q2/Q3 案页首也未单列 owner。