#!/usr/bin/env bash
# v1.7.2 AC13 腿 —— `verify_release.sh` 之【到达面自守】(L1 行为级 · 绿侧 + 红侧 · 接入出口码)
#
# 判据面: `scripts/verify_release.sh`(真面)∧ 其【逐字拷贝 + 删一调用点】之探针(红面)
# 器: `bash` ∧ `grep`(判据 = 门禁输出之 `检查26`/`检查27` 行)
#
# 病(`v1.7.1` 测试交付物评审 `P1`): `set -uo pipefail` 无 `-e` ⇒ 【调用点消失 ⇒ 门禁仍绿】。
# 治: 运行时【到达台账】(`note` 首标入账)收束时对表 `DOMAIN_DIM_MEMBERS_CHECK`。
#
# 承路标 §四.2「新增腿件须伴红侧(阳性对照)」⇒ 本腿之红侧【接入出口码】:
# 仅当【绿侧全过 ∧ 红侧咬合】时 exit 0; 否则 exit 1。
# ★ 红侧之面 = 【仓内未跟踪探针】= `verify_release.sh` 之逐字拷贝 ∧ 删 `check25_heredoc_expand`
# 之【调用点】(其标签仍留于函数体之 note ⇒ `L0` 之 检查26 支③【仍绿】)⇒ 证 `L0` 不捕、
# `L1` 独承。★ 探针置【仓内】之由: 门禁以 `BASH_SOURCE` 推 `REPO_ROOT` ⇒ 仓外副本会取错面;
# 且 `检查25` 之面 = `git ls-files` ⇒ 未跟踪探针不入其面(零污染)。
#
# 用法: bash scripts/tests/ac13_arrival_guard_leg.sh [仓根]
# 退出码: 0 = 绿侧全过 ∧ 红侧咬合 / 1 = 任一不符
# ★ 成本(本席实测): 门禁单跑 ≈ 566 s ⇒ 本腿 ≈ 19 min(gate-selftest 类 · 非 `M1` 深测 ⇒ 不受 §四.1 之禁)。
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT="${1:-$(cd "$HERE/../.." && pwd)}"
cd "$ROOT" || { echo "仓根不可达: $ROOT" >&2; exit 1; }
PASS=0
FAIL=0
ok() { printf ' ✓ %s\n' "$1"; PASS=$((PASS + 1)); }
no() { printf ' ✗ %s\n' "$1"; FAIL=$((FAIL + 1)); }
TMP="$(mktemp -d)"
PROBE="$ROOT/scripts/verify_release_probe_ac13.sh"
# ★★ v1.9.1 捕C-2(源 `test` 复核 · 承 `ar` 令「四项并批」): 旧形 `cleanup` **恒** `rm -rf "$TMP"`
# ⇒ `G1`/`R1` 之整门输出**即删** ⇒ 失败时**读数不可复查**(唯汇总行入 as-run;
# `test` 实证: 其求 `FAIL` 之因时该档已不可得, 唯另跑探针)。现形: **失败则保留**(并印路径),
# 成功且未显式要求保留则删。★ `$PROBE` **恒删**(其在仓内 ⇒ 留之则污工作树 ∧ 入 `检查25` 之面)。
# ★ 保留位在 `/tmp`(仓外)⇒ **不**入 `typos` ①h 族 ∧ 不入任何仓内判据面(承在册之耦合)。
cleanup() {
if [ "${FAIL:-0}" -eq 0 ] && [ "${AC13_LEG_KEEP:-0}" != "1" ]; then
rm -rf "$TMP"
else
printf ' ★ 留证: 整门输出【保留】(免读数不可复查 · 捕C-2) ⇒ %s\n' "$TMP"
printf ' 重跑保留: AC13_LEG_KEEP=1 bash %s\n' "${BASH_SOURCE[0]}"
fi
rm -f "$PROBE"
}
trap cleanup EXIT
echo "== AC13 腿 · 面 = $ROOT =="
# ── 绿侧 G1: 真面实跑 ⇒ 到达面【全到达】────────────────────────────────────
# ★★ v1.9.1 修(承 `ar` 令「取乙 · 与 `ci.yml` 同形」· 源 `test` 复核我捕一 · 陈年 `v1.7.2` 之失):
# 病: 本腿二处门禁调用皆【缺】`XW_VERIFY_RELEASE_WINDOW_BASE` ⇒ `检查15` 窗基缺省取
# `git describe --tags --abbrev=0 HEAD` ⇒ 于【`tag` 面】(`HEAD` 已 `tag`)窗 =
# `<该 tag>..HEAD` = `0` 提交 ⇒ 窗坍缩 ⇒ `检查15(sb2101_ac2)` FAIL(`r28-P1-3`)——
# 即【于 `tag` 面必红之假红】, 而于 mid-version 面不显(面依 · 非某版引入)。
# ★★★ 首修之【未竟】(`test` 复核二捕 · 本席一手复证 ⇒ 当场订正): 首修【无条件】传该键
# ⇒ 该键**非** `检查15` 专有 —— `检查2` 之 `_c2g_base` 亦直取之(`verify_release.sh:588`
# 逐字 `_c2g_base="${XW_VERIFY_RELEASE_WINDOW_BASE:-}"`)。于 mid 面 `describe HEAD^` =
# **本版 `tag`** ⇒ `base == tip`(`_c2g_tip="v${cargo_ver}^{}"`)⇒ `n_pin=0` ⇒ `检查2` 落
# 【无升钉窗】支而二面书【含升钉窗】⇒ **FAIL**。⇒ 首修系【以 `tag` 面假红换 mid 面假红 ·
# 修未竟】—— 且 mid 面系**常态面**(每次 CI/本地跑皆 mid), 较原病**更常发**。
# ★ 一手实证: `release/v1.9.1/evidence/gate_v191_c22_invocation_red.log:525`(同面 mid ·
# 窗基 `v1.9.0`)逐字「`FAIL: 检查2(D1 二分自书律): 窗**无** git 升钉(n_pin=0)…`」。
# 治(取乙 · 形 **∧ 前件** 俱与 `ci.yml` 同): `ci.yml` 之 `BASE` 行**亦无条件**, 然其所在 job
# `verify-release` 有 `if: startsWith(github.ref,'refs/tags/') || workflow_dispatch`(`:707`)
# ⇒ 该行**唯于 `tag` 面到达**。腿于**二面皆跑** ⇒ 须显式复刻该前件:
# `WIN_BASE` **唯于【`HEAD` 正落在 `tag` 上】时**取 `describe HEAD^`; 否则**留空**
# (空 ⇒ 门禁取 `${VAR:-缺省}` ⇒ 视同未设 ⇒ 二检各用其缺省 ⇒ mid 面二检皆绿)。
# ★ 二面之值: `tag` 面 ⇒ `检查15` 复常 ∧ `检查2` 之值与其缺省**同**(`describe HEAD^` ==
# `describe v${cargo_ver}^` · 二者同指前版 `tag`)⇒ 零射程; mid 面 ⇒ 键不发 ⇒ 零射程。
# ★ 空值 `WIN_BASE` 亦安 —— 门禁取 `${VAR:-缺省}` ⇒ 空视同未设(与 `ci.yml` 同)。
WIN_BASE=""
if git describe --exact-match --tags HEAD >/dev/null 2>&1; then
WIN_BASE="$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || true)"
fi
# ★★ v1.9.1 捕C-1(源 `test` 复核 · 承 `ar` 令「四项并批 · 即落」): `检查5` 键由【**无条件硬置**】
# 改【**条件注入 · fail-closed**】—— 与 `ci.yml:793-800` 同形。
# 病: 旧形之「预置无害」据仅在【文档面】(「`D4` 立 🚧 行之前该支不走」)⇒ 若 `检查5` 日后因
# 【**不同理由**】新增空窗而计数仍为 `1`, 该键将【**静默放行**】(键形只约束**广度**, 不约束**性质**)。
# 治: 探 `ROADMAP.md` 有无【本版】`🚧` 行 ⇒ **有则【不注入】**(令该空窗受判 · `fail-closed`)。
# ★ 射程(照实): 于【本版 `🚧` 行在位】之窗(`D4`–`tag`), 本腿将随 `ci` **同红**
# (`检查5` 空窗受判 ⇒ `GAP` ⇒ `G1` 之 `rc=0` 不成立)—— 此系严格度对齐之本义; 现态
# `ROADMAP.md` **无** `🚧` 行 ⇒ 键照注入 ⇒ **与旧形同** ⇒ 零射程。
SKIP5=""
VER="$(sed -n 's/^version = "\([0-9][0-9.]*\)".*/\1/p' Cargo.toml | head -1)"
if grep -qE "🚧[[:space:]]*v${VER}([^0-9.]|\$)" ROADMAP.md 2>/dev/null; then
echo " 检查5 键: ROADMAP 有本版 v${VER} 🚧 行 ⇒ **不**注入(令空窗受判 · fail-closed)"
else
SKIP5="检查5#1"
echo " 检查5 键: ROADMAP 无本版 v${VER} 🚧 行 ⇒ 注入 检查5#1(该支不走)"
fi
echo "-- G1 真面实跑(XW_ADJUDICATE_SKIP=${SKIP5:-<不发>} · mid-version 空窗具名裁定 · 面=$( [ -n "$WIN_BASE" ] && echo "tag 面(窗基=${WIN_BASE})" || echo "mid 面(窗基不发)"))"
XW_VERIFY_RELEASE_WINDOW_BASE="$WIN_BASE" XW_ADJUDICATE_SKIP="$SKIP5" bash scripts/verify_release.sh >"$TMP/g1.txt" 2>&1
G1RC=$?
if [ "$G1RC" -eq 0 ] \
&& grep -q '检查27(AC13/到达面): 声明面 .* 项【全到达】' "$TMP/g1.txt" \
&& grep -q '检查26(AC5): 穷举域维度完备' "$TMP/g1.txt"; then
ok "G1 rc=0 ∧ 检查27【全到达】∧ 检查26 零差集"
else
no "G1 rc=$G1RC(或缺 检查27【全到达】/ 检查26)"
# ★★ v1.9.1 捕D(源 `test` 复核 · 承 `ar` 令「四项并批」): 旧形**唯**印 `检查2[67]` 二行
# ⇒ 若真因系**他检**(如 `检查2` 之 `D1` 二分 / `检查15` 之窗坍缩 / `检查5` 之空窗受判)
# 则【印空】⇒ **诊断行误导**(读者以为失在 26/27)。现形: 先印【全 `FAIL`/`error` 行】,
# 再印 26/27 之上下文行 —— 真因**必**现于首段。
grep -E '\[verify_release\] (FAIL|error)' "$TMP/g1.txt" | head -8 | sed 's/^/ /'
grep -E '检查2[67]' "$TMP/g1.txt" | head -2 | sed 's/^/ /'
fi
# ── 红侧 R1(阳性对照 · L1 独承): 删一调用点(标签留于函数体 ⇒ L0 仍绿)⇒ 必红 ──
echo "-- R1 阳性对照: 逐字拷贝 + 删 check25_heredoc_expand 之调用点 ⇒ 检查27 必红"
python3 - "$PROBE" <<'PY'
import sys
src = open('scripts/verify_release.sh', encoding='utf-8').read()
old = '\ncheck25_heredoc_expand\n'
assert src.count(old) == 1, f'调用点数 = {src.count(old)}(须为 1)'
new = '\n# check25_heredoc_expand # ← AC13 阳性对照: 删调用点(标签仍留于函数体 ⇒ L0 仍绿)\n'
open(sys.argv[1], 'w', encoding='utf-8').write(src.replace(old, new, 1))
PY
XW_VERIFY_RELEASE_WINDOW_BASE="$WIN_BASE" XW_ADJUDICATE_SKIP="$SKIP5" bash "$PROBE" >"$TMP/r1.txt" 2>&1
R1RC=$?
R1_HIT27=0; R1_HIT25=0; R1_L0GREEN=0
grep -q '检查27(AC13/到达面): 声明而未【到达】之检查' "$TMP/r1.txt" && R1_HIT27=1
grep -q '未【到达】之检查 1 项 —— 检查25' "$TMP/r1.txt" && R1_HIT25=1
grep -q '检查26(AC5): 穷举域维度完备' "$TMP/r1.txt" && R1_L0GREEN=1
# ★★ 显名支(承裁19 §2 同律 · `test` 域修): 照实 —— 本腿**零** `timeout`(`bash "$PROBE"`
# 直调)⇒ `124` 支为**防御**(不可达)。真伪由 = 原 `else` 以「未中」径判「未咬合」
# ∧「探针面不纯」—— 整门未跑完/未真跑亦落此 ⇒ **伪由**。
if [ "$R1RC" -eq 124 ]; then
no "R1 ★ 逾时被杀 rc=124(**本腿未判**)—— 承裁19 §2: 超时 ≠ 未咬合 · 禁混(候复跑)"
elif [ ! -s "$TMP/r1.txt" ]; then
no "R1 ★ 器无输出 rc=$R1RC(**未判**)—— 无从判咬合(显名 · 非判「未咬合」)"
elif [ "$R1RC" -ne 0 ] && [ "$R1_HIT27" -eq 1 ] && [ "$R1_HIT25" -eq 1 ]; then
ok "R1 咬合 rc=$R1RC ∧ 检查27 红 ∧ 具名 检查25"
else
no "R1 未咬合 rc=$R1RC hit27=$R1_HIT27 hit25=$R1_HIT25(有输出 ∧ 未中)"
grep -E '检查2[67]' "$TMP/r1.txt" | head -4 | sed 's/^/ /'
fi
if [ "$R1RC" -eq 124 ]; then
no "R1 并证 ★ 逾时被杀 rc=124(**本腿未判**)—— 超时 ≠ 「探针面不纯」· 禁混(候复跑)"
elif [ "$R1_L0GREEN" -eq 1 ]; then
ok "R1 并证: 检查26(L0)仍【零差集 ✓】⇒ 本红系 L1 独承(L0 不捕 ⇒ AC13 之靶心成立)"
else
no "R1 并证失败: 检查26(L0)未呈绿 ⇒ 探针面不纯(其红可能出自 L0)"
fi
echo "== 结果: PASS=$PASS FAIL=$FAIL =="
[ "$FAIL" -eq 0 ] || exit 1
exit 0