fix(rectification): persist refreshed probes only when the engine has new questions (BUG-655)

Empty refreshes were writing inference rows, and GET-selected probe keys could miss inference_state, so persist rejected the next card.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-12 01:51:57 +08:00
co-authored by Cursor
parent 6c9a089620
commit 512be9b76e
6 changed files with 450 additions and 23 deletions
+18 -2
View File
@@ -10145,7 +10145,7 @@
- 修复:池空且未收敛时 `refreshDiscriminatorProbes` 用活跃候选 `column_times`、全部已答键 `asked_probe_keys``refresh_probes=true` 调引擎,探针并入 `inference_state.probes`,不改 `candidate_set_id` / 已答题。每个候选集最多刷新 2 次。剩余候选 ≤5 时刷新上限 12/4。带月份的家人 `dasha_boundary` 不再因先验丢弃,只用于排序。
- 验证:`frontend/tests/rectification-probe-pool-exhausted-20260911.test.ts` T0/T1`tests/test_candidate_discriminator_contract.py` 刷新上限与家人月级边界。
- 防复发:刷新必须走现有 `keepAnswers` 回放路径(BUG-587 / BUG-594);`asked_probe_keys` 带全部已答键,同域同年去重(BUG-559)。性格题不得进刷新池(BUG-651)。
- 相关记录:BUG-651、BUG-654、BUG-629、BUG-559、BUG-587、BUG-594
- 相关记录:BUG-651、BUG-654、BUG-655、BUG-629、BUG-559、BUG-587、BUG-594
- 复发自:BUG-651(池空即交付,未先按剩余候选再出题)
- 修复版本:待发布
@@ -10161,7 +10161,7 @@
- 修复:刷新后仍无带年月题则出定向补事口述题(剩余换升层映射到领域,≥2 个具体例子,不带推算年份)。答新事则重算回 S2;答「没有了」才交付。交付条件改为收敛,或刷新与定向补事都用尽,或用户主动停。卡片标题「目前范围」,卡下「还能再收窄」取定向补事首条。禁用「这次给出」「最终」。
- 验证:`frontend/tests/rectification-probe-pool-exhausted-20260911.test.ts` T3/T4`rectification-collection-question-pool.test.ts` 定向补事;`agent-voice-copy-contract.test.ts` 禁词。
- 防复发:`!separation.sufficient && !probe``refreshExhausted && targetedCollectExhausted` 之前不得 `completeWithRange` / `finish`。不得静默空载体(BUG-652)。
- 相关记录:BUG-653、BUG-651、BUG-652、BUG-629
- 相关记录:BUG-653、BUG-651、BUG-652、BUG-655、BUG-629
- 复发自:BUG-651(池空即交付,未做定向补事)
- 修复版本:待发布
@@ -10180,3 +10180,19 @@
- 相关记录:BUG-651、BUG-627、BUG-442
- 复发自:BUG-627`ensureNonTerminalTurnExit` 只在点「接着问」时触发,不在答题事务里)
- 修复版本:`66f63c76`
## BUG-655 | 刷新无新题不得写推理账本;并入探针须与已答同名
- 状态:resolved
- 首次发现:2026-09-11
- 最近更新:2026-09-12
- 影响面:`refreshDatedDiscriminatorPoolIfNeeded``persistV9InferenceState`、GET `decideFromDossier``persistServerOwnedFocus`
- 用户现象:带年月题问完后刷新,GET 已选出下一道探针,但持久化层拒绝,界面再次停在没有下一问。
- 触发条件:训练门已开、带年月池空、刷新调用引擎后没有可并入的新题,或并入探针 id 与已答 id 命名不一致,或写入时候选被清空 / 候选集被改掉。
- 根因:刷新在引擎没有新题时仍写 `reason=supersede` 的推理记录;GET 侧可能选中未映射进 `inference_state.probes` 的引擎探针,`expectedAnswerSchemaFor` 盖不上 `probe_id` 后 persist 返回 `invalid_choice_schema` / `skipped`
- 修复:只在引擎映射出可问新题时写库;写入前断言候选非空且 `candidate_set_id` 不变,候选沿用刷新前集合;并入探针 id 与已答同一规则(`probe:<semantic_key>` 或带 split hash);刷新只把可问探针写进 `inference_state.probes` 和 receiptGET 选中的 key 必须能 stamp 上 `probe_id`
- 验证:`frontend/tests/rectification-probe-pool-exhausted-20260911.test.ts` T0 打印最后一行推理记录与 GET 探针 key / persist 状态;T3 空刷新与候选集变更不写库。
- 防复发:刷新写库必须同时满足新题、候选非空、候选集不变、探针 id 与已答同名。不得靠客户端「接着问」补救(BUG-652)。
- 相关记录:BUG-653、BUG-654、BUG-652、BUG-587、BUG-594
- 复发自:BUG-653(刷新总会写库,未校验新题与候选集)
- 修复版本:待发布