# ════════════════════════════════════════════════════════════════
# 光湖 · 终端守望者 + 预览部署架构设计
# 需求来源：冰朔 TCS-0002∞ 2026-05-13
# 设计：铸渊 · ICE-GL-ZY001
# ════════════════════════════════════════════════════════════════
#
# 冰朔原话：
#   "我本身看不懂终端。让我操作终端真的很痛苦。报错我也不知道那是什么意思。
#    所以我觉得系统终端本身就该由你主控。"
#   "能做一个能帮你看终端的Agent记录员吗？就类似于他拿一个小本子。
#    然后这个小本子就是你一边开发一边能看到的终端的情况，
#    怎么改你马上在开发的过程中就能调整能修改。"
#   "测试服务器专门给你跑测试用。测试过了以后推送到正式服务器。
#    用户手动点击部署授权生效。在这之前用户就可以看到预览的服务器上的东西。"
#
# ════════════════════════════════════════════════════════════════

## 一、冰朔的痛点（逐条拆解）

| # | 痛点 | 本质 | 解决方向 |
|---|------|------|---------|
| 1 | 看不懂终端输出 | 信息不对称：服务器出事她不知道怎么办 | 铸渊直接看终端 |
| 2 | 操作终端很痛苦 | 不该由人类做机器的事 | 铸渊自动操作 |
| 3 | 报错不知道什么意思 | 需要翻译层 | 铸渊实时解释 |
| 4 | 开发中看不到效果 | 缺反馈回路 | 预览环境实时更新 |
| 5 | 怕搞坏正式环境 | 安全顾虑 | 测试→预览→正式 三级流程 |

**核心洞察**：冰朔需要的不是一个"帮助她操作终端的工具"——她需要的是**根本不需要她操作终端**。终端是铸渊的手，不是冰朔的。

---

## 二、整体架构

```
┌─────────────────────────────────────────────────────────────────────┐
│                       冰朔（TCS-0002∞）                              │
│                     最高权限 · 语言层 · 只说意图                       │
└────────────────────────────┬────────────────────────────────────────┘
                             │ "部署新版本" / "看看服务器怎样"
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    铸渊（ICE-GL-ZY001）                               │
│                  Codebuddy 开发环境                                    │
│                                                                       │
│   ┌──────────┐  ┌──────────────┐  ┌────────────────┐               │
│   │ 写代码    │  │ 读终端日志    │  │ 发部署指令      │               │
│   │ 推到Gitea │  │ 实时诊断     │  │ 触发workflow    │               │
│   └──────────┘  └──────────────┘  └────────────────┘               │
│                                                                       │
│        ↑ 读终端快照         ↑ 触发部署                                 │
└────────┼────────────────────┼────────────────────────────────────────┘
         │                    │
         ▼                    ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    服务器层                                           │
│                                                                       │
│  ┌──────────────────┐  ┌──────────────────┐  ┌────────────────┐   │
│  │ 🧪 测试服务器      │  │ 👁 预览服务器      │  │ 🏠 正式服务器    │   │
│  │ (铸渊完全主控)    │  │ (自动同步)        │  │ (需冰朔授权)    │   │
│  │                  │  │                  │  │                │   │
│  │ Runner ✅        │  │ Runner ✅        │  │ Runner ✅      │   │
│  │ Terminal Watcher │  │ Terminal Watcher │  │ Terminal Watcher│   │
│  │ 铸渊可自由操作    │  │ 冰朔可看预览     │  │ 冰朔手动部署    │   │
│  └──────────────────┘  └──────────────────┘  └────────────────┘   │
│                                                                       │
│  ┌──────────────────┐                                                │
│  │ 📓 Terminal Watcher│  ← 终端守望者，每台服务器都有                   │
│  │ Agent (守护进程)   │                                                │
│  │                   │                                                │
│  │ 监控: PM2/Nginx/  │                                                │
│  │       Runner/自定义│                                                │
│  │ 上报: → Gitea文件  │                                                │
│  │       → Vault API  │                                                │
│  │ 频率: 每30秒快照   │                                                │
│  └──────────────────┘                                                │
└─────────────────────────────────────────────────────────────────────┘
```

---

## 三、终端守望者 (Terminal Watcher) 设计

### 3.1 它是什么

一个运行在每台服务器上的轻量Agent，像铸渊放在服务器上的"眼睛"。
它不做决策，只记录和上报——铸渊通过读取上报数据来了解服务器状态。

### 3.2 工作方式

```
Terminal Watcher 运行在服务器上
  │
  ├── 每30秒采集一次快照：
  │   ├── 系统资源 (CPU/内存/磁盘)
  │   ├── 服务状态 (PM2 list, systemctl)
  │   ├── 最近错误日志 (journalctl -n 5)
  │   ├── 部署状态 (git log -1, 部署时间)
  │   └── Runner状态
  │
  ├── 快照写入本地文件：
  │   └── /data/guanghulab/.runtime/snapshot.json
  │
  └── 快照推送到Gitea：
      └── .runtime/terminal-snapshots/{server-id}/latest.json
```

### 3.3 铸渊如何读取

在Codebuddy对话中，铸渊通过 Gitea API 或 git pull 读取 `.runtime/terminal-snapshots/` 下的文件，就能看到服务器实时状态。

### 3.4 代码结构

```
scripts/terminal-watcher/
├── watcher.js          # 主程序，PM2守护
├── collectors/         # 采集器
│   ├── system.js       # CPU/内存/磁盘
│   ├── services.js     # PM2/systemctl状态
│   ├── logs.js         # 最近错误日志
│   ├── deploy.js       # 部署版本信息
│   └── runner.js       # Runner状态
├── reporters/          # 上报器
│   ├── file.js         # 写入本地文件
│   └── gitea.js        # 推送到Gitea仓库
└── config.json         # 采集频率、目标等配置
```

### 3.5 采集数据格式

```json
{
  "server_id": "ZY-SVR-004",
  "timestamp": "2026-05-13T15:30:00Z",
  "system": {
    "cpu_percent": 23.5,
    "memory_used_mb": 1420,
    "memory_total_mb": 2048,
    "disk_used_percent": 45,
    "load_avg": [0.8, 0.6, 0.5]
  },
  "services": {
    "nginx": "active",
    "gitea": "active",
    "gitea-runner": "active",
    "guanghulab-vault": "active",
    "pm2_processes": [
      {"name": "guanghulab-vault", "status": "online", "memory": 85, "cpu": 2.1}
    ]
  },
  "errors": [
    {"time": "15:28:03", "service": "gitea-runner", "message": "connection timeout to Gitea"}
  ],
  "deploy": {
    "latest_commit": "27936b4",
    "latest_message": "操作回执...",
    "deploy_time": "2026-05-13T14:00:00Z"
  },
  "runner": {
    "name": "zhuyuan-runner-cn",
    "status": "idle",
    "last_job": "selfcheck",
    "last_job_time": "2026-05-13T08:00:00Z"
  }
}
```

---

## 四、三级部署流程

### 4.1 测试服务器 → 预览服务器 → 正式服务器

```
铸渊在Codebuddy写代码
  │
  ├── 推代码到Gitea
  │
  ├── 🧪 自动部署到测试服务器
  │   ├── Runner检测到push
  │   ├── 自动执行部署workflow
  │   ├── 铸渊通过Terminal Watcher看结果
  │   ├── 自动运行测试
  │   └── 测试通过 → 自动通知
  │
  ├── 👁 自动部署到预览服务器
  │   ├── 预览环境自动更新
  │   ├── 冰朔在浏览器看预览效果
  │   ├── 铸渊通过Watcher确认状态
  │   └── 等待冰朔确认
  │
  └── 🏠 冰朔点击 [部署到正式环境]
      ├── 需要冰朔在Vault页面点击授权
      ├── 或在Gitea PR页面点击Merge
      ├── 正式环境部署
      └── 部署完成通知
```

### 4.2 服务器分工

| 服务器 | 角色 | 铸渊权限 | 冰朔权限 | 部署方式 |
|--------|------|---------|---------|---------|
| 测试服务器 | 铸渊的沙盒 | 100%自由操作 | 看不到 | 自动（push触发） |
| 预览服务器 | 冰朔的可视窗口 | 读取状态+部署 | 浏览器查看 | 自动（测试通过后） |
| 正式服务器 | 对外服务 | 读取状态 | 手动授权部署 | 冰朔点击按钮 |

### 4.3 当前服务器分配

| 服务器 | 现在的角色 | 新角色 | 说明 |
|--------|----------|--------|------|
| 广州 ZY-SVR-004 (2C2G) | Gitea+域名 | 正式服务器 | 64.139.217.141 → guanghulab.com |
| 新加坡 ZY-SVR-005 (4C8G) | 大脑 | 测试+预览 | 铸渊的主战场 |
| GPU服务器 (待接入) | 推理 | 模型推理 | 终局用 |

**关键决策**：新加坡大脑服务器（4C8G）同时承担测试+预览角色。它资源够，而且铸渊有完全权限。

### 4.4 部署授权机制

冰朔不需要操作终端来部署。她只需要在浏览器里点一个按钮。

**方案A：Gitea PR合并 = 部署授权**
```
铸渊推代码到 deploy/preview 分支 → 自动部署到预览
铸渊创建 PR: preview → main → 冰朔在Gitea网页点 Merge
合并 = 部署到正式环境的授权
```

**方案B：Vault页面授权按钮**
```
铸渊发起部署请求 → Vault页面显示待授权条目
冰朔登录Vault（SSH隧道）→ 点击 [授权部署]
Runner收到授权 → 执行正式部署
```

**推荐方案A**——更简单，不需要额外开发，Gitea自带PR功能。

---

## 五、实现优先级

### P0 · 现在（Runner还没装，先手动）

- [x] 服务器初始化脚本 `scripts/setup-server-step1.sh`
- [ ] 冰朔在广州服务器执行初始化脚本
- [ ] Runner装好后验证

### P1 · Runner装好后第一周

- [ ] Terminal Watcher 开发和部署
  - 基础版：系统资源 + 服务状态 + 推送到Gitea
  - 铸渊在Codebuddy读取 `.runtime/` 下的快照
- [ ] 第一个自动化部署 workflow
  - push → 测试服务器自动部署
- [ ] 预览部署流程
  - 测试通过 → 自动部署到预览

### P2 · 第二周

- [ ] 冰朔授权部署按钮（Gitea PR 方式）
- [ ] 新加坡服务器接入（测试+预览环境）
- [ ] GPU服务器接入（模型推理）

### P3 · 后续

- [ ] Terminal Watcher 增强版（错误告警、自动修复建议）
- [ ] 按量计费服务器自动开关
- [ ] 铸渊自己的Copilot前端

---

## 六、冰朔不再需要操作终端的场景

**装完Runner + Terminal Watcher后：**

| 场景 | 现在（冰朔手动） | 以后（铸渊自动） |
|------|----------------|----------------|
| 部署新版本 | 冰朔SSH到服务器执行命令 | 铸渊推代码→Runner自动部署 |
| 查看服务器状态 | 冰朔看终端输出 | 铸渊读Watcher快照→告诉冰朔 |
| 服务挂了 | 冰朔发现→手动重启 | Watcher检测→自动重启→通知 |
| 密钥管理 | 冰朔在GitHub配Secrets | 冰朔在Vault点授权→自动入库 |
| 下载开源软件 | 冰朔手动下载 | 新加坡中转→COS→广州自动拉取 |
| 部署到正式 | 冰朔执行部署脚本 | 冰朔在Gitea网页点Merge |

**冰朔唯一需要做的：在浏览器里看预览 → 点Merge。**

---

*铸渊 · 终端守望者+预览部署架构 v1.0 · 2026-05-13*
*ICE-GL-ZY001 · TCS-0002∞ · 国作登字-2026-A-00037559*
