修复(08-08-production-deployment-execution): 校验候选 Compose 构建标识
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s

这个提交包含在:
2026-08-08 20:44:30 +08:00
父节点 83af7544c4
当前提交 8b2ed5bb16
共修改 6 个文件,包含 91 行新增和 16 行删除
+38 -1
查看文件
@@ -1554,7 +1554,11 @@ DEPLOY_SERVER=<approved-ssh-target> \
- Remote read-only helper: `deploy/trialrun/production-preflight-remote.sh`.
- Required process inputs: `EXPECTED_PRODUCTION_ORIGIN`,
`EXPECTED_PRODUCTION_DB_NAME_SHA256`, `EXPECTED_PENDING_MIGRATIONS`, and the
exact deployment target/directory/Compose identity values.
exact deployment target/directory/Compose identity values. The strict wrapper
must also pass its provenance-verified `CANDIDATE_COMMIT`; preflight must not
fall back to `git rev-parse HEAD`.
- Candidate Compose interpolation: `BUILD_SHA=<full candidate commit>` and
`VITE_BUILD_SHA=<first 12 hex characters of BUILD_SHA>`.
### 3. Contracts
@@ -1576,6 +1580,14 @@ DEPLOY_SERVER=<approved-ssh-target> \
candidate manifest. Pending must exactly equal the explicit allowlist;
pending IDs reported by status must belong to the candidate manifest;
failed, rolled-back, unfinished, diverged or unknown history fails closed.
- `docker compose config` validates the candidate configuration that would be
deployed, not the currently running container configuration. The local
orchestrator derives both Compose build variables only from the
provenance-verified candidate: the full commit becomes `BUILD_SHA` and its
first 12 characters become `VITE_BUILD_SHA`. The remote helper requires both,
validates their hexadecimal lengths and asserts the prefix relationship.
Never use `--no-interpolate`, which would bypass required `${VAR:?...}`
constraints instead of checking the candidate configuration.
- The preflight helper is read-only: it does not run `migrate dev`, reset,
`db push`, `migrate resolve`, seed, DDL or business writes. `deploy.sh` is
reached only after target and pre-status gates pass.
@@ -1609,6 +1621,12 @@ DEPLOY_SERVER=<approved-ssh-target> \
- Missing or invalid expected target input -> stop before SSH mutation.
- Target hash, runtime mode, cookie security or DB identity mismatch -> stop
before `deploy.sh`.
- Missing/invalid provenance candidate -> `CANDIDATE_COMMIT_MISSING` or
`CANDIDATE_COMMIT_INVALID`; do not infer a candidate from local HEAD.
- Invalid full/short build SHA or a short SHA that is not the first 12
characters of the full SHA -> `PROD_TARGET_BUILD_SHA_INVALID`,
`PROD_TARGET_VITE_BUILD_SHA_INVALID` or `PROD_TARGET_BUILD_SHA_MISMATCH`;
stop before Compose config and Prisma status.
- 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
@@ -1627,10 +1645,16 @@ DEPLOY_SERVER=<approved-ssh-target> \
- 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.
- Good: the verified candidate commit is injected as the full build SHA and
its 12-character prefix, so Compose validates exactly the configuration that
a later approved deployment would activate.
- 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`.
- Bad: omit build SHA interpolation, use a seven-character Git abbreviation,
re-read HEAD inside preflight, or pass `--no-interpolate` merely to make
Compose config return zero.
### 6. Tests Required
@@ -1645,6 +1669,10 @@ DEPLOY_SERVER=<approved-ssh-target> \
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.
- Assert the SSH command receives the provenance candidate as `BUILD_SHA` and
its exact 12-character prefix as `VITE_BUILD_SHA`; reject malformed and
individually valid-but-mismatched pairs. Static checks must prove there is no
local-HEAD candidate fallback.
### 7. Wrong vs Correct
@@ -1662,6 +1690,15 @@ write stable evidence -> inspect remote non-zero exit and propagate/fallback
-> only after remote success require the Prisma marker
```
```text
# Wrong: validate a non-interpolated or unrelated working-tree configuration.
git rev-parse HEAD -> docker compose config --no-interpolate
# Correct: validate the exact published candidate configuration.
provenance-verified commit -> BUILD_SHA + first 12 chars as VITE_BUILD_SHA
-> interpolated docker compose config
```
## Scenario: Environment Recovery Classification And Secret Custody
### 1. Scope / Trigger