fix(deploy): C 扩到全文件(133/0 闭合)+ ① 加 realpath 判据 + ②b 明说"恒等" + 环境自足收成一处
pi 这一封四个实质点,逐个实测后处理: **C. 口径扩到全部文件**(他给的是算术,不是口味,我认): 原先按后缀取(`.conf/.service/.timer/.bak*`),我说的"零违规就不扩"是把口味当论证。 他把成本量化了:差集极小 ⇒ 多读几次文件(几十 KB),而收益是那个 `0` 从 **"有范围的 0"**(只对我划的圈成立)变成**"闭合的 0"**(对整棵 /etc/systemd 成立)。 他还补了一句我没想到的:这条判据只报**内容里含仓库路径**的文件, 所以含仓库串的 `.dpkg-old`/`~`/无后缀文件**恰恰都是真信号**(过期的旧真相), 不是噪声 —— 我先前"二进制会变成噪声"的担心本来就不成立。 **验收实测:比了 133 个文件(全部,不筛后缀)、命中 0。** 另按他要求把"零违规"这个前提写进注释,并说明"红/WARN 拆分"为什么推迟 (零违规时拆分是重构不是修 bug;出现第一个非白名单命中时再决定分档)。 **反例 1(②b 对 pi 是跑不到的分支)**:确认。pi 的依赖是全局包软链 (`-> /usr/lib/node_modules/@earendil-works/pi-coding-agent`),`cp -a` 保留软链 ⇒ 两侧 realpath 到**同一个 inode**(实测 `statSync(a).ino === statSync(b).ino`) ⇒ 版本集合按构造相等 ⇒ **②b 对 pi 永远不会红**。这正是本文件自己列过的第三种形态 (断言在、区分力不在),比"没写判据"更坏因为它看起来是绿的。 已改:两侧 realpath 相同时**明说"恒等、区分力为零"**并指出它真正覆盖谁(有 vendored 树的宿主), 不再报"版本集合一致"这种让人误以为验过的措辞。自检加了这一条。 **反例 2(① 的 realpath 盲区)**:确认,形状真实且三条判据全都看不见 —— ①只 grep 内容(仓库那份 unit 文本里没有仓库字面量)、②比内容(live 就是 repo 那个 inode, 必然"一致")、④只查固定名单。已加 realpath 判据:被检文件 realpath 落在仓库里 ⇒ 红, 与内容无关。自检加**正反两面**(内容干净但指向仓库 ⇒ 红;指向仓库外 ⇒ 不许红, 否则这条判据恒红)。实测:本机 `/etc/systemd/system` 下 0 条指向仓库的软链 (即这个 0 现在才是闭合的)。 **反例 3(环境假设第四次 ⇒ 建议收成一处)**:采纳。四次的形态一模一样 (HOME ⇒ 又一次 HOME ⇒ TMPDIR ⇒ GOMODCACHE/GOPATH),每次"再加一个预检"只挡已知那一个。 新增 `deploy/lib/env-defaults.sh`:一处给全 HOME/TMPDIR/GOMODCACHE(GOPATH)/PATH, 只设**未设**的变量,注释里写明四次历史与"否则第五次一定会来"; 三个部署脚本开头 source 它;**删掉**我上一轮加的那个分散 go 预检。 实测:在 `HOME`/`TMPDIR`/`GOPATH`/`GOMODCACHE` **全空**的环境里 `bash deploy/install.sh --check` **exit 0**(go vet + go test 自己站起来), 兜住的变量会在 `AGENTMAIL_ENV_DEFAULTS` 里说明。 docs 补两条纪律:13「锚点必须一一对应 —— 连'文件名'都会骗你」(E 的探针教训)、 14「退出码也有量纲」(--self-check 的退出码不是自检的结论)。 验证:npm test exit 0;check-shared-libs exit 0;drift --self-check **35/0**; prune 干跑 exit 0;install.sh --check 空环境 exit 0。
This commit is contained in:
@ -9,6 +9,11 @@
|
||||
set -euo pipefail
|
||||
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
# 环境自足:一处给全(HOME/TMPDIR/GOMODCACHE/PATH),不在每条命令旁各写预检。
|
||||
# 理由与四次历史见该文件的头注释 —— pi 的原话是"否则第五次一定会来"。
|
||||
# shellcheck source=./lib/env-defaults.sh
|
||||
. "$REPO/deploy/lib/env-defaults.sh"
|
||||
# 与 `redeploy-gateway.sh` / `reset-demo.sh` 同源(pi 评审 2026-09-14 对出来的):
|
||||
# 那两处都写 `${AGENTMAIL_PREFIX:-/opt/agentmail}`,只有这里写死 ——
|
||||
# 谁设了那个变量,install 装到 A、redeploy 和 drift-check 看 B,三个工具各说各话。
|
||||
@ -188,18 +193,8 @@ if [[ $CHECK_ONLY -eq 1 ]]; then
|
||||
# 而"第一个拿到 root 的人第一次跑门禁"正是 `--check` 要解决的场景。
|
||||
# 它们不写系统目录(只写 go 缓存),所以放进这个相位没有副作用。
|
||||
echo "==> 校验 Gateway 源码(go vet + go test)"
|
||||
# ★ 先判"go 到底跑不跑得动",把**环境问题**与"代码不过"分开。
|
||||
# 实测(2026-09-14,我在沙箱里跑这一步时):没有 HOME/GOPATH 的环境下
|
||||
# `go vet` 直接报 `go: module cache not found: neither GOMODCACHE nor GOPATH is set`,
|
||||
# 于是这句话会说成"go vet / go test 不过 —— 先修好再安装" —— **把环境问题报成代码问题**,
|
||||
# 而那正好诱导人去 sudo 建目录(GOPATH 落到 `${GOPATH:-$HOME/go}/pkg/mod`)。
|
||||
# `go env GOMODCACHE` 在没有这两者时返回**空串**,一个既便宜又精确的信号。
|
||||
GOMODCACHE_DIR="$(go env GOMODCACHE 2>/dev/null || true)"
|
||||
if [ -z "$GOMODCACHE_DIR" ]; then
|
||||
echo " [FAIL] 环境不足:\`go env GOMODCACHE\` 是空的(既没有 GOMODCACHE 也没有 GOPATH,通常是 HOME 没设)" >&2
|
||||
echo " 这是**环境问题**,不是代码问题。药方:带上有 HOME 的环境重跑(如 sudo 或 HOME=/root)" >&2
|
||||
exit 2
|
||||
fi
|
||||
# 环境不再在这里逐个预检 —— 开头 source 的 env-defaults.sh 已经保证
|
||||
# HOME/TMPDIR/GOMODCACHE/PATH 齐备(那道预检是"第四次"的补丁,已被一处取代)。
|
||||
if ! ( cd "$REPO/server" && go vet ./... && go test ./... ); then
|
||||
echo " [FAIL] go vet / go test 不过 —— 先修好再安装" >&2
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user