diff --git a/.task/feature-fast-slow-o2-c8-review.md b/.task/feature-fast-slow-o2-c8-review.md index af16a8ce..a7b2d750 100644 --- a/.task/feature-fast-slow-o2-c8-review.md +++ b/.task/feature-fast-slow-o2-c8-review.md @@ -9,17 +9,19 @@ - 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false - 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=5047963d4ab90c90c1c0f90e1e71ae0a04b16e9d082d3c9b94ac4bf0e0d0aeda;triage_receipt=/tmp/o2c8-20261021/triage.json;receipt_sha256=6a53842b6c14e09edbe1334abfa0b9b3829772a2129fe1325c2916fdbd324fa0 -- 授权与交付终点:<本次允许的动作与终点;未授权事项写明> +- 授权与交付终点:用户选择「1 零付费复核 C8」;允许离线只读调查、写复核文档与任务卡、Review、PR、CI 与合入。未授权:任何付费请求/复跑、代码实施、实例配置写入、部署 - 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进) - 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md) - 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入) - 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收 -- 当前阶段:需求拆解;当前增量:I1(待定义) +- 当前阶段:合入;当前增量:I1 复核文档(host 豁免路径,无实施单元) - 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位) ## 目标与非目标 -<预期结果、受影响入口/模块/契约;明确不做什么。> +目标:离线确定 P2 第 3 次请求 C8 的成因(工具名未声明还是参数 schema 不符),只读评估「schema 不符交给工具层返回可修正错误」的改法,并记录 P2 花费与结论。 + +非目标:不改 Backend/agent-native 代码、不改路由契约、不发起付费请求。 ## Agent 实施收据 @@ -27,25 +29,25 @@ | 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 | |---|---|---|---|---|---|---|---|---|---|---| -| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — | +| 无 | 仅 `docs/superpowers/specs/**` 与 `.task/**`(host 豁免) | 不适用 | — | — | — | — | 不适用 | — | — | — | ## 关联方向与规划 -- 适用状态:待核对(无适用规划时说明原因) -- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文) -- 对应里程碑:待核对 +- 适用状态:适用(O2 fast-slow A01 证据合规的后续复核) +- 主记录路径/版本:docs/superpowers/specs/2026-10-20-fast-slow-o2-a01-evidence-design.md(main a9566a6) +- 对应里程碑:O2 A01 付费复验通过 ## 需求分析 | ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 | |---|---|---|---|---|---|---| -| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 | +| R1 | 确定 C8 成因并评估改法,记录 P2 结论 | 符合:O2 下一步取决于此 | P0 | 复核文档给出可复核依据与建议 | P2 证据目录 | 完成:C8=工具名未声明;改法不适用 | ## 方案与计划 -- 方案引用:待填写(含对象版本) -- 实施计划引用:待填写(含增量与需求 ID) -- 测试计划引用:待填写(含需求 ID 与验收条件) +- 方案引用:docs/superpowers/specs/2026-10-21-fast-slow-o2-c8-review.md(Backend dfb31da、agent-native 2fc66be) +- 实施计划引用:不适用(只读复核) +- 测试计划引用:不适用;零付费,未运行模型 ## 阶段记录 @@ -66,7 +68,8 @@ | 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 | |---|---|---|---|---|---|---|---| -| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 | +| P2 A01 付费复验(前序已授权) | 证据说明收紧后 A01 不再被拒 | 3 次请求 / 17955 tokens,守卫 30000 | 0 拒绝且路由契约通过 | 用户「批准」 | NOT_PASS:第 3 次 C8;2 检查点 0 拒绝;收据 ec02e80753db2f85 | 证据合规已达成,阻塞转为 final-only 阈值 | 修正后需一次付费复验(待授权) | +| C8 零付费复核 | C8 来自 schema 不符 | 只读代码 + P2 记录 | 能否确定成因 | 用户选择「1」 | 否定假设:C8=工具名未声明(final-only 移除检查点工具) | 无代码变更 | 否 | ## 同步记录 @@ -90,18 +93,18 @@ ## 结果与验证(完成后填写) -- 结果: -- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表> -- 影响与剩余项: +- 结果:C8 成因为 `publish_work_checkpoint` 在 final-only 请求中未声明(SavedCheckpoints>=2 触发),与任务指令 reading→crosscheck 冲突;「schema 不符交给工具层」不适用且不建议实施。P2:3 次付费请求、17955 tokens、NOT_PASS(C8),证据合规达成(2 检查点 0 拒绝),路由文件已删除;本次复核零付费。 +- 验证:只读复核,依据见复核文档;模型复验 NOT_RUN(未授权) +- 影响与剩余项:推荐 F1(达阈值时工具结果与任务指令告知上限),需单独授权实施及一次付费复验 ## 规划进展与下一步 -- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划) -- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务) -- 推荐依据:待填写 -- 前置条件/待确认:待核对 -- 预期产物/验收条件:待定义 -- 重复任务核对:待核对(已有/在途任务、PR 与规划记录) +- 本次推进/剩余:C8 成因已确定;O2 A01 付费通过仍待修正与复验 +- 首选下一任务:F1 final-only 上限告知(Backend) +- 推荐依据:不动契约、零付费单测可验证宿主侧行为 +- 前置条件/待确认:用户授权实施 F1 与之后的付费复验 +- 预期产物/验收条件:final-only 前一次检查点结果含上限提示;付费复验无 C8 +- 重复任务核对:无在途同题任务 - 启动授权:未授权(建议不自动启动新任务,仍须明确授权) ## 合入与清理 diff --git a/docs/superpowers/specs/2026-10-21-fast-slow-o2-c8-review.md b/docs/superpowers/specs/2026-10-21-fast-slow-o2-c8-review.md new file mode 100644 index 00000000..09cd28f1 --- /dev/null +++ b/docs/superpowers/specs/2026-10-21-fast-slow-o2-c8-review.md @@ -0,0 +1,50 @@ +# O2 A01 P2 复验 C8 零付费复核 + +日期:2026-10-21;性质:只读复核(零付费、不改代码);对象:Backend `dfb31da20ab0276ea8e167cf26675f7ac95a1b26`、agent-native `2fc66be65201232ea38ba64d457efad5565d869d`、P2 收据 `ec02e80753db2f85…`、provider-records `add19bd1500127bb…`。 + +## 结论 + +P2 第 3 次请求的 C8 是**工具名未声明**,不是参数 schema 不符。原因是宿主的 final-only 阈值与任务指令冲突:第 2 个检查点保存后,宿主把第 3 次请求切到 final-only,从工具声明里移除了 `publish_work_checkpoint`;任务指令却要求模型按 reading → crosscheck 推进,模型仍去调用 `publish_work_checkpoint`。 + +所以「schema 不符时不丢弃整轮、交给工具层返回可修正错误」这一改法**不适用于本次失败**,即使实施也不会让 P2 通过。 + +## 依据 + +| # | 事实 | 来源 | +|---|---|---| +| E1 | 物料子 Agent 在 `SavedCheckpoints >= 2` 时无条件进入 final-only(预算充足同样触发) | Backend `internal/runtime/material_final_reserve.go:30` | +| E2 | final-only 请求从 `requestDecls` 中删除 `publish_work_checkpoint`,并插入系统提醒「不再发布检查点」 | Backend `internal/runtime/sub_loop.go:125-148` | +| E3 | P2 在第 3 次请求前已保存 2 个检查点(均 ok、0 拒绝),且 `phaseId` 只出现过 `reading` | P2 数据库 events | +| E4 | 第 3 次请求的预算核算:已用 12317、上次 prompt 5926、limit 30000,剩余 17683 > 5926+1481,不触发 stop;E1 触发 final-only | provider-records 第 1、2 次 usage,按 E1 公式计算 | +| E5 | 第 3 次 prompt_tokens 为 5160,比第 2 次的 5926 少;cache_read 从 5503 跌到 128。历史变长、prompt 反而变短且前缀缓存失效,与「删去大段检查点工具声明」一致 | provider-records 第 2、3 次 | +| E6 | 第 3 次思考末句为「Now crosscheck phase.」,随后发出一个 1000 字节、可解析的工具调用;任务指令要求 crosscheck 阶段调用 `publish_work_checkpoint` | P2 数据库;Backend `internal/runmgr/material.go:306` | +| E7 | C8 = `callsDeclared` 失败,即工具名不在本次请求声明中,或顶层 `argschema.Validate` 失败 | agent-native `runtime/llm/route_contract.go` `check`/`callsDeclared` | + +E1、E2、E4 是确定性代码路径,可以确定第 3 次请求未声明 `publish_work_checkpoint`。E5、E6 佐证模型调用的就是它。原始参数按设计不落盘,所以「调用名是 `publish_work_checkpoint`」属于高置信推断,未经原文核实。 + +## 对「schema 不符交给工具层」的只读评估 + +- **不解决本次问题**:本次是名称未声明,不经过 schema 分支。 +- **schema 分支本身风险有限,但收益也有限**:`argschema.Validate` 只校验顶层,即必填项非空、顶层原始类型、未声明的顶层键,不递归 `findings`。证据结构等深层错误本来就由工具层返回可修正结果。 +- **改契约语义需要设计评审**:C8 是 O2 已批准契约的一项。放宽后,一次顶层违规会从「终态失败」变成「多一轮请求」,影响付费上限的估算。 +- **即使没有契约也是终态**:final-only 阶段调用检查点时,`runTool` 返回可修正错误,但同时置位 `finalOnlyRejected`;下一次请求直接以 `checkpoint requested after final-only transition` 结束(`sub_loop.go:109-110`、`380-388`)。所以单改契约不能把它变成可恢复路径。 + +结论:不建议实施该改法。 + +## 可选修正(未实施,需单独授权) + +| 选项 | 做法 | 影响 | 建议 | +|---|---|---|---| +| F1 | 让模型知道上限:达到阈值的那次检查点,工具结果明确写「检查点已满,下一步直接写最终结论」;任务指令把「先 reading 再 crosscheck」改为与 2 次上限一致(例如第 2 次即 crosscheck) | 只改 Backend 物料提示与工具结果文字,不动契约;零付费单测可以验证请求声明和结果文本 | **推荐** | +| F2 | final-only 阶段保留检查点声明,由工具层拒绝,并去掉 `finalOnlyRejected` 终止 | 前缀缓存稳定(本次缓存从 5503 跌到 128),但每次违规多一轮付费请求 | 备选 | +| F3 | C8 对未声明名称改为可修正 | 削弱路由契约,与 O2 设计相悖 | 不建议 | + +F1、F2 是否真能让模型遵守,只能靠付费复验判定;零付费单测只能证明宿主侧行为。 + +## P2 花费与结论(记录) + +- 授权:用户批准一次 A01 付费复验(label `approved-o2-a01-evidence`,30000 tokens 守卫)。 +- 花费:3 次付费请求,共 17955 tokens(5873 + 6444 + 5638),未超守卫。 +- 结论:NOT_PASS。路由契约在第 3 次请求判 C8(`terminal_error`),子运行以 `tool call stream ended before [DONE]` 失败,outcome 为 partial。 +- 证据合规目标已达成:2 个检查点,0 拒绝,`material_record` 均未附 evidence。 +- 路由文件已在复验后删除;本次复核没有发起任何付费请求。