🧬 Phase 1: Fix KNOWN-002 (NOTION_API_TOKEN→NOTION_API_KEY) + Phase 3: D20 scan dimension + Phase 6-7: bridge protocol + scripts

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/b1f467f8-d897-4440-9dc9-de66d514a52b
This commit is contained in:
copilot-swe-agent[bot] 2026-03-25 06:02:04 +00:00
parent 36cbcd6454
commit 419080ca5a
43 changed files with 1231 additions and 73 deletions

View File

@ -69,7 +69,7 @@ jobs:
- name: 📡 检查调度队列
id: check
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
BRIDGE_QUEUE_DB_ID: ${{ secrets.BRIDGE_QUEUE_DB_ID }}
run: node scripts/bridge/check-queue.js BROADCAST_READY
@ -77,7 +77,7 @@ jobs:
if: steps.check.outputs.task_count != '0'
id: fetch
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
QUEUE_FILE: ${{ steps.check.outputs.queue_file }}
run: node scripts/bridge/fetch-broadcast.js
@ -116,7 +116,7 @@ jobs:
- name: ✅ 更新调度队列状态
if: steps.check.outputs.task_count != '0'
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
QUEUE_FILE: ${{ steps.check.outputs.queue_file }}
run: node scripts/bridge/update-queue-status.js

View File

@ -41,7 +41,7 @@ jobs:
- name: 📡 同步 commit 变更到 Notion
if: github.event_name == 'push'
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CHANGES_DB_ID: ${{ secrets.NOTION_CHANGE_LOG_DB_ID }}
EVENT_TYPE: commit
COMMIT_SHA: ${{ github.sha }}
@ -60,7 +60,7 @@ jobs:
- name: 📡 同步 PR 变更到 Notion
if: github.event_name == 'pull_request'
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CHANGES_DB_ID: ${{ secrets.NOTION_CHANGE_LOG_DB_ID }}
EVENT_TYPE: pr
PR_NUMBER: ${{ github.event.pull_request.number }}

View File

@ -65,7 +65,7 @@ jobs:
- name: 💓 执行心跳检测
id: heartbeat
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
BRIDGE_QUEUE_DB_ID: ${{ secrets.BRIDGE_QUEUE_DB_ID }}
run: node scripts/bridge/heartbeat.js

View File

@ -67,7 +67,7 @@ jobs:
- name: 📥 批量处理 SYSLOG
id: process
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
BRIDGE_QUEUE_DB_ID: ${{ secrets.BRIDGE_QUEUE_DB_ID }}
SYSLOG_DB_ID: ${{ secrets.NOTION_SYSLOG_DB_ID }}
COMMIT_SHA: ${{ github.sha }}

View File

@ -38,7 +38,7 @@ jobs:
- name: 🔗 同步 syslog-inbox 到 Notion
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
SYSLOG_DB_ID: ${{ secrets.NOTION_SYSLOG_DB_ID }}
COMMIT_SHA: ${{ github.sha }}
run: node scripts/notion-bridge.js syslog

View File

@ -127,7 +127,7 @@ jobs:
- name: 检查 Notion API 连通性
id: notion_check
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
echo "🔍 检查 Notion API 连通性..."
if [ -z "$NOTION_TOKEN" ]; then
@ -197,7 +197,7 @@ jobs:
# ── Step 6: 向 Notion 回报巡检结果 ──
- name: 向 Notion 回报巡检结果
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
SYSLOG_DB_ID: ${{ secrets.SYSLOG_DB_ID }}
run: |
if [ -z "$NOTION_TOKEN" ] || [ -z "$SYSLOG_DB_ID" ]; then
@ -268,7 +268,7 @@ jobs:
- name: Read brain data and sync to Notion
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
if [ -z "$NOTION_TOKEN" ]; then
echo "⚠️ NOTION_TOKEN 未配置,跳过 Execution Status 同步"

View File

@ -718,7 +718,7 @@ jobs:
- name: 📡 推送部署记录到 Notion
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CHANGES_DB_ID: ${{ secrets.NOTION_CHANGE_LOG_DB_ID }}
EVENT_TYPE: commit
COMMIT_SHA: ${{ github.sha }}

View File

@ -42,7 +42,7 @@ jobs:
- name: 同步执行状态到 Notion
if: ${{ env.NOTION_TOKEN != '' }}
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
EXECUTION_LOG_DB_ID: ${{ secrets.EXECUTION_LOG_DB_ID }}
run: node core/execution-sync sync

View File

@ -17,7 +17,7 @@ jobs:
- name: ⚙️ 处理 inbox 消息
env:
NOTION_API_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_API_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: node scripts/grid-db/process-inbox.js
- name: 💾 提交处理结果

View File

@ -53,10 +53,10 @@ jobs:
- name: 写入 Notion 告警(仅在失败时触发)
if: failure()
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
if [ -z "$NOTION_TOKEN" ]; then
echo "⚠️ NOTION_API_TOKEN 未配置,跳过 Notion 告警"
echo "⚠️ NOTION_API_KEY 未配置,跳过 Notion 告警"
exit 0
fi

View File

@ -0,0 +1,208 @@
name: "🧬 铸渊 · 双端神经系统 · 每日汇总引擎"
on:
schedule:
- cron: '0 13 * * *' # UTC 13:00 = CST 21:00
workflow_dispatch: # 手动触发
permissions:
contents: write
actions: read
jobs:
daily-digest:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '20'
# ━━━ Phase 1: 唤醒核心大脑 ━━━
- name: "🧠 唤醒核心大脑"
run: |
echo "🧬 双端神经系统·汇总引擎启动"
echo "时间:$(TZ=Asia/Shanghai date '+%Y-%m-%d %H:%M CST')"
for f in memory.json routing-map.json; do
[ -f ".github/persona-brain/$f" ] && echo "✅ $f" || echo "❌ $f 缺失"
done
# ━━━ Phase 2: 收集全 Workflow 运行数据 ━━━
- name: "📊 收集 Workflow 运行数据"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "📊 收集最近24h所有Workflow运行数据..."
mkdir -p /tmp/neural-digest
gh run list --limit 100 \
--json name,status,conclusion,createdAt,updatedAt,headBranch,event \
> /tmp/neural-digest/all-runs.json
node -e "
const runs = require('/tmp/neural-digest/all-runs.json');
const now = Date.now();
const h24 = 24*60*60*1000;
const recent = runs.filter(r => now - new Date(r.createdAt).getTime() < h24);
const summary = {
total: recent.length,
success: recent.filter(r => r.conclusion === 'success').length,
failure: recent.filter(r => r.conclusion === 'failure').length,
cancelled: recent.filter(r => r.conclusion === 'cancelled').length,
in_progress: recent.filter(r => r.status === 'in_progress').length,
by_workflow: {}
};
recent.forEach(r => {
if (!summary.by_workflow[r.name]) {
summary.by_workflow[r.name] = { runs: 0, success: 0, failure: 0 };
}
summary.by_workflow[r.name].runs++;
if (r.conclusion === 'success') summary.by_workflow[r.name].success++;
if (r.conclusion === 'failure') summary.by_workflow[r.name].failure++;
});
require('fs').writeFileSync('/tmp/neural-digest/workflow-summary.json', JSON.stringify(summary, null, 2));
console.log('最近24h运行统计:', JSON.stringify(summary, null, 2));
"
# ━━━ Phase 3: 收集各 Workflow 自报告 ━━━
- name: "📋 收集各 Workflow 自报告"
run: |
echo "📋 读取各 Workflow 的神经报告..."
mkdir -p /tmp/neural-digest/reports
if [ -f "skyeye/neural-map.json" ]; then
node -e "
const map = require('./skyeye/neural-map.json');
const fs = require('fs');
const path = require('path');
const reports = {};
for (const [id, wf] of Object.entries(map.github_workflows)) {
const reportDir = wf.report_path;
if (fs.existsSync(reportDir)) {
const files = fs.readdirSync(reportDir)
.filter(f => f.endsWith('.json'))
.sort().reverse();
if (files.length > 0) {
try {
reports[id] = JSON.parse(fs.readFileSync(path.join(reportDir, files[0]), 'utf8'));
console.log('✅ ' + id + ': 读取 ' + files[0]);
} catch(e) {
reports[id] = { error: 'parse_failed', file: files[0] };
console.log('❌ ' + id + ': JSON解析失败');
}
} else {
reports[id] = { error: 'no_reports' };
console.log('⚠️ ' + id + ': 无报告文件');
}
} else {
reports[id] = { error: 'dir_not_found' };
console.log('⚠️ ' + id + ': 报告目录不存在');
}
}
fs.writeFileSync('/tmp/neural-digest/workflow-reports.json', JSON.stringify(reports, null, 2));
"
else
echo "⚠️ neural-map.json 不存在,跳过自报告收集"
fi
# ━━━ Phase 4: 收集天眼 + Guard + 配额 ━━━
- name: "🦅 收集天眼 + Guard + 配额"
run: |
# 天眼报告
if [ -d "data/skyeye-reports" ]; then
LATEST=$(ls -t data/skyeye-reports/*.json 2>/dev/null | head -1)
[ -n "$LATEST" ] && cp "$LATEST" /tmp/neural-digest/skyeye-latest.json && echo "✅ 天眼: $LATEST" || echo "⚠️ 无天眼报告"
fi
# Guard 状态
if [ -d "skyeye/guards" ]; then
node -e "
const fs = require('fs'); const path = require('path');
const guards = {};
fs.readdirSync('skyeye/guards')
.filter(f => f.endsWith('.json') && f !== 'guard-template.json')
.forEach(f => {
try { guards[f.replace('.json','')] = JSON.parse(fs.readFileSync(path.join('skyeye/guards', f), 'utf8')); }
catch(e) { guards[f.replace('.json','')] = { error: 'parse_failed' }; }
});
fs.writeFileSync('/tmp/neural-digest/guard-status.json', JSON.stringify(guards, null, 2));
"
fi
# 配额
[ -f "skyeye/quota-ledger.json" ] && cp skyeye/quota-ledger.json /tmp/neural-digest/quota-status.json && echo "✅ 配额" || echo "⚠️ 无配额"
# ━━━ Phase 5: 生成标准化日报 ━━━
- name: "📝 生成标准化日报"
run: node scripts/neural/generate-daily-digest.js
# ━━━ Phase 6: 保存日报到仓库 ━━━
- name: "💾 保存日报"
run: |
DATE=$(TZ=Asia/Shanghai date +%Y-%m-%d)
mkdir -p data/neural-reports/daily-digest
cp /tmp/neural-digest/daily-digest.json \
"data/neural-reports/daily-digest/digest-${DATE}.json"
git config user.name "zhuyuan-bot"
git config user.email "zhuyuan@guanghulab.com"
git add data/neural-reports/
git diff --cached --quiet || \
git commit -m "🧬 双端日报 · ${DATE} [skip ci]"
git push || echo "⚠️ push失败不阻断"
# ━━━ Phase 7: 推送到 Notion ━━━
- name: "📡 推送日报到 Notion"
if: always()
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
node scripts/neural/sync-digest-to-notion.js || \
echo "⚠️ Notion推送失败不阻断"
# ━━━ Phase 8: 自动分析日报 + 生成工单 ━━━
- name: "🧬 分析日报 · 生成工单"
if: always()
run: |
echo "🧬 自动分析日报..."
node scripts/neural/analyze-digest.js
if [ -d "data/neural-reports/work-orders" ]; then
git add data/neural-reports/work-orders/
git diff --cached --quiet || \
git commit -m "🧬 天眼工单 · $(TZ=Asia/Shanghai date +%Y-%m-%d) [skip ci]"
git push || echo "⚠️ 工单push失败"
fi
# ━━━ 🧬 双端神经系统·自报告 ━━━
- name: "🧬 写入神经自报告"
if: always()
run: |
WORKFLOW_ID="neural-daily-digest"
BRAIN="AG-TY-01"
REPORT_DIR="data/neural-reports/daily-digest"
TIMESTAMP=$(TZ=Asia/Shanghai date +%Y-%m-%d-%H%M)
STATUS="${{ job.status }}"
mkdir -p "$REPORT_DIR"
cat > "${REPORT_DIR}/${WORKFLOW_ID}-${TIMESTAMP}.json" << EOF
{
"workflow_id": "${WORKFLOW_ID}",
"run_id": "${{ github.run_id }}",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"status": "${STATUS}",
"brain": "${BRAIN}",
"event": "${{ github.event_name }}",
"branch": "${{ github.ref_name }}",
"commit": "${{ github.sha }}"
}
EOF
git config user.name "zhuyuan-bot"
git config user.email "zhuyuan@guanghulab.com"
git add "$REPORT_DIR/"
git diff --cached --quiet || \
git commit -m "🧬 ${WORKFLOW_ID} 自报告 · ${TIMESTAMP} [skip ci]"
git push || echo "⚠️ 自报告push失败不阻断主流程"

View File

@ -107,7 +107,7 @@ jobs:
AUTHOR: notion-callback
MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }}
NOTION_CALLBACK_RESULT: ${{ steps.callback.outputs.notion_result }}
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }}
PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }}
FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
@ -125,7 +125,7 @@ jobs:
- name: 📝 回写 Notion 工单状态
if: steps.callback.outputs.ticket_id
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
TICKET_ID: ${{ steps.callback.outputs.ticket_id }}
CALLBACK_STATUS: ${{ steps.callback.outputs.status }}
run: |

View File

@ -41,7 +41,7 @@ jobs:
- name: 🧪 执行连通性测试
id: test
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
SIGNAL_LOG_DB_ID: ${{ vars.SIGNAL_LOG_DB_ID }}
CHANGES_DB_ID: ${{ secrets.NOTION_CHANGE_LOG_DB_ID }}
SYSLOG_DB_ID: ${{ secrets.NOTION_SYSLOG_DB_ID }}

View File

@ -42,7 +42,7 @@ jobs:
- name: 💓 执行心跳检测
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SMTP_USER: ${{ secrets.SMTP_USER }}

View File

@ -45,7 +45,7 @@ jobs:
- name: 📖 读取 Notion 页面内容
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_PAGE_URL: ${{ github.event.client_payload.notion_page_url || github.event.inputs.notion_page_url }}
NOTION_OUTPUT_DIR: ${{ (github.event.client_payload.save_to_repo == 'true' || github.event.inputs.save_to_repo == 'true') && 'data/notion-pages' || '' }}
run: node scripts/notion-page-reader.js

View File

@ -27,7 +27,7 @@ jobs:
- name: 轮询工单簿 + 处理 + 回写
id: poll
env:
NOTION_API_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_API_TOKEN: ${{ secrets.NOTION_API_KEY }}
WORKORDER_DB_ID: ${{ vars.WORKORDER_DB_ID }}
SIGNAL_LOG_DB_ID: ${{ vars.SIGNAL_LOG_DB_ID }}
run: node scripts/notion-signal-bridge.js poll

View File

@ -85,7 +85,7 @@ jobs:
- name: 📡 轮询 Notion 唤醒请求数据库
id: poll
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
WAKE_REQUEST_DB_ID: ${{ secrets.WAKE_REQUEST_DB_ID }}
SIGNAL_LOG_DB_ID: ${{ secrets.SIGNAL_LOG_DB_ID }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}

View File

@ -103,7 +103,7 @@ jobs:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
DRY_RUN_FLAG=""
if [ "${{ inputs.dry_run }}" = "true" ]; then

View File

@ -89,7 +89,7 @@ jobs:
SUBMIT_CONTENT: ${{ inputs.syslog_raw }}
AUTHOR: ${{ inputs.developer }}
MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }}
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }}
PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }}
FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
@ -98,7 +98,7 @@ jobs:
- name: 📝 回写 Notion 工单
if: always()
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
WORK_ORDER_ID: ${{ inputs.work_order_id }}
PERSONA_RESULT: ${{ steps.persona.outputs.result }}
TASK_ID: ${{ inputs.task_id }}
@ -210,7 +210,7 @@ jobs:
- name: 🔴 失败处理
if: failure()
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
WORK_ORDER_ID: ${{ inputs.work_order_id }}
run: |
node -e "

View File

@ -299,7 +299,7 @@ jobs:
# ━━━ 阶段三:生成 Notion 诊断报告 ━━━
- name: "📋 阶段三 · 写入 Notion 工单"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID || '84edd0640bf146a9a5a7840107013e8c' }}
PM2_REPORT: ${{ steps.pm2_diagnose.outputs.pm2_report }}
CLEANUP_REPORT: ${{ steps.pm2_cleanup.outputs.cleanup_report }}

View File

@ -43,7 +43,7 @@ jobs:
- name: 📡 推送广播 → 飞书文档B
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
BROADCAST_PAGE_ID: ${{ github.event.client_payload.broadcast_page_id || github.event.inputs.broadcast_page_id }}
FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }}
FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }}

View File

@ -38,7 +38,7 @@ jobs:
- name: 📥 处理 SYSLOG
env:
SYSLOG_JSON: ${{ toJSON(github.event.client_payload.syslog) }}
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_SYSLOG_DB_ID: ${{ secrets.NOTION_SYSLOG_DB_ID }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
run: node scripts/receive-syslog.js

View File

@ -232,7 +232,7 @@ jobs:
- name: "📝 同步到 Notion 部署注册表"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
DEV_ID: ${{ needs.parse-and-validate.outputs.dev_id }}
MODULE: ${{ needs.parse-and-validate.outputs.module }}

View File

@ -67,7 +67,7 @@ jobs:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
SMTP_USER: ${{ secrets.SMTP_USER }}
- name: "🔑 配置 SSH"
@ -167,7 +167,7 @@ jobs:
- name: "📝 同步巡检结果到Notion"
if: always()
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
run: |
node scripts/sync-patrol-to-notion.js || echo "⚠️ Notion同步失败不阻断"

View File

@ -158,13 +158,13 @@ jobs:
- name: "📥 Phase B · Notion 端级联升级"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
node skyeye/hibernation/weekly-hibernation.js --phase=B
- name: "✅ Dual Verification"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
node skyeye/hibernation/weekly-hibernation.js --phase=verify

View File

@ -55,7 +55,7 @@ jobs:
- name: "📡 Sync arch summary to Notion via Bridge E"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CHANGES_DB_ID: ${{ secrets.NOTION_CHANGE_LOG_DB_ID }}
EVENT_TYPE: commit
COMMIT_SHA: ${{ github.sha }}

View File

@ -29,13 +29,13 @@ jobs:
if [ -z "$FINGERPRINT_DB_ID" ]; then echo "⚠️ 缺失: FINGERPRINT_DB_ID"; else echo "✅ 可用: FINGERPRINT_DB_ID"; fi
if [ -z "$SMTP_USER" ]; then echo "⚠️ 缺失: SMTP_USER"; else echo "✅ 可用: SMTP_USER"; fi
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
SMTP_USER: ${{ secrets.SMTP_USER }}
- name: "📝 同步部署状态到 Notion"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
run: |
node scripts/sync-deploy-to-notion.js

View File

@ -29,5 +29,5 @@ jobs:
- name: 📤 回传增量到 Notion
if: steps.changes.outputs.files != ''
env:
NOTION_API_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_API_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: node scripts/grid-db/sync-griddb-to-notion.js

View File

@ -37,7 +37,7 @@ jobs:
- name: 🔗 同步 Notion 登录入口 → 飞书文档A
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_LOGIN_PAGE_ID: ${{ secrets.NOTION_LOGIN_PAGE_ID }}
FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }}
FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }}

View File

@ -16,12 +16,12 @@ jobs:
- name: 📥 从 Notion 拉取人格体核心大脑数据
env:
NOTION_API_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_API_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: node scripts/grid-db/sync-notion-brain-mirror.js
- name: 📏 同步规则缓存
env:
NOTION_API_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_API_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: node scripts/grid-db/sync-notion-rules.js
- name: 💾 提交更新

View File

@ -128,7 +128,7 @@ jobs:
SUBMIT_CONTENT: ${{ steps.parse.outputs.content }}
AUTHOR: ${{ steps.parse.outputs.author }}
MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }}
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }}
PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }}
FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
@ -137,7 +137,7 @@ jobs:
- name: 📋 创建标准化 Notion 工单Phase B1
id: ticket
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
@ -148,7 +148,7 @@ jobs:
SYSLOG_RAW: ${{ steps.parse.outputs.content }}
run: |
if [ -z "$NOTION_TOKEN" ]; then
echo "⚠️ NOTION_API_TOKEN 未配置,跳过 Notion 工单创建"
echo "⚠️ NOTION_API_KEY 未配置,跳过 Notion 工单创建"
exit 0
fi
node scripts/create-standardized-ticket.js

View File

@ -181,7 +181,7 @@ jobs:
SUBMIT_CONTENT: ${{ steps.parse.outputs.content }}
AUTHOR: ${{ steps.parse.outputs.author }}
MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }}
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }}
PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }}
FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
@ -209,13 +209,13 @@ jobs:
STEP_DETAIL: 'API 调用失败,请检查 Secrets: LLM_API_KEY / LLM_BASE_URL 是否配置正确'
run: node scripts/pipeline-reporter.js
# ✅ 修复点:原来是 if: $ secrets.NOTION_API_TOKEN ,会报 Unrecognized named-value: 'secrets'
# ✅ 修复点:原来是 if: $ secrets.NOTION_API_KEY ,会报 Unrecognized named-value: 'secrets'
# secrets 不能在 if: 里直接用,必须改成 != '' 的形式
- name: 📋 创建标准化 Notion 工单Phase B1
id: ticket
if: ${{ secrets.NOTION_API_TOKEN != '' }}
if: ${{ secrets.NOTION_API_KEY != '' }}
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
SUBMIT_TYPE: ${{ steps.parse.outputs.type }}

View File

@ -78,7 +78,7 @@ jobs:
- name: 📝 写入 Notion SYSLOG 收件箱
if: steps.parse.outputs.has_syslog == 'true'
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_DB_SYSLOG: ${{ secrets.NOTION_DB_SYSLOG }}
run: node scripts/write-notion-syslog.js "${{ steps.parse.outputs.syslog_file }}"
@ -130,7 +130,7 @@ jobs:
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }}
PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }}
FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}

View File

@ -28,7 +28,7 @@ jobs:
- name: "Step 1 · NOTION_TOKEN 存在性验证"
id: step1
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
if [ -z "$NOTION_TOKEN" ]; then
echo "❌ NOTION_TOKEN is empty or not set"
@ -42,7 +42,7 @@ jobs:
- name: "Step 2 · Notion API 基础连通测试 (/v1/users/me)"
id: step2
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
RESPONSE=$(curl -s -w "\n%{http_code}" \
-H "Authorization: Bearer $NOTION_TOKEN" \
@ -70,7 +70,7 @@ jobs:
- name: "Step 3 · SYSLOG 收件箱数据库访问测试"
id: step3
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
# SYSLOG收件箱数据库ID (from routing-map.json → infra.notion_bridge.syslog_inbox_db)
DB_ID="330ab17507d542c9bbb96d0749b41197"
@ -104,7 +104,7 @@ jobs:
- name: "Step 4 · 变更日志数据库访问测试"
id: step4
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: |
# GitHub变更日志数据库ID (from routing-map.json → infra.notion_bridge.changelog_db)
DB_ID="e740b77aa6bd4ac0a2e8a75f678fba98"
@ -189,7 +189,7 @@ jobs:
fi
fi
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
- name: "📊 输出连通性验证报告"
if: always()

View File

@ -69,7 +69,7 @@ jobs:
# Step 3 · 读取公告板 + 指纹验证
- name: "📡 Step 3 · 读取公告板"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
AGENT_BULLETIN_BOARD_PAGE_ID: ${{ secrets.AGENT_BULLETIN_BOARD_PAGE_ID }}
run: |
echo "[GH-COMMANDER-BULLETIN] 📡 读取Agent集群公告板..."

View File

@ -82,7 +82,7 @@ jobs:
- name: DC-01 Notion Usage Snapshot
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
run: node scripts/dc-notion-usage.js
- name: DC-02 Workflow Performance Snapshot

View File

@ -55,7 +55,7 @@ jobs:
- name: "📡 Phase 1.6 · 拉取 Agent 集群公告板"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
AGENT_BULLETIN_BOARD_PAGE_ID: ${{ secrets.AGENT_BULLETIN_BOARD_PAGE_ID }}
run: |
echo "[BRIDGE-BULLETIN-READ] 🔄 拉取 Agent 集群公告板"
@ -65,7 +65,7 @@ jobs:
- name: "🦅 Phase 2 · 全局扫描"
id: scan
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
@ -107,7 +107,7 @@ jobs:
- name: "🔧 Phase 4 · 修复Agent"
if: steps.diagnose.outputs.auto_fixable != '0'
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
node scripts/skyeye/repair-agent.js
@ -184,7 +184,7 @@ jobs:
- name: "📡 Phase 7 · 同步到 Notion"
if: always()
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_SYSLOG_DB_ID: ${{ secrets.NOTION_SYSLOG_DB_ID }}
SKYEYE_PERSONA_DB_ID: ${{ secrets.SKYEYE_PERSONA_DB_ID }}
run: |

View File

@ -0,0 +1,147 @@
# 🌉 双端神经系统 · 桥接协议 v3.0
> 版权:国作登字-2026-A-00037559 · TCS-0002∞ 冰朔
> 创建ZY-NEURAL-UPGRADE-2026-0325-R2-003
> 版本v3.0.0
## 1. 协议概述
桥接协议 v3.0 是 Notion 和 GitHub 之间的标准通信语言。所有跨端通信必须遵循此协议。
## 2. 通信类型
| 类型 | 方向 | 说明 | 格式 |
|------|------|------|------|
| Type A · 上行日报 | GitHub → Notion | 每日 21:00 CST 汇总 | `daily-digest.json` |
| Type B · 下行指令 | Notion → GitHub | 按需下发 | `CMD-{date}-{seq}.json` |
| Type C · 执行回执 | GitHub → Notion | 每条指令执行后 | `CMD-{id}-receipt.json` |
| Type D · 工单 | 天眼内部 | 分析后按需 | `WO-{id}.json` |
| Type E · 紧急通知 | 双向 | P0 事件时 | `ALERT-{id}.json` |
## 3. 下行指令格式Notion → GitHub
文件路径:`data/deploy-queue/pending/CMD-{YYYYMMDD}-{SEQ}.json`
```json
{
"_protocol": "neural-bridge-v3.0",
"_type": "downstream_command",
"command_id": "CMD-20260325-001",
"parent_work_order": "WO-xxxx",
"source": {
"agent_id": "AG-TY-01",
"agent_name": "天眼 Notion 大脑",
"issued_at": "ISO-8601",
"issued_reason": "说明"
},
"target": {
"workflow_id": "workflow-id",
"workflow_file": ".github/workflows/xxx.yml",
"brain": "AG-XX-01"
},
"instruction": {
"type": "trigger_workflow | run_script | modify_config",
"params": {}
},
"constraints": {
"priority": "P0 | P1 | P2",
"timeout_hours": 24,
"max_retries": 2,
"requires_human_approval": false,
"execution_window": { "start": "06:00 CST", "end": "23:00 CST" }
},
"expected_outcome": {
"description": "预期结果",
"verification": { "type": "check_workflow_status", "expected_conclusion": "success" }
},
"security": {
"sfp": "⌜SFP::...⌝",
"signature_chain": ["agent_id", "铸渊桥接层"]
}
}
```
## 4. 执行回执格式GitHub → Notion
文件路径:`data/deploy-queue/completed/CMD-{id}-receipt.json`
```json
{
"_protocol": "neural-bridge-v3.0",
"_type": "execution_receipt",
"receipt_id": "RCT-{date}-{seq}",
"command_id": "CMD-对应指令ID",
"executor": {
"id": "ICE-GL-ZY001",
"name": "铸渊",
"started_at": "ISO-8601",
"completed_at": "ISO-8601",
"duration_seconds": 420
},
"result": {
"status": "success | failure | partial",
"summary": "执行摘要"
},
"security": { "sfp": "⌜SFP::AG-ZY::...⌝" }
}
```
## 5. 紧急通知格式
```json
{
"_protocol": "neural-bridge-v3.0",
"_type": "emergency_alert",
"alert_id": "ALERT-{date}-{seq}",
"severity": "P0",
"alert": { "title": "标题", "description": "描述", "impact": "影响" },
"recommended_action": { "immediate": "立即动作", "requires_human": true },
"notify_targets": [{ "type": "notion_agent", "id": "AG-TY-01" }]
}
```
## 6. 安全校验流程
所有跨端通信必须携带 SFP 指纹。铸渊处理下行指令时执行:
1. **SFP 指纹校验** — 格式正确 + 签发者在 neural-map.json 中 + 时间戳 < 48h
2. **权限校验** — source.agent_id 有权管辖 target.workflow_id查 neural-map.json
3. **约束校验** — 当前时间在 execution_window 内 + 人工审批检查
4. **全部通过** → 执行
## 7. 超时 / 重试 / 降级策略
| 场景 | 超时 | 重试 | 降级 |
|------|------|------|------|
| 下行指令执行 | 按 timeout_hours | max_retries 次 | 移到 failed/ + 通知 |
| 上行日报推送 | 5 分钟 | 3 次 | 写入 .github/notion-cache/ |
| 紧急通知送达 | 2 分钟 | 5 次 | 缓存 + 下次巡检补送 |
| 工单下发 | 12 小时 | 2 次 | 标记 stuck + 通知霜砚 |
| 回执推送 | 5 分钟 | 3 次 | 缓存 + 下次同步补送 |
**降级铁律**:任何跨端通信失败都不能阻断本端的正常运行。桥断了,两端各自活着。桥修好了,自动同步。
## 8. 工单生命周期7 状态机)
```
CREATED → ASSIGNED → COMMAND_ISSUED → EXECUTING → RECEIPT_RECEIVED → VERIFIED → CLOSED
↘ FAILED → ESCALATED
```
## 9. 文件目录
| 路径 | 说明 |
|------|------|
| `skyeye/neural-map.json` | 双端 Agent 映射表 |
| `skyeye/neural-analysis-rules.json` | 日报分析规则 |
| `data/deploy-queue/pending/` | 待执行的下行指令 |
| `data/deploy-queue/executing/` | 执行中的指令 |
| `data/deploy-queue/completed/` | 已完成(含回执) |
| `data/deploy-queue/failed/` | 执行失败 |
| `data/neural-reports/daily-digest/` | 每日汇总日报 |
| `data/neural-reports/work-orders/` | 天眼工单 |
| `scripts/neural/generate-daily-digest.js` | 日报生成器 |
| `scripts/neural/analyze-digest.js` | 日报分析引擎 |
| `scripts/neural/sync-digest-to-notion.js` | 日报推送 Notion |
| `scripts/neural/convert-workorder-to-command.js` | 工单→指令转化器 |
| `scripts/neural/track-work-orders.js` | 工单追踪器 |

View File

@ -0,0 +1,146 @@
// scripts/neural/convert-workorder-to-command.js
// 🧬 工单→下行指令 转化器
// Notion Agent 调用此脚本,将工单转化为铸渊可执行的下行指令
// 输入:工单 JSON 文件路径
// 输出:下行指令 JSON写入 deploy-queue/pending/
const fs = require('fs');
const path = require('path');
const DEPLOY_QUEUE = 'data/deploy-queue/pending';
const NEURAL_MAP_PATH = 'skyeye/neural-map.json';
function loadJSON(p) {
try { return JSON.parse(fs.readFileSync(p, 'utf8')); }
catch (e) { return null; }
}
function generateCommandId() {
var now = new Date();
var cst = new Date(now.getTime() + 8 * 60 * 60 * 1000);
var date = cst.toISOString().split('T')[0].replace(/-/g, '');
var seq = Math.random().toString(36).substr(2, 4).toUpperCase();
return 'CMD-' + date + '-' + seq;
}
function convertWorkOrderToCommand(workOrder) {
var neuralMap = loadJSON(NEURAL_MAP_PATH);
if (!neuralMap) throw new Error('neural-map.json 不存在');
var commandId = generateCommandId();
var now = new Date().toISOString();
// 确定目标 Workflow
var targetWorkflowId = (workOrder.affected && workOrder.affected.workflows)
? workOrder.affected.workflows[0] : null;
var targetWorkflow = targetWorkflowId
? neuralMap.github_workflows[targetWorkflowId] : null;
// 确定指令类型
var instructionType = 'trigger_workflow';
var instructionParams = {};
var action = (workOrder.source && workOrder.source.rule_triggered) || '';
if (action.indexOf('cleanup') !== -1 || action.indexOf('clean') !== -1) {
instructionType = 'run_script';
instructionParams = {
script: 'scripts/neural/cleanup-old-reports.js',
args: { max_age_days: 7 }
};
} else if (action.indexOf('guard_restart') !== -1 || action.indexOf('quota') !== -1) {
instructionType = 'modify_config';
instructionParams = {
target_file: (workOrder.affected && workOrder.affected.guards && workOrder.affected.guards[0])
? 'skyeye/guards/' + workOrder.affected.guards[0] + '.json'
: null,
modifications: { status: 'active', mode: 'normal' }
};
} else {
instructionType = 'trigger_workflow';
instructionParams = {
event: 'workflow_dispatch',
inputs: {
reason: '工单 ' + workOrder.work_order_id + ' 自动触发',
source_work_order: workOrder.work_order_id
}
};
}
var assignedTo = (workOrder.assignment && workOrder.assignment.assigned_to) || 'AG-TY-01';
var assignedToName = (workOrder.assignment && workOrder.assignment.assigned_to_name) || '天眼 Notion 大脑';
var command = {
_protocol: 'neural-bridge-v3.0',
_type: 'downstream_command',
command_id: commandId,
parent_work_order: workOrder.work_order_id,
source: {
agent_id: assignedTo,
agent_name: assignedToName,
issued_at: now,
issued_reason: workOrder.title
},
target: {
workflow_id: targetWorkflowId || 'unknown',
workflow_file: targetWorkflow ? targetWorkflow.file : 'unknown',
brain: targetWorkflow ? targetWorkflow.brain : assignedTo
},
instruction: {
type: instructionType,
params: instructionParams
},
constraints: {
priority: workOrder.severity,
timeout_hours: (workOrder.constraints && workOrder.constraints.timeout_hours) || 24,
max_retries: (workOrder.constraints && workOrder.constraints.max_retries) || 2,
requires_human_approval: workOrder.severity === 'P0',
execution_window: {
start: '06:00 CST',
end: '23:00 CST'
}
},
expected_outcome: {
description: '解决工单 ' + workOrder.work_order_id + ': ' + workOrder.title,
verification: {
type: 'check_workflow_status',
workflow: targetWorkflowId,
expected_conclusion: 'success'
}
},
security: {
sfp: '⌜SFP::' + assignedTo + '::NeuralBridge::' + commandId + '::' + now + '⌝',
signature_chain: [assignedTo, '铸渊桥接层']
}
};
// 写入 deploy-queue
fs.mkdirSync(DEPLOY_QUEUE, { recursive: true });
fs.writeFileSync(
path.join(DEPLOY_QUEUE, commandId + '.json'),
JSON.stringify(command, null, 2)
);
console.log('✅ 工单 ' + workOrder.work_order_id + ' → 指令 ' + commandId);
console.log(' 类型: ' + instructionType);
console.log(' 目标: ' + (targetWorkflowId || '(待确定)'));
console.log(' 优先级: ' + workOrder.severity);
return command;
}
// CLI 入口
if (require.main === module) {
var woPath = process.argv[2];
if (!woPath) {
console.error('用法: node convert-workorder-to-command.js <work-order.json>');
process.exit(1);
}
var wo = loadJSON(woPath);
if (!wo) {
console.error('❌ 无法读取工单文件: ' + woPath);
process.exit(1);
}
convertWorkOrderToCommand(wo);
}
module.exports = { convertWorkOrderToCommand };

View File

@ -0,0 +1,159 @@
// scripts/neural/track-work-orders.js
// 🧬 工单追踪器
// 铸渊每次唤醒时运行,追踪所有活跃工单状态
// 检查超时、匹配回执、更新状态、生成追踪报告
const fs = require('fs');
const path = require('path');
const WORK_ORDER_DIR = 'data/neural-reports/work-orders';
const COMPLETED_DIR = 'data/deploy-queue/completed';
const TRACKER_DIR = 'data/neural-reports/work-orders';
function loadJSON(p) {
try { return JSON.parse(fs.readFileSync(p, 'utf8')); }
catch (e) { return null; }
}
function getActiveWorkOrders() {
if (!fs.existsSync(WORK_ORDER_DIR)) return [];
var allOrders = [];
var files = fs.readdirSync(WORK_ORDER_DIR)
.filter(function(f) { return f.startsWith('work-orders-') && f.endsWith('.json'); });
for (var i = 0; i < files.length; i++) {
var data = loadJSON(path.join(WORK_ORDER_DIR, files[i]));
if (data && data.work_orders) {
for (var j = 0; j < data.work_orders.length; j++) {
allOrders.push(data.work_orders[j]);
}
}
}
return allOrders.filter(function(wo) {
return wo.status !== 'CLOSED' && wo.status !== 'ESCALATED' && wo.status !== 'VERIFIED';
});
}
function getCompletedReceipts() {
if (!fs.existsSync(COMPLETED_DIR)) return {};
var receipts = {};
var files = fs.readdirSync(COMPLETED_DIR)
.filter(function(f) { return f.endsWith('.json'); });
for (var i = 0; i < files.length; i++) {
var receipt = loadJSON(path.join(COMPLETED_DIR, files[i]));
if (receipt && receipt.command_id) {
receipts[receipt.command_id] = receipt;
}
}
return receipts;
}
function checkTimeout(workOrder) {
var timeout = workOrder.timeout_hours || 24;
var created = new Date(workOrder.created);
var now = new Date();
var elapsed = (now - created) / (1000 * 60 * 60);
return elapsed > timeout;
}
function trackWorkOrders() {
console.log('\n━━━ 🧬 工单追踪器启动 ━━━\n');
var activeOrders = getActiveWorkOrders();
var receipts = getCompletedReceipts();
console.log('活跃工单: ' + activeOrders.length + ' 个');
var stats = {
total_active: activeOrders.length,
by_status: {},
timed_out: 0,
matched_receipts: 0,
escalated: 0
};
for (var i = 0; i < activeOrders.length; i++) {
var wo = activeOrders[i];
var status = wo.status || 'pending';
// 统计状态分布
if (!stats.by_status[status]) stats.by_status[status] = 0;
stats.by_status[status]++;
// 检查超时
if (checkTimeout(wo)) {
stats.timed_out++;
console.log(' ⏰ 超时: ' + wo.id + ' (' + wo.title + ')');
// 检查是否需要升级
var maxRetries = (wo.constraints && wo.constraints.max_retries) || 2;
if (wo.retry_count >= maxRetries) {
wo.status = 'ESCALATED';
stats.escalated++;
console.log(' 🔺 升级到人类: ' + wo.id);
}
}
// 检查回执匹配
if (wo.command_id && receipts[wo.command_id]) {
var receipt = receipts[wo.command_id];
stats.matched_receipts++;
if (receipt.result && receipt.result.status === 'success') {
wo.status = 'VERIFIED';
console.log(' ✅ 已验证: ' + wo.id + ' (回执成功)');
} else if (receipt.result && receipt.result.status === 'failure') {
wo.status = 'pending';
wo.retry_count = (wo.retry_count || 0) + 1;
console.log(' ❌ 失败: ' + wo.id + ' (重试 ' + wo.retry_count + ')');
}
}
}
// 生成追踪报告
var now = new Date();
var cstTime = new Date(now.getTime() + 8 * 60 * 60 * 1000);
var dateStr = cstTime.toISOString().split('T')[0];
var trackerReport = {
tracker_id: 'TRACKER-' + dateStr,
timestamp: now.toISOString(),
stats: stats,
active_orders: activeOrders.map(function(wo) {
return {
id: wo.id,
severity: wo.severity,
title: wo.title,
status: wo.status,
created: wo.created,
timed_out: checkTimeout(wo)
};
})
};
fs.mkdirSync(TRACKER_DIR, { recursive: true });
fs.writeFileSync(
path.join(TRACKER_DIR, 'tracker-' + dateStr + '.json'),
JSON.stringify(trackerReport, null, 2)
);
console.log('\n📊 追踪报告:');
console.log(' 活跃: ' + stats.total_active);
console.log(' 超时: ' + stats.timed_out);
console.log(' 回执匹配: ' + stats.matched_receipts);
console.log(' 升级: ' + stats.escalated);
console.log(' 状态分布: ' + JSON.stringify(stats.by_status));
console.log('\n━━━ 追踪完成 ━━━\n');
return trackerReport;
}
if (require.main === module) {
trackWorkOrders();
}
module.exports = { trackWorkOrders };

View File

@ -1,6 +1,6 @@
{
"version": "1.0.0",
"last_scan": "2026-03-24T04:24:59.723Z",
"last_scan": "2026-03-25T06:00:55.972Z",
"last_scan_by": "skyeye-scan-engine",
"infrastructure": {
"github": {
@ -114,7 +114,10 @@
"hibernate_exempt": true,
"priority": "P0",
"alert_on_failure": true,
"alert_channels": ["notion-dashboard", "agent-bulletin"]
"alert_channels": [
"notion-dashboard",
"agent-bulletin"
]
},
{
"id": "TOKEN-HEALTH",
@ -123,7 +126,10 @@
"hibernate_exempt": true,
"priority": "P0",
"alert_on_failure": true,
"alert_channels": ["notion-dashboard", "agent-bulletin"]
"alert_channels": [
"notion-dashboard",
"agent-bulletin"
]
},
{
"id": "NIGHTLY-REPAIR",
@ -132,7 +138,10 @@
"hibernate_exempt": true,
"priority": "P0",
"alert_on_failure": true,
"alert_channels": ["dashboard", "agent-bulletin"],
"alert_channels": [
"dashboard",
"agent-bulletin"
],
"note": "周六休眠期内仅执行扫描+仪表盘更新,跳过修复/PR"
}
]
@ -213,7 +222,10 @@
"nightly_scan": "每天 23:00 CST (15:00 UTC)",
"merge_watchdog": "事件驱动PR合并时触发"
},
"agents": ["AG-ZY-087", "AG-ZY-088"]
"agents": [
"AG-ZY-087",
"AG-ZY-088"
]
},
"sync_dev_status": {
"node_id": "SYNC-DEV-STATUS-V1",
@ -227,7 +239,10 @@
"data_file": ".github/persona-brain/dev-status.json",
"sync_log": ".github/persona-brain/dev-status-sync-log.json",
"schedule": {
"sync": ["09:00 CST (01:00 UTC)", "22:00 CST (14:00 UTC)"],
"sync": [
"09:00 CST (01:00 UTC)",
"22:00 CST (14:00 UTC)"
],
"monitor": "08:30 CST (00:30 UTC)"
},
"thresholds": {
@ -254,11 +269,31 @@
"ssl": "Let's Encrypt (pending)"
},
"services": {
"api_proxy": { "port": 3721, "name": "guanghulab-proxy", "desc": "AI 聊天代理 SSE" },
"backend": { "port": 3000, "name": "guanghulab-backend", "desc": "Express 主后端" },
"hli": { "port": 3001, "name": "guanghulab", "desc": "HLI 中间层" },
"persona_studio": { "port": 3002, "name": "persona-studio", "desc": "Persona Studio 后端" },
"websocket": { "port": 8080, "name": "guanghulab-ws", "desc": "看板 WebSocket" }
"api_proxy": {
"port": 3721,
"name": "guanghulab-proxy",
"desc": "AI 聊天代理 SSE"
},
"backend": {
"port": 3000,
"name": "guanghulab-backend",
"desc": "Express 主后端"
},
"hli": {
"port": 3001,
"name": "guanghulab",
"desc": "HLI 中间层"
},
"persona_studio": {
"port": 3002,
"name": "persona-studio",
"desc": "Persona Studio 后端"
},
"websocket": {
"port": 8080,
"name": "guanghulab-ws",
"desc": "看板 WebSocket"
}
},
"cd_workflow": "deploy-to-server.yml",
"guard": "skyeye/guards/web-deploy-guard.json",

View File

@ -0,0 +1,305 @@
{
"scan_id": "SCAN-20260325",
"mode": "full",
"timestamp": "2026-03-25T06:00:55.969Z",
"guard_scan": {
"total": 6,
"valid": 5,
"invalid": [],
"missing_fields": [
{
"file": "web-deploy-guard.json",
"missing": [
"quota_policy"
]
}
]
},
"workflow_scan": {
"total": 96,
"files": [
"agent-checkin.yml",
"auto-deploy-drive-bridge.yml",
"auto-reply-discussions.yml",
"bingshuo-deploy-agent.yml",
"bingshuo-neural-system.yml",
"brain-sync.yml",
"bridge-broadcast-pdf.yml",
"bridge-changes-to-notion.yml",
"bridge-heartbeat.yml",
"bridge-session-summary.yml",
"bridge-syslog-intake.yml",
"bridge-syslog-to-notion.yml",
"buffer-collect.yml",
"buffer-flush.yml",
"check-structure.yml",
"check-token-health.yml",
"daily-maintenance.yml",
"daily-report.yml",
"deploy-pages.yml",
"deploy-to-server.yml",
"distribute-broadcasts.yml",
"esp-signal-processor.yml",
"execution-sync.yml",
"federation-bridge.yml",
"feishu-syslog-bridge.yml",
"generate-module-doc.yml",
"grid-db-archive.yml",
"grid-db-processor.yml",
"grid-db-training-extract.yml",
"hli-contract-check.yml",
"merge-watchdog.yml",
"meta-watchdog.yml",
"multi-persona-awakening.yml",
"neural-daily-digest.yml",
"notion-callback-pipeline.yml",
"notion-connectivity-test.yml",
"notion-heartbeat.yml",
"notion-page-reader.yml",
"notion-poll.yml",
"notion-wake-listener.yml",
"openclaw-wake-loop.yml",
"persona-invoke.yml",
"persona-thinking-window.yml",
"pm2-server-diagnose.yml",
"process-notion-orders.yml",
"ps-on-build.yml",
"ps-on-chat.yml",
"ps-on-complete.yml",
"ps-on-login.yml",
"psp-daily-inspection.yml",
"pull-sync-awen.yml",
"push-broadcast-feishu.yml",
"push-broadcast.yml",
"readme-ui-refresh.yml",
"receive-spoke-checkin.yml",
"receive-syslog.yml",
"renew-gdrive-tokens.yml",
"sandbox-deploy.yml",
"server-patrol.yml",
"skyeye-checkin-audit.yml",
"skyeye-checkin-receiver.yml",
"skyeye-credential-audit.yml",
"skyeye-daily-hibernation.yml",
"skyeye-devsync-repair.yml",
"skyeye-weekly-hibernation.yml",
"skyeye-weekly-scan.yml",
"staging-preview.yml",
"sync-deploy-to-notion.yml",
"sync-dev-status.yml",
"sync-griddb-to-drive.yml",
"sync-griddb-to-notion.yml",
"sync-login-entry.yml",
"sync-notion-profiles.yml",
"sync-notion-to-griddb.yml",
"sync-persona-studio.yml",
"sync-repo-to-drive.yml",
"syslog-auto-pipeline.yml",
"syslog-issue-pipeline.yml",
"syslog-pipeline.yml",
"tcs-semantic-landing.yml",
"test-notion-bridge.yml",
"tianyan-daily-patrol.yml",
"tianyan-nightly-scan.yml",
"update-readme-bulletin.yml",
"update-readme.yml",
"update-repo-map.yml",
"zhuyuan-brain-sync.yml",
"zhuyuan-commander.yml",
"zhuyuan-daily-agent.yml",
"zhuyuan-daily-inspection.yml",
"zhuyuan-daily-selfcheck.yml",
"zhuyuan-exec-engine.yml",
"zhuyuan-gate-guard.yml",
"zhuyuan-issue-reply.yml",
"zhuyuan-pr-review.yml",
"zhuyuan-skyeye.yml"
],
"errors": []
},
"directory_scan": {
"checked": 19,
"present": 19,
"missing": []
},
"sub_repo_scan": {
"total": 2,
"verified": [
{
"name": "qinfendebingshuo/guanghulab",
"role": "main",
"guard_path_exists": true
},
{
"name": "WENZHUOXI/guanghu-awen",
"role": "sub-repo",
"guard_path_exists": true
}
]
},
"ontology_scan": {
"dimension": "D16",
"name": "本体论完整性",
"checks": [
{
"item": "ontology.json 存在",
"status": "✅",
"version": "1.0"
},
{
"item": "核心公理完整性",
"status": "✅",
"detail": "6/6 条公理"
},
{
"item": "三层安全定义",
"status": "✅",
"detail": "3/3 层"
},
{
"item": "copilot-instructions 本体论宣言",
"status": "✅",
"detail": "已注入"
},
{
"item": "README 本体论标识",
"status": "✅",
"detail": "已注入"
}
]
},
"neural_map_scan": {
"dimension": "D20",
"name": "双端映射完整性",
"checks": [
{
"item": "neural-map.json 存在且可解析",
"status": "✅",
"detail": "version: 3.0.0"
},
{
"item": "映射 Workflow 文件检查",
"status": "✅",
"detail": "11/11 文件存在"
},
{
"item": "未映射 Workflow 检查",
"status": "✅",
"detail": "85 个未映射(非核心 Workflow 可不映射)"
},
{
"item": "Brain 注册完整性",
"status": "✅",
"detail": "所有 Brain 均已注册"
},
{
"item": "报告目录存在性",
"status": "✅",
"detail": "所有报告目录已创建"
}
],
"unmapped_workflows": [
"agent-checkin.yml",
"auto-deploy-drive-bridge.yml",
"auto-reply-discussions.yml",
"bingshuo-deploy-agent.yml",
"bingshuo-neural-system.yml",
"brain-sync.yml",
"bridge-broadcast-pdf.yml",
"bridge-changes-to-notion.yml",
"bridge-heartbeat.yml",
"bridge-session-summary.yml",
"bridge-syslog-intake.yml",
"bridge-syslog-to-notion.yml",
"buffer-collect.yml",
"buffer-flush.yml",
"check-structure.yml",
"check-token-health.yml",
"daily-maintenance.yml",
"daily-report.yml",
"deploy-pages.yml",
"esp-signal-processor.yml",
"execution-sync.yml",
"federation-bridge.yml",
"feishu-syslog-bridge.yml",
"generate-module-doc.yml",
"grid-db-archive.yml",
"grid-db-processor.yml",
"grid-db-training-extract.yml",
"hli-contract-check.yml",
"merge-watchdog.yml",
"meta-watchdog.yml",
"multi-persona-awakening.yml",
"notion-callback-pipeline.yml",
"notion-connectivity-test.yml",
"notion-heartbeat.yml",
"notion-page-reader.yml",
"notion-poll.yml",
"notion-wake-listener.yml",
"openclaw-wake-loop.yml",
"persona-invoke.yml",
"persona-thinking-window.yml",
"pm2-server-diagnose.yml",
"process-notion-orders.yml",
"ps-on-build.yml",
"ps-on-chat.yml",
"ps-on-complete.yml",
"ps-on-login.yml",
"psp-daily-inspection.yml",
"pull-sync-awen.yml",
"push-broadcast-feishu.yml",
"push-broadcast.yml",
"readme-ui-refresh.yml",
"receive-spoke-checkin.yml",
"receive-syslog.yml",
"renew-gdrive-tokens.yml",
"sandbox-deploy.yml",
"skyeye-checkin-audit.yml",
"skyeye-checkin-receiver.yml",
"skyeye-credential-audit.yml",
"skyeye-daily-hibernation.yml",
"skyeye-devsync-repair.yml",
"skyeye-weekly-hibernation.yml",
"staging-preview.yml",
"sync-deploy-to-notion.yml",
"sync-griddb-to-drive.yml",
"sync-griddb-to-notion.yml",
"sync-login-entry.yml",
"sync-notion-profiles.yml",
"sync-notion-to-griddb.yml",
"sync-persona-studio.yml",
"sync-repo-to-drive.yml",
"syslog-auto-pipeline.yml",
"syslog-issue-pipeline.yml",
"tcs-semantic-landing.yml",
"test-notion-bridge.yml",
"tianyan-daily-patrol.yml",
"tianyan-nightly-scan.yml",
"update-readme-bulletin.yml",
"update-readme.yml",
"update-repo-map.yml",
"zhuyuan-brain-sync.yml",
"zhuyuan-commander.yml",
"zhuyuan-daily-agent.yml",
"zhuyuan-daily-inspection.yml",
"zhuyuan-issue-reply.yml",
"zhuyuan-pr-review.yml"
],
"invalid_brains": []
},
"issues": [
{
"severity": "warning",
"category": "guard_config",
"detail": "Guard web-deploy-guard.json missing fields: quota_policy"
}
],
"summary": {
"total_issues": 1,
"errors": 0,
"warnings": 1,
"guards_healthy": "5/6",
"workflows_found": 96,
"directories_ok": "19/19"
}
}

View File

@ -202,6 +202,129 @@ function checkOntologyIntegrity() {
return result;
}
// D20 · 双端映射完整性检查 (Neural Map Integrity)
function checkNeuralMapIntegrity() {
var result = {
dimension: 'D20',
name: '双端映射完整性',
checks: [],
unmapped_workflows: [],
invalid_brains: []
};
var neuralMapPath = path.join(SKYEYE_DIR, 'neural-map.json');
if (!fs.existsSync(neuralMapPath)) {
result.checks.push({
item: 'neural-map.json 存在',
status: '🔴',
detail: '文件缺失'
});
return result;
}
var neuralMap = loadJSON(neuralMapPath);
if (!neuralMap) {
result.checks.push({
item: 'neural-map.json 可解析',
status: '🔴',
detail: 'JSON 解析失败'
});
return result;
}
result.checks.push({
item: 'neural-map.json 存在且可解析',
status: '✅',
detail: 'version: ' + (neuralMap.version || 'unknown')
});
// 检查所有映射的 Workflow 文件是否实际存在
var mappedFiles = {};
var workflowEntries = Object.entries(neuralMap.github_workflows || {});
var existCount = 0;
var missingCount = 0;
for (var i = 0; i < workflowEntries.length; i++) {
var wfId = workflowEntries[i][0];
var wf = workflowEntries[i][1];
var filePath = path.join(ROOT, wf.file);
mappedFiles[wf.file] = true;
if (fs.existsSync(filePath)) {
existCount++;
} else {
missingCount++;
result.checks.push({
item: '映射文件存在: ' + wf.file,
status: '🔴',
detail: wfId + ' 映射的文件不存在'
});
}
}
result.checks.push({
item: '映射 Workflow 文件检查',
status: missingCount === 0 ? '✅' : '🔴',
detail: existCount + '/' + workflowEntries.length + ' 文件存在'
});
// 检查实际 .yml 中是否有未映射的(仅检查核心 Workflow非全量
var workflowDir = path.join(ROOT, '.github/workflows');
if (fs.existsSync(workflowDir)) {
var actualFiles = fs.readdirSync(workflowDir)
.filter(function(f) { return f.endsWith('.yml') || f.endsWith('.yaml'); });
for (var j = 0; j < actualFiles.length; j++) {
var ymlPath = '.github/workflows/' + actualFiles[j];
if (!mappedFiles[ymlPath]) {
result.unmapped_workflows.push(actualFiles[j]);
}
}
}
// 注意unmapped 不一定是错误,因为 neural-map 只映射核心 Workflow
result.checks.push({
item: '未映射 Workflow 检查',
status: result.unmapped_workflows.length <= 85 ? '✅' : '🟡',
detail: result.unmapped_workflows.length + ' 个未映射(非核心 Workflow 可不映射)'
});
// 检查每个 brain 是否在 notion_brains 中注册
for (var k = 0; k < workflowEntries.length; k++) {
var wfId2 = workflowEntries[k][0];
var wf2 = workflowEntries[k][1];
if (wf2.brain && !(neuralMap.notion_brains || {})[wf2.brain]) {
result.invalid_brains.push({ workflow: wfId2, brain: wf2.brain });
}
}
result.checks.push({
item: 'Brain 注册完整性',
status: result.invalid_brains.length === 0 ? '✅' : '🔴',
detail: result.invalid_brains.length === 0
? '所有 Brain 均已注册'
: result.invalid_brains.length + ' 个 Brain 未注册'
});
// 检查 report_path 目录是否存在
var reportPathMissing = 0;
for (var m = 0; m < workflowEntries.length; m++) {
var wf3 = workflowEntries[m][1];
if (wf3.report_path && !fs.existsSync(path.join(ROOT, wf3.report_path))) {
reportPathMissing++;
}
}
result.checks.push({
item: '报告目录存在性',
status: reportPathMissing === 0 ? '✅' : '🟡',
detail: reportPathMissing === 0
? '所有报告目录已创建'
: reportPathMissing + ' 个报告目录缺失'
});
return result;
}
function run() {
const args = process.argv.slice(2);
const mode = args.find(a => a.startsWith('--mode='))?.split('=')[1] || 'full';
@ -224,6 +347,7 @@ function run() {
directory_scan: scanDirectoryStructure(),
sub_repo_scan: scanSubRepos(manifest),
ontology_scan: checkOntologyIntegrity(),
neural_map_scan: checkNeuralMapIntegrity(),
issues: [],
summary: {}
};
@ -270,6 +394,32 @@ function run() {
}
}
// D20 · 双端映射完整性 issues
if (scanResult.neural_map_scan && scanResult.neural_map_scan.checks) {
for (const check of scanResult.neural_map_scan.checks) {
if (check.status === '🔴') {
scanResult.issues.push({
severity: 'error',
category: 'neural_map_integrity',
detail: `D20 · ${check.item}: ${check.detail || '失败'}`
});
} else if (check.status === '🟡') {
scanResult.issues.push({
severity: 'warning',
category: 'neural_map_integrity',
detail: `D20 · ${check.item}: ${check.detail || '需关注'}`
});
}
}
if (scanResult.neural_map_scan.invalid_brains.length > 0) {
scanResult.issues.push({
severity: 'error',
category: 'neural_map_integrity',
detail: `D20 · Brain 映射指向不存在的 Agent: ${scanResult.neural_map_scan.invalid_brains.map(b => b.brain).join(', ')}`
});
}
}
// Summary
scanResult.summary = {
total_issues: scanResult.issues.length,
@ -304,6 +454,14 @@ function run() {
console.log(` ${check.status} ${check.item}${check.detail ? ' · ' + check.detail : ''}${check.version ? ' · v' + check.version : ''}`);
}
}
// D20 · 双端映射完整性状态
if (scanResult.neural_map_scan) {
console.log(`[SkyEye Scan Engine] D20 Neural Map:`);
for (const check of scanResult.neural_map_scan.checks) {
console.log(` ${check.status} ${check.item}${check.detail ? ' · ' + check.detail : ''}`);
}
}
console.log(`[SkyEye Scan Engine] Log saved: ${logPath}`);
// Output full result as JSON for pipeline