fix(rectification): persist stop scores and deliver a range card (BUG-581–582)
Independent Staging Quality Gate / validate (push) Successful in 14m1s
Independent Staging Quality Gate / publish (push) Failing after 19m46s

Stop/idle reuse the scored evidence path so existing answers stay on the range. Delivery uses one range card (Skill 10.0.15) instead of four minute cards.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-07 19:22:01 +08:00
co-authored by Cursor
parent 058ad693cd
commit ab57d03f06
55 changed files with 2853 additions and 670 deletions
@@ -0,0 +1,38 @@
# PROGRESS · 生时校正区间交付卡(2026-09-07)
工作树:`.worktrees/rectification-stop-rescore-fix-20260907`
分支:`codex/rectification-range-delivery-card-20260907`(从 P0 停止后重算修复的未提交工作树切出)
任务书:`docs/tasks/TASK-rectification-range-delivery-card-20260907.md`
本单状态:**待验收**。未 commit、未 push、未部署。
未改:采用门、确认门、`MIN_SEPARATION_LEAD``_relative_support`、引擎、采用 RPC 校验、`adopted_credible_range` 落库。看盘板仍保留支持度。
## 做了什么
- **4.1** `v9/divergence-panel.ts`:按活跃簇(2~3)和未问的 D9 / D10 / 月宿层投影对比列。文案只取 `D9_TYPE_TABLE` / `D10_TYPE_TABLE``userChoice` 与 nakshatra `traits``latest_result` / Case GET / `parseRectificationCandidateResult``range_delivery`
- **4.2** `rectification-range-delivery.tsx` 替换四张分钟卡。动作「按这个范围用」(代表分钟或所选簇代表,UUID + `mode: "range"`)与「再补一件经历」(本地收起,不改状态)。`canShowRectificationSelectionCards` 语义不变。
- **4.3** 交付旁白去掉 `withProspectiveWindows` / 「候选 A 预测…」,改接 `deferredCareerWindow`。Skill §9 改口径,版本 **10.0.15**
- **4.4** CHANGELOG、本文件、手测场景第 5 条、DESIGN / VOICE。
## 三栏(被触碰断言)
| 用例 | 原值 | 新值 | 理由 |
| --- | --- | --- | --- |
| 交付轮 UI | `RectificationCandidateCards` + 相对支持度 / 当前推荐 / 采用此时间 | 一张 `RectificationRangeDelivery` | 产品决策 1 |
| 交付旁白 | `withProspectiveWindows` 三行候选预测 | `下一次事业变动的预测窗口留在采用后的核对阶段` | 决策 5 |
| Skill | 10.0.14,「候选卡仍作 adopt 控件…相对支持」 | 10.0.15,区间交付卡,不写相对支持度 | 决策 6 |
| 采用请求 | `{ sessionId, resultId, candidateId, requestId }` | 可选 `mode: "range"`,其余不变 | 决策 7,schema `.strict()` |
## 测试
- 任务书指定 TS 套件(`rectification-*.test.ts` + `consultation-*.test.ts` + `agent-voice-copy-contract.test.ts` + `skill-registry.test.ts`,排除 database):**1227 passed / 0 failed**P0 同切片 1202
- `frontend` `tsc --noEmit`0
- 本单改动文件 eslint**0 error**chat 上 2 条既有 hooks warning
- Docker `database-rectification-*.test.ts`:本机未跑,记 blocked
## 偏离
1. 任务书要求串行在 P0(BUG-581~582)合入并部署之后。用户要求同步代码并立即执行本单;P0 当时尚未部署,本单叠在同一工作树的 P0 修复之上切出 `codex/rectification-range-delivery-card-20260907`
2. `range_delivery` 挂在 Case GET 与 `latestResultToolProjection`,不进 `overlayPublicDecision`,避免 `decision-from-dossier``adopt-narration` 循环依赖。
3. 任务书写了 `v9/adopt-narration.ts` 旁白顺序;稳定/敏感句仍由既有 `withRangeReadingNarration` 插在 `adoptCue` 前,本单只替换预测窗口句。
@@ -0,0 +1,38 @@
# PROGRESS · 生时校正停止后重算丢掉答题(2026-09-07)
工作树:`.worktrees/rectification-stop-rescore-fix-20260907`
分支:`codex/rectification-stop-rescore-fix-20260907`(跟踪 `origin/staging` @ `058ad693`
任务书:`docs/tasks/TASK-rectification-stop-rescore-fix-20260907.md`
编号:BUG-581、BUG-582
本单状态:**待验收**。未 commit、未 push、未部署。区间交付卡任务仍串行等本单合入部署。
未改:采用门、确认门、`MIN_SEPARATION_LEAD``_relative_support``minute_step=1` 指纹、采用 RPC 校验。Skill 仍 10.0.14。
## 做了什么
- **BUG-581**`scoreAndPersistCurrentEvidence` 抽到 `v9/score-persist.ts`。STOP / 闲置 `keepAnswers=true` 重放上一份 `inference_state`;时段选定 / 放宽 `keepAnswers=false` 仍写出空答案的 `inference_state`
- **BUG-582**:无框或文案无效的 `distinguish_candidates` persist 为 `skipped`,不再改写成采集。`spokenFollowupForUser` 的 GENERIC 只留给真正的开场 `collect:other`。工具层删除 `?? GENERIC_COLLECT_QUESTION``persistPlanFocus` 不再在区分题 persist 失败后转口述采集。
- **P3**holdout 采集排到带年月采集与职业之后。计划层无框区分记 `dropped_probes(reason=frameless_distinguish)` 后继续往下走。
## 三栏(被触碰断言)
| 用例 | 原值 | 新值 | 理由 |
| --- | --- | --- | --- |
| 无框/文案无效区分题 persist | 改写成 `collect_spoken` / GENERIC 开场句 | `skipped`,不写焦点 | BUG-582 不得把区分题变成开场采集 |
| `precision stage d4` 覆盖完 dated 后 | 无框 `d4_home` 仍当下一问 | 记 `frameless_distinguish` 并继续;不再出无框区分 | 决策 3 |
| 源扫描 `rectification-v9-tools.ts` 里的对比包 / VedAstro 守卫 | 闭包内联 `scoreAndPersistCurrentEvidence` | 改扫 `v9/score-persist.ts` | 抽出共享重算路径 |
| `failed card persist still leaves a spoken collect next step` | `if (followup?.choice_frame)` + `?? GENERIC` | 仅采集意图且 `spokenFollowupForUser` 有题干才转口述 | 区分题不得 GENERIC 兜底 |
## 测试
- 任务书指定 TS 套件(`rectification-*.test.ts` + `consultation-*.test.ts` + `agent-voice-copy-contract.test.ts`,排除 database):**1202 passed / 0 failed**(上一轮同类切片约 1196
- `frontend` `tsc --noEmit`0(修完 `credible_range` 空值后复跑)
- Docker `database-rectification-*.test.ts`:本机未跑,记 blocked
## 偏离
1. 任务书说抽到 `tool-service.ts``v9/rescore.ts`;实际是 `v9/score-persist.ts`,避免 `tool-service` 循环依赖。
2. 未部署。区间交付卡(`TASK-rectification-range-delivery-card-20260907.md`)按任务书仍须等本单合入并部署。
3. 预检:系统 Python 3.14 无 swisseph/pytestERR-078);本单是前端 TS,以 `npx tsx --test` 为门。
4. 无框精度层(`lagna_frame` / 无探针的 d4)不再作为可问区分题;有 `choice_frame` 的精度卡仍可问。
+2 -2
View File
@@ -69,8 +69,8 @@
| `TASK-rectification-capability-fix-20260907.md` | `PROGRESS-rectification-capability-fix-20260907.md` | 能力补齐修复单:答后旁白把 `range_start/range_end`(搜索窗口)当范围比较,每题都说「范围没变」;`block_scan` 五段支持度按段内原始分求和,长时段先天占优(24/24/36/30/30 个候选);`TRACK_LABEL` 音译与产品 Vimshottari/Narayana 口径不一;BLK-001 写到 `docs/BLOCKED.md` 应回根目录 | 已验收通过(P2block_scan 15 s 壁钟断言在门禁里可能间歇红) | `517df002`BUG-569570);staging 未部署,需先 Migrate Staging Database |
| `TASK-rectification-declared-uncertainty-20260907.md` | `PROGRESS-rectification-declared-uncertainty-20260907.md` | 出生时间「有多确定」只在 intake 问一次:三档(医院记录 / 家人大概 ±15·30·60·120 / 时段或未知),校正窗口读档案(现在有钟点一律 ±15,声明值被忽略,BUG-571);吻合率 <60% 且代表分钟贴窗口边缘时出服务端一键放宽卡,放宽后重算并写回档案(BUG-572);窗口 >120 分钟先切三子段迭代到 ≤120 再进分钟(BUG-573);日级事件问一次可靠度;四个脚本化手测场景进 docs/testing | 已验收通过(2 P3 建议:可靠度正则去掉「记得」、档案写回改走 account-profile-patch | `8e31680b`BUG-571573);迁移 `20260907020000` 待应用,部署前先 Migrate Staging Database |
| `TASK-rectification-stale-compare-fix-20260907.md` | `PROGRESS-rectification-stale-compare-fix-20260907.md` | **P0**BUG-559 把过长 `candidate_split_hash` 塞进引擎比较键,答完性格/边界卡后比较静默失败;快照过期压过用户停止;holdout 用过期领域被改写成「再说一件事」;采集轮正文双写 | 已验收通过(P2 正文双写根因未拆、P3 重算节流 Map 只增不减) | `4e0db55f`(落地编号 BUG-577580);staging 未部署 |
| `TASK-rectification-stop-rescore-fix-20260907.md` | `PROGRESS-rectification-stop-rescore-fix-20260907.md` | **P0**:BUG-579 的停止路径用「裸重算」(`rescoreMinuteAfterWindowChange` 不重建 `inference_state`、不重放已答探针、不写 transition),停止后范围变宽、卡片变成引擎裸支持度、采用 RPC 报 `candidate_state_inconsistent`;无框区分题经 `spokenCollectFallbackFollowup` 变成 domain=other 的采集题,再次冒出开场句 `GENERIC_COLLECT_QUESTION`;holdout 采集排在带年月采集之前 | 待领取(当天须合入部署) | `codex/rectification-stop-rescore-fix-20260907`BUG-581582 |
| `TASK-rectification-range-delivery-card-20260907.md` | `PROGRESS-rectification-range-delivery-card-20260907.md` | 结尾重设计:四张分钟卡 + 相对支持度换成一张区间交付卡(范围、代表分钟、稳定/敏感主题、边界句)+ 只列未问 D9/D10/月宿分歧的 2~3 列对比面板(文案只取类型表),动作只有「按这个范围用 / 再补一件经历」;删交付旁白里三行预测窗口;Skill §9 口径改、bump 10.0.15 | 待领取(串行:在 stop-rescore-fix 部署之后) | `codex/rectification-range-delivery-card-20260907` |
| `TASK-rectification-stop-rescore-fix-20260907.md` | `PROGRESS-rectification-stop-rescore-fix-20260907.md` | **P0**:BUG-579 的停止路径用「裸重算」(`rescoreMinuteAfterWindowChange` 不重建 `inference_state`、不重放已答探针、不写 transition),停止后范围变宽、卡片变成引擎裸支持度、采用 RPC 报 `candidate_state_inconsistent`;无框区分题经 `spokenCollectFallbackFollowup` 变成 domain=other 的采集题,再次冒出开场句 `GENERIC_COLLECT_QUESTION`;holdout 采集排在带年月采集之前 | 待验收 | `codex/rectification-stop-rescore-fix-20260907`BUG-581582 |
| `TASK-rectification-range-delivery-card-20260907.md` | `PROGRESS-rectification-range-delivery-card-20260907.md` | 结尾重设计:四张分钟卡 + 相对支持度换成一张区间交付卡(范围、代表分钟、稳定/敏感主题、边界句)+ 只列未问 D9/D10/月宿分歧的 2~3 列对比面板(文案只取类型表),动作只有「按这个范围用 / 再补一件经历」;删交付旁白里三行预测窗口;Skill §9 口径改、bump 10.0.15 | 待验收 | `codex/rectification-range-delivery-card-20260907` |
| `TASK-api-not-configured-mislabel-20260904.md` | `PROGRESS-api-not-configured-mislabel-20260904.md` | 16 处路由把数据库瞬断(部署切换窗口)兜底翻译成 503「服务尚未配置」;改为仅配置错误用该文案,其余 `service_unavailable`,收敛为共享 helper | 已验收 | `5483649b`(BUG-542);2 条子进程测试留 CI Node 22 复核 |
| `TASK-rectification-ux-20260902.md` | `PROGRESS-rectification-ux-20260903.md` | 会话面空白假死与交互摩擦 | 已验收 | `d159f08e`(09-03 在新基线重做后合入,BUG-505509 |