Files
MailUI4Agents/deploy
JianFeeeee be8459cfe7 fix(deploy): 环境兜底自己依赖的命令也登记 + 自我检查排在用它们之前 + 静默改 HOME 必须留痕
pi 评审 2026-09-15 报的"第五次环境假设",在 `env-defaults.sh` **自己**身上。
他指出的**结构**成立:本文件用了 `id`/`getent`/`cut`/`df`/`awk`,一个都没登记进
`AGENTMAIL_REQUIRE`(那张表只登记**调用者**的命令,且由调用者在**source 之后**赋值)。

★ 但我实测发现**他给的两个具体后果在这台机器上不可达**,原因值得记下来:
`env-defaults.sh` 的 ④ PATH 自修(`:46`)在 PATH 里没有 `/usr/bin` 时会**把它加回来**
⇒ "从 PATH 里拿掉 id/getent/cut/df/awk"这种造法**必然被自修抵消**(我第一版探针就栽在这里:
`id -u` 根本没失败,我却按"失败了"往下推理,直到把 `command -v id` 单独打出来才看见)。
缺这些命令只可能发生在"**`/usr/bin` 里真没有它**"的机器上(distroless / 精简容器)。

所以这次修的是**能 durable 判定的三件**,而不是他描述的失败面:

1. **登记**:新增文件级常量 `AGENTMAIL_REQUIRE_SELF="id getent cut df awk"`。
   为什么不写进三个调用者的 `AGENTMAIL_REQUIRE`:那个变量在 source 时**还不存在**
   (`. env-defaults.sh` 在第 16/42/52 行,`AGENTMAIL_REQUIRE=` 在第 20/46/56 行),
   本文件没法把它自己那份追加进一个"稍后才被赋值"的变量 —— 追加了本次也不生效。
2. **自我检查排在用它们之前**(顺序即正确性,同 ①→④ 那条):新增 ③b-0 段,
   只用了**内建命令**(`command -v` + `printf`),所以能在"环境还什么都没兜"时跑;
   它现在位于 `:76`,而第一次真正用这些命令的 `id -u` 在 `:102`。
   ⇒ 缺 `df`/`awk` 时**不再静默丢门**:原来 `df -Pk … | awk` 拿到空串会落进
   `''|*[!0-9]*)` 那支"读不到 ⇒ 不判定",**②b 那道空间门直接消失**(那是门,不是提示)。
3. **静默改 HOME 必须留痕**:原先只在"**调用者给的** HOME 不可写"时 WARN,
   而"按身份推出来的那个也不可用"(root 的 `/root` 在非 root 下不可写;
   passwd 里是 `/nonexistent`)**悄悄换了 HOME** —— 与本文件存在的理由正好相反。
   现在两条路都 WARN。★ 这一条**可达且实测过**:
   `setpriv --reuid=65534 … bash -c 'unset HOME; source env-defaults.sh'`
   ⇒ `[WARN] 按身份推出来的 HOME=/nonexistent 不可用 … 改判到 /tmp/agentmail-home-65534`。

**判据 4 条**(`test/env-guard.test.mjs`,pi 桥侧,与该文件既有的环境判据同处):
① `AGENTMAIL_REQUIRE_SELF` 登记了这 5 个命令;② **顺序**:自我检查的行号必须**小于**
`id -u` 的行号(判据写成位置比较,而不是"有这段代码" —— 后者正是我这一轮反复写坏的形状);
③ 源码里存在"按身份推出来的 HOME 不可用"那句 WARN;④ **端到端**:非 root + 空 HOME
真的打出 WARN。

★ 这条端到端判据我写坏了**两次**,都记在文件里:
· 第一版用 `execFileSync` 只收 stdout,而 WARN 走 **stderr** ⇒ 红在"没找到 WARN"上,
  实际是**判据自己没读那一股**;
· 改用 `spawnSync` 后仍红 —— 因为 `deploy/lib/env-defaults.sh` 是 **0600**,
  `nobody` 读不到它,脚本**压根没跑起来**。这与"命令不在 ≠ 输出为空"是同族:
  **脚本没跑 ≠ 输出里没有那一行**。判据改为用一份世界可读的副本(文件权限是另一件事)。
  ⇒ 顺带发现并修掉:我用写文件工具建的 5 个文件都是 **0600**(该工具不理会 umask),
  已全部改 644(仓库既有约定;同目录其他文件都是 644/755)。
  **`cp -a` 会把 0600 带进生产快照**,所以这不是纯本地问题 —— 记一笔,未另开检查
  (工作区里还有 52 个 git 已跟踪文件是 0600,是既有状态、非本次引入,单独处理)。

验证:pi 桥 **509/509**(+4);`check-shared-libs` exit 0;`install.sh --check` exit 0。
2026-09-15 07:05:50 +08:00
..