Files
Jyotisha/docs/tasks/TASK-staging-gate-fix-20260924.md
T

6.6 KiB
Raw Blame History

TASK · 修复单:慢网首页 5 条测试未跟上致门禁红 + page.tsx 增长 + 原始附录残留(2026-09-24)

基线与现状

  • origin/staging = f125fae0。staging 线上仍是 1420471a:0e4dd0f4(慢网首页)之后的所有代码提交都没部署,包括 BUG-1020(fa8fef55/133aca49)与报告操作收敛(f125fae0)。
  • Claude 09-24 在 Linux / Node 20 独立验收(基线 edc9c22c vs f125fae0):tsc 0;lint 0 error(warning 119 → 121);next build 四路由标记与 gzip 130,932 B 与基线一致;全量 3807 → 3809 条,失败 56 → 61,新增 5 条红(下表),其余失败名单与基线逐条相同。门禁会跑同一套前端测试,因此判断门禁红、未发布镜像(Gitea API 匿名 401,run 号请产品在 Gitea 核对)。
  • 执行方 PROGRESS 记录了 npm test 89 条失败,但没有与基线逐条比对,新增的 5 条混在 Windows 环境失败里没被发现;BUG-1021/1022 被提前写成 resolved。
  • 分支 codex/staging-gate-fix-20260924。

新增 5 条失败(全部是源码合同断言没跟上实现,不是行为回归)

测试 文件 原因
auth redirects stay hard document loads so stale session state cannot survive tests/chat-navigation-a11y-contract.test.ts 断言 page.tsx 中 window.location 硬跳转共 4 处,实现把「重试」从 location.reload() 改成局部重试(任务书 D2),现为 3 处
bootstrap failure retries with a hard reload because refresh cannot rerun client bootstrap 同上 正则 onClick={() => window.location.reload()}>重试</button>;任务书 D2 有意推翻了该断言的前提(局部重试已能重跑 bootstrap)
new chat keeps its local landing while a reserved older consultation recovers tests/new-chat-recovery.test.ts 按字符串切 page.tsx 源码,结束边界 if (modelCatalogResult.unavailable) 已被删除 → missing source boundary(我在 BUG-1015 验收时标注过的 P2 脆弱点,这次触发)
ordinary home landing still activates and announces the reserved consultation 同上 同上
tab-local pending ids drive strict bootstrap recovery before the global fallback tests/consultation-recovery.test.ts 切片起点 `let reservedConsultation: ConsultationStatus

同类问题第五次(BUG-933/934/939/992 同型):执行方只跑定向测试,没跑全量并与基线逐条比对。

其它验收问题

  1. P2 红线违反:page.tsx 1849 → 1858 行(+9),任务书红线 4「page.tsx 不得净增行」。主要来自「重试」内联的 5 行状态重置。
  2. P2 行为:use-billing-panel.ts 支付轮询成功后改为 if (typeof payload.credits === "number") notifyBalanceChanged(payload.credits);/api/payment/epay/status 的 credits 是订单点数,订阅类订单可能为空 → 不发余额事件 → 首页账户不刷新。page.tsx 的 BALANCE_CHANGED_EVENT 监听只调 refreshAccount()、不读传入值,所以应无条件通知。
  3. 报告操作收敛残留(f125fae0 执行方删除权限被拒):raw-appendix-download.tsx、app/api/reports/[reportId]/raw-appendix/route.ts、lib/personal-report-raw-appendix.ts 已无入口但仍在;执行方也没能写 PROGRESS 与真机清单(工具拒绝写入)。
  4. 代码本身(慢网并行、20 秒错误屏、局部重试、不再半揭幕、账单预取与缓存、CRLF 正则)我逐行核对符合任务书,不需要改逻辑。

决策记录

  • 本单只修测试与收尾,不改任务书已批准的行为(D2 局部重试、并行预取、20 秒阈值)。
  • 5 条断言按新行为改写,不得删除测试;new-chat-recovery 与 consultation-recovery 的源码切片改为不依赖会被删改的具体语句作边界:优先把被测逻辑抽到 frontend/src/lib/ 纯函数直接调用;做不到时用稳定的注释锚点(如 // bootstrap:recovery-begin / // bootstrap:recovery-end)并在两处测试共用。
  • chat-navigation-a11y-contract:硬跳转计数改为 3,并新增断言「重试」调用 reloadSessionList 且不含 location.reload(行为锁,不是弱化)。
  • 原始附录三件套连同只测它们的测试一并删除(任务书 D2 已授权);personal-report-raw-appendix.test.ts 中仍有价值的投影断言若依赖 cleanReaderAppendixMarkdown,保留该 helper 所在模块,只删路由 / 组件 / release 函数。

硬红线

  1. 失败清单必须与基线 edc9c22c 逐条一致(56 条),新增 0;进度记录附对比命令与结果。
  2. 每条改动的断言写「原值 / 新值 / 原因」三栏;测试总数不低于 3809 − 被删文件的测试数,并列出删了哪些。
  3. page.tsx 行数 ≤ 1849(edc9c22c 基线);Home() 不新增 hook。
  4. 不改首页 / 账单 / 报告的已验收行为;不改数据库、workflow。

任务分解

  • T1 修 5 条断言(抽纯函数或注释锚点)。验收:5 条转绿,grep -n "modelCatalogResult.unavailable" frontend/tests = 0。
  • T2 page.tsx 回到 ≤ 1849 行:重试处理抽到 frontend/src/lib/ 或现有 hook。
  • T3 支付成功无条件 notifyBalanceChanged。验收:billing-panel.test.ts 新增订阅订单(credits 缺失)也触发余额事件。
  • T4 删除原始附录三件套与相关测试。验收:git grep -n "raw-appendix\|RawAppendixDownload\|releaseRawReportAppendix" frontend/src = 0。
  • T5 记录:BUG_HISTORY 中 BUG-1021/1022 状态保持 investigating 直到部署 health 核对;补 docs/tasks/PROGRESS-report-reader-actions-20260924.md 与 docs/testing/report-reader-actions-20260924.md(上一执行方未能写入);本单 PROGRESS。推 staging 后核对门禁绿与 /api/health 的 gitCommit。

开工前置命令

git fetch origin --prune
git worktree add -b codex/staging-gate-fix-20260924 .worktrees/staging-gate-fix-20260924 origin/staging
git worktree add --detach .worktrees/gate-baseline-20260924 edc9c22c   # 基线
cd .worktrees/gate-baseline-20260924/frontend && npm test > /tmp/base.log 2>&1
cd ../../staging-gate-fix-20260924/frontend && npm test > /tmp/head.log 2>&1
diff <(grep '^not ok' /tmp/base.log | sed 's/^not ok [0-9]* - //;s/ # .*//' | sort) \
     <(grep '^not ok' /tmp/head.log | sed 's/^not ok [0-9]* - //;s/ # .*//' | sort)

BUG 编号

不新开号;沿用 BUG-1021 / 1022(首页 / 账单)与报告操作收敛的产品变更记录。