Files
Jyotisha/TASK-contract-repairs-20260901.md
T
Jesse_Chen a6148af845
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
docs(chat): add contract-repairs and home-split batch-two task briefs
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVapmh2oGNyr6ECHKjPJY8
2026-09-01 15:08:26 +00:00

64 lines
5.4 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.
# 任务书 · 小刀轮:孤儿契约红修复 + popstate 副作用对齐(2026-09-01
基线:`origin/staging` @ `54269fcf`(开工时以 `origin/staging` 最新为准)。**本轮必须先于 `TASK-home-split-batch2-20260901.md` 执行**——第二批会再次搬动本轮涉及的函数,顺序反了会白修一遍。与其它改 `page.tsx` 的轮次不得并行。
这是一轮小刀:三个任务互相独立、单个都很小,但每个都有明确的性质要保住。
---
## 为什么要做(事故实证)
1. **`tests/test_session_management_entrypoints.py::test_archiving_never_calls_the_delete_endpoint` 红**P2a 起)。它按 `function toggleArchivedSession``async function shareSession` 切片,断言切片含 `setArchivedSessionIds` 且不含 `/api/sessions/`。P2a 后归档改走 PATCH `archived_at`:旧符号没了,而且切片里**合法地**出现了对 `/api/sessions/[id]` 的 PATCH。断言锁的形而不是质。它锁的真正性质——**归档动作绝不能变成删除**——是数据安全级的,值得进 gate。
2. **`tests/test_birth_time_journey_contract.py::test_web_onboarding_uses_the_deterministic_free_journey` 红**(更早轮次起)。`assert 'entry_mode: entryMode' in mastra` 的源码 token 已过期;配套的反向断言 `'entry_mode: "direct_chart"' not in mastra` 仍成立。性质——**引导旅程透传入口模式、不硬编码 direct_chart**——还在,表达式变了。
3. 两条都不在 `scripts/run_quality_gate.py``CORE_PYTEST_TARGETS`,所以 CI 从不运行——又是"没人跑的契约测试"(同类问题上轮刚在 `test_supabase_user_data_contract.py` 处理过一次)。
4. **popstate 回默认态副作用缺失**P1 验收记录的遗留)。`page.tsx``applySessionPopStateRef``if (!requestedId) { setActiveSessionId(""); return; }` 分支:用 back 键回到无 `?c=` 的默认态时,只重置了选中会话,**没有**走 `selectSession` 的清草稿、清提示、切换绑定星盘等副作用——和用户在侧栏点击同一会话的行为不一致。
## 决策记录(产品授权,2026-09-01)
1. **任务 3 是行为变化**(三个搬家轮里唯一授权的一处):back 键回默认态时执行与主动点击选择相同的副作用。`chat-session-url.test.ts` 中锁旧行为的断言按例外条款修改。
2. `test_session_management_entrypoints.py` 修复后**加入** `CORE_PYTEST_TARGETS``test_birth_time_journey_contract.py` 修复后**评估**加入:整文件在纯源码/SQL 正则内且无重依赖则加入;有运行时依赖导致 gate 环境跑不了,则不加入并在 PROGRESS 写明依赖是什么。
3. 修断言的方向一律是**对齐现状、保住性质**:归档测试改为断言切片走 `archived_at` 的 PATCH 且不含 `"DELETE"` 方法(token 由执行方按现码确定);journey 测试找到现码里透传入口模式的等价表达式,正负两条断言都保留。**不得删除检查了事。**
4. 修好的两个测试文件的读取面要**经得起第二批搬家**:涉及 `page.tsx` 函数切片的断言,改用上轮 `_home_surface()` 式的拼接读取(`page.tsx` + 已抽出文件),切片标记若在第二批要搬的函数上,选择对搬家稳健的定位方式。
## 硬红线
1. 不得修改本任务书范围外的任何测试断言;范围内的修改逐条在 PROGRESS 注明原值与新值。
2. 任务 3 之外不得有任何行为变化;popstate 修改不得引入二次 pushState(P1 的防翻倍合同测试必须保持绿灯)。
3. 推 staging 前 `./node_modules/.bin/tsc --noEmit` 通过(不要 `npx tsc`)。
4. 前端测试总数不低于 **2427**Docker 环境 fail=0、skipped=0;无 Docker 既有缺口 24+10,清单与 `54269fcf` 一致逐条比对)。Python 侧:两个目标文件修复后全文件 pytest 输出附进 PROGRESS。
5. 不改 `.gitea/workflows/**`(白名单在 `scripts/run_quality_gate.py`)。`next build``/``○ Static`。不动数据库。
6. 不在脏工作树切分支。不自行提升 main。
让步顺序:性质不丢失 > 功能与测试不回归 > 代码整洁。
## 开工前置
```bash
git fetch origin --prune
git worktree add -b codex/contract-repairs-20260901 \
../.worktrees/contract-repairs-20260901 origin/staging
```
`pre_work_error_ledger.md``scripts/pre_work_check.py``frontend/AGENTS.md`。参考上轮 `PROGRESS-home-split-20260901.md` 的任务 0 —— 同类修复的完整样板。
## 任务分解
### 任务 1 · 归档契约修复入 gate
-`test_archiving_never_calls_the_delete_endpoint`(决策记录 3/4 的方向),全文件跑绿。
- 加入 `CORE_PYTEST_TARGETS`,注释说明它锁"归档绝不删除"。
### 任务 2 · 引导旅程契约修复
-`test_web_onboarding_uses_the_deterministic_free_journey`,全文件跑绿。
- 按决策记录 2 评估白名单。
### 任务 3 · popstate 副作用对齐
- `applySessionPopStateRef` 的无参数分支:有可选会话时经与主动选择一致的路径切换(不 push,来源标志保持 history 语义);无会话时维持现状。
- `chat-session-url.test.ts` 相应断言按例外条款更新,并补一条锁新行为的断言。
## 总验收
`tsc` 通过;前端测试满足红线 4 并附失败清单比对;两个 Python 文件 pytest 全绿输出;`/` 仍 StaticPROGRESS 列出全部断言改动的原值/新值与白名单决定。