docs(ci): define real staging gate rules

This commit is contained in:
Your Name
2026-04-21 09:28:27 +08:00
parent 3aeddc0b43
commit 3f509d1a6c
7 changed files with 167 additions and 8 deletions

View File

@@ -94,3 +94,22 @@ rg -n "IntrospectTokenResponse|tenant_id|project_id|operator_id|metadata|IssueTo
1. 已创建 `docs/plans/2026-04-21-release-manifest-contract.md`,记录 `latest_file_or_empty` 依赖入口、`run_id` 规则、目录结构与 `manifest.json` 必填字段。
2. 已创建 `reports/releases/.gitkeep`,为后续 `<run_id>` 工件目录预留稳定路径。
3. 已在四个脚本中补入 manifest 迁移设计说明,明确后续必须从 `decision_inputs` / `artifact_paths` 读取本次 run 的证据。
## P2-B 真实 staging 硬门禁规则设计完成
执行命令:
```bash
rg -n 'P2-B-0[1-8]|PASS_REAL|PASS_REHEARSAL|FAIL|override|DEFERRED|real_staging_pass' docs/plans/2026-04-21-real-staging-gate-rules.md
bash -n scripts/ci/superpowers_stage_validate.sh
bash -n scripts/ci/staging_real_readiness_check.sh
bash -n scripts/ci/superpowers_release_pipeline.sh
bash -n scripts/ci/final_decision_consistency_check.sh
git diff --check
```
执行结果:
1. 已创建 `docs/plans/2026-04-21-real-staging-gate-rules.md`,逐项覆盖 `P2-B-01``P2-B-08`,写死 rehearsal / real staging 术语边界、`PASS_REAL|PASS_REHEARSAL|FAIL` 状态枚举、override 约束和完成率口径。
2. 已在 `scripts/ci/superpowers_stage_validate.sh``scripts/ci/staging_real_readiness_check.sh``scripts/ci/superpowers_release_pipeline.sh``scripts/ci/final_decision_consistency_check.sh` 补入迁移设计注释,明确真实 staging 是唯一 release 硬门禁,且 `DEFERRED` / rehearsal 不得计入 release pass。
3. 四个脚本 `bash -n` 通过,且 `git diff --check` 无格式错误;本批次仅落设计规则与迁移约束,没有伪装成已完成实现。

View File

@@ -329,21 +329,21 @@
- Modify: `scripts/ci/final_decision_consistency_check.sh`
- Create: `docs/plans/2026-04-21-real-staging-gate-rules.md`
- [ ] `P2-B-01` 找出 `mock``local``DEFERRED` 被计为通过的判定点。
- [x] `P2-B-01` 找出 `mock``local``DEFERRED` 被计为通过的判定点。
完成标准:每个判定点都有文件和行号。
- [ ] `P2-B-02` 定义 rehearsal 与 real staging 的术语。
- [x] `P2-B-02` 定义 rehearsal 与 real staging 的术语。
完成标准:规则文档中两者语义不重叠。
- [ ] `P2-B-03` 定义“只有 real staging 通过才允许 release pass”的总规则。
- [x] `P2-B-03` 定义“只有 real staging 通过才允许 release pass”的总规则。
完成标准:总规则写成一句可执行判定语句。
- [ ] `P2-B-04` 设计 `superpowers_stage_validate.sh` 的状态枚举。
- [x] `P2-B-04` 设计 `superpowers_stage_validate.sh` 的状态枚举。
完成标准:至少区分 `PASS_REAL``PASS_REHEARSAL``FAIL`
- [ ] `P2-B-05` 设计 `staging_real_readiness_check.sh` 的阻断输出格式。
- [x] `P2-B-05` 设计 `staging_real_readiness_check.sh` 的阻断输出格式。
完成标准:输出里包含明确的 pass/fail 字段。
- [ ] `P2-B-06` 设计 `superpowers_release_pipeline.sh` 的 fail-fast 位置。
- [x] `P2-B-06` 设计 `superpowers_release_pipeline.sh` 的 fail-fast 位置。
完成标准release 在 real staging 未通过时立即退出。
- [ ] `P2-B-07` 设计 override 机制。
- [x] `P2-B-07` 设计 override 机制。
完成标准override 必须要求审批人、时间戳、run_id、理由。
- [ ] `P2-B-08` 设计禁止 `DEFERRED` 计入完成率的规则。
- [x] `P2-B-08` 设计禁止 `DEFERRED` 计入完成率的规则。
完成标准:文档里写出精确计算口径。
### Task P2-C: 统一环境语义和配置模板

View File

@@ -0,0 +1,105 @@
# 2026-04-21 Real Staging Gate Rules
## P2-B-01 当前把 `mock` / `local` / `DEFERRED` 计为通过的判定点
1. `scripts/ci/superpowers_stage_validate.sh:100`
local/mock 环境直接把 `PHASE-07` 写成 `DEFERRED`
2. `scripts/ci/superpowers_stage_validate.sh:110`
`run_step_allow_deferred` 允许真实 staging 前置检查用 `DEFERRED` 退出。
3. `scripts/ci/superpowers_stage_validate.sh:166`
`PHASE-02``PHASE-04` 继续在 `.env.local-mock` 上执行 rehearsal 流程。
4. `scripts/ci/superpowers_stage_validate.sh:233`
只要存在 `DEFERRED` 就给出 `CONDITIONAL_GO`,没有直接把它判成失败。
5. `scripts/ci/superpowers_stage_validate.sh:238`
local/mock 环境即使其余步骤都通过,也只降级到 `CONDITIONAL_GO`,仍可能被后续流水继续消费。
6. `scripts/ci/staging_real_readiness_check.sh:68`
环境分类同时存在 `local-mock``placeholder``real-staging`,但输出结果仍是 `READY/BLOCKED`,没有单独的 real-pass 字段。
7. `scripts/ci/superpowers_release_pipeline.sh:78`
发布流水当前在 `STEP-01` 之后不会校验“是否 real staging pass”会继续执行 `STEP-02``STEP-04`
8. `scripts/ci/final_decision_consistency_check.sh:100`
当前只比较最终决议与机判是否一致,没有把 `DEFERRED` / rehearsal 明确排除在 release pass 之外。
## P2-B-02 rehearsal 与 real staging 术语
术语定义:
1. `rehearsal`
任一使用 `local-mock``localhost`、占位 API 地址、占位 token、或无法访问真实 staging 的运行。
2. `real staging`
使用真实外网 staging 地址、真实 owner/viewer/admin token并通过真实连通性检查的运行。
约束:
1. rehearsal 只用于排练脚本链路与产物结构。
2. real staging 才能产生发布硬门禁证据。
3. 两者语义完全不重叠rehearsal 结果不得冒充 real staging。
## P2-B-03 总规则
只有当同一 `run_id` 下的 real staging 检查通过,且阶段验证状态为 `PASS_REAL`,发布流水才允许输出 `PASS`
## P2-B-04 `superpowers_stage_validate.sh` 状态枚举设计
必须只保留三种发布语义状态:
1. `PASS_REAL`
`PHASE-07` 在真实 staging 上通过。
2. `PASS_REHEARSAL`
rehearsal 流程通过,但 `PHASE-07` 是 local/mock/deferred。
3. `FAIL`
任一必需阶段失败,或真实 staging 要求未满足。
映射约束:
1. 当前 `GO` 只能在未来映射为 `PASS_REAL`
2. 当前 `CONDITIONAL_GO` 统一映射为 `PASS_REHEARSAL`
3. `DEFERRED` 只能流向 `PASS_REHEARSAL``FAIL`,不能直接升格。
## P2-B-05 `staging_real_readiness_check.sh` 阻断输出格式
输出至少包含以下稳定字段:
- `real_staging_pass=true|false`
- `classification=REAL|REHEARSAL`
- `reason_code=<stable_code>`
- `run_id=<run_id>`
阻断规则:
1. 只要 `real_staging_pass=false`,发布链路必须立即阻断。
2. `classification=REHEARSAL` 时,无论其余检查如何,都不能视为 real-pass。
## P2-B-06 `superpowers_release_pipeline.sh` fail-fast 位置
fail-fast 放置点:
1. `STEP-01` 执行完阶段验证后立即解析其输出。
2. 若状态不是 `PASS_REAL` 且没有合法 override立刻 `exit 1`
3. `STEP-02` TOK-007、`STEP-03` final consistency、`STEP-04` final decision candidate 都不得在 non-real-pass 条件下继续执行。
## P2-B-07 override 机制设计
override 必填字段:
- `approver`
- `timestamp`
- `run_id`
- `reason`
约束:
1. override 必须显式落盘到本次 `run_id` 目录。
2. 没有完整四字段的 override 一律视为无效。
3. override 只能豁免发布阻断,不能把 rehearsal 改写成 real staging 事实。
## P2-B-08 `DEFERRED` 不计入完成率的规则
精确口径:
`phase_completion_rate = PASS_REAL_required_phases / total_required_phases`
规则说明:
1. 分子只统计 `PASS_REAL` 的必需阶段。
2. `DEFERRED``PASS_REHEARSAL``WARN``SKIP` 都不计入分子。
3. `DEFERRED` 仍占据必需阶段名额,因此会拉低完成率,不能被当作“完成一半”或“条件通过”。

View File

@@ -14,6 +14,10 @@ LOG_FILE="${OUT_DIR}/final_decision_consistency_${TS}.log"
# - preferred entry: --manifest <reports/releases/<run_id>/manifest.json>
# - this script should bind final_decision, tok007_recheck and stage validation inputs
# to one run_id and stop reading historical "latest" outputs
# Real staging gate design:
# - DEFERRED / PASS_REHEARSAL must not be counted as release completion
# - override metadata, if present, must include approver, timestamp, run_id, and reason
# - final consistency WARN must not upgrade a non-real staging run into release PASS
latest_file_or_empty() {
local pattern="$1"

View File

@@ -15,6 +15,12 @@ TS="$(date +%F_%H%M%S)"
REPORT_FILE="${OUT_DIR}/staging_real_readiness_${TS}.md"
LOG_FILE="${OUT_DIR}/staging_real_readiness_${TS}.log"
# Planned blocking output contract:
# - real_staging_pass=true|false
# - classification=REAL|REHEARSAL
# - reason_code=<stable_code>
# - run_id=<required in release flow>
CHECK_IDS=()
CHECK_STATUS=()
CHECK_DESC=()
@@ -164,6 +170,11 @@ if [[ "${has_fail}" == "1" ]]; then
NOTE="at least one required check failed"
fi
# Future status mapping:
# - READY => PASS_REAL only when ENV_CLASS=real-staging
# - BLOCKED => FAIL
# - local-mock / placeholder classifications must never be treated as PASS_REAL
{
echo "# 真实 STG 就绪度检查"
echo

View File

@@ -13,6 +13,11 @@ ENABLE_MINIMAX_MONITORING="${ENABLE_MINIMAX_MONITORING:-0}"
MINIMAX_ENV_FILE="${MINIMAX_ENV_FILE:-scripts/supply-gate/.env.minimax-dev}"
MINIMAX_RUN_ACTIVE_SMOKE="${MINIMAX_RUN_ACTIVE_SMOKE:-0}"
# Planned real-staging hard gate:
# - fail fast immediately after STEP-01 if stage validation is not PASS_REAL
# - STEP-02 onward must not run release-path decisions on PASS_REHEARSAL/DEFERRED
# - override, if ever allowed, must require approver, timestamp, run_id, and reason
log() {
echo "$1" | tee -a "${LOG_FILE}"
}
@@ -101,6 +106,10 @@ run_optional_step_non_blocking \
"${ENABLE_MINIMAX_MONITORING}" \
"cd \"${ROOT_DIR}\" && RUN_ACTIVE_SMOKE=\"${MINIMAX_RUN_ACTIVE_SMOKE}\" bash \"scripts/ci/minimax_upstream_daily_snapshot.sh\" \"${TODAY_TAG}\" \"${MINIMAX_ENV_FILE}\" && bash \"scripts/ci/minimax_upstream_trend_report.sh\" \"${TODAY_TAG}\""
# Planned fail-fast insertion point:
# - parse STEP-01 report here
# - if real staging status != PASS_REAL and no valid override record exists, exit 1 before STEP-02
has_fail=0
for row in "${STEP_RESULTS[@]}"; do
status="$(echo "${row}" | awk -F'|' '{print $2}')"

View File

@@ -115,6 +115,12 @@ run_phase07() {
"env_class=local-mock|placeholder token detected|placeholder API_BASE_URL|missing env var|API_BASE_URL unreachable"
}
# Real staging decision design:
# - PASS_REAL: PHASE-07 runs against real staging and succeeds.
# - PASS_REHEARSAL: all executable rehearsal phases pass, but PHASE-07 is local/mock/deferred.
# - FAIL: any required phase fails, or PHASE-07 is not real-pass when release flow requests hard gate.
# - DEFERRED must never be promoted to PASS_REAL.
ensure_mock_server() {
if curl -sS -m 2 "http://127.0.0.1:18080/actuator/health" >/dev/null 2>&1; then
echo "already_running"
@@ -240,6 +246,11 @@ if is_mock_staging_env "${STAGING_ENV_FILE}" && [[ "${DECISION}" == "GO" ]]; the
DECISION_REASON="all phases passed but PHASE-07 used local/mock staging env"
fi
# Future release hard-gate mapping:
# - GO maps to PASS_REAL only when PHASE-07 is real-staging PASS.
# - CONDITIONAL_GO maps to PASS_REHEARSAL and must not satisfy release pass.
# - NO_GO maps to FAIL.
{
echo "# Superpowers 阶段验证报告"
echo