Merge remote-tracking branch 'origin/main' into fix/staging-gate-retry-and-admin-audit
Staging Backend Quality Gate / validate (pull_request) Successful in 14m24s
Staging Backend Quality Gate / publish (pull_request) Has been skipped

# Conflicts:
#	docs/BUG_HISTORY.md
#	frontend/tests/admin-users-contract.test.ts
This commit is contained in:
Jesse
2026-08-06 22:11:41 +08:00
3 changed files with 24 additions and 2 deletions
+17 -1
View File
@@ -2299,8 +2299,24 @@
- 触发条件:legacy `/api/admin/users` Route Handler 通过 `export { ..., runtime } from "../customers/route"` 同时重导出 handlers 和 route segment config。
- 根因:Next.js 要求 `runtime` 等 route segment config 在当前 route 文件中可被静态解析,不允许从另一 Route Handler 重导出;既有精确合同测试反而固化了非法 re-export,且并发功能本地 production build 未闭环。
- 修复:在 users route 本文件静态声明 `export const runtime = "nodejs"`,只重导出 DELETE/GET/PATCH/POST/PUT handlers;不复制 handler、不修改权限或客户数据逻辑。合同测试改为强制本地 runtime 常量并拒绝 runtime re-export。
- 验证:admin users 目标合同、Next production build、完整 Gitea PR gate 和 staging gate完成前不得标记 resolved。
- 验证:admin users 目标合同、`tsc --noEmit`、默认 Turbopack `next build``next build --webpack`、全 route segment config re-export 扫描与 `git diff --check` 已通过;Gitea PR gate `1499` 在 SHA `015f1e501e2132d2abc6bbbcb8e6af074c326b47` 上通过并完成 production build。待最新并发主线 staging gate 与部署验收,完成前不得标记 resolved。
- 防复发:Route Handler 的 `runtime``dynamic``revalidate` 等 segment config 必须本地静态声明;handler 可复用,但 segment config 不得 re-export。新增 alias route 必须经过 production build,而不只运行文本合同测试。
- 相关记录:BUG-131、BUG-132
- 复发自:无
- 修复版本:待 Route Handler 静态 config 修复与 staging 验收
## BUG-134 | staging admin origin selector 未配置导致 exact-SHA 自动部署失败
- 状态:investigating
- 首次发现:2026-08-06
- 最近更新:2026-08-06
- 影响面:staging `.env.staging` 的公开 identity selector、自动 deploy run `1502`;应用容器、业务数据库和 production 未被修改。
- 用户现象:staging gate `1500` 已成功验证并发布 SHA `9a3d0d440f43deab66c1f8a4a08cdbfc6f9d73eb` 的 immutable artifact,但自动 deploy `1502` 在远端 env 校验时报 `invalid staging selector: ADMIN_USER_ORIGIN` 并 fail closed;公网继续健康运行旧 SHA `e59f15d352787f3d05425ba8c459d092e9801a20`
- 触发条件:包含双 host self-hosted identity validator 的 controller 部署到现有 staging host,而 `.env.staging` 尚未包含精确且唯一的 `ADMIN_USER_ORIGIN=https://admin.staging.jyotisha.chat`
- 根因:并发 admin rollout 将 admin host origin 加入应用和 validator 合同,但 staging host-managed env 未在发布前同步新增的非密钥 selectorquality gate 验证仓库合同,不读取主机 secret/env,因此直到 mutation 前远端校验才暴露漂移。
- 修复:待在共享 staging mutation lock 下,仅向原文件原子补入公开 `ADMIN_USER_ORIGIN` selector,保留全部既有内容、`deploy:deploy` owner 和 `0600` mode;不得输出、复制或重写其他 secret 值。随后用 exact-SHA gate artifact 重新部署。
- 验证:脱敏只读检查已确认 `.env.staging``deploy:deploy 0600``AUTH_USER_ORIGIN` 精确且唯一、`ADMIN_USER_ORIGIN` 计数为 0;待 selector validator、最新 staging gate、exact-SHA deploy、公网/host SHA、容器 restart、日志和未登录边界验收。
- 防复发:任何新增 staging host-managed selector 必须在同一 rollout runbook 中包含 deploy 前 presence/exact-value 检查;quality gate 成功不能替代 host env validation。env 修复必须共享 mutation lock、原子替换并保持 owner/mode,严禁打印 raw env。
- 相关记录:BUG-128、BUG-133、ERR-093、ERR-097
- 复发自:无
- 修复版本:待 staging env selector 对齐与 exact-SHA 部署验收
+6
View File
@@ -157,6 +157,12 @@ Staging gate `1485` failed before validation when its single exact-SHA shallow f
Prevention: both validate and publish exact-SHA checkouts use three bounded 300-second attempts, a 15-second connect timeout, and a 60-second/1-B/s stalled-transfer threshold. Preserve `--depth=1 --no-tags origin "$GITEA_SHA"`, exact HEAD equality, clean-tree checks, artifact non-reuse, and fail-closed exhaustion. Never report a skipped publish job as successful artifact publication.
## ERR-097 | Staging host env missed the reviewed admin-origin selector | investigating 2026-08-06
Staging gate `1500` successfully validated and published the exact SHA, but automatic deploy `1502` stopped before app mutation with `invalid staging selector: ADMIN_USER_ORIGIN`. A redacted read-only check confirmed `.env.staging` remained `deploy:deploy 0600`, had one exact user origin, and had zero admin-origin definitions. Public staging therefore remained on the prior healthy SHA; this was not a migration failure and production was not involved.
Prevention: when a reviewed identity rollout adds a host-managed non-secret selector, update the staging env under the shared mutation lock before deploying the dependent controller. Modify only the named public selector through a mode-`0600` atomic replacement that preserves deployment-tree UID/GID; never print or copy the raw env. Re-run the exact validator and require the same gate-attested SHA in `main`, `staging`, host state, and public health before closure.
## Fragment Sweep Command Set
## ERR-086 | Steve Jobs jyotishganit artifacts used non-San-Francisco coordinates | mitigated 2026-07-21
+1 -1
View File
@@ -41,5 +41,5 @@ test("admin_users migration is service-role-only and auditable", () => {
test("legacy admin users route aliases handlers but declares runtime statically", () => {
assert.match(usersSource, /export const runtime = "nodejs"/);
assert.match(usersSource, /export \{ DELETE, GET, PATCH, POST, PUT \} from "\.\.\/customers\/route"/);
assert.doesNotMatch(usersSource, /export \{[^}]*runtime[^}]*\} from/);
assert.doesNotMatch(usersSource, /export \{[^}]*\bruntime\b[^}]*\} from/);
});