Merge branch 'codex/rectification-timeline-fix-20260909' into codex/merge-bug602-606-staging
This commit is contained in:
@@ -9333,3 +9333,35 @@
|
||||
- 相关记录:BUG-043(禁止把后台评分状态渲染成用户需要管理的面板。本处边界不同且不冲突:等待屏是只读的,展示的是用户交付物自身的章节结构,`attemptCount`、原始错误码、lease、job id、payload 一律不出服务端)、BUG-576、BUG-574
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-602 | 时间轴宽度按差值算,卡片与报告按含两端算
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-09
|
||||
- 最近更新:2026-09-09
|
||||
- 影响面:`rectification-timeline-scale.ts` 区间读数 `widthLabel`、`frontend/DESIGN.md` §10
|
||||
- 用户现象:同一屏上时间轴写的宽度比三列卡和验证报告少 1 分钟。例如区间 04:51–04:59 条上写「8 分钟」、卡上写「9 分钟」;05:07–05:09 条上写「2 分钟」;整天窗口写「23 小时 59 分」。
|
||||
- 触发条件:分钟阶段已有 `credible_range`,或时段阶段轴铺满整天窗口。必现。
|
||||
- 根因:`widthLabel` 用 `timelineDurationLabel(bandEnd - bandStart)`,少算两端都计入的那一分钟。BUG-593 已把交付报告与三列卡定为含两端分钟数;任务书示例「05:07–05:09 · 2 分钟」是差值口径,首版时间轴照抄了。
|
||||
- 修复:改为 `timelineDurationLabel(bandEnd - bandStart + 1)`。整天 00:00–23:59 显示「24 小时」,单分钟显示「1 分钟」。DESIGN.md §10 示例改为「05:07–05:09 · 3 分钟」。
|
||||
- 验证:`frontend/tests/rectification-timeline-20260909.test.ts`(含两端宽度表:04:51–04:59 → 9 分钟、05:07–05:09 → 3 分钟、04:51–04:53 → 3 分钟、单分钟 → 1 分钟、整天 → 24 小时);与 `frontend/tests/rectification-delivery-report-facts.test.ts` 的 `width_minutes === 3` 同一形状。
|
||||
- 防复发:时间轴读数必须与报告/卡片同一套含两端分钟数;禁止再把 `bandEnd - bandStart` 当宽度。
|
||||
- 相关记录:BUG-593
|
||||
- 复发自:无
|
||||
- 修复版本:`92e3d5e7`
|
||||
|
||||
## BUG-603 | 被排除的分钟到不了客户端,时间轴空心点画不出来
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-09
|
||||
- 最近更新:2026-09-09
|
||||
- 影响面:`rectification-candidate-result.ts`、`rectification-timeline-scale.ts`、`rectification-agentic-chat.tsx` 的 `timelineView` 候选来源
|
||||
- 用户现象:DESIGN.md §10 写「被排除的点留在原地变空心、不消失」;真实会话里答完一题后那些分钟从条上消失,剩下的全是实心。看不到刚才那一答排掉了哪几分钟。
|
||||
- 触发条件:分钟阶段已有推断层、至少淘汰过一个候选。必现。
|
||||
- 根因:`inference-adapter.ts` 投影只保留 `status !== "eliminated"` 的候选;时间轴把 `candidateResult.candidates.map(time)` 当点,再按是否落在区间带内判 in/out。到达客户端的点都在带内,全是实心;被淘汰的分钟根本不在列表里。测试里的 `["out","in","in","in","out"]` 是合成输入,不是这条数据路径。
|
||||
- 修复:`RectificationCandidateResult` 增加只读 `inferenceMarks: [{time, eliminated}]`,从 `decisionReceipt.inference_state.candidates` 的 `time` / `status` 解析(组件不读原始 receipt)。`state = status === "eliminated" ? "out" : "in"`,不再按点是否落在带内判断。没有 `inference_state` 时退回引擎候选全部实心。
|
||||
- 验证:`frontend/tests/rectification-timeline-20260909.test.ts`:推断层 9 个候选、7 个 eliminated、可信区间 04:51–04:53 → 9 个点、7 空心 2 实心;再淘汰 1 个 → 8 空心 1 实心,key 不变。`frontend/tests/rectification-candidate-result.test.ts`:有 `inference_state` 时解析出全集,无则 `[]`。聊天源码合同:`timelineView` 读 `inferenceMarks`,不读 `decisionReceipt`。
|
||||
- 防复发:时间轴标记必须来自推断层候选全集;禁止再用引擎 active 投影或带内位置当 in/out。空心/实心只看 `status === "eliminated"`。
|
||||
- 相关记录:BUG-560、DESIGN.md §10
|
||||
- 复发自:无
|
||||
- 修复版本:`92e3d5e7`
|
||||
|
||||
@@ -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` 切出)
|
||||
|
||||
本单状态:**待验收**。提交 `92e3d5e7`。未 push,未合入 staging/main,未声称生产部署。
|
||||
|
||||
预检:本机 `python3 scripts/pre_work_check.py` 失败(系统 Python 3.14 无 pytest、无 swisseph,ERR-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:07–05:09 | `2 分钟` | `3 分钟` | 含 05:07、05:08、05:09 三分钟;与 DESIGN §10 / 报告口径一致 |
|
||||
| 04:51–04:59 | `8 分钟` | `9 分钟` | 含两端;与三列卡同一形状 |
|
||||
| 04:51–04:53 | `2 分钟` | `3 分钟` | 与 `rectification-delivery-report-facts.test.ts` 的 `width_minutes === 3` 同一形状 |
|
||||
| 05:07–05:07 | `0 分钟` | `1 分钟` | 单分钟窗口 |
|
||||
| 00:00–23:59 整天 | `23 小时 59 分` | `24 小时` | 1440 分钟;时段阶段尚未排除任何分钟 |
|
||||
| 04:56–05:20(放宽后) | `24 分钟` | `25 分钟` | 含两端 |
|
||||
| 00:30–01:30(跨午夜带) | `1 小时` | `1 小时 1 分` | 61 分钟,同一条 `+ 1` 规则 |
|
||||
|
||||
## 三栏 · 标记改按 status
|
||||
|
||||
| 用例 | 原值 | 新值 | 理由 |
|
||||
| --- | --- | --- | --- |
|
||||
| 合成 05:06…05:10,带 05:07–05: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。浏览器级空心点/贴底仍欠真实会话。不把合同测试写成已经看见真实像素。
|
||||
@@ -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-505~509) |
|
||||
| `TASK-rectification-timeline-20260909.md` | — | 常驻吸顶时间轴:轴锁**当前**搜索窗口并随放宽缩放、时段/分钟两套标记、候选点二元编码不分置信度(BUG-560 blocked)、无 hover(BUG-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-602~603) |
|
||||
| `TASK-rectification-timeline-fix-20260909.md` | `PROGRESS-rectification-timeline-fix-20260909.md` | 时间轴修复单:宽度读数改含两端分钟数(与 BUG-593 报告/卡片一致);标记改读推断层候选全集,被淘汰分钟留在原地变空心(客户端投影只含 active,DESIGN §10 描述在真实数据下画不出) | 待验收 | `92e3d5e7`(BUG-602~603) |
|
||||
| `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-604~606) |
|
||||
|
||||
### 聊天主链路与首页
|
||||
|
||||
@@ -35,7 +35,7 @@ iOS Safari 与 Android Chrome 各走一次,在校正对话里点输入框唤
|
||||
|
||||
需要一个「完全不知道出生时间」的 Case 才能走到时段阶段。
|
||||
|
||||
- [ ] 开场(整天或 ±120)时:条上是否**不出现**分钟圆点,区间带铺满整条轴,读数写整个窗口的宽度(如「23 小时 59 分」)?
|
||||
- [ ] 开场(整天或 ±120)时:条上是否**不出现**分钟圆点,区间带铺满整条轴,读数写整个窗口的宽度(如「24 小时」)?
|
||||
- [ ] 选定时段后:轴是否重新对到新窗口,读数变小?
|
||||
- [ ] 进入分钟阶段后:候选圆点是否出现?
|
||||
- [ ] 触发一次放宽(吻合率低且代表分钟贴边缘,BUG-572):轴是否向外扩,区间带**没有**被裁掉或溢出轴外?
|
||||
@@ -43,11 +43,11 @@ iOS Safari 与 Android Chrome 各走一次,在校正对话里点输入框唤
|
||||
|
||||
## 4. 二元编码与只读
|
||||
|
||||
- [ ] 答完一道区分题后,被排除的分钟是否**留在原地变成空心**而不是消失?
|
||||
- [ ] 答完一道区分题后,被排除的分钟是否**留在原地变成空心且不消失**(数据来自推断层)?
|
||||
- [ ] 所有圆点是否**一样大**?(不得有任何按可能性大小分级的迹象——BUG-560 状态是 blocked)
|
||||
- [ ] 鼠标悬停在条上任何位置:是否**没有**任何浮层、提示、文案变化?
|
||||
- [ ] 点击条上任何位置:是否**没有**任何反应?(采用只在交付卡上)
|
||||
- [ ] 条上是否只有两样东西:轴,和形如 `05:07–05:09 · 2 分钟` 的读数?不应出现计数、图例、阶段名、「已对照 N 件经历」或任何注脚。
|
||||
- [ ] 条上是否只有两样东西:轴,和形如 `05:07–05:09 · 3 分钟` 的读数?不应出现计数、图例、阶段名、「已对照 N 件经历」或任何注脚。
|
||||
|
||||
## 5. 跨午夜窗口
|
||||
|
||||
|
||||
Reference in New Issue
Block a user