修复(08-08-production-deployment-execution): 持久化远端部署阶段日志
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s

这个提交包含在:
2026-08-08 21:29:55 +08:00
父节点 b94afcfab0
当前提交 0224ad83d7
共修改 6 个文件,包含 110 行新增和 3 行删除
@@ -165,3 +165,17 @@
- termination migration 尚未应用时,终止能力不可能由本轮应用生效;helper 现以 `_prisma_migrations` applied set 走显式分支,不发送 `contract_registry` 状态查询,固定输出 `rollbackWindow=OPEN terminatedRows=0 basis=migration_not_applied`。
- migration 已应用时继续执行真实 `status = 'terminated'` 计数,输出 `basis=terminated_status_count`;查询失败或结果不可解析分别返回固定错误,不使用 catch/default 把未知状态误报为 OPEN。
- 聚焦 fixture 覆盖:未应用且状态查询被设置为必失败仍应 OPEN(证明未查询)、已应用 0 行 OPEN、已应用 2 行 CLOSED,以及已应用查询失败必须 `PROD_TERMINATED_COUNT_UNAVAILABLE`。聚焦测试 19/19 PASS。
## First Production Deployment Attempt Evidence (2026-08-08)
- 窗口依据修复提交 `b94afcf` 已进入 `origin/main`;发布前 preflight 再次通过:精确身份组、13 项聚合体检、数据库三方身份、唯一 pending allowlist 和 `rollbackWindow=OPEN ... basis=migration_not_applied` 全部 PASS。
- 唯一生产入口随后完成已验证源码同步并进入远端 `build init`;编排进程在该长阶段退出,未到 `run init`。代码顺序固定为先 `build init`、后 `prisma:migrate:deploy`,只读复核同时证明 termination migration 仍 pending、公开 `/ready` 仍为旧 build、新 init 镜像仍为旧 build,故 schema 写入和应用切换均为 0。
- 同一候选在本地 `client` typecheck/build PASS;远端当时仍有可用磁盘和内存,未取得明确 OOM 证据,不能把环境猜测写成根因。原裸调用只把输出写入 SSH 流,通道证据不完整,未能恢复真实末尾错误。
- 失败后未重试部署、未运行 reset/resolve/drop、未改生产配置。额外只读检查确认现有 13 项合同仍健康、回滚窗口仍 OPEN;用户随后只批准一次在远端持久化日志机制落地后的受控重试。
## Persistent Remote Stage Log Repair Evidence (2026-08-08)
- `deploy.sh` 为 `build-init`、`run-init` 和 `build-switch-server` 三个长阶段统一增加远端日志包装器;完整 stdout/stderr 直接写入仓库相对 `artifacts/deployment-runtime/`,目录 `0700`、文件 `0600`,文件名只含固定阶段名和已验证候选 12 位 SHA。
- 普通输出仅记录 stage、真实 child exit code 和相对 `logRef`。失败状态在 Bash `else` 分支中立即捕获并返回,随后由 `set -e` 停止,不会因 `fi` 后读取 `$?` 而丢失原码。
- 原始 build/init 日志不写入 Git、task 或普通对话;若受控重试失败,先只读取对应远端日志尾部并脱敏定性,再决定后续动作。任何下一次 rsync 可能清除旧 runtime artifacts,因此读取必须发生在重试之前。
- 聚焦静态回归证明三个裸调用均已替换、重定向和权限合同存在、失败分支立即捕获退出码;shell syntax、env contract 与部署安全测试 PASS。