docs(rectification): record the surface round — BUG-479..483, DESIGN.md rectification surface, walkthrough section 8

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
This commit is contained in:
Jesse_Chen
2026-09-02 04:56:38 +00:00
co-authored by Claude Fable 5.1
parent ef11f6e335
commit fec000f79d
5 changed files with 228 additions and 1 deletions
+80
View File
@@ -7362,3 +7362,83 @@
- 相关记录:BUG-477
- 复发自:无
- 修复版本:待发布
## BUG-479 | 生时校正会话面在打开、恢复与第一轮结束时各有一段空白,且整块重挂
- 状态:resolved
- 首次发现:2026-09-02
- 最近更新:2026-09-02
- 影响面:`page.tsx``use-rectification-surface.ts``use-session-management.ts``rectification-agentic-chat.tsx``starter-home.tsx``sidebar-session-row.tsx``app-sidebar.tsx``rectification-surface-state.ts`(新)
- 用户现象:首页点「生时校正」卡片无任何反馈;从侧栏点开已有校正会话先闪一帧普通对话、再整块空白、再重挂;新建校正第一轮回答结束时整个面板闪一下、滚动归零;恢复会话后问题槽在快照回来前空着;问题槽出现「正在等待服务端更新」的开发者文案。
- 触发条件:任意进入校正面;任意校正第一轮完成。
- 根因:面板 key 含 `rectificationTurns.length > 0 ? "ready" : "loading"`turns 到达即卸载重挂;`rectificationSurfaceOpen` 要求 `activeSession.id === rectificationSessionId`,而 `selectSession` 先切会话再异步 open;面板挂载后自己再拉一次快照;入口卡只 `disabled`
- 修复:`/cases/open` 返回后先 `hydrateRectificationCase`(一次 Case 读取同时取 turns 与快照,4 秒上限)再一次性切换会话;`selectSession` 对未打开的校正会话不再先 `setActiveSessionId`;面板 key 只保留 `${sessionId}-${caseId}`turns/快照作为初始 state,后到的 turns 经 prop 更新只填空 transcript;卸载时中止流与快照读;入口卡与侧栏行给静态「正在打开…」/「打开中」;问题槽改为纯函数四态(`rectification-surface-state.ts`),缝隙期显示时间线 live 行并定时重拉,两次后给「重新加载」按钮,旧文案删除。
- 验证:`tests/rectification-surface-contract.test.ts``tests/rectification-surface-state.test.ts``rectification-agentic-entry`key 锁改写)、`rectification-spoken-collect`(文案锁改写)、`chat-session-url`
- 防复发:校正面一个会话只挂载一次;turns 与快照只能是 prop/state 更新;任何等待必须是时间线 live 行或问题槽 live 行,不得出现「等待服务端更新」类文案;揭幕后不得再出现非生成中的 spinner。
- 相关记录:BUG-480、BUG-481、BUG-478
- 复发自:无
- 修复版本:待发布
## BUG-480 | 选择题点击与采用候选之间有空帧、下一题卡片闪现,采用时只有按钮文案在变
- 状态:resolved
- 首次发现:2026-09-02
- 最近更新:2026-09-02
- 影响面:`rectification-agentic-chat.tsx`
- 用户现象:点完选项后「正在记录本次选择」行消失一帧,下一题卡片闪一下又没了,再出现新的「正在处理」行;点「采用此时间」只看到按钮变灰变成「正在采用…」,对话区静止数秒。
- 触发条件:任意会继续追问的结构化选择;任意采用候选。
- 根因:`submitStructuredChoice``willContinue` 分支删掉 thinking 行、置 `choiceContinuationPending`,由下一次 effect 再 `send("read_only")` 并重新追加一行;中间 `busy` 掉回 false`showLiveChoiceCard` 对刚装进的新卡片为真。`acceptCandidate` 不在 transcript 里放任何 live 行。
- 修复:`send` 增加 `continuation: { reuseAssistantRenderKey, label }`,续接同一条 live 行并跳过 busy 守卫;选择与采用都在同一个 async 链里 `await loadCaseSnapshot()` 后直接 `await send("read_only", …)``busy` 全程为 true`choiceContinuationPending` 与对应 effect 删除;采用时先追加「正在采用 HH:MM…」行。
- 验证:`tests/rectification-surface-contract.test.ts``rectification-agentic-entry`(采用链锁改写)、`rectification-answer-choice``send("read_only", "")` 锁改写)。
- 防复发:续接的回合复用已有 live 行,不得删行再由 effect 追加;`busy` 在整条链上不得中途回落。
- 相关记录:BUG-479
- 复发自:无
- 修复版本:待发布
## BUG-481 | 开场失败或未持久化的校正会话再进来永远空白,没有任何起点
- 状态:resolved
- 首次发现:2026-09-02
- 最近更新:2026-09-02
- 影响面:`rectification-agentic-chat.tsx``rectification-surface-state.ts`
- 用户现象:从侧栏进入一个没有任何记录的旧校正会话,画面空白,输入框可用但用户不知道该先说什么。
- 触发条件:服务端对 resumed case 一律返回 `should_start_opening=false`,且该 case 的 turns 为空。
- 根因:面板只在 `shouldStartOpening` 为真时自动发开场,其它情况不显示任何 CTA。
- 修复:`rectificationConversationState` 判定 `empty` 时显示「这段校正还没有开始。」与「开始提问」按钮,调用已有的 `send("opening", "")`;服务端已抑制重复开场,客户端 `openingStarted` 守卫。不改服务端与 SQL。
- 验证:`tests/rectification-surface-state.test.ts``tests/rectification-surface-contract.test.ts`
- 防复发:面板任何"无内容"状态都必须给出下一步动作。
- 相关记录:BUG-479
- 复发自:无
- 修复版本:待发布
## BUG-482 | 用户的选择不回显、选中无确认感
- 状态:resolved
- 首次发现:2026-09-02
- 最近更新:2026-09-02
- 影响面:`rectification-agentic-chat.tsx``rectification-choice-card.tsx``globals.css`
- 用户现象:点完选项,transcript 里没有一条"我选了 B",刷新后更看不到自己答过什么;卡片选中后没有对勾,等待时只是鼠标变沙漏。
- 触发条件:任意结构化选择。
- 根因:答过的卡贴在 assistant 消息下但不产生用户行;服务端返回的 `userMessage``applied.userDisplay`)客户端未用;持久化的结构化选择 turn 被 `isStructuredChoiceUserText` 过滤掉;卡片 pending 只改 `cursor: wait`
- 修复:点击即以 `userVisibleChoiceLine`(停止用 `stop_label`)追加用户气泡,成功后以服务端 `userMessage` 校正文本,失败则连同 live 行一起移除;`messagesFromTurns` 保留结构化选择 turn;卡片选中项显示 `Check` + 「已选择」,pending 时卡顶一行 `InlineSpinner` + 「正在记录…」。
- 验证:`tests/rectification-surface-contract.test.ts``rectification-agentic-entry``isStructuredChoiceUserText` 锁改写)。
- 防复发:用户的每个动作在 transcript 里都要有对应的用户行;等待态必须有可见进度。
- 相关记录:BUG-480
- 复发自:无
- 修复版本:待发布
## BUG-483 | 盘面首态是一整块空面板
- 状态:resolved
- 首次发现:2026-09-02
- 最近更新:2026-09-02
- 影响面:`rectification-board.tsx``rectification-board-model.ts``rectification-surface-state.ts``page.tsx``globals.css`
- 用户现象:第一阶段右侧 18–22.5rem 的面板只有一句「补充经历后,这里会显示当前本命宫位和换升时刻。」;移动端 peek 是「补充经历后会在这里更新」。用户明明填过出生时间。
- 触发条件:任何候选结果出现之前。
- 根因:面板没有拿到填报时间;快照 API 不含填报时间对应的宫位表(已核实 `cases/[caseId]/route.ts` 只有 accepted/confirmed time)。
- 修复:面板新增 `declaredTime``page.tsx` 从 profile 派生),无结果时时钟位显示填报时间,正文两行「填报出生时间 HH:MM」「回答几个问题后,这里会显示宫位随时间的变化。」;peek 为「当前盘面 · 填报 HH:MM」;`is-board-empty` 把板列收为 `minmax(16rem, 18rem)`。不造宫位数据。
- 验证:`tests/rectification-surface-state.test.ts``tests/rectification-surface-contract.test.ts``rectification-board-model`
- 防复发:面板空态必须显示已知的用户数据,不得只放一句说明。
- 相关记录:BUG-479
- 复发自:无
- 修复版本:待发布
@@ -56,3 +56,22 @@
---
四轮改造:BUG-464(消息权威化)、BUG-465(会话 URL)、BUG-466(云端唯一真相)、拆页两批。自动化侧每轮均已验收(tsc / 2400+ 条测试 / 构建 / SQL 幂等),此清单覆盖的是自动化够不着的真浏览器行为。
## 8. 生时校正面:一次揭幕与无缝续接(BUG-479–483)
1. 首页点「生时校正」卡片。
- ✅ 预期:卡片脚注立即变成「正在打开…」(不转圈),随后**一次性**出现完整面板:历史消息、问题槽、右侧盘面同时就位;不会先出现一个空面板再填内容。
2. 在普通对话里,从侧栏点一个已有的校正会话。
- ✅ 预期:旧画面保持不动,侧栏该行短暂显示「打开中」,然后直接切到校正面板;**不闪**一帧普通对话,**不出现**空白面板。
3. 新建一段校正,等第一条引导说完。
- ✅ 预期:第一轮结束的瞬间画面不闪、滚动不归零、时间线开合状态保留。
4. 连续答两道选择题。
- ✅ 预期:点完选项立刻在卡上看到对勾「已选择」、卡顶一行「正在记录…」,transcript 里出现你选的那句作为你的气泡,后面一条「正在记录本次选择…」的进行中行**一直在**,直到下一题出现;中间没有空帧,下一题卡片不会闪现又消失。
5. 出现候选时间后点「采用此时间」。
- ✅ 预期:transcript 末尾出现「正在采用 HH:MM…」进行中行,同一条行一直到后续回复出现。
6. 找一个当初开场失败的旧校正会话(记录为空)进入。
- ✅ 预期:看到「这段校正还没有开始。」和「开始提问」按钮,点后正常开场。
7. 右侧盘面在没有候选前。
- ✅ 预期:头部时钟位显示你填报的出生时间,正文是「填报出生时间 HH:MM」两行;面板比有结果时窄一些。
8. 流式回答中点停止。
- ✅ 预期:已生成内容保留,提示「已停止,已生成的内容保留;本次不会扣点。」,不是「暂时不可用」。