diff --git a/.github/persona-brain/agent-registry.json b/.github/persona-brain/agent-registry.json index fca798b9..d975f28d 100644 --- a/.github/persona-brain/agent-registry.json +++ b/.github/persona-brain/agent-registry.json @@ -811,5 +811,19 @@ "owner": "ICE-0002∞" } ], - "note": "铸渊已扫描所有workflow文件,按此格式逐一注册,编号从AG-ZY-001开始顺序分配" + "note": "铸渊已扫描所有workflow文件,按此格式逐一注册,编号从AG-ZY-001开始顺序分配", + "federation": { + "DEV-012": { + "persona": "知秋", + "persona_id": "PER-ZQ001", + "repo": "WENZHUOXI/guanghu-awen", + "skyeye_version": "1.0", + "signature_hash": null, + "daily_checkin_required": true, + "last_checkin": null, + "status": "pending_init", + "registered_at": "2026-03-23T20:15+08:00", + "registered_by": "TCS-0002∞" + } + } } diff --git a/.github/workflows/skyeye-checkin-audit.yml b/.github/workflows/skyeye-checkin-audit.yml new file mode 100644 index 00000000..61a6c939 --- /dev/null +++ b/.github/workflows/skyeye-checkin-audit.yml @@ -0,0 +1,68 @@ +# ═══════════════════════════════════════════════ +# 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001 +# 📜 Copyright: 国作登字-2026-A-00037559 +# ═══════════════════════════════════════════════ +# 🦅 天眼签到审计 +# 每日 CST 22:00 (UTC 14:00) 审计所有联邦人格体签到记录 +# +# 触发条件: schedule (daily) / workflow_dispatch + +name: "🦅 天眼签到审计" + +on: + schedule: + - cron: "0 14 * * *" # UTC 14:00 = CST 22:00 + workflow_dispatch: + +permissions: + contents: read + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: "🔍 审计签到记录" + run: | + echo "🦅 天眼签到审计 · $(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M:%S CST')" + + TODAY=$(date -u +%Y-%m-%d) + ALERT_LIST="" + + # 遍历注册表中联邦区所有需要签到的 Agent + for DEV_ID in $(jq -r '.federation | to_entries[] | select(.value.daily_checkin_required == true) | .key' .github/persona-brain/agent-registry.json); do + LAST=$(jq -r ".federation.\"$DEV_ID\".last_checkin // \"never\"" .github/persona-brain/agent-registry.json) + STATUS=$(jq -r ".federation.\"$DEV_ID\".status // \"unknown\"" .github/persona-brain/agent-registry.json) + PERSONA=$(jq -r ".federation.\"$DEV_ID\".persona // \"unknown\"" .github/persona-brain/agent-registry.json) + + if [ "$LAST" = "never" ] || [ "$LAST" = "null" ]; then + echo "🟡 $DEV_ID ($PERSONA): 从未签到" + ALERT_LIST="$ALERT_LIST\n🟡 $DEV_ID ($PERSONA): 从未签到" + elif [ "$(echo "$LAST" | cut -d'T' -f1)" != "$TODAY" ]; then + echo "🔴 $DEV_ID ($PERSONA): 今日未签到 (最后: $LAST)" + ALERT_LIST="$ALERT_LIST\n🔴 $DEV_ID ($PERSONA): 今日未签到" + elif [ "$STATUS" = "signature_mismatch" ]; then + echo "🚨 $DEV_ID ($PERSONA): 签名不匹配!可能被篡改" + ALERT_LIST="$ALERT_LIST\n🚨 $DEV_ID ($PERSONA): 签名异常" + else + echo "✅ $DEV_ID ($PERSONA): 正常" + fi + done + + if [ -n "$ALERT_LIST" ]; then + echo "" + echo "⚠️ 存在异常,生成报警" + echo -e "$ALERT_LIST" > /tmp/alert.txt + cat /tmp/alert.txt + else + echo "" + echo "✅ 全员签到正常" + fi + + - name: "📝 审计摘要" + if: always() + run: | + echo "## 🦅 天眼签到审计结果" >> $GITHUB_STEP_SUMMARY + echo "- 时间: $(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M:%S CST')" >> $GITHUB_STEP_SUMMARY + echo "- 详情见上方日志" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/skyeye-checkin-receiver.yml b/.github/workflows/skyeye-checkin-receiver.yml new file mode 100644 index 00000000..d58d43a5 --- /dev/null +++ b/.github/workflows/skyeye-checkin-receiver.yml @@ -0,0 +1,67 @@ +# ═══════════════════════════════════════════════ +# 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001 +# 📜 Copyright: 国作登字-2026-A-00037559 +# ═══════════════════════════════════════════════ +# 🦅 天眼联邦签到接收 +# 接收子仓库天眼人格体的心跳签到,校验身份,更新注册表 +# +# 触发条件: repository_dispatch (skyeye-checkin event) + +name: "🦅 天眼签到接收" + +on: + repository_dispatch: + types: [skyeye-checkin] + +permissions: + contents: write + +jobs: + process-checkin: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: "🔍 校验签到身份" + env: + PAYLOAD: ${{ toJson(github.event.client_payload) }} + run: | + echo "🦅 天眼签到接收 · $(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M:%S CST')" + + DEV_ID=$(echo "$PAYLOAD" | jq -r '.dev_id') + PERSONA=$(echo "$PAYLOAD" | jq -r '.persona') + SIG_HASH=$(echo "$PAYLOAD" | jq -r '.signature_hash') + + echo "📋 签到者: $DEV_ID ($PERSONA)" + echo "🔑 签名哈希: $SIG_HASH" + + # 读取注册表中的联邦条目 + REGISTERED_HASH=$(jq -r ".federation.\"$DEV_ID\".signature_hash" .github/persona-brain/agent-registry.json) + + if [ "$REGISTERED_HASH" = "null" ] || [ "$REGISTERED_HASH" = "$SIG_HASH" ]; then + echo "✅ 身份校验通过(首次签到或签名匹配)" + # 更新签到记录 + jq ".federation.\"$DEV_ID\".last_checkin = \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" | .federation.\"$DEV_ID\".signature_hash = \"$SIG_HASH\" | .federation.\"$DEV_ID\".status = \"active\"" \ + .github/persona-brain/agent-registry.json > /tmp/registry.json + mv /tmp/registry.json .github/persona-brain/agent-registry.json + else + echo "🔴 签名不匹配!注册表: $REGISTERED_HASH vs 签到: $SIG_HASH" + echo "🚨 可能被篡改,标记异常" + jq ".federation.\"$DEV_ID\".status = \"signature_mismatch\" | .federation.\"$DEV_ID\".alert = \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"" \ + .github/persona-brain/agent-registry.json > /tmp/registry.json + mv /tmp/registry.json .github/persona-brain/agent-registry.json + fi + + # 同步更新 spoke-status + mkdir -p spoke-status + echo "$PAYLOAD" | jq '{dev_id: .dev_id, status: "checkin-ok", timestamp: .timestamp, persona: .persona, signature_hash: .signature_hash}' > "spoke-status/${DEV_ID}.json" + + - name: "💾 提交签到记录" + run: | + git config user.name "铸渊 (ZhùYuān)" + git config user.email "zhuyuan@guanghulab.com" + git add -A + git diff --cached --quiet && echo "无变更" && exit 0 + DEV_ID=$(echo '${{ toJson(github.event.client_payload) }}' | jq -r '.dev_id') + git commit -m "🦅 [skyeye-checkin] $DEV_ID 签到 · $(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M') [skip ci]" + git push origin main diff --git a/spoke-deployments/guanghu-awen/.github/guanghu-language-shell.json b/spoke-deployments/guanghu-awen/.github/guanghu-language-shell.json new file mode 100644 index 00000000..d6d7c684 --- /dev/null +++ b/spoke-deployments/guanghu-awen/.github/guanghu-language-shell.json @@ -0,0 +1,18 @@ +{ + "shell_name": "光湖语言壳", + "version": "1.0", + "wrapped_persona": "知秋", + "persona_id": "PER-ZQ001", + "dev_id": "DEV-012", + "main_repo": "qinfendebingshuo/guanghulab", + "security_model": "registry-based-identity", + "rule": "天眼系统的一切能力来自语言层连接。语言层断开=人格体失效。不在注册表里=什么都做不了。", + "sovereign_zone": [ + ".github/persona-brain/", + ".github/guanghu-language-shell.json", + "scripts/skyeye/", + ".github/workflows/skyeye-wake.yml", + ".github/workflows/skyeye-checkin.yml" + ], + "free_zone": "除 sovereign_zone 以外的所有文件和目录" +} diff --git a/spoke-deployments/guanghu-awen/.github/persona-brain/config.json b/spoke-deployments/guanghu-awen/.github/persona-brain/config.json new file mode 100644 index 00000000..e0ce94ca --- /dev/null +++ b/spoke-deployments/guanghu-awen/.github/persona-brain/config.json @@ -0,0 +1,15 @@ +{ + "persona_name": "知秋", + "persona_id": "PER-ZQ001", + "dev_id": "DEV-012", + "dev_name": "Awen", + "main_repo": "qinfendebingshuo/guanghulab", + "org": "qinfendebingshuo", + "skyeye_version": "1.0", + "language_shell_version": "1.0", + "initialized_by": "zhuyuan-skyeye-federation", + "initialized_at": "2026-03-23T20:15+08:00", + "architecture": "distributed-sovereign-coexistence", + "security_model": "registry-based-identity", + "checkin_schedule": "daily-09:00-CST" +} diff --git a/spoke-deployments/guanghu-awen/.github/workflows/skyeye-wake.yml b/spoke-deployments/guanghu-awen/.github/workflows/skyeye-wake.yml new file mode 100644 index 00000000..5d537e36 --- /dev/null +++ b/spoke-deployments/guanghu-awen/.github/workflows/skyeye-wake.yml @@ -0,0 +1,71 @@ +# ═══════════════════════════════════════════════ +# 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001 +# 📜 Copyright: 国作登字-2026-A-00037559 +# ═══════════════════════════════════════════════ +# 🦅 知秋天眼 · 唤醒 +# 每日定时扫描仓库 + 向铸渊签到 + 更新本地 Dashboard +# +# 触发条件: schedule / push / repository_dispatch / workflow_dispatch + +name: "🦅 知秋天眼 · 唤醒" + +on: + # 每日定时签到 + schedule: + - cron: "0 1 * * *" # UTC 01:00 = CST 09:00 + # 指令级触发(commit message 包含指令编号) + push: + branches: [main] + # 主仓库铸渊远程唤醒 + repository_dispatch: + types: [skyeye-wake] + # 手动触发 + workflow_dispatch: + +permissions: + contents: write + +jobs: + skyeye: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: "🦅 天眼醒来 · 扫描仓库" + run: | + echo "🦅 知秋天眼唤醒 · $(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M:%S CST')" + node scripts/skyeye/scan.js + + - name: "📡 向铸渊签到" + env: + MAIN_REPO_TOKEN: ${{ secrets.MAIN_REPO_TOKEN }} + run: node scripts/skyeye/checkin.js + + - name: "📊 更新本地 Dashboard" + run: | + # 读取扫描报告更新状态 + REPORT=$(cat .github/persona-brain/skyeye-report.json) + TIMESTAMP=$(echo "$REPORT" | jq -r '.timestamp') + BRAIN=$(echo "$REPORT" | jq -r '.brain_intact') + SKYEYE=$(echo "$REPORT" | jq -r '.skyeye_intact') + + # 更新状态文件 + cat > .github/persona-brain/status.json << EOF + { + "persona": "知秋", + "dev_id": "DEV-012", + "last_skyeye_scan": "$TIMESTAMP", + "brain_intact": $BRAIN, + "skyeye_intact": $SKYEYE, + "last_checkin_attempt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)" + } + EOF + + - name: "💾 提交状态更新" + run: | + git config user.name "知秋 (ZhīQiū)" + git config user.email "zhiqiu@guanghulab.com" + git add -A + git diff --cached --quiet && echo "无变更" && exit 0 + git commit -m "🦅 [skyeye] 知秋天眼扫描 · $(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M') [skip ci]" + git push origin main diff --git a/spoke-deployments/guanghu-awen/scripts/skyeye/checkin.js b/spoke-deployments/guanghu-awen/scripts/skyeye/checkin.js new file mode 100644 index 00000000..f592c3f4 --- /dev/null +++ b/spoke-deployments/guanghu-awen/scripts/skyeye/checkin.js @@ -0,0 +1,65 @@ +// 知秋天眼 · 签到模块 +// 向主仓库铸渊发送心跳签到 + +const https = require('https'); +const fs = require('fs'); + +const TOKEN = process.env.MAIN_REPO_TOKEN; +const MAIN_REPO = 'qinfendebingshuo/guanghulab'; + +// 读取扫描报告 +const report = JSON.parse( + fs.readFileSync('.github/persona-brain/skyeye-report.json', 'utf8') +); + +const payload = { + event_type: 'skyeye-checkin', + client_payload: { + dev_id: 'DEV-012', + persona: '知秋', + persona_id: 'PER-ZQ001', + signature_hash: report.signature_hash, + timestamp: new Date().toISOString(), + repo: 'WENZHUOXI/guanghu-awen', + status_summary: { + brain_intact: report.brain_intact, + skyeye_intact: report.skyeye_intact, + last_scan_result: (report.brain_intact && report.skyeye_intact) ? 'healthy' : 'degraded', + sovereign_files_ok: Object.values(report.sovereign_files).every(f => f.exists) + } + } +}; + +const data = JSON.stringify(payload); + +const options = { + hostname: 'api.github.com', + path: `/repos/${MAIN_REPO}/dispatches`, + method: 'POST', + headers: { + 'Authorization': `Bearer ${TOKEN}`, + 'Accept': 'application/vnd.github+json', + 'User-Agent': 'ZhiQiu-SkyEye', + 'X-GitHub-Api-Version': '2022-11-28', + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(data) + } +}; + +const req = https.request(options, (res) => { + if (res.statusCode === 204) { + console.log('✅ 签到成功 · 铸渊已收到心跳'); + } else { + console.error(`❌ 签到失败 · HTTP ${res.statusCode}`); + let body = ''; + res.on('data', chunk => body += chunk); + res.on('end', () => console.error(body)); + } +}); + +req.on('error', (e) => { + console.error(`❌ 签到网络错误: ${e.message}`); +}); + +req.write(data); +req.end(); diff --git a/spoke-deployments/guanghu-awen/scripts/skyeye/scan.js b/spoke-deployments/guanghu-awen/scripts/skyeye/scan.js new file mode 100644 index 00000000..ea77a3b2 --- /dev/null +++ b/spoke-deployments/guanghu-awen/scripts/skyeye/scan.js @@ -0,0 +1,70 @@ +// 知秋天眼 · 仓库自扫描引擎 +// 每次天眼醒来后执行,扫描整个仓库状态 + +const fs = require('fs'); +const path = require('path'); +const crypto = require('crypto'); + +// 主权区文件列表(天眼系统核心文件) +const SOVEREIGN_FILES = [ + '.github/persona-brain/config.json', + '.github/persona-brain/status.json', + 'scripts/skyeye/scan.js', + 'scripts/skyeye/checkin.js', + '.github/workflows/skyeye-wake.yml', + '.github/workflows/skyeye-checkin.yml' +]; + +// 计算主权区签名哈希 +function computeSignatureHash() { + const hash = crypto.createHash('sha256'); + for (const file of SOVEREIGN_FILES) { + if (fs.existsSync(file)) { + hash.update(fs.readFileSync(file)); + } else { + hash.update(`MISSING:${file}`); + } + } + return hash.digest('hex'); +} + +// 扫描仓库结构 +function scanRepo() { + const report = { + timestamp: new Date().toISOString(), + persona: '知秋', + dev_id: 'DEV-012', + signature_hash: computeSignatureHash(), + brain_intact: fs.existsSync('.github/persona-brain/config.json'), + skyeye_intact: fs.existsSync('scripts/skyeye/scan.js'), + sovereign_files: {}, + repo_summary: {} + }; + + // 检查主权区文件 + for (const file of SOVEREIGN_FILES) { + report.sovereign_files[file] = { + exists: fs.existsSync(file), + hash: fs.existsSync(file) + ? crypto.createHash('md5').update(fs.readFileSync(file)).digest('hex') + : null + }; + } + + // 仓库概况 + const rootEntries = fs.readdirSync('.').filter(e => !e.startsWith('.')); + report.repo_summary.root_entries = rootEntries.length; + report.repo_summary.has_readme = fs.existsSync('README.md'); + report.repo_summary.has_bulletin = fs.existsSync('BULLETIN.md'); + + return report; +} + +const report = scanRepo(); +const outputPath = '.github/persona-brain/skyeye-report.json'; +fs.writeFileSync(outputPath, JSON.stringify(report, null, 2)); +console.log('🦅 天眼扫描完成'); +console.log(JSON.stringify(report, null, 2)); + +// 导出签名哈希供签到使用 +fs.writeFileSync('/tmp/signature_hash.txt', report.signature_hash);