# TASK-staging-gate-red-20260923 · staging 门禁自 09-22 起持续变红 ## 基线 commit - 诊断基线:`origin/staging` = `88e89e10`(2026-09-23) - 最后一次部署成功:`1bc6a954`(2026-09-22 01:14)。此后门禁 run 1445(`6d06fca0`)、1448(`3fed71ab`)、2853(`f77a1b5a`)、2854(原 `f968cb21`)、6294(`a12f2c0d`)全部红,**staging 两天没有新部署** - 修复分支:`codex/staging-gate-red-20260923`,从 `origin/staging` 起 ## 事故实证 在 `88e89e10` 上用 Node 22(与门禁同版本)逐文件重跑本机与基线共有的前端失败。分成两类: ### A · 代码或合同真问题(3 条,本单修) 每一条都在引入提交的父提交上通过、在引入提交上失败,逐条复现: | 测试 | 父提交 | 引入提交 | 失败内容 | |---|---|---|---| | `viewport-breakpoint-contract.test.ts` · CSS width breakpoints stay on the published allowlist | `92e79642` 通过 | `45ec4617`(首页入口边框变轻)失败 | `globals.css` 新增 `@media (max-width: 375px)`,375 不在白名单 `480 / 640 / 641 / 767 / 768 / 860 / 1023 / 1024` | | `chat-panel-scroll-guard.test.ts` · the guard covers every component that renders inside the panel today | `6d06fca0` 通过 | `2a3013f2`(BUG-1000 聊天人物选择)失败 | `chat-profile-picker.tsx` 两处 `triggerRef.current?.focus()` 没带 `{ preventScroll: true }`,关闭选择器时会滚动聊天面板 | | `chat-composer-queue.test.ts` · generating does not disable the textarea | `6d06fca0` 通过 | `2a3013f2` 失败 | `(app)/page.tsx` 的 `inputDisabled` 前面多了 `subjectDeleted \|\|`(资料已删除的旧会话阻断发送,BUG-1000 的设计),源码合同的正则没跟上 | 第三条是**合同滞后,不是行为错误**:它要守的性质——生成中不得禁用输入框(`inputDisabled` 里不能有 `isLoading`)——仍然成立。 ### B · 本机缺工具,门禁环境有(本单不修,但要在门禁上确认) | 测试 | 本机报错 | 判断 | |---|---|---| | `health-deployment` 1 条 | 子进程 status `null`(`spawnSync docker`) | 本机无 Docker | | `staging-backend-workflows` 2 条 | `rsync: command not found` | 本机无 rsync | | `model-configuration-security`、`identity-auth-integration`、`admin-database` 各 1 条,以及全部 `database-*.test.ts` | `spawnSync docker ENOENT` | 本机无 Docker | 诊断方看不到门禁日志(Gitea job 日志需要 token,不借用)。**B 类在门禁上是否通过,本单执行方必须读门禁日志确认**,不得据本机推断。其中 `database-personal-report-sections.test.ts` 已知会在门禁上失败,见 BUG-1011 与 `TASK-report-density-fix2-20260923.md`,不在本单。 ## 根因 1. 两次 09-22 的提交(`45ec4617`、`2a3013f2`)落 staging 时门禁已经是红的(BUG-1002 那一组),新增的失败被原有红色淹没,没人逐条比对。 2. `45ec4617` 按"新切点必须先改白名单"本应先过 `viewport-breakpoint-contract`,但直接加了 375。 3. `2a3013f2` 新组件渲染在聊天面板里,没有按 `chat-panel-scroll-guard` 的规则给 `focus()` 带 `preventScroll`;同一提交改了 `inputDisabled` 却没更新源码合同。 ## 决策记录 - **375 断点并入既有 480 断点,不扩白名单。** 依据 BUG-697 的收敛口径(宁可合并,不新增切点)。那条规则只把入口按钮行与按钮限制为 `max-width: 100%`,放到 ≤480 时,376–480px 宽度下只会防止溢出、不会改变不溢出时的样子。`globals.css` 里 `.starter-entry` 附近已经有一个**空的** `@media (max-width: 480px) {}`,放进去即可。这是 Claude 的常规判断;若执行方实测发现 376–480 出现可见变化,停下来报告,不要改成扩白名单。 - **选择器的 `focus()` 一律带 `{ preventScroll: true }`。** 触发按钮在顶栏,本来就在视口里,`preventScroll` 不改变焦点落点,只阻止面板被滚动。 - **更新 `chat-composer-queue` 的源码合同**,把 `subjectDeleted ||` 写进期望,并按 AGENTS.md §7.3 写三栏说明。同时新增一条断言:`inputDisabled` 表达式里不含 `isLoading` 与 `cancellationPending`,让真正要守的性质不依赖整串正则。 ## 硬红线 1. 不得删测试、跳过测试或把失败测试标 skip;不得放宽 `viewport-breakpoint-contract` 白名单;不得给 `chat-panel-scroll-guard` 加豁免。 2. 不得改 `(app)/page.tsx` 的逻辑,本单只改测试合同;`Home()` 的 `useState` / `useRef` 数不得变。 3. 不得改 `.gitea/workflows/**`,不得为了过门禁在门禁里跳步骤。 4. 不得动 `tests/helpers/postgres-fixture.ts`(属于 `TASK-report-density-fix2-20260923.md`)。 5. 测试总数不得低于开工时 `origin/staging` 的实测。 ## 任务分解 ### H1 · 375 断点并入 480(BUG-1012) 把 `@media (max-width: 375px)` 里的两条规则移进 `.starter-entry` 附近那个空的 `@media (max-width: 480px)`,删掉 375 块。改 UI 的同一提交更新 `frontend/DESIGN.md`。 **验收标准**:`viewport-breakpoint-contract.test.ts` 全过;`globals.css` 中不再有 375 的宽度断点;在 360 / 375 / 390 / 414 / 480 五个宽度下首页入口按钮不溢出(本机 Chrome 无头截图或 `docs/testing/` 清单一条)。 ### H2 · 人物选择器不滚动面板(BUG-1013) `chat-profile-picker.tsx` 的两处 `triggerRef.current?.focus()` 改为 `focus({ preventScroll: true })`。 **验收标准**:`chat-panel-scroll-guard.test.ts` 全过;选择器关闭后焦点仍回到触发按钮(新增或已有测试覆盖)。 ### H3 · 输入框合同跟上 BUG-1000(BUG-1014) 更新 `chat-composer-queue.test.ts` 对 `inputDisabled` 的期望,加三栏说明;新增"表达式不含 `isLoading` / `cancellationPending`"断言。 **验收标准**:该文件全过;把 `isLoading ||` 临时加进 `inputDisabled` 时新断言变红(变异验证写进进度记录)。 ### H4 · 门禁确认(对应 B 类) 修完后推 staging,读门禁 run 日志,把失败测试名单(如有)逐条列进进度记录,并与本单 B 类及 BUG-1011 对照。 **验收标准**:门禁 run 除 BUG-1011 那一条外无失败;若还有别的失败,列出 run 编号与测试名,写成新的 investigating 记录,不得声称门禁已绿。 ### H5 · 记录 `docs/BUG_HISTORY.md` 写 BUG-1012~1014,关联 BUG-1000、BUG-1002、BUG-697;`docs/tasks/PROGRESS-staging-gate-red-20260923.md` 写三栏说明与门禁证据。 ## 让步顺序 H1、H2、H3 都很小,必须一起做;H4 在推送后做;H5 同一提交。 ## 与其他单的关系 与 `TASK-report-density-fix2-20260923.md`(BUG-1011)文件不重叠,可以并行。两单都合入后门禁才可能全绿。 ## 开工前置命令 ```bash git fetch origin --prune git status -sb git worktree add -b codex/staging-gate-red-20260923 .worktrees/staging-gate-red-20260923 origin/staging # 前端测试用 Node 22;本机 Node 20 下有一批子进程 @/ 别名解析失败的误红 ``` ## BUG 编号 BUG-1012~1014。开工时核对 `docs/BUG_HISTORY.md` 最大号(当前 1011)。