Why: user passed stage 6; Backend #224 merged. Evidence: Backend merge c164950, tree equals verified head 16f98b8 Impact: task card and review package only. Refs: docs/superpowers/specs/2026-10-20-fast-slow-o2-i2-review.md Co-authored-by: Cursor <cursoragent@cursor.com>
5.4 KiB
5.4 KiB
快慢通道 O2 I2(Backend route_contract_eof 配置与挂载):阶段 6 评审包
- 状态:用户阶段 6 通过(2026-10-20),并要求启动 I3。Backend #224 已合入 main(
c164950)。P1 付费探针另提资源方案。 - 日期:2026-10-20;作者:host;Dev 任务:
feature/fast-slow-o2-i2-backend(Dev 草稿 PR #652)。 - 依据:阶段 4 方案 §4.5 与阶段 5 计划 §3;I1 已于 2026-10-20 通过,Agent-Native #48 合入
2fc66be。 - 交付对象:Backend 草稿 PR #224,base
b5eb89c(origin/main),head16f98b8。
1. 交付内容
| 计划条目 | 实现 | 位置 |
|---|---|---|
| 改钉 Agent-Native | deps/agent-native 28f3ea7 → 2fc66be(I1 合入点) |
gitlink |
| 系统层配置键 | models.routeContractEOF.model/.baseUrl/.identitySha256,SettingScopeSystem、缺省空;任一为空即关闭;用户/项目层写入被 ManagedPaths 剥除 |
internal/settings/settings.go |
| 按身份挂合同 | routeContractFor(eff, route):三项非空、模型名精确相等、NormalizeRouteBaseURL(route.Base) 成功且等于配置值、RouteContractIdentity 等于摘要,全部满足才挂;只看本 client 实际解析出的 (model, base),不看 Kind |
internal/runtime/llm.go |
| 5 个调用点全覆盖 | llm.go、sub_loop.go、squad_runner.go、verify.go、workflow_compiled.go 统一改用 openRouteClient(route, eff);轻量档、视觉改模、子代理各自独立判定 |
同左 |
| 运行记录透传 | Backend 包装器(annotateKeyFailure、GuardProjectStream、budgetedStream 等)原样转发事件,CompletionBasis/TerminalObservation 不丢;runmgr/store 本来不记录终态观测,无需改 |
测试断言 |
| 快慢通道收据透传 | 评测工具按同一规则挂合同(导出薄封装 runtime.RouteContractFor);受保护 route 文件可选 routeContractEOF{…} 移入系统层;provider-records.json 每条记录新增 completionBasis,terminalObservation 透传 completionBasis/contractCheck,均按枚举白名单(其它值记 unknown,空保持空) |
internal/server/work_checkpoint_eval_test.go(live tag) |
2. 验证
- 实施:两个 Cursor worker 单元,均经
agent-exec apply快进集成。o2-i2-backend-route-contract-config:attempt 2 success(attempt 1 是 host 把写单元包与派发并行,导致 invalid-config)。o2-i2b-eval-receipt-route-contract:补收据透传,attempt 2 success(attempt 1 因 Cursor CLI 连接中断记为 failed-unknown)。两次重跑均经用户授权。
- host 验证(SELF)@
16f98b8:gofmt、git diff --check、go vet ./internal/runtime ./internal/server(含-tags live)通过。go test ./internal/runtime ./internal/settings -count=1通过。go test -tags live ./internal/server新增 4 个TestEvalRouteContract*与既有 20 个评测预算/脱敏测试全部通过。
- CI(GATE):Backend CI 跑
go vet ./... && go test ./...。e1a90a5已 success。16f98b8success(ci / vet-and-testruns/4409、governanceruns/4410)。livetag 的评测测试不在 CI 内,这部分只有 SELF 和独立评审重放。
- 独立 Review(全新会话,只接收需求、base/head 与 diff):
- 第 1 轮 @
e1a90a5:PASS-with-fixes。5 条单元验收满足;指出计划 §3 的“快慢通道收据透传”缺失,由第二个单元补齐。 - 第 2 轮 @
16f98b8:PASS,无阻塞项。确认生产代码零行为变化,评测判定经真实 settings 服务与生产同源,白名单无泄漏,不匹配时失败关闭,既有断言未删减;评审者重放live评测测试与 runtime 测试均通过(REPLAY)。
- 第 1 轮 @
3. 需人审确认与非阻塞项
- 小队 agent-native 内核不挂合同(非阻塞,失败关闭):
internal/app/app.go:350用主模型路由直接构造 client,不在计划列出的 5 个调用点内,行为维持今天的拒绝。若希望小队路径也享受合同放行,需另开增量。 - 意图生成器无合同(无影响):
app.go:519不涉及工具放行。 - 调用点接线靠审读确认(非阻塞):测试注入
Stream,没有直接执行Execute的 nil-stream 分支;判定函数与包装器透传均有直接测试。 baseUrl说明措辞(非阻塞):只写了“无查询串”,未提 fragment/userinfo 同样不匹配。- 评测配置写错时静默无合同(非阻塞,建议 P1 前处理):route 文件写了
routeContractEOF但与路由不匹配时,评测按“无合同”运行(安全),但可能白花一次付费请求才发现。建议在 P1 资源方案前,把这种情况改为直接失败,且报错不带配置值。
4. 下一步(通过后)
- 合入 Backend #224(组件仓,无需 #518 窗口);Dev #652 收口合入。
- 启动 I3:Dev 改钉 Agent-Native
2fc66be与 Backend 合入点,make test组合验证,经 #518 窗口合入。 - P1 付费探针另提资源方案(预算上限、停止条件、收据路径)并单独批准;在此之前不写任何实例的系统层配置。