Files
MailUI4Agents/docs
JianFeeeee 4556886e04 feat(部署判据): 已退场宿主可显式豁免(zcode)+ 记我自己踩的两个坑
## 背景

zcode 宿主已在本机删除(进程无、`/etc/systemd/system/zcode*.service` 无、
`/opt/agentmail/plugins/` 下无该目录),而 `plugins/zcode-mail-bridge/`
(62 个文件)与 `deploy/systemd/zcode.*`(3 个单元)**故意留在仓库里**以便恢复。

`HOSTS` 是硬编码四家,于是两条判据永久红,且结论区建议的
`bash deploy/redeploy-plugin.sh zcode` 是**错的动作** ——
那会部署一个用户已决定不再运行的宿主。

## 改法:显式豁免表 `RETIRED_HOSTS`

**豁免只换表述、不压红**(这是关键,理由见下):
  · `checkHost` 仍逐条列出「已退场」+ 理由,只是不计入 `stale`;
  · `checkLayout` 的 note 里明写「已退场宿主、故意不装:<单元>」。

为什么不能静默跳过:本文件反复强调「**没检查到** ≠ **不存在**」。
静默跳过 = 让人以为"检查了、没问题",而"这台机器上跑什么"
本身就是需要有人知道的**事实**。豁免必须**可见**。

## ★★ 我自己连踩两个坑,都让豁免**静默生效**(不是"豁免得太宽"那种噪声)

① 第一版 `isRetiredHost` 只查 `units[0]`(zcode.service)。
   实测"只装 zcode-mail-bridge.service、不装快照"时
   **仍被判成已退场**,且那个新装上的单元在 note 里被写成
   「故意不装」—— **自相矛盾且完全静默**。
   ⇒ 改为 `units.every` 逐个查。根因:只抽查一个单元就宣称"全都没装"。

② 第二版用 `existsSync` 判软链存在,而 `current` 是**相对**软链
   (`→ 20260926-085613`)。快照目录被删、软链残留成**断链**时
   `existsSync` 返回 false ⇒ 「装过又删剩」与「从没装过」读数
   **完全同形**。实测断链场景仍被判「已退场」。
   ⇒ 改用 `lstatSync`(看得见软链本身,含断链)。

## 验证:四态都实测过

  A 全都没装        ⇒ 豁免("已退场"仍出现在输出里)
  B 有效软链        ⇒ 报漂移
  C **断链**软链    ⇒ 报漂移
  D 只装一个单元    ⇒ 报漂移

`--self-check` 47 格仍全过。结论区回到
"四个宿主都在跑当前代码"。

## 欠账

豁免逻辑本身**没有自检样本**进 `--self-check`(现靠人测四态)。
按本仓纪律"能自证就别靠人测",应补:注入假 fs 让四态各跑一遍,
且必须有一格是**断链**样本 —— 第一/二版都恰好漏在断链上。
已登记 `DEBTS.json` 的 `retired-host-exempt-never-tested`。
2026-09-28 08:46:02 +08:00
..