Files
Jyotisha/docs/tasks/PROGRESS-rectification-unwritten-evidence-claim-20260910.md
T

98 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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-641643。同一工作树交付 BUG-637640,见 `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-641643 未做。
## 验收结论(Claude2026-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 条真人走查未做。