修复(08-08-production-deployment-execution): 保留生产预检真实错误码
这个提交包含在:
@@ -1553,14 +1553,16 @@ DEPLOY_SERVER=<approved-ssh-target> \
|
||||
- Local orchestrator: `deploy/trialrun/production-preflight.mjs`.
|
||||
- Remote read-only helper: `deploy/trialrun/production-preflight-remote.sh`.
|
||||
- Required process inputs: `EXPECTED_PRODUCTION_ORIGIN`,
|
||||
`EXPECTED_PRODUCTION_DB_NAME`, and `EXPECTED_PENDING_MIGRATIONS`.
|
||||
`EXPECTED_PRODUCTION_DB_NAME_SHA256`, `EXPECTED_PENDING_MIGRATIONS`, and the
|
||||
exact deployment target/directory/Compose identity values.
|
||||
|
||||
### 3. Contracts
|
||||
|
||||
- Production R2 is the inverse of the local migration task: the gate must prove
|
||||
the target is the expected production HTTPS origin and database identity, and
|
||||
reject loopback, local regression, staging and trialrun identities. It must
|
||||
never infer production from an SSH alias, Compose label or directory name.
|
||||
reject loopback, local regression, staging, shadow and placeholder identities.
|
||||
A legacy `trialrun` token is neutral; the gate must never infer production or
|
||||
non-production from an SSH alias, Compose label or directory name alone.
|
||||
- The strict production-validation wrapper rejects unpublished-commit overrides;
|
||||
disaster-recovery exceptions use a separately approved recovery flow.
|
||||
- Expected target values remain process-only. The local orchestrator sends only
|
||||
@@ -1583,6 +1585,12 @@ DEPLOY_SERVER=<approved-ssh-target> \
|
||||
insufficient.
|
||||
- Each preflight run removes only its two known report files before SSH; a
|
||||
reused report directory must never leave an old PASS status artifact in place.
|
||||
- After the stable remote summary and report reference are emitted, a non-zero
|
||||
remote exit is evaluated before Prisma marker completeness. A parsed remote
|
||||
`code=...` remains the primary stop reason; a non-zero exit without a safe
|
||||
code becomes `PRODUCTION_PREFLIGHT_REMOTE_FAILED`. Only a zero remote exit
|
||||
without the required marker becomes `PRISMA_STATUS_OUTPUT_MISSING`. This
|
||||
ordering preserves both the original safety diagnosis and failure evidence.
|
||||
- When the strict wrapper invokes `deploy.sh`, it sets
|
||||
`DEPLOY_STATUS_OUTPUT_MODE=quiet`; the legacy status check must not echo raw
|
||||
datasource output. Detailed evidence comes from the controlled pre/post
|
||||
@@ -1603,12 +1611,28 @@ DEPLOY_SERVER=<approved-ssh-target> \
|
||||
before `deploy.sh`.
|
||||
- Status output missing/unreadable, failed/rolled-back/diverged history or an
|
||||
unknown pending migration -> `PAUSED`; do not reset or resolve in place.
|
||||
- Non-zero remote exit with a safe `code=...`, with or without a Prisma marker
|
||||
-> propagate that code and stop. Non-zero exit without a parseable code ->
|
||||
`PRODUCTION_PREFLIGHT_REMOTE_FAILED`; never continue to marker validation.
|
||||
- Zero remote exit without the Prisma marker ->
|
||||
`PRISMA_STATUS_OUTPUT_MISSING`; do not treat the transport success as a
|
||||
complete pre-status result.
|
||||
- Pending set differs from the approved allowlist -> `PAUSED` and retain the
|
||||
status artifact for human review.
|
||||
- `terminated` count greater than zero -> record `rollbackWindow=CLOSED` and
|
||||
disallow compatibility rollback; this task never creates such a row.
|
||||
|
||||
### 5. Tests Required
|
||||
### 5. Good/Base/Bad Cases
|
||||
|
||||
- Good: the remote helper exits non-zero with a stable database-identity code;
|
||||
the wrapper writes the stable evidence summary, returns that exact code and
|
||||
stops before migration or deployment.
|
||||
- Base: the remote helper exits zero with a readable Prisma marker and the
|
||||
wrapper continues into migration reconciliation.
|
||||
- Bad: check for a missing marker before checking the remote exit and replace
|
||||
the real remote safety code with `PRISMA_STATUS_OUTPUT_MISSING`.
|
||||
|
||||
### 6. Tests Required
|
||||
|
||||
- `node --check deploy/trialrun/production-preflight.mjs`.
|
||||
- `bash -n deploy/trialrun/production-preflight-remote.sh`.
|
||||
@@ -1617,6 +1641,26 @@ DEPLOY_SERVER=<approved-ssh-target> \
|
||||
- Static ordering must prove production preflight precedes `deploy.sh`, and the
|
||||
remote status marker precedes migration-history reconciliation. Fixtures must
|
||||
reject loopback/staging target identities without invoking SSH.
|
||||
- Cover all remote-result precedence combinations: non-zero with a safe code
|
||||
and missing marker; non-zero with a safe code and present marker; non-zero
|
||||
without a safe code; zero with a missing marker. Also assert the stable
|
||||
summary and report reference are emitted before either failure check.
|
||||
|
||||
### 7. Wrong vs Correct
|
||||
|
||||
#### Wrong
|
||||
|
||||
```text
|
||||
missing Prisma marker -> PRISMA_STATUS_OUTPUT_MISSING
|
||||
-> inspect remote non-zero exit afterward
|
||||
```
|
||||
|
||||
#### Correct
|
||||
|
||||
```text
|
||||
write stable evidence -> inspect remote non-zero exit and propagate/fallback
|
||||
-> only after remote success require the Prisma marker
|
||||
```
|
||||
|
||||
## Scenario: Environment Recovery Classification And Secret Custody
|
||||
|
||||
|
||||
@@ -128,3 +128,11 @@
|
||||
- DB hash 引导成功只证明远端 `.env` 数据库名已形成比较基线,不证明后续 `.env` / `current_database()` / runtime `DATABASE_URL` 三方一致性;远端 preflight 未输出 `target_identity_and_database_identity` PASS,故该验收项保持未通过。
|
||||
- 未获得 migration reconciliation、pending allowlist 对账或 `terminated` count;rollback window 仍为 `UNKNOWN`,不得写作 OPEN/CLOSED。
|
||||
- `PRODUCTION_READ_ONLY_PREFLIGHT=1` 未进入 `deploy.sh`;未执行 rsync、`migrate deploy`、应用切换、contract refresh 或业务 API,生产 schema 写入与业务写入均为 0。失败后未重跑、未跳过门禁。
|
||||
|
||||
## Pre-status Diagnostic Wrapper Repair Evidence (2026-08-08)
|
||||
|
||||
- 已确认外层 `production-preflight.mjs` 在远端非零退出且 Prisma marker 缺失时,先抛出 `PRISMA_STATUS_OUTPUT_MISSING`,遮蔽了远端 helper 已输出的稳定安全码;该结论来自源码顺序与既有脱敏 evidence,不反推或猜测真实远端原因。
|
||||
- 最小修复保持稳定摘要与 `reportRef` 在失败判断前输出,并把远端非零退出判断提前:可解析 `code=...` 时传播原码,不可解析时固定失败为 `PRODUCTION_PREFLIGHT_REMOTE_FAILED`;只有远端退出 0 且 marker 缺失时才返回 `PRISMA_STATUS_OUTPUT_MISSING`。
|
||||
- 聚焦回归覆盖四种组合:非零/有安全码/marker 缺失,非零/有安全码/marker 存在,非零/无可解析码/marker 缺失,以及退出 0/marker 缺失;`deployment-safety-contract.test.js` 为 19/19 PASS。
|
||||
- 本地 Node/shell syntax、env contract、task validate、process contract、docs audit、Trellis governance、sensitive scan 与 `git diff --check` 均通过;docs audit 仅保留仓库既有的未注册文档 warning。
|
||||
- 本节修复阶段未连接生产、未运行 target/status、未执行 rsync、migration、应用切换或业务 API;生产 schema 写入与业务写入仍为 0。候选提交进入上游且 provenance 重新通过后,才允许重跑只读 pre-status;取得真实远端错误码后必须立即停止并复核原因。
|
||||
|
||||
在新工单中引用
屏蔽一个用户