Files
Agent-System-Documents/docs/proposals/2026-10-05-ext-1-inproc-command-handler.md
weichen a1be057b19 Add EXT-1 inproc command handler proposal; align tag name to v0.2.0
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)
2026-10-06 14:42:57 +00:00

3.9 KiB
Raw Permalink Blame History

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 与 manifest provides.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)。