Why: RDM G1/G2 are blocked on four base capabilities - the member agent cannot see published project knowledge inside a run, plugin commands are unreachable as tools, members cannot see or open conversations in shared projects, and the isolated exec tier needs a backend seam. Evidence: SELF - code citations verified at Dev main (runmgr.go:726-736 owner-only Retrieve; hostcaps.go:64-66 owner-only search; server.go:438-441 owner-only listProjects; store/projects.go:124-130 owner-scoped conversation creation); bwrap availability tested on this host (2026-10-09). Impact: Docs only. New proposal docs/proposals/2026-10-09-ext-g1-b1-b3-exec-backend.md registering EXT-13..EXT-16 per the compat-policy template; no code change. Refs: RDM plan V1.1 sections 3.3/3.4/5.3; owner Q1-Q8 (Q4=option A, Q2)
10 KiB
10 KiB
EXT 申请包 · G1:回合内共享检索、命令即工具、项目列表共享与执行后端接口(B-1/B-2/B-3 + B-5②)
状态:proposed(2026-10-09);owner:weichen;需求依据 = RDM 评审与实施方案 V1.1
(Agent-System-RDM docs/proposals/2026-10-09-V22-review-and-implementation-plan.md §3.3/§3.4/§5.3,
owner 2026-10-09 Q1–Q8 批复;Q4=方案 A,Q2=暂时禁用+隔离档)。
撰写日期:2026-10-09。配套:扩展面兼容与演进、
EXT 申请包 C1–C7(EXT-6…EXT-12)。
0. 总则
- 本包四条申请按既有序列顺延 EXT-13…EXT-16;最终编号以受理评审为准。
- 分期(对齐 RDM 方案 §5.2):B-1(EXT-13)与 B-3(EXT-15)为 G1 序 4 的硬前置
(成员智能体看不到项目知识 = R04 路径不通);B-2(EXT-14)为 G2/V0.1 端到端的硬前置
(对话入口无法触达
rdm.*);B-5②(EXT-16)为 G2-8 原型的前置。 - SurfaceVersion 影响:EXT-14 触及
pkg/extension导出面(命令规格新字段)→ 需升 SurfaceVersion 并同步 surface.txt;EXT-13/15/16 为 internal 行为扩展,不改导出面 (EXT-16 若只加Options字段则属加法,见 §4)。
1. EXT-13(←B-1)回合内共享检索:智能体的检索遵循项目共享授权
- 场景:RDM R04/R05——成员 B 的智能体在回合内(ReAct 循环的
knowledge_search工具与自动知识注入)必须能检索到成员 A 已发布的项目知识;现状只能看到本人 owner 的 知识。HTTP 面(/api/…/search)已走RetrieveShared(EXT-8 余项,Dev #269/#273), 但回合内两条路径仍是 owner-only:internal/runmgr/runmgr.go:726-736runCtx.Retrieve→retriever.Retrieve(ctx, c.run.Owner, q)(owner-only);internal/app/hostcaps.go:64-66hostcaps.search(进程内Host.KnowledgeSearch底座)→pipe.Retrieve(owner)(owner-only)。 结果:同一个成员,页面搜索能看到共享知识,智能体对话里看不到——「所有用户的智能体 应当能够看到项目级的共享信息」(用户补充材料 §2树1图)走不通。
- 希望公开面:组合根把 EXT-8 适配器(
Server.ProjectAuthz同款判定函数)注入 runmgr 与 hostcaps:两条检索路径在本人 owner 两路(全文+向量)如常之外,追加 「经适配器放行的共享两路」——与 HTTP 面rag.Pipeline.RetrieveShared完全同一实现与 同一授权判定(复用sharedVisible/SearchKnowledgeShared,不另造第二套语义)。 进程内Host.KnowledgeSearch同步走共享版。 - 为何组合不出:
RetrieveShared已存在,但 runmgr/hostcaps 没有适配器的引用—— 适配器槽在internal/app/hostcaps.go的projectAuthz,由组合根在装载扩展后注入 Server;runmgr 的构造早于扩展装载,且Manager无该依赖。下游无法经任何公开面把 「按 owner 判定共享」的回调递进回合执行路径。 - 兼容方式:适配器未注册=现状(本人两路);注册后共享命中追加、RRF 融合。
不动
pkg/extension导出面,SurfaceVersion 不变。 - 验收:同项目两人+另一项目一人(RDM 成员表桩):成员 B 发起对话,模型经
knowledge_search命中 A 已发布的知识切片(共享命中出现在工具结果);未授权者与 跨项目者为零命中;Host.KnowledgeSearch(hostapi 与进程内两形态)行为一致; 未注册适配器时与现状逐字节一致(回归)。
2. EXT-14(←B-2)插件命令即工具:exposeAsTool(Q4 方案 A)
- 场景:RDM V0.1 端到端(C-11)要求「从空项目创建到生成项目建议书,全对话完成」;
RDM 的全部能力(两树一网读写、上传、起草、追溯查询)都登记为
rdm.*命令,而智能体 回合的工具清单里没有任何插件命令——模型既不能检索笔记树,也不能发起rdm.draft.compose。 U0 §3.3/方案 §3.3 裁定走方案 A:命令经命令总线暴露为工具,四入口同源 (button/card/slash/chat)自然延伸出第五入口「智能体」。 - 希望公开面:命令规格(
agentcommand.CommandSpec经Registry.AddCommandHandler登记的 JSON)新增可选字段"exposeAsTool": {"risk": "low|medium|high"}(缺省不暴露)。 runmgr 装配工具清单时,把带该字段的命令投影为工具描述(名称=命令 id,参数=命令 paramsSchema);模型调用该工具时,不分发为工具执行,而是构造cmdbus.Request经 命令总线分发(Entrance="agent",Actor=会话 owner,ConversationID=当前会话)—— 同一审计信封、同一 HITL 内联确认卡(risk=high或命令规格要求确认时照常弹卡)、 同一危险分级。 - 为何组合不出:
Registry只有 AddSkill/AddCommand/AddCommandHandler/Note/ RegisterResourceAuthorizer;工具注册表(tools.Registry)与命令总线之间没有任何 桥接;MCP 通道(方案 B)绕过命令总线与确认卡,与 SR-E6/HITL 门禁冲突,已被 Q4 否决。 - 兼容方式:
pkg/extension命令规格加可选字段=导出面加法,SurfaceVersion 升 (建议 2.6.0-experimental)+ surface.txt 同步。缺省(不写 exposeAsTool)=现状零差异。 - 验收:带
exposeAsTool的/rdm.ping出现在模型工具清单且调用返回回执, 审计信封 Entrance="agent" 与按钮入口同源;risk=high的暴露命令在对话内触发内联 确认卡;不带字段的命令不出现;RDM 侧rdm.trace/rdm.baseline等只读命令可在 回合内被模型调用(成员 B 场景结合 EXT-13)。
3. EXT-15(←B-3)项目列表与建会话的共享放行(SR-G10)
- 场景:RDM R03——成员 B 被加入项目后「界面自动出现该项目,可直接开始工作(新建
对话)」。基座
projects表按 owner 硬隔离(store/projects.go:22-34):GET /api/projects(server.go:438-441listProjects)只返回本人 owner 的项目——成员看不到共享项目;POST /api/projects/{id}/conversations(store/projects.go:124-130)校验「项目属于请求者」——成员在共享项目下建会话被 404。 EXT-8 已放行的入口(工件三入口、SSE 项目流、检索)不含这两处。
- 希望公开面:这两处入口在 owner 自有判定未命中时咨询同一 EXT-8 适配器:
listProjects追加经适配器放行的项目(去重、标注shared: true字段供前端区分 展示);CreateConversation的归属校验放宽为「本人自有 或 适配器放行」。会话 本身仍归属创建者(owner 不变),只是创建权扩展到成员。 - 为何组合不出:
ListProjects(owner)的 SQL 按 owner 过滤,无回调;建会话校验在 store 层硬编码。与 C4(EXT-8)同因:纯下游无法改变基座 owner 过滤。 - 兼容方式:未注册适配器=现状;放行结果带审计。internal 行为扩展,SurfaceVersion 不变。
- 验收:成员 B 的
GET /api/projects含共享项目(shared 标注)且不含未授权项目; B 在共享项目下POST conversations成功、会话 owner=B;撤销成员后两者立即拒绝; 项目拥有者视角无任何变化。
4. EXT-16(←B-5②)执行后端接口:隔离执行档(Q2 阶段二,G2-8 原型)
- 场景:Q2 裁定「暂时禁用,但后续执行任务时肯定还是要代码执行能力」。v0.2.0 已
交付启动级硬关闭(
Options.DisableExecTools,Backend #110);隔离档是恢复执行能力的 路径:执行的是模型生成的代码,须按不可信代码对待(方案 §3.4):只读系统根、仅挂 会话工作目录与技能目录、默认无网、cgroup 资源限额、硬超时、按项目 venv 只读挂载; 本机已实测bwrap --unshare-all可用(无特权 userns 被 AppArmor 限制,bwrap 专门 策略放行)。 - 希望公开面:
internal/tools/exec_interpreter.go的进程启动点抽象为「执行后端」 接口(ExecBackend:Run(spec) → result),启动参数选择后端:ExecBackend = direct | sandbox(缺省 direct=现状)。sandbox 后端以 bwrap 实现 (资源限额经 systemd-run/cgroup v2)。extension.Options增加ExecBackend string(加法;空=direct)。DisableExecTools保留为最终兜底,优先级 高于后端选择。 - 为何组合不出:现实现直接
exec.Command(runInterpreter),无后端抽象;沙箱 参数组装(bind 清单、网络命名空间、限额)属平台面,下游插件无法注入。 - 兼容方式:缺省 direct=逐字节现状;
Options加字段=SurfaceVersion 升。RDM 在 G3-7 才切换 sandbox;G1–G2 期间维持DisableExecTools=true。 - 验收:sandbox 后端下逃逸负例全部被拦——读
~/.secrets、读其他会话目录、访问 外网、fork 炸弹、超时不可杀均为拒绝/杀灭;会话工作目录内 docx 生成任务成功且产物 可登记;direct 后端与现状一致(回归)。
5. 不在本申请包(显式排除)
- EXT-6/7/10/12 完整形态:仍在 C1–C7 包(EXT-6…12)受理轨道,节奏不变。
- 提示词随执行可用性切换(
base.deliverables在禁用期的降级文案):基座自有任务, 不占 EXT 编号。 - UI 仓 nightly runner 修复:与代码无关(rolldown 原生绑定缺失),另立任务。
6. 受理建议
| 申请 | 内容 | 优先级 | 兼容 |
|---|---|---|---|
| EXT-13 回合内共享检索 | G1 序 4 硬前置(R04/R05) | P0 最先 | 不变(internal) |
| EXT-15 项目列表/建会话共享 | G1 序 4(R03/SR-G10) | P0 | 不变(internal) |
| EXT-14 命令即工具 | G2/V0.1 端到端硬前置(Q4 方案 A) | P1 | 升(加字段) |
| EXT-16 执行后端接口 | G2-8 原型(Q2 阶段二) | P1 | 升(加字段) |