fix(rectification): keep candidate state coherent
Independent Staging Quality Gate / validate (push) Failing after 15m32s
Independent Staging Quality Gate / publish (push) Has been skipped

This commit is contained in:
Jesse_Chen
2026-08-27 13:59:38 +08:00
parent 518119acbd
commit 5f855c610c
30 changed files with 2109 additions and 167 deletions
+16
View File
@@ -6138,3 +6138,19 @@
- 防复发:结构化命令成功响应新增或变更决策字段时,客户端必须有消费合同;不得把 loading 状态写成持久化回答。服务器探针可锁定语义,不得把内部分类标签当成最终题干模板。
- 相关记录:BUG-391、BUG-392、BUG-394、BUG-398、BUG-401
- 修复版本:10.0.12
## BUG-403 | 生时纠正候选后验、展示排名和停止语义不一致
- 状态:resolved(本地修复,未提交)
- 首次发现:2026-08-27
- 最近更新:2026-08-27
- 影响面:生时纠正停止意图、方法追问、候选区分探针、结构化选择评分、候选结果投影、Profile freshness、候选采用 RPC、采用后反向核验续跑、A/B/C/D 选项文案
- 用户现象:用户在当前领域回答「没有了」后,系统误结束整个 Case 并提前展示候选;已有感情起止证据仍重复询问是否谈过恋爱;既有教育证据误抑制尚未问过的 D24 高信息量区分机会;一次结构化选择几乎淘汰全部候选;候选卡排名、`representative_time``credible_range` 与 inference 后验互相矛盾;首次采用候选返回 `candidate_profile_changed`;采用后虽已有 `verify_adopted_time` 计划但前端没有发起下一轮,反向前事核验不会出现;选择题标签未按服务端 `answer_class` 动态生成。
- 触发条件:局部否定被当作全局停止;方法覆盖只按领域而不看已确认事件语义;候选对比把 Evidence 内容推断成已问 probe;单轮冲突使用硬淘汰;持久化候选与 inference 各自投影;Profile freshness 把展示地点和历史 `active_birth_time` 当作本轮计算输入,却漏掉声明时间窗;候选采用只刷新快照,没有复用结构化选择的 `read_only` 续跑;动态选项按数组位置而非答案类别映射。
- 根因:停止语义、语义去重、asked-probe 账本、评分更新、公开候选投影和 Profile freshness 分别维护了不兼容规则。尤其 Evidence 只能证明事件存在,不能证明某个候选分组问题已经问过;展示地点和历史 `active_birth_time` 也不是本轮计算输入变化。
- 修复:仅明确的「结束校正 / 不想继续 / 直接给结果 / 就到这里」触发全局停止,并排除「不是 / 不要 / 还没」等否定语境;普通「没有 / 没有了 / 想不起来了」只关闭当前领域。已确认感情证据抑制泛化 D9 复问,但不抑制真实候选区分 probe。structured/varga probe 只按 inference receipt 的已答 key 去重,普通事件 probe 按 live evidence 的 `domain.year` 去重,保留未问过的 D24/varga 高信息量分组。结构化答案改为累计软评分,累计 3 次唯一 strong conflict 才淘汰,并保证至少一个候选存活。UI、API、Mastra 和报告统一从 active inference 候选投影排名、代表时间和可信区间;候选映射、cluster range、代表时间或 receipt range 任一不一致时隐藏候选并禁止采用。新增向前迁移和统一 fingerprint:忽略展示地点与历史 `active_birth_time`,对出生日期、原始时间、时间来源/时段、声明时间窗、不确定范围、经纬度和时区等真实计算输入变化立即 rebaseline、失效结果并在采用事务内 fail closed。采用期间复用现有 `pending/busy` 锁定输入,刷新快照后再由既有 continuation effect 发起 `read_only`,避免采用与普通消息并发,并让 `candidate_accepted` 状态进入 `verify_adopted_time` 反向前事核验;不新增平行状态机。采用 RPC 在存在 append-only inference transition 时以最新 transition 为权威,仅在没有 transition 时回退 immutable result receiptrevision、candidate set 和候选 load-bearing JSON 字段缺失或矛盾时 fail closed。SQL read projection 同样只在没有 transition 时回退 immutable receiptlatest transition 存在但 revision、candidate set 或 nested inference 矛盾时删除 `inference_state``decision_state_fingerprint`,使 GET 隐藏候选并与 POST 采用同步 fail closed。选项标签按 `answer_class` 映射,写死文案只保留为 fail-closed fallback。
- 验证:相关 TypeScript 串行全量套件 2109/2109 通过;最终 SQL read/write coherence 修复后的受影响数据库与迁移套件 24/24 通过。新增回归覆盖感情泛化复问、D24 structured probe 不被普通教育 Evidence 屏蔽、累计冲突软淘汰、候选投影不变量、latest inference transition 权威采用、候选 JSON 缺少 status/probability/posterior_score 时 fail closed、矛盾 latest transition 时 GET 隐藏候选且采用 RPC 拒绝、采用/普通消息互斥、展示字段 fingerprint 稳定和声明时间窗 freshness。`tsc --noEmit` 通过;定向 ESLint 0 error2 条既有 warning);`git diff --check``scripts/pre_work_check.py` 通过。
- 防复发:Evidence 语义覆盖不得替代 structured probe receipt;单个启发式选择不得一票淘汰候选;公开候选卡、代表时间、可信区间与采用入口必须共享 active inference 投影;投影不变量失败必须 fail closedSQL read projection 与 accept write authority 对 latest transition 必须采用同一权威顺序和一致性条件,禁止 GET 回退旧 receipt 而 POST 拒绝;展示字段和采用输出不得进入计算 fingerprint,声明时间窗必须进入;采用期间必须锁定消息发送,采用后必须续跑现有反向前事核验;采用 RPC 必须优先读取最新 append-only transition,并对候选 schema 做 null-safe fail-closed 校验;局部否定不得结束整个 Case,否定语境不得误触停止词。
- 相关记录:BUG-366、BUG-367、BUG-398、BUG-401、BUG-402
- 复发自:BUG-366(覆盖完成被当成收敛)、BUG-367(结构化选择旁路)、BUG-398probe freshness)、BUG-401(伪 probe 与过早出卡)、BUG-402(点选后续跑)
- 修复版本:未提交