Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
98 lines
7.9 KiB
Markdown
98 lines
7.9 KiB
Markdown
# PROGRESS · 证据轮只说「记下了」却没写入(2026-09-10)
|
||
|
||
工作树:`.worktrees/rectification-unwritten-evidence-claim-20260910`
|
||
分支:`codex/rectification-unwritten-evidence-claim-20260910`
|
||
任务书:`docs/tasks/TASK-rectification-unwritten-evidence-claim-20260910.md`
|
||
基线:任务书写 `origin/staging` @ `d96b24c2`;开工接到 `84572c07`;合入前再接到 `origin/staging` @ `301827ad`(collect-semantics 任务书 + BUG-635 决策 4 去掉年份正则)。
|
||
|
||
## 开工回执
|
||
|
||
- 编号 **BUG-635**(P1)/ **BUG-636**(P2)。`docs/BUG_HISTORY.md` 当时最大已发布号是 634。
|
||
- 顺序:分类器 `expectedWrite` → 无写入的「记下了」收回并重试一次 → 第二次主持人正文且不结算 → 客户端只认最后一条 settled 助手消息 → schema 拒绝信封失败映射 → 记录。
|
||
- 未实现 BUG-641~643。同一工作树交付 BUG-637~640,见 `PROGRESS-rectification-latent-audit-20260910.md`。
|
||
|
||
## 决策 3
|
||
|
||
选 **turn `status=completed` + `answer_origin=host_fallback` + 不结算计费**。
|
||
|
||
实现:`completeAttempt(false)` → `settleBilling === false` → `billing.release()`,不写 `billing.settled`。客户端仍走完成轮刷新;未答焦点靠 T4 的主持人问题行。
|
||
|
||
## 决策 4(`301827ad` 修订)
|
||
|
||
`expectedWrite: "evidence" | "none" | "unknown"`。分类器 null/出错重试一次,仍失败则 `"unknown"`,守卫 fail-open。**没有年份正则 / 关键词兜底。** 无焦点的 `message` 路径也跑同一分类器。正文里的「记下了」仍触发守卫(决策 1)。
|
||
|
||
## 已完成
|
||
|
||
- **T1**:`expectedWrite` 声明在 `immediateResponse` IIFE **之外**(`POST` 作用域),否则 `runV9AgentTurn({ expectedWrite })` 编译失败(TS18004)。collect / choice / 无焦点 message 都走 `classifyTurnIntentWithRetry`。`provide_new_evidence` 或 `answer_current_focus` + `has_new_dated_event` → `"evidence"`。`opening` / `read_only` 不触发。
|
||
- **T2**:`streamAttempt` 在 `empty_stream` 之后、`loadV9CaseDossier` 之前:`needsWrite && !publicWriteToolCompleted && !hostFallbackUsed` → 第一次 `evidence_not_written` + `retractSpoken()`(不进 `RETRYABLE_ERROR_CODES`);第二次主持人正文 `RECTIFICATION_USER_COPY.evidenceNotRecorded`。`needsWrite` = `expectedWrite === "evidence"` 或正文含「记下了」。batch 已完成且无正文仍走 BUG-633 `applyHostFallback`。
|
||
- **T3**:`buildAgentMessages` 在 `attempt > 1` 时用 `retryConstraintForAttempt(lastAttemptError)`。
|
||
- **T4**:`liveQuestionOnMessages` 只认 `latestSettledAssistant`。未答焦点落到既有 `persisted_question` 主持人问题行。`frontend/DESIGN.md` 表已补完成轮未答焦点。
|
||
- **T5**:schema 拒绝信封 `{ error: true, validationErrors: object }` → `tool.activity failed code=tool_call_rejected`;phase 映射与 batch recap 返回 null;公开事件不含 `validationErrors`。
|
||
- **T6**:BUG-635/636、CHANGELOG、走查第 15 条、任务表待验收、本文件。Skill 版本不变(`10.0.21`)。
|
||
|
||
## 验收命令(实测)
|
||
|
||
工作树 `codex/rectification-unwritten-evidence-claim-20260910`,相对 `origin/staging` @ `301827ad`。
|
||
|
||
| 命令 | 结果 |
|
||
| --- | --- |
|
||
| `frontend` `tsx --test` 任务书相关文件(unwritten / host-fallback / spoken-collect / turn-intent / agentic-entry / agent-voice / v9-stream) | **141/141 pass** |
|
||
| `frontend` `./node_modules/.bin/tsc --noEmit` | **0 error** |
|
||
| `frontend` `npm run lint` | **0 error** / 111 warning(既有债) |
|
||
| `git diff --check` | 干净 |
|
||
| `next build` | 未跑;记环境缺口 |
|
||
|
||
### 本单测试名
|
||
|
||
- `collect intent maps provide_new_evidence and dated current-focus to expectedWrite`
|
||
- `runner does not use a year-utterance fallback`
|
||
- `retry bootstrap uses the unwritten-evidence constraint only for that error`
|
||
- `route passes classifier expectedWrite into the agent runner`
|
||
- `classifyTurnIntentWithRetry fails open as unknown after two misses`
|
||
- `unwritten 记下了 retries once then host-falls-back without billing`
|
||
- `read-case then batch then set-focus then 记下了 stays on the baseline path`
|
||
- `empty body after a completed batch still uses BUG-633 host fallback`
|
||
- `read_only action with a dated utterance does not trigger the write guard`
|
||
- `schema rejection envelopes fail the tool and never count as a batch recap`
|
||
- `rejected batch tool-result is failed in the runner terminal status`
|
||
- `chat live question only reads the last settled assistant message`
|
||
- host-fallback:`schema rejection envelopes are not treated as batch recaps or write completion`
|
||
- host-fallback:`year fallback is gone; only explicit evidence expectedWrite triggers the guard`
|
||
|
||
### 既有断言改动
|
||
|
||
- `rectification-v9-stream.test.ts` empty_stream 二次成功正文:原值「记下了这件事。」/ 新值「先继续核对。」;原因:BUG-635 把无写入的「记下了」收口成 `evidence_not_written`,该用例只锁 empty_stream 重试。
|
||
- `rectification-v9-agent.test.ts` `evidence persist keeps the first sentence when the model writes three`:断言未改。原夹具 read-case 后直接写三句「记下了」、无 batch / 新夹具 batch + set-focus completed 后再写那三句 / 原因:Gitea `Independent Staging Quality Gate` run 2545 全文套件 3082/3083,该条被 635 收口成「这件我还没记上」;用例名是 persist,夹具必须真写入。
|
||
|
||
## 环境缺口
|
||
|
||
- 无登录态:`docs/testing/rectification-scenarios-20260907.md` 第 15 节真人走查未做,不得写通过。
|
||
- 未跑 `next build`,未核 `/` 是否仍 `○ Static`、首屏 gzip ±2%。
|
||
- 推 staging 后才核 `/api/health` 的 `deployment.gitCommit`;未部署则记缺口。
|
||
|
||
## 未做
|
||
|
||
- 未提升 `main`。Skill 未升版。
|
||
- 观察项与 BUG-641~643 未做。
|
||
|
||
## 验收结论(Claude,2026-09-10,基线 `origin/staging` @ `8f9eb587`,staging 已部署同 SHA)
|
||
|
||
| 项 | 结论 |
|
||
| --- | --- |
|
||
| T1 路由 `expectedWrite` → 运行器;无焦点 message 也跑分类器;分类器失败重试一次后 `unknown` fail-open;无年份正则 | 通过(`grep 'd{4}'` 四个文件为空) |
|
||
| T2 收尾守卫:无写入的「记下了」/`expectedWrite=evidence` → 收回、`evidence_not_written` 重试一次;第二次主持人正文、`answer.host_fallback`、不结算(`billing.release`) | 通过(`rectification-unwritten-evidence.test.ts` 5 条运行器用例) |
|
||
| T3 重试约束句只对 `evidence_not_written` | 通过 |
|
||
| T4 客户端只认最后一条 settled 助手消息;`DESIGN.md` 已补 | 通过 |
|
||
| T5 Mastra 拒绝信封 → `tool.activity failed code=tool_call_rejected`,batch recap / phase 不认信封 | 通过 |
|
||
| T6 BUG-635/636、CHANGELOG、`docs/testing` 第 15 条 | 通过;Bug 历史无个人资料 |
|
||
| `tsc --noEmit` | 0 错 |
|
||
| `npm run lint` | 0 error / 110 warning(既有债) |
|
||
| 前端全套 | 3083 条:3042 过、14 跳过、27 失败;18 条 `spawnSync docker ENOENT`,其余 9 条在基线 `d96b24c2` 同环境下逐条同样失败(`@/` 别名 eval 解析、部署/环境断言),非本轮引入 |
|
||
| 静态测试数 | 3045 → 3066(+21) |
|
||
| 既有断言改动 | 两处均写明原值 / 新值 / 原因,理由成立 |
|
||
| 部署 | `/api/health` `deployment.gitCommit` = `8f9eb587` |
|
||
|
||
**口径缺口(P2,已并入 `TASK-rectification-collect-semantics-20260910.md` T3)**:`expectedWriteFromCollectIntent` 只把 `provide_new_evidence` 与 `answer_current_focus + has_new_dated_event` 判为需要写入;按分类器提示词,用户**直接用一件带年月的事回答采集题**会被标成 `answer_current_focus + yes` 且 `has_new_dated_event=false`(该字段定义为「除了回答当前问题之外」),于是 `expectedWrite="none"`,守卫只剩「记下了」文字判定兜着。这是任务书决策 4 自身的漏写,不是执行方偏差。
|
||
|
||
环境缺口:未跑 `next build`(worktree 下 Turbopack 拒外部软链),`/` 是否仍 Static 与首屏 gzip 未核;无登录态,第 15 条真人走查未做。
|