# PROGRESS · 生时校正过期比较修复(2026-09-07) 分支:`codex/rectification-stale-compare-fix-20260907` 任务书:`docs/tasks/TASK-rectification-stale-compare-fix-20260907.md` 编号:任务书写 BUG-575~578;开工时 `docs/BUG_HISTORY.md` 已占用 575(悬停/步骤条)、576(长报告附录)。本单落地为 **BUG-577~580**。 ## 做了什么 - **BUG-577**:引擎比较只传 `semantic_key` + 账本年份键;丢掉 `candidate_split_hash` / `:varga.` / 超 200 字符键。Python 上限 200,超长跳过并计数 `dropped_asked_probe_keys`。128 字符键在新上限下保留(任务书 5.1 写「跳过 128」与决策 1「上限 200」冲突,按决策 1)。 - **BUG-578**:比较失败 receipt 带 `safe_error_code` + `engine_message`(120 字);Agent 正文追加固定句;闲置/非终止退出在快照过期时先重算一次(同 case+指纹+turn 只一次)。 - **BUG-579**:`userStopped && ranked>0` 排在 `snapshotCurrent === false` 之前。STOP / 无焦点 `stop_and_review` 先重算;重算失败旁白「这是按上一次成功比较给出的范围。」 - **BUG-580**:holdout 排除账本已有带年月事件的领域;无可问则不再出 holdout 题。题干 = `USER_COLLECT_QUESTION[domain]`,口述采集,无选择题框。不把该状态改写成决策层 `unavailable`(那条路径会变成 `offer_provisional_range` 而不是交付)。 - **P2**:`composeCollectSpokenAssistantText` 去掉与题干前 12 字相同的复述句。`intent.classified` 仍可能因 `case.loaded` 两次出现;本单未拆 Agent 生命周期,记在偏离。 未改:采用门、确认门、`MIN_SEPARATION_LEAD`、`_relative_support`、`minute_step=1` 指纹身份。 ## 三栏(被触碰断言) | 用例 | 原值 | 新值 | 理由 | | --- | --- | --- | --- | | `four scoreable events skip declined OOS domain and ask education holdout` | `intent=out_of_sample_check` / `source=oos_blind` / `domain=education` | holdout 为 null;下一问不是已在账本的 education/finance | BUG-580 账本已有学业/财务不得再 holdout | | `stop_and_review does not write an inference transition` | 旁白匹配「已记录你的选择」 | `session_outcome ∈ ADOPT_OUTCOMES` 且 `can_adopt=true`;仍不写 inference | BUG-579 停止必须能出卡 | | Python 128 字符键 | 任务书 5.1:跳过并计数 | 保留,无 `dropped_asked_probe_keys` | 决策 1 把上限提到 200 | ## 测试 - Python `tests/test_rectification_input_contract.py` + `tests/test_rectification_v5_services.py`:38 passed - 任务书指定 TS 套件(`rectification-*.test.ts` + `consultation-*.test.ts` + `agent-voice-copy-contract.test.ts`,排除 database):1196 passed / 0 failed - 全量 frontend `tests/*.test.ts`(排除 database):2814 passed / 0 failed(≥1899) - `frontend` `tsc --noEmit`:0 - 指定 Python 契约:128 字符键保留、不 400 ## 偏离 1. Bug 编号 577~580,不是任务书的 575~578。 2. 128 字符键保留,不跳过。 3. P2 只做了题干近重复删除;`intent.classified` 双触发未在本提交拆掉。 4. 预检:本机按 ERR-078 用项目 `.venv`;不把 `.workbuddy` 当主仓。 5. 无可问 holdout 领域时不把决策层改成 `unavailable`,只在提问层返回 null,避免误入 `offer_provisional_range`。