# TASK · 校正能力补齐修复单:答后旁白比错范围、时段支持度按时段长度偏置(2026-09-07) - 基线:`origin/staging` @ `814c924e`(含 BUG-565~568 与三份能力任务书的实现) - 分支:`codex/rectification-capability-fix-20260907` - 执行方:coding agent;验收:Claude - 涉及文件:`frontend/src/lib/rectification-agentic/v9/answer-choice.ts`、`probe-explain.ts`、`frontend/tests/rectification-answer-choice.test.ts`、`scripts/rectification/api_service.py::block_scan`、`tests/test_rectification_v5_services.py`、`BLOCKED.md` / `docs/BLOCKED.md` - BUG 编号起点:**BUG-569**(开工时 `grep -o "^## BUG-5[0-9][0-9]" docs/BUG_HISTORY.md | tail -1` 复核) - 父任务书:`TASK-rectification-explain-layer-20260906.md`、`TASK-rectification-unknown-time-20260906.md`(验收记录在各自末尾) ## 1. 事故实证 ### 1.1 P1 · 答后旁白永远说「范围没变」(BUG-569) `answer-choice.ts` L595–596 把 `[previous.range_start, previous.range_end]` 与 `[applied.state.range_start, applied.state.range_end]` 传给 `composeChoiceNarration`。`InferenceState.range_start/range_end` 是候选**搜索窗口**(`build-state.ts` L149 直接抄入参,答题从不改变);答题真正改变的是 `credible_range`(`build-state.ts` L159,`unionStillValidRange`)。结果:无论候选如何淘汰,用户每答一题都看到「范围没变」,而顶部只读范围已经在收窄。`rectification-answer-choice.test.ts` L1210–1231 直接给 `composeChoiceNarration` 喂了两个不同范围,所以没拦住。 ### 1.2 P1 · 时段支持度按时段长度偏置(BUG-570) `api_service.py::block_scan` 对五个时段分别 `sum(score)`。10 分钟步长下段内候选数:清晨 24、上午 24、下午 36、傍晚 30、夜里 30。引擎原始分底座 11~15、事件差只有 4~5(BUG-560),所以在**没有任何证据差异**时下午段已占 25.0%、清晨只有 16.7%;第一张时段卡实际在比时段长度。 ### 1.3 P2 · 文案 `probe-explain.ts` 的 `TRACK_LABEL` 把两条大运写成「毗湿奴多利、那罗延」。产品其他位置(`rectification-varga-sentence.ts`「本轮对照了 Vimshottari、Narayana…」、Skill 报告)一律用 Vimshottari / Narayana。 ### 1.4 P3 · BLOCKED 位置 BLK-001 写进了新建的 `docs/BLOCKED.md`;`AGENTS.md` §4 约定被环境挡住的事项写根目录 `BLOCKED.md`(已有 85 行)。两处并存会漂。 ## 2. 决策记录 1. 旁白比的是 `credible_range`(前:`previous.credible_range`;后:`applied.state.credible_range`),二者任一为空时不说范围句。 2. 时段支持度 = 段内候选**均值**减去**全日最低分**后归一(`max(mean_block − min_day, 0)`),全部为零时均分。这是对 BUG-560「不得换尺度」的例外:BUG-560 说的是分钟级 prior,时段级比较本来就是任务书 C 授权的新口径,且不进采用门。 3. `TRACK_LABEL` 改 Vimshottari / Narayana,与 `rectification-varga-sentence.ts` 同源(直接复用其映射表,不再维护第二份)。 4. `docs/BLOCKED.md` 的 BLK-001 搬回根目录 `BLOCKED.md` 末尾,删除 `docs/BLOCKED.md`。 ## 3. 硬红线 - 不改 `minute_step=1` 路径的任何字节(`test_rectification_v5_services.py` 指纹用例继续通过)。 - 不动采用门、确认门、`MIN_SEPARATION_LEAD`、`_relative_support`(分钟级 prior 仍是 proportional,BUG-560 保持 blocked)。 - 既有断言改动写三栏;测试总数 ≥ 1518(本次验收实测口径:`rectification-*` + `consultation-*` + `report-*` + `personal-report-*` + voice 契约,排除 database)。 ## 4. 任务分解 ### 4.1 BUG-569 - `applyRectificationChoice` 改传 `credible_range`;`composeChoiceNarration` 入参改名 `credibleBefore/credibleAfter` 防止再传错。 - 验收:`rectification-answer-choice.test.ts` 新增端到端用例——构造 `previous` state(`range_start/range_end` 固定,`credible_range` 宽)与答 A 后 `credible_range` 收窄,断言旁白含「范围从 X 收到 Y」;再一例 `credible_range` 不变 → 「范围没变」;三栏说明改掉 L1210–1231 的直喂用例或保留为纯函数用例。 ### 4.2 BUG-570 - `block_scan`:`raw_support = max(mean(score in block) − min(all scores), 0)`;`candidate_count` 已在返回里,保留。 - 验收:`test_rectification_v5_services.py` 新增——用 `row_provider` 或直接构造等分 `candidate_scores`(144 行同分)→ 五段 `relative_support` 各 20.0;只把清晨段抬高 → 清晨最高且下午不再因长度领先。 ### 4.3 P2 / P3 - `TRACK_LABEL` 复用 `rectification-varga-sentence.ts` 的标签表;`agent-voice-copy-contract` 增加「不得出现 毗湿奴多利 / 那罗延」守卫。 - BLK-001 搬回根目录 `BLOCKED.md`,删 `docs/BLOCKED.md`;`docs/tasks/PROGRESS-rectification-convergence-exit-fix-20260906.md` 的引用改路径。 ### 4.4 记录 - `docs/BUG_HISTORY.md` BUG-569、BUG-570;`CHANGELOG.md`;`docs/tasks/PROGRESS-rectification-capability-fix-20260907.md`;`docs/testing/rectification-explain-layer-20260906.md` 第 2 条改为「答完一题旁白里的范围与顶部范围一致」。 ## 5. 让步顺序 4.1 + 4.2 不可拆;4.3 可后置到同分支第二次提交;4.4 不可省。 ## 6. 开工前置命令 ```bash git fetch origin --prune git worktree add -b codex/rectification-capability-fix-20260907 .worktrees/rectification-capability-fix-20260907 origin/staging cd .worktrees/rectification-capability-fix-20260907 ln -s /workspace/Jyotisha/frontend/node_modules frontend/node_modules ln -s /workspace/Jyotisha/.venv .venv .venv/bin/python -m pytest tests/test_rectification_v5_services.py -q cd frontend && ls tests/rectification-*.test.ts tests/consultation-*.test.ts tests/report-*.test.ts tests/personal-report-*.test.ts tests/agent-voice-copy-contract.test.ts | grep -v database | xargs npx tsx --test 2>&1 | grep -E "^# (tests|pass|fail)" ``` ## 验收(Claude,2026-09-07,`origin/staging` @ `0a1076d6`,实现 `517df002`) | 门 | 结果 | | --- | --- | | tsc / lint | 0 错 / 0 error | | 前端 rectification + consultation + report + personal-report + voice(非 DB) | 1521 / 0 | | Python v5_services / event_probes / engine_convergence / growth contract / flexible engine | 全绿 | | `block_scan` 虚构 7 件事全日 10 分钟步长 | 5.9 s;五段支持 12.3 / 22.6 / 18.5 / 28.3 / 18.3,36 候选的下午段不再因长度领先 | | 项 | 结论 | | --- | --- | | 4.1 BUG-569 | 通过。旁白比 `previous.credible_range` / `applied.state.credible_range`,端到端用例走 `applyRectificationChoice`,源扫描锁定不再传 `range_start` | | 4.2 BUG-570 | 通过。段内均值减全日最低分;等分网格 20×5 用例 + 清晨抬高用例 | | 4.3 P2/P3 | 通过。大运标签复用 `publicRectificationMethodLabel`;BLK-001 回根目录 `BLOCKED.md`,`docs/BLOCKED.md` 已删 | | 4.4 记录 | 通过 | | 新 P2 | `test_block_scan_seven_events_finishes_within_fifteen_seconds` 是壁钟断言,执行方自己记录整文件连跑时 16~35 s;进 Gitea 门禁的 Python 段可能间歇红。建议改为只断言候选数与结构、耗时改成打印,或用环境变量放宽 |