Files
Jyotisha/docs/tasks/TASK-home-state-lowering-batch2-20260916.md
T
Jesse_ChenandClaude Opus 5 37e6c519f7 docs(tasks): 校正状态板 + 状态下沉第二批 + 后门单 + 对账清单
① 状态板校正:09-15~16 这 10 份任务书的实现早已合入 staging 并经逐单
   验收,状态板却仍写「待领取 / 待验收」。改成「已验收」并补上落点 SHA
   与验收要点;顺带补齐 8 个 PROGRESS 列。防复发写进「命名与归档」:
   实现合入的同一次推送必须同时改状态板那一行。

② 新增 TASK-home-state-lowering-batch2-20260916(不占 BUG 号):
   第一批 f8e607c2 已验收(useState 66→52、useRef 41→39、散装
   rectification* 归零)。本单搬剩下三簇 session*10 / profile*6 /
   synastry*4,目标 52→≤36;并修第一批尾巴——
   createRectificationShellSetters 每帧新身份多出的那条 exhaustive-deps
   warning(119→120),正解是稳住 setter 身份而不是塞进 deps。

③ 新增 TASK-api-server-backdoor-close-20260916(不占 BUG 号):
   实测四处 __new__ 的传递闭包只有 8 方法 / 314 行且 0 个碰 HTTP 上下文,
   占全类 4%。所以关后门不必捆绑 2,000+ 行体量搬运。产品拍板阶段 2/3
   不立单,由 3b17c1b2 换好的门禁长期推进。原 decomposition 单标为已取代。

④ 新增 RECONCILE-20260916:另外 7 份 09-10~14 的单没有 PROGRESS、但
   引用的 BUG 号都是 resolved,无法从 README 判断,列成一页纸让执行方
   回填;另附三条确定没做的证据、两条未闭环状态、BLK-001 仍红。

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

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

150 lines
9.3 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 · page.tsx 状态下沉第二批:session / profile / synastry 三簇 + 稳住外壳 setter
- 日期:2026-09-16
- 基线 commit`origin/staging` @ `4f643aa0`(开工时以最新 `origin/staging` 为准,数字全部重测)
- 执行分支:`codex/home-state-lowering-batch2-20260916`
- 落点:`frontend/src/app/page.tsx``frontend/src/hooks/use-session-management.ts``frontend/src/hooks/use-profile-onboarding.ts``frontend/src/hooks/use-rectification-surface.ts`、以及为合盘新建的 hook
- **串行在 `f8e607c2`(第一批)之后**,已满足
-`TASK-consultation-residual-hotspots-20260916`(纯 Python)、`TASK-api-server-backdoor-close-20260916`(纯 Python)**无文件重叠,三单可并行**
- 规模:照第一批的成方再搬三簇。**零行为变化、零文案变化。**
---
## 1. 第一批已经证明这条路走得通
`f8e607c2` 把 15 个 `rectification*` 状态搬走,我验收实测:
| 指标 | 第一批前 | 第一批后 |
| --- | ---: | ---: |
| `Home()``useState` | 66 | **52** |
| `Home()``useRef` | 41 | **39** |
| `page.tsx` 行数 | 1,951 | 1,931 |
| 残留散装 `rectification*` state | 15 | **0** |
做法是:先把 15 个逐条分类成「只服务子树」与「外壳也要读」,前者搬进 `useRectificationSurface`,后者合并成**一个**对象 state。全量前端套件两侧完全相同(3329 tests / fail 31,失败清单逐条一致),首屏 gzip 0.00 % 变化,`/``○ Static`。增长冻结基线**往紧里收**66/41/1951 → 52/39/1931)。
本单把同一套做法用在剩下的三簇上。
## 2. 事故实证:剩下的 52 个里还有 20 个是成簇的
`Home()` 现在 52 个 `useState`,按前缀分群:
| 群 | 个数 | 已经有的抽取点 |
| --- | ---: | --- |
| `session*` | **10** | `use-session-management.ts`(参数式,解构约 40 个参数) |
| `profile*` | **6** | `use-profile-onboarding.ts` |
| `synastry*` | **4** | 无,散在 `Home()` 里 |
| 其余分散 | 32 | — |
`useSessionManagement(params)` 的第一件事仍然是解构约 40 个参数——第一批没有碰它。这就是「代码搬走了、状态没搬」的残留部分。
另有第一批留下的一个小尾巴(执行方已在进度记录里主动披露,判断正确):
`createRectificationShellSetters(setRectification)` 在 render 体里**无记忆化调用**,每帧返回新的函数身份,于是入口摘要那个 `useEffect` 多了一条 `react-hooks/exhaustive-deps` warning(全仓 119 → **120**)。进度记录写明「不能把它们放进 deps,否则每帧重拉摘要」——这个判断是对的,我核过:那几个 setter 都只是 `setRectification(prev => ...)` 的包装,任何身份行为都一样,**当前是安全的**。但它是个陷阱:后面任何人为了消除 warning 把它们塞进 deps,就会造成每帧重新拉取入口摘要。
## 3. 决策记录
产品 2026-09-16 授权本单,口径与第一批一致:
1. **继续走「状态下沉」**,不引外部 store、不铺全局 Context Provider(第一批已否决这两条,本单不重开)。
2. **抽出去的 hook 与子组件持有自己的状态**——`AGENTS.md` §6 已于 `3b17c1b2` 改写,「参数式 hook 内部保持 0 个 React hook」那条红线已经推翻。执行方不得以旧 AGENTS 为由拒改。
3. **零行为变化。** 本单不修任何已知交互缺陷,发现了写进进度记录。
4. **那条 warning 要在本单里消掉**,做法是稳住 setter 身份,**不是**把它们加进 deps。
## 4. 硬红线
1. **先分类再动手。** 三簇共 20 个状态,每一个都要归到「只服务子树 → 搬下去」或「外壳也要读 → 合并成一个对象」,分类表连同「谁在读」写进进度记录,一个不漏。第一批的分类表是格式范本。
2. **零行为变化**是唯一成败判据。逐条对照:会话列表加载/翻页/切换/归档/置顶/重命名/删除、模型切换与同步失败、资料引导各步、头像上传、合盘发起与历史、写满后开新对话。
3. `next build``/` 仍须 `○ Static`;首屏 gzip 变化在 ±2 % 内(第一批实测 130,872 B,同一种量法)。
4. 测试总数不得低于开工时 `origin/staging` 的实测;改任何既有断言必须写「原值 / 新值 / 原因」三栏(AGENTS §7.3)。第一批那批源码正则合同(`foo={bar}``foo: bar`)是可接受的改法范本:**主语不许变**。
5. **`npm run lint` 的 warning 数不得上升**,并且本单要把 120 降回 **119**(消掉 §2 那条)。
6. 不得新写第二个聊天输入框、第二套滚动跟随、第二套加载动画(§6 第三条原样有效)。
7. 不得顺手升级依赖、不得顺手修不在本单里的 warning。
## 5. 任务分解
### 5.1 稳住外壳 setter,消掉那条 warning(先做,最小)
`createRectificationShellSetters(setRectification)` 的结果记忆化(`useMemo`,依赖只有 `setRectification`,而它是 React 的稳定 setter),使四个 setter 身份跨帧稳定;然后把它们按 eslint 的要求补进那个 `useEffect` 的 deps。
- 验收:`npm run lint` 从 120 warning 回到 **119**,且**没有新增任何其它 warning**(按规则+信息归一化比对,不要只比数字)。
- 验收:入口摘要的 effect 仍然只在 `accountId` / `bootstrapPhase` 变化时触发——新增一条断言或在进度记录里给出证明,**不得靠肉眼**。
### 5.2 `synastry*` 四个下沉(第二小,边界最清楚)
`synastryRelationshipType` / `synastryPendingId` / `synastryReportCard` / `synastryHistory` 目前散在 `Home()` 里,没有对应 hook。新建一个 hook 或直接让合盘子树持有。
- 验收:`Home()``const [synastry` 的出现次数为 **0**
- 验收:合盘发起、失败、历史列表三条路径行为不变。
### 5.3 `profile*` 六个下沉
`use-profile-onboarding.ts` 已存在(445 行,参数式)。改成持有自己的状态。注意资料引导与 `bootstrapPhase`、揭幕门耦合较深,分类时要特别小心哪些是外壳要读的。
- 验收:分类表里每个 `profile*` 都写明谁在读。
- 验收:`Home()` 里散装 `profile*` state ≤ **1**(合并对象),多留必须逐个说明理由。
### 5.4 `session*` 十个下沉(最大、最后做)
`use-session-management.ts` 是三簇里耦合最深的(约 40 个参数,522 行),而且它和校正面有交叉(第一批的进度记录写明:`useSessionManagement` 必须在 surface hook 之前调用,用 `rectificationSessionOpenerRef` 把 opener 递过去)。**这条交叉关系不得破坏**。
- 验收:`useSessionManagement` 的参数个数显著下降,新值写进进度记录(改前约 40)。
- 验收:`Home()` 里散装 `session*` state ≤ **2**
- 验收:`rectificationSessionOpenerRef` 那条调用顺序约束仍然成立,并有一条断言钉住。
### 5.5 收口指标
- 验收:`Home()``useState`**52** 降到 **≤ 36**(三簇共 20 个,允许留 ≤ 4 个在外壳);`useRef` 不得上升(改前 39)。
- 验收:`frontend/tests/home-shell-growth-contract.test.ts` 更新为新基线(**只许往紧里收**),并贴一次反向验证(人为加一个 `useState` 必须变红)。
- 验收:全量前端套件失败清单与开工基线逐条一致。
### 5.6 真人清单
`docs/testing/home-state-lowering-20260915.md` 的格式,为本单三簇补一份可照做的走查条目(本仓无浏览器与登录态)。
## 6. 让步顺序
1. 5.1 必须做,它是第一批留下的尾巴,最小。
2. 5.2 → 5.3 → 5.4 按由易到难推进。**做不完可以只交前两簇**,砍掉的簇在进度记录里写明,并把 5.5 的目标值按实际达成调整(**只许往紧里收,不许放松**)。
3. 5.5、5.6 不得砍。
## 7. 开工前置命令
```bash
git fetch origin --prune
git worktree add -b codex/home-state-lowering-batch2-20260916 \
.worktrees/home-state-lowering-batch2-20260916 origin/staging
cd .worktrees/home-state-lowering-batch2-20260916/frontend
git status -sb | head -1
npm ci
# 重测基线,不要抄本任务书里的数
grep -cE '\buseState[<(]' src/app/page.tsx
grep -cE '\buseRef[<(]' src/app/page.tsx
for p in session profile synastry; do printf "%s: %s\n" "$p" "$(grep -cE "const \[$p" src/app/page.tsx)"; done
npm run lint 2>&1 | tail -2
```
开工前必读:`docs/tasks/PROGRESS-home-state-lowering-20260915.md`(第一批的分类表与收尾实测,是本单的格式范本)。
验收命令:
```bash
./node_modules/.bin/tsc --noEmit
npm run lint # 0 errorwarning 必须 ≤ 119
npx tsx --test tests/home-shell-growth-contract.test.ts tests/rectification-*.test.ts \
tests/chat-session-*.test.ts tests/session-*.test.ts
npx tsx --test tests/*.test.ts # 与基线逐条比对失败清单
npm run build # `/` 仍须 ○ Static
```
## 8. BUG 编号起点
本单不占 BUG 号(结构改造,不是缺陷)。基线 `4f643aa0` 上最大号 **BUG-733**734/735 已被 `TASK-consultation-residual-hotspots-20260916` 预占。
## 9. 不在本单范围
- 其余 32 个分散状态(没有成簇,逐个搬性价比低)
- Context Provider 或外部 store
- 任何交互缺陷(本单零行为变化)
- API server 一侧(另一条线)