# 自动化账号（automation accounts）

记录项目里的**机器账号**：身份、用途、token、scope、轮换流程、撤销影响。
开发者本人 PAT（chentao.jia / hongwei.zhang 等）不在此列。

## AIBot

| 字段 | 值 |
|---|---|
| Gitea username | `AIBot`（实际账号名以 Gitea 后台为准，落地于 PR #281） |
| 用途 | **只读 + 评论 + issue 维护** 类任务的执行者 |
| **不参与 PR 合并** | 严格禁止——见 `CLAUDE.md`「PR 合并规则」段；旧的 `gitea-pr-merge.py` relax-dance 已在 PR #304 删除 |

### 现有 secrets（Gitea Actions repo secrets）

| Secret 名 | 用在哪 | 最小 scope |
|---|---|---|
| `AI_REVIEW_GITEA_TOKEN` | `.gitea/workflows/ai-review.yml`（写 PR 评论 + 状态）；`.gitea/workflows/lockfile-diff.yml`（写 PR 评论） | `read:repository` + `write:issue` + `write:status` |
| `WEEKLY_RETRO_TOKEN` | `.gitea/workflows/weekly-retro.yml` + `scripts/ops/weekly-retro-issue.py` + `.gitea/workflows/weekly-stale-sweep.yml` | `read:repository` + `write:issue` + **`write:repository`**（sweep `--sweep-orphan --execute` 用 `DELETE /branches/{name}` 删 orphan 分支需要） |

### Host-deployed secret（auto-merge daemon，2026-05-19 上线）

跟 Gitea Actions secret 平行的另一类：daemon 跑在 host 本机的 systemd 上，token 通过 `EnvironmentFile=/etc/auto-merge-daemon/env` 注入，**不进 Gitea secret store**。

| Secret 名 | 用在哪 | 最小 scope | 部署位置 |
|---|---|---|---|
| `AIBOT_MERGE_TOKEN`（runtime 用 env var `GITEA_API_TOKEN` 名字）| `scripts/ops/auto-merge-develop.py`（被两台 dedicated runner 的 systemd timer 触发） | `write:repository` + `read:user` | `.48` 和 `.155` 各一份 `/etc/auto-merge-daemon/env`（chmod 600 root:root） |

AIBot 不是 PR 作者，可正常 approve + merge，**不需要绕过分支保护**。

**部署方法**：
```bash
export AIBOT_MERGE_TOKEN=<新生成 token>
bash scripts/ops/auto-merge-daemon/deploy.sh 43.166.205.48 0
bash scripts/ops/auto-merge-daemon/deploy.sh 43.166.182.155 2
```

完整架构 + 故障模式见 [`docs/ops/03-auto-merge-daemon.md`](./03-auto-merge-daemon.md)。

### 历史背景

2026-05-19 前 `AIBOT_MERGE_TOKEN` 由 `.gitea/workflows/auto-merge.yml` 通过 Gitea Actions cron 调用，token 走 secret `AI_REVIEW_GITEA_TOKEN`（共用，因 write:repository scope 是它的超集）。2026-05-19 把 cron 搬到本地 daemon（issue #437）后，token 独立到 host 上，跟 ai-review 解耦——任一泄漏不影响另一边。

### scope 取舍原则

最小够用——每个 secret 只授当前 workflow 真用得到的权限。例：
- ai-review 不需要 `write:repository`（不改代码、不合 PR）→ 给 `write:issue + write:status` 就够
- weekly-retro 不需要 `write:status`（不报 CI 状态）→ 不给

如果 token 泄漏，影响范围跟 scope 严格挂钩。

### 轮换流程

1. 用 AIBot 账号登录 Gitea → Settings → Applications → Generate New Token
   - **不删旧 token**——给新旧并存窗口
2. 改 Gitea Actions repo secrets：把 `AI_REVIEW_GITEA_TOKEN` / `WEEKLY_RETRO_TOKEN` 替换为新 token 值
3. 手动触发对应 workflow 验证新 token 工作（ai-review 触发：PR 上评论 `/ai-review`；weekly-retro 触发：在 workflow 页面 `workflow_dispatch`）
4. 验证通过后，回到 Settings → 撤销旧 token
5. 在 `.learnings/` 或本文件下方 changelog 记录轮换日期 + 原因

### 撤销影响

撤销 AIBot 任一 token 会让：
- 对应的 workflow / 脚本立刻失败（HTTP 401）
- 业务**不受影响**：ai-review 失败 ≠ PR 不能合（CI 全过 + 人手 review 仍是金标准）

不会影响：
- PR 合并（AIBot 不参与合并）
- 本地开发脚本（开发者本人 PAT）
- 业务数据

### 谁能管理

- AIBot 的密码 / 邮箱 / 二次密钥：项目 admin（当前是 `hongwei.zhang` / `chentao.jia`，落地于 PR #281）
- token rotate：任何能登 AIBot 账号的人

### 应急停用

token 怀疑泄漏时：
1. 立刻进 Gitea → AIBot Settings → Revoke 该 token（生效即时）
2. 走轮换流程生成新 token + 改 secret
3. 在 issue tracker 开一个 incident，记录泄漏路径 + 影响窗口

## 开发者 PAT（不在本文范围）

- 个人 PAT 配置规范见 `CLAUDE.md`「API 认证」段
- 个人 PAT 不进 Gitea Actions secrets，**不允许跨人共享**
- 本地 ops 脚本（`weekly-review.py` / `sweep-remote-stale.py`）默认读 `$GITEA_API_TOKEN`（开发者本人 PAT）

## Changelog

| 日期 | 事件 | 备注 |
|---|---|---|
| 2026-04-?? | AIBot 账号创建 + 首批 secret 配置 | PR #281 |
| 2026-05-11 | 文档化（本文件） + 删除 `gitea-pr-merge.py` relax-dance | PR #304 |
