Why: independent review returned PASS-with-fixes with eight non-blocking clarifications. Evidence: review session fdb9367a (fresh, docs-only input), base2b7fdc3head5a7a0da. Impact: docs and task card only. Refs: docs/superpowers/specs/2026-10-19-fast-slow-o2-route-contract-eof-design.md Co-authored-by: Cursor <cursoragent@cursor.com>
7.2 KiB
7.2 KiB
快慢通道 O2:限路由等价终态 阶段 5 实施与测试计划
- 状态:阶段 5 计划稿,待人审(与阶段 4 方案同批评审)。人审通过前不派 worker、不改产品代码。
- 日期:2026-10-19;作者:host;来源等级:SELF。
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md);worker 不提交、不推送、不开 PR;host 负责范围审阅、权威验证、PR/CI/合入。
- 付费与真实模型:本计划零付费部分不需要任何付费请求;P1 付费验证另提资源方案并单独批准。
1. 交付切分与顺序
| 增量 | 仓 | 内容 | 依赖 | 合入方式 |
|---|---|---|---|---|
| I1 | Agent-Native | runtime/argschema 提炼 + 解析器延后判定 + RouteContractEOF 传输层判定 + 夹具 |
无 | 组件仓 PR,CI 通过后合入(组件仓无需 #518 窗口) |
| I2 | Backend | 系统层设置键、openLLMClient 按身份挂合同、运行记录透传 CompletionBasis |
I1 合入且 Backend deps/agent-native 改钉 |
组件仓 PR |
| I3 | Dev | 改钉 Agent-Native 与 Backend,组合验证 make test |
I1、I2 | #518 窗口合入 |
| P1 | — | 1 次短工具探针 + 1 次 A01(付费) | I3 合入、资源方案获批、系统层配置写入 | 另行授权 |
各增量阶段 6 评审包写入 docs/superpowers/specs/;I1–I3 每个增量完成后先交用户阶段 6 再合入(与快慢通道既往 manual 口径一致)。
2. I1 Agent-Native(单元 o2-i1-agent-native-route-contract)
- 允许路径:
runtime/llm/**、runtime/argschema/**(新)、runtime/tools/registry.go、runtime/tools/registry_test.go。 - 动作:
- 新包
runtime/argschema:Validate(schema, args json.RawMessage) error,整体迁移现validateArgs与matchesType,语义逐项相同;registry.validateArgs改为委托,现有 registry 测试不改断言。 - 解析器:内部选项
deferMissingDone;新增计数finishChunks、标志toolAfterFinish。只有在“除缺[DONE]外全部现有检查通过”时才返回候选终态,否则行为同今。公开ParseSSE签名与零值行为不变。 - 传输层:
Client.RouteContract;在bodyObserver快照后按方案 §4.2 的 C1–C9 判定;放行发message_end(CompletionBasis=route_contract_eof,StreamComplete=false),拒绝发与今天相同文案的终态失败并附ContractCheck。 Event/TerminalObservation新增CompletionBasis、ContractCheck(JSON 字段名completionBasis、contractCheck)。
- 新包
- 测试(
httptest;HTTP/2 用httptest.NewUnstartedServer+EnableHTTP2+ TLS):
| 用例 | 期望 |
|---|---|
有 [DONE](合同开/关) |
放行,CompletionBasis=done_marker,与现状一致 |
无 [DONE]、合同关 |
拒绝,文案不变 |
无 [DONE]、合同开、HTTP/2 正常结束、全部条件成立 |
放行,route_contract_eof,工具调用逐字节等于输入 |
同上但 known_length+match / mismatch |
依人审 §6.1 结论放行 / 拒绝(C2) |
close_delimited、chunked、unknown |
拒绝(C2) |
| 缺 Usage | 拒绝(C5) |
Usage 在 finish_reason 块之前 / 之后 |
均放行(顺序不作要求,评估稿 §3) |
两个非空 finish_reason 块;finish_reason=stop 或 length 却有工具;一块含多个 choice |
拒绝(C4) |
在帧边界截断、无 finish_reason,但 HTTP/2 正常结束 |
拒绝(C4) |
HTTP/2 RST_STREAM 或连接中途断开导致读错 |
拒绝(C3) |
与 finish_reason 同一块内的工具片段 / 后续块再出现工具片段 |
放行 / 拒绝(C6) |
| 合同开但任一条件不满足 vs 合同关 | 两个终态事件除 contractCheck 外 deep-equal |
| 哨兵扫描 | contractCheck、completionBasis 不含正文、工具名、参数或错误原文 |
| 半帧 / 无效帧 / 供应商错误帧 | 拒绝(C3/C9) |
| ID 或名称缺失、参数非 JSON 对象 | 拒绝(C7) |
工具名不在请求 tools;缺 required;属性类型不符 |
拒绝(C8) |
模型名不符、基址不符(含 http、userinfo、query)、摘要不符、APIBase 覆盖到他址、重定向(他主机、同主机改路径、降级) |
拒绝(C1) |
| 读取中取消 | 中止事件,无放行 |
每个用例同时断言 Usage 保留与“放行次数/工具调用数”。
- 验证:
gofmt -l runtime;go vet ./runtime/...;go test ./runtime/llm/... ./runtime/argschema/... ./runtime/tools/... -count=1;git diff --check。 - 停止条件:若延后判定需要改变公开
ParseSSE的零值行为或既有测试断言,停止并回到方案评审。
3. I2 Backend(单元 o2-i2-backend-route-contract-config)
- 允许路径:
internal/runtime/**、internal/settings/**、internal/runmgr/**(仅透传字段)、Backenddeps/agent-nativegitlink(host 改钉,不由 worker 改)。 - 动作:
settings.Schema()以SettingScopeSystem声明三个扁平键models.routeContractEOF.model/.baseUrl/.identitySha256(任一为空即关闭;用户/项目层由ManagedPaths剥除);openLLMClient增参ResolvedModel与配置,三元组与摘要全部精确一致才挂合同(按三元组、不看Kind),5 个调用点llm.go、sub_loop.go、squad_runner.go、verify.go、workflow_compiled.go全部覆盖;轻量档、视觉改模、子代理独立判断;运行记录与快慢通道收据透传completionBasis。 - 测试:缺省关闭;用户层写入被忽略;模型/基址/摘要任一不符不挂合同;视觉改模后不继承;挂合同后假流放行一次工具并记录
route_contract_eof;删除配置后恢复拒绝。 - 验证:
gofmt;go vet ./internal/runtime ./internal/settings ./internal/runmgr;go test ./internal/runtime ./internal/settings ./internal/runmgr -count=1。
4. I3 Dev 组合
- host 改钉
deps/agent-native(I1 合入 SHA)与modules/backend(I2 合入 SHA);make test+make build由 PR CI(GATE)确认;无产品代码改动。 - 注意与同期 IAM 链路 initiative(Dev #628)对 Backend gitlink 的合入顺序:以合入时最新 main 为准重新组合验证,冲突由 host 选择包含双方的 Backend SHA,不回退对方提交。
5. P1 付费验证(不在本计划授权内)
- 前提:I3 合入;系统层配置写入目标路由三元组;核对 r0.6 证据身份(受保护路由文件 SHA-256
2a92569d…)与生产三元组指向同一模型/基址。 - 内容:1 次短工具探针(预期约 500 tokens,参考 r0.5/r0.6),期望
route_contract_eof放行且工具执行恰好一次;通过后 1 次 A01,规模参考 r0.4。 - 另提资源方案(预算上限、停止条件、收据路径),用户批准后执行;失败即停、不补跑。
6. 完成与停止
- 零付费完成:I1–I3 合入,夹具全绿,配置缺省关闭时线上行为不变(以既有
[DONE]与拒绝用例为回归证据)。 - 停止并回到方案评审:需要改变
StreamComplete语义、泛化到其他路由、或任何条件无法在本地确定性观察。