From 724a1215fec381744a3bde4e8206f75e57cfc532 Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Wed, 9 Sep 2026 04:23:11 +0000 Subject: [PATCH] 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 Claude-Session: https://claude.ai/code/session_016P5RoqzmUQEbeC2qjAkeGr --- BLOCKED.md | 7 ++ CHANGELOG.md | 9 +++ ...ROGRESS-rectification-timeline-20260909.md | 64 +++++++++++++++++++ .../rectification-timeline-20260909.md | 63 ++++++++++++++++++ 4 files changed, 143 insertions(+) create mode 100644 docs/tasks/PROGRESS-rectification-timeline-20260909.md create mode 100644 docs/testing/rectification-timeline-20260909.md diff --git a/BLOCKED.md b/BLOCKED.md index d1459ed4..579c5605 100644 --- a/BLOCKED.md +++ b/BLOCKED.md @@ -1,5 +1,12 @@ # BLOCKED +## 生时校正常驻时间轴(2026-09-09,分支 `codex/rectification-timeline-20260909`) + +- **浏览器级验收全部未做:执行环境无登录态、无 Chrome。** 六节走查条目写进 `docs/testing/rectification-timeline-20260909.md`,未标记为通过。替代证据是 `frontend/tests/rectification-timeline-20260909.test.ts` 的 17 项(几何换算、二元编码、闭区间边界、跨午夜窗口、放宽后仍落在轴内、三处源码锁、CSS 合同)。 +- **最需要真人确认的一条:贴底跟随。** 时间轴在滚动容器之外,高度固定是靠 CSS 与合同测试保证的;「贴底时新消息不会滑出视野下缘」只有真实滚动能确认。BUG-218/252 的教训正是纯源码合同测试固定不了几何。 +- **时段阶段的区块未画(任务书 §6 让步 1)。** 区块边界在客户端只以显示字符串存在(`BLOCK_PERIOD_LABELS` 形如 `"清晨 04:00—07:59"`),没有结构化 `start/end` 下发;反解析展示文案太脆,未做。该阶段区间带铺满窗口、读数写窗口宽度。若日后要画区块,需要服务端把子段边界结构化下发——属于另立一单的响应新增字段。 +- **桌面端时间轴与右侧板「换升时刻」是否重复,未判定。** 任务书决策记录第 7 条明确留给真人走查(清单 1.1),本轮未做取舍。 + ## 报告生成分章进度(2026-09-09,分支 `codex/report-progress-20260909`,BUG-601) - **真实报告生成一次都没跑过:执行环境无登录态、无 Chrome、无模型凭据。** 因此"写作阶段真的会出现""章节名不错位""慢章节文案真的会切换"这三条**没有任何运行时证据**,只有纯函数测试与源码锁(`frontend/tests/personal-report-progress.test.ts` 16 项)。逐条走查清单见 `docs/testing/report-progress-20260909.md`,交给有真实账号的人。 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f9f05f8..56f9128b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # 印度占星 Skill 更新日志 +## 2026-09-09 — 生时校正对话上方常驻一条时间轴,看得见范围在收窄 + +做生时校正时,对话上方多了一条固定的横条,写着当前的出生时间范围和它有多宽,例如「05:07–05:09 · 2 分钟」。下面那条轴按当前搜索范围铺开,候选分钟是一个个小圆点:还在范围内的是实心,已经被排除的变成空心留在原地——每答一题就能看见自己刚才那一答排掉了哪几分钟。范围收窄或放宽时,轴和圆点会滑到新位置。 + +还在按时段比对(只知道大概时段、或完全不知道出生时间)的阶段,轴上不出现分钟圆点,写的是整个时段的宽度,因为那时确实还没排除任何分钟。 + +这条轴只用来看,不能点:选哪一个分钟仍然在最后的候选对照卡上完成。条上只有范围读数和轴本身,没有计数、没有图例,也不显示预计还要多久。Skill 版本不变。 + + ## 2026-09-09 — 报告生成改成按章报进度,不再只有一个转圈 生成个人报告时,等待页不再只显示一个转圈和已等待时间。准备证据时仍是一句「正在准备你的星盘证据」;开始写章节后换成「已完成 N / M 章」,下面是一条按章分格的进度条和章节清单(事业、婚恋、财富、应期、健康),每章标着已完成 / 正在写 / 待写 / 写作失败;最后收尾时显示「正在整理成文」。某一章写超过 90 秒会改成「用时较长,仍在写」,不再让人以为卡死。进度条按章分格而不是画百分比,也不做平滑动画——后端没推进,屏幕就不动。写作失败的章仍然计入完成数,但结尾会说明哪几个主题没写成,不会只说一句完成。Skill 版本不变。 diff --git a/docs/tasks/PROGRESS-rectification-timeline-20260909.md b/docs/tasks/PROGRESS-rectification-timeline-20260909.md new file mode 100644 index 00000000..6b4cf632 --- /dev/null +++ b/docs/tasks/PROGRESS-rectification-timeline-20260909.md @@ -0,0 +1,64 @@ +# 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_range` 与 `stage` 补进该类型并加解析器。**这是读一个已经在网线上的字段,不是新增服务端字段。** | +| 阶段 | `stage` | **可得**,同上 :126,取值 `"minute" \| "block_scan"` | +| 区间带 | `credibleRange` | **可得**,`rectification-candidate-result.ts:95`,会话中途即有 | +| 候选标记 | `candidates[].time` | **可得**,同上 :71 | + +**一处任务书未预料的事实:`stage === "block_scan"` 时 `latest_result` 恒为 `null`**(`route.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:00–23: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: left` 加 `translateX(起点%) scaleX(跨度)`,一个 transform 同时承载起点与宽度;候选点套一层满宽定位元素用 `translateX(百分比)`。副作用是区间带不能再用 `border-inline`(`scaleX` 会把边框一起压扁),改为纯色块——`--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.ts` 的 `git 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,本地提交,等验收。 diff --git a/docs/testing/rectification-timeline-20260909.md b/docs/testing/rectification-timeline-20260909.md new file mode 100644 index 00000000..4a58a017 --- /dev/null +++ b/docs/testing/rectification-timeline-20260909.md @@ -0,0 +1,63 @@ +# 生时校正常驻时间轴:真实环境走查清单(2026-09-09) + +分支 `codex/rectification-timeline-20260909`,任务书 `docs/tasks/TASK-rectification-timeline-20260909.md`。 + +执行环境无登录态、无 Chrome、无 Docker,以下条目**全部未做**,交给有真实会话的人。自动化替代证据见 `frontend/tests/rectification-timeline-20260909.test.ts`(17 项):它锁得住 DOM、类名、CSS 声明与几何换算,**锁不住浏览器里的真实像素与滚动行为**。BUG-218/252 的教训正是这一条——纯源码合同测试能固定属性,固定不了几何位置。 + +## 1. 两条任务书点名、本环境判断不了的 + +### 1.1 桌面端时间轴与右侧板「换升时刻」是否显得重复 + +桌面宽屏打开一个已进入分钟阶段的 Case,让时间轴与右侧板同屏。 + +- [ ] 两者是否读起来像同一份信息重复了两遍? +- [ ] 时间轴的刻度只标整点/整刻(不标每个候选分钟的数字),板上的「换升时刻」才逐分钟列出并带 LayerChips——这个粗细差别在真实屏幕上是否足以让人不觉得重复? +- [ ] 若判断为重复,产品需在两条出路里选一条:时间轴取代板上「换升时刻」段,或时间轴只留区间带、把分钟点也去掉。**本轮未做取舍**(任务书决策记录第 7 条留下的问题)。 + +### 1.2 移动端键盘弹出后是否仍同屏 + +iOS Safari 与 Android Chrome 各走一次,在校正对话里点输入框唤起键盘。 + +- [ ] 时间轴 + 输入框 + 至少一条完整消息气泡是否仍同屏可见? +- [ ] 时间轴是否随视觉视口收缩按比例缩小,而不是被键盘顶出屏幕或盖住输入框? +- [ ] 键盘收起后布局是否回到原样、没有残留空白? + +## 2. 贴底跟随(本设计最大的技术风险) + +时间轴在滚动容器之外,它的高度变化不会被 `useConversationScrollAnchor` 的 `ResizeObserver` 看到。代码上高度是固定的,但需要真实验证没有别的路径改变它。 + +- [ ] 滚到底部后连续答 3 道题:新消息到达时是否始终自动贴底,没有内容停在视野下缘之外? +- [ ] 手动向上滚一段,再答一题:是否正确解除贴底(不强行拉回),且「跳到最新」按钮出现? +- [ ] 「跳到最新」按钮是否仍挂在输入框上沿,**没有被时间轴遮住**,点击后正常落底? +- [ ] Case 从未载入切到已载入的那一瞬间,时间轴是否**没有**改变高度(不应看到对话区跳动,也不应看到「跳到最新」凭空弹出)? + +## 3. 轴缩放与两个阶段 + +需要一个「完全不知道出生时间」的 Case 才能走到时段阶段。 + +- [ ] 开场(整天或 ±120)时:条上是否**不出现**分钟圆点,区间带铺满整条轴,读数写整个窗口的宽度(如「23 小时 59 分」)? +- [ ] 选定时段后:轴是否重新对到新窗口,读数变小? +- [ ] 进入分钟阶段后:候选圆点是否出现? +- [ ] 触发一次放宽(吻合率低且代表分钟贴边缘,BUG-572):轴是否向外扩,区间带**没有**被裁掉或溢出轴外? +- [ ] 系统开启「减弱动效」后,上述变化是否瞬间完成、没有过渡动画? + +## 4. 二元编码与只读 + +- [ ] 答完一道区分题后,被排除的分钟是否**留在原地变成空心**而不是消失? +- [ ] 所有圆点是否**一样大**?(不得有任何按可能性大小分级的迹象——BUG-560 状态是 blocked) +- [ ] 鼠标悬停在条上任何位置:是否**没有**任何浮层、提示、文案变化? +- [ ] 点击条上任何位置:是否**没有**任何反应?(采用只在交付卡上) +- [ ] 条上是否只有两样东西:轴,和形如 `05:07–05:09 · 2 分钟` 的读数?不应出现计数、图例、阶段名、「已对照 N 件经历」或任何注脚。 + +## 5. 跨午夜窗口 + +需要一个声明为「夜里到凌晨」(23:00–03:59)的 Case。 + +- [ ] 轴是否从 23:00 单调走到 03:59(刻度依次 23:00 / 00:00 / 01:00 / 02:00 / 03:00),而不是首尾颠倒或空白? +- [ ] 区间带与圆点是否落在正确位置? + +## 6. 视觉 + +- [ ] 浅色与深色主题下条的背景、发丝线、区间带、空心点是否都清晰可辨? +- [ ] 开启「增强对比度」与「减少透明度」后是否仍可读?(本条用纯色背景、未用 `backdrop-filter`,预期不受影响) +- [ ] 长时间会话滚动时,条是否稳定不抖动?