fix(rectification): count timeline width inclusively and keep eliminated minutes hollow (BUG-602, BUG-603)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-09 13:58:55 +08:00
co-authored by Cursor
parent d925251654
commit 92e3d5e7a3
11 changed files with 338 additions and 25 deletions
@@ -0,0 +1,58 @@
# PROGRESS · 生时校正时间轴修复单:宽度含两端、空心点来自推断层(2026-09-09)
工作树:`.worktrees/rectification-timeline-fix-20260909`
分支:`codex/rectification-timeline-fix-20260909`
任务书:`docs/tasks/TASK-rectification-timeline-fix-20260909.md`
基线:`origin/staging` @ `d9252516`(任务书写 `724a1215`;本 worktree 按开工指令从当时 `origin/staging` 切出)
本单状态:**待验收**。未 push,未合入 staging/main,未声称生产部署。
预检:本机 `python3 scripts/pre_work_check.py` 失败(系统 Python 3.14 无 pytest、无 swissephERR-078)。不把预检失败写成门禁已过。前端用 worktree 里已有的 `frontend/node_modules` 符号链接。
未改:二元编码、只读、固定条高、grid 行、transform-only、`use-conversation-scroll-anchor.ts``frontend/src/lib/rectification-agentic/v9/*`、Skill / `references/conversation-strategy.md`、composer-wrap / collect 按钮 / vargaSentence / opening / spoken copy。Skill 版本不变。
## 做了什么
- **BUG-602** `widthLabel = timelineDurationLabel(bandEnd - bandStart + 1)`,与 BUG-593 交付报告含两端分钟数同一形状。
- **BUG-603** `RectificationCandidateResult.inferenceMarks``decisionReceipt.inference_state.candidates``time` / `status` 解析;组件只把该数组交给时间轴,不读 raw receipt。`state = eliminated ? "out" : "in"`,不再按点是否落在区间带内判断。无 `inference_state` 时引擎候选全部实心。
`inferenceMarks` 在类型上是可选的:`parseRectificationCandidateResult` **每次都写出数组**(没有推断层则为 `[]`)。若做成必填,会迫使改 `tests/rectification-range-delivery-20260907.test.ts` 里的结果字面量——该文件不在本单所有权内。
## 三栏 · widthLabel
| 用例 | 原值 | 新值 | 理由 |
| --- | --- | --- | --- |
| 05:0705:09 | `2 分钟` | `3 分钟` | 含 05:07、05:08、05:09 三分钟;与 DESIGN §10 / 报告口径一致 |
| 04:5104:59 | `8 分钟` | `9 分钟` | 含两端;与三列卡同一形状 |
| 04:5104:53 | `2 分钟` | `3 分钟` | 与 `rectification-delivery-report-facts.test.ts``width_minutes === 3` 同一形状 |
| 05:0705:07 | `0 分钟` | `1 分钟` | 单分钟窗口 |
| 00:0023:59 整天 | `23 小时 59 分` | `24 小时` | 1440 分钟;时段阶段尚未排除任何分钟 |
| 04:5605:20(放宽后) | `24 分钟` | `25 分钟` | 含两端 |
| 00:3001:30(跨午夜带) | `1 小时` | `1 小时 1 分` | 61 分钟,同一条 `+ 1` 规则 |
## 三栏 · 标记改按 status
| 用例 | 原值 | 新值 | 理由 |
| --- | --- | --- | --- |
| 合成 05:06…05:10,带 05:0705:09,无 inferenceMarks | `["out","in","in","in","out"]`(按是否落在带内) | 全部 `"in"` | 无推断层时引擎候选全部实心,决策 2 |
| 同上,05:08 在带内但 `eliminated` | 05:08 会被判 `"in"` | 05:08 `"out"` | in/out 只看 `status === "eliminated"`,不看带 |
| 推断层 9 点、7 淘汰、带 04:51–04:53,引擎投影只有 2 个 active | 条上 2 个实心点 | 9 个点,7 空心 2 实心 | 客户端以前拿不到被淘汰分钟 |
| 下一轮再淘汰 1 个 | 点消失或 key 重建 | 8 空心 1 实心,key 不变 | 空心留在原地,过渡不重建 |
## 测试
- `frontend` `./node_modules/.bin/tsc --noEmit`exit 0
- `npm run lint`0 error / 108 warning(仓库既有 warning,无新增 error
- 指定切片 `tsx --test tests/rectification-timeline-20260909.test.ts tests/rectification-delivery-report-facts.test.ts tests/rectification-candidate-result.test.ts`**39 passed / 0 failed**(时间轴 22、候选解析 13、交付报告事实 4)
- 浏览器真人走查:无登录态,仍见 `docs/testing/rectification-timeline-20260909.md`;§4 第一条已改为「被排除的分钟变空心且不消失(数据来自推断层)」
## 偏离
1. 任务书基线写 `724a1215`;本 worktree 按开工指令基于当时 `origin/staging` `d9252516`
2. `inferenceMarks` 类型可选,解析器始终赋值。见上文。
3. 跨午夜 00:30–01:30 读数从「1 小时」变为「1 小时 1 分」,任务书未点名,但是同一条含两端规则。
4. 未改 `inference-adapter.ts`:active 投影仍只给卡片;时间轴改走推断层全集。
## 环境缺口
无登录态、无 Chrome、无 Docker。浏览器级空心点/贴底仍欠真实会话。不把合同测试写成已经看见真实像素。
+1 -1
View File
@@ -84,7 +84,7 @@
| `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 |
| `TASK-rectification-timeline-20260909.md` | — | 常驻吸顶时间轴:轴锁**当前**搜索窗口并随放宽缩放、时段/分钟两套标记、候选点二元编码不分置信度(BUG-560 blocked)、无 hoverBUG-575)、只读不可采用。实现用第三个 grid 行而非 `position: sticky``useConversationScrollAnchor` 一行不改;条高固定是正确性要求;吸顶条只留区间与宽度两个元素 | 已验收通过;宽度口径与空心点两处未通过→修复单 | `ce91a0d2` |
| `TASK-rectification-timeline-fix-20260909.md` | `PROGRESS-rectification-timeline-fix-20260909.md` | 时间轴修复单:宽度读数改含两端分钟数(与 BUG-593 报告/卡片一致);标记改读推断层候选全集,被淘汰分钟留在原地变空心(客户端投影只含 active,DESIGN §10 描述在真实数据下画不出) | 待执行 | `codex/rectification-timeline-fix-20260909`BUG-602603 |
| `TASK-rectification-timeline-fix-20260909.md` | `PROGRESS-rectification-timeline-fix-20260909.md` | 时间轴修复单:宽度读数改含两端分钟数(与 BUG-593 报告/卡片一致);标记改读推断层候选全集,被淘汰分钟留在原地变空心(客户端投影只含 active,DESIGN §10 描述在真实数据下画不出) | 待验收 | `codex/rectification-timeline-fix-20260909`BUG-602603 |
| `TASK-rectification-conversation-economy-20260909.md` | `PROGRESS-rectification-conversation-economy-20260909.md` | 对照竞品后产品拍板三条:开场三句讲做法 + 一次收多件(推翻 opening brief「不要一次说完/不举例」与 SKILL L52);采集题「没有 / 记不清」按钮(不做示例骨架条);每轮只留一句(方法句进活动记录、点选旁白去领先落后、证据轮正文一句复述 + 服务端裁剪);Skill 10.0.19 | 待执行 | `codex/rectification-conversation-economy-20260909`BUG-604606 |
### 聊天主链路与首页