Merge pull request 'Add O2 A01 checkpoint evidence compliance design and plan' (#662) from feature/fast-slow-o2-a01-evidence-design into main
ci / svc-realcombo (push) Successful in 2m28s
ci / test (push) Successful in 8m32s
ci / test-pg (push) Successful in 12m19s

This commit was merged in pull request #662.
This commit is contained in:
2026-10-20 15:32:10 +00:00
3 changed files with 334 additions and 0 deletions
@@ -0,0 +1,168 @@
# feature/fast-slow-o2-a01-evidence-design 任务卡
任务主记录:PR #662 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/662;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 556201541c9a98f34fdad860cfad886af069279d
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-fast-slow-o2-a01-evidence-design(worktree);分支:feature/fast-slow-o2-a01-evidence-design
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=df1a6812c2cf304f074b3d29139cfafd427960f9720935b99497ab67e5d2a646;triage_receipt=/tmp/o2a01d-20261020/triage.json;receipt_sha256=2828ea8adadd8f90cb348a28a7c750dfa85dc5a91f8d3e6877decdbed120ea27
- 授权与交付终点:用户 2026-10-20 选定“立项:出设计和资源提案,方向是收紧说明并让评测允许修正一次(推荐,先零付费)”。本任务只交付方案、实施计划(入仓)与源码外资源提案,经 PR 合入 Dev 后请用户审阅。**未授权**:产品代码改动、派遣实施 worker、任何付费请求或 A01 复验、实例系统层配置写入、部署。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:方案与计划已成稿,待合入后人审;当前增量:D1(设计文档,无实施单元)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
**目标**:针对 O2 P1 第二段 A01 被核心校验拒绝(`checkpoint.evidence: direct relation cannot have result`)后评测立即停止的问题,产出零付费的方案与实施计划:收紧 `publish_work_checkpoint` 工具说明/字段说明与材料任务提示,让模型按 mode 填对 evidence;评测把“首次被拒即停”改为“累计 2 次即停”;并提出一次 A01 付费复验的资源提案。
**非目标**:不改 core 校验器与宿主证据归一语义;不改 schema 结构(不引入 `oneOf`);不改路由契约/传输层;不实施、不付费、不写实例配置、不部署。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 无(本任务仅 host 豁免路径:`.task/**`、`docs/superpowers/{specs,plans}/**`) | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 关联方向与规划
- 适用状态:适用——快慢通道 O2 后续(O2 方案 `docs/superpowers/specs/2026-10-19-fast-slow-o2-route-contract-eof-design.md`;P1 结论见 `.task/archive/feature-fast-slow-o2-p1.md`)
- 主记录路径/版本:本卡;方案与计划见下
- 对应里程碑:快慢通道 O2 收口(A01 真实路由通过)
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 方案:定位 A01 被拒根因并给出说明收紧与评测修正一次的设计 | 符合:用户 2026-10-20 选定 design_both;根因由离线重放(SELF)确认 | P1 | 方案文档入仓,含根因、改动、非目标、替代方案、判定表 | P1 结论 | 已成稿 |
| R2 | 实施与测试计划:单元范围、允许路径、离线测试与停止条件 | 符合:policy/delivery.md 计划阶段 | P1 | 计划文档入仓,测试全部零付费 | R1 | 已成稿 |
| R3 | 一次 A01 付费复验资源提案(≤60,000 tokens) | 符合:付费须单独批准 | P2 | 源码外提案就位并请用户批准 | R1、R2 | 已成稿,待批准 |
## 方案与计划
- 方案引用:`docs/superpowers/specs/2026-10-20-fast-slow-o2-a01-evidence-design.md`(sha256 前缀 d99475c4ae6741ee;Backend 依据 74e5396)
- 实施计划引用:`docs/superpowers/plans/2026-10-20-fast-slow-o2-a01-evidence-plan.md`(sha256 前缀 5925f66ae205d6d2;增量 I1 Backend、I2 Dev 改钉、P2 付费复验)
- 测试计划引用:同计划 §2 T1–T9(全部离线;eval/live 用 -tags live 单独运行)
- 资源提案:`~/.local/share/agent-system-evidence/fast-slow-o2-a01e-20261020/resource-proposal.md`(源码外,sha256 前缀 bd00293f0b8240e7)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | R1–R3 | 完成 | host | 2026-10-20 | 用户选定 design_both |
| 需求评估 | R1–R3 | 完成 | host | 2026-10-20 | 零付费调查与离线重放(SELF) |
| 需求表确认 | R1–R3 | 完成 | 用户 | 2026-10-20 | AskQuestion a01_next=design_both |
| 方案设计 | d99475c4ae6741ee | 成稿,待人审 | host | 2026-10-20 | 方案文档 |
| 实施计划 | 5925f66ae205d6d2 | 成稿,待人审 | host | 2026-10-20 | 计划文档 |
| 实施与自检 | — | 不适用(未授权实施) | — | — | 授权与交付终点 |
| 正式测试与验收 | — | 不适用(仅文档) | — | — | — |
| 代码 Review | 6db2d614 | PASS(第 2 轮) | code-reviewer 子智能体(fresh session) | 2026-10-20 | 见合入与清理节 Review 记录 |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| D0 离线重放 | A01 被拒源于 finding 0 在 direct_relation 下混入 total/phase 前提与 result | `/tmp/o2a01-replay`,同参数 + core 当前版本 | 重放能复现拒绝原因即止 | 零付费只读调查 | 复现:整检查点被拒;去掉 evidence 后通过(SELF) | 支撑方案 §2 根因 | 否 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 556201541c9a98f34fdad860cfad886af069279d | 556201541c9a98f34fdad860cfad886af069279d | 2026-10-20T14:12:47Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:方案、实施计划入仓;源码外资源提案就位;均待用户审阅。
- 验证:文档任务,无代码测试(NOT_RUN 不适用);PR CI 为准(`make test`+`make build`)。
- 影响与剩余项:仅新增两份文档与本卡;产品行为不变。
## 规划进展与下一步
- 本次推进/剩余:O2 后续设计完成;剩余 I1/I2 实施与 P2 付费复验。
- 首选下一任务:按计划实施 I1(Backend 单元 `o2a01e-i1-backend-evidence-guidance`)与 I2(Dev 改钉)
- 推荐依据:零付费、范围限于 Backend 文案与评测代码,是付费复验的前置
- 前置条件/待确认:用户批准方案与计划;P2 另需批准资源提案并重新放置路由文件
- 预期产物/验收条件:计划 §2 T1–T9 通过、Backend 与 Dev PR 当前 HEAD CI 通过并合入
- 重复任务核对:无在途同题任务或 PR(task-triage verdict=NEW)
- 启动授权:未授权(待用户审阅)
## 合入与清理
- Review 记录:
- 第 1 轮:Cursor code-reviewer 子智能体(fresh_session=true,session `8826f456`,只读),base 556201541c / head 9c6c2f0,结论 BLOCK。B1:方案让分析类使用 `direct_relation`,但宿主仅对单一来源完整原句的 `material_record` 保留,其余转待确认;B2:`eval/live` 带 `live` 构建标签,计划验证命令会失败且 CI 不覆盖。host 复核两项属实(`material_evidence.go:215-227`;`go list ./eval/live/` exit 1),已修订方案 §2/§3.1/§3.2 与计划 §2(允许路径、T1/T4/T5、新增 T8/T9、验证命令);非阻塞建议 1–5 一并吸收。
- 第 2 轮:Cursor code-reviewer 子智能体(fresh_session=true,新 session `c9f1fce3`,只读,未转交第 1 轮会话),head 6db2d614,结论 PASS;B1/B2 确认闭合,审阅者重放 `go test -tags live -run '^TestFollowupA01KeepsItsOwnOneShotResult$' ./eval/live/` 与 `go vet -tags live ./eval/live/` 通过(REPLAY,Backend 74e5396)。3 条非阻塞提示(T5 夹具同缺 `}`、无 evidence 的 `needs_user` 原文被替换、T3 比较基准)已作为澄清写入文档,未改变方案结论。
- 冲突记录:task-sync 合入 main 7e19cf3(#661 卡闭合),无冲突;本变更仅文档与任务卡,无组件组合影响。
- CI 记录:以 PR #662 合入时 HEAD 的必需检查为准(GATE,`make ci-wait SHA=<HEAD>` + 合入脚本核验 commit status=success);HEAD 与运行结果见窗口释放评论(Agent-System-Dev#518)。
- 合入记录:授权范围为本卡“授权与交付终点”(仅文档);PR #662 合入 main,被核验 HEAD 与 merge commit 见窗口释放评论(Agent-System-Dev#518)。
- 清理记录:合入后核对写者退出,于任务 worktree 运行 `TASK_WRITERS_STOPPED=1 make task-finish`;本卡随本 PR 闭合归档。
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-20T13:52:28.231377+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "556201541c9a98f34fdad860cfad886af069279d",
"after_head": "556201541c9a98f34fdad860cfad886af069279d",
"branch": "main",
"target_branch": "main",
"target_head": "556201541c9a98f34fdad860cfad886af069279d",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=556201541c",
"[remote] origin/main=556201541c ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=3",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 556201541c(完整:556201541c9a98f34fdad860cfad886af069279d)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "b9fa778a80fdbf2d33925aa16abddd250afd5dee536104a503c73e7e540bd62f",
"receipt_sha256": "2a13d032916edd33cee13cf74004a0f5feeabc71fa751e68d738adc425297196",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/2a13d032916edd33cee13cf74004a0f5feeabc71fa751e68d738adc425297196.json"
}
```
| 同步(记录前对象) | 7e19cf3e182b566bdc48a7e690e44ff11b4ab33c | 25d22faae7726176c16ca4bcdf5ff0094af404a2 | 2026-10-20T14:24:43Z |
## 闭合记录(合入前折叠)
- 本卡在 PR #662(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/662)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
| 同步(记录前对象) | ed3847c85ce111a74f0cb100908abfb40f62db07 | 398e8e6ff91eb5109878f69c6a2ca6ef7c174513 | 2026-10-20T14:46:15Z |
| 同步(记录前对象) | 6945b6701f7579bf4e31def283825e392c33ad16 | 316e087262219272af5f74a5f6758cc8e82919f2 | 2026-10-20T15:16:46Z |
@@ -0,0 +1,73 @@
# 快慢通道 O2 后续:A01 检查点证据合规 实施与测试计划
- 状态:**计划稿,待人审**(与[方案](../specs/2026-10-20-fast-slow-o2-a01-evidence-design.md)同批评审)。人审通过前不派 worker、不改产品代码。
- 日期:2026-10-20;作者:host;来源等级:SELF。
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md);worker 不提交、不推送、不开 PR;host 负责范围审阅、权威验证、PR/CI/合入。
- 付费与真实模型:I1/I2 零付费;P2 付费复验按资源提案单独批准。
## 1. 交付切分与顺序
| 增量 | 仓 | 内容 | 依赖 | 合入方式 |
|---|---|---|---|---|
| I1 | Backend | 说明/提示收紧(方案 §3.1)+ 评测允许修正一次与新标签(§3.2) | 无 | 组件仓 PR,当前 HEAD CI 通过后合入 |
| I2 | Dev | `modules/backend` gitlink 前移到 I1 合入提交 | I1 | Dev PR,`make test` 组合验证 + 合入窗口 |
| P2 | 证据目录 | 一次 A01 付费复验 | I2 + 用户批准资源提案 | 不入仓;结论写回后续任务卡 |
I1 是一个可独立实施的单元:文案与评测两处改动都在 Backend 且共享同一验证命令,拆开只会增加一次派遣与一次 CI。
## 2. I1 Backend(单元 `o2a01e-i1-backend-evidence-guidance`)
**允许路径**(前缀):
- `internal/runtime/work_checkpoint.go`、`internal/runtime/work_checkpoint_test.go`
- `internal/runmgr/material.go`
- `internal/runmgr/material_sources_test.go`、`internal/runmgr/material_first_checkpoint_test.go`(提示断言所在文件)
- `internal/runmgr/material_evidence_test.go`(宿主归一断言,只加测试,不改 `material_evidence.go`)
- `internal/server/work_checkpoint_eval_test.go`、`internal/server/work_checkpoint_eval_budget_test.go`
- `eval/live/work_checkpoints_test.go`
**改动**:
1. `checkpointDecl()`:按方案 §3.1 第 1、2 条重写 `Description`,并只给现有 schema 字段补 `description`;类型、枚举、`required`、`additionalProperties`、`minItems/maxItems` 与嵌套结构逐字不变。
2. `material.go`:按方案 §3.1 第 3 条调整材料任务提示的三句;其余提示不动。
3. `evalRejectedCheckpointPersisted` 改为返回被拒检查点去重计数;评测流按方案 §3.2 计算 `max(库内计数, 本次输入计数)`,达 2 才停,原因 `repeated rejected work checkpoint`,停止状态保持且判断优先于终态异常;库读失败仍 `checkpoint stop state unavailable`。
4. 新标签:`evalA01Budget` 增加 `approved-o2-a01-evidence`(30,000、护栏开);`checkpointEvalOutputName("A01", "approved-o2-a01-evidence")` → `candidate-o2-a01-evidence`。评测调用记录增加本样本被拒检查点计数字段。
**测试**(全部离线、零付费):
| ID | 测试 | 断言 |
|---|---|---|
| T1 | 说明示例可校验 | 从 `Description` 抽出的示例 JSON(`material_record` 无 evidence、`material_record`+`direct_relation`、`difference`、`unresolved_relation`)套入最小合法检查点后 `core.ValidateWorkCheckpoint` 通过 |
| T2 | 反例仍被拒 | `direct_relation` 带 result、`unresolved_relation` 带 result 均被核心校验拒绝(锁定说明与校验一致) |
| T3 | Schema 结构不变 | 现有 `work_checkpoint_test.go` schema 断言保持通过;新增断言:新旧 schema **都**去掉全部 `description` 键后一致(旧 schema 的 `quote` 已带 description,不能直接与改动前原文比) |
| T4 | 一次被拒可继续 | 改写 `TestEvaluationStopsPaidRequestsAfterRejectedCheckpoint`:先修正该测试 SSE 夹具缺失的结尾 `}`(否则真实调用会触发终态异常);输入含 1 次被拒 → 允许 1 次 provider 调用且无错误;输入含 2 次被拒 → 不调用、原因 `repeated rejected work checkpoint`;其后再发一次无被拒输入的请求仍被拒(停止状态保持) |
| T5 | 跨 run 累计 | 改写 `TestEvaluationStopsAcrossRunsAfterPersistedCheckpointRejection`(同样先修正其 SSE 夹具缺失的结尾 `}`;因 `terminalFault` 在同一评测流内保持,各子用例各用新的评测流与数据目录):库内 1 次被拒 → 允许;2 次(不同 callId)→ 停;同一 callId 重复事件只计 1;库内 1 次 + 输入中同一次 → 仍只计 1 |
| T6 | fail closed 不变 | `TestEvaluationFailsClosedWhenCheckpointEventsUnavailable` 保持通过 |
| T7 | 新标签 | `evalA01Budget` 与 `checkpointEvalOutputName` 表驱动用例覆盖新标签;未知标签仍拒绝 |
| T8 | 宿主降级与说明一致 | `material_evidence_test.go`:`analysis`+`direct_relation` 经 `normalizeMaterialEvidence` 转 `needs_user`;`material_record` 无 evidence 保持 `material_record` |
| T9 | 提示约定 | 提示断言文件中断言材料任务提示含“原样记载用 material_record,只附 sources,不附 evidence”的约定 |
**单元验证命令**(worker 自检与 host 权威验证相同):
1. `go test ./internal/runtime/ ./internal/runmgr/ ./internal/server/ -count=1`
2. `go test -tags live -run '^TestFollowupA01KeepsItsOwnOneShotResult$' ./eval/live/ -count=1` 与 `go vet -tags live ./eval/live/`:`eval/live` 全部文件带 `//go:build live`,默认 `go test ./...` 与 Backend CI **不覆盖**,须单独运行;该用例为表驱动、不联网(2026-10-20 在 Backend 74e5396 本地实测通过,SELF)。不设置 `WORK_CHECKPOINT_SERVER_MODE`。
3. host 另在 Backend 根目录运行 `go test ./... -count=1` 与 `go vet ./...` 各一次;PR CI 为准(不含第 2 条,由 host 经 `make evidence` 记录)。
**越界即停**:需要改 core、schema 结构、生产停止逻辑或其他文件时,worker 以 `scope-expansion` 终止,由 host 请求授权。
## 3. I2 Dev 组合
- 前移 `modules/backend` 到 I1 合入提交;`make test` + `make build` 由 PR CI 验证;按合入窗口流程合入。
- 不改 `pins/` 与其他组件;`task-pr-check` 通过后合入。
## 4. P2 付费复验(不在本计划授权内)
- 依据方案 §5、§6 与源码外资源提案执行一次 A01;标签 `approved-o2-a01-evidence`,数据目录名含 `fast-slow-u2-u3-`(如 `fast-slow-u2-u3-o2-a01e-model-data`)。
- 候选二进制从 I2 合入后的 Dev 精确提交构建,记录 Dev/Backend SHA。
- 结束后删除路由文件,判定按方案 §5 表格,结论与花费写入后续任务卡。
## 5. 完成与停止
- 本任务(设计)完成标准:方案、计划与源码外资源提案经 PR 合入 Dev,用户收到审阅请求。
- I1/I2 在用户批准方案与计划后启动;P2 在用户单独批准资源提案后启动。
- 任一单元 fail-stop 终态(`failed-unknown`、`scope-expansion`、`blocked` 等)立即停止并报告,不自动重试。
@@ -0,0 +1,93 @@
# 快慢通道 O2 后续:A01 检查点证据合规方案
- 状态:**方案稿,待人审。** 本文不授权产品代码改动、付费请求、A01 复验、实例配置写入或部署;人审通过后才按配套计划派 worker 实施零付费部分,付费复验按[资源提案](#6-付费复验资源提案摘要)单独批准。
- 日期:2026-10-20;作者:host(只读调查与文档撰写);来源等级:SELF。
- 决策来源:用户 2026-10-20 选定“立项:出设计和资源提案,方向是收紧说明并让评测允许修正一次(推荐,先零付费)”。
- 前序:[O2 方案](2026-10-19-fast-slow-o2-route-contract-eof-design.md);P1 结论见归档卡 `.task/archive/feature-fast-slow-o2-p1.md`(限路由契约在真实路由上有效;A01 停在应用层证据合规)。
- 配套计划:[实施与测试计划](../plans/2026-10-20-fast-slow-o2-a01-evidence-plan.md)。
## 1. 目标与非目标
**目标**:让 A01 在已生效的限路由契约下,第一批检查点按工具约定发布成功;偶发一次不合规时,评测允许模型按工具结果修正一次,而不是立即判失败。
**非目标**:
- 不改 `agent-system-core` 校验器(`validateWorkFindingEvidence`)与宿主证据归一(`normalizeMaterialEvidence`)语义;“不合规证据软降级为待确认”另行讨论(§5)。
- 不改工具 JSON Schema 结构(不引入 `oneOf`/条件 schema);不改路由契约、传输层或 `[DONE]` 判定。
- 不放宽评测质量判据(仍要求至少 2 个 running 检查点落库并经独立评估);不改预算上限的数值口径。
- 不写实例系统层配置、不部署。
## 2. 现状与根因(零付费调查)
**A01 事实**(P1 第二段,收据 `a01-run-receipt.json` sha256 前缀 `7e3583a8`):第一批检查点被核心校验拒绝:`checkpoint.evidence: direct relation cannot have result`。离线重放(同一参数、`agent-system-core` 当前版本)得到:finding 0 为 `kind=material_record`、`mode=direct_relation`,却带 `total=2`、`phase=1` 两个前提与 `result=8`;去掉 evidence 后同一 finding 校验通过。评测随即按“检查点被拒即停”停止全部付费请求,样本终止。
| 位置 | 现行行为 | 问题 |
|---|---|---|
| Backend `internal/runtime/work_checkpoint.go` `checkpointDecl()` | 工具说明用一句话并列三种 mode;schema 为单一扁平对象:`mode` 枚举、`premises[].role` 四值枚举、`result` 可选 | schema 允许任意 mode 搭配任意 role/value/result;各 mode 的必填与禁填只在核心校验器里,模型看不到 |
| Backend `internal/runmgr/material.go`(材料任务提示) | “分析判断必须写 assumptions,并说明单位、算式或前提”;“数字或分期归属用 evidence 给依据” | 未说明 `material_record` 不需要 evidence;“算式或前提”推动模型给原样记载也补数字前提 |
| core `task_snapshot.go` `validateWorkFindingEvidence` | `direct_relation`:恰 1 个 `direct_relation` 前提、无 value、无 result;`difference`:total、phase 带值且有 result;`unresolved_relation`:total、phase、dependent 带值、无 result | 一条 finding 不合规即整次检查点被拒(工具说明称“宿主会改为待确认”,与此不一致) |
| Backend `runmgr/material_evidence.go` `normalizeMaterialEvidence` | 无 evidence 的 `material_record` 由宿主扩展为整句并按原句展示(原句语境不唯一则转待确认);无 evidence 的非审慎分析转待确认;`direct_relation` **仅当** kind 为 `material_record`、单一来源、短引即完整原句且原句明确表达关系时保留,其余一律转待确认;`difference` 要求 `result == total − phase`,否则转待确认 | 正常路径本已支持“原样记载不附 evidence”;分析类使用 `direct_relation` 必然被降级 |
| Backend `internal/server/work_checkpoint_eval_test.go` 评测流 | 输入中出现被拒的 `publish_work_checkpoint` 工具结果,或库内已落一次被拒结果 → 停止后续全部付费请求 | 比生产严格:生产(`runtime/sub_loop.go`)把错误结果回给模型并继续 |
**根因**:模型看不到“按 mode 的必填/禁填”,提示又鼓励给记载补前提;而评测对首个不合规零容忍。前者是主因,后者把一次可修正的偏差放大为整样本失败。
## 3. 方案
### 3.1 收紧工具说明与任务提示(生产可见,零付费)
1. **工具说明**(`checkpointDecl().Description`)改为分条写清:
- `material_record` 默认只引用原句,**不附 evidence**(宿主扩展为整句并按原句展示)。
- 唯一例外:原句本身明确表达关系(如“第二期包含3项依赖外部接口的需求”)时,`material_record` 可附 `direct_relation`:单一来源、短引即完整原句、恰 1 个前提 `{role:"direct_relation", sourceIndex:0}`,**不写 value、不写 result**;不满足这些条件宿主会转待确认。
- `analysis`/`provisional`/`needs_user` 里的数字或分期归属用以下两种 mode 之一(每条 finding 只选一种;不要用 `direct_relation`,宿主会转待确认):
- `difference`:前提 `total`、`phase` 各 1 个且都写 value;`result` 必须等于 total − phase。
- `unresolved_relation`:前提 `total`、`phase`、`dependent` 各 1 个且都写 value;**不写 result**。
- 各给一个最小 JSON 示例(字段名与 schema 一致)。
- 删除“宿主会把不能证明的判断改为待确认”中与校验器不一致的承诺,改为如实描述两类结果:(a) evidence 结构不符(如 `direct_relation` 带 result)会**整次被拒**并在工具结果给出原因,须按原因修正后重发;(b) 结构合规但宿主核不上的——前提数字与短引不符、`direct_relation` 不满足上述条件、原句语境不唯一、无 evidence 的非审慎分析、无 evidence 的 `needs_user`(原文会被替换为通用待确认文案)——该条转为待确认并在工具结果说明。
2. **Schema 字段说明**:仅在现有字段上补 `description`(`evidence`、`mode`、`premises`、`role`、`value`、`result`),写明上面的按 mode 约束;**不改类型、枚举、必填和嵌套结构**,不引入 `oneOf`(部分 OpenAI 兼容服务对复合 schema 支持不确定)。
3. **材料任务提示**(`material.go`):把“分析判断必须写 assumptions,并说明单位、算式或前提”限定为分析类;补一句“原样记载用 material_record,只附 sources,不附 evidence”;保留现有 12/8/3 反例。
**测试锚点**:
- 说明中的每个 JSON 示例在测试里抽出并经 `core.ValidateWorkCheckpoint`(套入最小合法检查点)校验通过;反例(`direct_relation` 带 result)断言被拒。
- 宿主归一层(`normalizeMaterialEvidence`)补断言:`analysis` + `direct_relation` 转 `needs_user`;`material_record` 无 evidence 保持原样记载——锁定说明所述的降级行为与宿主一致。
- 材料任务提示补断言:含“原样记载不附 evidence”的约定。
- 不以整段文案做快照断言,避免文案调整引起脆弱失败。
### 3.2 评测允许修正一次(仅评测代码)
- 现行“首个被拒即停”改为:**同一评测数据目录内,被拒的 `publish_work_checkpoint` 结果累计达 2 次即停**,原因串改为 `repeated rejected work checkpoint`;第 1 次被拒后允许继续请求,让模型按工具结果修正。
- 计数口径:库内按 `(conversation, run, callId)` 去重的被拒检查点数,与当前请求输入中被拒检查点工具消息数取较大值(同一次被拒同时出现在库与输入中只计 1);库不可读仍 fail closed(原因不变)。停止状态一旦触发即保持,后续请求一律拒绝;被拒判断优先于终态异常等其他原因。
- 已知边界:生产写 `tool.result` 事件时忽略写入错误(`runtime/sub_loop.go`),若事件未落库且两次被拒分属不同 run,可能少计一次、多放行一次请求;该请求仍受预算与单 run 调用上限约束,不阻塞本方案。
- 其余停止条件(预算、单 run 8 次调用、6 个 run、终态异常、用量不可得)全部不变;修正请求同样计入这些上限。
- 评测输出新增已批准标签(见 §6),不复用 `approved-r04-20261014`;该标签沿用 A01 30,000 token 画像上限与护栏。
- 评测调用记录写入每次调用前的被拒计数;因最后一次被拒可能发生在最后一次调用之后,**判定以收尾时库内去重计数为准**,供独立评估区分“一次修正后通过”与“首发即通过”。
### 3.3 不做的替代方案
| 方案 | 不选原因 |
|---|---|
| Schema 改为按 mode 的 `oneOf` | 模型侧约束最强,但 provider 对复合 schema 的支持未核实,可能整体拒绝工具或静默忽略;收益不确定且扩大验证面 |
| 核心校验器对不合规 evidence 软降级为待确认 | 改变核心契约与跨仓语义,影响生产展示;作为二次失败后的候选(§5) |
| 只改评测不改说明 | 修正一次能掩盖说明缺陷,但每个样本多花一轮,且生产用户仍会看到被拒结果 |
## 4. 影响面与风险
- 生产:仅改模型可见文案与 schema 字段说明;校验与归一逻辑不变。风险是模型更少附 evidence,结果更多显示为“待确认”——这是当前设计允许的保守方向。
- 评测:只放宽“被拒即停”的次数,预算与调用上限不变,最坏额外消耗受同一上限约束。
- 跨仓:仅 Backend 一个组件仓 PR + Dev gitlink 组合 PR;不触 core、Agent-Native、Frontend/UI。
## 5. 付费复验判定
| 结果 | 判定 | 后续 |
|---|---|---|
| 首发检查点即合规,≥2 个 running 检查点落库,最终正文完整且独立评估通过 | PASS | O2 收口;是否写实例契约配置另行决策 |
| 第 1 次被拒、修正后合规,其余同上 | PASS(附注:说明仍有缺口) | 记录被拒原因,评估是否需进一步收紧 |
| 被拒 2 次 | FAIL(证据合规) | 提出“核心软降级”方案另行评审,不追加付费 |
| 传输终态、预算、用量等其他原因停止 | 按原因归类,不计入本方案结论 | 按原因另行处理,不自动重跑 |
## 6. 付费复验资源提案(摘要)
- 范围:在本方案零付费部分合入 Dev 后,一次 A01(同一 MiniMax-M3 路由 + 已验证的限路由契约),不重跑、不扩样本。
- 上限:报告 token ≤ 60,000(`WORK_CHECKPOINT_REMAINING_TOKENS=60000`);单 run ≤ 8 次调用;被拒检查点达 2 次即停。
- 前置:用户重新放置路由文件(P1 结束后已删除);host 只核验权限、哈希、模型、主机、key 是否存在及三元组摘要,不读取或回显 key。
- 详细提案(逐项命令、收据路径、停止规则)放在源码外证据目录,人审时一并提供;本提案不随本文获批,须用户单独批准。