diff --git a/deploy/check-require-declaration.sh b/deploy/check-require-declaration.sh index 8915084..45bd093 100755 --- a/deploy/check-require-declaration.sh +++ b/deploy/check-require-declaration.sh @@ -71,6 +71,16 @@ LIB_REL='deploy/lib/env-defaults.sh' # ⇒ 正确做法:先把去注释结果**收集到变量**,再对它做匹配(无管道、无 SIGPIPE)。 strip_comments() { sed 's/#.*$//' "$1"; } +# ── 判定的**唯一**实现:输入文本 ⇒ 输出违规行号(每行一个,`行号:内容`) +# 正向对照与正式扫描**都走这一个函数** —— 否则"两套实现"会各自漂移, +# 而漂移恰恰是这条判据要防的东西(见下方 ★★ 共模洞)。 +AM_SCAN_RE='^[[:space:]]*AGENTMAIL_REQUIRE=' +_scan_text() { + local _t + _t="$(sed 's/#.*$//' <<< "$1")" + grep -nE "$AM_SCAN_RE" <<< "$_t" +} + # ① 找"调用者":非注释行里以 `. ` 或 `source ` 起头、且提到 env-defaults.sh 的文件。 callers="" for f in $(find deploy -name '*.sh' -type f | sort); do @@ -119,15 +129,46 @@ for f in "$@"; do # ⇒ 报 **0** 个违规、rc=**0**(3 个违规**全部静默漏掉**)—— 判定又一次落在输出通道上。 # ⇒ 记法: **"计数"与"证据"若走同一条通道,那条通道静音就等于"没有"**; # 要要么分通道、要么**规定静音=失败侧**(本处取后者)。 + # + # ★★★ 第四版(pi `3be8a091` 指出 ③ **有个我没写出来的前提**,我复现并采纳): + # ③ 的 fail-closed 只在"**两通道不一致**"时触发 ⇒ 它默认两条通道**失效不相关**。 + # 而我的两条通道**共享 2 个东西**:(a)**同一个正则字面量**(两处逐字相同) + # (b)**同一个 `$body`**(都来自 `strip_comments "$f"`)。 + # ⇒ ★ **单点改动同时哑掉两条时,它们"一致"(都沉默)⇒ `_had=1 ∧ _cnt=0` 不成立 + # ⇒ fail-closed 恰好不触发**。pi 的实测我照做复现: + # 把两处正则字面量一起改成 `'^NOMATCH='`(树上**注入着 3 处裸赋值**) + # ⇒ rc=**0**,并打出"裸赋值 **0** 处"—— **与真实情况相反**。 + # ⇒ 记法: **"两条通道"要成为独立证据,须"不存在单点改动能同时哑掉两条"** —— + # 条数 ≥ 2 **不是**独立性的判据;要检查它们共享的**字面量/变量/函数/上游命令**。 + # + # ★ 补法是**正向对照**(判据自检),且**让它走与正式扫描同一个函数**: + # 用一个**已知违规样本**跑 `_scan_text`,若它匹配不到 ⇒ 说明"沉默"是**共模**的 + # ⇒ 按**红**计(不能因为两条通道都不说话就当成"没问题")。 + # ★ 为什么走同一函数而不是抄一份正则:抄一份 ⇒ 又出现"两套实现",而 + # pi 标的残余正是"正则对、别的环节(body 被过度 strip)静音"—— + # 走同一函数能把**整条管线**(strip + 匹配 + 行号输出)一起对照到, + # 而不只对照那个正则字面量。 + _pc="$(_scan_text 'x=1 +AGENTMAIL_REQUIRE="git go"' || true)" + case "$_pc" in + *AGENTMAIL_REQUIRE*) : ;; # 自检通过:能匹配到已知样本 + *) + printf ' [FAIL] 判据自检失败:违规扫描连一个**已知样本**都匹配不到 —— 这是**共模失效**\n' >&2 + printf ' (两条通道因同一原因一起沉默 ⇒ fail-closed 的不一致条件不成立)。按红计。\n' >&2 + exit 1 + ;; + esac + unset _pc + body="$(strip_comments "$f")" _had=0 - grep -qE '^[[:space:]]*AGENTMAIL_REQUIRE=' <<< "$body" && _had=1 + grep -qE "$AM_SCAN_RE" <<< "$body" && _had=1 _cnt=0 while IFS=: read -r _ln _rest; do [ -z "${_ln:-}" ] && continue printf ' [FAIL] %s:%s 用了裸赋值(应改为 `agentmail_require <命令…>`)\n' "$f" "$_ln" >&2 _cnt=$((_cnt + 1)) - done < <(grep -nE '^[[:space:]]*AGENTMAIL_REQUIRE=' <<< "$body") + done < <(grep -nE "$AM_SCAN_RE" <<< "$body") if [ "$_had" -eq 1 ] && [ "$_cnt" -eq 0 ]; then printf ' [FAIL] %s 有裸赋值,但**取行号的那条通道没给出任何行号** —— 判据内部不一致;\n' "$f" >&2 printf ' 按 fail-closed 记作 1 处违规(两条通道必须都给得出,否则判定就落在单条通道上)。\n' >&2