fix(consult): progress timeline shows only real steps, not the answer outline (BUG-1145)
Independent Staging Quality Gate / validate (push) Successful in 14m43s
Independent Staging Quality Gate / publish (push) Successful in 3m46s

The answer outline (think.plan / thinking.section) was drawn as four think
rows and ticked done as soon as the chart calculation started. The reducer
now keeps the outline only as calculate-row detail; live and history views
share it. Product chose option B on 2026-10-01.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
Jesse_Chen
2026-10-01 16:40:27 +08:00
co-authored by Claude Opus 5.5
parent f1a169cb93
commit c0f059125b
9 changed files with 195 additions and 43 deletions
+16
View File
@@ -15376,3 +15376,19 @@
- 相关记录:BUG-1116、BUG-1143、BUG-1105。
- 复发自:无
- 修复版本:`codex/rectification-segment-order-20261001`。
## BUG-1145 | 普通对话进度栏提前打勾:回答提纲在算盘前就显示为「已完成」
- 状态:resolved(2026-10-01 Claude 直接执行;单测复现修前失败、修后通过;未部署时以部署后 health 为准)
- 首次发现 / 最近更新:2026-10-01 / 2026-10-01
- 影响面:`frontend/src/lib/consultation-run-timeline.ts`(普通对话进度栏的实时与历史重建共用同一个 reducer);生时校正进度栏不用这个 reducer,不受影响。
- 用户现象:发问后,「先回答你问的这件事」「把判断钉在盘上」「时间窗口怎么看」「这周可以做什么」四行立刻全部打勾,而这时「正在计算本命盘…」还在转,正文一个字都没写。
- 触发条件:任何本命普通对话首轮(通用 / 每日 / 申报时段的计划节同理)。
- 根因:服务端在第一个流块就下发回答提纲(`think.plan` + 每节一条 `thinking.section`);reducer 把每节做成一行 live 的 think 行,而 `completeLiveThink` 在下一个事件(下一节、`tool.started`)到来时把所有 live think 行标成完成。提纲是「回答将怎么写」,不是已走过的步骤,却按步骤渲染,于是算盘一开始四行就假完成。自 09-18 进度栏设计(`94c1e81f`)起即存在;BUG-1132 之后回答按人分段、「盘上依据」「时间怎么看」可省,提纲与真实正文进一步对不上。
- 修复:产品 10-01 选 B——提纲不再成行。`think.plan` 不改状态;`thinking.section` 只把领域与对照项暂存为计算行的明细(`calculateHints`),在计算行出现时补上(实时与历史一致);正文开始(`answer.delta`)时计算行收口为完成;历史重建的思考文本改走 `thinking.delta` 行,不再挂在提纲行上。服务端仍下发 `think.plan` / `thinking.section`(公共事件合同与存档字段不变,供 `applyThinkingSectionProgress` 等使用),客户端只是不再把它们画成行。
- 验证:`frontend/tests/consultation-run-timeline.test.ts` 新增三条(算盘前提纲不成行、只有「读取分析方法」完成;整轮结束无提纲行、无 live 行;历史重建与实时同形且计算行仍有明细),三条在修前代码上失败、修后通过;改写一条既有断言(三栏见测试注释)。
- 防复发:进度栏只画真实发生的步骤(方法、计算、写作、模型推理);回答提纲若要再上屏,必须由正文标题驱动、不能用「下一事件到来即完成」的规则。
- 相关记录:BUG-942~944(进度 / 思考 / 正文分通道)、BUG-1074(发出即显示排队行)、BUG-1132(按人分段)。
- 复发自:无
- 修复版本:`codex/consult-timeline-no-plan-20261001`。
@@ -0,0 +1,34 @@
# PROGRESS · 普通对话进度栏去掉回答提纲行(2026-10-01)
任务书:`docs/tasks/TASK-consult-timeline-no-plan-20261001.md`;BUG-1145。
## 实现
- `frontend/src/lib/consultation-run-timeline.ts`:
- `think.plan` 直接返回原状态(不再生成提纲行)。
- `thinking.section` 只把领域与对照项累积到新增的 `calculateHints`,经 `applyCalculateHints` 补到计算行;`tool.started` 建计算行时也补上(提纲在算盘前下发,原 `enrichCalculate` 在实时流里因计算行尚不存在而落空,历史重建里才有明细;现在两边一致)。
- `answer.delta` 同时把计算行收口为完成(原来由 `thinking.section` 顺手收口)。
- `consultationTimelineFromSettled`:有思考文本就发一条 `thinking.delta`,删掉「把思考文本挂到最后一条提纲行」的补丁。
- 服务端 `think.plan` / `thinking.section` 照发(公共事件合同、`consultation-agentic-runtime` 测试锁定 `think.plan` 存在;客户端已不再用它画行)。`thinkPlanSteps` 仍被服务端与测试使用,未删。
## 改动的断言(原值 / 新值 / 原因)
| 测试 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| `consultation-run-timeline.test.ts` 首条(改名为 “…then the first write (no outline row)”) | 行种类 `["method","calculate","think","write"]`,第 3 行「先回答你问的这件事」已完成 | 行种类 `["method","calculate","write"]`,不存在该标签行;写作行下标 3→2 | BUG-1145:提纲不是步骤,产品选 B 去掉 |
新增三条:算盘前提纲不成行且只有方法行完成;整轮结束无 think 行、无 live 行;历史重建同形且计算行有明细。三条与改写的一条在修前代码上均失败(已实测:4 fail),修后通过。
## 门禁(Node 22.14)
| 项 | 基线 `f1a169cb` | 分支 |
| --- | --- | --- |
| tsc | — | 0 |
| lint | — | 0 error / 126 warning |
| npm test | 4,851 条,fail 24 | 4,854 条,fail 24(同名) |
| build `/` | — | Static |
| `.next/static` js gzip 合计 | 1,632,680 B | 1,632,662 B(−18 B) |
## 环境缺口
- 浏览器级(真机看进度栏)留给 `docs/testing/consult-plain-answer-20261001.md` 第 10 步。
+1
View File
@@ -400,3 +400,4 @@
- **实现合入 `staging` 的同一次推送里,必须同时把状态板那一行改掉。** 2026-09-16 的对账发现 10 份早已合入的单仍写着「待领取 / 待验收」,会导致重复派活。
| `TASK-consult-plain-answer-20261001.md` | `PROGRESS-consult-plain-answer-20261001.md` | 普通对话「还是废话」:09-17 四步开场形状(格局名 → 谁推谁修 → 扮演哪个象)逼出谜语,问父母时爸妈被揉成一段;产品授权推翻该形状,改成先答 + 按问题里的对象分段 + 人话自检 + 空宫不单独下结论 + 父母卡标 mother/father(BUG-1132~1134) | **已实现,待 Claude 验收**(fork 子代理直接执行);未推 staging、未部署;模型对比为环境缺口,真机清单 `docs/testing/consult-plain-answer-20261001.md` | 分支 `codex/consult-plain-answer-20261001` |
| `TASK-consult-answer-clock-20261001.md` | `PROGRESS-consult-answer-clock-20261001.md` | 普通对话答题时钟 70 s 容不下推理模型(v4-pro 77 s),无出生分钟路线只受 110 s 工具钟管;产品定 5 分钟防卡死(BUG-1142) | **已实现,待 Claude 验收**(直接执行) | 分支 `codex/consult-answer-clock-20261001` |
| `TASK-consult-timeline-no-plan-20261001.md` | `PROGRESS-consult-timeline-no-plan-20261001.md` | 普通对话进度栏提前打勾:回答提纲在算盘前就作为四行步骤显示并全部打勾(BUG-1145);产品选 B 去掉提纲行,只显示真实步骤 | **实现完成,待 Claude 验收**(直接执行) | 分支 `codex/consult-timeline-no-plan-20261001` |
@@ -0,0 +1,31 @@
# TASK · 普通对话进度栏去掉回答提纲行(2026-10-01)
- 基线:`origin/staging` `f1a169cb`
- 分支 / worktree:`codex/consult-timeline-no-plan-20261001` / `.worktrees/consult-timeline-no-plan-20261001`
- 模式:直接执行(产品 10-01 选 B 后明确要求直接做),Claude 派子代理实现、Claude 独立验收
- BUG:BUG-1145
## 事故实证
产品 10-01 真机截图:问「我跟我父母的关系怎么样」,进度栏「读取分析方法」之后立刻出现「先回答你问的这件事 / 把判断钉在盘上 / 时间窗口怎么看 / 这周可以做什么」四行且全部打勾,最下面「正在计算本命盘…」仍在转。
## 根因
`frontend/src/lib/stream-agent-response.ts` `flushThinkingPlan` 在第一个流块就下发回答提纲(`think.plan` + 每节 `thinking.section`);`frontend/src/lib/consultation-run-timeline.ts` `reduceConsultationTimeline` 把每节做成 live think 行,`completeLiveThink` 在下一个事件到来时把它们全标完成。提纲不是走过的步骤,却按步骤渲染。
## 决策记录
产品 10-01 在两案中选 **B:去掉提纲行,只显示真实步骤**(读取分析方法 → 计算本命盘 → 正在写 → 完成)。未选 A(提纲等算完再出现、按正文标题逐条打勾),原因:BUG-1132 之后回答按人分段、两节可省,提纲与正文对不上;产品偏好「多余入口宁可删除」。
## 硬红线
1. 只改渲染层(timeline reducer);服务端事件、`thinkingPlan`、`applyThinkingSectionProgress`、存档字段、API / DB 结构不动。
2. 生时校正进度栏不动(它不用这个 reducer,只共用行类型与组件)。
3. `page.tsx` 不增长;不加 spinner / 骨架。
## 任务与验收
- T1 reducer:`think.plan` 不改状态;`thinking.section` 只暂存计算行明细并在计算行出现时补上;正文开始时计算行收口。验收:新增回归测试在修前失败、修后通过。
- T2 历史重建与实时同形(`consultationTimelineFromSettled` 走同一 reducer;思考文本改走 `thinking.delta` 行)。验收:历史重建测试。
- T3 记录:BUG_HISTORY、CHANGELOG、DESIGN.md、真机清单第 10 步、本任务书与进度记录、索引。
- 门禁:tsc 0;lint 0 error;`npm test` 失败名单与基线同名;`next build` `/` Static;首屏 gzip ±2%。
@@ -13,3 +13,4 @@
| 7 | 第 1 步的回答如果明显被截断(最后一节没写完就停了) | 记下时间和模型名报给 Claude——这是取消字数上限后要盯的风险(见进度记录「长度副作用核对」) |
| 8 | (BUG-1142,答题时钟改 5 分钟后)选 `deepseek-v4-pro` 新开对话,问「我和父母关系如何,他们怎么对待我」 | 回答完整写到「这周可以做的一件事」,不出现「回答未完成」;记下从发出到写完大约多少秒 |
| 9 | 用没填出生分钟的人物档案、选 `deepseek-v4-pro` 问一个长问题(例如「完整讲讲我今年的事业和感情」) | 回答写完,不出现「回答未完成」 |
| 10 | (BUG-1145)新开对话问任一问题,盯住回答上方的进度栏 | 只出现「读取分析方法」「计算本命盘」「正在写…」这类真实步骤;不再出现「先回答你问的这件事 / 把判断钉在盘上 / 时间窗口怎么看 / 这周可以做什么」四行,也没有在算盘时就打上的勾;刷新后打开这条历史对话,进度栏一样 |