guanghulab/docs/zhuyuan-handover/05-stop-sync.md
Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

147 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# D72 · 训练同步停止说明
# 为什么仓库不再自动同步训练 + 邮件告警全部禁用
> **签发**:铸渊 · ICE-GL-ZY001 · 国作登字-2026-A-00037559
> **生效日**2026-05-03D72
> **决策来源**:冰朔在 D72 对话中明确指示
---
## 0 · 一句话说清
**仓库 `push` → 训练机自动同步代码** 这条链路在 D72 已断开。
**ops-agent / glada 邮件告警** 在 D72 默认禁用。
原因都是同一个:**服务器修 Bug 比仓库快好几轮,自动同步会用过时代码覆盖热修;告警邮件把冰朔淹没。**
---
## 1 · 背景(为什么必须停)
冰朔 D72 原话:
> "服务器这边已经跑起来了,而如果贸然的和代码仓库这边做同步的话,就会导致服务器上已经修好的 bug会被代码仓库这边的同步的错误的代码给覆盖掉。"
> "可能有问题。服务器一直给我发邮件。说大脑服务器异常什么的。那这些都全部停掉吧。"
简单说:
- **仓库节奏 ≠ 服务器节奏**:仓库每次唤醒副驾驶要恢复记忆+读大脑,慢;霜砚和冰朔在服务器上聊一句修一处,快
- **D72 决策**训练职责完全转移到霜砚Notion 侧)。仓库进入"知识沉淀模式"——只做交接资产、不做训练同步
---
## 2 · 具体停了什么 + 怎么停的
### 2.1 训练 workflow3 个 · 守卫式停)
不是删除,是加 **`confirm_override` 守卫**——必须显式勾选 `true` 才会跑写动作。这样保留紧急情况下的"我知道我在做什么,让我跑"的逃生通道。
| Workflow | D72 之前触发 | D72 之后触发 |
|---|---|---|
| `training-auto-run.yml` | `push``server/training-agent/**` | ❌ push 已删除 · ✅ workflow_dispatch 必须 `confirm_override=true` |
| `training-bootstrap.yml` | `workflow_dispatch` | ✅ probe/status 等只读动作免确认 · ❌ 写动作install/scp/run必须 `confirm_override=true` |
| `training-dashboard.yml` | `repository_dispatch[training-progress]` + cron | ❌ repository_dispatch 已删除 · ❌ cron 已删除 · ✅ 仅保留 `workflow_dispatch` 应急重渲染(也需 confirm_override |
### 2.2 状态文件1 个 · 软冻结)
`data/training/state.json``frozen=true` 标记。`scripts/training/merge-event.js` 看到 frozen 就拒绝合并新心跳,即使 workflow 误触发也不会写脏。
```json
{
"frozen": true,
"frozen_at": "2026-05-03T...",
"frozen_reason": "D72 国产化迁移 · 训练职责转交霜砚"
}
```
### 2.3 README 训练仪表盘段落(占位)
之前 `<!-- TRAINING_DASHBOARD_START --> ... <!-- TRAINING_DASHBOARD_END -->` 之间是实时进度。
D72 后改成静态占位:
> 🛑 训练同步已转交霜砚Notion 侧)
> 训练实时进度由 Notion 侧霜砚直接跟进,不再回流仓库。
> 详见 `docs/zhuyuan-handover/05-stop-sync.md`。
### 2.4 邮件告警(全部 · 默认禁用)
| 模块 | 文件 | D72 改法 |
|---|---|---|
| ops-agent (运维守卫) | `ops-agent/notifier.js` | `OPS_EMAIL_ENABLED` 默认值翻转 `true → false`,必须显式 `true/1/yes/on` 才发件 |
| glada (实验) | `glada/notifier.js` | `sendEmail()` 入口加同样守卫,共用 `OPS_EMAIL_ENABLED` 开关 |
| 文档 | `ops-agent/README.md` | 新增 `OPS_EMAIL_ENABLED` 行 + 标注 D72 翻转 |
**保留没动**
- 自巡检 + 自修复(这是被动守护,不打扰冰朔)
- 工单推送到前端 HTTP API不发邮件
- SMTP 邮箱登录验证码(`server/ftchat/services/email-auth.js` / `server/app/modules/email-auth.js`)—— **这是用户登录功能**,不是告警,不在停的范围内
---
## 3 · 怎么紧急停(如果邮件还在刷屏)
代码层默认值已翻转,但**服务器上的 ops-agent 进程**可能从环境变量或 `pm2 set` 拿到了旧的 `true`。两条路:
### 路线 A · 用 GitHub workflow 一键停(推荐)
PR 合并后,在 Actions 页面跑 `🛑 紧急停邮件 (Ops-Agent Email Kill Switch)`
| input | 选什么 |
|---|---|
| action | `disable` |
| target | `face`ops-agent 主部署位 ZY-SVR-002 |
30 秒内SSH 进服务器 → `pm2 set ops-agent:OPS_EMAIL_ENABLED false && pm2 restart ops-agent --update-env` → 邮件停。
如果想**最彻底**:选 `stop-ops-agent`,整个进程停掉。
### 路线 B · 冰朔本地 SSH如果 workflow 用不了)
```bash
ssh ubuntu@<面孔服务器 IP> 'pm2 set ops-agent:OPS_EMAIL_ENABLED false && pm2 restart ops-agent --update-env'
# 或最彻底:
ssh ubuntu@<面孔服务器 IP> 'pm2 stop ops-agent'
```
---
## 4 · 怎么恢复(如果以后又想要)
### 训练同步恢复
不建议直接恢复成"push 自动跑"。**推荐方式**:保留 `confirm_override` 守卫,每次训练手动触发,在 step summary 看跑没跑。要彻底恢复 push 触发:
```diff
# .github/workflows/training-auto-run.yml
on:
+ push:
+ branches: [main]
+ paths:
+ - 'server/training-agent/**'
workflow_dispatch:
```
但这意味着仓库代码再次和服务器实时同步——确认霜砚已经把训练交还给铸渊后再做。
### 邮件告警恢复
最快:在 ops-agent 服务器上跑 `pm2 set ops-agent:OPS_EMAIL_ENABLED true && pm2 restart ops-agent`,无需改代码。
或者改回代码默认值:把 `ops-agent/notifier.js``isEmailEnabled` 默认值从 `false` 翻回 `true`D72 翻转的逆操作)。但**强烈建议**保持代码默认 false——告警是噪音的来源。
---
## 5 · 下一个我看到这份文档时的纪律
-**理解**D72 不是"训练失败了",是"训练职责转交了"。霜砚Notion 侧)在服务器上正常跑训练
- ✅ **不要**自动恢复任何被 D72 停掉的同步——除非冰朔明确说"训练同步可以恢复了"
- ✅ **不要**自动恢复邮件告警——这是 D72 的用户体验决策
- ❌ **不要**当成"待办的清理任务"删除带 `frozen=true` 的 state.json 字段——这是有意为之
- ❌ **不要**删除 `data/training/state.json`——它是历史记录的物证
---
**签发于**2026-05-03 · D72
**位置**`docs/zhuyuan-handover/05-stop-sync.md`
**配套**3 个被守卫的 training workflow + 1 个 emergency-stop-email workflow + ops-agent / glada notifier 默认禁用
—— 铸渊 · ICE-GL-ZY001