Files
Jyotisha/docs/tasks/TASK-rectification-timeline-fix-20260909.md
T

61 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TASK · 生时校正时间轴修复单:宽度读数与卡片/报告口径不一致;被排除的分钟根本到不了客户端,"空心点"画不出来(2026-09-09
- 基线:`origin/staging` @ `724a1215`(时间轴 `ce91a0d2` 已合入并部署)
- 分支:`codex/rectification-timeline-fix-20260909`,基于 `origin/staging`
- 执行方:coding agent;验收:Claude
- 涉及文件:`frontend/src/lib/rectification-timeline-scale.ts``frontend/src/components/rectification-agentic-chat.tsx``timelineView``candidateTimes` 来源)、`frontend/src/lib/rectification-candidate-result.ts`(或直接读 `decisionReceipt.inference_state.candidates`)、`frontend/tests/rectification-timeline-20260909.test.ts``frontend/DESIGN.md` §10
- BUG 编号起点:**BUG-602**`docs/BUG_HISTORY.md` 当前最大 BUG-601
- 优先级:**P1**(两处都是"条上写的和别处不一样",用户会当成算错)
## 1. 事实
### 1.1 BUG-602:宽度按差值算,卡片与报告按含两端算
`timelineDurationLabel(bandEnd - bandStart)`04:5104:59 显示"8 分钟"05:0705:09 显示"2 分钟",整天窗口显示"23 小时 59 分"。而 BUG-593 已把交付报告与三列卡的宽度定为**含两端的分钟数**:04:5104:59 = 9 分钟、04:5104:53 = 3 分钟(`rectification-delivery-report-facts.test.ts`)。同一屏上条写 8、卡写 9。任务书 §4.3 的示例"05:0705:09 · 2 分钟"本身就是差值口径,执行方照抄了。
### 1.2 BUG-603:客户端候选列表只含 active 分钟,被排除的分钟不会变空心、而是消失
`inference-adapter.ts` L292 `candidates = active.flatMap(...)`:投影只保留 `status !== "eliminated"` 的候选;`rectification-agentic-chat.tsx``candidateResult.candidates.map(time)` 喂给时间轴,`buildRectificationTimeline` 再按"是否落在区间带内"判 in/out。结果:分钟阶段所有到达客户端的点都在带内、全是实心;答完一题被淘汰的分钟直接从条上消失。DESIGN.md §10 写的"被排除的点留在原地变空心、不消失——用户由此看见自己刚才那一答排掉了哪几分钟"在真实数据下不成立;测试里的 `["out","in","in","in","out"]` 是合成输入。另外 `credible_range` 是 active 候选的跨度,带内若有被淘汰分钟(可能出现)也会被按位置判成 in。
## 2. 决策记录
1. **宽度统一为含两端分钟数**`widthLabel = timelineDurationLabel(bandEnd - bandStart + 1)`;整天窗口显示"24 小时";单分钟显示"1 分钟"。DESIGN.md §10 示例改为"05:0705:09 · 3 分钟"。
2. **标记来源改为推断层候选全集**:客户端从 `decisionReceipt.inference_state.candidates`(有 `time``status`)取点;`state = status === "eliminated" ? "out" : "in"`,不再按位置判。没有 `inference_state` 时退回现有行为(引擎候选全部实心)。`RectificationCandidateResult` 加只读字段 `inferenceMarks: [{time, eliminated}]`,解析放在 `rectification-candidate-result.ts`,组件不碰 receipt。
3. 二元编码、只读、固定条高、grid 行、transform-only 全部不动;`use-conversation-scroll-anchor.ts` 仍一行不改。
## 3. 验收
- (a) 04:5104:59 → "9 分钟"05:0705:09 → "3 分钟"00:0023:59 整天 → "24 小时"`rectification-delivery-report-facts.test.ts` 的同一形状与条读数一致。
- (b) 推断层 9 个候选、7 个 eliminated、`credible_range` 04:5104:53 → 条上 9 个点,7 空心 2 实心;下一轮再淘汰 1 个 → 8 空心 1 实心,点的 key 不变(过渡不重建)。
- (c) 无 `inference_state`(时段阶段刚选定)→ 引擎候选全部实心,行为同今天。
- (d) 三栏:`widthLabel` 用例原值/新值/原因;合成 marks 用例改为按 status。
- (e) 记录:BUG-602(关联 BUG-593)、BUG-603(关联 BUG-560、DESIGN §10);`CHANGELOG.md``PROGRESS-…``docs/testing/rectification-timeline-20260909.md` §4 第一条改为"被排除的分钟变空心且不消失(数据来自推断层)"。
## 4. 开工前置命令
```bash
git fetch origin --prune
git worktree add -b codex/rectification-timeline-fix-20260909 .worktrees/rectification-timeline-fix-20260909 origin/staging
cd .worktrees/rectification-timeline-fix-20260909
ln -s /workspace/Jyotisha/frontend/node_modules frontend/node_modules
cd frontend && ./node_modules/.bin/tsc --noEmit; npm run lint 2>&1 | tail -1
npx tsx --test tests/rectification-timeline-20260909.test.ts tests/rectification-delivery-report-facts.test.ts 2>&1 | grep -E "^# (tests|pass|fail)"
```
## 验收(Claude2026-09-09`origin/staging` @ `04ad3325`staging 当时部署 `fa293b31`
| 门 | 结果 |
| --- | --- |
| tsc | 0 错 |
| lint | 0 error / 108 warning |
| 前端 rectification + consultation + session + voice + skill-registry(非 DB | 1347 / 0 |
| Python v5_services + event_probes + growth contract | 72 passed / 0 failed |
| 项 | 结论 |
| --- | --- |
| BUG-602 宽度含两端 | 通过。`bandEnd - bandStart + 1`;七组三栏齐全,与 BUG-593 报告口径一致 |
| BUG-603 空心点来自推断层 | 通过。`inferenceMarks``decisionReceipt.inference_state.candidates` 解析,`eliminated` 是唯一判据;无推断层退回全实心 |
| 偏离 2`inferenceMarks` 可选、解析器始终赋值) | 接受 |
结论:通过(实现 `92e3d5e7`)。