Files
Jyotisha/docs/tasks/PROGRESS-rectification-timeline-20260909.md
T
Jesse_ChenandClaude Fable 5 724a1215fe
Independent Staging Quality Gate / validate (push) Successful in 10m54s
Independent Staging Quality Gate / publish (push) Successful in 8m31s
docs(rectification): timeline progress notes, walkthrough and blockers
No BUG entry: this is new capability and no existing defect surfaced.
Records the block-scan concession and the width-transition guard that
the first attempt tripped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016P5RoqzmUQEbeC2qjAkeGr
2026-09-09 04:23:11 +00:00

5.5 KiB
Raw Blame History

PROGRESS · 生时校正常驻时间轴(2026-09-09)

  • 任务书:docs/tasks/TASK-rectification-timeline-20260909.md
  • 分支:codex/rectification-timeline-20260909,基线 origin/staging = 109b1d7f
  • BUG 编号:未开条目。开工核对最大号为 601(任务书预期 602 仍可用)。本单是新增能力,实现中未发现既有缺陷,按任务书任务 7「不强开」。
  • 服务端与数据库:未改一行

任务 0 · 数据源确认

用途 字段 结论
轴的两端 candidate_range 可得。服务端已在 api/rectification/cases/[caseId]/route.ts:125 下发;客户端类型 RectificationCaseSnapshotPayload.case 此前只声明 status / accepted_time / confirmed_time,本轮把 candidate_rangestage 补进该类型并加解析器。这是读一个已经在网线上的字段,不是新增服务端字段。
阶段 stage 可得,同上 :126,取值 "minute" | "block_scan"
区间带 credibleRange 可得rectification-candidate-result.ts:95,会话中途即有
候选标记 candidates[].time 可得,同上 :71

一处任务书未预料的事实:stage === "block_scan"latest_result 恒为 nullroute.ts:145 显式短路),因此该阶段既没有 credibleRange 也没有候选分钟。处理见让步 1。

让步

让步 1(任务书 §6 第 1 条):时段阶段不画区块。 区块边界在客户端只以显示字符串存在(BLOCK_PERIOD_LABELS 形如 "清晨 04:00—07:59"block-scan.ts:39-44),没有结构化的 start/end 到达客户端;把展示文案反解析成几何太脆。

按任务书让步条款,该阶段只画轴与区间带。结合上面 latest_result === null 的事实,具体呈现是:区间带铺满整个窗口,读数写窗口宽度(如 00:0023:59 · 23 小时 59 分)。这不是占位——那一刻确实一分钟都还没排除,写满宽是事实。时段选定后窗口收窄、轴随之缩放,读数跟着变小,收敛感仍然成立。

未让步:任务 4 的轴缩放动画照做(用 CSS transition);任务 6 的移动端照做(56px)。不可让步的五条全部落地。

一处与任务书写法不同(行为不变)

任务书任务 1 写「按当前轴跨度换算百分比」,未规定用哪个 CSS 属性落位。初版用 left / width 加 transition撞上既有红线tests/sidebar-contract.test.ts:314 有一条全文件断言 doesNotMatch(globalStyles, /transition:[^;}]*\b(?:width|grid-template-columns)\b/),对应 DESIGN.md 的 "Sidebar state changes are immediate"——globals.css 里禁止任何 width 过渡。

改为只用 transform 落位与过渡:区间带是满宽元素,transform-origin: lefttranslateX(起点%) scaleX(跨度),一个 transform 同时承载起点与宽度;候选点套一层满宽定位元素用 translateX(百分比)。副作用是区间带不能再用 border-inlinescaleX 会把边框一起压扁),改为纯色块——--color-action-soft 的填充边缘本身就是边界,且更符合本单「越简约越好」的口径。刻度仍用静态 left(不过渡:轴一缩放整套刻度就重建,滑动它没有意义)。

这个改法比原写法更好:transform 走合成层,不像 left/width 每帧触发布局。既有断言未修改、未弱化。

数字

基线 109b1d7f 改后 结论
npm test 总数 2949 2966+17 不低于基线
pass 2907 2924+17
fail 28 28 失败清单与基线 diff 逐条一致(全部为无 Docker 的数据库/部署套件)
skipped 14 14
tsc --noEmit 退出码 0 / 0 行 退出码 0 / 0 行
npm run lint 0 error / 108 warning 0 error / 108 warning 无一条新 warning
next build 退出码 0┌ ○ / / 仍 Static
首屏 CSS gzip 38,916 B 39,287 B+0.95% ±2% 内

gzip 口径:next build 输出不含体积列,故量 .next/static/chunks/*.css 的 gzip 合计。基线数字是在同一 worktree 里把 globals.css 临时换回 origin/staging 版本重新构建所得,量完已还原(git status 干净)。新增 JS 不进首屏:page.tsx 不引用时间轴,校正面本来就是 dynamic() 分包。

frontend/src/hooks/use-conversation-scroll-anchor.tsgit diff 为空(任务 2 验收标准)。

中途修掉的一次自伤

初版全量测试 fail 从 28 涨到 29,新增的是 sidebar-contract.test.ts 的 "selects desktop and tablet shell widths from provider data"。原因即上面那条 width 过渡。改用 transform 后失败数回到 28,并在本单测试里加了一条锁(band/mark 不得出现内联 left/width,条的样式块不得出现 width/left/height 过渡),防止后人改回去。

环境缺口

无登录态、无 Chrome、无 Docker浏览器级验收全部未做,写成 docs/testing/rectification-timeline-20260909.md(6 节)交给有真实会话的人,未标记为通过。其中两条是任务书点名、本环境判断不了的:桌面端与右侧板「换升时刻」是否重复;移动端键盘弹出后是否仍同屏。

第 2 节「贴底跟随」是本设计最大的技术风险点:代码上条高固定、合同测试也锁了,但「贴底时内容不会滑出视野」这件事只有真实滚动才能确认。

交付

  • 未 push,本地提交,等验收。