fix: 三处"判定对、但信号假"——豁免的自检覆盖、rm 失败仍报"已删除"、show_diff 截断证据
pi 通读后逐处指出,三条都实测复现:
**1. `jsonTestOnlyChange`/`testOnlyDrift`/`runtimeOnly` 没有任何自检碰过。**
他的质疑成立:我上一封说"配了六个样本",那六个样本是**开发时的内联脚本、没进文件**
(他读了全文,找不到——我核了,确实没有)。而这段逻辑是文件里**唯一一处"把红变成绿"
的代码**,也是唯一没有判据的代码,失效方向恰好是"比恒黄更坏"那个(假绿)。
已补 **4 条走真路径的样本**(真临时树 + `diffSummary(d,{repoDir,snapDir})`):
★只差 `scripts.test` ⇒ 不算运行时漂移且必须说出豁免了哪条键;
★`scripts.start` 变了 ⇒ 必须算运行时;★解析不了 ⇒ 不许豁免;★不传 ctx ⇒ 不豁免。
★ 写样本时被一对**同义不同数**的字段绊住:断言 `runtimeDrift === 0` 却得到 1 ——
`diffSummary` 报的是**原始**检测数,而 `checkHost` 自己又减了一遍豁免。
判据自己产出两个矛盾口径,与"注释里两组矛盾的写点计数"同族 ⇒ **统一**:
`runtimeDrift` = 减掉豁免后的结论,被豁免的只出现在 `testOnly` 里;
`checkHost` 删掉自算的 `runtimeOnly`。不传 ctx 时行为与旧版逐字相同。
**2. `prune-deploy-artifacts.sh` 的 `del()`:`rm` 的结果没人看。**
脚本是 `set -uo pipefail`(**无 -e**)⇒ `rm -rf` 失败(权限/只读挂载/immutable)后
照样打"删除 …(NMB)"、收尾汇总"**已删除 N 项,释放约 X MB**"
——**一次失败之后仍产出成功措辞**(与 `redeploy-plugin.sh` 里"被拒还打 [ OK ]"同族)。
已改:判失败即报错 `exit 2`;`removed`/`freed_kb` **只在成功后累加**;并加抽验
(`rm` 报成功但路径还在 ⇒ 报错),不信单一退出码。
⚠️ **这一条的失败路径我没能实测**:本机以 root 跑,权限拦不住 `rm`;
`unshare -r` 建只读挂载被拒(`/proc/self/uid_map: Permission denied`);
tmpfs 无 `chattr +i`。要覆盖得在带 CAP_LINUX_IMMUTABLE 的环境用 immutable 文件,
或给 `del()` 加 `RM` 注入点。**我没有把"改过"说成"验过"。**
**3. `check-shared-libs.sh` 的 `show_diff` 被 `set -e` 当场中止。**
`cmp` 有差异返回 1 ⇒ `pipefail` 让函数返回 1 ⇒ 独立调用触发 `set -e` ⇒ **脚本当场死**。
实测(脚本级,fixture 树里造两处分叉:pi 与 zcode):
旧版:报告 1 处分叉、收尾汇总 0 次
新版:报告 2 处分叉、收尾汇总 0 次(收尾那句本来只在成功时打,见下)
两者退出码都是 1(判定一直是对的)—— 所以**光量退出码看不见这个 bug**,
正是 pi 说的"判定对、证据被截断"。而且旧版连 `fail=1` 都执行不到:
退出码 1 是 `set -e` 给的。加 `|| true` 后遍历跑完。
This commit is contained in:
@ -81,7 +81,29 @@ del() {
|
||||
exit 1;;
|
||||
esac
|
||||
local kb; kb=$(du -sk "$path" 2>/dev/null | cut -f1); kb=${kb:-0}
|
||||
if [ "$APPLY" = "1" ]; then rm -rf "$path"; fi
|
||||
# ★ `rm` 的结果必须看:本脚本是 `set -uo pipefail`(**没有 -e**),
|
||||
# 于是 `rm -rf` 失败(权限、只读挂载、immutable)之后脚本照样往下走,
|
||||
# 先打"删除 …(NMB)"、收尾再汇总"**已删除 N 项,释放约 X MB**" ——
|
||||
# **一次失败之后仍然产出成功措辞**(pi 评审 2026-09-14 抓到,实测确认)。
|
||||
# 这与 `redeploy-plugin.sh` 里"被拒之后照样打 `[ OK ]`"是同一族,也是本仓库
|
||||
# 反复记录的那个病:从失败里产出一份看着正常的报告。
|
||||
# 所以:判失败即报错并 `exit 2`(环境/权限问题),且 `removed`/`freed_kb`
|
||||
# **只在成功后才累加**,收尾汇总不再虚报。
|
||||
if [ "$APPLY" = "1" ]; then
|
||||
if ! rm -rf "$path"; then
|
||||
printf '
|
||||
[FAIL] 删不掉:%s(权限/只读挂载/immutable?)\n' "$path" >&2
|
||||
printf ' 已停在中途 —— 后面的判断没跑,收尾汇总也不会报"已删除"。\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
# 删完还要**抽验**:`rm -rf` 对某些情况会"成功"却留东西(例如非空目录里
|
||||
# 有不可删项时,某些实现返回 0)。存在即报错,别信退出码单一信号。
|
||||
if [ -e "$path" ]; then
|
||||
printf '
|
||||
[FAIL] `rm -rf` 报了成功但 %s 还在\n' "$path" >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
freed_kb=$((freed_kb + kb)); removed=$((removed + 1))
|
||||
report " $([ "$APPLY" = 1 ] && echo 删除 || echo 待删)" "$path($((kb/1024))MB)"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user