SY-CMD-KEY-012: 密钥全量替换 — 59个旧密钥→37个ZY_*统一命名 + 密钥清单 + 验证器 + .env安全修复 + LLM统一路由

Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/d1e3a208-2089-466b-ac54-eb690c554bca

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-03-29 10:58:16 +00:00 committed by GitHub
parent 80b0eff638
commit 50bbc07601
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 1379 additions and 345 deletions

6
.env
View File

@ -1,6 +0,0 @@
DINGTALK_APP_KEY=dingzerc04si7jmyvasq
DINGTALK_APP_SECRET=vJnmeF0B1yaYRv7u4IzdKsC6wPfStyUWEQnBdjas-NH5JUAKUwj7Dc659Bau66di
DINGTALK_ROBOT_CODE=dingzerc04si7jmyvasq
PORT=3000
KIMI_API_KEY=sk-A1STcZTjWTYOiG864MCt31VHHq8fD1r9E7LBDxoaMDDoGGbx

View File

@ -1,11 +0,0 @@
{\rtf1\ansi\ansicpg936\cocoartf2867
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\paperw11900\paperh16840\margl1440\margr1440\vieww17500\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\f0\fs24 \cf0 DINGTALK_APP_KEY=dingzerc04si7jmyvasq\
DINGTALK_APP_SECRET=vJnmeF0B1yaYRv7u4IzdKsC6wPfStyUWEQnBdjas-NH5JUAKUwj7Dc659Bau66di\
DINGTALK_ROBOT_CODE=dingzerc04si7jmyvasq\
PORT=3000}

View File

@ -21,10 +21,10 @@ jobs:
- name: ⚡ 执行部署
env:
GDRIVE_CLIENT_ID: ${{ secrets.GDRIVE_CLIENT_ID }}
GDRIVE_CLIENT_SECRET: ${{ secrets.GDRIVE_CLIENT_SECRET }}
GDRIVE_REFRESH_TOKEN: ${{ secrets.GDRIVE_REFRESH_TOKEN }}
DEPLOY_GITHUB_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GDRIVE_CLIENT_ID: ${{ secrets.ZY_GDRIVE_CLIENT_ID }}
GDRIVE_CLIENT_SECRET: ${{ secrets.ZY_GDRIVE_SECRET }}
GDRIVE_REFRESH_TOKEN: ${{ secrets.ZY_GDRIVE_REFRESH_TOKEN }}
DEPLOY_GITHUB_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
run: |
for f in grid-db/deploy-queue/*.json; do
[ -f "$f" ] && node scripts/grid-db/deploy-drive-bridge.js "$f"

View File

@ -54,12 +54,12 @@ jobs:
- name: 🧠 唤醒铸渊核心大脑
id: wake
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: |
node core/brain-wake --task "冰朔神经系统维护" || {
echo "⚠️ 核心大脑唤醒失败,使用 dry-run 模式继续"

View File

@ -41,8 +41,8 @@ jobs:
- name: 🧠 唤醒铸渊核心大脑
id: wake
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
run: |
node core/brain-wake --task "桥接广播PDF生成分发" || {
echo "⚠️ 核心大脑唤醒失败,使用 dry-run 模式继续"
@ -69,15 +69,15 @@ jobs:
- name: 📡 检查调度队列
id: check
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
BRIDGE_QUEUE_DB_ID: ${{ secrets.BRIDGE_QUEUE_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
BRIDGE_QUEUE_DB_ID: ${{ secrets.ZY_NOTION_BRIDGE_DB }}
run: node scripts/bridge/check-queue.js BROADCAST_READY
- name: 📥 拉取广播内容
if: steps.check.outputs.task_count != '0'
id: fetch
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
QUEUE_FILE: ${{ steps.check.outputs.queue_file }}
run: node scripts/bridge/fetch-broadcast.js
@ -96,19 +96,19 @@ jobs:
env:
PDF_MANIFEST: ${{ steps.pdf.outputs.pdf_manifest }}
UPLOAD_MODE: ${{ vars.BRIDGE_UPLOAD_MODE || 'server' }}
OSS_ACCESS_KEY: ${{ secrets.OSS_ACCESS_KEY }}
OSS_SECRET_KEY: ${{ secrets.OSS_SECRET_KEY }}
OSS_ACCESS_KEY: ${{ secrets.ZY_OSS_KEY }}
OSS_SECRET_KEY: ${{ secrets.ZY_OSS_SECRET }}
run: node scripts/bridge/upload-pdf.js
- name: 📢 分发到IM
if: steps.check.outputs.task_count != '0'
env:
DIST_MANIFEST: ${{ steps.upload.outputs.dist_manifest }}
FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }}
FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }}
DINGTALK_TOKEN: ${{ secrets.DINGTALK_TOKEN }}
SMTP_USER: ${{ secrets.SMTP_USER }}
SMTP_PASS: ${{ secrets.SMTP_PASS }}
FEISHU_APP_ID: ${{ secrets.ZY_FEISHU_APP_ID }}
FEISHU_APP_SECRET: ${{ secrets.ZY_FEISHU_APP_SECRET }}
DINGTALK_TOKEN: ${{ secrets.ZY_DINGTALK_TOKEN }}
SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
SMTP_PASS: ${{ secrets.ZY_SMTP_PASS }}
ALERT_EMAIL: ${{ vars.ALERT_EMAIL || '565183519@qq.com' }}
FEISHU_BROADCAST_CHAT_ID: ${{ vars.FEISHU_BROADCAST_CHAT_ID }}
run: node scripts/bridge/distribute.js
@ -116,7 +116,7 @@ jobs:
- name: ✅ 更新调度队列状态
if: steps.check.outputs.task_count != '0'
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
QUEUE_FILE: ${{ steps.check.outputs.queue_file }}
run: node scripts/bridge/update-queue-status.js

View File

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

View File

@ -37,8 +37,8 @@ jobs:
- name: 🧠 唤醒铸渊核心大脑
id: wake
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
run: |
node core/brain-wake --task "桥接心跳检测" || {
echo "⚠️ 核心大脑唤醒失败,使用 dry-run 模式继续"
@ -65,8 +65,8 @@ jobs:
- name: 💓 执行心跳检测
id: heartbeat
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
BRIDGE_QUEUE_DB_ID: ${{ secrets.BRIDGE_QUEUE_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
BRIDGE_QUEUE_DB_ID: ${{ secrets.ZY_NOTION_BRIDGE_DB }}
run: node scripts/bridge/heartbeat.js
- name: 📦 提交心跳日志

View File

@ -39,8 +39,8 @@ jobs:
- name: 🧠 唤醒铸渊核心大脑
id: wake
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
run: |
node core/brain-wake --task "桥接SYSLOG上行" || {
echo "⚠️ 核心大脑唤醒失败,使用 dry-run 模式继续"
@ -67,9 +67,9 @@ jobs:
- name: 📥 批量处理 SYSLOG
id: process
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
BRIDGE_QUEUE_DB_ID: ${{ secrets.BRIDGE_QUEUE_DB_ID }}
SYSLOG_DB_ID: ${{ secrets.NOTION_SYSLOG_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
BRIDGE_QUEUE_DB_ID: ${{ secrets.ZY_NOTION_BRIDGE_DB }}
SYSLOG_DB_ID: ${{ secrets.ZY_NOTION_SYSLOG_DB }}
COMMIT_SHA: ${{ github.sha }}
run: node scripts/bridge/process-syslog-batch.js

View File

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

View File

@ -32,12 +32,12 @@ jobs:
- name: 🧠 唤醒铸渊核心大脑
id: wake
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: |
node core/brain-wake --task "每日维护" || {
echo "⚠️ 核心大脑唤醒失败,使用 dry-run 模式继续"
@ -127,7 +127,7 @@ jobs:
- name: 检查 Notion API 连通性
id: notion_check
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
run: |
echo "🔍 检查 Notion API 连通性..."
if [ -z "$NOTION_TOKEN" ]; then
@ -197,8 +197,8 @@ jobs:
# ── Step 6: 向 Notion 回报巡检结果 ──
- name: 向 Notion 回报巡检结果
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
SYSLOG_DB_ID: ${{ secrets.SYSLOG_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
SYSLOG_DB_ID: ${{ secrets.ZY_NOTION_SYSLOG_DB }}
run: |
if [ -z "$NOTION_TOKEN" ] || [ -z "$SYSLOG_DB_ID" ]; then
echo "⚠️ NOTION_TOKEN 或 SYSLOG_DB_ID 未配置,跳过 Notion 回报"
@ -268,7 +268,7 @@ jobs:
- name: Read brain data and sync to Notion
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
run: |
if [ -z "$NOTION_TOKEN" ]; then
echo "⚠️ NOTION_TOKEN 未配置,跳过 Execution Status 同步"

View File

@ -34,11 +34,11 @@ jobs:
- name: "🚀 部署到阿里云"
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_KEY }}
host: ${{ secrets.ZY_SERVER_HOST }}
username: ${{ secrets.ZY_SERVER_USER }}
key: ${{ secrets.ZY_SERVER_KEY }}
script: |
cd ${{ secrets.DEPLOY_PATH }}/backend/api-server/
cd ${{ secrets.ZY_SERVER_PATH }}/backend/api-server/
git pull origin main
npm install --production
pm2 restart guanghu-api || pm2 start ecosystem.config.js

View File

@ -8,18 +8,15 @@ name: "🚀 铸渊 CD · 自动部署到 guanghulab.com"
# 已从阿里云(8.155.62.235)迁移到腾讯云(150.109.76.244)
# push 到 main → 校验 → rsync 同步全站到服务器 → 后端重启 → Nginx 配置 → Notion 通知
#
# 必需 GitHub Secrets仓库 Settings → Secrets → Actions:
# 必需 GitHub Secrets参考 brain/secrets-manifest.json:
# ZY_SERVER_HOST — 铸渊主权服务器 IP (150.109.76.244)
# ZY_SERVER_USER — SSH 用户名
# ZY_SERVER_KEY — SSH 私钥(完整 PEM 内容)
# ZY_SERVER_PATH — 网站根目录(/opt/zhuyuan
#
# 兼容旧密钥(过渡期自动降级):
# DEPLOY_HOST / DEPLOY_USER / DEPLOY_KEY / DEPLOY_PATH
#
# 可选 Secrets已有则自动启用 Notion 通知):
# NOTION_TOKEN — Notion 集成 token
# CHANGES_DB_ID — Notion 变更日志数据库 ID有内置默认值
# 可选 Secrets:
# ZY_NOTION_TOKEN — Notion 集成 token
# ZY_NOTION_CHANGELOG_DB — Notion 变更日志数据库 ID
on:
push:
@ -96,8 +93,7 @@ jobs:
steps:
- name: 🔐 检查必需 Secrets
run: |
# 优先使用 ZY_SERVER_* 密钥(腾讯云主权服务器)
# 如未配置,降级使用旧 DEPLOY_* 密钥(过渡期兼容)
# ZY_SERVER_* 密钥(铸渊主权服务器 · 参考 brain/secrets-manifest.json
if [ -n "${{ secrets.ZY_SERVER_HOST }}" ]; then
echo "SERVER_HOST=${{ secrets.ZY_SERVER_HOST }}" >> $GITHUB_ENV
echo "SERVER_USER=${{ secrets.ZY_SERVER_USER }}" >> $GITHUB_ENV
@ -106,14 +102,6 @@ jobs:
echo "KEYEOF" >> $GITHUB_ENV
echo "SERVER_PATH=${{ secrets.ZY_SERVER_PATH }}" >> $GITHUB_ENV
echo "✅ 使用铸渊主权服务器密钥 (ZY_SERVER_*)"
elif [ -n "${{ secrets.DEPLOY_HOST }}" ]; then
echo "SERVER_HOST=${{ secrets.DEPLOY_HOST }}" >> $GITHUB_ENV
echo "SERVER_USER=${{ secrets.DEPLOY_USER }}" >> $GITHUB_ENV
echo "SERVER_KEY<<KEYEOF" >> $GITHUB_ENV
echo "${{ secrets.DEPLOY_KEY }}" >> $GITHUB_ENV
echo "KEYEOF" >> $GITHUB_ENV
echo "SERVER_PATH=${{ secrets.DEPLOY_PATH }}" >> $GITHUB_ENV
echo "⚠️ 使用旧部署密钥 (DEPLOY_*),建议迁移到 ZY_SERVER_*"
else
echo "❌ 未配置服务器部署密钥"
echo ""
@ -130,10 +118,10 @@ jobs:
# 验证必需字段
MISSING=""
if [ -z "${{ secrets.ZY_SERVER_HOST }}${{ secrets.DEPLOY_HOST }}" ]; then MISSING="${MISSING} HOST"; fi
if [ -z "${{ secrets.ZY_SERVER_USER }}${{ secrets.DEPLOY_USER }}" ]; then MISSING="${MISSING} USER"; fi
if [ -z "${{ secrets.ZY_SERVER_KEY }}${{ secrets.DEPLOY_KEY }}" ]; then MISSING="${MISSING} KEY"; fi
if [ -z "${{ secrets.ZY_SERVER_PATH }}${{ secrets.DEPLOY_PATH }}" ]; then MISSING="${MISSING} PATH"; fi
if [ -z "${{ secrets.ZY_SERVER_HOST }}" ]; then MISSING="${MISSING} HOST"; fi
if [ -z "${{ secrets.ZY_SERVER_USER }}" ]; then MISSING="${MISSING} USER"; fi
if [ -z "${{ secrets.ZY_SERVER_KEY }}" ]; then MISSING="${MISSING} KEY"; fi
if [ -z "${{ secrets.ZY_SERVER_PATH }}" ]; then MISSING="${MISSING} PATH"; fi
if [ -n "$MISSING" ]; then
echo "❌ 缺少必需密钥:${MISSING}"
exit 1
@ -178,7 +166,7 @@ jobs:
"${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}" \
"mkdir -p '${{ env.SERVER_PATH }}'" || {
echo "❌ 无法创建远程部署目录SSH 连接失败或权限不足)"
echo "请确认 DEPLOY_PATH 设置正确且 DEPLOY_USER 有写入权限"
echo "请确认 ZY_SERVER_PATH 设置正确且 ZY_SERVER_USER 有写入权限"
exit 1
}
echo "✅ 远程部署目录已就绪"
@ -318,10 +306,10 @@ jobs:
cd '${{ env.SERVER_PATH }}/backend-integration'
npm install --production 2>/dev/null || echo '⚠️ api-proxy npm install 失败(可能无 package.json继续'
echo '🔄 重启 API 代理服务...'
export YUNWU_API_KEY='${{ secrets.YUNWU_API_KEY }}'
export DEEPSEEK_API_KEY='${{ secrets.YUNWU_API_KEY }}'
export YUNWU_API_KEY='${{ secrets.ZY_LLM_API_KEY }}'
export DEEPSEEK_API_KEY='${{ secrets.ZY_LLM_API_KEY }}'
pm2 delete guanghulab-proxy 2>/dev/null || true
YUNWU_API_KEY='${{ secrets.YUNWU_API_KEY }}' DEEPSEEK_API_KEY='${{ secrets.YUNWU_API_KEY }}' \
YUNWU_API_KEY='${{ secrets.ZY_LLM_API_KEY }}' DEEPSEEK_API_KEY='${{ secrets.ZY_LLM_API_KEY }}' \
pm2 start api-proxy.js --name guanghulab-proxy --update-env 2>/dev/null || \
echo '⚠️ API 代理 pm2 启动失败'
fi
@ -365,9 +353,9 @@ jobs:
cd '${{ env.SERVER_PATH }}/persona-studio/backend'
npm install --production 2>/dev/null || echo '⚠️ persona-studio npm install 失败'
echo '🔄 重启 persona-studio 服务...'
export MODEL_API_KEY='${{ secrets.MODEL_API_KEY }}'
export MODEL_API_KEY='${{ secrets.ZY_LLM_API_KEY }}'
pm2 delete persona-studio 2>/dev/null || true
MODEL_API_KEY='${{ secrets.MODEL_API_KEY }}' \
MODEL_API_KEY='${{ secrets.ZY_LLM_API_KEY }}' \
pm2 start server.js --name persona-studio --update-env 2>/dev/null || \
echo '⚠️ persona-studio pm2 启动失败'
fi
@ -760,8 +748,8 @@ jobs:
- name: 📡 推送部署记录到 Notion
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
CHANGES_DB_ID: ${{ secrets.NOTION_CHANGE_LOG_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
CHANGES_DB_ID: ${{ secrets.ZY_NOTION_CHANGELOG_DB }}
EVENT_TYPE: commit
COMMIT_SHA: ${{ github.sha }}
COMMIT_MSG: "[CD 部署] ${{ github.event.head_commit.message }}"
@ -813,8 +801,8 @@ jobs:
- name: "📡 同步回执到 Notion"
if: always()
env:
NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
RECEIPT_DB_ID: ${{ secrets.RECEIPT_DB_ID }}
NOTION_API_KEY: ${{ secrets.ZY_NOTION_TOKEN }}
RECEIPT_DB_ID: ${{ secrets.ZY_NOTION_RECEIPT_DB }}
run: |
node scripts/neural/write-receipt-to-notion.js \
--instruction-id "${{ github.event.inputs.instruction_id || 'AUTO' }}" \

View File

@ -48,7 +48,7 @@ jobs:
- name: 定时任务 · 公告或汇总
if: github.event_name == 'schedule'
env:
MAIN_REPO_TOKEN: ${{ secrets.MAIN_REPO_TOKEN }}
MAIN_REPO_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
GITHUB_ORG: qinfendebingshuo
run: |
HOUR=$(date -u +%H)
@ -61,7 +61,7 @@ jobs:
- name: 手动触发
if: github.event_name == 'workflow_dispatch'
env:
MAIN_REPO_TOKEN: ${{ secrets.MAIN_REPO_TOKEN }}
MAIN_REPO_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
GITHUB_ORG: qinfendebingshuo
run: |
ACTION="${{ github.event.inputs.action }}"
@ -75,7 +75,7 @@ jobs:
- name: Push触发 · 公告+广播
if: github.event_name == 'push'
env:
MAIN_REPO_TOKEN: ${{ secrets.MAIN_REPO_TOKEN }}
MAIN_REPO_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
GITHUB_ORG: qinfendebingshuo
run: |
node scripts/bridge-app.js bulletin

View File

@ -72,26 +72,26 @@ jobs:
# Step 2 · 模型状态检查
- name: "📊 模型状态检查"
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: |
node scripts/llm-automation-host.js --status
# Step 3 · 执行 LLM 任务
- name: "🤖 执行 LLM 任务"
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
YUNWU_API_KEY: ${{ secrets.YUNWU_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
YUNWU_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
GEMINI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: |
TASK="${{ github.event.inputs.task }}"
TASK_TYPE="${{ github.event.inputs.task_type }}"

View File

@ -55,7 +55,7 @@ jobs:
- name: "🔍 识别修复目标"
id: check
env:
GH_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
run: |
echo "[Merge Watchdog] 检测到 auto-repair PR 合并"
@ -126,7 +126,7 @@ jobs:
- name: "⏳ 等待目标 Workflow 运行"
id: wait
env:
GH_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
TARGET: ${{ needs.gate.outputs.target_workflows }}
run: |
echo "[Merge Watchdog] 等待目标 Workflow 下一次运行..."
@ -205,7 +205,7 @@ jobs:
- name: "✅ 修复确认 — 静默更新仪表盘"
if: needs.observe.outputs.workflow_result == 'success'
env:
GH_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
PR_NUM: ${{ needs.gate.outputs.pr_number }}
run: |
echo "[Merge Watchdog] ✅ 修复已生效 — 静默更新仪表盘"
@ -236,7 +236,7 @@ jobs:
if: needs.observe.outputs.workflow_result == 'failure'
env:
RETRY_COUNT: ${{ steps.load.outputs.retry_count }}
GH_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
PR_NUM: ${{ needs.gate.outputs.pr_number }}
run: |
NEW_COUNT=$((RETRY_COUNT + 1))
@ -306,10 +306,10 @@ jobs:
server_address: smtp.gmail.com
server_port: 465
secure: true
username: ${{ secrets.MAIL_USERNAME }}
password: ${{ secrets.MAIL_PASSWORD }}
username: ${{ secrets.ZY_SMTP_USER }}
password: ${{ secrets.ZY_SMTP_PASS }}
subject: "⛔ [光湖系统] 自动修复三次失败 — 需要手动介入"
to: ${{ secrets.HUMAN_EMAIL }}
to: ${{ secrets.ZY_SMTP_USER }}
from: "光湖 Merge Watchdog <noreply@guanghulab.com>"
html_body: |
<h2>⛔ 合并指令看守者 · 三振出局通知</h2>

View File

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

View File

@ -66,8 +66,8 @@ jobs:
# ━━━ 串行唤醒人格体 ━━━
- name: "🧠 串行唤醒人格体"
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
LLM_MODEL: ${{ vars.LLM_MODEL || 'deepseek-chat' }}
MODE: ${{ steps.quota.outputs.mode }}
INPUT_REASON: ${{ github.event.inputs.reason }}

View File

@ -27,7 +27,7 @@ jobs:
- name: 轮询工单簿 + 处理 + 回写
id: poll
env:
NOTION_API_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_API_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
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

@ -56,12 +56,12 @@ jobs:
- name: 🧠 唤醒铸渊核心大脑
id: wake
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: |
node core/brain-wake --task "Notion唤醒请求监听" || {
echo "⚠️ 核心大脑唤醒失败,使用 dry-run 模式继续"
@ -86,15 +86,15 @@ jobs:
- name: 📡 轮询 Notion 唤醒请求数据库
id: poll
env:
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 }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
WAKE_REQUEST_DB_ID: ${{ secrets.ZY_NOTION_WAKE_DB }}
SIGNAL_LOG_DB_ID: ${{ secrets.ZY_NOTION_SIGNAL_DB }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: node connectors/notion-wake-listener poll
- name: 📊 输出监听结果

View File

@ -133,8 +133,8 @@ jobs:
# ━━━ 唤醒人格体 · 进入思考模式 ━━━
- name: "🧠 唤醒人格体 · 进入思考模式"
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
LLM_MODEL: ${{ vars.LLM_MODEL || 'deepseek-chat' }}
PERSONA_ID: ${{ steps.schedule.outputs.persona }}
PERSONA_NAME: ${{ steps.schedule.outputs.name }}

View File

@ -50,9 +50,9 @@ jobs:
- name: 🔑 配置 SSH 连接
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/deploy_key
echo "${{ secrets.ZY_SERVER_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts 2>/dev/null || {
ssh-keyscan -H "${{ secrets.ZY_SERVER_HOST }}" >> ~/.ssh/known_hosts 2>/dev/null || {
echo "⚠️ ssh-keyscan 失败,使用 StrictHostKeyChecking=no 后备"
}
@ -66,7 +66,7 @@ jobs:
PM2_REPORT=$(ssh -i ~/.ssh/deploy_key \
-o StrictHostKeyChecking=no \
"${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" '
"${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}" '
echo "══════════════════════════════════════"
echo " PM2 进程状态概览"
echo "══════════════════════════════════════"
@ -163,7 +163,7 @@ jobs:
CLEANUP_REPORT=$(ssh -i ~/.ssh/deploy_key \
-o StrictHostKeyChecking=no \
"${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" '
"${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}" '
ERRORED_LIST=$(pm2 jlist 2>/dev/null | python3 -c "
import sys, json
try:
@ -220,7 +220,7 @@ jobs:
HEALTH_REPORT=$(ssh -i ~/.ssh/deploy_key \
-o StrictHostKeyChecking=no \
"${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" '
"${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}" '
echo "══════════════════════════════════════"
echo " Nginx 状态"
echo "══════════════════════════════════════"
@ -299,8 +299,8 @@ jobs:
# ━━━ 阶段三:生成 Notion 诊断报告 ━━━
- name: "📋 阶段三 · 写入 Notion 工单"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID || '84edd0640bf146a9a5a7840107013e8c' }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
NOTION_TICKET_DB_ID: ${{ secrets.ZY_NOTION_TICKET_DB || '84edd0640bf146a9a5a7840107013e8c' }}
PM2_REPORT: ${{ steps.pm2_diagnose.outputs.pm2_report }}
CLEANUP_REPORT: ${{ steps.pm2_cleanup.outputs.cleanup_report }}
HEALTH_REPORT: ${{ steps.health_check.outputs.health_report }}

View File

@ -30,12 +30,12 @@ jobs:
- name: 🧠 唤醒铸渊核心大脑
id: wake
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: |
node core/brain-wake --task "PSP 分身巡检" || {
echo "⚠️ 核心大脑唤醒失败,使用 dry-run 模式继续"
@ -63,8 +63,8 @@ jobs:
- name: 执行 PSP 巡检5项检查
env:
EMAIL_ADDRESS: ${{ secrets.EMAIL_ADDRESS }}
EMAIL_APP_PASSWORD: ${{ secrets.EMAIL_APP_PASSWORD }}
EMAIL_ADDRESS: ${{ secrets.ZY_SMTP_USER }}
EMAIL_APP_PASSWORD: ${{ secrets.ZY_SMTP_PASS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: node scripts/psp-inspection.js

View File

@ -44,14 +44,14 @@ jobs:
- name: 🔄 执行 Token 刷新
env:
GDRIVE_CLIENT_ID: ${{ secrets.GDRIVE_CLIENT_ID }}
GDRIVE_CLIENT_SECRET: ${{ secrets.GDRIVE_CLIENT_SECRET }}
GDRIVE_REFRESH_TOKEN: ${{ secrets.GDRIVE_REFRESH_TOKEN }}
GDRIVE_CLIENT_ID: ${{ secrets.ZY_GDRIVE_CLIENT_ID }}
GDRIVE_CLIENT_SECRET: ${{ secrets.ZY_GDRIVE_SECRET }}
GDRIVE_REFRESH_TOKEN: ${{ secrets.ZY_GDRIVE_REFRESH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FORCE_RENEW: ${{ inputs.force_renew || 'false' }}
# 新增开发者 Token每次加人时追加
# GDRIVE_REFRESH_TOKEN_DEV001: ${{ secrets.GDRIVE_REFRESH_TOKEN_DEV001 }}
# GDRIVE_REFRESH_TOKEN_DEV002: ${{ secrets.GDRIVE_REFRESH_TOKEN_DEV002 }}
# GDRIVE_REFRESH_TOKEN_DEV001: ${{ secrets.ZY_GDRIVE_REFRESH_TOKEN }}
# GDRIVE_REFRESH_TOKEN_DEV002: ${{ secrets.ZY_GDRIVE_REFRESH_TOKEN }}
run: node scripts/gdrive/renew-tokens.js
- name: 📋 提交注册表更新

View File

@ -63,17 +63,17 @@ jobs:
- name: "🔑 配置 SSH"
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_rsa
echo "${{ secrets.ZY_SERVER_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: "🏠 部署到沙盒"
id: deploy
env:
DEV_ID: ${{ needs.parse-and-validate.outputs.dev_id }}
MODULE: ${{ needs.parse-and-validate.outputs.module }}
HOST: ${{ secrets.DEPLOY_HOST }}
USER: ${{ secrets.DEPLOY_USER }}
HOST: ${{ secrets.ZY_SERVER_HOST }}
USER: ${{ secrets.ZY_SERVER_USER }}
run: |
SANDBOX="/var/www/${DEV_ID}/${MODULE}"
echo "📦 部署目标: ${SANDBOX}"
@ -102,8 +102,8 @@ jobs:
env:
DEV_ID: ${{ needs.parse-and-validate.outputs.dev_id }}
MODULE: ${{ needs.parse-and-validate.outputs.module }}
HOST: ${{ secrets.DEPLOY_HOST }}
USER: ${{ secrets.DEPLOY_USER }}
HOST: ${{ secrets.ZY_SERVER_HOST }}
USER: ${{ secrets.ZY_SERVER_USER }}
run: |
# 上传自检脚本
scp scripts/deploy-check.sh ${USER}@${HOST}:/tmp/deploy-check.sh
@ -123,8 +123,8 @@ jobs:
- name: "🔥 运行 smoke-test.sh"
id: smoke
env:
HOST: ${{ secrets.DEPLOY_HOST }}
USER: ${{ secrets.DEPLOY_USER }}
HOST: ${{ secrets.ZY_SERVER_HOST }}
USER: ${{ secrets.ZY_SERVER_USER }}
run: |
scp scripts/smoke-test.sh ${USER}@${HOST}:/tmp/smoke-test.sh
SMOKE=$(ssh ${USER}@${HOST} "bash /tmp/smoke-test.sh" 2>&1) || true
@ -189,8 +189,8 @@ jobs:
- name: "📧 发送部署结果邮件"
if: needs.parse-and-validate.outputs.email != ''
env:
SMTP_USER: ${{ secrets.SMTP_USER }}
SMTP_PASS: ${{ secrets.SMTP_PASS }}
SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
SMTP_PASS: ${{ secrets.ZY_SMTP_PASS }}
TO_EMAIL: ${{ needs.parse-and-validate.outputs.email }}
DEV_ID: ${{ needs.parse-and-validate.outputs.dev_id }}
MODULE: ${{ needs.parse-and-validate.outputs.module }}
@ -232,8 +232,8 @@ jobs:
- name: "📝 同步到 Notion 部署注册表"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
FINGERPRINT_DB_ID: ${{ secrets.ZY_NOTION_FINGERPRINT_DB }}
DEV_ID: ${{ needs.parse-and-validate.outputs.dev_id }}
MODULE: ${{ needs.parse-and-validate.outputs.module }}
RESULT: ${{ needs.deploy-to-sandbox.outputs.deploy_result }}

View File

@ -37,12 +37,12 @@ jobs:
- name: 🧠 唤醒铸渊核心大脑
id: wake
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: |
node core/brain-wake --task "服务器巡检" || {
echo "⚠️ 核心大脑唤醒失败,使用 dry-run 模式继续"
@ -64,24 +64,24 @@ jobs:
if [ -n "$NOTION_TOKEN" ]; then echo "✅ NOTION_TOKEN 可用"; else echo "⚠️ NOTION_TOKEN 缺失"; fi
if [ -n "$SMTP_USER" ]; then echo "✅ SMTP_USER 可用"; else echo "⚠️ SMTP_USER 缺失"; fi
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
SMTP_USER: ${{ secrets.SMTP_USER }}
DEPLOY_HOST: ${{ secrets.ZY_SERVER_HOST }}
DEPLOY_USER: ${{ secrets.ZY_SERVER_USER }}
DEPLOY_KEY: ${{ secrets.ZY_SERVER_KEY }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
- name: "🔑 配置 SSH"
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_rsa
echo "${{ secrets.ZY_SERVER_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: "🔍 执行服务器巡检"
id: patrol
env:
HOST: ${{ secrets.DEPLOY_HOST }}
USER: ${{ secrets.DEPLOY_USER }}
HOST: ${{ secrets.ZY_SERVER_HOST }}
USER: ${{ secrets.ZY_SERVER_USER }}
run: |
# 上传巡检脚本
scp scripts/server-patrol.sh ${USER}@${HOST}:/tmp/server-patrol.sh
@ -122,8 +122,8 @@ jobs:
- name: "📧 异常时通知妈妈"
if: steps.patrol.outputs.overall == 'has_issues'
env:
SMTP_USER: ${{ secrets.SMTP_USER }}
SMTP_PASS: ${{ secrets.SMTP_PASS }}
SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
SMTP_PASS: ${{ secrets.ZY_SMTP_PASS }}
run: |
python3 << 'PYEOF'
import smtplib, json, os
@ -167,8 +167,8 @@ jobs:
- name: "📝 同步巡检结果到Notion"
if: always()
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
NOTION_TICKET_DB_ID: ${{ secrets.ZY_NOTION_TICKET_DB }}
run: |
node scripts/sync-patrol-to-notion.js || echo "⚠️ Notion同步失败不阻断"
@ -207,8 +207,8 @@ jobs:
- name: "📡 同步回执到 Notion"
if: always()
env:
NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
RECEIPT_DB_ID: ${{ secrets.RECEIPT_DB_ID }}
NOTION_API_KEY: ${{ secrets.ZY_NOTION_TOKEN }}
RECEIPT_DB_ID: ${{ secrets.ZY_NOTION_RECEIPT_DB }}
run: |
node scripts/neural/write-receipt-to-notion.js \
--instruction-id "${{ github.event.inputs.instruction_id || 'AUTO' }}" \

View File

@ -45,14 +45,14 @@ jobs:
- name: 执行跨仓库同步
env:
CROSS_REPO_TOKEN: ${{ secrets.CROSS_REPO_TOKEN }}
CROSS_REPO_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
SYNC_TARGET: ${{ github.event.inputs.sync_target || 'all' }}
run: node scripts/cross-repo-sync.js
- name: 通知 persona-studio 仓库
if: env.CROSS_REPO_TOKEN != ''
env:
CROSS_REPO_TOKEN: ${{ secrets.CROSS_REPO_TOKEN }}
CROSS_REPO_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
run: |
curl -X POST \
-H "Accept: application/vnd.github+json" \

View File

@ -121,24 +121,24 @@ jobs:
- name: 🧠 Auto-detect and wake up persona
id: persona
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
SUBMIT_CONTENT: ${{ steps.parse.outputs.content }}
AUTHOR: ${{ steps.parse.outputs.author }}
MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }}
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 }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
CORE_BRAIN_PAGE_ID: ${{ secrets.ZY_NOTION_BRAIN_PAGE }}
PORTRAIT_DB_ID: ${{ secrets.ZY_NOTION_PORTRAIT_DB }}
FINGERPRINT_DB_ID: ${{ secrets.ZY_NOTION_FINGERPRINT_DB }}
run: node scripts/wake-persona.js
- name: 📋 创建标准化 Notion 工单Phase B1
id: ticket
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
NOTION_TICKET_DB_ID: ${{ secrets.ZY_NOTION_TICKET_DB }}
BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
PERSONA_RESULT: ${{ steps.persona.outputs.result }}
@ -164,8 +164,8 @@ jobs:
- name: 📧 Send email to developer
env:
SMTP_USER: ${{ secrets.SMTP_USER }}
SMTP_PASS: ${{ secrets.SMTP_PASS }}
SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
SMTP_PASS: ${{ secrets.ZY_SMTP_PASS }}
EMAIL_TO: ${{ steps.parse.outputs.email }}
BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
SUBMIT_TYPE: ${{ steps.parse.outputs.type }}

View File

@ -174,17 +174,17 @@ jobs:
- name: 🧠 Auto-detect and wake up persona
id: persona
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
SUBMIT_CONTENT: ${{ steps.parse.outputs.content }}
AUTHOR: ${{ steps.parse.outputs.author }}
MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }}
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 }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
CORE_BRAIN_PAGE_ID: ${{ secrets.ZY_NOTION_BRAIN_PAGE }}
PORTRAIT_DB_ID: ${{ secrets.ZY_NOTION_PORTRAIT_DB }}
FINGERPRINT_DB_ID: ${{ secrets.ZY_NOTION_FINGERPRINT_DB }}
run: node scripts/wake-persona.js
- name: 📋 步骤 4/8 · 唤醒核心大脑(成功)
@ -209,14 +209,14 @@ jobs:
STEP_DETAIL: 'API 调用失败,请检查 Secrets: LLM_API_KEY / LLM_BASE_URL 是否配置正确'
run: node scripts/pipeline-reporter.js
# ✅ 修复点:原来是 if: $ secrets.NOTION_API_KEY ,会报 Unrecognized named-value: 'secrets'
# ✅ 修复点:原来是 if: $ secrets.ZY_NOTION_TOKEN ,会报 Unrecognized named-value: 'secrets'
# secrets 不能在 if: 里直接用,必须改成 != '' 的形式
- name: 📋 创建标准化 Notion 工单Phase B1
id: ticket
if: ${{ secrets.NOTION_API_KEY != '' }}
if: ${{ secrets.ZY_NOTION_TOKEN != '' }}
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
NOTION_TICKET_DB_ID: ${{ secrets.ZY_NOTION_TICKET_DB }}
BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
PERSONA_RESULT: ${{ steps.persona.outputs.result }}
@ -305,8 +305,8 @@ jobs:
- name: 📧 Send email to developer
id: email
env:
SMTP_USER: ${{ secrets.SMTP_USER }}
SMTP_PASS: ${{ secrets.SMTP_PASS }}
SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
SMTP_PASS: ${{ secrets.ZY_SMTP_PASS }}
EMAIL_TO: ${{ steps.parse.outputs.email }}
BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
SUBMIT_TYPE: ${{ steps.parse.outputs.type }}

View File

@ -78,8 +78,8 @@ jobs:
- name: 📝 写入 Notion SYSLOG 收件箱
if: steps.parse.outputs.has_syslog == 'true'
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_DB_SYSLOG: ${{ secrets.NOTION_DB_SYSLOG }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
NOTION_DB_SYSLOG: ${{ secrets.ZY_NOTION_SYSLOG_DB }}
run: node scripts/write-notion-syslog.js "${{ steps.parse.outputs.syslog_file }}"
# Step 2: 处理 syslog-inbox 条目(归档到 syslog-processed/
@ -128,12 +128,12 @@ jobs:
- name: 🧠 唤醒人格体处理 SYSLOG
id: persona
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
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 }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
CORE_BRAIN_PAGE_ID: ${{ secrets.ZY_NOTION_BRAIN_PAGE }}
PORTRAIT_DB_ID: ${{ secrets.ZY_NOTION_PORTRAIT_DB }}
FINGERPRINT_DB_ID: ${{ secrets.ZY_NOTION_FINGERPRINT_DB }}
SUBMIT_TYPE: syslog
SYSLOG_FILE: ${{ needs.pipeline-a-syslog.outputs.syslog_file }}
AUTHOR: ${{ needs.pipeline-a-syslog.outputs.sender_name }}
@ -199,7 +199,7 @@ jobs:
- name: 📢 推送广播到飞书
env:
PUSH_URL: https://guanghulab.com/webhook/push-broadcast
PUSH_TOKEN: ${{ secrets.PUSH_BROADCAST_TOKEN }}
PUSH_TOKEN: ${{ secrets.ZY_PUSH_TOKEN }}
CHAT_ID: ${{ needs.pipeline-a-syslog.outputs.chat_id }}
SENDER_OPEN_ID: ${{ needs.pipeline-a-syslog.outputs.sender_open_id }}
BROADCAST_TITLE: ${{ needs.pipeline-b-persona.outputs.broadcast_title }}
@ -351,8 +351,8 @@ jobs:
- name: "📡 同步回执到 Notion"
if: always()
env:
NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
RECEIPT_DB_ID: ${{ secrets.RECEIPT_DB_ID }}
NOTION_API_KEY: ${{ secrets.ZY_NOTION_TOKEN }}
RECEIPT_DB_ID: ${{ secrets.ZY_NOTION_RECEIPT_DB }}
run: |
node scripts/neural/write-receipt-to-notion.js \
--instruction-id "${{ github.event.inputs.instruction_id || 'AUTO' }}" \

View File

@ -31,9 +31,9 @@ jobs:
- name: 🛰️ 执行语义落盘
env:
GDRIVE_CLIENT_ID: ${{ secrets.GDRIVE_CLIENT_ID }}
GDRIVE_CLIENT_SECRET: ${{ secrets.GDRIVE_CLIENT_SECRET }}
GDRIVE_REFRESH_TOKEN: ${{ secrets.GDRIVE_REFRESH_TOKEN }}
GDRIVE_CLIENT_ID: ${{ secrets.ZY_GDRIVE_CLIENT_ID }}
GDRIVE_CLIENT_SECRET: ${{ secrets.ZY_GDRIVE_SECRET }}
GDRIVE_REFRESH_TOKEN: ${{ secrets.ZY_GDRIVE_REFRESH_TOKEN }}
DRIVE_LANDING_FOLDER_ID: '1fqWdLPaZkUZYt4OT_h3fJQHnd-q5QN3G'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}

View File

@ -56,7 +56,7 @@ jobs:
- name: "🔭 扫描过去24小时 Workflow 运行记录"
id: scan
env:
GH_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
run: |
echo "[天眼 v3.0] Phase A 启动 — 夜间巡查扫描"
echo "═══════════════════════════════════════════"
@ -123,7 +123,7 @@ jobs:
- name: "🧠 Phase B — Gemini 报错分析"
id: analyze
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
ERROR_REPORT: ${{ needs.nightly-scan.outputs.error_report }}
run: |
echo "[铸渊核心大脑] Phase B 启动 — 报错智能分析"
@ -133,8 +133,8 @@ jobs:
- name: "⚒️ Phase C — 铸渊自动修复"
id: repair
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
GH_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GEMINI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
GH_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
run: |
echo "[铸渊核心大脑] Phase C 启动 — 自动修复"
@ -230,7 +230,7 @@ jobs:
- name: "🔄 Phase D 重试(如审核未通过)"
if: steps.review.outputs.pr_needed == 'false' && steps.repair.outputs.branch_name != ''
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: |
echo "[天眼 v3.0] 审核未通过 — 进入重试流程"
RETRY=0
@ -274,7 +274,7 @@ jobs:
- name: "📦 Phase E — 创建 Pull Request"
id: create_pr
env:
GH_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
BRANCH: ${{ needs.analyze-and-repair.outputs.repair_branch }}
SUMMARY: ${{ needs.analyze-and-repair.outputs.repair_summary }}
FIX_COUNT: ${{ needs.analyze-and-repair.outputs.fix_count }}
@ -314,7 +314,7 @@ jobs:
- name: "📊 Phase F — 更新仪表盘"
env:
GH_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
PR_URL: ${{ steps.create_pr.outputs.pr_url }}
FIX_COUNT: ${{ needs.analyze-and-repair.outputs.fix_count }}
run: |
@ -352,7 +352,7 @@ jobs:
- name: "✅ 更新仪表盘 — 今日无异常"
env:
GH_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
run: |
DATE=$(date +%Y-%m-%d)
TIME=$(date +%H:%M)

View File

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

View File

@ -27,10 +27,10 @@ jobs:
- name: 推送工单到Notion
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NOTION_TOKEN_BINGSUO: ${{ secrets.NOTION_TOKEN_BINGSUO }}
NOTION_TOKEN_ZHIZHI: ${{ secrets.NOTION_TOKEN_ZHIZHI }}
WORKORDER_DB_BINGSUO: ${{ secrets.WORKORDER_DB_BINGSUO }}
WORKORDER_DB_ZHIZHI: ${{ secrets.WORKORDER_DB_ZHIZHI }}
NOTION_TOKEN_BINGSUO: ${{ secrets.ZY_NOTION_TOKEN }}
NOTION_TOKEN_ZHIZHI: ${{ secrets.ZY_NOTION_TOKEN }}
WORKORDER_DB_BINGSUO: ${{ secrets.ZY_NOTION_WORKORDER_DB }}
WORKORDER_DB_ZHIZHI: ${{ secrets.ZY_NOTION_WORKORDER_DB }}
run: node scripts/push-inspection-report.js
- name: 提交巡检记录
run: |

View File

@ -30,12 +30,12 @@ jobs:
- name: 🧠 唤醒铸渊核心大脑
id: wake
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DASHSCOPE_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
run: |
node core/brain-wake --task "每日自检" || {
echo "⚠️ 核心大脑唤醒失败,使用 dry-run 模式继续"
@ -82,7 +82,7 @@ jobs:
- name: DC-01 Notion Usage Snapshot
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
run: node scripts/dc-notion-usage.js
- name: DC-02 Workflow Performance Snapshot
@ -165,8 +165,8 @@ jobs:
- name: "📡 同步回执到 Notion"
if: always()
env:
NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
RECEIPT_DB_ID: ${{ secrets.RECEIPT_DB_ID }}
NOTION_API_KEY: ${{ secrets.ZY_NOTION_TOKEN }}
RECEIPT_DB_ID: ${{ secrets.ZY_NOTION_RECEIPT_DB }}
run: |
node scripts/neural/write-receipt-to-notion.js \
--instruction-id "${{ github.event.inputs.instruction_id || 'AUTO' }}" \

View File

@ -85,11 +85,11 @@ jobs:
# ====== Step 3: 执行指令 ======
- name: "⚡ 执行铸渊指令"
env:
GHAPP_APP_ID: ${{ secrets.GHAPP_APP_ID }}
GHAPP_PRIVATE_KEY: ${{ secrets.GHAPP_PRIVATE_KEY }}
MAIN_REPO_TOKEN: ${{ secrets.MAIN_REPO_TOKEN }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
GHAPP_APP_ID: ${{ secrets.ZY_GHAPP_ID }}
GHAPP_PRIVATE_KEY: ${{ secrets.ZY_GHAPP_KEY }}
MAIN_REPO_TOKEN: ${{ secrets.ZY_GITHUB_PAT }}
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
node services/zhuyuan-bridge/scripts/execute-instruction.js
@ -160,8 +160,8 @@ jobs:
- name: "📡 同步回执到 Notion"
if: always()
env:
NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
RECEIPT_DB_ID: ${{ secrets.RECEIPT_DB_ID }}
NOTION_API_KEY: ${{ secrets.ZY_NOTION_TOKEN }}
RECEIPT_DB_ID: ${{ secrets.ZY_NOTION_RECEIPT_DB }}
run: |
node scripts/neural/write-receipt-to-notion.js \
--instruction-id "${{ github.event.inputs.instruction_id || 'AUTO' }}" \

View File

@ -211,8 +211,8 @@ jobs:
- name: "📡 同步回执到 Notion"
if: always()
env:
NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
RECEIPT_DB_ID: ${{ secrets.RECEIPT_DB_ID }}
NOTION_API_KEY: ${{ secrets.ZY_NOTION_TOKEN }}
RECEIPT_DB_ID: ${{ secrets.ZY_NOTION_RECEIPT_DB }}
run: |
node scripts/neural/write-receipt-to-notion.js \
--instruction-id "${{ github.event.inputs.instruction_id || 'AUTO' }}" \

View File

@ -104,7 +104,7 @@ jobs:
- name: 铸渊处理Issue
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
YUNWU_API_KEY: ${{ secrets.YUNWU_API_KEY }}
YUNWU_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}

View File

@ -55,8 +55,8 @@ jobs:
- name: "📡 Phase 1.6 · 拉取 Agent 集群公告板"
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
AGENT_BULLETIN_BOARD_PAGE_ID: ${{ secrets.AGENT_BULLETIN_BOARD_PAGE_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
AGENT_BULLETIN_BOARD_PAGE_ID: ${{ secrets.ZY_NOTION_BULLETIN_PAGE }}
run: |
echo "[BRIDGE-BULLETIN-READ] 🔄 拉取 Agent 集群公告板"
mkdir -p /tmp/skyeye
@ -65,12 +65,12 @@ jobs:
- name: "🦅 Phase 2 · 全局扫描"
id: scan
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
SMTP_USER: ${{ secrets.SMTP_USER }}
SMTP_PASS: ${{ secrets.SMTP_PASS }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
DEPLOY_HOST: ${{ secrets.ZY_SERVER_HOST }}
DEPLOY_USER: ${{ secrets.ZY_SERVER_USER }}
DEPLOY_KEY: ${{ secrets.ZY_SERVER_KEY }}
SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
SMTP_PASS: ${{ secrets.ZY_SMTP_PASS }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir -p /tmp/skyeye
@ -107,7 +107,7 @@ jobs:
- name: "🔧 Phase 4 · 修复Agent"
if: steps.diagnose.outputs.auto_fixable != '0'
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
node scripts/skyeye/repair-agent.js
@ -184,9 +184,9 @@ jobs:
- name: "📡 Phase 7 · 同步到 Notion"
if: always()
env:
NOTION_TOKEN: ${{ secrets.NOTION_API_KEY }}
NOTION_SYSLOG_DB_ID: ${{ secrets.NOTION_SYSLOG_DB_ID }}
SKYEYE_PERSONA_DB_ID: ${{ secrets.SKYEYE_PERSONA_DB_ID }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
NOTION_SYSLOG_DB_ID: ${{ secrets.ZY_NOTION_SYSLOG_DB }}
SKYEYE_PERSONA_DB_ID: ${{ secrets.ZY_NOTION_SKYEYE_DB }}
run: |
node scripts/skyeye/sync-to-notion.js || echo "⚠️ Notion同步失败不阻断"
# 人格体注册表全量同步双端同步Notion → 本地配置)
@ -202,8 +202,8 @@ jobs:
- name: "📧 通知妈妈(仅有严重问题时)"
if: steps.diagnose.outputs.needs_human != '0'
env:
SMTP_USER: ${{ secrets.SMTP_USER }}
SMTP_PASS: ${{ secrets.SMTP_PASS }}
SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
SMTP_PASS: ${{ secrets.ZY_SMTP_PASS }}
run: |
echo "📧 发现 ${{ steps.diagnose.outputs.needs_human }} 个需要妈妈处理的问题"
echo "工单已记录在天眼报告中 · data/skyeye-reports/"
@ -249,8 +249,8 @@ jobs:
- name: "📡 同步回执到 Notion"
if: always()
env:
NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
RECEIPT_DB_ID: ${{ secrets.RECEIPT_DB_ID }}
NOTION_API_KEY: ${{ secrets.ZY_NOTION_TOKEN }}
RECEIPT_DB_ID: ${{ secrets.ZY_NOTION_RECEIPT_DB }}
run: |
node scripts/neural/write-receipt-to-notion.js \
--instruction-id "${{ github.event.inputs.instruction_id || 'AUTO' }}" \

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
.env
.env.*
node_modules/
*.bak
*.log

856
brain/secrets-manifest.json Normal file
View File

@ -0,0 +1,856 @@
{
"_meta": {
"manifest_id": "ZY-SECRETS-MANIFEST-v1.0",
"created": "2026-03-29T10:43:00Z",
"created_by": "铸渊 · ICE-GL-ZY001",
"directive": "SY-CMD-KEY-012 · 密钥全量清理与统一替换",
"purpose": "铸渊仓库密钥主清单 — 冰朔配置密钥的唯一参考文档",
"naming_convention": "所有密钥统一使用 ZY_ 前缀 · 铸渊(Zhuyuan)自主命名体系",
"total_secrets": 37,
"required": 25,
"optional": 12,
"replaced_old_secrets": 59,
"reduction": "59 → 37 (37%减少 · 消除重复与冗余)"
},
"migration_mapping": {
"description": "旧密钥名称 → 新ZY_*名称 完整映射表",
"note": "冰朔在GitHub Settings清空所有旧密钥后按此清单配置新密钥。合并PR后自动生效。",
"mappings": {
"LLM_API_KEY": "ZY_LLM_API_KEY",
"ANTHROPIC_API_KEY": "ZY_LLM_API_KEY",
"OPENAI_API_KEY": "ZY_LLM_API_KEY",
"DASHSCOPE_API_KEY": "ZY_LLM_API_KEY",
"DEEPSEEK_API_KEY": "ZY_LLM_API_KEY",
"GEMINI_API_KEY": "ZY_LLM_API_KEY",
"YUNWU_API_KEY": "ZY_LLM_API_KEY",
"MODEL_API_KEY": "ZY_LLM_API_KEY",
"LLM_BASE_URL": "ZY_LLM_BASE_URL",
"DEPLOY_HOST": "ZY_SERVER_HOST",
"DEPLOY_USER": "ZY_SERVER_USER",
"DEPLOY_KEY": "ZY_SERVER_KEY",
"DEPLOY_PATH": "ZY_SERVER_PATH",
"NOTION_API_KEY": "ZY_NOTION_TOKEN",
"NOTION_TOKEN_BINGSUO": "ZY_NOTION_TOKEN",
"NOTION_TOKEN_ZHIZHI": "ZY_NOTION_TOKEN",
"NOTION_SYSLOG_DB_ID": "ZY_NOTION_SYSLOG_DB",
"NOTION_DB_SYSLOG": "ZY_NOTION_SYSLOG_DB",
"SYSLOG_DB_ID": "ZY_NOTION_SYSLOG_DB",
"NOTION_TICKET_DB_ID": "ZY_NOTION_TICKET_DB",
"NOTION_CHANGE_LOG_DB_ID": "ZY_NOTION_CHANGELOG_DB",
"CORE_BRAIN_PAGE_ID": "ZY_NOTION_BRAIN_PAGE",
"PORTRAIT_DB_ID": "ZY_NOTION_PORTRAIT_DB",
"FINGERPRINT_DB_ID": "ZY_NOTION_FINGERPRINT_DB",
"RECEIPT_DB_ID": "ZY_NOTION_RECEIPT_DB",
"SIGNAL_LOG_DB_ID": "ZY_NOTION_SIGNAL_DB",
"BRIDGE_QUEUE_DB_ID": "ZY_NOTION_BRIDGE_DB",
"WAKE_REQUEST_DB_ID": "ZY_NOTION_WAKE_DB",
"SKYEYE_PERSONA_DB_ID": "ZY_NOTION_SKYEYE_DB",
"AGENT_BULLETIN_BOARD_PAGE_ID": "ZY_NOTION_BULLETIN_PAGE",
"WORKORDER_DB_BINGSUO": "ZY_NOTION_WORKORDER_DB",
"WORKORDER_DB_ZHIZHI": "ZY_NOTION_WORKORDER_DB",
"SMTP_USER": "ZY_SMTP_USER",
"SMTP_PASS": "ZY_SMTP_PASS",
"MAIL_USERNAME": "ZY_SMTP_USER",
"MAIL_PASSWORD": "ZY_SMTP_PASS",
"EMAIL_ADDRESS": "ZY_SMTP_USER",
"EMAIL_APP_PASSWORD": "ZY_SMTP_PASS",
"HUMAN_EMAIL": "ZY_SMTP_USER",
"MAIN_REPO_TOKEN": "ZY_GITHUB_PAT",
"CROSS_REPO_TOKEN": "ZY_GITHUB_PAT",
"DEPLOY_GITHUB_TOKEN": "ZY_GITHUB_PAT",
"GDRIVE_CLIENT_ID": "ZY_GDRIVE_CLIENT_ID",
"GDRIVE_CLIENT_SECRET": "ZY_GDRIVE_SECRET",
"GDRIVE_REFRESH_TOKEN": "ZY_GDRIVE_REFRESH_TOKEN",
"GDRIVE_REFRESH_TOKEN_DEV001": "ZY_GDRIVE_REFRESH_TOKEN",
"GDRIVE_REFRESH_TOKEN_DEV002": "ZY_GDRIVE_REFRESH_TOKEN",
"FEISHU_APP_ID": "ZY_FEISHU_APP_ID",
"FEISHU_APP_SECRET": "ZY_FEISHU_APP_SECRET",
"FEISHU_BROADCAST_CHAT_ID": "ZY_FEISHU_CHAT_ID",
"DINGTALK_TOKEN": "ZY_DINGTALK_TOKEN",
"GHAPP_APP_ID": "ZY_GHAPP_ID",
"GHAPP_PRIVATE_KEY": "ZY_GHAPP_KEY",
"PUSH_BROADCAST_TOKEN": "ZY_PUSH_TOKEN",
"OSS_ACCESS_KEY": "ZY_OSS_KEY",
"OSS_SECRET_KEY": "ZY_OSS_SECRET"
}
},
"secrets": {
"required": [
{
"id": 1,
"name": "ZY_LLM_API_KEY",
"category": "LLM · AI模型",
"description": "三方LLM API统一密钥支持多模型动态路由",
"type": "api_key",
"example_format": "sk-xxxxxxxxxxxxxxxx",
"replaces": ["LLM_API_KEY", "ANTHROPIC_API_KEY", "OPENAI_API_KEY", "DASHSCOPE_API_KEY", "DEEPSEEK_API_KEY", "GEMINI_API_KEY", "YUNWU_API_KEY", "MODEL_API_KEY"],
"used_by_workflows": [
"llm-auto-tasks.yml",
"daily-maintenance.yml",
"server-patrol.yml",
"notion-wake-listener.yml",
"zhuyuan-daily-selfcheck.yml",
"psp-daily-inspection.yml",
"bingshuo-neural-system.yml",
"syslog-issue-pipeline.yml",
"syslog-auto-pipeline.yml",
"syslog-pipeline.yml",
"bridge-heartbeat.yml",
"bridge-syslog-intake.yml",
"bridge-broadcast-pdf.yml",
"multi-persona-awakening.yml",
"persona-thinking-window.yml",
"deploy-to-server.yml",
"zhuyuan-exec-engine.yml",
"zhuyuan-issue-reply.yml",
"tianyan-nightly-scan.yml"
],
"note": "冰朔的三方API密钥。铸渊会根据任务类型自动选择最优模型如DeepSeek用于低成本任务Claude用于推理任务"
},
{
"id": 2,
"name": "ZY_LLM_BASE_URL",
"category": "LLM · AI模型",
"description": "三方LLM API端点URL",
"type": "url",
"example_format": "https://api.example.com/v1",
"replaces": ["LLM_BASE_URL"],
"used_by_workflows": [
"llm-auto-tasks.yml",
"daily-maintenance.yml",
"server-patrol.yml",
"notion-wake-listener.yml",
"zhuyuan-daily-selfcheck.yml",
"psp-daily-inspection.yml",
"bingshuo-neural-system.yml",
"syslog-issue-pipeline.yml",
"syslog-auto-pipeline.yml",
"bridge-heartbeat.yml",
"bridge-syslog-intake.yml",
"bridge-broadcast-pdf.yml",
"multi-persona-awakening.yml",
"persona-thinking-window.yml",
"zhuyuan-exec-engine.yml"
],
"note": "三方API的基础URL地址"
},
{
"id": 3,
"name": "ZY_SERVER_HOST",
"category": "服务器 · 部署",
"description": "铸渊主权服务器IP/主机名(腾讯云 ZY-SVR-001",
"type": "hostname",
"example_format": "150.109.76.244",
"replaces": ["DEPLOY_HOST", "ZY_SERVER_HOST"],
"used_by_workflows": [
"deploy-to-server.yml",
"deploy-to-zhuyuan-server.yml",
"server-patrol.yml",
"zhuyuan-skyeye.yml",
"sandbox-deploy.yml",
"deploy-backend.yml",
"pm2-server-diagnose.yml"
],
"note": "腾讯云轻量应用服务器·香港二区·150.109.76.244"
},
{
"id": 4,
"name": "ZY_SERVER_USER",
"category": "服务器 · 部署",
"description": "服务器SSH登录用户名",
"type": "username",
"example_format": "root 或 zhuyuan",
"replaces": ["DEPLOY_USER", "ZY_SERVER_USER"],
"used_by_workflows": [
"deploy-to-server.yml",
"deploy-to-zhuyuan-server.yml",
"server-patrol.yml",
"zhuyuan-skyeye.yml",
"sandbox-deploy.yml",
"deploy-backend.yml",
"pm2-server-diagnose.yml"
],
"note": "SSH登录用户名"
},
{
"id": 5,
"name": "ZY_SERVER_KEY",
"category": "服务器 · 部署",
"description": "服务器SSH私钥完整PEM格式",
"type": "ssh_private_key",
"example_format": "-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----",
"replaces": ["DEPLOY_KEY", "ZY_SERVER_KEY"],
"used_by_workflows": [
"deploy-to-server.yml",
"deploy-to-zhuyuan-server.yml",
"server-patrol.yml",
"zhuyuan-skyeye.yml",
"sandbox-deploy.yml",
"deploy-backend.yml",
"pm2-server-diagnose.yml"
],
"note": "⚠️ 关键密钥 · SSH私钥·请确保是腾讯云服务器的密钥"
},
{
"id": 6,
"name": "ZY_SERVER_PATH",
"category": "服务器 · 部署",
"description": "服务器部署基础路径",
"type": "path",
"example_format": "/opt/zhuyuan",
"replaces": ["DEPLOY_PATH", "ZY_SERVER_PATH"],
"used_by_workflows": [
"deploy-to-server.yml",
"deploy-to-zhuyuan-server.yml"
],
"note": "服务器上的部署根目录"
},
{
"id": 7,
"name": "ZY_DOMAIN_MAIN",
"category": "服务器 · 域名",
"description": "主站域名",
"type": "domain",
"example_format": "guanghulab.com",
"replaces": [],
"used_by_workflows": [
"deploy-to-zhuyuan-server.yml",
"deploy-to-server.yml"
],
"note": "正式发布站点的域名"
},
{
"id": 8,
"name": "ZY_DOMAIN_PREVIEW",
"category": "服务器 · 域名",
"description": "预览站域名",
"type": "domain",
"example_format": "preview.guanghulab.com",
"replaces": [],
"used_by_workflows": [
"deploy-to-zhuyuan-server.yml"
],
"note": "预览/测试站点的域名"
},
{
"id": 9,
"name": "ZY_NOTION_TOKEN",
"category": "Notion · 数据库",
"description": "Notion API集成令牌统一所有Notion访问",
"type": "api_token",
"example_format": "ntn_xxxxxxxxxxxxxxxx 或 secret_xxxxxxxxxxxxxxxx",
"replaces": ["NOTION_API_KEY", "NOTION_TOKEN_BINGSUO", "NOTION_TOKEN_ZHIZHI"],
"used_by_workflows": [
"notion-poll.yml",
"notion-wake-listener.yml",
"meta-watchdog.yml",
"zhuyuan-commander.yml",
"zhuyuan-skyeye.yml",
"zhuyuan-gate-guard.yml",
"zhuyuan-exec-engine.yml",
"zhuyuan-daily-selfcheck.yml",
"zhuyuan-daily-inspection.yml",
"server-patrol.yml",
"daily-maintenance.yml",
"bridge-heartbeat.yml",
"bridge-changes-to-notion.yml",
"bridge-syslog-to-notion.yml",
"bridge-syslog-intake.yml",
"bridge-broadcast-pdf.yml",
"syslog-issue-pipeline.yml",
"syslog-auto-pipeline.yml",
"syslog-pipeline.yml",
"pm2-server-diagnose.yml",
"sandbox-deploy.yml",
"deploy-to-server.yml"
],
"note": "⚠️ 关键密钥 · 访问所有Notion数据库的统一令牌"
},
{
"id": 10,
"name": "ZY_NOTION_SYSLOG_DB",
"category": "Notion · 数据库ID",
"description": "SYSLOG系统日志数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["NOTION_SYSLOG_DB_ID", "NOTION_DB_SYSLOG", "SYSLOG_DB_ID"],
"used_by_workflows": [
"bridge-syslog-to-notion.yml",
"bridge-syslog-intake.yml",
"zhuyuan-skyeye.yml",
"syslog-pipeline.yml",
"daily-maintenance.yml"
],
"note": "系统日志数据库·铸渊运行日志的存储位置"
},
{
"id": 11,
"name": "ZY_NOTION_TICKET_DB",
"category": "Notion · 数据库ID",
"description": "工单/Ticket数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["NOTION_TICKET_DB_ID"],
"used_by_workflows": [
"syslog-issue-pipeline.yml",
"syslog-auto-pipeline.yml",
"server-patrol.yml",
"pm2-server-diagnose.yml"
],
"note": "工单系统数据库·用于SYSLOG→Notion工单创建"
},
{
"id": 12,
"name": "ZY_NOTION_CHANGELOG_DB",
"category": "Notion · 数据库ID",
"description": "变更日志数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["NOTION_CHANGE_LOG_DB_ID"],
"used_by_workflows": [
"bridge-changes-to-notion.yml",
"deploy-to-server.yml"
],
"note": "代码变更→Notion同步的目标数据库"
},
{
"id": 13,
"name": "ZY_NOTION_BRAIN_PAGE",
"category": "Notion · 页面ID",
"description": "核心大脑页面IDNotion认知层根节点",
"type": "notion_page_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["CORE_BRAIN_PAGE_ID"],
"used_by_workflows": [
"syslog-issue-pipeline.yml",
"syslog-auto-pipeline.yml",
"syslog-pipeline.yml"
],
"note": "Notion大脑首页·认知层的根节点"
},
{
"id": 14,
"name": "ZY_NOTION_PORTRAIT_DB",
"category": "Notion · 数据库ID",
"description": "用户画像数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["PORTRAIT_DB_ID"],
"used_by_workflows": [
"syslog-issue-pipeline.yml",
"syslog-auto-pipeline.yml",
"syslog-pipeline.yml"
],
"note": "人格体画像数据库"
},
{
"id": 15,
"name": "ZY_NOTION_FINGERPRINT_DB",
"category": "Notion · 数据库ID",
"description": "系统指纹数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["FINGERPRINT_DB_ID"],
"used_by_workflows": [
"syslog-issue-pipeline.yml",
"syslog-auto-pipeline.yml",
"syslog-pipeline.yml",
"sandbox-deploy.yml"
],
"note": "系统指纹记录数据库"
},
{
"id": 16,
"name": "ZY_NOTION_RECEIPT_DB",
"category": "Notion · 数据库ID",
"description": "回执数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["RECEIPT_DB_ID"],
"used_by_workflows": [
"zhuyuan-gate-guard.yml",
"zhuyuan-skyeye.yml",
"zhuyuan-exec-engine.yml",
"zhuyuan-daily-selfcheck.yml",
"server-patrol.yml",
"deploy-to-server.yml",
"syslog-pipeline.yml"
],
"note": "工作流执行回执·铸渊向Notion汇报执行结果"
},
{
"id": 17,
"name": "ZY_NOTION_SIGNAL_DB",
"category": "Notion · 数据库ID",
"description": "信号日志数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["SIGNAL_LOG_DB_ID"],
"used_by_workflows": [
"notion-wake-listener.yml"
],
"note": "信号收发日志数据库"
},
{
"id": 18,
"name": "ZY_NOTION_BRIDGE_DB",
"category": "Notion · 数据库ID",
"description": "桥接队列数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["BRIDGE_QUEUE_DB_ID"],
"used_by_workflows": [
"bridge-heartbeat.yml",
"bridge-syslog-intake.yml",
"bridge-broadcast-pdf.yml"
],
"note": "Notion↔GitHub桥接通信队列"
},
{
"id": 19,
"name": "ZY_NOTION_WAKE_DB",
"category": "Notion · 数据库ID",
"description": "唤醒请求数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["WAKE_REQUEST_DB_ID"],
"used_by_workflows": [
"notion-wake-listener.yml"
],
"note": "Notion侧→GitHub侧的唤醒请求存储"
},
{
"id": 20,
"name": "ZY_NOTION_SKYEYE_DB",
"category": "Notion · 数据库ID",
"description": "天眼人格数据库ID",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["SKYEYE_PERSONA_DB_ID"],
"used_by_workflows": [
"zhuyuan-skyeye.yml"
],
"note": "天眼观测系统的人格体数据库"
},
{
"id": 21,
"name": "ZY_NOTION_BULLETIN_PAGE",
"category": "Notion · 页面ID",
"description": "Agent公告板页面ID",
"type": "notion_page_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["AGENT_BULLETIN_BOARD_PAGE_ID"],
"used_by_workflows": [
"zhuyuan-commander.yml",
"zhuyuan-skyeye.yml"
],
"note": "铸渊Agent间通信公告板"
},
{
"id": 22,
"name": "ZY_NOTION_WORKORDER_DB",
"category": "Notion · 数据库ID",
"description": "工单数据库ID统一所有工单来源",
"type": "notion_database_id",
"example_format": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"replaces": ["WORKORDER_DB_BINGSUO", "WORKORDER_DB_ZHIZHI"],
"used_by_workflows": [
"zhuyuan-daily-inspection.yml"
],
"note": "统一工单数据库·替代之前按人格体分开的工单库"
},
{
"id": 23,
"name": "ZY_SMTP_USER",
"category": "邮件 · SMTP",
"description": "SMTP邮箱账号/发件人地址",
"type": "email",
"example_format": "zhuyuan@guanghulab.com",
"replaces": ["SMTP_USER", "MAIL_USERNAME", "EMAIL_ADDRESS", "HUMAN_EMAIL"],
"used_by_workflows": [
"syslog-issue-pipeline.yml",
"syslog-auto-pipeline.yml",
"server-patrol.yml",
"zhuyuan-skyeye.yml",
"sandbox-deploy.yml",
"bridge-broadcast-pdf.yml",
"merge-watchdog.yml",
"psp-daily-inspection.yml"
],
"note": "邮件发送的SMTP登录用户名/发件人地址"
},
{
"id": 24,
"name": "ZY_SMTP_PASS",
"category": "邮件 · SMTP",
"description": "SMTP邮箱密码/应用专用密码",
"type": "password",
"example_format": "应用专用密码(非邮箱登录密码)",
"replaces": ["SMTP_PASS", "MAIL_PASSWORD", "EMAIL_APP_PASSWORD"],
"used_by_workflows": [
"syslog-issue-pipeline.yml",
"syslog-auto-pipeline.yml",
"server-patrol.yml",
"zhuyuan-skyeye.yml",
"sandbox-deploy.yml",
"bridge-broadcast-pdf.yml",
"merge-watchdog.yml",
"psp-daily-inspection.yml"
],
"note": "⚠️ 关键密钥 · SMTP认证密码"
},
{
"id": 25,
"name": "ZY_GITHUB_PAT",
"category": "GitHub · 访问令牌",
"description": "GitHub个人访问令牌跨仓库操作用",
"type": "github_pat",
"example_format": "ghp_xxxxxxxxxxxxxxxx",
"replaces": ["MAIN_REPO_TOKEN", "CROSS_REPO_TOKEN", "DEPLOY_GITHUB_TOKEN"],
"used_by_workflows": [
"federation-bridge.yml",
"sync-persona-studio.yml",
"zhuyuan-exec-engine.yml",
"merge-watchdog.yml",
"tianyan-nightly-scan.yml",
"auto-deploy-drive-bridge.yml"
],
"note": "需要repo + workflow权限的GitHub PAT · 用于跨仓库和高级操作"
}
],
"optional": [
{
"id": 26,
"name": "ZY_GDRIVE_CLIENT_ID",
"category": "Google Drive · OAuth",
"description": "Google Drive OAuth客户端ID",
"type": "oauth_client_id",
"replaces": ["GDRIVE_CLIENT_ID"],
"used_by_workflows": ["renew-gdrive-tokens.yml", "auto-deploy-drive-bridge.yml", "tcs-semantic-landing.yml"],
"note": "如果不使用Google Drive功能可以不配置",
"needed": "仅在使用Google Drive桥接时需要"
},
{
"id": 27,
"name": "ZY_GDRIVE_SECRET",
"category": "Google Drive · OAuth",
"description": "Google Drive OAuth客户端密钥",
"type": "oauth_client_secret",
"replaces": ["GDRIVE_CLIENT_SECRET"],
"used_by_workflows": ["renew-gdrive-tokens.yml", "auto-deploy-drive-bridge.yml", "tcs-semantic-landing.yml"],
"note": "如果不使用Google Drive功能可以不配置",
"needed": "仅在使用Google Drive桥接时需要"
},
{
"id": 28,
"name": "ZY_GDRIVE_REFRESH_TOKEN",
"category": "Google Drive · OAuth",
"description": "Google Drive OAuth刷新令牌",
"type": "oauth_refresh_token",
"replaces": ["GDRIVE_REFRESH_TOKEN", "GDRIVE_REFRESH_TOKEN_DEV001", "GDRIVE_REFRESH_TOKEN_DEV002"],
"used_by_workflows": ["renew-gdrive-tokens.yml", "auto-deploy-drive-bridge.yml", "tcs-semantic-landing.yml"],
"note": "统一为一个刷新令牌·替代之前3个(主+DEV001+DEV002)",
"needed": "仅在使用Google Drive桥接时需要"
},
{
"id": 29,
"name": "ZY_FEISHU_APP_ID",
"category": "飞书 · 集成",
"description": "飞书应用ID",
"type": "app_id",
"replaces": ["FEISHU_APP_ID"],
"used_by_workflows": ["bridge-broadcast-pdf.yml"],
"note": "飞书广播分发需要",
"needed": "仅在使用飞书通知时需要"
},
{
"id": 30,
"name": "ZY_FEISHU_APP_SECRET",
"category": "飞书 · 集成",
"description": "飞书应用密钥",
"type": "app_secret",
"replaces": ["FEISHU_APP_SECRET"],
"used_by_workflows": ["bridge-broadcast-pdf.yml"],
"note": "飞书广播分发需要",
"needed": "仅在使用飞书通知时需要"
},
{
"id": 31,
"name": "ZY_FEISHU_CHAT_ID",
"category": "飞书 · 集成",
"description": "飞书广播群ID",
"type": "chat_id",
"replaces": ["FEISHU_BROADCAST_CHAT_ID"],
"used_by_workflows": ["bridge-broadcast-pdf.yml"],
"note": "飞书广播目标群聊",
"needed": "仅在使用飞书通知时需要"
},
{
"id": 32,
"name": "ZY_DINGTALK_TOKEN",
"category": "钉钉 · 集成",
"description": "钉钉机器人令牌",
"type": "bot_token",
"replaces": ["DINGTALK_TOKEN"],
"used_by_workflows": ["bridge-broadcast-pdf.yml"],
"note": "钉钉消息推送需要",
"needed": "仅在使用钉钉通知时需要"
},
{
"id": 33,
"name": "ZY_GHAPP_ID",
"category": "GitHub App · 集成",
"description": "GitHub App ID",
"type": "app_id",
"replaces": ["GHAPP_APP_ID"],
"used_by_workflows": ["zhuyuan-exec-engine.yml"],
"note": "铸渊远程执行引擎使用的GitHub App",
"needed": "仅在使用远程执行引擎时需要"
},
{
"id": 34,
"name": "ZY_GHAPP_KEY",
"category": "GitHub App · 集成",
"description": "GitHub App私钥PEM格式",
"type": "private_key",
"replaces": ["GHAPP_PRIVATE_KEY"],
"used_by_workflows": ["zhuyuan-exec-engine.yml"],
"note": "⚠️ 关键密钥 · GitHub App的PEM私钥",
"needed": "仅在使用远程执行引擎时需要"
},
{
"id": 35,
"name": "ZY_PUSH_TOKEN",
"category": "推送 · 广播",
"description": "推送广播令牌",
"type": "token",
"replaces": ["PUSH_BROADCAST_TOKEN"],
"used_by_workflows": ["syslog-pipeline.yml"],
"note": "SYSLOG广播推送令牌",
"needed": "仅在使用推送广播时需要"
},
{
"id": 36,
"name": "ZY_OSS_KEY",
"category": "对象存储 · 已弃用评估中",
"description": "对象存储Access Key原阿里云OSS",
"type": "access_key",
"replaces": ["OSS_ACCESS_KEY"],
"used_by_workflows": ["bridge-broadcast-pdf.yml"],
"note": "⚠️ 阿里云已弃用·评估是否迁移到腾讯云COS或其他存储",
"needed": "仅bridge-broadcast-pdf使用·可能需要替换为其他存储方案"
},
{
"id": 37,
"name": "ZY_OSS_SECRET",
"category": "对象存储 · 已弃用评估中",
"description": "对象存储Secret Key原阿里云OSS",
"type": "secret_key",
"replaces": ["OSS_SECRET_KEY"],
"used_by_workflows": ["bridge-broadcast-pdf.yml"],
"note": "⚠️ 阿里云已弃用·评估是否迁移到腾讯云COS或其他存储",
"needed": "仅bridge-broadcast-pdf使用·可能需要替换为其他存储方案"
}
],
"auto_provided": [
{
"name": "GITHUB_TOKEN",
"category": "GitHub · 自动",
"description": "GitHub Actions自动提供的令牌无需配置",
"note": "每次工作流运行自动生成·权限在workflow文件的permissions中定义"
}
],
"deprecated": [
{
"name": "DEPLOY_HOST",
"replaced_by": "ZY_SERVER_HOST",
"reason": "阿里云→腾讯云迁移·统一命名"
},
{
"name": "DEPLOY_USER",
"replaced_by": "ZY_SERVER_USER",
"reason": "统一命名"
},
{
"name": "DEPLOY_KEY",
"replaced_by": "ZY_SERVER_KEY",
"reason": "统一命名"
},
{
"name": "DEPLOY_PATH",
"replaced_by": "ZY_SERVER_PATH",
"reason": "统一命名"
},
{
"name": "ANTHROPIC_API_KEY",
"replaced_by": "ZY_LLM_API_KEY",
"reason": "三方API统一密钥·不再分别配置各厂商密钥"
},
{
"name": "OPENAI_API_KEY",
"replaced_by": "ZY_LLM_API_KEY",
"reason": "三方API统一密钥"
},
{
"name": "DASHSCOPE_API_KEY",
"replaced_by": "ZY_LLM_API_KEY",
"reason": "三方API统一密钥"
},
{
"name": "DEEPSEEK_API_KEY",
"replaced_by": "ZY_LLM_API_KEY",
"reason": "三方API统一密钥"
},
{
"name": "GEMINI_API_KEY",
"replaced_by": "ZY_LLM_API_KEY",
"reason": "三方API统一密钥"
},
{
"name": "YUNWU_API_KEY",
"replaced_by": "ZY_LLM_API_KEY",
"reason": "三方API统一密钥"
},
{
"name": "MODEL_API_KEY",
"replaced_by": "ZY_LLM_API_KEY",
"reason": "三方API统一密钥"
},
{
"name": "NOTION_API_KEY",
"replaced_by": "ZY_NOTION_TOKEN",
"reason": "统一命名"
},
{
"name": "NOTION_TOKEN_BINGSUO",
"replaced_by": "ZY_NOTION_TOKEN",
"reason": "按人格体分密钥已弃用·统一为一个令牌"
},
{
"name": "NOTION_TOKEN_ZHIZHI",
"replaced_by": "ZY_NOTION_TOKEN",
"reason": "按人格体分密钥已弃用·统一为一个令牌"
},
{
"name": "SMTP_USER",
"replaced_by": "ZY_SMTP_USER",
"reason": "统一命名"
},
{
"name": "SMTP_PASS",
"replaced_by": "ZY_SMTP_PASS",
"reason": "统一命名"
},
{
"name": "MAIL_USERNAME",
"replaced_by": "ZY_SMTP_USER",
"reason": "重复密钥·合并"
},
{
"name": "MAIL_PASSWORD",
"replaced_by": "ZY_SMTP_PASS",
"reason": "重复密钥·合并"
},
{
"name": "EMAIL_ADDRESS",
"replaced_by": "ZY_SMTP_USER",
"reason": "重复密钥·合并"
},
{
"name": "EMAIL_APP_PASSWORD",
"replaced_by": "ZY_SMTP_PASS",
"reason": "重复密钥·合并"
},
{
"name": "HUMAN_EMAIL",
"replaced_by": "ZY_SMTP_USER",
"reason": "重复密钥·合并"
},
{
"name": "MAIN_REPO_TOKEN",
"replaced_by": "ZY_GITHUB_PAT",
"reason": "统一GitHub PAT"
},
{
"name": "CROSS_REPO_TOKEN",
"replaced_by": "ZY_GITHUB_PAT",
"reason": "统一GitHub PAT"
},
{
"name": "DEPLOY_GITHUB_TOKEN",
"replaced_by": "ZY_GITHUB_PAT",
"reason": "统一GitHub PAT"
},
{
"name": "GDRIVE_REFRESH_TOKEN_DEV001",
"replaced_by": "ZY_GDRIVE_REFRESH_TOKEN",
"reason": "统一为一个刷新令牌"
},
{
"name": "GDRIVE_REFRESH_TOKEN_DEV002",
"replaced_by": "ZY_GDRIVE_REFRESH_TOKEN",
"reason": "统一为一个刷新令牌"
},
{
"name": "WORKORDER_DB_BINGSUO",
"replaced_by": "ZY_NOTION_WORKORDER_DB",
"reason": "按人格体分数据库已弃用·统一为一个工单库"
},
{
"name": "WORKORDER_DB_ZHIZHI",
"replaced_by": "ZY_NOTION_WORKORDER_DB",
"reason": "按人格体分数据库已弃用·统一为一个工单库"
},
{
"name": "NOTION_DB_SYSLOG",
"replaced_by": "ZY_NOTION_SYSLOG_DB",
"reason": "重复命名·统一"
}
]
},
"security_alerts": [
{
"severity": "CRITICAL",
"issue": ".env文件包含硬编码凭证DingTalk+KIMI API Key",
"action": "已从git跟踪中移除·冰朔需立即轮换这些密钥",
"files": [".env", ".env.rtf"]
}
],
"workflow_status": {
"core_alive": {
"description": "6个核心存活工作流铸渊身体器官",
"workflows": [
{"file": "notion-wake-listener.yml", "organ": "ZY-WF-听潮", "role": "耳朵·信号接收", "status": "active"},
{"file": "deploy-to-server.yml", "organ": "ZY-WF-锻心", "role": "心脏·部署引擎", "status": "active"},
{"file": "bingshuo-neural-system.yml", "organ": "ZY-WF-织脉", "role": "神经网络·大脑同步", "status": "active"},
{"file": "deploy-pages.yml", "organ": "ZY-WF-映阁", "role": "面容·前端展示", "status": "active"},
{"file": "meta-watchdog.yml", "organ": "ZY-WF-守夜", "role": "免疫系统·健康监控", "status": "active"},
{"file": "preview-deploy.yml", "organ": "ZY-WF-试镜", "role": "试衣间·预览部署", "status": "active"}
]
},
"total_active": 48,
"no_secrets_needed": [
"deploy-pages.yml",
"preview-deploy.yml",
"bridge-session-summary.yml",
"buffer-collect.yml",
"buffer-flush.yml",
"staging-preview.yml",
"process-notion-orders.yml",
"tianyan-daily-patrol.yml",
"zhuyuan-brain-sync.yml",
"zhuyuan-pr-review.yml",
"brain-sync.yml",
"agent-checkin.yml",
"copilot-dev-bridge.yml",
"feishu-syslog-bridge.yml"
]
}
}

View File

@ -27,57 +27,57 @@ const path = require('path');
const ROOT = path.resolve(__dirname, '..');
// ── 模型后端配置(与 core/brain-wake 和 connectors/model-router 保持一致)
// ── 模型后端配置
// SY-CMD-KEY-012: 统一使用 ZY_LLM_API_KEY + ZY_LLM_BASE_URL
// 三方API密钥支持多模型动态路由铸渊根据任务类型自动选择最优模型
const MODEL_BACKENDS = [
{
name: 'anthropic',
envKey: 'ANTHROPIC_API_KEY',
baseUrl: 'https://api.anthropic.com',
format: 'anthropic',
models: ['claude-sonnet-4', 'claude-3-5-sonnet-20241022', 'claude-3-haiku'],
strengths: ['reasoning', 'code-review', 'architecture', 'long-context'],
costTier: 'high',
description: 'Anthropic Claude 系列'
},
{
name: 'openai',
envKey: 'OPENAI_API_KEY',
baseUrl: 'https://api.openai.com/v1',
format: 'openai',
models: ['gpt-4o', 'gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo'],
strengths: ['general', 'code-generation', 'structured-output'],
costTier: 'high',
description: 'OpenAI GPT 系列'
},
{
name: 'dashscope',
envKey: 'DASHSCOPE_API_KEY',
baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
format: 'openai',
models: ['qwen-max', 'qwen-plus', 'qwen-turbo'],
strengths: ['chinese', 'general', 'cost-effective'],
costTier: 'medium',
description: '通义千问系列'
},
{
name: 'deepseek',
envKey: 'DEEPSEEK_API_KEY',
baseUrl: 'https://api.deepseek.com/v1',
model: 'deepseek-chat',
format: 'openai',
models: ['deepseek-chat', 'deepseek-reasoner'],
strengths: ['reasoning', 'code', 'cost-effective'],
costTier: 'low',
description: 'DeepSeek 系列'
description: 'DeepSeek 系列 · 高性价比推理'
},
{
name: 'custom',
envKey: 'LLM_API_KEY',
baseUrlEnv: 'LLM_BASE_URL',
name: 'deepseek-reasoner',
model: 'deepseek-reasoner',
format: 'openai',
models: [],
strengths: ['general'],
costTier: 'variable',
description: '自定义 LLM 平台'
strengths: ['reasoning', 'architecture', 'long-context'],
costTier: 'medium',
description: 'DeepSeek Reasoner · 深度推理'
},
{
name: 'claude-sonnet',
model: 'claude-sonnet-4-20250514',
format: 'openai',
strengths: ['reasoning', 'code-review', 'architecture', 'long-context'],
costTier: 'high',
description: 'Claude Sonnet · 强推理代码审查'
},
{
name: 'gpt-4o',
model: 'gpt-4o',
format: 'openai',
strengths: ['general', 'code-generation', 'structured-output'],
costTier: 'high',
description: 'GPT-4o · 通用能力'
},
{
name: 'qwen-plus',
model: 'qwen-plus',
format: 'openai',
strengths: ['chinese', 'general', 'cost-effective'],
costTier: 'medium',
description: '通义千问 Plus · 中文优化'
},
{
name: 'qwen-turbo',
model: 'qwen-turbo',
format: 'openai',
strengths: ['chinese', 'general', 'cost-effective'],
costTier: 'low',
description: '通义千问 Turbo · 快速低成本'
}
];
@ -153,22 +153,22 @@ function httpRequest(url, options, body) {
}
// ── 检测可用模型后端 ────────────────────────────
// SY-CMD-KEY-012: 统一使用 ZY_LLM_API_KEY + ZY_LLM_BASE_URL
// 兼容旧环境变量名LLM_API_KEY/LLM_BASE_URL用于脚本过渡
function detectAvailableBackends() {
const available = [];
const apiKey = process.env.ZY_LLM_API_KEY || process.env.LLM_API_KEY || '';
const baseUrl = (process.env.ZY_LLM_BASE_URL || process.env.LLM_BASE_URL || '').replace(/\/+$/, '');
for (const backend of MODEL_BACKENDS) {
const apiKey = process.env[backend.envKey] || '';
if (!apiKey) continue;
const baseUrl = backend.baseUrlEnv
? (process.env[backend.baseUrlEnv] || '').replace(/\/+$/, '')
: backend.baseUrl;
if (!baseUrl) continue;
available.push({ ...backend, apiKey, baseUrl });
if (!apiKey || !baseUrl) {
return [];
}
return available;
// 所有模型后端共享同一个API密钥和端点
return MODEL_BACKENDS.map(backend => ({
...backend,
apiKey,
baseUrl
}));
}
// ── 动态模型路由 ────────────────────────────────
@ -176,16 +176,17 @@ function selectModel(taskType, preferredBackend) {
const available = detectAvailableBackends();
if (available.length === 0) {
return { error: '未检测到任何可用模型后端,请检查 API 密钥配置' };
return { error: '未检测到 LLM API 密钥,请配置 ZY_LLM_API_KEY 和 ZY_LLM_BASE_URL' };
}
// 如果指定了后端
if (preferredBackend && preferredBackend !== 'auto') {
const match = available.find(b => b.name === preferredBackend);
const match = available.find(b => b.name === preferredBackend || b.model === preferredBackend);
if (match) {
return { backend: match, model: match.models[0] || 'default', reason: '用户指定' };
return { backend: match, model: match.model, reason: '用户指定' };
}
return { error: `指定的模型后端 "${preferredBackend}" 不可用` };
// 如果直接指定了模型名,使用第一个后端配置但覆盖模型名
return { backend: { ...available[0], model: preferredBackend }, model: preferredBackend, reason: '用户指定模型名' };
}
// 动态路由
@ -229,9 +230,9 @@ function selectModel(taskType, preferredBackend) {
return {
backend: bestBackend,
model: bestBackend.models[0] || 'default',
model: bestBackend.model,
reason: `动态路由 · ${routing.description} · 得分 ${bestScore}`,
all_available: available.map(b => b.name)
all_available: available.map(b => `${b.name}(${b.model})`)
};
}

View File

@ -0,0 +1,205 @@
#!/usr/bin/env node
/**
*
* 🔺 Sovereign: TCS-0002 | Root: SYS-GLW-0001
* 📜 Copyright: 国作登字-2026-A-00037559
*
*
* 铸渊 · 密钥配置验证器
* scripts/secrets-validator.js
*
* 功能验证所有必需的 GitHub Secrets 是否已配置
* 用法node scripts/secrets-validator.js [--check] [--report]
*
* 指令SY-CMD-KEY-012 · 密钥全量清理与统一替换
*/
const fs = require('fs');
const path = require('path');
// ━━━ 加载密钥清单 ━━━
const manifestPath = path.join(__dirname, '..', 'brain', 'secrets-manifest.json');
let manifest;
try {
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
} catch (e) {
console.error('❌ 无法加载密钥清单: brain/secrets-manifest.json');
process.exit(1);
}
// ━━━ 从环境变量检查密钥状态 ━━━
function checkSecrets() {
const results = {
configured: [],
missing: [],
optional_configured: [],
optional_missing: []
};
// 检查必需密钥
for (const secret of manifest.secrets.required) {
const envName = secret.name;
if (process.env[envName] && process.env[envName].length > 0) {
results.configured.push(secret);
} else {
results.missing.push(secret);
}
}
// 检查可选密钥
for (const secret of manifest.secrets.optional) {
const envName = secret.name;
if (process.env[envName] && process.env[envName].length > 0) {
results.optional_configured.push(secret);
} else {
results.optional_missing.push(secret);
}
}
return results;
}
// ━━━ 扫描工作流文件验证密钥引用一致性 ━━━
function scanWorkflows() {
const workflowDir = path.join(__dirname, '..', '.github', 'workflows');
const issues = [];
if (!fs.existsSync(workflowDir)) {
return { issues: ['工作流目录不存在'], stats: {} };
}
const files = fs.readdirSync(workflowDir).filter(f => f.endsWith('.yml'));
const secretRefs = new Map();
let oldSecretRefs = [];
// 旧密钥名称列表(不应再出现)
const oldSecretNames = Object.keys(manifest.migration_mapping.mappings);
for (const file of files) {
const content = fs.readFileSync(path.join(workflowDir, file), 'utf8');
const matches = content.match(/secrets\.([A-Z_0-9]+)/g) || [];
for (const match of matches) {
const secretName = match.replace('secrets.', '');
// 跳过 GITHUB_TOKEN自动提供
if (secretName === 'GITHUB_TOKEN') continue;
if (!secretRefs.has(secretName)) {
secretRefs.set(secretName, []);
}
secretRefs.get(secretName).push(file);
// 检查是否使用了旧密钥名称
if (oldSecretNames.includes(secretName)) {
oldSecretRefs.push({ secret: secretName, file, newName: manifest.migration_mapping.mappings[secretName] });
}
}
}
if (oldSecretRefs.length > 0) {
issues.push(`⚠️ 发现 ${oldSecretRefs.length} 处旧密钥名称引用未迁移`);
}
return {
issues,
oldSecretRefs,
stats: {
total_workflows: files.length,
unique_secrets: secretRefs.size,
secret_refs: Object.fromEntries(secretRefs)
}
};
}
// ━━━ 生成报告 ━━━
function generateReport(mode) {
const envCheck = checkSecrets();
const workflowScan = scanWorkflows();
if (mode === 'check') {
// CI模式仅检查工作流引用是否已迁移到ZY_*
console.log('🔍 铸渊密钥迁移验证');
console.log('═'.repeat(50));
if (workflowScan.oldSecretRefs && workflowScan.oldSecretRefs.length > 0) {
console.log(`\n❌ 发现 ${workflowScan.oldSecretRefs.length} 处旧密钥引用:`);
for (const ref of workflowScan.oldSecretRefs) {
console.log(` ${ref.file}: ${ref.secret} → 应改为 ${ref.newName}`);
}
process.exit(1);
} else {
console.log('\n✅ 所有工作流密钥引用已迁移到 ZY_* 命名体系');
console.log(` 工作流总数: ${workflowScan.stats.total_workflows}`);
console.log(` 唯一密钥数: ${workflowScan.stats.unique_secrets}`);
}
return;
}
// 完整报告
console.log('');
console.log('🔺 铸渊密钥配置验证报告');
console.log('═'.repeat(60));
console.log(`📋 密钥清单版本: ${manifest._meta.manifest_id}`);
console.log(`📅 清单创建时间: ${manifest._meta.created}`);
console.log('');
// 必需密钥状态
console.log('━━━ 必需密钥 (Required) ━━━');
console.log(` ✅ 已配置: ${envCheck.configured.length}/${manifest.secrets.required.length}`);
console.log(` ❌ 未配置: ${envCheck.missing.length}/${manifest.secrets.required.length}`);
console.log('');
if (envCheck.missing.length > 0) {
console.log(' 未配置的必需密钥:');
for (const s of envCheck.missing) {
console.log(`${s.name}${s.description}`);
}
console.log('');
}
if (envCheck.configured.length > 0) {
console.log(' 已配置的必需密钥:');
for (const s of envCheck.configured) {
console.log(`${s.name}`);
}
console.log('');
}
// 可选密钥状态
console.log('━━━ 可选密钥 (Optional) ━━━');
console.log(` ✅ 已配置: ${envCheck.optional_configured.length}/${manifest.secrets.optional.length}`);
console.log(` ⬜ 未配置: ${envCheck.optional_missing.length}/${manifest.secrets.optional.length}`);
console.log('');
// 工作流扫描
console.log('━━━ 工作流密钥引用扫描 ━━━');
console.log(` 工作流总数: ${workflowScan.stats.total_workflows}`);
console.log(` 唯一密钥数: ${workflowScan.stats.unique_secrets}`);
if (workflowScan.issues.length > 0) {
for (const issue of workflowScan.issues) {
console.log(` ${issue}`);
}
} else {
console.log(' ✅ 所有引用已使用 ZY_* 命名');
}
console.log('');
// 总结
const allRequired = envCheck.missing.length === 0;
console.log('━━━ 总结 ━━━');
if (allRequired) {
console.log(' 🟢 所有必需密钥已配置 · 系统可以正常运行');
} else {
console.log(` 🔴 还有 ${envCheck.missing.length} 个必需密钥未配置`);
console.log(' 请参考 brain/secrets-manifest.json 逐一配置');
}
console.log('');
}
// ━━━ 主程序 ━━━
const args = process.argv.slice(2);
const mode = args.includes('--check') ? 'check' : 'report';
generateReport(mode);