fix(rectification): run adopt narration on the last discriminator click
Independent Staging Quality Gate / validate (push) Failing after 9m46s
Independent Staging Quality Gate / publish (push) Has been skipped

The early-exit reused the pre-click dossier, so the agent never ran on the common path. Use this-turn decision, log agent vs template outcome, and time out after 8s.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-04 14:59:15 +08:00
parent e18bd25b19
commit 13dded9fff
8 changed files with 353 additions and 45 deletions
+32
View File
@@ -8033,3 +8033,35 @@
- 复发自:无
- 修复版本:待发布
- 编号说明:与 BUG-519 同批;任务书原写 BUG-517,因编号冲突改为 BUG-520。
## BUG-521 | 点选最后一道区分题时采用旁白 Agent 从不运行
- 状态:resolved
- 首次发现:2026-09-04
- 最近更新:2026-09-04
- 影响面:`frontend/src/lib/rectification-agentic/v9/answer-choice.ts` `persistNextInterviewAfterChoice`
- 用户现象:点完最后一道区分题才出采用卡时,旁白仍是模板句;只有采集题答「没有」和空闲兜底才会走 Agent。
- 触发条件:`applyRectificationChoice``persistApplied` 传入的 dossier 仍是点选前的 `decisionReceipt`;本轮新状态在 `decisionState`,本轮决策在 `nextDecision`
- 根因:采用早退分支从旧 dossier 再算一遍 `decideFromDossier`。旧决策还是「还有题要问」,`precisionStage !== "ready_to_adopt"``shouldWriteAdoptNarration` 为 false,模型一次都没调。模板范围也来自这份过期决策。同一次调用里决策层算了两遍(BUG-440 防复发条款)。
- 修复:`persistNextInterviewAfterChoice` 接受调用方传入的 `decision`;未传时用 `decideAfterInferenceChange({ dossier, state: decisionState })`。函数体内不再出现 `decideFromDossier(``adoptDeliveryFacts` / 模板兜底使用合成后的 receipt(本轮 `inference_state`)。三条调用方都传入本轮决策。
- 验证:`rectification-adopt-narration-20260904` 点选用例改为点选前 dossierrevision 5、分数 23/16/7+ 答完后 `decisionState` / `nextAction`;断言模型调用 1 次、facts 为 05:00 与 21/18/9、`ready_to_adopt`。非法模型输出时模板范围仍来自本轮决策。源码断言该函数体内无 `decideFromDossier(`
- 防复发:`persistNextInterviewAfterChoice` 不得再从旧 dossier 重算决策。点选路径测试不得用已答完 dossier 冒充点选前状态。
- 相关记录:BUG-440、BUG-519、BUG-522
- 复发自:BUG-440
- 修复版本:待发布
## BUG-522 | 采用旁白校验把「不是确认」整段打回,且真实环境无法证明 Agent 有没有写
- 状态:resolved
- 首次发现:2026-09-04
- 最近更新:2026-09-04
- 影响面:`adopt-narration-agent.ts` 提示词、`deliverAdoptNarration` 超时与诊断字段
- 用户现象:校验器全文匹配「确认|精确」,模型写「这不是确认的分钟」会被静默退到模板;部署后日志看不出 Agent 路径命中还是模板兜底。
- 触发条件:采用旁白 Agent 生成含「确认」或「精确」的否定句;或模型挂起超过等待时间。
- 根因:提示词只禁止承诺确认/精确,校验器却禁这两个字。分类器同款调用没有超时。结果没有可观测枚举。
- 修复:提示词改为「不要出现『确认』『精确』这两个词」,与校验器同口径;校验器本身不放宽,「这不是确认的分钟」仍打回。`deliverAdoptNarration``adopt_narration=agent | template:<reason> | template:model_error | template:not_ready`(不含模型原文),并用 `AbortSignal.timeout(8000)` 超时走模板。意图分类器超时仍是既有缺口,本单不修。
- 验证:提示词源码断言含「不要出现」;`deliverAdoptNarration` 对 agent / template:unknown_minute / template:model_error / template:not_ready 各有断言;短 timeout 挂起 generateText 走模板且不抛。
- 防复发:采用旁白结果必须留下 `adopt_narration=` 日志。Agent.generate 必须带超时。不得把「确认」从校验器删掉却不改提示词。
- 相关记录:BUG-521
- 复发自:无
- 修复版本:待发布
@@ -0,0 +1,32 @@
# PROGRESS · 采用旁白点选入口修复(2026-09-04)
工作树:`.worktrees/rectification-adopt-narration-fix-20260904`
分支:`codex/rectification-adopt-narration-fix-20260904`
基线:任务书写 `0aaa0d70`;本工作树从当时 `origin/staging` `e18bd25b`(修复单提交)拉出。
任务书:`docs/tasks/TASK-rectification-adopt-narration-fix-20260904.md`
未改 Python、未 bump Skill、未放宽采用门。未提交、未 push。
| 任务 | 状态 | BUG |
| --- | --- | --- |
| 5.1 早退分支用本轮决策 | 完成 | BUG-521 |
| 5.2 提示词同口径、诊断字段、8s 超时 | 完成 | BUG-522 |
| 5.3 `stopFactsFromDropped` 婚恋标签 | 推迟 | — |
## 实现要点
- `persistNextInterviewAfterChoice` 新增可选 `decision``persistApplied` / `applyCollectFocusDenial` / `persistNextInterviewIfIdle` 都传入本轮决策。未传时走 `decideAfterInferenceChange`。函数体内不再出现 `decideFromDossier(`
- `adoptDeliveryFacts` 与模板兜底用 `dossierWithCurrentInference` 合成后的 receipt,活跃分数来自本轮 `decisionState`
- `deliverAdoptNarration` 返回 `adopt_narration` 枚举并打 `console.info`(无模型原文)。`AbortSignal.any([request.signal, AbortSignal.timeout(8000)])`;超时 / 抛错走 `template:model_error`
- 提示词改为「不要出现『确认』『精确』这两个词」。校验器仍打回「这不是确认的分钟」。
## 偏离 / 推迟
- 5.3 按让步顺序推迟:`not_renderable` 仍可能被标成「婚恋题只覆盖窗口两端」。
- 意图分类器没有超时:既有缺口,本单不修,记在此处,不改 `BLOCKED.md`
## 测试
- `tsc --noEmit`0 错
- `npm run lint`0 error74 warning(既有)
- `rectification-adopt-narration-20260904` 10/10;与 answer-choice / collect-stall / provisional-adopt 合计 66/66
- `tests/rectification-*.test.ts tests/agentic-rectification-*.test.ts tests/birth-time-rectification-contract.test.ts`871 pass / 0 fail(基线 869 + 本单 2 条诊断/超时测试)
+1 -1
View File
@@ -45,7 +45,7 @@
| `TASK-rectification-adopt-flow-fix-20260903.md` | — | 采用流程修复单(含删「用这个时间看盘」) | 已验收 | `e8c98c37`BUG-501/502 |
| `TASK-rectification-uncertainty-stop-20260903.md` | — | 不确定度停止规则加样本下限 | 已验收 | `0c0df426`BUG-503 |
| `TASK-rectification-adopt-narration-20260904.md` | `PROGRESS-rectification-adopt-narration-20260904.md` | 探针池耗尽时采用卡旁白改 Agent 生成 + 已丢弃探针绕过 BUG-472 早退 + 区分题答否关线 | 已验收(4.1.4 点选入口未通过,见修复单) | `0aaa0d70`BUG-519/520 |
| `TASK-rectification-adopt-narration-fix-20260904.md` | | 采用旁白 Agent 在点选入口从不运行(早退分支重算过期决策)+ 校验器/可观测/超时 | 待执行 | 基线 `0aaa0d70`BUG-521 |
| `TASK-rectification-adopt-narration-fix-20260904.md` | `PROGRESS-rectification-adopt-narration-fix-20260904.md` | 采用旁白 Agent 在点选入口从不运行(早退分支重算过期决策)+ 校验器/可观测/超时 | 待验收 | 基线 `e18bd25b`(任务书写 `0aaa0d70`BUG-521 / BUG-522 |
| `TASK-rectification-ux-20260902.md` | `PROGRESS-rectification-ux-20260903.md` | 会话面空白假死与交互摩擦 | 已验收 | `d159f08e`(09-03 在新基线重做后合入,BUG-505509 |
### 聊天主链路与首页
@@ -6,13 +6,20 @@
浏览器打开 `https://staging.jyotisha.chat/api/health`,看 `deployment.gitCommit` 前 8 位是否等于本单合入 staging 后的提交。不一致 = 先别测。
## 1. 探针池耗尽后出现采用卡(P0 · BUG-519)
## 1. 探针池耗尽后出现采用卡(P0 · BUG-519 / BUG-521
1. 新开一个生时校正会话,按平常走完区分题,直到系统再问一道口述采集(家里结婚/添丁/住院这类)。
2. 对那道采集题回答「没有」。
- ✅ 预期:同一轮出现「当前可能的出生时间」采用卡;composer **没有**再冒出开场题或新的点选卡
- ✅ 预期:旁白说出为什么停(分不开两个相邻分钟)、现在的范围和代表分钟,并以「可以从下面选一个先用着」收尾
- ❌ 改造前:旁白是「我按现有材料继续往下收」,采用卡却已经出来
优先测这条(最常见入口):
1. 新开一个生时校正会话,按平常走完区分题
2. **点选最后一道区分题**(不要用采集题「没有」代替)
- ✅ 预期:同一轮出现「当前可能的出生时间」采用卡;旁白说出为什么停(分不开两个相邻分钟)、现在的范围和代表分钟,并以「可以从下面选一个先用着」收尾
- ❌ 改造前(BUG-521):点选入口旁白仍是模板句,Agent 没上场。
采集题路径仍要能走:
1. 若系统再问一道口述采集(家里结婚/添丁/住院这类),回答「没有」。
- ✅ 预期:同一轮出现采用卡;composer **没有**再冒出开场题或新的点选卡;旁白同样说清为什么停。
- ❌ 更早改造前:旁白是「我按现有材料继续往下收」,采用卡却已经出来。
## 2. 采用后进入核对(P0 · 与 BUG-501/502 衔接)