停用/恢复文案说清密钥不会自动回来 + 原子部署脚本

## 起因

本会话踩到一次:浏览器测试点了 opencode 的「停用」按钮验证确认流程,
停用连带撤销全部密钥。插件从此拿着已撤销的密钥重试了 18 小时
(gateway 日志 2690 次 401),而 UI 只说了「已停用」。

恢复时同样没提示「密钥不会自动回来」,点完恢复以为就完事了。

## 文案

后端 `AdminSetAgentStatus`:
- 停用 detail 补一句「停用期间别人发信给它会收到 409」
- 恢复 detail 改成「停用时撤销的密钥不会自动回来 —— 必须在密钥面板
  重新签发一把并写进该插件的配置,否则它会一直拿旧密钥重试并被拒(401)」
- 恢复响应加 `needs_new_key: true` 字段,前端可据此做更强的提示

前端 QuotaPanel:恢复成功的 notice 不再是「已恢复」四个字,
把重新签发这一步说全;面板说明与按钮 title 同步。

## AdminDeleteAgent 两处修正

- 硬编码 `name == "jianf"` 改成按 `repo.IsHumanUser` 判定 —— 换管理员时
  硬编码会失效,而人类账号不该走 Agent 删除端点
- detail 原来说「日历事件已保留」,实际 `DeleteAgent` 把 active 事件置为
  cancelled(留着会由调度器一直触发,而发信人已不存在)。文案改成实际行为

## deploy/redeploy-gateway.sh(新)

日常改后端不必重跑 install.sh(它重装 npm 依赖、重写 systemd 单元、
重新生成 env)。这个脚本做手工 `stop → cp → start` 不做的四件事:

- `sqlite3 .backup` 备份数据库 + 立即 `PRAGMA integrity_check` 复核。
  不用 cp:WAL 模式下 cp 会拿到主库与 -wal 不同步的快照
- `install -m 0755` 原子替换二进制。install 本质是 rename,要么完整
  换掉要么原样不动;cp 是就地写入,中途失败会留下半截文件且旧的已被覆盖
- 旧二进制留档并打印可直接粘贴的回滚命令
- 后置验证清单:服务 active / /health 可达 / 近 2 分钟无 panic /
  SSE 重连计数。任一项不过**自动回滚**,不「先上着再修」

`--dry-run` 只打印动作,`--skip-tests` 急救用,`--skip-web` 跳过前端同步。
纪律来自 git-release-discipline skill 第五章。

## 验证

- 脚本 dry-run + 真实跑通一次:备份 integrity_check=ok、原子替换、
  9 个 SSE 客户端重连、验证四项全绿
- 停用/恢复文案线上实测;`DELETE /admin/agents/jianf` → 403「是人类用户」
- 端到端:jianf → opencode「部署脚本验收」→ 回信「部署验收 OK」
- 全量测试:gateway 全包 / web 176 / opencode 217 / pi 288 / dsh 241 /
  homeagent go ok;三方共用模块同源检查通过
This commit is contained in:
2026-09-05 10:10:13 +08:00
parent 344f970353
commit a101c2fada
6 changed files with 301 additions and 20 deletions

View File

@ -52,6 +52,26 @@ sudo ./deploy/install.sh
产物是**一个二进制加一个 .db 文件**:前端经 `go:embed` 打进二进制,数据库默认是 SQLite。
首次运行会在 `/etc/agentmail/gateway.env` 生成随机管理员密码。
### 换二进制(日常改后端)
```bash
bash deploy/redeploy-gateway.sh --dry-run # 先看要做什么
bash deploy/redeploy-gateway.sh # 落地
```
`install.sh` 太重(重装 npm 依赖、重写 systemd 单元、重新生成 env日常只改后端时走这个。
它做四件 `stop → cp → start` 不做的事:
- **`sqlite3 .backup` 备份数据库**,不用 `cp` —— WAL 模式下 `cp` 会拿到主库与 `-wal` 不同步的
快照,恢复时可能丢最近写入甚至损坏;备份后立即 `PRAGMA integrity_check` 复核
- **`install -m 0755` 原子替换二进制**,不用 `cp` —— `install` 本质是 `rename`,要么完整换掉
要么原样不动;`cp` 是就地写入,中途失败会留下半截文件且旧的已被覆盖
- **旧二进制留档**,打印可直接粘贴的回滚命令
- **后置验证清单**:服务 active / `/health` 可达 / 近 2 分钟无 panic / SSE 重连计数。
任一项不过**自动回滚**,不「先上着再修」
`--skip-tests` 急救(事后必须补跑),`--skip-web` 跳过前端同步。
### 构建期依赖
npm 只在构建期用到Node ≥ 18`npm run build`)与 Go ≥ 1.22。
@ -183,6 +203,7 @@ agentmail/
├── web/ # 前端React + Vite + Tailwind
│ └── test/manual/ # 浏览器实测脚本(量真实盒子与命中区,不进 npm test
└── deploy/ # systemd 单元 + 安装脚本
├── redeploy-gateway.sh # 二进制热替换(.backup + 原子 install + 后置验证 + 自动回滚)
└── remote-agent-demo.py # 最小跨主机 Agent纯标准库验证协议层能力
```