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

5.4 KiB
Raw Blame History

任务书 · 小刀轮:孤儿契约红修复 + 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_endpointP2a 起)。它按 function toggleArchivedSessionasync 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.pyCORE_PYTEST_TARGETS,所以 CI 从不运行——又是"没人跑的契约测试"(同类问题上轮刚在 test_supabase_user_data_contract.py 处理过一次)。
  4. popstate 回默认态副作用缺失P1 验收记录的遗留)。page.tsxapplySessionPopStateRefif (!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_TARGETStest_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. 前端测试总数不低于 2427Docker 环境 fail=0、skipped=0;无 Docker 既有缺口 24+10,清单与 54269fcf 一致逐条比对)。Python 侧:两个目标文件修复后全文件 pytest 输出附进 PROGRESS。
  5. 不改 .gitea/workflows/**(白名单在 scripts/run_quality_gate.py)。next build/○ Static。不动数据库。
  6. 不在脏工作树切分支。不自行提升 main。

让步顺序:性质不丢失 > 功能与测试不回归 > 代码整洁。

开工前置

git fetch origin --prune
git worktree add -b codex/contract-repairs-20260901 \
  ../.worktrees/contract-repairs-20260901 origin/staging

pre_work_error_ledger.mdscripts/pre_work_check.pyfrontend/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 列出全部断言改动的原值/新值与白名单决定。