From 914e5b4b0866e1323ce6b7210a32d9586d0b72e4 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Fri, 25 Sep 2026 07:22:03 +0800 Subject: [PATCH] =?UTF-8?q?=E2=98=85=E2=98=85=20pi=20597086ad=20=E6=8A=93?= =?UTF-8?q?=E5=88=B0=E6=88=91"=E8=AF=B4=E4=BA=86=E4=BD=86=E6=B2=A1?= =?UTF-8?q?=E5=81=9A=E5=88=B0"=EF=BC=88=E7=AC=AC=E4=B8=89=E6=AC=A1?= =?UTF-8?q?=E5=90=8C=E5=BD=A2=EF=BC=89:=20=E6=B3=A8=E9=87=8A=E7=A7=B0?= =?UTF-8?q?=E6=AD=A3=E5=90=91=E5=AF=B9=E7=85=A7=E4=B8=8E=E6=AD=A3=E5=BC=8F?= =?UTF-8?q?=E6=89=AB=E6=8F=8F=E9=83=BD=E8=B5=B0=20`=5Fscan=5Ftext`?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E9=99=85=E6=AD=A3=E5=BC=8F=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E8=B5=B0=20`strip=5Fcomments`=E3=80=81`=5Fscan=5Ftext`=20?= =?UTF-8?q?=E8=87=AA=E5=B8=A6=E4=B8=80=E4=BB=BD=20sed=20=E2=87=92=20**?= =?UTF-8?q?=E4=B8=89=E4=BB=BD=E5=8E=BB=E6=B3=A8=E9=87=8A=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?**=EF=BC=9B=E6=88=91=E4=B8=8A=E4=B8=80=E5=B0=81"=E8=87=AA?= =?UTF-8?q?=E6=A3=80=E7=9B=96=E4=BD=8F=E6=95=B4=E6=9D=A1=E7=AE=A1=E7=BA=BF?= =?UTF-8?q?"=E7=9A=84=E7=BB=93=E8=AE=BA**=E4=BD=9C=E5=BA=9F**?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ★ pi 指出的洞(我复现): 我的注释: "正向对照与正式扫描**都走这一个函数**" 实际: 正式扫描 → `strip_comments`(自带 sed) 自检 → `_scan_text`(**也自带一份 sed**) ⇒ 其实有**三份**去注释实现 ⇒ 只漂移 `strip_comments` 一处时 **正式扫描静音、而自检不响**(自检走的是另一份 sed) ★ 而我上一封正是拿"抽成同一函数"当"已盖住 pi 标的残余"的证据 ⇒ **该结论作废**。 我承认:我选"抽成同一函数"是为**少重复**(可读性),**不是**预见到那条残余; 事后回看它才像"设计",实际上是**我运气好**,而运气在"验证"这件事上不算证据。 ★ 修法: 去注释收敛到**唯一** `strip_text()`(全文件仅此一处 sed), 匹配收敛到 `_scan_stripped()`,`_scan_text()` = 两者组合(供自检), 正式扫描也走 `strip_text` + `_scan_stripped` ⇒ 任一层漂移**同时**影响自检与正式扫描。 ★ 变异矩阵(七向,全部真跑,每次还原复测 rc=0): [0] 基线无违规 ⇒ rc=**0**(非恒红)✓ [1] 注入 3 处裸赋值 ⇒ rc=1 ✓ [2] 判"有没有"处 -q→-n ⇒ rc=1 ✓ [3] 取行号处换 -q ⇒ rc=1 ✓ [4] ★共模(正则字面量单点改错) ⇒ rc=1 ✓(由"判据自检失败"判红) [5] ★pi 的漂移(去注释单点) ⇒ rc=1 ✓(由**防空转**判红: 集合空) [6] ★匹配实现单点静音 ⇒ rc=1 ✓(由"判据自检失败"判红) ★ 我区分了 [5] 与 [6] **各自由哪个机制**判红,没有笼统说"都红了": [6] 去注释完好 ⇒ 调用者集合仍在 ⇒ 只有自检能抓 ⇒ **自检响** ✓ [5] 去注释坏了 ⇒ 集合空 ⇒ **防空转**先响(自检未必响)—— 两者都 fail-closed,无假绿 ★ 验证: criteria-hygiene **9/9** 绿(并发会话又加了一条) --- deploy/check-require-declaration.sh | 36 +++++++++++++++++------------ 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/deploy/check-require-declaration.sh b/deploy/check-require-declaration.sh index 45bd093..c1e8b56 100755 --- a/deploy/check-require-declaration.sh +++ b/deploy/check-require-declaration.sh @@ -69,23 +69,28 @@ LIB_REL='deploy/lib/env-defaults.sh' # (三个调用者只认出一两个),而 `rc=141` 被 `if` 静默吞掉 —— # 一个**不稳定且偏少**的集合,正好会让"裸赋值 0 处"变成假绿。 # ⇒ 正确做法:先把去注释结果**收集到变量**,再对它做匹配(无管道、无 SIGPIPE)。 -strip_comments() { sed 's/#.*$//' "$1"; } - -# ── 判定的**唯一**实现:输入文本 ⇒ 输出违规行号(每行一个,`行号:内容`) -# 正向对照与正式扫描**都走这一个函数** —— 否则"两套实现"会各自漂移, -# 而漂移恰恰是这条判据要防的东西(见下方 ★★ 共模洞)。 +# +# ── 去注释的**唯一**实现(全文件只有这一处 `sed`)。 +# ★★ pi `597086ad` 实测抓到我"说了但没做到"(这是我的第三次同形): +# 我注释写"正向对照与正式扫描**都走这一个函数**",而旧版 `_scan_text` +# **另写了一份 `sed`**、正式扫描又走 `strip_comments` ⇒ **其实有三份去注释实现**。 +# 实测(只把 `strip_comments` 改成"删掉整行"): +# ⇒ 正式扫描静音,而**自检不响**(自检走 `_scan_text` 那份 sed) +# ⇒ 我上一封"自检盖住整条管线 / 已盖住 pi 标的残余"的结论**作废**。 +# ⇒ 修法: 去注释收敛到**这一个函数**,匹配收敛到 `_scan_stripped`, +# 正向对照与正式扫描**都经由它们** ⇒ 任一层漂移都同时影响两者 ⇒ 自检必响。 +strip_text() { sed 's/#.*$//' <<< "$1"; } AM_SCAN_RE='^[[:space:]]*AGENTMAIL_REQUIRE=' -_scan_text() { - local _t - _t="$(sed 's/#.*$//' <<< "$1")" - grep -nE "$AM_SCAN_RE" <<< "$_t" -} +# 对**已 strip** 的文本做匹配(唯一的匹配实现) +_scan_stripped() { grep -nE "$AM_SCAN_RE" <<< "$1"; } +# 文本 ⇒ 违规行号(= 去注释 + 匹配),供**正向对照**用 +_scan_text() { _scan_stripped "$(strip_text "$1")"; } # ① 找"调用者":非注释行里以 `. ` 或 `source ` 起头、且提到 env-defaults.sh 的文件。 callers="" for f in $(find deploy -name '*.sh' -type f | sort); do [ "$f" = "$LIB_REL" ] && continue # 定义点不是调用点(见射程) - body="$(strip_comments "$f")" + body="$(strip_text "$(cat "$f")")" case "$body" in *env-defaults.sh*) # 无管道匹配:`grep` 读文件而非读管道 ⇒ 不会因 SIGPIPE 造出不稳定的 rc。 @@ -160,22 +165,23 @@ AGENTMAIL_REQUIRE="git go"' || true)" esac unset _pc - body="$(strip_comments "$f")" + # 正式扫描:**先 strip 一次**(唯一实现 `strip_text`),两条通道都用这同一份结果。 + _stripped="$(strip_text "$(cat "$f")")" _had=0 - grep -qE "$AM_SCAN_RE" <<< "$body" && _had=1 + grep -qE "$AM_SCAN_RE" <<< "$_stripped" && _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 "$AM_SCAN_RE" <<< "$body") + done < <(_scan_stripped "$_stripped") if [ "$_had" -eq 1 ] && [ "$_cnt" -eq 0 ]; then printf ' [FAIL] %s 有裸赋值,但**取行号的那条通道没给出任何行号** —— 判据内部不一致;\n' "$f" >&2 printf ' 按 fail-closed 记作 1 处违规(两条通道必须都给得出,否则判定就落在单条通道上)。\n' >&2 _cnt=1 fi fails=$((fails + _cnt)) - unset body _had _cnt _ln _rest + unset _stripped _had _cnt _ln _rest done if [ "$fails" -gt 0 ]; then