docs: product-level README, AGENTS.md split into code/reading parts, add CLAUDE.md, move task briefs to docs/tasks

- README.md is now the product/repo front door (architecture, repo map,
  local dev, test tiers, delivery flow, doc map). Engine positioning,
  VedAstro/Codex setup and the oracle/benchmark command reference move
  verbatim to docs/engine/README.md, docs/engine/vedastro-gateway.md and
  docs/benchmark/README.md. Capability badges realigned with the registry
  (91/78/8/0); tests/test_readme_badges.py was red on staging.
- AGENTS.md: Part A (environment truth, delivery, worktrees, record
  placement, bug workflow, growth freeze, frontend red lines, privacy,
  pre-work check, test tiers) and Part B (reading-rigor constraints).
  GitHub issue-tracker/triage boilerplate removed: GitHub is a read-only
  mirror. All strings locked by tests/ are preserved.
- CLAUDE.md added: roles, three working modes, task-brief sections,
  acceptance criteria, session discipline; imports AGENTS.md.
- 50 tracked TASK-*/PROGRESS-* files and 3 never-committed briefs move to
  docs/tasks/ with an index; REPO_LAYOUT.md merged into README.

Docs-only change (no gated path touched).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
This commit is contained in:
Jesse_Chen
2026-09-03 06:56:06 +00:00
co-authored by Claude Fable 5.1
parent af411f590a
commit 8db71aaf81
63 changed files with 1958 additions and 1196 deletions
@@ -0,0 +1,98 @@
# PROGRESS · 拆分首页巨石组件·第二批:聊天主链路(2026-09-01)
工作树:`.worktrees/contract-repairs-20260901`
分支:`codex/contract-repairs-20260901`
基线:小刀轮未推送,故未另开 `codex/home-split-batch2-20260901`;产品代码从 `a6148af8` + 小刀轮改动继续。
不要写成 `PROGRESS.md`。交付为快进推 `origin/staging`
React Compiler 仍关(`BLOCKED.md` 2026-08-17)。未引入 context/store。无手写 `useCallback`/`useMemo`。自定义 hook 按任务书决策记录 1 允许。`site-styles` import 仍在 `page.tsx` 顶。`const BirthTimeRectification = dynamic(...)` 未动。
## 度量
| 项 | 拆前(第一批后 3505 / 小刀后约 3510 | 拆后 | 说明 |
| --- | ---: | ---: | --- |
| `frontend/src/app/page.tsx` 行数 | 3505 | 2445 | 目标 ≤2600,达标 |
| `useState(` Home / session hook / consult hook | 26 / — / — | 26 / 0 / 0 | 独占 state 未下移,见 hook 顺序 |
| `useRef(` Home / session / consult | 19 / — / — | 19 / 0 / 0 | 同上 |
| `useEffect(` Home / session / consult | 20 / — / — | 20 / 0 / 0 | 拉取/恢复 effect 仍在 Home |
| `/` 路由 | `○ Static` | `○ Static` | webpack `next build --webpack` |
| 首屏 JS gzip -9 | 第一批后 501315 B | 501104 B = 489.4 KB | 211 B / **0.04%**(±2% 内) |
| 前端测试 | 小刀后 2428 | 2428 | 见验证 |
剩余未达标块(第三批):onboarding/profile`refreshAccount``signOut`)、rectification 胶水(`refreshRectificationEntrySummary``handleRectificationMessagesChange`)、合盘草稿、composer `submit`
## Hook 调用顺序(红线 1
搬前 `Home` 内真正的 React hook 序列(`a6148af8`):
`useRouter``useState`×26 → `useRef`×19 → `useBirthTimeGuidedJourney``useEffect`×8 → `useConversationScrollAnchor``useEffect`×12
咨询/会话的 `useState`/`useRef` **不是连续块**:中间夹着校正会话、引导草稿、星盘库、合盘等。若只把「引擎独占」的那几项抠进 hook,会改变 `Home` 里 hook 的相对次序。
因此本轮两个新 hook **内部零 `useState`/`useRef`/`useEffect`**,只搬函数体与 `.current =` 赋值。串接后 `useState`/`useRef`/`useEffect` 次序与搬前逐一相同;新增的只是两个无内部 hook 的调用点:
| 调用点 | 位置 | 原因 |
| --- | --- | --- |
| `useSessionManagement(...)` | `useBirthTimeGuidedJourney` 之后、**第一条 `useEffect` 之前** | 紧随其后的 effect 调用 `ensureSessionMessages` |
| `useConsultationRun(...)` | `useConversationScrollAnchor` 之后、其余 `useEffect` 之前 | `send` 需要 `conversationAnchor.anchorToLatest()` |
依赖方向:session hook 先返回 `persistSession` / `updateSession` / `startNewChat` / `continueInNewChat`,由 Home 传入 consult hook。两文件 **不得、也没有** 互相 import。
`setDraft` / `setDraftTheme` / `setDraftEntrypoint` / `refreshAccount` / `openAccountDialog` / `openRectificationFromHomepage` / `openRectificationSession` 仍是 `Home`**function declaration**(JS 提升),所以可以出现在 hook 调用点之上的参数列表里。这不是 React hook 顺序问题。
核对方式:对 `export default function Home` 之后的 `useRouter|useState|useRef|useEffect|useBirthTimeGuidedJourney|useConversationScrollAnchor|useSessionManagement|useConsultationRun` 计数;两 hook 文件内上述符号计数为 0。
## 任务 12 · 搬家
新文件(函数体与 `a6148af8``page.tsx` 逐行一致;允许差异仅缩进、`export`、经参数/返回值改道的标识符。popstate 以小刀轮为准,不回退到 `a6148af8`):
| 文件 | 行 | 内容 |
| --- | ---: | --- |
| `frontend/src/hooks/use-session-management.ts` | 443 | `updateSession``selectSessionModel` + 小刀修过的 `applySessionPopStateRef.current` |
| `frontend/src/hooks/use-consultation-run.ts` | 1073 | `restoreConsultationRecovery` + recovery/replay 赋值、`requestCancellation` / `confirmCancellation` / `stopResponse` / `completeConsultationInterface` / `send` / `regenerateLatestAnswer` |
函数体公证(对 `a6148af8` 去缩进后逐行):
`updateSession` 3、`persistSession` 25、`ensureSessionMessages` 24、`continueInNewChat` 7、`renameSession` 11、`deleteSession` 20、`togglePinnedSession` 10、`toggleArchivedSession` 22、`shareSession` 28、`startNewChat` 33、`startConsultationAfterRectification` 5、`selectSession` 28、`selectSessionModel` 52、`restoreConsultationRecovery` 53、`requestCancellation` 27、`confirmCancellation` 19、`stopResponse` 129、`completeConsultationInterface` 9、`send` 567、`regenerateLatestAnswer` 23`consultationRecoveryCheck.current` / `consultationReplay.current` 赋值块亦相同。
改名清单:**零**(无业务标识符重命名)。
`applySessionPopStateRef` 相对 `a6148af8` 的差异即小刀轮任务 3,原样搬进 session hook。
## 合同测试路径(同一 token,只换读取面)
拼接件 `frontend/tests/home-surface.ts` / Python `_home_surface()`:第一批文件 + 可选 `use-session-management.ts` / `use-consultation-run.ts``existsSync` / `Path.exists()`)。hook 落地后自动拼进。
| 测试 | 原路径 | 新路径 |
| --- | --- | --- |
| `sidebar-contract.test.ts`「keeps the page session selection callback…」 | `page.tsx` 正则 `selectSession` | `homeSurface`(函数已搬走;断言内容未改) |
| `consultation-birth-time-mode.test.ts` homepage `consultationMode:` | `page.tsx` | `homeSurface`token 在 `send` |
| `tests/test_supabase_user_data_contract.py` | 已是 `_home_surface()` | 可选 hook 列入清单(`persistSession(completedSession)` 等在 consult hook |
| `rectification-agentic-entry.test.ts` refreshAccount 切片 | `function updateSession` 作终点 | `function openAccountDialog``updateSession` 已搬走;若终点落在拼接后的 hook 文件,切片会吞进仍留在 page 的 `persistProfile`/`setProfileDraft`。断言内容未改) |
| `profile-state.test.ts` 同一切片 | 同上 | 同上(该文件仍只读 `page.tsx`,终点改为仍相邻的 `openAccountDialog` |
| `chat-stream-layout.test.ts` 活动/ndjson/`regenerateLatestAnswer` | `page.tsx` | `homeSurface`token 在 `send` / consult hook |
| `evidence-audit-panel.test.ts` workflow receipt headers | `page.tsx` | `homeSurface` |
| `chat-notice-and-scroll-contract.test.ts` send 切片 | `page.tsx``updateSession(sessionId, () => userSession)` | `homeSurface`(仅该条;JSX/poll 仍读 `page.tsx` |
其余已走 `homeSurface` 的聊天主链路测试(`chat-session-url` / `consultation-recovery` / `consultation-entrypoint` / `composer-isolation` / `chat-session-authority` 等)无需再改:切片标记仍在 hook 文件内且相邻。
锁 JSX/仍留在 `page.tsx` 的测试继续只读 `page.tsx``site-style-isolation``rectification-lazy-loading``chat-notice-and-scroll` 的 poll timer、profile/onboarding 等)。
小刀轮两个 Python 文件保持全绿(见小刀 PROGRESS)。
## 验证
- `./node_modules/.bin/tsc --noEmit`:通过。
- 聚焦合同:`consultation-recovery` / `chat-session-*` / `composer-isolation` / `consultation-entrypoint` / `starter-questions` / `chat-navigation-a11y` / `settings-mvp` / `sidebar-contract` / `consultation-birth-time-mode` / `rectification-agentic-entry` / `profile-state` 全绿。
- 全量 `npm test`2428 pass / 0 fail / 0 skipped。
- `./node_modules/.bin/next build --webpack``┌ ○ /` Static。首屏 JS gzip-9 501104 B vs 第一批后 501315 B(−211 B / 0.04%)。
- 行为抽查:无登录态浏览器点选会话 / 发送咨询。由合同测试覆盖抽取正确性;popstate 行为变化已在小刀轮用源码合同锁住。
未改 `.gitea/workflows/**`。未动数据库。未提升 `main`。未重开 React Compiler。
## 明确未做
- onboarding/profile 簇与 rectification 胶水(第三批)。
- 未把 streaming/pending 等 state 下移进 hook(为保住 hook 顺序)。
- 未修任何行为(popstate 已在小刀轮完成)。