# TASK · 生时校正修复单:范围已收到 2 分钟、决策已是采用,却把答过的财务题再问一遍(2026-09-08)
- 基线:`origin/staging` @ `df182c16`(BUG-584~589 已合入并部署;事故 Case 就是这版跑出来的,Skill 10.0.15)
- 分支:`codex/rectification-covered-domain-recollect-20260908`,基于 `origin/staging`
- 执行方:coding agent;验收:Claude
- 涉及文件:`frontend/src/lib/rectification-agentic/v9/method-followup.ts`(L2224 起的 yearless→采集分支、`holdoutFollowupFor`)、`v9/server-focus.ts`(`persistCollectFocus` 的 `:next` 重试)、`v9/answer-choice.ts`(`shouldSkipFollowupPersist`)
- BUG 编号起点:**BUG-590**(`docs/BUG_HISTORY.md` 当前最大 BUG-589)
- 优先级:**P1**(收敛已经成功,出口被一道重复题堵死;用户原话"怎么又问相同的问题 而且时间已经收敛到 2 分钟的范围了")
## 1. 事故实证(2026-09-08 staging `df182c16`,Case 导出;只写结构)
| 项 | 事实 |
| --- | --- |
| 推断状态 | 6 道题全部重放(`rounds` 6 条、`carried: true`、分盘 key 已是星座分区),`credible_range = 04:51–04:53`,`stop_reason = probe_pool_exhausted` |
| 决策 | `type = ready_to_adopt`、`session_outcome = adopt_representative`、`can_adopt = true`、`step_state.stage = deliver` |
| 当前问题 | `collect:finance:collect_method_evidence:next`,题干 = `USER_COLLECT_QUESTION.finance` 逐字。财务领域账本里已有一条带年月的确认事件(`usage = holdout`),该领域焦点早已 `resolved` |
| 该轮 receipt | `rectification-set-focus` **failed** `focus_idempotency_conflict`;随后闲置路径把同题以 `:next` 后缀落库 |
| 界面 | 没有区间交付卡(采集焦点挂着即 `interviewQuestionBlocksAdoptOffer`),输入框上方是财务题 |
BUG-587 的重放已经把范围收到 2 分钟,出口本该是区间交付卡。
## 2. 根因
### 2.1 BUG-590(P1):职业覆盖后的"无年份分盘题→采集"分支不看领域是否已覆盖
`method-followup.ts` L2224:`!next && dashaCovered && coverageComplete && occupationCovered` 时取 `yearlessDiscriminators[0]`(本例是 D11 财富分盘的对照题,D24 学业题因账本已提到该分盘被降权、D12 家人题被拒答),把它的领域直接变成一道 **dated collect**(`intent = collect_method_evidence`、`source = method_coverage`、无 `choice_frame`)。分支只检查 `!declined.has(domain)`,不检查该领域是否已有带年月事件、是否已问过采集题。财务已经答过,于是再问一遍。
这个分支的本意是"分盘对照题没有年份可锚,先向该领域要一件带年月的事";领域已经有带年月事件时,再要一件也锚不上(引擎把它标成 `yearless_ungrounded_contrast` 不是因为缺事件),应当跳过该领域、继续找下一个,没有就交付。
链条第二环:`answer-choice.ts::shouldSkipFollowupPersist` 对 `canAdopt = true` 的决策,只要 `isRemainingEvidenceCollect(followup)`(领域在 `DATED_COLLECT_ORDER` 里)就不跳过 → 采用被这道题挡住。第三环:工具层 set-focus 用同一 `next_followup` 落库,`questionId` 与已 resolved 的财务焦点相同 → `focus_idempotency_conflict`;闲置路径再来一次。
### 2.2 BUG-591(P2):采集焦点撞 id 时无条件加 `:next` 再插一次
`server-focus.ts::persistCollectFocus` L359:`insertFocus(questionId)` 报 `focus_idempotency_conflict` 就改用 `${questionId}:next` 再插。这是 `75fc456d`(BUG-462 附带)为"穷尽采集撞开场题号"加的;BUG-586 删掉 other 穷尽采集后,它只剩副作用——同一领域的采集题只要被计划层重复派出,就一定能以 `:next` 落地。撞 id 本身就是"这题问过了"的信号,非 `collect_retry` 的采集题应当在这里止步。
### 2.3 P2:holdout 的 `occupied` 不认 `health` / `health_pressure` 同义
`holdoutFollowupFor` 用账本领域算 `occupied`,账本里健康事件的 `domain = "health"`,而 `oos_blind_prompts` 用 `health_pressure`;用户答了健康事件后,holdout 仍会把健康当"没用过的线"再问一遍。`datedCollectDomainBlocked` 已经用 `hasConfirmedHealth` 处理了这对同义词,`holdoutFollowupFor` 没有。本例没触发(财务题先挡住),但下一次会。
### 2.4 记录:转录里选择题题干看似出现两次
选择题的题干在问题块 `
` 与卡片 `