Files
Jyotisha/docs/tasks/TASK-rectification-message-cleanup-20261001.md
T

94 lines
9.4 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.
# TASK · 生时校正消息清理:题干只出现一次 / 正文复述变短 / 去掉结算后的步骤回执(2026-10-01)
## 基线
- `origin/staging` @ `00420f89`(写作时 head;开工时以最新 `origin/staging` 为准)。盘型口径(BUG-1115~1117、1131)已在其中。
- 分支 `codex/rectification-message-cleanup-20261001`,工作树 `.worktrees/rectification-message-cleanup-20261001`。
- **并行关系**:与 `TASK-rectification-chart-tier-caveats-20261001.md`(报告 / 聊天标注不可判分盘)文件不重叠,可并行;两单都会追加 `docs/BUG_HISTORY.md`、`CHANGELOG.md`、`frontend/DESIGN.md`,后合入者解冲突保留两侧。与 `TASK-consult-plain-answer-20261001.md` 不重叠。
- 不动冻结计分文件(`sealed_holdout_rerun.py::PRODUCTION_FILES`)、引擎、出题、出卡时机、盘型交付逻辑。
## 事故实证
产品负责人 2026-09-29 staging 真机,一条校正回复呈现为:
```
已完成 3 步
1.
记下了:2000年 随家人搬家、2006年 小学毕业、…、2025-02 工作开始不稳定。
2024 年 1 月前后,你有过搬家或者长期住到外地的情况吗?
2024 年 1 月前后,你有过搬家或者长期住到外地的情况吗?
A. 明确发生且时间吻合 B. 发生过但程度较弱 C. 明确没有发生 D. 这段记不清楚
```
2026-10-01 产品追问「为什么 Agent 输出下面要跟一个问题,这一部分怎么优化」。Claude 只读调研(`origin/staging` @ `a8820f2c`):
| 块 | 渲染位置 |
| --- | --- |
| 步骤回执「已完成 N 步」 | `components/chat-message-row.tsx`(rectification 分支)→ `ConsultationRunTimeline`(`components/consultation-run-timeline.tsx` 的 `已完成 ${rows.length} 步`),行来自 `rectification-message-entry.tsx::rectificationTimelineRows` |
| 正文 | `ChatMessageContent`(`chat-message-row.tsx`) |
| 题干 | `rectification-message-entry.tsx` 的 `<p className="rectification-message-question__prompt">{question.prompt}</p>`——**只要 `question` 存在且消息已结算就打印,即使嵌入卡为 null(作废 / 被替换的旧题)** |
| 选项 | `components/rectification-choice-card.tsx`(legend 是 sr-only,不另显示题目) |
| 独立问题块 | `components/rectification-question-gap-notices.tsx` 两处打印 `currentQuestion.prompt` + 嵌入卡 |
题干可见位置共三处:正文(未剥净时)、消息内题干、独立问题块。
## 根因
1. **题干两遍(主因,待执行方 DOM 复现确认)**:最新消息挂着一道已作废 / 被替换的旧焦点,题干文字与新焦点相同。`rectification-message-entry.tsx` 对它仍打印题干(BUG-917 路径,无选项);`rectification-snapshot-messages.ts::placePersistedQuestion` 因焦点 id 不同把新题设为 `standalone`,`rectification-question-gap-notices.tsx` 再打印一次题干 + 选项 → 「题干、题干、选项」。`turn-question.ts::attachQuestionsToTurns` 同一轮多个焦点只保留最后一个,是可能的诱因。
2. **次因(同时防住)**:`placePersistedQuestion` 把问题挂到最新已结算消息时**不剥正文里的题干**;正文剥离只在 `agent-run-attempt.ts`(焦点已绑本轮时)、`turn-question.ts`(GET)、`rectification-snapshot-messages.ts::mergeTurnQuestions`(turnId 命中时)三条路径做。
3. **正文过长**:证据轮正文按提示要求逐条复述「记下了:年 月 事件、…」,开场一次说 12 件时整段占满屏幕,题目被挤到下面。
4. **结算后步骤回执**:记录经历、重打分、出题是系统内部步骤,结算后折叠的「已完成 N 步」对用户无信息量;「1.」疑为列表序号泄漏(`globals.css` 已 `list-style: none`,需执行方定位)。
## 决策记录(产品 2026-10-01)
- **D1 一屏一题干**:任一时刻屏幕上只有**当前有效焦点**打印题干;作废 / 被替换的旧焦点在消息上**什么都不显示**(不留半句题干,不显示「已作废」)。题干只能出现一次(`DESIGN.md` 现有规则不变,本单补代码守卫)。
- **推翻**:BUG-917 中「作废题保留题干、去掉选项」的显示方式;执行方在该条防复发下追加「2026-10-01 产品修订:见本任务书 D1」,不删原文。
- **D2 正文复述变短**:证据轮正文只说「记下了 N 件事」(N = 本轮实际入账件数);入账清单作为可展开的列表,**数据来自服务端证据记录**,不来自模型正文。N ≤ 2 时可直接列出两件,不折叠。
- 推翻 `frontend/docs/VOICE.md` 与 Agent 提示中「证据轮正文只写一句复述『记下了:年 月 事件短语(、…)。』」的逐条复述要求,改为本条。
- **D3 校正回复结算后不再显示「已完成 N 步」**:生成中的步骤进度(等待态)保留不变;结算后整块不渲染。只作用于生时校正,普通对话不变。
- 推翻 `DESIGN.md` 中校正与普通对话「共享全部等待词汇」里**结算后回执**这一项;等待态共享不变。
- **不做**:不改选项、不改题干写法(仍由 Agent 经 set-focus 写、服务端核对)、不改出题与计分、不改盘型交付卡。
## 硬红线
1. 不得再出现第二个问题渲染位置;不得手写第二个聊天输入框 / 滚动跟随 / 加载动画(AGENTS §6)。
2. 刷新、历史打开、实时三条路径(实时流式、GET 重建、快照合并)都满足 D1;旧 Case(盘型口径之前、旧 Skill 版本)打开不报错、不丢选项(BUG-621)。
3. 前端:tsc 0、lint 0 error、npm test 失败清单与开工基线逐名一致且基线测试名 0 丢失(按 `frontend/AGENTS.md` 的名单 diff)、`/` Static、首屏 gzip ±2%。
4. 改既有断言写「原值 / 新值 / 原因」;按源码文本断言的合同测试先 grep(`frontend/tests/`、`tests/`)。
5. Agent 提示改动按 CHANGELOG 规则记录;若改到 Skill 文本须 bump 并验证历史 Case 可打开。
6. 隐私:测试 fixture 只用虚构数据;Bug 历史不写真机事件内容。
## 任务分解
- **T1 一屏一题干(BUG-1135)**
- 先写失败测试复现两种形状:(a) 最新消息带作废旧焦点 + 独立问题块的新焦点、题干文字相同 → 页面题干出现 2 次;(b) 正文末尾含题干句 + `placePersistedQuestion` 挂题 → 题干出现 2 次。DOM 级(渲染后数 `rectification-message-question__prompt` 与 `persisted-question` 中题干文本出现次数),不只断言数据结构。
- 修:`rectification-message-entry.tsx` 只为当前有效焦点打印题干;`placePersistedQuestion` 挂题时同样剥正文题干句(复用 `collect-prompt.ts::stripQuestionSentences`,不新写正则);查清 `attachQuestionsToTurns` 同轮多焦点是否会让旧焦点落到最新消息,必要时只挂有效焦点。
- 验收:(a)(b) 先红后绿;实时 / GET / 快照三路径表驱动断言「题干恰好 1 次」;BUG-917、BUG-1045、BUG-1046 的既有测试不放宽。
- **T2 正文复述变短(BUG-1136)**
- 服务端:证据轮正文改为确定性的「记下了 N 件事」,N 与清单来自本轮入账证据(`agentic_rectification_evidence` 读模型 / 现有 dossier 投影),模型不再写复述;Agent 提示相应删去逐条复述要求。
- 前端:清单作为该消息内可展开列表(默认折叠,N ≤ 2 直接显示),展开交互不新增加载动画。
- 验收:一次说 12 件 → 正文一行 + 折叠清单 12 条,日期与精度显示与 `display_date_label` 一致;0 件入账(全被拒)时正文说明而非「记下了 0 件」;`VOICE.md` / `DESIGN.md` 同提交更新。
- **T3 结算后不显示步骤回执 + 「1.」泄漏(BUG-1137)**
- 校正消息结算后不渲染 `ConsultationRunTimeline`;生成中保留。定位截图中「1.」来源并修。
- 验收:结算 / 刷新 / 历史打开均无「已完成 N 步」;生成中步骤进度照常;普通对话回执不变(测试锁定)。
- **T4 记录**:`docs/BUG_HISTORY.md`(BUG-1135~1137,检索 BUG-585 / 917 / 1045 / 1046 并在 1135 写「复发自」关联及旧防线为何未拦住)、`CHANGELOG.md`、`frontend/DESIGN.md`、`frontend/docs/VOICE.md`、`docs/testing/rectification-message-cleanup-20261001.md` 真机清单(开场一次说 10 件以上;答一题后出下一题;刷新;打开旧 Case)、`docs/tasks/PROGRESS-rectification-message-cleanup-20261001.md`、`docs/tasks/README.md`。
## 让步顺序
T1 > T3 > T2 > T4 之外的截图。T1 缺之不可合入。
## 开工前置命令
```bash
git fetch origin --prune
export PATH=/exec-daemon:$PATH && node -v # 22.x
git worktree add -b codex/rectification-message-cleanup-20261001 .worktrees/rectification-message-cleanup-20261001 origin/staging
cd .worktrees/rectification-message-cleanup-20261001/frontend && npm ci
./node_modules/.bin/tsc --noEmit && npm run lint
npm test 2>&1 | grep -E "^(not )?ok [0-9]+ - " | sed -E 's/^(not )?ok [0-9]+ - //' | sort > /tmp/msg-cleanup-names-base.txt
```
## BUG 编号
开工时核对 `docs/BUG_HISTORY.md` 最大号(写作时 `BUG-1131`;`1132`~`1134` 已被 `TASK-consult-plain-answer-20261001.md` 预留)。本单:**BUG-1135**(题干两遍)、**BUG-1136**(证据轮正文逐条复述过长)、**BUG-1137**(结算后步骤回执与「1.」泄漏)。号冲突顺延并在 PROGRESS 说明。关联 BUG-585、BUG-917、BUG-1045、BUG-1046、BUG-621。