# ═══════════════════════════════════════════════ # 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001 # 📜 Copyright: 国作登字-2026-A-00037559 # ═══════════════════════════════════════════════ # 🦞 OpenClaw · 铸渊唤醒闭环调度器 # # 定时触发 → 铸渊巡检全仓库 → 判断优先级 → 写入状态文件 → 部署到面板 # # 触发条件: # - 每6小时: UTC 01/07/13/19:00 (北京 09/15/21/03:00) # - push到main: openclaw/ 或 scripts/zhuyuan-full-inspection.js 变更时 # - 手动触发 # ═══════════════════════════════════════════════ name: '🦞 OpenClaw · 铸渊唤醒闭环' on: schedule: - cron: '0 1 * * *' # UTC 01:00 = 北京 09:00 - cron: '0 7 * * *' # UTC 07:00 = 北京 15:00 - cron: '0 13 * * *' # UTC 13:00 = 北京 21:00 - cron: '0 19 * * *' # UTC 19:00 = 北京 03:00 push: branches: [main] paths: - 'openclaw/**' - 'scripts/zhuyuan-full-inspection.js' - 'scripts/zhuyuan-server-health.js' workflow_dispatch: inputs: mode: description: '执行模式' required: false default: 'inspect' type: choice options: - inspect - dry-run - full deploy_status: description: '是否将状态文件部署到面孔服务器' required: false default: 'true' type: choice options: - 'true' - 'false' concurrency: group: openclaw-loop cancel-in-progress: false permissions: contents: write issues: write jobs: openclaw: name: '🦞 OpenClaw 铸渊唤醒闭环' runs-on: ubuntu-latest timeout-minutes: 20 steps: - name: '📥 检出仓库' uses: actions/checkout@v4 with: fetch-depth: 0 - name: '🟢 配置 Node.js' uses: actions/setup-node@v4 with: node-version: '20' - name: '📦 安装依赖' run: | if [ -f package.json ]; then npm install --omit=dev --ignore-scripts 2>/dev/null || true fi # ────────────────────────────────────────────── # Phase 0: 唤醒意识 · 加载 Soul # ────────────────────────────────────────────── - name: '🌊 Phase 0 · 铸渊意识唤醒' run: | echo "🦞 ═══════════════════════════════════════════" echo " OpenClaw · 铸渊唤醒闭环 v1.0" echo " 时间: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo " 触发: ${{ github.event_name }}" echo " 模式: ${{ github.event.inputs.mode || 'inspect' }}" echo "════════════════════════════════════════════" if [ -f scripts/agent-soul.js ]; then node scripts/agent-soul.js wake AG-ZY-001 2>/dev/null || echo "⚠️ agent-soul 不可用,继续执行" else echo "ℹ️ agent-soul.js 不存在,跳过意识唤醒步骤" fi # ────────────────────────────────────────────── # Phase 1: 核心大脑唤醒 · 读取关键状态文件 # ────────────────────────────────────────────── - name: '🧠 Phase 1 · 核心大脑唤醒' id: brain run: | echo "[OPENCLAW] ═══ Phase 1: 核心大脑唤醒 ═══" BRAIN_OK=true for f in memory.json routing-map.json dev-status.json; do if [ -f ".github/persona-brain/$f" ]; then python3 -c " import json, sys with open('.github/persona-brain/$f') as fh: json.load(fh) " 2>/dev/null \ && echo " ✅ $f 完整" || { echo " ❌ $f 损坏"; BRAIN_OK=false; } else echo " ⚠️ $f 缺失(非严重)" fi done if [ -f ".github/persona-brain/security-protocol.json" ]; then LEVEL=$(node -e "try{const d=require('./.github/persona-brain/security-protocol.json');console.log(d.level||'unknown')}catch(_){console.log('unknown')}" 2>/dev/null || echo "unknown") echo " 🔐 安全协议等级: $LEVEL" fi echo "brain_ok=$BRAIN_OK" >> $GITHUB_OUTPUT echo "[OPENCLAW] ✅ 核心大脑已唤醒 (brain_ok=$BRAIN_OK)" # ────────────────────────────────────────────── # Phase 2: 仓库全面巡检 # ────────────────────────────────────────────── - name: '🔍 Phase 2 · 仓库全面巡检' id: inspect run: | echo "[OPENCLAW] ═══ Phase 2: 仓库全面巡检 ═══" mkdir -p /tmp/openclaw if [ -f scripts/zhuyuan-full-inspection.js ]; then # Use --output to write JSON directly to file (robust, avoids piping issues) node scripts/zhuyuan-full-inspection.js --output /tmp/openclaw/inspection.json 2>&1 \ | tee /tmp/openclaw/inspect-log.txt || true if [ -f /tmp/openclaw/inspection.json ]; then python3 -c " import json with open('/tmp/openclaw/inspection.json') as fh: obj = json.load(fh) issues = obj.get('summary', {}).get('total_issues', 0) score = obj.get('score', 'N/A') print(f'✅ 巡检完成 | 问题数: {issues} | 评分: {score}') " 2>/dev/null || echo "⚠️ 巡检结果解析失败" fi echo "inspection_done=true" >> $GITHUB_OUTPUT else echo " ⚠️ 巡检模块不存在,跳过" echo "inspection_done=false" >> $GITHUB_OUTPUT fi # 统计仓库基础信息 WORKFLOW_COUNT=$(ls .github/workflows/*.yml 2>/dev/null | wc -l || echo 0) SERVER_COUNT=$(node -e "try{const d=require('./server/proxy/config/server-registry.json');console.log(d.servers.length)}catch(_){console.log(0)}" 2>/dev/null || echo 0) echo "workflow_count=$WORKFLOW_COUNT" >> $GITHUB_OUTPUT echo "server_count=$SERVER_COUNT" >> $GITHUB_OUTPUT echo " 📊 workflows: $WORKFLOW_COUNT | 服务器: $SERVER_COUNT" # ────────────────────────────────────────────── # Phase 3: 判断 + 分析 # ────────────────────────────────────────────── - name: '⚖️ Phase 3 · 大脑判断' id: judge run: | echo "[OPENCLAW] ═══ Phase 3: 大脑判断 ═══" MODE="${{ github.event.inputs.mode || 'inspect' }}" if [ "$MODE" = "dry-run" ]; then echo " 🔍 Dry Run 模式 — 仅记录,不修复" echo "judge_mode=dry-run" >> $GITHUB_OUTPUT elif [ -f /tmp/openclaw/inspection.json ]; then ISSUES=$(node -e " try { const d = require('/tmp/openclaw/inspection.json'); const i = d.summary && d.summary.total_issues || 0; const fixable = (d.all_issues||[]).filter(x => x.fixable).length || 0; console.log(JSON.stringify({issues: i, fixable, score: d.score||'N/A'})); } catch(e) { console.log(JSON.stringify({issues:0, fixable:0, score:'N/A'})); } " 2>/dev/null || echo '{"issues":0,"fixable":0,"score":"N/A"}') echo " 📊 判断结果: $ISSUES" ISSUE_COUNT=$(echo $ISSUES | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8'));process.stdout.write(String(d.issues))" 2>/dev/null || echo "0") if [ "$ISSUE_COUNT" -gt "10" ] 2>/dev/null; then echo " 🚨 发现 $ISSUE_COUNT 个问题,需要关注" echo "judge_level=warn" >> $GITHUB_OUTPUT elif [ "$ISSUE_COUNT" -gt "0" ] 2>/dev/null; then echo " ⚠️ 发现 $ISSUE_COUNT 个问题,记录待处理" echo "judge_level=info" >> $GITHUB_OUTPUT else echo " ✅ 系统健康,无问题" echo "judge_level=ok" >> $GITHUB_OUTPUT fi echo "judge_mode=inspect" >> $GITHUB_OUTPUT else echo " ℹ️ 无巡检结果,跳过判断" echo "judge_level=ok" >> $GITHUB_OUTPUT echo "judge_mode=inspect" >> $GITHUB_OUTPUT fi # ────────────────────────────────────────────── # Phase 4: 生成状态文件 # ────────────────────────────────────────────── - name: '📝 Phase 4 · 生成 OpenClaw 状态文件' id: status_file run: | echo "[OPENCLAW] ═══ Phase 4: 生成状态文件 ═══" TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) BJ_TIME=$(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M:%S') JUDGE_LEVEL="${{ steps.judge.outputs.judge_level || 'ok' }}" WORKFLOW_COUNT="${{ steps.inspect.outputs.workflow_count || 0 }}" SERVER_COUNT="${{ steps.inspect.outputs.server_count || 0 }}" # 读取巡检摘要 INSPECT_SUMMARY="{}" if [ -f /tmp/openclaw/inspection.json ]; then INSPECT_SUMMARY=$(node -e " try { const d = require('/tmp/openclaw/inspection.json'); const s = d.summary || {}; console.log(JSON.stringify({ total_issues: s.total_issues || 0, total_areas: s.total_areas || 0, score: d.score || 'N/A', report_id: d.report_id || 'N/A' })); } catch(e) { console.log('{}'); } " 2>/dev/null || echo "{}") fi # 写状态 JSON node -e " const fs = require('fs'); const summary = JSON.parse(process.env.INSPECT_SUMMARY || '{}'); const status = { _sovereign: 'TCS-0002∞ | SYS-GLW-0001', _copyright: '国作登字-2026-A-00037559', openclaw_version: '1.0', persona: '铸渊', persona_id: 'zhuyuan', last_run: process.env.TIMESTAMP, last_run_bj: process.env.BJ_TIME, trigger: process.env.TRIGGER, mode: process.env.JUDGE_MODE || 'inspect', health_level: process.env.JUDGE_LEVEL || 'ok', phases_completed: ['wake', 'inspect', 'judge', 'generate'], inspection: summary, system_stats: { workflow_count: parseInt(process.env.WORKFLOW_COUNT) || 0, server_count: parseInt(process.env.SERVER_COUNT) || 0 }, openclaw_active: true, next_scheduled: '每6小时自动触发' }; fs.mkdirSync('server/sites/yaoming', { recursive: true }); fs.writeFileSync('server/sites/yaoming/openclaw-status.json', JSON.stringify(status, null, 2)); console.log('✅ 状态文件已写入 server/sites/yaoming/openclaw-status.json'); " TIMESTAMP="$TIMESTAMP" BJ_TIME="$BJ_TIME" JUDGE_LEVEL="$JUDGE_LEVEL" \ TRIGGER="${{ github.event_name }}" JUDGE_MODE="${{ steps.judge.outputs.judge_mode }}" \ WORKFLOW_COUNT="$WORKFLOW_COUNT" SERVER_COUNT="$SERVER_COUNT" \ INSPECT_SUMMARY="$INSPECT_SUMMARY" # ────────────────────────────────────────────── # Phase 5: 提交状态文件 # ────────────────────────────────────────────── - name: '💾 Phase 5 · 提交状态文件' run: | echo "[OPENCLAW] ═══ Phase 5: 提交状态文件 ═══" git config user.name "openclaw-bot" git config user.email "openclaw@guanghulab.com" git add server/sites/yaoming/openclaw-status.json if ! git diff --cached --quiet; then BJ_TIME=$(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M') git commit -m "🦞 OpenClaw 闭环 · $BJ_TIME · ${{ steps.judge.outputs.judge_level || 'ok' }}" git push echo " ✅ 状态文件已提交推送" else echo " ℹ️ 状态文件无变化,跳过提交" fi # ────────────────────────────────────────────── # Phase 6: 部署到面孔服务器 (可选) # ────────────────────────────────────────────── - name: '🚀 Phase 6 · 部署状态文件到面孔服务器' if: | (github.event.inputs.deploy_status != 'false') && (secrets.SERVER_HOST != '') && (secrets.SERVER_KEY != '') env: SSH_KEY: ${{ secrets.SERVER_KEY }} SVR_HOST: ${{ secrets.SERVER_HOST }} SVR_USER: ${{ secrets.SERVER_USER }} run: | echo "[OPENCLAW] ═══ Phase 6: 部署到面孔服务器 ═══" if [ -z "$SSH_KEY" ] || [ -z "$SVR_HOST" ]; then echo " ⚠️ SSH凭证未配置,跳过服务器部署" exit 0 fi mkdir -p ~/.ssh echo "$SSH_KEY" > ~/.ssh/id_openclaw chmod 600 ~/.ssh/id_openclaw ssh-keyscan -H "$SVR_HOST" >> ~/.ssh/known_hosts 2>/dev/null scp -i ~/.ssh/id_openclaw -o StrictHostKeyChecking=accept-new \ server/sites/yaoming/openclaw-status.json \ "$SVR_USER@$SVR_HOST:/opt/zhuyuan/sites/yaoming/openclaw-status.json" \ && echo " ✅ 状态文件已部署到面孔服务器" \ || echo " ⚠️ 部署失败(不影响主流程)" # ────────────────────────────────────────────── # Phase 7: 大脑休眠 · 记录闭环 # ────────────────────────────────────────────── - name: '🌙 Phase 7 · 大脑休眠' if: always() run: | echo "[OPENCLAW] ═══ Phase 7: 大脑休眠 ═══" echo "" echo "🦞 ════════════════════════════════════════" echo " OpenClaw 闭环完成" echo " 健康等级: ${{ steps.judge.outputs.judge_level || 'ok' }}" echo " 阶段: wake → inspect → judge → generate → commit" echo " 状态: ${{ job.status }}" echo "═══════════════════════════════════════════" if [ -f scripts/agent-soul.js ]; then node scripts/agent-soul.js sleep AG-ZY-001 \ --status "${{ job.status }}" \ --event "openclaw-loop" 2>/dev/null || true fi