Why: EXT-1 申请卡按 compat-policy §6 四要素成文,作为 surface 变更的提案记录;
compat-policy §5 的 v0.2.0-experimental 与 V1.2 定稿批复的 v0.2.0 口径不一致,统一为后者。
Evidence: 新增 docs/proposals/2026-10-05-ext-1-inproc-command-handler.md;§5 tag 命令改为 v0.2.0 并注明对齐来源。
Impact: 仅文档;下游与基座发版材料(12 号核对清单)按 v0.2.0 口径。
Refs: 2026-10-01-extension-compat-policy.md §5/§6;10-实施推进方案 V1.2 D2 批复。
(cherry picked from commit a47754b494)
3.9 KiB
3.9 KiB
EXT-1:进程内命令处理器与 owner 作用域宿主句柄(最小集)
状态:实施中(2026-10-05);owner:weichen;主任务:Dev 仓 feature/ext-1-inproc-handler(任务卡即本提案的申请卡)。
撰写日期:2026-10-05。配套:扩展面兼容与演进、基座路线图修正、V1.2 实施推进方案(批注 1 最小/完整集划分)。
1. 申请卡(compat-policy §6 四要素)
- 场景:Agent-System-RDM 的
rdm.ingest等命令经四入口(button/card/slash/chat)分发到cmdbus.Dispatch时被以no host handler bound拒绝——Registry.AddCommand与 manifestprovides.commands只注册规格不绑处理器;进程内插件同时没有任何 owner 凭证与基座服务端回调身份(H4)。 - 希望符号:
pkg/extension新增Request/Handler/Host(owner 作用域宿主句柄最小集)与Registry.AddCommandHandler(spec, h);基座侧配套cmdbus.Bus.RegisterPluginCommand。 - 为何现有注册点组合不出来:
RegisterPluginCommands仅登记 spec;HostClient走 sidecar HTTP 且需要进程内不可得的 host token;owner 作用域必须由基座在分发时构造,插件无法自造。 - 兼容:只加符号与方法,不改既有路径语义;
SurfaceVersion保持2.0.0-experimental,实验窗口内的接口调整以本提案为记录。
2. 公开面变更(surface.txt 12 → 15 项)
pkg/extension 新增导出符号 Handler、Host、Request(见 host.go);Registry 接口追加 AddCommandHandler 方法(方法不计入快照)。
依赖变化:根包自此 import agent-system-core 类型(KnowledgeDoc/RetrievalHit/Artifact/ID),此前为零外部依赖。声明式 Go 插件的 go.mod 需按 compat-policy §4 模板同时 require+replace agent-system-core。
3. Host 接口(最小集)
PluginID() / Owner()
KVPut / KVGet // 按 pluginID+owner 隔离
Audit(action, target, evidence) // owner 名下审计事件,Actor=plugin:<id>
Complete(ctx, prompt) // 经基座 LLM 路由(owner 模型配置生效)
KnowledgeSearch(ctx, projectID, text, topK)
KnowledgeWrite(ctx, docs, embed) // Owner 强制改写为本次分发 owner;Source 空则补 plugin:<id>;
// embed=false 只写全文,embed=true 建向量(失败降级纯全文)
TaskCreate / TaskUpdate // 后台任务台账(执行体由下游自跑)
ArtifactGet / ArtifactContent // 工件只读(R1-3 ingest 读原件)
artifacts 写入属完整集,R1-7 前再评估(V1.2 批注 1)。
4. 基座实现要点
cmdbus.Bus.RegisterPluginCommand(spec, h):登记规格(SourcePlugin)+ 绑定处理器;高危命令的内联确认卡拦截位于 handler 查找之前,插件命令天然覆盖。internal/app.hostcaps:聚合 store/检索管线/LLM 路由,同一实现同时服务 hostapi.Server 闭包与进程内inprocHost(批注 1:复用 owner 作用域函数,不新造句柄)。inprocHost每次分发按req.Owner新建,所有 store 调用以该 owner 为第一参数。rag.Pipeline.IndexChunks自IndexDocument抽出:写全文(回填 ID)后建向量,embed 失败降级语义不变。
5. 验证
- cmdbus:处理器被 Dispatch 调用返回 committed;仅登记规格仍 rejected(no host handler bound);高危插件命令先确认卡后执行。
- internal/app(组合根级):两 owner 各分发一次,审计/知识/KV/任务台账各落自己 owner 名下(D8 烟测的单元级前置);
provider=hash档KnowledgeWrite(embed=true)写出向量行且 Owner/Source 被强制改写。 examples/downstream-rdm增加rdm.ping处理器示范(读工件元数据 + 写审计)。- 权威验证源:CI 在 PR HEAD 上
make test+make build(.gitea/workflows/ci.yaml)。