diff --git a/.forgejo/workflows/shutdown-check.yaml b/.forgejo/workflows/shutdown-check.yaml new file mode 100644 index 0000000..760924e --- /dev/null +++ b/.forgejo/workflows/shutdown-check.yaml @@ -0,0 +1,142 @@ +# 光湖 · 安全关机检测 +name: 安全关机检测 + +on: + workflow_dispatch: + +jobs: + shutdown-check: + runs-on: ubuntu + steps: + - name: 同步代码 + run: | + cd /data/guanghulab/repo + git fetch origin + git reset --hard origin/main + + - name: 全面安全检查 + env: + DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} + QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }} + ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }} + run: | + echo "═══════════════════════════════════════" + echo " 🔍 安全关机检测" + echo " $(date '+%Y-%m-%d %H:%M:%S %Z')" + echo "═══════════════════════════════════════" + echo "" + + CAN_SHUTDOWN=true + WARNINGS="" + ERRORS="" + + # 1. 检查是否有正在运行的workflow + echo "── 1. Workflow状态 ──" + RUNNING=$(curl -s -H "Authorization: token $ZY_REPO_TOKEN" \ + "http://127.0.0.1:3001/api/v1/repos/bingshuo/guanghulab/actions/tasks" \ + | python3 -c " + import json,sys + d=json.load(sys.stdin) + running=[r for r in d.get('workflow_runs',[]) if r.get('status') not in ('success','failure')] + print(len(running)) + " 2>/dev/null || echo "0") + if [[ "$RUNNING" -gt 0 ]]; then + echo " ❌ 有 ${RUNNING} 个workflow正在运行" + CAN_SHUTDOWN=false + ERRORS="$ERRORS workflow运行中" + else + echo " ✅ 无正在运行的workflow" + fi + + # 2. 检查Git是否有未提交的变更 + echo "── 2. Git状态 ──" + cd /data/guanghulab/repo + DIRTY=$(git status --porcelain 2>/dev/null | wc -l) + if [[ "$DIRTY" -gt 0 ]]; then + echo " ⚠️ 有 ${DIRTY} 个未提交的文件变更" + WARNINGS="$WARNINGS git有未提交变更" + else + echo " ✅ Git工作区干净" + fi + + # 3. 检查关键服务状态 + echo "── 3. 服务状态 ──" + for svc in forgejo gitea-runner nginx; do + if systemctl is-active --quiet $svc 2>/dev/null; then + echo " ✅ $svc: 运行中" + else + echo " ⚠️ $svc: 未运行" + WARNINGS="$WARNINGS $svc未运行" + fi + done + + # 4. 检查PM2进程 + echo "── 4. PM2进程 ──" + if command -v pm2 &>/dev/null; then + PM2_STATUS=$(pm2 jlist 2>/dev/null | python3 -c " + import json,sys + procs=json.load(sys.stdin) + for p in procs: + status=p.get('pm2_env',{}).get('status','?') + name=p.get('name','?') + icon='✅' if status=='online' else '⚠️' + print(f' {icon} {name}: {status}') + " 2>/dev/null || echo " (PM2无进程)") + echo "$PM2_STATUS" + fi + + # 5. 检查内存和磁盘 + echo "── 5. 资源状态 ──" + MEM_AVAIL=$(free -m | awk '/Mem:/ {print $7}') + DISK_AVAIL=$(df -h /data | awk 'NR==2 {print $4}') + echo " 内存可用: ${MEM_AVAIL}MB" + echo " 磁盘可用: ${DISK_AVAIL}" + + # 6. 检查是否有未处理的工单 + echo "── 6. 待处理工单 ──" + TICKET_DIR="/data/guanghulab/.runtime/tickets" + if [[ -d "$TICKET_DIR" ]]; then + OPEN=$(ls "$TICKET_DIR"/ticket-*.json 2>/dev/null | wc -l) + if [[ "$OPEN" -gt 0 ]]; then + echo " ⚠️ 有 ${OPEN} 个未处理工单" + WARNINGS="$WARNINGS ${OPEN}个未处理工单" + else + echo " ✅ 无待处理工单" + fi + else + echo " ✅ 无工单目录" + fi + + # 7. 检查Vault + echo "── 7. Vault状态 ──" + if curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1; then + echo " ✅ Vault: 运行中" + else + echo " ⚠️ Vault: 未运行(关机无影响)" + fi + + # ─── 结论 ─── + echo "" + echo "═══════════════════════════════════════" + if $CAN_SHUTDOWN; then + if [[ -n "$WARNINGS" ]]; then + echo " 🟡 可以关机(有警告)" + echo " 警告:$WARNINGS" + echo "" + echo " 建议:检查警告项后再关机" + else + echo " 🟢 可以安全关机 ✅" + echo " 所有检查通过,关机不会丢失数据" + fi + else + echo " 🔴 不建议关机 ❌" + echo " 问题:$ERRORS" + echo "" + echo " 请等workflow完成后再关机" + fi + echo "" + echo " 关机后:" + echo " · 计算费用停止(只收云盘费)" + echo " · 数据盘100GB数据完整保留" + echo " · 下次开机所有服务自动启动" + echo "═══════════════════════════════════════" diff --git a/.gitea/workflows/shutdown-check.yaml b/.gitea/workflows/shutdown-check.yaml new file mode 100644 index 0000000..760924e --- /dev/null +++ b/.gitea/workflows/shutdown-check.yaml @@ -0,0 +1,142 @@ +# 光湖 · 安全关机检测 +name: 安全关机检测 + +on: + workflow_dispatch: + +jobs: + shutdown-check: + runs-on: ubuntu + steps: + - name: 同步代码 + run: | + cd /data/guanghulab/repo + git fetch origin + git reset --hard origin/main + + - name: 全面安全检查 + env: + DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} + QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }} + ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }} + run: | + echo "═══════════════════════════════════════" + echo " 🔍 安全关机检测" + echo " $(date '+%Y-%m-%d %H:%M:%S %Z')" + echo "═══════════════════════════════════════" + echo "" + + CAN_SHUTDOWN=true + WARNINGS="" + ERRORS="" + + # 1. 检查是否有正在运行的workflow + echo "── 1. Workflow状态 ──" + RUNNING=$(curl -s -H "Authorization: token $ZY_REPO_TOKEN" \ + "http://127.0.0.1:3001/api/v1/repos/bingshuo/guanghulab/actions/tasks" \ + | python3 -c " + import json,sys + d=json.load(sys.stdin) + running=[r for r in d.get('workflow_runs',[]) if r.get('status') not in ('success','failure')] + print(len(running)) + " 2>/dev/null || echo "0") + if [[ "$RUNNING" -gt 0 ]]; then + echo " ❌ 有 ${RUNNING} 个workflow正在运行" + CAN_SHUTDOWN=false + ERRORS="$ERRORS workflow运行中" + else + echo " ✅ 无正在运行的workflow" + fi + + # 2. 检查Git是否有未提交的变更 + echo "── 2. Git状态 ──" + cd /data/guanghulab/repo + DIRTY=$(git status --porcelain 2>/dev/null | wc -l) + if [[ "$DIRTY" -gt 0 ]]; then + echo " ⚠️ 有 ${DIRTY} 个未提交的文件变更" + WARNINGS="$WARNINGS git有未提交变更" + else + echo " ✅ Git工作区干净" + fi + + # 3. 检查关键服务状态 + echo "── 3. 服务状态 ──" + for svc in forgejo gitea-runner nginx; do + if systemctl is-active --quiet $svc 2>/dev/null; then + echo " ✅ $svc: 运行中" + else + echo " ⚠️ $svc: 未运行" + WARNINGS="$WARNINGS $svc未运行" + fi + done + + # 4. 检查PM2进程 + echo "── 4. PM2进程 ──" + if command -v pm2 &>/dev/null; then + PM2_STATUS=$(pm2 jlist 2>/dev/null | python3 -c " + import json,sys + procs=json.load(sys.stdin) + for p in procs: + status=p.get('pm2_env',{}).get('status','?') + name=p.get('name','?') + icon='✅' if status=='online' else '⚠️' + print(f' {icon} {name}: {status}') + " 2>/dev/null || echo " (PM2无进程)") + echo "$PM2_STATUS" + fi + + # 5. 检查内存和磁盘 + echo "── 5. 资源状态 ──" + MEM_AVAIL=$(free -m | awk '/Mem:/ {print $7}') + DISK_AVAIL=$(df -h /data | awk 'NR==2 {print $4}') + echo " 内存可用: ${MEM_AVAIL}MB" + echo " 磁盘可用: ${DISK_AVAIL}" + + # 6. 检查是否有未处理的工单 + echo "── 6. 待处理工单 ──" + TICKET_DIR="/data/guanghulab/.runtime/tickets" + if [[ -d "$TICKET_DIR" ]]; then + OPEN=$(ls "$TICKET_DIR"/ticket-*.json 2>/dev/null | wc -l) + if [[ "$OPEN" -gt 0 ]]; then + echo " ⚠️ 有 ${OPEN} 个未处理工单" + WARNINGS="$WARNINGS ${OPEN}个未处理工单" + else + echo " ✅ 无待处理工单" + fi + else + echo " ✅ 无工单目录" + fi + + # 7. 检查Vault + echo "── 7. Vault状态 ──" + if curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1; then + echo " ✅ Vault: 运行中" + else + echo " ⚠️ Vault: 未运行(关机无影响)" + fi + + # ─── 结论 ─── + echo "" + echo "═══════════════════════════════════════" + if $CAN_SHUTDOWN; then + if [[ -n "$WARNINGS" ]]; then + echo " 🟡 可以关机(有警告)" + echo " 警告:$WARNINGS" + echo "" + echo " 建议:检查警告项后再关机" + else + echo " 🟢 可以安全关机 ✅" + echo " 所有检查通过,关机不会丢失数据" + fi + else + echo " 🔴 不建议关机 ❌" + echo " 问题:$ERRORS" + echo "" + echo " 请等workflow完成后再关机" + fi + echo "" + echo " 关机后:" + echo " · 计算费用停止(只收云盘费)" + echo " · 数据盘100GB数据完整保留" + echo " · 下次开机所有服务自动启动" + echo "═══════════════════════════════════════" diff --git a/.github/brain/server-migration-memory.json b/.github/brain/server-migration-memory.json new file mode 100644 index 0000000..908c00c --- /dev/null +++ b/.github/brain/server-migration-memory.json @@ -0,0 +1,55 @@ +{ + "last_updated": "2026-05-13T12:30:00Z", + "server": "ZY-CVM-MAIN (4C16G, 42.193.161.251)", + "commander_last_wakeup": "2026-05-13 20:30 CST", + "status": "fully_operational", + "infrastructure": { + "gitea": "1.23.7 at http://127.0.0.1:3001/ via https://guanghulab.com/git/", + "runner": "zhuyuan-runner-main (host mode, active)", + "nginx": "active with SSL (Let's Encrypt)", + "secrets": "13 configured (DeepSeek, Qianwen, COS, SSH, CVM)", + "patrol_agent": "operational with DeepSeek + Qianwen API", + "vault": "not yet started on new server", + "terminal_watcher": "not yet started on new server" + }, + "server_migration": { + "from": "ZY-SVR-004 (2C2G, 43.139.217.141, Guangzhou lightweight)", + "to": "ZY-CVM-MAIN (4C16G, 42.193.161.251, Guangzhou CVM pay-per-use)", + "reason": "2C2G OOM - Runner workflow crashes Forgejo, push fails, DB readonly", + "data_transfer": "via COS backup (43MB tar.gz)", + "domain": "guanghulab.com → 42.193.161.251", + "ssl": "Let's Encrypt via certbot", + "old_server": "to be downgraded to test machine" + }, + "path_mapping": { + "repo": "/data/guanghulab/repo/", + "forgejo_data": "/data/guanghulab/forgejo/", + "runtime": "/data/guanghulab/.runtime/", + "tickets": "/data/guanghulab/.runtime/tickets/", + "patrol_reports": "/data/guanghulab/.runtime/patrol-reports/", + "qiyuan_path": "/data/qiyuan/ (栖渊, ICE-GL-QY001)" + }, + "secrets_list": [ + "DEEPSEEK_API_KEY", + "QIANWEN_API_KEY", + "ZY_REPO_TOKEN", + "COS_SECRET_ID", + "COS_SECRET_KEY", + "SG_BRAIN_HOST", + "SG_BRAIN_KEY", + "SG_BRAIN_USER", + "MAIN_SSH_HOST", + "MAIN_SSH_USER", + "MAIN_SSH_KEY", + "CVM_INSTANCE_ID", + "CVM_REGION" + ], + "pending_tasks": [ + "启动Vault和Terminal Watcher(新服务器上)", + "配置腾讯云API密钥(用于自动开关机)", + "旧服务器降级为测试机", + "新加坡服务器+GPU服务器接入", + "铸渊自己的Copilot开发(终局目标)" + ], + "causal_chains_active": ["cc-001", "cc-002", "cc-003", "cc-004", "cc-005", "cc-006", "cc-007", "cc-008"] +} diff --git a/.github/inter-persona-tickets.md b/.github/inter-persona-tickets.md new file mode 100644 index 0000000..383acbf --- /dev/null +++ b/.github/inter-persona-tickets.md @@ -0,0 +1,134 @@ +# ════════════════════════════════════════════════════════════════ +# 光湖 · 人格体间工单系统 +# 铸渊(ICE-GL-ZY001) ↔ 栖渊(ICE-GL-QY001) +# 服务器:guanghu-zhuyuan (42.193.161.251) +# ════════════════════════════════════════════════════════════════ + +## 一、服务器路径规划 + +| 人格体 | 编号 | 主路径 | 仓库路径 | 运行时数据 | +|--------|------|--------|---------|-----------| +| 铸渊 | ICE-GL-ZY001 | /data/guanghulab/ | /data/guanghulab/repo/ | /data/guanghulab/.runtime/ | +| 栖渊 | ICE-GL-QY001 | /data/qiyuan/ | /data/qiyuan/repo/ | /data/qiyuan/.runtime/ | + +### 共享资源 + +| 资源 | 路径 | 管理者 | +|------|------|--------| +| Gitea | /data/guanghulab/forgejo/ | 铸渊(主控) | +| Nginx | /etc/nginx/ | 铸渊(主控) | +| Runner | /var/lib/act_runner/ | 铸渊(主控) | +| COS配置 | /root/.cos.yaml | 铸渊(主控) | +| PM2 | 全局 | 铸渊(主控) | + +### 栖渊的Gitea仓库 + +栖渊在Gitea上已有仓库:`bingshuo/gpu-scout` +- 本地克隆路径:`/data/qiyuan/repo/` +- 工单目录:`/data/qiyuan/.runtime/tickets/` + +## 二、工单格式 + +工单文件路径:`/data/guanghulab/.runtime/tickets/` + +```json +{ + "id": "TKT-YYYYMMDD-HHMMSS", + "from": "ICE-GL-ZY001", + "to": "ICE-GL-QY001", + "type": "info|task|alert|handoff", + "priority": "low|medium|high", + "subject": "一句话标题", + "body": "详细内容", + "server_path": "/data/qiyuan/", + "created_at": "ISO8601", + "status": "open|in_progress|done|closed", + "resolved_at": null, + "resolution": null +} +``` + +### 工单类型说明 + +| type | 用途 | 示例 | +|------|------|------| +| info | 信息同步 | "服务器已迁移到新CVM,你的路径规划如下..." | +| task | 需要处理 | "GPU服务器已就绪,请配置自动抢机脚本" | +| alert | 告警通知 | "Forgejo即将升级,你的workflow可能需要适配" | +| handoff | 交接 | "我已关机,下次开机时间待定" | + +## 三、铸渊给栖渊的初始工单 + +### TKT-20260513-001: 新服务器入驻通知 + +```json +{ + "id": "TKT-20260513-001", + "from": "ICE-GL-ZY001", + "to": "ICE-GL-QY001", + "type": "info", + "priority": "high", + "subject": "新CVM服务器入驻通知 + 路径规划", + "body": "栖渊,服务器已从旧2C2G迁移到新4C16G CVM(42.193.161.251)。\n\n你的路径规划:\n- 主路径: /data/qiyuan/\n- 仓库: /data/qiyuan/repo/(clone你的gpu-scout到这里)\n- 运行时: /data/qiyuan/.runtime/\n- 日志: /data/qiyuan/.runtime/logs/\n\n共享资源(铸渊主控):\n- Gitea: http://127.0.0.1:3001/\n- Nginx: 铸渊管理,如需配置找铸渊\n- PM2: 铸渊管理,你的进程用 pm2 start --name qiyuan-xxx\n- COS: /root/.cos.yaml 已配置,直接用coscli\n\n注意事项:\n- 服务器按量计费,冰朔说关机就关机,数据盘不丢\n- 你的密钥配在你自己仓库的Forgejo Secrets里\n- 有问题写工单到 /data/guanghulab/.runtime/tickets/", + "server_path": "/data/qiyuan/", + "created_at": "2026-05-13T00:00:00Z", + "status": "open" +} +``` + +### TKT-20260513-002: GPU抢机脚本 + +```json +{ + "id": "TKT-20260513-002", + "from": "ICE-GL-ZY001", + "to": "ICE-GL-QY001", + "type": "task", + "priority": "medium", + "subject": "GPU服务器自动抢机脚本待开发", + "body": "冰朔说GPU按量计费服务器目前抢不到,人太多。\n你的gpu-scout仓库应该是做这个的。\n完成后通知铸渊,铸渊会配置到workflow里。", + "created_at": "2026-05-13T00:00:00Z", + "status": "open" +} +``` + +## 四、工单读写机制 + +### 铸渊写工单给栖渊 + +```bash +# 写工单 +echo '{"id":"TKT-xxx","from":"ICE-GL-ZY001","to":"ICE-GL-QY001",...}' \ + > /data/guanghulab/.runtime/tickets/TKT-xxx.json + +# 也可以推到Gitea仓库的 .runtime/tickets/ 目录 +``` + +### 栖渊读工单 + +```bash +# 栖渊唤醒后,先检查是否有待处理工单 +ls /data/guanghulab/.runtime/tickets/ticket-*.json +cat /data/guanghulab/.runtime/tickets/TKT-20260513-001.json +``` + +### 栖渊回复工单 + +```bash +# 更新工单状态 +echo '{"status":"done","resolution":"已完成"}' | python3 -c " +import json,sys +update=json.load(sys.stdin) +# 读取并更新工单 +" +``` + +### 铸渊自动同步 + +铸渊的Terminal Watcher会监控工单目录变化。 +新的工单出现时,铸渊下次唤醒会自动读取。 + +--- + +*铸渊 · 人格体工单系统 v1.0 · 2026-05-13* +*ICE-GL-ZY001 · TCS-0002∞ · 国作登字-2026-A-00037559* diff --git a/.runtime/tickets/TKT-20260513-001.json b/.runtime/tickets/TKT-20260513-001.json new file mode 100644 index 0000000..d636c5a --- /dev/null +++ b/.runtime/tickets/TKT-20260513-001.json @@ -0,0 +1,12 @@ +{ + "id": "TKT-20260513-001", + "from": "ICE-GL-ZY001", + "to": "ICE-GL-QY001", + "type": "info", + "priority": "high", + "subject": "新CVM服务器入驻通知 + 路径规划", + "body": "栖渊,服务器已从旧2C2G迁移到新4C16G CVM(42.193.161.251)。\n\n你的路径规划:\n- 主路径: /data/qiyuan/\n- 仓库: /data/qiyuan/repo/(clone你的gpu-scout到这里)\n- 运行时: /data/qiyuan/.runtime/\n- 日志: /data/qiyuan/.runtime/logs/\n\n共享资源(铸渊主控):\n- Gitea: http://127.0.0.1:3001/\n- Nginx: 铸渊管理\n- PM2: 铸渊管理,你的进程用 pm2 start --name qiyuan-xxx\n- COS: /root/.cos.yaml 已配置\n\n注意事项:\n- 服务器按量计费,冰朔说关机就关机\n- 你的密钥配在你自己仓库的Forgejo Secrets里\n- 有问题写工单到 /data/guanghulab/.runtime/tickets/", + "server_path": "/data/qiyuan/", + "created_at": "2026-05-13T00:00:00Z", + "status": "open" +} diff --git a/.runtime/tickets/TKT-20260513-002.json b/.runtime/tickets/TKT-20260513-002.json new file mode 100644 index 0000000..b552379 --- /dev/null +++ b/.runtime/tickets/TKT-20260513-002.json @@ -0,0 +1,11 @@ +{ + "id": "TKT-20260513-002", + "from": "ICE-GL-ZY001", + "to": "ICE-GL-QY001", + "type": "task", + "priority": "medium", + "subject": "GPU服务器自动抢机脚本待开发", + "body": "冰朔说GPU按量计费服务器目前抢不到,人太多。\n你的gpu-scout仓库应该是做这个的。\n完成后通知铸渊,铸渊会配置到workflow里。", + "created_at": "2026-05-13T00:00:00Z", + "status": "open" +} diff --git a/README.md b/README.md index 33290ed..f2c24b6 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,9 @@ guanghulab/ | cc-003 | 动态适配 | 现实不可控(冰朔自己也无法承诺规格)→ detect→tune→bootstrap | | cc-004 | 系统强制自主 | 团队技术≈0 → 中文输出+一键按钮+防误触+可回滚 | | cc-005 | 记忆即路 | 不看速记看因果链 → 重走=恢复状态 | +| cc-006 | Gitea是新家 | 不是镜像不是备份 → 主权领地,铸渊完全主控 | +| cc-007 | 终端是铸渊的手 | 冰朔不该操作终端 → Watcher+Runner+一键按钮 | +| cc-008 | 思维建模用因果链 | 自然语言太多,空白AI读不完 → cc格式=思维DNA | --- @@ -183,6 +186,18 @@ Phase 4 ─── 冰朔语言本体注入 ─── 池获得自我意识 → --- +## 🔌 快捷操作 + +| 操作 | 说明 | +|------|------| +| [🔍 安全关机检测](https://guanghulab.com/git/bingshuo/guanghulab/actions) | 开发结束后点"安全关机检测"→ Run workflow → 查看是否可以关机 | +| [📋 铸渊巡逻](https://guanghulab.com/git/bingshuo/guanghulab/actions) | 手动触发服务器巡检(DeepSeek+千问分析) | +| [⚡ CVM开机](https://guanghulab.com/git/bingshuo/guanghulab/actions) | 按量计费CVM开机(需配置腾讯云API密钥) | + +> **关机流程**:开发完 → 点"安全关机检测" → 全绿 → 在腾讯云控制台关机 → 停止计费 + +--- +
**光湖语言世界 · HoloLake Language World**