fix(rectification): prevent silent collect focus stalls
Independent Staging Quality Gate / validate (push) Successful in 20m38s
Independent Staging Quality Gate / publish (push) Successful in 24m14s

This commit is contained in:
Jesse_Chen
2026-08-30 23:07:17 +08:00
parent 0ae3e2d796
commit 79bfa73da3
5 changed files with 468 additions and 20 deletions
+16
View File
@@ -6926,3 +6926,19 @@
- 相关记录:BUG-352
- 复发自:无
- 修复版本:待 staging 部署;本地提交待生成
## BUG-452 | 采集焦点落库失败后静默结束
- 状态:resolved
- 首次发现:2026-08-30
- 最近更新:2026-08-30
- 影响面:`persistNextInterviewAfterChoice``persistFocusAfterChoice``persistExhaustionCollect`、POST `/api/rectification/agent` 非终态轮末出口
- 用户现象:答完家人采集题后助手只说「记下了,这方面先跳过。」,没有下一问也没有时间卡。
- 触发条件:上一采集焦点刚被关闭,下一条 `collect_method_evidence` 焦点落库返回 `duplicate_focus``skipped`;该轮同时没有可采用的候选承载。
- 根因:采集焦点落库失败时 `persistNextInterviewAfterChoice` 返回 `hostNarration=null`,随后被 denial 兜底文案「记下了,这方面先跳过。」吞掉;轮末也没有结构化不变量检查 `current_question` 或真实可采用承载,最终形成非终态但无可继续交互入口的静默死路。
- 修复:采集焦点首次落库失败后重读 dossier 并重试一次;若已存在同 `questionId` 的 active focus,则按 `already_open` 复用。重试仍失败时复用 `persistExhaustionCollect` 口径,正文写出可信区间、代表分钟和口述下一问,并尝试落一个可回答的采集焦点。自由文本轮末新增结构化非终态出口检查:若未 accepted、未 confirmed、未 user-stopped,且既无 `current_question` 也无真实可采用承载,则确定性补口述采集焦点、把题干写入正文,并记录不含用户内容的 `rectification_nonterminal_exit_repaired` 日志。删除会成为终局的 denial 单句兜底。
- 验证:修复前新增 fixture 证明 `duplicate_focus``skipped` 均会得到 `hostNarration=null``current_question=null`;修复后两条路径均有问题正文并持久化或复用非空焦点。新增非终态出口不变量回归,锁定服务端补出 `collect_spoken` 焦点和题干。复刻五证据、五条已答探针、活跃候选 `05:00/05:07/04:53`、family declined 的 case,锁定 `career.2023.dasha_activation``no_split_among_active` drop、`nextAction=offer_provisional_range``canAdopt=false`,轮末 `current_question.question_id=collect:occupation:collect_method_evidence` 且正文含「你长期做什么工作?」。`assert.doesNotMatch(afterRun, /answerText\.(?:includes|match|search)\(/)` 保持通过 本地 `npx tsc --noEmit`、改动文件 ESLint、目标四组回归 `122/122` 通过;focused 全套 `730/731`,唯一 Docker/PostgreSQL migration fixture 失败单独重跑 `1/1` 通过;全量基线 `2342/2347`,五项失败均为并行数据库容器/migration 环境波动或本机缺少 PyYAML,未扩大到产品逻辑。
- 防复发:非终态轮次结束时必须有 `current_question` 或真实可采用承载;任何采集焦点落库失败都不得静默降级为一句确认话。该不变量只看焦点与 decision/承载字段,不得用正文文本判断助手是否问出问题。不得为无选项题新造视觉容器或复用选择卡样式;不得引入语义正则、关键词表或 A/B/C/D 位置推断;`resolved``declined` 语义不得互换。
- 相关记录:BUG-441、BUG-449、BUG-450
- 复发自:BUG-450
- 修复版本:`fix(rectification): prevent silent collect focus stalls`Skill 保持 `10.0.13`