Files
Jyotisha/docs/tasks/TASK-home-state-lowering-20260915.md
T
Jesse_ChenandClaude Opus 5 e4788dfc00 docs(tasks): 换掉两条增长冻结口径 + page.tsx 状态下沉第一簇 + C1 提前
产品 2026-09-15 三项拍板,落成两份新单与两处既有单的修订:

- 新增 TASK-freeze-metric-change-20260915(无 BUG 号,后面两单的前置):
  两条冻结余量已用完(page.tsx 1951/1951 余 0;api server 11334/11363 余 29),
  冻结从「逼新代码往外走」退化成拦路。实证:page.tsx 行数砍 59% 但 Home()
  的 useState 从 56 涨到 66;api server 225 个类方法只有 12 处真碰 HTTP。
  主门换成耦合指标,行数降为粗护栏;同时推翻 §6「参数式 hook 内部保持
  0 个 React hook」——那正是状态搬不走的原因。
- 新增 TASK-home-state-lowering-20260915(无 BUG 号):先搬 rectification*
  那 15 个 state 进已经是 dynamic 子树的校正面,Home() useState 66 → ≤53。
  零行为变化;串行在 freeze-metric-change + C2 + R3 之后。
- 修订 TASK-consultation-external-evidence-cache-20260915:依赖反转,C1 排在
  API server 拆解之前(它动模块级函数,拆解动类方法);补「不得新增类方法、
  行数余量仅 29」的硬红线。
- 修订 TASK-api-server-decomposition-20260916:串行依赖加 C1 与
  freeze-metric-change;__new__ 计数按 grep 的 4 计(原文 3 是文件数);
  阶段 4 收尾口径改写;基线 11,314 → 11,334。

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

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

160 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TASK · 把校正面的 15 个状态从首页搬下去(page.tsx 状态下沉 · 第一簇)
- 日期:2026-09-15
- 基线 commit`origin/staging` @ `6b3248bf`(开工时以最新 `origin/staging` 为准,见 §7
- 执行分支:`codex/home-state-lowering-20260915`
- 落点:`frontend/src/app/page.tsx``frontend/src/hooks/use-rectification-surface.ts``frontend/src/components/conversational-birth-time-rectification.tsx`(或新建的容器组件)
- **串行依赖(三条,缺一不可)**:
1. `TASK-freeze-metric-change-20260915` —— 本单要让抽出去的 hook 持有 React 状态,那正是现行 `AGENTS.md §6` 禁止的;必须等新口径生效
2. `TASK-consultation-context-memory-20260915`C2)—— 它在改 `use-session-management.ts` / `use-consultation-run.ts`,与本单同一片状态层
3. `TASK-rectification-settled-render-split-20260915`R3)—— 它在改 `rectification-agentic-chat.tsx`,与本单同一片子树
- 规模:一簇状态换个住处。**零行为变化、零文案变化。**
---
## 1. 为什么是这一簇
`page.tsx` 现在 1,951 行,行数上限 1,951,**余量 0**。但行数不是病根:
| 指标 | BUG-249 当时 | 今天 |
| --- | ---: | ---: |
| 文件行数 | 4,766 | 1,951 |
| `Home()``useState` | 56 | **66** |
| `useEffect` | 18 | 22 |
| `useRef` | — | 41 |
| `useCallback` / `useMemo` | 0 / 0 | 0 / 0 |
**行数砍掉 59%,状态反而从 56 涨到 66。** 前几轮拆的是代码不是状态:抽出去的 hook 是参数式的,`useSessionManagement(params)` 开头要解构约 40 个参数,`useRectificationSurface(params)` 约 56 个——状态所有权一个都没搬,每搬一次还要新增一批传参。
66 个 state 按归属分群:
| 群 | 个数 |
| --- | ---: |
| **`rectification*`** | **15** |
| `session*` | 10 |
| `profile*` | 6 |
| `synastry*` | 4 |
| `account*` | 4 |
| 其余分散 | 27 |
最大的一簇服务的是一个**已经是 `dynamic()` 懒加载的子树**`<ConversationalBirthTimeRectification>` 挂着 **24 个 props**,而喂它们的 15 个 state 全住在 `Home()` 里。边界最清楚、收益最大,所以第一簇搬它。
那 15 个是:
```
rectificationSessionId rectificationShouldStartOpening
rectificationCaseId rectificationTurns
rectificationHeaderSlot rectificationSnapshot
rectificationPendingQuestion rectificationOpeningSessionId
rectificationLoading rectificationEntrySummary
rectificationMutationPending rectificationEntrySummarySettled
rectificationError
rectificationErrorSessionId
rectificationReadonly
```
## 2. 根因
`AGENTS.md §6` 现行那句「参数式 hook 内部保持 0 个 React hook 的既定模式」把状态钉死在 `Home()` 里;同一节的行数冻结又不许 `page.tsx` 增长。两条合起来等于「不许再加状态」,而每一轮新功能都要加。`TASK-freeze-metric-change-20260915` 已经拿到产品授权推翻前半句,本单是第一个吃到新口径的轮次。
## 3. 决策记录
产品 2026-09-15 拍板:
1. **`page.tsx` 走「状态下沉」这条路**,不引外部 store、不铺全局 Context Provider。理由:不引新依赖、可以一簇一簇增量做,每搬一簇 `page.tsx` 就真降一截。
2. **第一簇搬校正面的 15 个。** 后续 `session*` / `profile*` / `synastry*` 各自另开单,本单不碰。
3. **抽出去的 hook 与子组件从此持有自己的状态**(推翻 §6 旧红线,措辞由 freeze-metric-change 单落地)。执行方不得以「AGENTS 说参数式 hook 里不能有 React hook」为由拒改。
4. **零行为变化。** 本单不修任何已知交互缺陷,发现了写进进度记录。
## 4. 硬红线
1. **不是 15 个都能搬。** 有几个外壳自己要读(例如 `rectificationSessionId` / `rectificationCaseId` 参与决定显示哪个界面、侧栏会话列表也要知道)。**第一步必须逐个分类**:「只服务子树 → 搬下去」「外壳也要读 → 留在外壳,但收敛成一个对象,不再是散装的多个 `useState`」。分类表写进进度记录,不许含糊。
2. **零行为变化**是唯一成败判据:进入校正面、退出、刷新、从首页卡片打开、打开历史校正、开场自动触发、只读态、报错态、换模型、采用后回首页——逐条与改前一致。
3. `next build``/` 仍须 `○ Static`;首屏 JS gzip 变化在 ±2 % 内(上次实测 584,413 B)。
4. 测试总数不得低于开工时 `origin/staging` 的实测;改任何既有断言必须写「原值 / 新值 / 原因」三栏(AGENTS §7.3)。
5. 不得新写第二个聊天输入框、第二套滚动跟随、第二套加载动画(§6 第三条原样有效)。
6. 不得顺手升级依赖、不得顺手修不在本单里的 warning。
7. **不得改数据库、不得改任何 API 路由。** 本单只动前端状态的住处。
## 5. 任务分解
### 5.1 先分类,再动手
把 15 个逐个归类并写进进度记录:
| 类别 | 处置 |
| --- | --- |
| 只服务校正子树 | 搬进子树(`useRectificationSurface` 变成真 hook,或由容器组件持有) |
| 外壳也要读 | 留在外壳,但合并成**一个**状态对象,散装 `useState` 数下降 |
- 验收:分类表在进度记录里,15 个一个不漏,每个写明依据(谁在读它)。
### 5.2 `useRectificationSurface` 变成真 hook
现在它要解构约 56 个参数。改成自己 `useState` / `useEffect` 持有第一类状态,对外只暴露子树真正需要的接口;`page.tsx` 侧的传参随之消失。
- 验收:`useRectificationSurface` 的参数个数显著下降,新值写进进度记录(改前约 56)。
- 验收:`<ConversationalBirthTimeRectification>` 的 props 个数下降,新值写进进度记录(改前 24)。
### 5.3 `Home()` 的状态计数必须真降
- 验收:`Home()``useState` 数从 **66** 降到 **≤ 53**(搬走至少 13 个;允许留 2 个在外壳,多留必须逐个说明理由)。
- 验收:`useRef` 数不得上升(改前 41)——不许把 state 改写成 ref 来凑数字。
- 验收:`frontend/tests/home-shell-growth-contract.test.ts`(由 freeze-metric-change 单建立)在本单收尾时更新为新基线,并贴一次反向验证。
### 5.4 行为等价证明
- 验收:改动前后各跑一次全量前端套件,失败清单逐条一致(无 Docker 时数据库套件照常红)。
- 验收:`npx tsx --test tests/rectification-*.test.ts` 全绿,断言零改动——如果必须改,按 §4.4 写三栏说明。
- 验收:`docs/testing/` 下留一份真人走查清单,覆盖 §4.2 那十条路径(本仓没有浏览器与登录态,这一项只能人工)。
### 5.5 记录
本单不产生 Bug 记录(不是缺陷,是结构改造),不进 `CHANGELOG.md`(无用户可感知变化)。若过程中确实改了任何可见样式,必须同提交更新 `frontend/DESIGN.md`AGENTS §7.5)。
## 6. 让步顺序
1. 5.1(分类)**不得砍**——没有分类表就动手,一定会把外壳要读的状态搬下去然后再搬回来。
2. 5.2 + 5.3 是主体。
3. 5.3 的目标值可以让步(比如只搬到 ≤ 56),但让步幅度和原因必须写进进度记录,**不得静默降低**。
4. 5.4 不得砍。
5. 5.5 不得砍。
## 7. 开工前置命令
```bash
git fetch origin --prune
# 三条串行依赖必须都已合入 staging,逐个确认
git log --oneline origin/staging | head -20
git worktree add -b codex/home-state-lowering-20260915 \
.worktrees/home-state-lowering-20260915 origin/staging
cd .worktrees/home-state-lowering-20260915/frontend
git status -sb | head -1
npm ci
# 取当时实测基线,不要抄本任务书里的数字(七条在飞分支合并后会变)
grep -cE '\buseState[<(]' src/app/page.tsx
grep -cE '\buseRef[<(]' src/app/page.tsx
grep -oE 'const \[rectification[A-Za-z]+' src/app/page.tsx | wc -l
```
验收命令:
```bash
./node_modules/.bin/tsc --noEmit
npm run lint # 0 error
npx tsx --test tests/rectification-*.test.ts tests/home-shell-growth-contract.test.ts
npx tsx --test tests/*.test.ts # 与基线逐条比对失败清单
npm run build # `/` 仍须 ○ Static,首屏 gzip ±2%
```
## 8. BUG 编号起点
本单不占 BUG 号。基线 `6b3248bf` 上最大号 **BUG-720**,721–732 已被两轮审计七单预占。
## 9. 不在本单范围
- `session*` / `profile*` / `synastry*` / `account*` 四簇(各自另开单)
- Context Provider 或外部 store(§3.1 已否决这一轮走这两条路)
- 校正面自身的任何交互缺陷(本单零行为变化)
- API server 拆解(另一条线)