Commit Graph
2329 Commits
Author SHA1 Message Date
Jesse_ChenandClaude Fable 5.1 548b032d08 docs(tasks): 年月焦点单验收通过;D9 探针单验收未通过(自建探针未进持久化 state),修复单 BUG-915/916
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 23:59:24 +00:00
jesse-ux 8d7dfbf01e fix(rectification): 自建探针注入不得把 GET 目录探针写进 inference_state
Independent Staging Quality Gate / validate (push) Successful in 9m57s
Independent Staging Quality Gate / publish (push) Successful in 21m4s
2026-09-17 01:24:13 +08:00
jesse-ux 227a75719b fix(rectification): D9 判别题不再借 D24 探针,性格描述一列一句
Independent Staging Quality Gate / validate (push) Failing after 13m34s
Independent Staging Quality Gate / publish (push) Skipped
2026-09-17 01:06:17 +08:00
Jesse_ChenandClaude Fable 5.1 daacaab9e9 docs(tasks): BUG-912 定为 BUG-375 复发:D9 风格题借 D24 对照探针,错分 + 无卡(P0)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 16:39:18 +00:00
Jesse_ChenandClaude Fable 5.1 2837cd3034 docs(tasks): 感情判别题落库无卡 + 平局直接出卡 + 卡头相反两极任务书(BUG-912~914)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 16:30:52 +00:00
jesse-ux 6aabbe386f feat(rectification): 删掉年月录入卡,年月阶段打字回答且不被追问覆盖
Independent Staging Quality Gate / validate (push) Successful in 10m1s
Independent Staging Quality Gate / publish (push) Successful in 36m54s
2026-09-16 23:22:32 +08:00
Jesse_ChenandClaude Fable 5.1 abcfdac523 docs(tasks): 年月焦点单追加产品决策:删掉领域/年月录入卡,年月阶段改打字回答
推翻 precision-gate-guided-collect 单 T3 与 SKILL.md:84 的「不得邀请自由打字」,BUG-750 失去对象。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 14:41:00 +00:00
Jesse_ChenandClaude Fable 5.1 3f4a303a8f docs(tasks): 年月焦点单补充卡片消失链路与失败轮断言
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 14:38:38 +00:00
Jesse_ChenandClaude Fable 5.1 453b6c017d docs(tasks): 年月阶段焦点被模型追问覆盖任务书(BUG-908~911)
追问句下挂录入卡 = set-focus 同号覆盖 event_date_entry 焦点题干;事件入账后年月焦点没关;答短句撞步骤上限;persisted 问题块无缩进。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 14:32:30 +00:00
Jesse_ChenandClaude Fable 5.1 37f77fe8b3 docs(tasks): 控制台噪音清理任务书(SVG height=auto、consult/status 无活动任务 404 → 204)
三条控制台红字定性:SVG 属性非法是我方缺陷(BUG-906)、无参 status 404 是设计噪音(BUG-907)、reportAllChanges 是扩展注入脚本不处理。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 14:15:18 +00:00
jesse-ux 05cf20fb83 fix(ci): capability audit 丢掉 Next.js 路由组,公开 URL 不变
Independent Staging Quality Gate / validate (push) Successful in 14m41s
Independent Staging Quality Gate / publish (push) Successful in 40m10s
Gitea run 2697 唯一失败:侧栏把 /chart /ephemeris /reports 移进 app/(secondary)/ 后,_scan_app_routes 把文件夹名写进 app_routes。扫描时丢掉括号段。BUG-753。
2026-09-16 21:09:24 +08:00
Jesse_ChenandClaude Fable 5.1 6a843ac6e1 docs(tasks): 精度门槛修复单验收通过,状态板改已合入
Independent Staging Quality Gate / validate (push) Failing after 6m21s
Independent Staging Quality Gate / publish (push) Skipped
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 12:22:13 +00:00
Jesse_ChenandClaude Fable 5.1 dc732825d8 fix(rectification): 有题就接着问,题问完才出卡;引导窗口不再硬贴领域
出卡时机只看题源有没有空:撤回「门槛达标就短路采集线」的写法,同时
按 D2 保住「题源全空就按现行规则出卡」——门槛只在还有题可问时挡住
出卡,precision_gate_met 改成只上报(新挂在决策与公开投影上),不再
单独决定时机。引导窗口题在无领域轨道上改问开放题,一个时间窗只问一
次;录入卡提交的是「YYYY 年 M 月,<领域>方面有一件事」,不再是题干
的三选一列表。记忆化 golden 只补一个新键并冻结墙钟。离线回放改成注
入真值方向的边界事件,另跑一组反方向对照。Skill 10.0.28。

BUG-747~752

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 12:16:55 +00:00
Jesse_ChenandClaude Fable 5.1 a396bbe076 docs(tasks): 侧栏统一验收通过,状态板改已验收
Independent Staging Quality Gate / validate (push) Failing after 6m36s
Independent Staging Quality Gate / publish (push) Skipped
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 11:47:21 +00:00
Jesse_ChenandClaude Fable 5.1 22edabbcd3 docs(tasks): 侧栏统一进度记录、BUG-744~746、真机清单与 CHANGELOG
`PROGRESS-sidebar-unify-20260916.md` 记基线与改后的 tsc / lint / 测试总数 /
失败清单 diff / 五个路由标记 / gzip,逐条列改过的既有断言、触发的让步顺序
(T5 第 1 条)、次级页体积增加的原因,以及无 Chrome 无登录态的环境缺口。
`docs/testing/sidebar-unify-20260916.md` 是七组可照做的真机条目。
状态板本单一行改「待验收」,执行分支 `codex/sidebar-unify-20260916`。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 11:23:43 +00:00
Jesse_ChenandClaude Fable 5.1 fb77c86585 test(ui): 侧栏只读模式、共享外壳与列表缓存的合同回归
新增 8 条:`sidebar-data-cache.test.ts`(命中不重拉 / 过期重拉一次 / 写操作后
拿到新标题并逐条锁住五个写路径 / 双账户不串 / 只存内存 / 401 清空)、
`sidebar-state.test.ts` +2(收起后重挂仍收起,含三种降级;移动端不读不写)、
`sidebar-contract.test.ts` +1(只读模式只少三样)、`chart-page-view.test.tsx` +1
(`(secondary)` layout 恰好挂一份只读侧栏,数据 hook 无写方法)。

改写 9 处既有断言,每处带「原值 / 新值 / 原因」三栏注释,均未削弱:
`window.location.assign(path)` → `<SidebarMenuLink href>` 并追加反向断言;
`onOpenReports` / `useRouter` 改成 doesNotMatch;`SecondaryShell` → `SecondaryHeader`;
导航顺序改在 `NAV_PAGES` 常量里量;两个 render 辅助改为裹 `SidebarProvider`
(provider 上移到 layout);三处源码路径跟随路由组移动。

测试总数 3391 → 3399,失败清单与基线逐条一致(47 条均为无 Docker 的既有缺口)。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 11:23:11 +00:00
Jesse_ChenandClaude Fable 5.1 d9d347236f refactor(ui): 侧栏统一成一个组件,次级页共享外壳,跳转不再整页刷新
BUG-744 / BUG-745 / BUG-746,任务书 TASK-sidebar-unify-20260916。

T1 侧栏只剩一个组件。`AppSidebar` 收编次级页那份另写的侧栏:会话操作与
账户菜单收进可选的 `controls`,不传就渲染只读模式。只读行仍是同一个
`SidebarSessionRow`、同一套 `.session-row > .session-main` 标记,只是
`.session-main` 是 `<Link>`、不渲染菜单按钮,并用 `data-readonly="true"`
去掉那一列从不使用的 44px 空位;页脚是同一个 56px `.profile-trigger`,
渲染成去 `/` 的链接。只读模式只少菜单按钮、chevron、账户菜单三样。
`app-nav-rail.tsx`、`use-nav-rail.ts` 与 `.nav-rail-*` 两段 CSS 删除。

T2 四个次级路由移进 `app/(secondary)/` 路由组,`layout.tsx` 承载
`SidebarProvider + AppSidebar(只读) + SidebarInset`。`SecondaryShell` 拆剩
46px 顶栏并改名 `SecondaryHeader`,14 处调用同步。路由组不进 URL,四个
地址与四个渲染标记均未变。

T3 `sidebar-data-cache.ts`:模块级、按账户 id 键、60 秒的内存缓存,同步读
再后台刷新,不落 localStorage。`use-session-management.ts` 的新建 / 重命名 /
删除 / 归档 / 收藏成功后失效,401 清空。

T4 三个页面项改 `<SidebarMenuLink href=…>` 客户端跳转,`persistLoginSessionReturn()`
保留在 `onClick` 里,`/login` 仍是硬跳转。顺带删掉从未被调用的死 prop
`onOpenReports`;它删掉后 `page.tsx` 的 `router` 再无消费者,`useConsultationRun`
里同样解构成 `_router` 的死参数一并删。

T5 折叠状态存 localStorage 的 `sidebar_state`(不用 cookie:`/`、`/chart`、
`/ephemeris` 都是 Static,服务端读 cookie 会让三条路由掉出静态渲染)。移动端
抽屉不记。整页加载首帧仍可能闪一下,属让步顺序第 1 条,写在 BUG-746 与真机清单。

`Home()` 的 useState 36 / useRef 37 均未增长,`page.tsx` 净删 1 行。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 11:23:11 +00:00
Jesse_ChenandClaude Fable 5.1 302ff08504 docs(tasks): 修复单 D6 拍板——门槛是必要条件,采集线问完再出卡
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 11:00:28 +00:00
Jesse_ChenandClaude Fable 5.1 062af26d99 docs(tasks): 侧栏统一成一个组件 + 次级页共享外壳 + 跳转不整页刷新任务书
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 10:49:36 +00:00
Jesse_ChenandClaude Fable 5.1 8055792e56 docs(tasks): 精度门槛+引导补经历验收:未通过,修复单 F1~F7
cfb41daf:tsc/lint/Static/gzip 通过,D1~D5 单测通过;npm test 新增 16 红、
memoization golden 因 receipt 新键红(门禁级,staging 仍部署 317e9f18);
引导窗口领域轮询、回放未按真值注入、录入卡走模型轮。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 10:49:21 +00:00
jesse-ux cfb41daf3d feat(rectification): 出卡加精度门槛,补经历改成系统点名
Independent Staging Quality Gate / validate (push) Failing after 6m28s
Independent Staging Quality Gate / publish (push) Skipped
宽度超过 10 分钟或头名并列时不再出交付卡,改为按大运边界逐条问、
用类型芯片和年/月选择器录入。跳过的线换问法再问一次;答「这类事
都没有过」的不再问。用户说「没有了」仍立刻给目前范围。Skill 10.0.27。

BUG-740~743
2026-09-16 18:35:27 +08:00
Jesse_ChenandClaude Opus 5 317e9f1886 fix(rectification): 顶栏被 focus 滚出视野——面板改 clip,面板内 focus 一律 preventScroll
Independent Staging Quality Gate / validate (push) Successful in 10m24s
Independent Staging Quality Gate / publish (push) Successful in 19m9s
产品实测:生时校正答了三题后 46px 顶栏消失。devtools 取证——栅格是对的
(rows "46px 1297px"、panel y=0),但 header 自己的 rect 在 **y=-88**:
面板被程序化滚动了 88px。

根因:`overflow: hidden` 仍然是滚动容器,它只是去掉了滚动条。
BirthTimeChoiceQuestion 在每答完一题后 focus 新题的第一个选项,浏览器
为把它带进视野会滚动所有可滚动祖先,`.chat-panel` 就是其中之一——
而用户没有滚动条可以滚回来,顶栏于是永久消失。

两处都修:
- 病因:面板内 7 处程序化 focus 一律加 { preventScroll: true }。
  消息区有自己的 useConversationScrollAnchor,本来就不需要浏览器代劳。
  账户弹窗的 closeButton / returnTarget 不在此列——那是对话框焦点管理。
  同一教训 use-billing-panel.ts 已经吃过一次(那里早写了 preventScroll)。
- 结构:.chat-panel 与 .chat-app 从 overflow:hidden 改成 overflow:clip。
  clip 根本不创建滚动容器,此后任何 focus / scrollIntoView 都无法位移它。

新增 tests/chat-panel-scroll-guard.test.ts:锁住两个容器必须是 clip、
面板内不得有裸 focus(),并遍历 rectification/birth-time/chat- 全部组件,
新组件再写裸 focus 会直接打红。

测试 3372(+3),fail 仍 31 且与基线逐条一致;四个路由标记不变。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 08:56:07 +00:00
Jesse_ChenandClaude Fable 5.1 20435a1916 docs(tasks): 校正出卡加精度门槛 + 引导式补经历任务书
产品 2026-09-16 拍板:宽度 ≤10 分钟且不并列才出卡;用户说没有了仍按现行规则出卡;
门槛未达改为系统点名逐题问 + 年/月选择器录入,删自由文本邀请;跳过的线换问法再问一次;
时间点题答没发生不关领域、存在性题问整个领域、七条线一张表不按领域写死。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 08:50:35 +00:00
Jesse_ChenandClaude Opus 5 071317f7ee fix(ui): 加回 agent 头像,范围带调深到看得见
Independent Staging Quality Gate / validate (push) Successful in 10m34s
Independent Staging Quality Gate / publish (push) Successful in 3m48s
产品真机走查:

1. agent 头像加回来(推翻 R3 的 D7)。R3 删它的理由是「一屏几十条时是重复度
   最高的元素」,但没有它助手那一轮就没有视觉归属——生时校正面尤其明显,
   旁白、题干、选项全是平铺文字。--assistant-content-inset 随之回到
   「32px 头像 + 间隙」,追问 chip 与运行时间轴重新对齐正文。

2. 时间范围带用的是 --color-action-soft,那是给文字底色用的浅色调,
   画在画布上几乎看不见——而它是整条轴上唯一必须一眼看到的标记。
   改成 color-mix(--color-action-strong 32%, --color-canvas)。

测试 3369,fail 仍 31 且与基线逐条一致;四个路由标记不变。

未修:生时校正面顶部溢出。工作区在栅格里、没有脱离定位,
chat-panel.is-rectification 仍是 46px + 1fr 两行,从代码上看不出
46px 顶栏为什么会消失,待产品确认截图是否裁切。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 08:23:50 +00:00
Jesse_ChenandClaude Opus 5 524015cfc1 fix(ui): 回答不再折叠,次级页侧栏改真链接并补回头像
Independent Staging Quality Gate / validate (push) Canceled after 8m15s
Independent Staging Quality Gate / publish (push) Canceled after 0s
真机走查第二批:

1. 普通对话的回答,首个 H2 之后的全部内容(带推理的那一半)被
   <details class="answer-detail">「完整分析」默认收起——用户「输出根本
   看不到」。折叠控件与组件文件一并删除,报告层直接渲染进正文。
   技法审计表保留自己的折叠:那是给人核对的证据,不是回复正文。
   product-voice.ts 同步改掉「UI 会折叠」那句,否则模型继续按折叠写。

2. 次级页侧栏点不了头像、头像样式与首页不一致。根因是 R4 的取舍:
   SecondaryShell 共用,但里面挂的是新写的 AppNavRail 而不是 AppSidebar。
   现在 use-nav-rail 也取 avatar,渲染同一个 UserAvatar;页脚改成真链接,
   指向 / —— 账户菜单连着设置弹窗栈,留在那儿,不在这里复制第二份。

3. 「新建对话」整页刷新。原来走 location.assign,现在是 next/link。
   /login 保留硬跳转:它跨鉴权边界,要先存返回目标。

   注意:第一版我改成了 useRouter(),它在 app-router 上下文外会抛
   「invariant expected app router to be mounted」,打红 12 条渲染测试。
   改用 <Link>,静态渲染也安全;折叠态 tooltip 换成原生 title。

测试 3369,fail 仍 31 且与基线逐条一致;四个路由标记不变;
CSS gzip 40,002。

未修:截图里 `## 适合推进 / 需要避开` 被当字面量渲染,是模型输出里
那两个 H2 前面没有换行,属生成层,另记。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 08:15:25 +00:00
Jesse_ChenandClaude Opus 5 49bc4a8ba1 fix(ui): 空态居中、大运页去重、星历加日历、顶栏动作按 46px 收
真机走查四条:

1. 空态不居中——问候+输入框+pill 整组贴在屏幕底部。加一个可压缩的
   配重行,让 chat-panel 变成 46px/1fr/auto/1fr,两个 1fr 抵消,
   整组居中;composer 仍是同一个 DOM 位置,不重挂载。

2. 大运页「Vimshottari」出现两遍、「当前 当前 Chara 段…」两个当前。
   两条轨道的 method 与自身 title 同字符串,method 只在不同时才渲染;
   兜底文案自带的「当前」去掉——它同时被参数表当「当前大运」的值用,
   不能把前缀塞进数据。

3. 星历只能一天一天点。日期改成可点的日历弹层,复用出生日期字段
   同一套 Calendar+Popover。新增 parseEphemerisDate/toEphemerisDate,
   都走本地日历字段、不经 UTC,避免跨时区差一天。

4. 「生成完整报告」在 46px 顶栏里是 44px 实心大按钮,像个横幅 CTA。
   顶栏作用域内动作统一 32px + outline,触摸目标靠 ::after 扩热区补。

测试 3372,fail 仍 31 且与基线逐条一致;四个路由标记不变;
CSS gzip 40,080。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 08:06:12 +00:00
jesse-ux d548bd0554 docs(tasks): 回填 BUG-739 门禁 SHA 与 staging 部署证据 2026-09-16 15:52:17 +08:00
jesse-ux 7061d0d1f3 fix(test): 容量合同按 fixture.psql 的 f: 字母表断言(BUG-739)
Independent Staging Quality Gate / validate (push) Successful in 11m47s
Independent Staging Quality Gate / publish (push) Successful in 13m18s
Independent Staging Quality Gate run 2683 唯一失败:
database-consultation-session-capacity 期望 false:session_missing,
实际是 f:session_missing。夹具把 boolean::text 的 false 规范成 psql -A 的 f。
五处期望值对齐既有合同;无 Docker 源码合同锁住 false→f。
2026-09-16 15:22:55 +08:00
Jesse_ChenandClaude Opus 5 8cb1877eb3 docs(agents): 禁止 git stash —— 栈是全仓共用的,并行会话会互相弹走
2026-09-16 一轮四个并行 agent 里有三个踩中:stash 栈是一个全仓库的 ref,
不按 worktree 隔离。R5 弹走了 R6 的、R6 弹走了 R7 的、R7 弹走了 R5 的,
三方各自做了一次 git fsck --unreachable + git stash store 的救援才没丢。

§3 新增第 5 条:禁止 git stash,给出三条替代做法(wip commit 后
reset --soft / 一次性 worktree / diff 存 patch),以及误弹后的救援步骤。
原第 5 条顺延为第 6 条。

同时把状态板标为 R4–R8 全部合入。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 06:51:37 +00:00
Jesse_ChenandClaude Opus 5 1e3570b462 feat(ui): 星盘 tab 下划线化、参数收成键值表,星历日期条改 ‹ 日期 ›
Independent Staging Quality Gate / validate (push) Failing after 9m13s
Independent Staging Quality Gate / publish (push) Skipped
星盘页(T5.1):
- 五个体系 tab 从五枚描边药丸改成顶栏下方一条下划线式 tab 行,
  flex-wrap: nowrap + 容器自身横滚,375px 下仍是一行;底线画在滚动
  容器的 border 上,不随内容滚走。眉标(BUG-717 的成本与速度承诺)
  原文保留,位置从 tab 行上方移到下方,让 tab 行直接接住 46px 顶栏。
- 分盘 chips 保留但降一级:去描边去卡面、caption 字号、三级色,
  当前项只留浅底。它是一个 tab 内部的筛选器,不是第二层导航。
- 参数从「中宫叠卡(手机两行/桌面六行)+ 盘下重复卡 + media query
  三选一」收成一张八行键值表。同一组事实原本画三遍,改一处要改三处。
  .chart-page-center-card / -compact / -extra / .chart-page-params-below
  / .chart-page-boundary-desktop 五个类连同 767/768 开关块一并删除。
  view.vedic.boundary 那句准确性边界句原文未动,紧跟在表下方,且
  DOM 里从出现两次变成一次。
- 三张行星表(印度宿度 / 西洋相位 / 七政十一曜)全部包上横向滚动
  容器,wrap 补 min-width: 0 —— 少了它 grid item 按内容定宽,表格会
  撑宽页面而不是在自己盒子里滚动。原先只有第一张有 wrap。

星历页(T5.2):
- 日期导航从三个并排等宽按钮改成居中的 ‹ 日期 ›:日期是主语,两枚
  44px 箭头是把手。箭头字形 aria-hidden,可访问名仍是「前一天」
  「后一天」,读屏不丢方向。
- 「今天」只在非今日时以文字按钮出现在日期下方;在今日时整个不渲染,
  而不是渲染成禁用按钮——灰掉的按钮仍要被读、仍要被 Tab 跳过。
- 三段统一成同一套卡片:框从内容上移到段落,.ephemeris-panchanga 的
  dl 网格原样保留。收尾句原文不变,但从底部第四张卡降为页尾一行小字。

两条既有断言改动,测试文件内就地写了原值/新值/原因,进度记录成表:
参数断点开关的三条断言换成「参数只有一张键值表且那五个类不再有规则」
(更强,且避开了原写法 indexOf 未命中后静默锚错断点块的陷阱);
「今天」在场的单状态断言拆成今日/非今日两状态并加断不出现 disabled。
测试总数 3350 → 3352,失败清单与基线逐条一致(31 条无 Docker 缺口)。

tsc 0 错;lint 0 error / 118 warning(与基线同数);/ /chart /ephemeris
渲染标记均保持 ○ Static,/reports 仍 ƒ;主 CSS gzip 36,745 → 36,788
(+0.12%)。行星表 375px 横滚、tab 行横滚、读屏播报无真机验收,已在
进度记录里如实写成环境缺口。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 06:47:50 +00:00
Jesse_ChenandClaude Opus 5 ca0204984b feat(rectification): 区间常驻条补代表分钟与已答题数,盘面五段折叠收成两段
Independent Staging Quality Gate / validate (push) Canceled after 3m14s
Independent Staging Quality Gate / publish (push) Canceled after 0s
R7 / 决策 D10。任务书 docs/tasks/TASK-cend-surfaces-claude-alignment-20260916.md。

T7.1 常驻条。任务书 E9 说区间只在盘面标题行,实际读代码:对话区顶部
已有常驻条 RectificationTimeline 且已显示区间与宽度,窄屏 .is-compact 下
也可见。真正只存在于 .rectification-board__clock 的是代表分钟——窄屏盘面
是默认关闭的 overlay,代表分钟就此看不见。所以没有另造第二条(会撞固定条
高这条正确性约束),而是在既有条上补齐缺的两项:

  05:07–05:09 · 3 分钟 · 代表分钟 05:08 · 已答 6 题

代表分钟与盘面标题行是同一次 workingRectificationTime(result) 调用,一个
值两处用,不是两条推导路径。已答题数逐字读服务端的
inference_state.answered_probe_count,投影没给就整项不显示,不补「已答 0 题」。
条上不写确认,边界句仍只在交付/采用旁白里出现一次。读数只增宽不增高:条高
在滚动容器外,变高会让贴底读者的内容无声滑出视野。

收窄进度未做,触发让步顺序第 5 条。没有这个字段(服务端只把这句话拼进旁白
正文),且前端自己减会算错——candidate_range 是当前窗口且会放宽(BUG-572),
拿它当「最初」相减会把一次放宽报成一次收窄。缺口与解除条件写进 BLOCKED.md。

T7.2 盘面折叠。实际有 8 个 details(任务书记的五处漏了交界节奏、错标了两块),
按内容归成「候选分钟」(换升时刻 + 次级候选)与「参数与口径」(宫位表、确认门、
本轮技法、两段本命上升、经历与大运对照含双轨一致性、交界节奏)。每块保留原有
渲染条件,engineMeaningToDisplayCopy() 仍是 5 处,逐分钟行的 is-changed /
当前时间 一字未改。共享组件 technique-audit-disclosure.tsx 未动。

顺带修掉一个静默失效的断言:rectification-agentic-entry 用
board.slice(indexOf(A), indexOf(B)),B 改名后 indexOf 返回 -1,slice(i, -1)
会悄悄退化成几乎整份文件,底下四条 doesNotMatch 照样绿。已换成带越界断言的
sliceBetween()。两处改动的断言都在测试里写了原值/新值/原因。

tsc 0 错;lint 0 error / 118 warning(同基线);npm test 3350 → 3360,失败
仍是 31 条无 Docker 用例且与基线逐条一致;next build exit 0,/ 仍 ○ Static;
产物 CSS gzip 39,017 → 38,973 B(−0.11%)。

窄屏 .is-compact 下常驻条的实际可见性无 Chrome 无法验证,已按任务书写成环境
缺口,未标通过;CSS 上已确认无任何规则在该状态下隐藏该条,并写成测试断言。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 06:44:49 +00:00
Jesse_ChenandClaude Opus 5 a1a78c7ebc feat(ui): 报告中心改行式列表,阅读页并入外壳并把目录挪到右侧常驻
Independent Staging Quality Gate / validate (push) Canceled after 3m14s
Independent Staging Quality Gate / publish (push) Canceled after 0s
报告中心原来是卡片方阵,状态只靠三块底色区分;报告一多,扫读成本
按卡片数线性涨。现在一列一行:带色点的状态 chip、标题、创建时间 ·
深度 · 主题,操作靠右。失败原因从右边一小块挪进行内,能完整读到。

chip 里原来的 StatusIcon(generating 转圈、ready 打勾、failed 警告)
换成 5px 色点——原型如此,且列表是轮询不是演出。失败行不加「重新
生成」,顶栏已经有唯一的生成入口。

行内小字只写接口真给的东西。GET /api/reports 不返回节数和盘数,所以
不写「9 节 · 22 张盘」(VOICE.md 第 2 条),原型图上那行是 mock。

/reports/[reportId] 是最后一个脱离外壳的全屏路由,九个 phase 全部并进
SecondaryShell,根节点从 <main> 改成 <div>(外壳自己就是 main)。

任务书 E10「没有目录」已过期:目录在 cfcd369d 就存在。本轮把它从左栏
挪到正文右侧并定稿视觉,位置用 grid-column 显式指定而不是靠 DOM 次序,
这样窄屏抽屉仍能排在源码最前面,不会掉到全文末尾。860px 以下常驻栏
消失、折叠抽屉保留——删掉抽屉等于窄屏彻底失去章节定位。

挂外壳带出一个真实风险:window.print() 打的是整篇,而 .chat-app /
.chat-panel 是 height:100%;overflow:hidden,会把九节报告裁成一页。阅读
页因此多挂一条 media="print" 样式,把外壳既隐藏又解锁。放组件里而不是
globals.css:它只在阅读页挂载期存在,对话页的打印不受影响,也不用
:has() 去够祖先,更不越界到并行轮次的 CSS 区段。

纸面三个 token 一个没动,--report-accent 仍是 #85432f;目录栏用应用
调色板,因为它是 chrome 不是纸。report-chart-grid-rehype.ts 一行未动,
新增断言守住它仍然接线(BUG-616/617)。

tsc 0 错;lint 0 error / 118 warning(未增);3350→3355 条,0 条既有
断言被改,31 条无 Docker 失败与基线逐条一致;四个路由渲染标记不变,
/ 首屏 gzip −0.58%。

「20 张盘以上不重叠、滚动不卡」与「挂外壳后的打印真实输出」无真机做
不了,已写成环境缺口,清单在 docs/testing/cend-report-20260916.md。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 06:41:39 +00:00
Jesse_ChenandClaude Opus 5 c3bcddb652 feat(billing): ?plan= 深链用一句文案指向目标卡,而不是第三层描边
Independent Staging Quality Gate / validate (push) Canceled after 8m19s
Independent Staging Quality Gate / publish (push) Canceled after 0s
D13 把 URL 高亮改成纯滚动定位后留下一个空档:桌面上三张套餐卡本来就都在
视口内,滚动等于什么都没指。付费转化路径上,用户从「开通年度会员」的链接
进来,看不到任何东西指向那张卡。

产品在「加一行文案 / 维持现状 / 把描边加回来」里选了第一个。

用卡片自己的套餐名,不用序数——手机端 [data-plan-alias="monthly"] 带
order:-1,序数会指错。新增断言锁住这两点(必须有 note、不得出现序数写法)。

测试 3354 不变,fail 仍 31 且与基线逐条一致;/ 仍 Static;
干净构建 CSS gzip 39,724→39,733。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 06:35:52 +00:00
Jesse_ChenandClaude Opus 5 5edc519db9 docs(tasks): 状态板标记 R8 已实现,R5/R6/R7 进行中
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 06:29:51 +00:00
Jesse_ChenandClaude Opus 5 34628ecb67 feat(settings): 表单分区收窄到 440px,套餐卡收敛成两种互斥状态
Independent Staging Quality Gate / validate (push) Canceled after 6m18s
Independent Staging Quality Gate / publish (push) Canceled after 0s
任务书 TASK-cend-surfaces-claude-alignment-20260916 §R8(T8.1 / T8.2)。

T8.1(E13):880px 弹窗里「个人资料」「通用设置」的一列表单铺满约 690px,
字段与标签被拉断。表单分区的内容区加 `settings-dialog-content--form`,
子元素上限 440px 并左对齐;「星盘资料」「账户与点数」两个列表分区保持铺满。
上限只挂在滚动容器的子元素上,不挂 `.settings-modal` / `.account-settings-shell`,
因此传不到固定尺寸的弹窗(BUG-554 / BUG-698 的现象无法复现)。

T8.2(D13):套餐卡的三个修饰符可同时命中,叠出没有设计定义的边框与底色。
收敛成两种互斥状态 `is-current`(当前套餐)与 `is-recommended`(推荐),
「推荐且当前」判给当前套餐(该卡的动作是续费)。
`highlighted` 不再进 className,删掉 `--highlighted` 那条描边规则,
定位交给 use-billing-panel 里已有的 scrollIntoView + focus。
手机端「月卡置顶」改挂 `[data-plan-alias="monthly"]`——版位不是状态,
月卡成为当前套餐后排序不变。

测试:3350 → 3354(+4),fail 31 → 31 且失败清单与基线逐条一致。
6 处既有断言改动均就地写了「原值/新值/原因」,另有 3 次破坏性验证。
tsc 0 错;lint 0 error / 118 warning(持平);干净 next build 后 `/` 仍 `○ Static`,
产物 CSS gzip 39,034 → 38,882 B(−0.39%),三条新规则在产物里逐条取证。

环境缺口(未记为通过):四个分区切换不跳尺寸、支付下单流程、`?plan=` 滚动定位的
视觉确认——无 Chrome、无受控账号,见 PROGRESS 的环境缺口段。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 06:24:11 +00:00
Jesse_ChenandClaude Opus 5 50ce02c837 feat(ui): 星盘/星历/报告中心并入 app 外壳,侧栏不再消失
Independent Staging Quality Gate / validate (push) Failing after 9m57s
Independent Staging Quality Gate / publish (push) Skipped
三个页面此前各是脱离外壳的独立全屏路由,各写了一套一样的
*-shell / *-topbar(只有一个「返回对话」链接)/ *-hero 骨架,
侧栏在打开它们的瞬间整个消失。

新增 AppNavRail(只读:两个 GET,零写操作)与 SecondaryShell。
会话行走 sessionHref → /?c=<uuid>,跳转复用现有侧栏的
persistLoginSessionReturn + location.assign,行为完全一致。

刻意不带重命名/收藏/归档/删除与账户菜单:那套连着 Home() 的乐观更新与
回滚层,为四个路由把它整体上提远超需要,且会撞 useState 增长门禁。

四个路由渲染标记完全不变:/ ○、/chart ○、/ephemeris ○、/reports ƒ。
CSS gzip 39,825→39,727(−0.25%);per-route JS 体积构建不输出,
已作为口径缺口记录。

两处自身问题被测试抓到并修复:usePathname() 在 app-router 上下文外
返回 null(类型说是 string)、fetch 在 jsdom 里可能不存在。
另差点随 hero 一起丢掉 BUG-717 的 eyebrow 文案(成本与速度承诺,
会印在失败页上),已放回 tab 行下方。

/reports/[reportId] 留给 R6 与目录一起做;根边界页保留「返回对话」,
它们不得 import globals.css,挂不了外壳。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 06:03:30 +00:00
Jesse_ChenandClaude Opus 5 b3ea8c336e feat(ui): 侧栏三段合成一条平铺列表,助手消息去掉头像
Independent Staging Quality Gate / validate (push) Failing after 9m19s
Independent Staging Quality Gate / publish (push) Skipped
侧栏此前在第一条会话之前压着三段:星盘名字 chip 组、收藏对话 <details>、
历史对话 <details>——两个折叠箭头,底下都没有值得折叠的东西。现在是一条
平铺列表:收藏作为首个标签组(带 13px 星标),其余沿用既有的日期分组。

星盘入口收敛到一处。这里与任务书 D6 的字面写法方向相反:D6 说留侧栏删
账户菜单,我做的是删侧栏留账户菜单。理由——D6 写于侧栏只有 2 个导航项时,
现在是 4 个;且 chip 点下去只是开弹窗(page.tsx 里三个回调都是
openAccountDialog("chart-library")),一组只会开弹窗的名字没有导航价值。
连带删 charts/onSelectChart/onAddChart props、SidebarChart 类型、
sidebarCharts 派生与一批 CSS。

助手头像删除,--assistant-content-inset 由 calc(32px + gap) 归零,
追问 chip 与运行时间轴改为与正文对齐。/jyotish-logo.png 文件保留。

顺带关闭 R2 留下的隐患:入口 pill 36px 低于 44px 触摸推荐值,补
::after inset -4px 热区扩展,并在 touch-target-contract 里接替
已删除的 .chart-nav-chip。

测试 3350 不变,fail 仍 31 且与基线逐条一致;/ 仍 Static;
CSS gzip 41,044→39,825(−3.0%),三轮累计 −3.1%。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 05:46:29 +00:00
Jesse_ChenandClaude Opus 5 62903b7a12 feat(ui): 空状态改成「问候 + 输入框 + 两枚入口 pill」
Independent Staging Quality Gate / validate (push) Failing after 9m13s
Independent Staging Quality Gate / publish (push) Skipped
此前空态是 hero 卡(h1 clamp 到 52px)加两张 min-height 228px 的产品卡,
输入框被压在约 800px 内容之下,主动作不是视觉焦点。

改法:问候拆成 StarterGreeting 留在对话区并底对齐,两个产品入口降级成
StarterEntries 渲染在 composer 之后。composer 本身一行未动——它在空态与
会话态是同一个 DOM 位置,首条消息落地时不重挂载,草稿/焦点/排队卡都不受影响。

顺带修掉:空态 composer 1040px、会话态 760px,发首条消息时输入框会当场
变窄一截。两态统一到 --session-column-width,并新增断言锁住。

校正入口保留三个服务端驱动的文案分支(我第一版收成了两个,是
rectification-agentic-entry 打红才发现)。

DESIGN.md:Product entrypoint card 整节重写为 Starter home;删掉
Suggestion card 死文档(它描述的主题卡样式正是本轮删除的 CSS)。

测试 3350 不变,fail 仍 31 且与基线双向零差异;/ 仍 Static;
CSS gzip 41,096→41,044(−0.13%)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 05:31:15 +00:00
Jesse_ChenandClaude Opus 5 66d9f59d84 feat(ui): 标题不再落宋体,强调色分阶换 coral,删输入框常驻底栏(BUG-737/738)
Independent Staging Quality Gate / validate (push) Failing after 9m26s
Independent Staging Quality Gate / publish (push) Skipped
BUG-737:--font-display 以两个从未加载的 Anthropic 授权字体开头
(Tiempos Headline / StyreneB:无 @font-face、public/ 无字体、layout.tsx
只 vendor 了 Inter),于是每个中文标题都掉到 Songti SC / SimSun——20 条
规则宽,含助手回答正文的 h2/h3。display 与 body 合并为同一条无衬线栈,
层级改由字重承担(33 条 display 规则 400→500)。

拉丁衬线方案实测否决:Newsreader 拉丁子集 132 KB(Inter 的 2.7 倍),
只为给一个品牌字上衬线,且会把「D10 事业盘怎么读」劈成两种字形。

BUG-738:亮色 #85432f 与暗色 #d78064 不同源;--color-ring 在
@theme inline 里硬编码不跟随 :root。产品拍板换 Claude coral #cc785c,
但实测它作文字色只有 3.14:1,而 62 个调用点里 53 个是 color:。
按角色拆两阶:--color-action #a9583e(文字 4.85:1)、
--color-action-strong #cc785c(填充/导轨/焦点环,3:1 非文字阈值)。
--report-accent 刻意保持 #85432f(报告是纸面,不跟应用强调色)。

T1.3/T1.4:模型选择器进 ChatComposer 的 toolbar 插槽,删掉常驻 44px 的
.composer-footer;顶栏 68→46px,「分析对象:」改为标题旁静默 chip。

防复发:新增 font-stack-loadable-contract,断言字体栈里每个 family 要么
vendored 要么是系统字体,且 --font-display 不得触达任何 CJK 衬线。

测试 3346→3350,fail 仍 31 且清单与基线逐条一致;/ 仍 Static;
CSS gzip 41,095→41,096(+0.002%);快速门 pytest 段 798 passed / 0 failed。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 04:53:14 +00:00
Jesse_ChenandClaude Opus 5 3fd74daf34 docs(tasks): C 端次级页面对齐任务书(R4–R8)
星盘/星历/报告三个页面各是脱离 app 外壳的独立全屏页,侧栏整个消失,
且三家各写了一套一样的 shell/topbar/hero 骨架——与上一单空状态同根因。

R4 抽只读导航外壳(前置)→ R5 星盘+星历、R6 报告
R7 生时校正、R8 设置+充值 可并行

设置单已于 111b4a84 合入,R8 阻塞解除。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 04:18:37 +00:00
Jesse_ChenandClaude Opus 5 111b4a8455 fix(settings): 弹窗高度补 vh 基线,分区菜单去掉强调条(BUG-698)
Independent Staging Quality Gate / validate (push) Failing after 9m25s
Independent Staging Quality Gate / publish (push) Skipped
设置弹窗的固定高度只用 dvh 写、没有回退。不认识该单位的引擎会把整条
height 与 max-height 作废,盒子退回按内容撑开,于是切分区就跳大小——
这正是 BUG-554 现象的复发,而 BUG-554 的防复发「必须同时声明 width 与
height」只检查声明存不存在,挡不住「写了但没生效」。

实测(Chrome 151,真实产物 CSS + 复刻 DOM,1440×900):dvh 正常时四个
分区恒定 866.80×640px,**事故不复现**;摘掉 dvh 后变成 313/313/378/1130,
宽度不动——与用户描述的形状完全一致。因此机制已证实,但用户当时的浏览器
未定位,BUG-698 记为 investigating 而非 resolved。

附带发现:任务书要求照抄的重复声明式回退 `height: 100vh; height: 100dvh;`
在本仓根本发布不出去——Lightning CSS 会合并同名属性的重复声明只留最后一条,
全仓唯一那处回退(sidebar-provider)在线上早就是死的,还有一条测试专门守着
这个从未发布过的写法。改用 @supports (height: 1dvh):vh 作基线,dvh 作升级。
修复后不支持 dvh 的引擎也收敛到恒定 640px,支持的逐像素无变化。

同轮按产品决策去掉设置分区菜单的左侧/下方强调色条,选中与悬停改用面与
墨色等级区分,不用色相、不用字重。左侧会话列表的色条本轮不动。

- 新增 viewport-unit-fallback-contract(3 条,全文件),三次破坏性验证各自打红
- account-dialog-overlay 新增同尺寸契约与分区菜单契约
- 三条钉死旧 dvh 字面量的既有断言按「原值/新值/原因」更新,均未弱化
- tsc 0 错;lint 0 error / 118 warning(持平);npm test 3346/3300/fail 31,
  失败清单与基线逐字相同;/ 仍 ○ Static;样式 gzip +0.38%;
  快速门 pytest 段 792 passed / 1 skipped / 0 failed

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 03:50:38 +00:00
Jesse_ChenandClaude Opus 5 5582091851 refactor(api): 抽出 offline compute mixins,关掉 2/4 处 handler 伪造
Independent Staging Quality Gate / validate (push) Canceled after 2m18s
Independent Staging Quality Gate / publish (push) Canceled after 0s
spike 闸门(任务书 §5.2)结果为红,按 §6.3 退回 A 方案。

spike:115 个闭包方法整体移入 ConsultationComputeMixin 后,
tests/test_api_server_security.py 一字不改跑出 1 failed / 128 passed。
test_chart_async_job_executes_in_background 挂在
monkeypatch.setattr(jyotish_api_server, '_write_async_job_record', ...):
调用方法随 mixin 搬走后从新模块 globals 解析,补丁落在旧模块绑定上不生效。
已实证把同一 fake 打到 mixin 模块即恢复原行为,故为落点问题而非搬坏。
循环 import 不是障碍(移动集不引用 JyotishAPIHandler)。

退回 A 的实际交付:新建 scripts/offline_compute_mixins.py,
收 BadRequest、3 个模块级助手,以及 RequestParamMixin /
VedastroEvidenceMixin / SynastryMixin 共 7 个方法(300 行),
JyotishAPIHandler 通过继承保留全部方法,HTTP 侧零变化。
consultation_workflow_service.build_runtime_evidence_helpers 与
local_accuracy_report 改为直接实例化 mixin,不再伪造 handler。

11 个搬走的定义经 SHA-256 逐个比对与搬走前字节级相同;
jyotish_api_server.py 的 diff 为 11 行插入 / 378 行删除,无重排。

scripts 侧 __new__ 4 → 2(剩 2 处都在咨询工作流链上);
类方法 225 → 218;行数 11,291 → 10,924。
合同测试收紧基线并新增 scripts 侧专门断言与反向 import 断言;
两次反向验证(加回 __new__ / 加类方法)均正确变红。
新增 tests/test_offline_compute_mixins.py 覆盖此前零覆盖的 MCP 路径,
并加入 CORE_PYTEST_TARGETS。

tests/test_api_server_security.py 一字未改,129 passed。
快速门 pytest 段 798 passed / 1 skipped / 0 failed。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 03:46:01 +00:00
Jesse_ChenandClaude Opus 5 30f9e0943f docs(tasks): 后门单 §5.1 闭包重算结果
从四处 JyotishAPIHandler.__new__ 的实际入口重算传递闭包(含模块级
execute_consultation_workflow 的 handler._x() 一层):实测 115 方法 /
4,104 行,非任务书估算的 8 方法 / 314 行;碰 HTTP 上下文者 0 个,
任务书 §5.1 的停手条件未触发。

闭包按入口分裂为可搬的 7 方法 / 300 行(vedastro 证据 + 合盘)与
不可搬的 114 方法 / 4,086 行(咨询工作流),后者含 _compute_chart_sync
与 _build_chart_prompt_pack 两个 ≥150 行方法,与 §4.3 冲突。

未改 scripts/ 与 tests/。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 03:46:01 +00:00
Jesse_ChenandClaude Opus 5 a2c1f1fbda docs(tasks): C 端界面向 claude.ai 产品界面对齐任务书(三轮串行)
根因:CLAUDE_DESIGN.md 扒的是 claude.com 营销官网,它自己在 Known Gaps
里写明 claude.ai 产品界面不在范围内,而 DESIGN.md 把它当成了产品界面的
实现契约。于是营销页语汇(hero band、3-up feature card)进了聊天空状态,
拉丁 display face 的衬线规则套到中文界面变成了宋体。

R1 字体 + 强调色 + chrome 瘦身(BUG-737/738)
R2 空状态重做
R3 侧栏拍平 + 入口收敛 + 去头像

三轮都动 globals.css,不得并行。附原型图链接。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-16 03:42:28 +00:00
Jesse_ChenandClaude Opus 5 5094fd2620 docs(tasks): 后门单改写为 mixin 方案(产品选 B),修正闭包规模
第一版写「8 方法 / 314 行」错了一个数量级。错因:闭包只跟 self._x(),而
_compute_consultation_workflow 只有 6 行、转给模块级
execute_consultation_workflow(self, ...),那个函数体 394 行、对传进来的
handler 调 16 个方法再往下扇出。跟丢那一跳,300 行被当成了全部。
执行方重算:约 115 方法 / 4,104 行,占全类 51% 方法;碰 HTTP 上下文的
仍是 0 个——本单成立的前提没变。

产品在 A/B/C 中选定 B(mixin 抽取),并授权把 §4「不得搬 ≥150 行业务
方法」按本意解释:那条红线针对的是 C 那种逐行改写,而 mixin 是把方法体
原样挪家、self 含义不变、靠 MRO 解析,HTTP 那一面零变化。决策记录里已
写明这是该红线的推翻记录。

新增 spike 闸门:搬进 mixin 后 test_api_server_security.py 一字不改直接
跑,绿则继续、红则退回 A(7 方法/300 行、关 2 个伪造点)。已查明两个降
风险事实(security 测试无结构性断言、增长合同用整文件正则),并点名真
风险是循环 import——闭包引用同文件 44 个模块级函数 + 21 个常量/类。

另修正 __new__ 归零口径:合同基线 33 = scripts 4 + tests 29,tests 侧含
不许改的 security 测试,所以归零只针对 scripts 侧 4 → 0。

纯文档推送,不触发门禁、不发布镜像、不部署。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 03:14:41 +00:00
Jesse_ChenandClaude Opus 5 dc8cae316e test(contract): 让前端源码合同跟上搬家,快速门 Python 段恢复全绿(BUG-736)
Independent Staging Quality Gate / validate (push) Failing after 10m4s
Independent Staging Quality Gate / publish (push) Skipped
三条断言过期,不是保证丢了:

- 149e1ec4 把创建路由改走 chatSessionCreateInsertRow(...),`user_id: user.id`
  字面量消失。按三栏改成路由断 `userId: user.id`、write-contract 断
  `user_id: input.userId`,两处都断,不放宽。
- 状态下沉第二批把合盘搬进新建的 use-synastry.ts,而 _home_surface() 只拼
  OPTIONAL_HOME_HOOKS 白名单,于是 fetch("/api/synastry" 与「未能存入历史」
  在并集里找不到。白名单补上该 hook 并注明新增 Home 级 hook 必须同步登记。

为什么没被拦住:这几条是 Python 测试,断言对象却是前端源码;前端轮次的验收
口径不含快速门,AGENTS §10 又只要求「任何 Python 改动」跑快速门——纯前端改动
落在两张网中间。验收方两轮都只跑前端套件,带红合入。防复发写进 BUG-736。

验证:test_supabase_user_data_contract.py 8 条全绿;快速门 pytest 段
792 passed / 1 skipped / 0 failed(此前 3 failed)。整体仍退出 1,剩余唯一
原因是本机无 rsync、无 Docker 的既有环境缺口。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 02:12:36 +00:00
Jesse_ChenandClaude Opus 5 7ae6df3ebb docs(tasks): 状态下沉第二批进度记录与真人走查清单
Independent Staging Quality Gate / validate (push) Failing after 6m17s
Independent Staging Quality Gate / publish (push) Skipped
进度记录含三簇 20 个状态的分类表(每个写明谁在读)、改前改后实测、
既有断言改动的三栏说明、反向验证、lint warning 逐条比对、以及
session 簇留 4 个在外壳的让步说明。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 02:02:22 +00:00
Jesse_ChenandClaude Opus 5 bdb81c8c86 refactor(home): let useSessionManagement own six session states
5.4: sessionsCursor / showArchivedSessions / sessionMenuId /
pendingSessionDeletion / sessionDetailLoadingId / sessionFullPrompt move into
use-session-management.ts, which now also computes visibleSessions from the
archived flag it owns. Home reads back only what its own JSX renders.

sessions / activeSessionId / creatingSession / pendingSessionId stay in the
shell: each is read by the bootstrap effect or the consultation run before the
session hook is called. Reasons are listed one by one in the progress record.

useSessionManagement params 41 -> 34, useProfileOnboarding 38 -> 26.

The growth contract tightens to useState 36 / useRef 37 / lines 1846 and gains an
assertion that useSessionManagement still runs before useRectificationSurface,
with the opener handed over through rectificationSessionOpenerRef.

Zero behavior change, zero copy change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 02:02:22 +00:00
Jesse_ChenandClaude Opus 5 e6c6839742 test(home): follow the profile hook's return through the signOut marker
The mount-once bootstrap effect keeps its literal `}, []);` dependency array:
two existing contract tests use that exact text as a slicing landmark, so the
effect stays as it was and its existing exhaustive-deps warning simply names two
more stable setters. Only the signOut slice marker in
chat-navigation-a11y-contract moves, with the three-column note; the assertion's
subject is untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 02:02:22 +00:00
Jesse_ChenandClaude Opus 5 ae4573897a refactor(home): let useProfileOnboarding own the six profile states
5.3: profile / profileDraft / profileNotice / avatarNotice / avatarSaving /
profileSaving move into use-profile-onboarding.ts; Home reads them back from the
hook's return. The hook call moves above useBirthTimeGuidedJourney so profile is
defined before the first reader.

Turning the hook stateful made the React compiler lint rules apply to it, which
surfaced five errors that only a hook-shaped file gets checked for:
- two ref params written through .current (dialogReturnTarget,
  birthTimeRevisionPending) now end in "Ref" as the rule's hint asks;
- two render-phase ref writes (guidedBirthTimeReadyRef /
  editDeclaredBirthTimeDetailsRef) are gone: the hook already returns
  completeGuidedBirthTime and editDeclaredBirthTimeDetails, and now that it runs
  before useBirthTimeGuidedJourney they are passed straight in. Both callbacks
  were only ever read from render-scope closures, so the call target is the same
  function on every frame as before.

setProfile / setProfileDraft are listed in the two effects that call them; they
are raw useState setters handed through the return, so identity never changes
and neither effect gains a re-run.

Zero behavior change, zero copy change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 02:02:22 +00:00