docs(tasks): Claude acceptance for birth-sky cover + followup
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
731c3b364b
commit
be9e4dbee5
@@ -215,3 +215,27 @@ JS 的 +773 B 是首页为 T6 引入的 `useBirthSkyReveal`、`startBirthSkyReve
|
|||||||
- 无 Docker:24 条 DB / 部署套件失败与基线逐条同名;quick 门禁最后一步因此退出码 1。本单不改表结构、不加迁移。
|
- 无 Docker:24 条 DB / 部署套件失败与基线逐条同名;quick 门禁最后一步因此退出码 1。本单不改表结构、不加迁移。
|
||||||
- 无模型凭据:真实报告生成(含写入指纹的三条路径)只在注入假代理的单测里跑过,部署后需新生成一份报告复核(清单第 18 条)。
|
- 无模型凭据:真实报告生成(含写入指纹的三条路径)只在注入假代理的单测里跑过,部署后需新生成一份报告复核(清单第 18 条)。
|
||||||
- 未推送、未部署(按任务书由 Claude 验收后整体快进推 staging)。
|
- 未推送、未部署(按任务书由 Claude 验收后整体快进推 staging)。
|
||||||
|
|
||||||
|
## Claude 验收(2026-09-28,分支五个提交,`731c3b36`)
|
||||||
|
|
||||||
|
在同一工作树上独立重跑,不采信执行方数字。
|
||||||
|
|
||||||
|
| 项 | 结论 | 证据 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `tsc --noEmit` | 通过 | 0 错 |
|
||||||
|
| `npm run lint` | 通过 | 0 error / 127 warning(与基线同) |
|
||||||
|
| `npm test` | 通过(环境缺口除外) | tests 4310 · pass 4255 · fail 24 · skipped 31;24 条失败逐条同名于基线,全部是 Docker / PostgreSQL / 部署套件 |
|
||||||
|
| pytest `test_birth_sky` + `test_api_server_growth_contract` + `test_personal_report_contract` + `test_repo_privacy_markers` | 通过 | 全部 passed |
|
||||||
|
| quick 门禁 | Python 部分通过 | 997 passed / 1 skipped;末步 `npm test` 因无 Docker 退出码 1 |
|
||||||
|
| `rm -rf .next && next build` | 通过 | `/` ○ Static |
|
||||||
|
| 首屏 gzip | 通过 | Claude 口径(`index.html` 里 `/_next/static/*.js|css` 逐个 gzip -9 求和)另建基线 `d670521f` 对比:JS 649,819 → 650,883 B(+0.16%),CSS 66,126 → 66,126 B(0)。与执行方口径绝对值不同、相对变化一致 |
|
||||||
|
| 硬红线 1 指纹不下发 | 通过 | 报告详情只下发 `coverSubject`;`reportDocument` 走白名单投影不含 `subject`;测试断言响应体不含指纹与出生字段;指纹不进模型 bundle |
|
||||||
|
| 硬红线 2 不改表 | 通过 | 无迁移、无 schema 目录改动 |
|
||||||
|
| 硬红线 3 增长 | 通过 | `jyotish_api_server.py` 本系列仅 T2 的 7 行薄注册;`page.tsx` 追加单未改 |
|
||||||
|
| 硬红线 4 不等待 | 通过 | 3 秒预算含取数 / 字体 / chunk,超时静默;报告封面失败返回 null 不占位 |
|
||||||
|
| 硬红线 5 末帧一致 | 通过 | `interpolateSkyPoint` t≥1 精确返回真实点、alpha 乘 1;测试逐条比对画布调用序列;执行方取帧停留帧与导出 PNG dataURL 相同 |
|
||||||
|
| 四帧 | 已看 | scratchpad `birth-sky-converge-night-{t0,t050,t100,hold}.png`:散开 → 半程 → 到位无字 → 停留有字 |
|
||||||
|
|
||||||
|
偏离裁定:1(指纹不进 bundle)采纳,比任务书更稳;2(指纹含姓名 / 岁差,改名后旧报告失去封面)接受,属「同一种算法」的直接后果,已写给产品;3–7 接受。
|
||||||
|
|
||||||
|
环境缺口不变:真机 / 登录态(清单 18–30 条)、Docker、模型凭据。
|
||||||
|
|||||||
@@ -248,7 +248,8 @@
|
|||||||
| `TASK-consult-first-frame-and-pacing-20260928.md` | `PROGRESS-consult-first-frame-and-pacing-20260928.md` | **普通对话发出即有反馈、正文按打字节奏放出**:客户端分类前静默(BUG-976 副作用)+ 服务端分类后才开流 → 发出后一两秒空白;服务端 160 字截留 + 客户端 settle 一帧全放 → 追问轮正文一下全出。D1 首帧「收到,正在看你的问题…」、D2 先建流、D3 每帧上限 + 限时收尾、D4 160 字阈值不动 | 已验收并部署 staging(真机欠) | 分支 `codex/consult-first-frame-and-pacing-20260928`(未推送);进度 `PROGRESS-consult-first-frame-and-pacing-20260928.md`;BUG-1074 / BUG-1075 |
|
| `TASK-consult-first-frame-and-pacing-20260928.md` | `PROGRESS-consult-first-frame-and-pacing-20260928.md` | **普通对话发出即有反馈、正文按打字节奏放出**:客户端分类前静默(BUG-976 副作用)+ 服务端分类后才开流 → 发出后一两秒空白;服务端 160 字截留 + 客户端 settle 一帧全放 → 追问轮正文一下全出。D1 首帧「收到,正在看你的问题…」、D2 先建流、D3 每帧上限 + 限时收尾、D4 160 字阈值不动 | 已验收并部署 staging(真机欠) | 分支 `codex/consult-first-frame-and-pacing-20260928`(未推送);进度 `PROGRESS-consult-first-frame-and-pacing-20260928.md`;BUG-1074 / BUG-1075 |
|
||||||
| `TASK-chart-types-and-report-buttons-20260928.md` | `PROGRESS-chart-types-and-report-buttons-20260928.md`、`PROGRESS-ayanamsa-report-buttons-20260928.md` | **星盘盘型扩充 + 表格随盘换 + 七政隐藏 + 岁差 6 项 + 我的报告按钮配色**:分盘表一直显示 D1 数据(BUG-1076);盘型条 + 「星盘类型」面板共 23 种(加 月亮盘 / Bhava / 行运 / D40 / D45 / D60);Bhava 端点缺 MC 静默等宫(BUG-1077);报告深色主按钮黑字深红、禁用半透明(BUG-1078,只改报告范围) | 已验收、已部署 staging `6a4e312c`(真机欠) | `af27709d`…`4189750c`(子代理实现 + Claude 验收补丁);BUG-1076~1078;含迁移 `20260928010000_profile_ayanamsa_six` |
|
| `TASK-chart-types-and-report-buttons-20260928.md` | `PROGRESS-chart-types-and-report-buttons-20260928.md`、`PROGRESS-ayanamsa-report-buttons-20260928.md` | **星盘盘型扩充 + 表格随盘换 + 七政隐藏 + 岁差 6 项 + 我的报告按钮配色**:分盘表一直显示 D1 数据(BUG-1076);盘型条 + 「星盘类型」面板共 23 种(加 月亮盘 / Bhava / 行运 / D40 / D45 / D60);Bhava 端点缺 MC 静默等宫(BUG-1077);报告深色主按钮黑字深红、禁用半透明(BUG-1078,只改报告范围) | 已验收、已部署 staging `6a4e312c`(真机欠) | `af27709d`…`4189750c`(子代理实现 + Claude 验收补丁);BUG-1076~1078;含迁移 `20260928010000_profile_ayanamsa_six` |
|
||||||
| `TASK-site-button-contrast-20260928.md` | `PROGRESS-site-button-contrast-20260928.md` | **全站实心按钮配色与禁用态统一**:层外 `button { color: inherit }` 压掉 Tailwind 文字色(61 个 `<Button>` 浅 3.33 / 深 2.57),`.button-primary` 30 个浅色 3.14,全部禁用态 45% 透明;产品选 A:全站用报告页配色(浅 4.85 / 深 5.77),推翻 DESIGN「已知缺口」;禁用改灰;删 BUG-1078 局部覆盖(BUG-1079) | 已验收、已部署 staging `dc640931`(真机欠) | `12aac87b` + `fa58df16`;BUG-1079 |
|
| `TASK-site-button-contrast-20260928.md` | `PROGRESS-site-button-contrast-20260928.md` | **全站实心按钮配色与禁用态统一**:层外 `button { color: inherit }` 压掉 Tailwind 文字色(61 个 `<Button>` 浅 3.33 / 深 2.57),`.button-primary` 30 个浅色 3.14,全部禁用态 45% 透明;产品选 A:全站用报告页配色(浅 4.85 / 深 5.77),推翻 DESIGN「已知缺口」;禁用改灰;删 BUG-1078 局部覆盖(BUG-1079) | 已验收、已部署 staging `dc640931`(真机欠) | `12aac87b` + `fa58df16`;BUG-1079 |
|
||||||
| `TASK-birth-sky-cover-20260928.md` | `PROGRESS-birth-sky-cover-20260928.md` | **「那一刻的天空」封面**:出生那一刻头顶的真实天空做成 3:4 封面(产品从 A 年轮 / B 一笔画 / C 天空三版样稿中选 C,样稿 `assets/birth-sky-cover-sample-20260928.html`);星盘页按钮 + 保存图片、报告封面(须对得上报告出生资料)、首次建盘揭幕;不印出生资料、句库只描述天空、无新依赖 | 已实现待验收(分支 `codex/birth-sky-cover-20260928`,未推送);T5 报告封面 blocked(无出生资料绑定,见 BLOCKED.md) | 新功能,不开 BUG |
|
| `TASK-birth-sky-cover-20260928.md` | `PROGRESS-birth-sky-cover-20260928.md` | **「那一刻的天空」封面**:出生那一刻头顶的真实天空做成 3:4 封面(产品从 A 年轮 / B 一笔画 / C 天空三版样稿中选 C,样稿 `assets/birth-sky-cover-sample-20260928.html`);星盘页按钮 + 保存图片、报告封面(须对得上报告出生资料)、首次建盘揭幕;不印出生资料、句库只描述天空、无新依赖 | 已验收(Claude 2026-09-28),随分支五个提交推 staging;T5 由追加单解除 | 新功能,不开 BUG |
|
||||||
|
| `TASK-birth-sky-followup-20260928.md` | `PROGRESS-birth-sky-cover-20260928.md`(追加单) | **天空封面追加**:报告封面按生成时出生资料指纹绑定(方案 A,旧报告永不显示);首次建盘揭幕改群星汇聚过场(无按钮、3 秒预算、可点跳过、减弱动态只淡入淡出) | 已验收(Claude 2026-09-28),已推 staging | 新功能,不开 BUG |
|
||||||
| `TASK-serif-headings-20260928.md` | `PROGRESS-serif-headings-20260928.md` | **全站标题改用自托管宋体、正文保持黑体**:产品推翻 BUG-737「CJK 不用衬线」结论(保留「声明的字体必须可加载」「不落系统宋体」两条);Noto Serif SC SemiBold 按通用规范汉字表 6500 字 unicode-range 切片自托管(改名 Jyotisha Serif SC),swap 不 preload;首页宋体流量 ≤300 KB;先于天空封面单 | 已实现待验收(分支 `codex/serif-headings-20260928`,未推送) | 不开新 BUG;BUG-737 追加说明 |
|
| `TASK-serif-headings-20260928.md` | `PROGRESS-serif-headings-20260928.md` | **全站标题改用自托管宋体、正文保持黑体**:产品推翻 BUG-737「CJK 不用衬线」结论(保留「声明的字体必须可加载」「不落系统宋体」两条);Noto Serif SC SemiBold 按通用规范汉字表 6500 字 unicode-range 切片自托管(改名 Jyotisha Serif SC),swap 不 preload;首页宋体流量 ≤300 KB;先于天空封面单 | 已实现待验收(分支 `codex/serif-headings-20260928`,未推送) | 不开新 BUG;BUG-737 追加说明 |
|
||||||
| `TASK-cend-ui-claude-alignment-20260916.md` | `PROGRESS-cend-ui-r1/r2/r3-20260916.md` | **C 端界面向 claude.ai 产品界面对齐(三轮串行 R1→R2→R3,都动 `globals.css`,不得并行)**:根因是 `frontend/CLAUDE_DESIGN.md` 扒的是 **claude.com 营销官网**,它自己在 Known Gaps 里写明 claude.ai 产品界面不在范围内,而 `DESIGN.md:3` 把它当成了产品界面的实现契约。**R1**:`--font-display` 里 Tiempos Headline / StyreneB **从未加载**(无 `@font-face`、`public/` 无字体、`layout.tsx` 只 vendor 了 Inter),中文标题全站落到 **宋体 / SimSun**,波及 20 处含助手回答的 h2/h3(BUG-737);亮色强调色 `#85432f` 与暗色 `#d78064` 不同源,产品拍板亮色换 **Claude coral `#cc785c`**,**易漏点**是 `globals.css:16` 的 `--color-ring` 硬编码在 `@theme inline` 里不跟随 `:root`,另有第四个 `:root` 亮色块(`:4358`)必须同步(BUG-738);`.composer-footer` 常驻 44px + 顶栏 68px + `--composer-reserve` 148px,每屏固定吃掉 216px,模型选择器移进输入框内部、删掉底栏、顶栏收到 46px 并删「分析对象」副标题。**R2**:空状态是营销落地页(hero 卡 + 两张 132px 入口大卡 + 3 列 156px 主题卡),输入框被压在 **800px 以上**内容之下,重排成「问候 + 居中输入框 + 两枚入口 pill + 一排 chip」。**R3**:侧栏两个 `<details>` 拍平成一条「最近」、星盘的两个入口(侧栏分组 + 账户菜单)收敛到一处、删掉逐条助手头像。**决策记录 D3 推翻 DESIGN.md「报告强调色与应用同源」一句**(报告刻意保留深棕)。原型图 https://claude.ai/code/artifact/da275da6-2954-4f50-99aa-32bb8694d38b(三套画面 + 明暗,页面标题就是建议字体栈的实际渲染)。环境缺口:无登录态无 Chrome,四项真机观感留 `docs/testing/`。BUG 段 737–738 | 待领取 | — |
|
| `TASK-cend-ui-claude-alignment-20260916.md` | `PROGRESS-cend-ui-r1/r2/r3-20260916.md` | **C 端界面向 claude.ai 产品界面对齐(三轮串行 R1→R2→R3,都动 `globals.css`,不得并行)**:根因是 `frontend/CLAUDE_DESIGN.md` 扒的是 **claude.com 营销官网**,它自己在 Known Gaps 里写明 claude.ai 产品界面不在范围内,而 `DESIGN.md:3` 把它当成了产品界面的实现契约。**R1**:`--font-display` 里 Tiempos Headline / StyreneB **从未加载**(无 `@font-face`、`public/` 无字体、`layout.tsx` 只 vendor 了 Inter),中文标题全站落到 **宋体 / SimSun**,波及 20 处含助手回答的 h2/h3(BUG-737);亮色强调色 `#85432f` 与暗色 `#d78064` 不同源,产品拍板亮色换 **Claude coral `#cc785c`**,**易漏点**是 `globals.css:16` 的 `--color-ring` 硬编码在 `@theme inline` 里不跟随 `:root`,另有第四个 `:root` 亮色块(`:4358`)必须同步(BUG-738);`.composer-footer` 常驻 44px + 顶栏 68px + `--composer-reserve` 148px,每屏固定吃掉 216px,模型选择器移进输入框内部、删掉底栏、顶栏收到 46px 并删「分析对象」副标题。**R2**:空状态是营销落地页(hero 卡 + 两张 132px 入口大卡 + 3 列 156px 主题卡),输入框被压在 **800px 以上**内容之下,重排成「问候 + 居中输入框 + 两枚入口 pill + 一排 chip」。**R3**:侧栏两个 `<details>` 拍平成一条「最近」、星盘的两个入口(侧栏分组 + 账户菜单)收敛到一处、删掉逐条助手头像。**决策记录 D3 推翻 DESIGN.md「报告强调色与应用同源」一句**(报告刻意保留深棕)。原型图 https://claude.ai/code/artifact/da275da6-2954-4f50-99aa-32bb8694d38b(三套画面 + 明暗,页面标题就是建议字体栈的实际渲染)。环境缺口:无登录态无 Chrome,四项真机观感留 `docs/testing/`。BUG 段 737–738 | 待领取 | — |
|
||||||
| `TASK-cend-surfaces-claude-alignment-20260916.md` | `PROGRESS-cend-shell-20260916.md`、`PROGRESS-cend-report-20260916.md`、`PROGRESS-cend-rectification-20260916.md`、`PROGRESS-cend-chart-eph-20260916.md` | **次级页面对齐(上一单的续篇,R4→R5/R6,R7、R8 可并行)**:星盘 `/chart`、星历 `/ephemeris`、报告 `/reports` **各是脱离 app 外壳的独立全屏页**,顶部只有一个「返回对话」链接、侧栏整个消失,且三家各写了一套一模一样的 `*-shell`/`*-topbar`/`*-hero` 骨架——与上一单 E5 同根因(营销站 band 结构被套到产品界面)。**R4** 抽只读导航外壳 `AppNavRail`(只用现成的 `GET /api/sessions` + `GET /api/account`,会话行走 `sessionHref` 跳 `/?c=<uuid>`;**刻意不带**重命名/删除/收藏/归档——那套连着 `Home()` 的乐观更新与回滚,搬过来会撞 useState 增长门禁)。**R5** 星盘五 tab 下划线化 + 参数合表 + 行星表横向滚动;星历日期导航改 `‹ 日期 ›`。**R6** 报告中心卡片网格改行式列表;阅读页加常驻目录。**R7** 生时校正把可信区间从盘面板标题行提成常驻条(窄屏 `.is-compact` 下盘面板是 overlay,现在默认看不到区间),五个 `technique-audit` 折叠块收成两段。**R8** 设置内容区收窄(880px 弹窗里表单铺了 690px)、套餐卡三修饰符收敛成两态。**已解锁**:原挡路的设置单已于 `111b4a84`(BUG-698)合入。**两条不得回退**:BUG-698 的 `@supports (height: 1dvh)` 写法(重复声明回退会被 Lightning CSS 折叠)、BUG-616/617 的报告盘面 grid 实现。默认不占 BUG 号 | **R4–R8 全部已实现并验收合入** | R4:抽出 `AppNavRail`(只读,两个 GET,零写操作)+ `SecondaryShell`,三个次级页并入 app 外壳并删掉各自的 shell/topbar/hero;四个路由渲染标记**完全不变**(`/` `/chart` `/ephemeris` 仍 Static);CSS gzip −0.25%。`/reports/[reportId]` 留给 R6 与目录一起做。两处自身健壮性问题被测试抓到:`usePathname()` 可为 null、`fetch` 可能不存在。差点弄丢 BUG-717 的 eyebrow 文案(已放回)。R8:表单分区收窄到 440px(列表分区不变)、套餐卡三修饰符收敛成互斥的 `is-current` / `is-recommended`,`--highlighted` 删除改为滚动定位;手机端 `order:-1` 改挂 `[data-plan-alias]`(版位不是状态)。测试 3350→3354(净增 4),失败清单与基线逐条一致;`/` 仍 Static;我的干净构建实测 CSS gzip −3 字节。**遗留待产品拍板**:`?plan=` 深链现在完全没有视觉指向,只有滚动位置。R6:报告中心卡片网格改行式列表、阅读页并入外壳并把目录挪到右侧常驻。**任务书 E10 过期**——目录在 `cfcd369d` 就已存在,本轮是挪位置定稿而非从零加。挂外壳带出一个真实打印风险已处理:`.chat-app`/`.chat-panel` 是 `height:100%;overflow:hidden`,裸 `window.print()` 会把九节报告裁成一页,阅读页因此多挂一条只在挂载期生效的 print 样式解锁外壳。「生成中的分节进度」做不了——`REPORT_LIST_COLUMNS` 不返回节数,按 VOICE.md 不许前端编。R7:区间常驻条与盘面折叠收敛。**任务书 E9 也不准确**——对话区顶部早有常驻条 `RectificationTimeline` 且窄屏可见,真正只在盘面标题行的是**代表分钟**;因此没另造第二条,在既有条上补齐代表分钟与已答题数(与盘面同一次 `workingRectificationTime()` 调用)。折叠块实际是 **8 个**不是 5 个。**触发让步顺序第 5 条**:收窄进度未做——服务端无该字段,且 `candidate_range` 会放宽(BUG-572),前端相减会把一次放宽报成收窄,已写进 `BLOCKED.md`。顺带修掉一个**静默失效的旧断言**(`slice(indexOf(A), indexOf(B))` 在 B 改名后变成几乎整份文件,四条 `doesNotMatch` 假通过)|
|
| `TASK-cend-surfaces-claude-alignment-20260916.md` | `PROGRESS-cend-shell-20260916.md`、`PROGRESS-cend-report-20260916.md`、`PROGRESS-cend-rectification-20260916.md`、`PROGRESS-cend-chart-eph-20260916.md` | **次级页面对齐(上一单的续篇,R4→R5/R6,R7、R8 可并行)**:星盘 `/chart`、星历 `/ephemeris`、报告 `/reports` **各是脱离 app 外壳的独立全屏页**,顶部只有一个「返回对话」链接、侧栏整个消失,且三家各写了一套一模一样的 `*-shell`/`*-topbar`/`*-hero` 骨架——与上一单 E5 同根因(营销站 band 结构被套到产品界面)。**R4** 抽只读导航外壳 `AppNavRail`(只用现成的 `GET /api/sessions` + `GET /api/account`,会话行走 `sessionHref` 跳 `/?c=<uuid>`;**刻意不带**重命名/删除/收藏/归档——那套连着 `Home()` 的乐观更新与回滚,搬过来会撞 useState 增长门禁)。**R5** 星盘五 tab 下划线化 + 参数合表 + 行星表横向滚动;星历日期导航改 `‹ 日期 ›`。**R6** 报告中心卡片网格改行式列表;阅读页加常驻目录。**R7** 生时校正把可信区间从盘面板标题行提成常驻条(窄屏 `.is-compact` 下盘面板是 overlay,现在默认看不到区间),五个 `technique-audit` 折叠块收成两段。**R8** 设置内容区收窄(880px 弹窗里表单铺了 690px)、套餐卡三修饰符收敛成两态。**已解锁**:原挡路的设置单已于 `111b4a84`(BUG-698)合入。**两条不得回退**:BUG-698 的 `@supports (height: 1dvh)` 写法(重复声明回退会被 Lightning CSS 折叠)、BUG-616/617 的报告盘面 grid 实现。默认不占 BUG 号 | **R4–R8 全部已实现并验收合入** | R4:抽出 `AppNavRail`(只读,两个 GET,零写操作)+ `SecondaryShell`,三个次级页并入 app 外壳并删掉各自的 shell/topbar/hero;四个路由渲染标记**完全不变**(`/` `/chart` `/ephemeris` 仍 Static);CSS gzip −0.25%。`/reports/[reportId]` 留给 R6 与目录一起做。两处自身健壮性问题被测试抓到:`usePathname()` 可为 null、`fetch` 可能不存在。差点弄丢 BUG-717 的 eyebrow 文案(已放回)。R8:表单分区收窄到 440px(列表分区不变)、套餐卡三修饰符收敛成互斥的 `is-current` / `is-recommended`,`--highlighted` 删除改为滚动定位;手机端 `order:-1` 改挂 `[data-plan-alias]`(版位不是状态)。测试 3350→3354(净增 4),失败清单与基线逐条一致;`/` 仍 Static;我的干净构建实测 CSS gzip −3 字节。**遗留待产品拍板**:`?plan=` 深链现在完全没有视觉指向,只有滚动位置。R6:报告中心卡片网格改行式列表、阅读页并入外壳并把目录挪到右侧常驻。**任务书 E10 过期**——目录在 `cfcd369d` 就已存在,本轮是挪位置定稿而非从零加。挂外壳带出一个真实打印风险已处理:`.chat-app`/`.chat-panel` 是 `height:100%;overflow:hidden`,裸 `window.print()` 会把九节报告裁成一页,阅读页因此多挂一条只在挂载期生效的 print 样式解锁外壳。「生成中的分节进度」做不了——`REPORT_LIST_COLUMNS` 不返回节数,按 VOICE.md 不许前端编。R7:区间常驻条与盘面折叠收敛。**任务书 E9 也不准确**——对话区顶部早有常驻条 `RectificationTimeline` 且窄屏可见,真正只在盘面标题行的是**代表分钟**;因此没另造第二条,在既有条上补齐代表分钟与已答题数(与盘面同一次 `workingRectificationTime()` 调用)。折叠块实际是 **8 个**不是 5 个。**触发让步顺序第 5 条**:收窄进度未做——服务端无该字段,且 `candidate_range` 会放宽(BUG-572),前端相减会把一次放宽报成收窄,已写进 `BLOCKED.md`。顺带修掉一个**静默失效的旧断言**(`slice(indexOf(A), indexOf(B))` 在 B 改名后变成几乎整份文件,四条 `doesNotMatch` 假通过)|
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
# TASK · 天空封面追加:报告封面绑定(方案 A)+ 首次建盘群星汇聚过场(2026-09-28)
|
||||||
|
|
||||||
|
## 基线与依赖
|
||||||
|
|
||||||
|
- 前置任务书:`TASK-birth-sky-cover-20260928.md`。它的实现在本地分支 `codex/birth-sky-cover-20260928`,有三个提交(`d277cbd8` T1–T4+T7、`028aef27` T5 blocked、`14ef18ac` T6 弹窗),**尚未推送、尚未由 Claude 验收**。
|
||||||
|
- 本单**在同一分支上继续**,再追加两个提交;工作树 `.worktrees/birth-sky-cover-20260928`。开工前 `git fetch origin --prune`:
|
||||||
|
- `origin/staging` 若前进了,先 `git rebase origin/staging`(这个分支只有本系列在用);
|
||||||
|
- 基线 SHA 写进 PROGRESS。
|
||||||
|
- 进度记录继续写 `docs/tasks/PROGRESS-birth-sky-cover-20260928.md`,新增「追加单」一节。
|
||||||
|
- 前置的宋体单 `TASK-serif-headings-20260928` 已在 staging(`d670521f`)。
|
||||||
|
|
||||||
|
## 事实
|
||||||
|
|
||||||
|
1. **报告封面被挡住**:报告没有记录生成时用的是哪一套出生资料,所以无法判断封面和报告是否对得上。
|
||||||
|
- `personal_reports` 行、报告文档、job / section / appendix 都没有出生资料指纹;
|
||||||
|
- `request_fingerprint` 不含出生资料;
|
||||||
|
- `calculation_hash` 是引擎结果或 markdown 的哈希。
|
||||||
|
- 这些证据见分支上的 `BLOCKED.md`「TASK-birth-sky-cover T5」。
|
||||||
|
2. **第一次建盘揭幕**目前是一个带「继续」按钮的弹窗(`components/birth-sky/birth-sky-dialog.tsx` 的 reveal 变体,由 `hooks/use-birth-sky-reveal.ts` 与 `lib/birth-sky/reveal.ts` 驱动)。
|
||||||
|
|
||||||
|
## 决策记录(产品 2026-09-28 授权)
|
||||||
|
|
||||||
|
1. **报告封面选方案 A**:
|
||||||
|
- 从现在起,生成报告时写入当时的出生资料指纹;
|
||||||
|
- 只有指纹与当前一致的报告才显示封面;
|
||||||
|
- 旧报告没有这个字段,**永远不显示封面**,不补算、不回填;
|
||||||
|
- 不改数据库结构。
|
||||||
|
2. **第一次建盘的揭幕改成群星汇聚过场**,替换现在的弹窗:
|
||||||
|
- 星星从散开的位置汇聚到出生那一刻的真实位置;
|
||||||
|
- 然后显现文字,文字停留一会儿后整层淡出,进入下一步;
|
||||||
|
- 过场里不放任何按钮。
|
||||||
|
3. **平时打开首页的加载动画不改**。群星过场只在「本人第一次保存出生地」时放一次。
|
||||||
|
|
||||||
|
## 硬红线
|
||||||
|
|
||||||
|
1. 出生资料与指纹**都不下发客户端**,比对在服务端完成。
|
||||||
|
2. 不改表结构、不加迁移。
|
||||||
|
3. `JyotishAPIHandler` 类方法数与 `__new__` 伪造点不增长;`Home()` 的 `useState` / `useRef` 数不增长。
|
||||||
|
4. 过场**不得变成等待**:
|
||||||
|
- 天空数据必须先就绪才开始放;
|
||||||
|
- 沿用现有的 3 秒预算,超时就静默跳过;
|
||||||
|
- 不加 spinner 或骨架(DESIGN §9)。
|
||||||
|
5. 汇聚完成的最后一帧必须与 `drawBirthSky` 导出的封面**完全一致**。复用同一个绘制函数,只对位置做插值。
|
||||||
|
6. 不新增 npm 依赖。
|
||||||
|
7. 移动或改写组件前,先在 `frontend/tests/` 和 `tests/` 里 grep 按源码文本断言的合同测试(AGENTS §7.8);任何改动的断言都写「原值 / 新值 / 原因」三栏。
|
||||||
|
8. 隐私:只用样稿里的虚构资料(1994-05-18 07:40 UTC+8,30.27N 120.15E)。
|
||||||
|
|
||||||
|
## 任务分解
|
||||||
|
|
||||||
|
### F1 · 报告写入出生资料指纹(方案 A)
|
||||||
|
|
||||||
|
- 普通报告、长报告,每一条生成路径都在报告文档的 `subject` 里写入可选字段 `birthFingerprint`,取值为 `resolveServerOwnedChartBirth(...).fingerprint`。
|
||||||
|
- 先核实它与星盘页下发的 `profileFingerprint` 是**同一种算法**;如果不是,两边统一用同一种,并在 PROGRESS 里说明。
|
||||||
|
- v2 evidence bundle / 报告文档的 schema 加这个可选字段,旧报告照常能读。
|
||||||
|
|
||||||
|
**验收**:每条生成路径各有一条测试,断言写入了指纹;缺这个字段的旧文档照常能解析。
|
||||||
|
|
||||||
|
### F2 · 服务端比对,下发封面对象
|
||||||
|
|
||||||
|
- 报告视图(`reportView`,在 `lib/personal-report-route-core.ts`)新增 `coverSubject` 字段:
|
||||||
|
- 报告存的指纹与该人物当前的指纹一致时,取值为 subject id(`chart_profile_id` 为 null 时取 `"self"`);
|
||||||
|
- 其余一律为 `null`,包括不一致、缺字段、不是本人的报告、人物已删除。
|
||||||
|
- 不下发指纹原文。
|
||||||
|
|
||||||
|
**验收**:一致、不一致、缺字段、非本人四种情况各一条测试;序列化后的响应里不含指纹与出生资料。
|
||||||
|
|
||||||
|
### F3 · 报告封面(原任务书 T5)
|
||||||
|
|
||||||
|
- 屏幕上:`coverSubject` 不为 null 时,在正文最上方放封面块。
|
||||||
|
- 用 `night` palette,宽度随正文列,比例 3:4;
|
||||||
|
- 不放按钮;
|
||||||
|
- 正文出现之后才取数;取数失败就不显示封面,不留占位,不加等待态。
|
||||||
|
- 打印 / PDF:
|
||||||
|
- 封面改用 `paper` palette;
|
||||||
|
- 封面独占 A4 第一页(`break-after: page`);
|
||||||
|
- 不新增打印入口。
|
||||||
|
- 把分支上 `BLOCKED.md` 的 T5 条目划掉(不删),并注明「→ 已解除:产品 2026-09-28 选 A」。
|
||||||
|
|
||||||
|
**验收**:
|
||||||
|
- 指纹一致时有封面;不一致或缺字段时无封面;取数失败时正文不受影响;
|
||||||
|
- 打印样式断言 `paper` palette 与分页。
|
||||||
|
|
||||||
|
### F4 · 首次建盘群星汇聚过场(替换 T6 弹窗)
|
||||||
|
|
||||||
|
- **触发条件不变**:只在首页 onboarding 里**本人**的出生地保存成功后触发一次。以下情况都不触发:新建家人档案、修改资料、平时打开首页。
|
||||||
|
- **时序**(总长约 3 秒):
|
||||||
|
1. 汇聚约 1.5 秒:可见的恒星与行星从随机散开的位置出发,ease-out 汇聚到真实投影位置。散开位置由固定种子生成,同一张盘每次一样;地平线圆、方位字、高度圈同步淡入。
|
||||||
|
2. 显现文字约 1 秒:主句与事实句淡入,并停留。
|
||||||
|
3. 淡出约 0.5 秒:整层淡出,露出**原本的下一步**(问候 / 首页,或者出生时间校正引导),不改变下一步是什么。
|
||||||
|
- **全屏覆盖层,不放按钮**:
|
||||||
|
- 点击、触摸或按 Esc,立刻结束并进入下一步;
|
||||||
|
- 系统开了 `prefers-reduced-motion` 时,不做汇聚,只整体淡入、停留、淡出。
|
||||||
|
- **实现要求**:
|
||||||
|
- 画布用 `requestAnimationFrame`,按视口尺寸与 DPR 绘制;
|
||||||
|
- 组件卸载时取消动画;
|
||||||
|
- 插值写成纯函数:t=0 是散开位置,t=1 是真实位置。
|
||||||
|
- **结束后的提示**:在首页轻提示一次「这片天空在星盘页可以保存。」。复用已有的 sonner Toaster,不写新组件;这句收进 VOICE.md。
|
||||||
|
- 删除不再使用的弹窗 reveal 变体(「继续」按钮、`is-reveal` 样式)。星盘页那个「那一刻的天空」弹窗不动。
|
||||||
|
|
||||||
|
**验收**:
|
||||||
|
- 插值纯函数有测试:t=0 等于种子决定的散开位置,t=1 与真实位置逐点相等;
|
||||||
|
- 点击或 Esc 能立即结束;reduced-motion 走淡入淡出;
|
||||||
|
- 触发条件与原 T6 相同(本人保存出生地才触发,家人档案、`saveProfile`、`chart-profile-form` 都不触发);3 秒内数据没到就不放;
|
||||||
|
- 提示只出现一次;
|
||||||
|
- 用无头 Chrome 从 golden 夹具取 t=0、0.5、1.0 与停留四帧 PNG,放进 scratchpad,路径写进 PROGRESS。
|
||||||
|
|
||||||
|
### F5 · 文档
|
||||||
|
|
||||||
|
- `frontend/DESIGN.md` §17:
|
||||||
|
- 报告封面一段,写屏幕与打印的做法;
|
||||||
|
- 群星过场一段,写时序、跳过、减少动态效果、「平时的首页加载动画不改」。
|
||||||
|
- `frontend/docs/VOICE.md`:收录提示句。
|
||||||
|
- `CHANGELOG.md`:追加一条。
|
||||||
|
- `docs/testing/birth-sky-cover-checklist.md`,追加以下真机条目:
|
||||||
|
- 新账号首次建盘,完整看一遍过场;
|
||||||
|
- 过场中点一下能跳过;
|
||||||
|
- 手机开「减少动态效果」后只淡入淡出;
|
||||||
|
- 断网或慢网时过场不出现,也不卡住;
|
||||||
|
- 新生成的报告有封面、打印 PDF 第一页是封面;
|
||||||
|
- 旧报告没有封面;
|
||||||
|
- 改过出生时间后,改之前生成的报告没有封面。
|
||||||
|
|
||||||
|
## 验证(两个提交都完成后)
|
||||||
|
|
||||||
|
- `tsc --noEmit` 0 错;`npm run lint` 0 error。
|
||||||
|
- `npm test` 全量:
|
||||||
|
- 与分支 PROGRESS 记录的基线对比**测试名清单**,不得有测试名消失(被删除的弹窗测试逐条列出原因);
|
||||||
|
- 失败清单与基线逐条相同。
|
||||||
|
- Python:
|
||||||
|
- `python3 -m pytest tests/test_birth_sky.py tests/test_api_server_growth_contract.py`;
|
||||||
|
- `python3 scripts/run_quality_gate.py --profile quick`。
|
||||||
|
- `rm -rf .next && next build`:`/` 仍是 `○ Static`;首屏 JS / CSS gzip 与基线 651,590 / 66,346 对比,变化在 ±2% 内。
|
||||||
|
- 隐私:`python3 -m pytest tests/test_repo_privacy_markers.py -q`。
|
||||||
|
|
||||||
|
## 让步顺序
|
||||||
|
|
||||||
|
1. 结束后的提示可以砍。
|
||||||
|
2. 过场里地平线、方位字的淡入可以简化成与星点同时出现。
|
||||||
|
3. F1~F3 的方案 A 绑定、「最后一帧与导出封面一致」、「不等待」**不可让步**。
|
||||||
|
|
||||||
|
## 交付
|
||||||
|
|
||||||
|
- 在同一分支上再加两个提交:F1–F3 + 对应文档;F4 + 对应文档。
|
||||||
|
- **不推送**,由 Claude 独立验收后把整个分支(五个提交)一起快进推上 staging。
|
||||||
|
|
||||||
|
## BUG 编号
|
||||||
|
|
||||||
|
这是新功能,不开 BUG。实现中若发现既有缺陷,从 `docs/BUG_HISTORY.md` 开工时的最大号 +1 起编(写作时是 BUG-1079)。
|
||||||
Reference in New Issue
Block a user