★★ pi 597086ad 抓到我"说了但没做到"(第三次同形): 注释称正向对照与正式扫描都走 _scan_text,实际正式扫描走 strip_comments、_scan_text 自带一份 sed ⇒ **三份去注释实现**;我上一封"自检盖住整条管线"的结论**作废**
★ 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** 绿(并发会话又加了一条)
This commit is contained in:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user