文件
hyb-oa/.trellis/tasks/08-08-production-deployment-execution/prd.md
T
wangsli 4596ed0686
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s
规划(08-08-production-deployment-execution): 生产部署执行与验收
2026-08-08 12:01:59 +08:00

10 KiB
原始文件 Blame 文件历史

生产部署执行与验收

Goal

在已完成生产目标与迁移门禁实现的基础上,于明确批准的生产窗口内执行一次可审计的既有部署,验证合同 terminated 三列迁移已经安全落地,并完成部署后只读 readiness 检查。任何门禁失败都必须停止,不得以退出码、部分输出或后续部署结果替代人工核对。

本任务不主动制造真实 terminated 记录,也不执行其他业务写入;它只在生产侧执行获批的迁移/发布动作,并保留足以产出审查的脱敏证据。

Background and Confirmed Facts

  • 生产部署入口是 deploy/trialrun/deploy-existing.sh。它读取受控 systemd deployment contract,固定 SYNC_ENV=0、DEPLOY_DATA_MODE=existing,并在 deploy.sh 前调用生产 target/pre-migration gate,部署后再做 post-status gate。
  • 生产 target gate 必须确认 HTTPS origin、预期 origin、NODE_ENV=production、COOKIE_SECURE=true、数据库名与预期一致,并拒绝回环、本地回归库、staging/trialrun 等身份。生产判据不能复用本地任务“必须是回环地址”的规则。
  • pre-status 的原始 stdout/stderr 只能留在受控执行现场;任务目录和报告只保存脱敏副本、稳定状态码、迁移 ID、计数和证据引用。
  • 候选发布必须是干净、已提交并已进入上游的 commit。当前仓库的远端 origin/main 落后于本地发布线,且严格 wrapper 拒绝未发布提交 override;在候选发布前必须解决发布来源问题。
  • 当前候选迁移为 20260807193000_contract_registry_termination_workspace。部署前须从候选 commit 生成 manifest,并以生产 _prisma_migrations 与 prisma migrate status 原始输出共同核对 pending、failed、rolled-back、unfinished 和 diverged 状态。
  • contract_registry.status = 'terminated' 的第一条已提交记录会关闭回滚窗口。窗口按事件定义,不按发布时间或时间窗口定义;本任务不执行终止写入。
  • 既有生产部署、真实合同写入、企业微信、付款、审批和其他业务数据操作均需受控;本任务明确只授权本节列出的发布迁移和只读验证。

Scope

  1. 在候选发布进入上游且工作区干净后,执行生产 target gate、既有 13 项部署体检、pre-migration status 与 terminated 行数查询。
  2. 在所有 pre-gate 通过且变更冻结成立后,使用唯一获批入口执行既有部署;允许的 schema 写入仅为候选 commit 已声明的 Prisma migration。
  3. 部署后执行 post-migration status、/ready、候选 build SHA、基础/external/runtime smoke、公开 bundle 扫描和权限负向/详情只读检查,并生成脱敏证据包。
  4. 按失败阶段记录 PAUSED、FAIL 或 DEPLOYED_BUT_CONTRACT_REFRESH_FAILED,完成只读 review、收口和归档。

Requirements

R1 发布来源与生产目标

  • 候选 commit 必须干净、已提交、已进入配置的上游远端;严格 wrapper 不接受 DEPLOY_ALLOW_UNPUBLISHED_COMMIT 或 DEPLOY_UNPUBLISHED_REASON。
  • 执行时才提供 EXPECTED_PRODUCTION_ORIGIN、EXPECTED_PRODUCTION_DB_NAME 和 EXPECTED_PENDING_MIGRATIONS;这些值不写入仓库、任务文档或普通日志。
  • target gate 必须验证 origin、数据库身份、运行时 DATABASE_URL host/database、NODE_ENV 和 cookie 安全配置;任何身份不确定均 fail-closed。

R2 pre-status 与回滚窗口先行

  • 在任何 migrate deploy、seed、应用切换或业务写入前,人工阅读 target gate 和 prisma migrate status 原始输出,并核对脱敏副本。
  • pending 集合必须与批准 allowlist 精确一致;未知 migration、failed/rolled-back/unfinished/diverged、不可解释 status 或数据库目标漂移均立即停止。
  • 同一只读阶段查询 terminated 行数:0 记 rollbackWindow=OPEN,大于 0 记 CLOSED。必须在权限负向路径与任何未来真实终止写入前完成。

R3 受控发布

  • 只使用 DEPLOY_SERVER=<受控目标> DEPLOY_REFRESH_SERVER=<受控刷新目标> bash deploy/trialrun/deploy-existing.sh。
  • 保持 SYNC_ENV=0、DEPLOY_DATA_MODE=existing,不得覆盖生产 .env,不得选择其他部署脚本或 SSH 身份。
  • 只有 R1/R2 全部 PASS 且能证明 preflight 到 deploy 期间目标与配置冻结,才允许进入 schema/app 写入阶段。

R4 发布后只读验收

  • post-status 必须显示候选迁移全部 applied / schema up to date;不能只看命令退出码。
  • /ready、完整 build SHA、公开短 SHA、基础 smoke、external/runtime smoke、公开 bundle 扫描和权限负向路径必须与候选 commit 一致。
  • 登录态、企业微信真机、真实 OCR 或其他缺少专用凭据/样本的检查只能记 PAUSED/SKIP,不得伪装成 PASS。

R5 失败与回滚边界

  • target/preflight/status 失败:不部署、不写库,保留现场并返回 PAUSED。
  • migrate deploy/init 中途失败:保留现场,禁止 reset、resolve、drop、手工 DDL 或重复部署,等待明确决策。
  • OPEN 窗口下应用健康失败可按既有合同回退兼容应用但不 drop 三列;CLOSED 窗口下只允许 roll-forward 或兼容 hotfix。
  • refresh 失败标记 DEPLOYED_BUT_CONTRACT_REFRESH_FAILED,不重复发布应用。

Acceptance Criteria

  • AC1:候选 commit 已提交、工作区 clean、已进入上游;来源校验和既有 13 项体检均 PASS。若候选未发布,任务在此处 PAUSED,不使用 override。
  • AC2:target gate 的原始输出在受控现场可供人工阅读,脱敏副本只证明 PASS/FAIL 和原因;HTTPS origin、预期数据库、运行时身份和生产配置全部匹配,未泄露环境值。
  • AC3:任何 schema 写入前完成 pre-status;原始 status 输出与脱敏副本可对账,异常集合为空,pending 与 allowlist 精确一致,terminated 行数和 rollbackWindow=OPEN|CLOSED 判定已记录。
  • AC4:仅在 AC1–AC3 全部 PASS 后调用 deploy-existing.sh;未执行 reset、db push、resolve、手工 DDL、seed 之外的业务写入或真实 terminated 写入。
  • AC5:部署后 status 显示全部候选迁移 applied/schema up to date,/ready、build SHA、smoke、external/runtime smoke、bundle scan 结果与候选 commit 一致。
  • AC6:权限负向路径和合同详情只读检查排在任何真实终止写入之前;缺少凭据项明确标记 PAUSED/SKIP。
  • AC7:结果证据包含候选 commit、target gate、pre/post status 引用、窗口状态、各检查真实数字/输出摘要、失败分流和业务写入计数;不含凭据、原始环境或合同正文。
  • AC8:Trellis task validate、process contract、docs audit、governance、sensitive scan 和 diff check 通过;生产、公网或真机未全通过时,最终答复不得告知“可以测试”。

Out of Scope

  • 不执行真实 terminated 写入、合同编辑/归档/恢复、报销/付款/审批/银行/ERP/企业微信写入。
  • 不执行 prisma migrate dev、migrate reset、db push、migrate resolve、手工 DDL、删除/修改 _prisma_migrations 或自动 drop 新列。
  • 不修改合同业务代码、权限模型、状态机、生产 .env 或应用配置;如发现缺陷,登记后另建 task。
  • 不以本地、staging、trialrun 或临时 runner 代替预期生产目标;不以删除断言、缺失凭据或历史报告冒充通过。
  • 不在本任务内自行 push/发布候选 commit;候选发布需要明确的外部仓库授权(见 Open Questions)。

Accepted Risk and Deferred Items

  • 首条已提交 terminated 记录出现后,旧应用回退窗口永久关闭;本任务只读取并记录窗口状态,不主动关闭它。
  • 生产公网 smoke、企业微信真机、登录态或真实 OCR 可能因专用凭据/样本缺失而 PAUSED/SKIP,不等同于部署通过。
  • preflight 与 deploy 之间无法建立配置/数据库变更冻结时,必须在写入前暂停;post-status 不能事后补救错误目标写入风险。
  • 任何非迁移产品失败不得在本任务内顺手修复,应登记为独立后续任务。

Operational Inputs (not committed)

  • EXPECTED_PRODUCTION_ORIGIN
  • EXPECTED_PRODUCTION_DB_NAME
  • EXPECTED_PENDING_MIGRATIONS
  • 受控 DEPLOY_SERVER、DEPLOY_REFRESH_SERVER、systemd contract 与 live smoke 凭据(如获批提供)

Open Questions

  • 阻塞执行决策:是否批准将本次候选发布线(包含已批准部署 tooling 及本执行 task 的规划提交)发布到配置的上游 origin/main,以满足严格 provenance gate? 当前只读证据显示本地 HEAD 尚未在远端,且 wrapper 明确拒绝未发布 override。推荐发布精确候选 commit;若不批准,任务只能停在 AC1/PAUSED,不能安全进入生产 preflight。

Test Plan

规划/本地

  • node deploy/trialrun/validate-env-contract.js
  • 新增执行 task 后运行 python3 ./.trellis/scripts/task.py validate 08-08-production-deployment-execution
  • node scripts/qa/check-process-contract.mjs --baseline --json
  • node scripts/qa/audit-docs.mjs --check-registry
  • node scripts/qa/check-trellis-governance.mjs --json
  • node scripts/qa/check-sensitive-content.mjs
  • git diff --check

生产执行窗口

  • 先保存 target gate、13 项体检、candidate provenance、pre-status 原始输出(受控现场)及脱敏副本。
  • 核对 migration manifest、_prisma_migrations、pending allowlist、异常集合和 terminated 行数;任一失败即停止。
  • 仅在前置证据全部 PASS 后运行 deploy-existing.sh。
  • 部署后保存 post-status 原始输出及脱敏副本,运行 /ready、build/SHA、基础/external/runtime smoke、bundle scan 和权限负向检查。
  • 失败按阶段分流;不重复部署、不 reset、不 resolve、不 drop。

Evidence Rules

  • 原始 target/status stdout/stderr 只留在受控执行现场;任务 artifacts 只保存脱敏副本、短 ID、计数、状态码和引用。
  • 不记录生产 origin、数据库名、SSH target、用户名、路径、连接串、凭据、业务正文或原始 payload。
  • 报告目录重用时仅清理已知 evidence 文件,不能保留旧 PASS。