fix(rectification): stop speaking unstampable distinguish stems (BUG-674/675)
Independent Staging Quality Gate / validate (push) Failing after 20s
Independent Staging Quality Gate / publish (push) Skipped

Distinguish followups that cannot stamp a probe now go to persistExhaustionCollect instead of repeating the card stem in the assistant body. Choice focuses without asked_turn_id hang on the last assistant turn, and persisted_question with a live choice_card renders the existing card. Representative-time inconsistency is warn-only (BUG-676 investigating).
This commit is contained in:
jesse-ux
2026-09-14 03:42:48 +08:00
parent 9375012f17
commit 69ffa07d6b
16 changed files with 887 additions and 46 deletions
+48
View File
@@ -10484,3 +10484,51 @@
- 相关记录:BUG-670、BUG-669、BUG-671、BUG-661
- 复发自:BUG-670
- 修复版本:待发布
## BUG-674 | 探针耗尽后判别题被念进正文,同一题反复问且答了不算数
- 状态:resolved
- 首次发现:2026-09-14
- 最近更新:2026-09-14
- 影响面:`persistNextInterviewAfterChoice``expectedAnswerSchemaFor` / `stampChoiceSchemaWithProbe``persistExhaustionCollect`
- 用户现象:答完带年月题后,正文反复出现同一句判别题(无 A/B/C/D)。用户打字回答「没有」只得到「记下了,这方面先跳过」,同一句再出现一次。
- 触发条件:`prospective_probes` 为空,精度阶段仍给出带 `choice_frame` 的判别题;`stampChoiceSchemaWithProbe` 盖不上 `probe_id`persist 返回 `invalid_choice_schema`
- 根因:上一单把「焦点没写成功」当成「题还在、只是没进消息」,把卡片题干拼进旁白。探针耗尽时这道题根本不该再问,也没有焦点可答。
- 修复:判别题(`intent === distinguish_candidates`,或带 `choice_frame` 的非采集题)落不了库时改走 `persistExhaustionCollect`,不得把题干写进正文。采集题仍可进正文,但与上一条助手消息相同的题干会去重并转耗尽分支。
- 验证:`frontend/tests/rectification-unstampable-probe-20260914.test.ts`
- 防复发:判别题落不了库时不得把题干写进正文;探针耗尽必须转定向补事卡。
- 相关记录:BUG-673、BUG-652、BUG-661
- 复发自:BUG-673(D3 把未落库题干拼进旁白)
- 修复版本:待发布
## BUG-675 | 快照已有 choice_card,界面仍画一行裸题
- 状态:resolved
- 首次发现:2026-09-14
- 最近更新:2026-09-14
- 影响面:`attachQuestionsToTurns``persisted_question` 渲染、`persistedQuestionSurface`
- 用户现象:`目前范围` 下面一行裸题(如「结过婚或订过婚吗?」),无头像、无选项、也没有「接着问」。
- 触发条件:`current_question.kind === "choice"` 且 GET `choice_card` 非空,但焦点没有 `asked_turn_id`,卡片无法挂到消息上;`persisted_question` 只画 `prompt`
- 根因:`persisted_question` 从设计起只服务口述题。BUG-673 把定向题修成点选后,这个纯文本块成了新的裸题来源。
- 修复:无 `asked_turn_id` 的活动选择题挂到最后一条助手消息,走既有消息内卡片。`persisted_question` 在有卡时渲染同一套 `RectificationChoiceCard`,不再只画一行字。
- 验证:`frontend/tests/rectification-unstampable-probe-20260914.test.ts``rectification-surface-state.test.ts`
- 防复发:`current_question.kind === "choice"` 且有 `choice_card` 时必须渲染可点卡,不得只画题干。不得新增第二套卡片组件。
- 相关记录:BUG-673、BUG-669、BUG-671
- 复发自:BUG-673(数据形态修好后渲染仍走口述兜底)
- 修复版本:待发布
## BUG-676 | 代表时间取到被淘汰候选
- 状态:investigating
- 首次发现:2026-09-14
- 最近更新:2026-09-14
- 影响面:`evaluateCandidateSeparation``rankActive`、decision receipt `representative_time` / `last_inference_round`
- 用户现象:同一轮 receipt 里 `representative_time` 落在 `eliminated_ids` 中(例如 05:14),界面范围是 04:48–05:07,也不含该分钟。
- 触发条件:本轮有淘汰名单,对外代表时间与 `winner_id` / 范围不一致。
- 根因:未知。已确认 `evaluateCandidateSeparation` 按 score 取 `ranked[0]``evaluateConvergence` 先滤 `status === eliminated` 再按后验排序。尚未拿到同一份 `inference_state.candidates`id / time / status / probability / posterior_score)与 `credible_range`,不能断定是 status 没写回、后验没重算,还是两套分数不是同一份。
- 修复:本轮只加不变量告警 `rectification_representative_time_inconsistent`(代表时间在 eliminated 内或落在 credible_range 外)。不改排序。
- 验证:`frontend/tests/rectification-unstampable-probe-20260914.test.ts` 两条告警路径。
- 防复发:代表时间必须不在本轮 `eliminated_ids` 内,且落在 `credible_range` 内。根因确认后另立修复单,不得为了「数字看起来对」顺手改排序。
- 相关记录:BUG-442
- 复发自:无
- 修复版本:待发布
@@ -0,0 +1,23 @@
# 进度 · 探针耗尽、裸题与代表时间(2026-09-14)
## 范围
- 分支:`codex/rectification-unstampable-probe-20260914`(基于 `origin/staging` @ `9375012f`
- 任务单:`docs/tasks/TASK-rectification-unstampable-probe-and-naked-card-20260914.md`
- BUG-674 / BUG-675 resolvedBUG-676 investigating
- 上一单 D3 已在任务书里标注推翻
## 完成
- T1`persistNextInterviewAfterChoice` 尾部对判别题改走 `persistExhaustionCollect`;采集题保留题干进正文,但与上一条助手消息相同则去重。
- T2`attachQuestionsToTurns` 把无 `asked_turn_id` 的活动选择题挂到最后一条助手消息;`persisted_question` 有卡时渲染既有 `RectificationChoiceCard`
- T3`warnRepresentativeTimeInconsistency`,不改排序。
- T4BUG_HISTORY、CHANGELOG、真机清单。
## 验收数字
- `./node_modules/.bin/tsc --noEmit`0 错
- `npm run lint`0 error120 warning,与基线同类,无新增 error)
- 相关单测 93/93`rectification-unstampable-probe-20260914.test.ts` 8/8,加上 collect-prompt / question-in-message / surface-state / targeted-spoken / targeted-card-live / answer-choice
- `npm test`2985 tests2818 pass / 153 fail / 14 skip。失败项是本机 Windows 基线(Caddy/CRLF、Docker、bash、workflow YAML、Skill SHA),新增用例均绿,没有新的校正产品失败
- `next build`:本工作树 `frontend/node_modules` 是 junctionTurbopack 拒绝软链;`--webpack` 编译成功后在收集 page data 时因本机 Skill 10.0.26 SHA 与 registry 不一致失败(环境问题,未改 skill 包)。`/` 是否仍 `○ Static` 需在有真实 `node_modules` 且 skill 哈希匹配的树上复核
+1 -1
View File
@@ -184,7 +184,7 @@
| `TASK-rectification-targeted-card-dead-20260913.md` | `PROGRESS-rectification-targeted-card-dead-20260913.md` | **P0**:定向补事卡在快照投影里拿不到 `choice_card`(承接焦点分支不重建 `choice_frame`),卡片看得见点不动、流程停在采集等待态;模型还会把定向题改写成口述题(BUG-669~671)。先于 tie-break 修复单执行 | 待验收 | `codex/rectification-targeted-card-dead-20260913` |
| `TASK-rectification-unstampable-probe-and-naked-card-20260914.md` | `PROGRESS-rectification-unstampable-probe-20260914.md` | **P0**:探针池空后判别题盖不上 probe → 焦点写不进 → 题干被念进正文、同一题反复问且答了不算数(BUG-674,推翻前一单 D3);快照已有 `choice_card` 但 `persisted_question` 仍只画一行裸题(BUG-675);同一轮 receipt 里 `representative_time` 取到 `eliminated_ids` 里的候选(BUG-676investigating | 待执行 | `codex/rectification-unstampable-probe-20260914` |
| `TASK-rectification-unstampable-probe-and-naked-card-20260914.md` | `PROGRESS-rectification-unstampable-probe-20260914.md` | **P0**:探针池空后判别题盖不上 probe → 焦点写不进 → 题干被念进正文、同一题反复问且答了不算数(BUG-674,推翻前一单 D3);快照已有 `choice_card` 但 `persisted_question` 仍只画一行裸题(BUG-675);同一轮 receipt 里 `representative_time` 取到 `eliminated_ids` 里的候选(BUG-676investigating | 待验收 | `codex/rectification-unstampable-probe-20260914` |
| `TASK-rectification-targeted-collect-spoken-focus-20260913.md` | `PROGRESS-rectification-targeted-collect-spoken-focus-20260913.md` | **P0**:定向补事题以采集型 schema 存进焦点,前端只能裸画一行题干(无头像无卡无修复入口),本轮计划的 D9 题被静默吞掉;BUG-670 的识别条件只认 `targeted_collect` 章,复原不了(BUG-673,复发自 BUG-670 | 待验收 | `codex/rectification-targeted-collect-spoken-focus-20260913` |
@@ -0,0 +1,20 @@
# 探针耗尽、裸题与代表时间:真机清单(2026-09-14)
分支 `codex/rectification-unstampable-probe-20260914`。本环境无 staging 登录态。
## BUG-674
进入当时那个校正会话,或再走一遍「答完带年月题、探针池空」。
- [ ] 正文不再反复出现同一句「2023 年 5 月前后,有没有开始一段认真关系…」且没有选项。
- [ ] 下一问是定向补事四选一卡,或诚实说明为什么现在没有下一题。
- [ ] 打字回答「没有」不会让同一句判别题再出现一次。
## BUG-675
- [ ] 「结过婚或订过婚吗?」或「家里添过丁或长辈住过院吗?」出现时带四个选项,可点。
- [ ] 刷新后仍是卡,不是一行裸题,也不应只剩「再说一件带年月的事就能继续」。
## BUG-676
- [ ] 打开当时那轮的 receipt(脱敏):记下 `inference_state.candidates` 每条的 `id` / `time` / `status` / `probability` / `posterior_score`,以及 `credible_range`。把这段交给修复单,不要改排序。