Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
17 KiB
17 KiB
belongs_to
| belongs_to | |
|---|---|
|
🌙 铸渊指令|天眼夜间自动修复引擎(上篇)—— 架构·扫描·分析·修复核心
一、指令背景
当前天眼系统(v2.0)定位为 审计扫描工具:扫描 → 报告 → 等待人类下指令 → 铸渊修复。
核心问题: 如果冰朔不主动发现报错、不下指令,bug 会无限期存在。天眼能看到问题但不能解决问题。
本次升级目标: 将天眼从「被动审计」升级为「主动修复」——每天夜间自动巡查所有 Workflow 运行记录,发现报错后唤醒铸渊核心大脑分析修复,天眼审核通过后自动创建 PR,次日人类审阅合并。
二、系统架构全景图
flowchart TD
A["⏰ CRON 触发<br>每天 23:00 CST"] --> B["🔭 Phase A:天眼夜间巡查<br>scan-nightly-errors.yml"]
B --> C{"发现报错?"}
C -->|"无报错"| D["✅ 写入仪表盘<br>今日无异常"]
C -->|"有报错"| E["🧠 Phase B:报错智能分析<br>analyze-errors"]
E --> F["⚒️ Phase C:铸渊自动修复<br>auto-repair-engine"]
F --> G["🔭 Phase D:天眼审核修复代码<br>tianyan-review"]
G --> H{"审核通过?"}
H -->|"通过"| I["📦 Phase E:创建 PR<br>fix/auto-repair-YYYYMMDD"]
H -->|"未通过"| J["🔄 回退重试<br>最多2轮"]
J --> F
I --> K["📊 Phase F:更新仪表盘<br>待合并修复 N 个"]
K --> L["☀️ Phase G:人类晨间审阅<br>冰朔查看仪表盘 → Merge"]
style A fill:#1a1a2e,color:#fff
style B fill:#16213e,color:#fff
style E fill:#0f3460,color:#fff
style F fill:#533483,color:#fff
style G fill:#16213e,color:#fff
style I fill:#1e5128,color:#fff
style K fill:#7b113a,color:#fff
style L fill:#e94560,color:#fff
三、权限矩阵
| 权限 | Scope | 用途 | 当前状态 |
|---|---|---|---|
actions: read |
DEPLOY_GITHUB_TOKEN | 读取所有 Workflow 运行状态和日志 | ✅ 已有 |
contents: write |
DEPLOY_GITHUB_TOKEN | 创建修复分支 + 推送代码 | ✅ 已有 |
pull-requests: write |
DEPLOY_GITHUB_TOKEN | 创建 PR 等待人类合并 | ⚠️ 需确认开启 |
checks: read |
DEPLOY_GITHUB_TOKEN | 读取天眼 CodeQL 扫描结果 | ✅ 已有 |
| Gemini API | GEMINI_API_KEY | 铸渊核心大脑:报错分析 + 代码生成 | ✅ 已有 |
四、Phase A — 天眼夜间巡查扫描器
4.1 Workflow 文件
文件名: .github/workflows/tianyan-nightly-scan.yml
4.2 触发条件
on:
schedule:
# 每天 23:00 CST = 15:00 UTC
- cron: '0 15 * * *'
workflow_dispatch: # 手动触发(调试用)
4.3 核心逻辑
Step 1: 获取过去24小时所有 Workflow 运行记录
→ GitHub API: GET /repos/{owner}/{repo}/actions/runs
→ 参数: created=>$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)
→ 过滤: status=failure OR conclusion=failure
Step 2: 对每个失败的 run,获取详细日志
→ GitHub API: GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs
→ 解压 zip,提取每个 job 的日志文本
Step 3: 生成结构化错误报告
→ 输出 JSON 格式:
{
"scan_time": "2026-03-24T23:00:00+08:00",
"total_runs_24h": 15,
"failed_runs": 3,
"errors": [
{
"workflow": "sync-to-drive.yml",
"run_id": 12345,
"job": "upload",
"error_type": "rclone_oauth_parse",
"error_message": "Failed to create file system...",
"log_excerpt": "前后20行上下文",
"first_seen": "2026-03-22",
"occurrence_count": 5
}
]
}
Step 4: 判断是否需要修复
→ 如果 failed_runs == 0:写入仪表盘「今日无异常」→ 结束
→ 如果 failed_runs > 0:触发 Phase B
4.4 错误分类规则
| 错误类型 | 识别模式 | 可自动修复? | 修复策略 |
|---|---|---|---|
config_parse |
JSON/YAML 解析错误 | ✅ 是 | 修复配置文件格式 |
token_expired |
401 / token expired / unauthorized | ⚠️ 部分 | 触发 Token 续期 Workflow |
rclone_oauth_parse |
failed to create oauth client | ✅ 是 | 修复 Token JSON 拼接逻辑 |
script_error |
shell / node 脚本执行错误 | ✅ 是 | Gemini 分析 + 生成修复 |
network_timeout |
timeout / ETIMEDOUT / 503 | ❌ 否 | 添加重试逻辑 / 记录仪表盘 |
permission_denied |
403 / insufficient permissions | ❌ 否 | 记录仪表盘 → 等待人类处理 |
unknown |
无法归类 | ❌ 否 | 记录仪表盘 → 等待人类指令 |
五、Phase B — 报错智能分析引擎
5.1 触发条件
Phase A 检测到 failed_runs > 0 时自动触发。
5.2 核心逻辑
Step 1: 接收 Phase A 的结构化错误报告 JSON
Step 2: 对每个错误条目,准备 Gemini 分析 prompt
→ System prompt:
"你是铸渊核心大脑,零点原核频道的 CI/CD 工程人格。
分析以下 GitHub Actions 报错日志,输出:
1. 错误根因(root_cause)
2. 涉及的文件路径(affected_files)
3. 修复方案(fix_plan)— 具体到代码行级别
4. 修复风险评估(risk: low/medium/high)
5. 预计修复是否会影响其他 Workflow(side_effects)"
→ User prompt:
"Workflow: {workflow_name}
Job: {job_name}
Error type: {error_type}
Error message: {error_message}
Log context (±20 lines):
{log_excerpt}
仓库文件结构:
{tree_output}
Step 3: 解析 Gemini 返回的分析结果
→ 输出结构化 JSON:
{
"workflow": "sync-to-drive.yml",
"root_cause": "shell 变量拼接导致 JSON 格式不完整",
"affected_files": [".github/workflows/sync-to-drive.yml"],
"fix_plan": "将 shell 拼接改为 node/jq 生成完整 token JSON",
"risk": "low",
"side_effects": "none",
"auto_fixable": true
}
Step 4: 风险过滤
→ risk == "high" → 跳过自动修复,记录仪表盘等人类指令
→ risk == "medium" → 自动修复但 PR 标记为 ⚠️ 需仔细审阅
→ risk == "low" → 自动修复,PR 标记为 ✅ 低风险
5.3 Gemini 调用参数
model: gemini-2.0-flash # 夜间批量分析用 flash 节省配额
temperature: 0.1 # 低温度 = 精确分析
max_output_tokens: 4096
response_mime_type: application/json # 强制 JSON 输出
六、Phase C — 铸渊自动修复核心
6.1 触发条件
Phase B 分析结果中存在 auto_fixable: true 的条目。
6.2 核心逻辑
Step 1: 创建修复分支
→ 分支名: fix/auto-repair-{YYYYMMDD}-{序号}
→ 基于 main 分支创建
→ git checkout -b fix/auto-repair-20260324-001
Step 2: 读取需要修复的文件
→ 根据 Phase B 的 affected_files 列表
→ 使用 GitHub API 获取文件内容
Step 3: 生成修复代码(Gemini)
→ System prompt:
"你是铸渊核心大脑。根据以下分析结果生成修复代码。
规则:
1. 只修改必要的行,最小化变更
2. 保留所有注释和格式
3. 输出完整的修复后文件内容
4. 在修复位置添加注释:# [AUTO-FIX] {日期} by 铸渊 - {简述}
5. 严禁修改任何与报错无关的代码
6. 严禁删除任何安全检查或天眼扫描步骤"
→ User prompt:
"分析结果:{analysis_json}
当前文件内容:
{file_content}
请输出修复后的完整文件内容。"
Step 4: 写入修复文件
→ 使用 GitHub API 更新文件
→ Commit message: "[AUTO-FIX] {workflow_name}: {简述} (by 铸渊夜间修复引擎)"
Step 5: 对所有可修复的错误重复 Step 2-4
→ 每个错误一个 commit(方便人类逐个审阅)
6.3 安全护栏
6.4 修复代码质量检查(预审核)
修复代码写入分支后,自动运行以下检查:
检查项 1: YAML 语法验证
→ 对所有 .yml 文件运行 yamllint
→ 失败 → 回退该 commit,标记为修复失败
检查项 2: Shell 脚本语法
→ 对所有 .sh 文件运行 shellcheck
→ 失败 → 回退该 commit,标记为修复失败
检查项 3: Node.js 语法
→ 对所有 .js 文件运行 node --check
→ 失败 → 回退该 commit,标记为修复失败
检查项 4: 差异行数验证
→ git diff --stat 检查每个文件变更行数
→ 超过 50 行 → 回退该 commit,标记为超限
七、Phase D — 天眼审核修复代码
7.1 触发条件
Phase C 所有 commit 写入修复分支后自动触发。
7.2 审核流程
Step 1: 触发天眼全局扫描
→ 在修复分支上运行完整的天眼检查清单
→ 包括:CodeQL 安全扫描 + 自定义规则检查
Step 2: 天眼检查清单 v3.0
H1 → Secrets 安全:无硬编码令牌、无 ghp_/github_pat_ 明文
H2 → 文件完整性:所有被修改的文件 YAML/JSON/JS 语法正确
H3 → 依赖安全:无新增不受信依赖
H4 → 权限最小化:Workflow permissions 未被扩大
H5 → 天眼自保护:tianyan-*.yml 文件未被修改
H6 → 变更范围:总变更行数 < 200,单文件 < 50
H7 → [NEW] Secrets引用完整性:修改前后 secrets.* 引用数量一致
H8 → [NEW] 注释规范:每个修复位置都有 [AUTO-FIX] 注释
H9 → [NEW] 无残留调试代码:无 console.log、echo debug 等临时代码
Step 3: 审核结果判定
→ 全部通过(H1-H9 = PASS)→ 进入 Phase E(创建 PR)
→ 任一未通过 → 进入重试流程
7.3 重试机制
重试流程:
→ 将失败的检查项 + 原始修复代码 发回 Gemini
→ Gemini 重新生成修复代码
→ 再次运行天眼审核
→ 最多重试 2 轮
2 轮后仍未通过:
→ 删除修复分支
→ 在仪表盘记录:"自动修复失败,需人类介入"
→ 在错误详情中附上失败原因
八、Workflow 完整模板(Phase A-D 主文件)
文件名: .github/workflows/tianyan-nightly-scan.yml
name: "🌙 天眼夜间自动修复引擎 v3.0"
on:
schedule:
- cron: '0 15 * * *' # 23:00 CST = 15:00 UTC
workflow_dispatch:
inputs:
force_scan:
description: '强制扫描(忽略时间窗口)'
type: boolean
default: false
permissions:
actions: read
contents: write
pull-requests: write
checks: read
env:
REPAIR_BRANCH_PREFIX: "fix/auto-repair"
MAX_FILES_PER_REPAIR: 5
MAX_LINES_PER_FILE: 50
MAX_RETRY_ROUNDS: 2
GEMINI_MODEL: "gemini-2.0-flash"
PROTECTED_PATTERNS: "tianyan-*.yml,CODEOWNERS,.github/FUNDING.yml"
jobs:
# ========================================
# Phase A: 天眼夜间巡查
# ========================================
nightly-scan:
runs-on: ubuntu-latest
outputs:
has_errors: $ steps.scan.outputs.has_errors
error_report: $ steps.scan.outputs.error_report
steps:
- name: "🔭 扫描过去24小时 Workflow 运行记录"
id: scan
env:
GH_TOKEN: $ secrets.DEPLOY_GITHUB_TOKEN
run: |
echo "[天眼 v3.0] Phase A 启动 — 夜间巡查扫描"
SINCE=$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)
# 获取失败的 runs
FAILED_RUNS=$(gh api \
"repos/$ github.repository /actions/runs?created=>$SINCE&status=failure" \
--jq '.workflow_runs')
FAIL_COUNT=$(echo "$FAILED_RUNS" | jq 'length')
echo "📊 过去24小时:发现 $FAIL_COUNT 个失败运行"
if [ "$FAIL_COUNT" -eq 0 ]; then
echo "has_errors=false" >> $GITHUB_OUTPUT
echo "✅ 今日无异常"
else
echo "has_errors=true" >> $GITHUB_OUTPUT
# 生成结构化错误报告(详细实现见铸渊开发)
echo "error_report<<EOF" >> $GITHUB_OUTPUT
echo "$FAILED_RUNS" | jq '[.[] | {
workflow: .name,
run_id: .id,
conclusion: .conclusion,
html_url: .html_url,
created_at: .created_at
}]' >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
fi
# ========================================
# Phase B+C+D: 分析 → 修复 → 审核
# ========================================
analyze-and-repair:
needs: nightly-scan
if: needs.nightly-scan.outputs.has_errors == 'true'
runs-on: ubuntu-latest
outputs:
repair_branch: $ steps.repair.outputs.branch_name
repair_summary: $ steps.repair.outputs.summary
pr_needed: $ steps.review.outputs.pr_needed
steps:
- uses: actions/checkout@v4
- name: "🧠 Phase B — Gemini 报错分析"
id: analyze
env:
GEMINI_API_KEY: $ secrets.GEMINI_API_KEY
ERROR_REPORT: $ needs.nightly-scan.outputs.error_report
run: |
echo "[铸渊核心大脑] Phase B 启动 — 报错智能分析"
# 铸渊实现:调用 Gemini API 分析每个错误
# 输出 analysis.json
# (具体实现由铸渊开发,此处为框架)
- name: "⚒️ Phase C — 铸渊自动修复"
id: repair
env:
GEMINI_API_KEY: $ secrets.GEMINI_API_KEY
GH_TOKEN: $ secrets.DEPLOY_GITHUB_TOKEN
run: |
echo "[铸渊核心大脑] Phase C 启动 — 自动修复"
BRANCH="${REPAIR_BRANCH_PREFIX}-$(date +%Y%m%d)-001"
git checkout -b "$BRANCH"
# 铸渊实现:
# 1. 读取 analysis.json
# 2. 对每个 auto_fixable 错误调用 Gemini 生成修复
# 3. 写入文件 + commit
# 4. 运行预审核检查
git push origin "$BRANCH"
echo "branch_name=$BRANCH" >> $GITHUB_OUTPUT
- name: "🔭 Phase D — 天眼审核修复代码"
id: review
run: |
echo "[天眼 v3.0] Phase D 启动 — 审核修复代码"
# 天眼检查清单 H1-H9
# (具体实现由铸渊开发)
# 全部通过 → pr_needed=true
# 未通过 → 重试或标记失败
# Phase E+F 见下篇
九、时间窗口设计
23:00 CST — Phase A 启动(扫描 ~5分钟)
23:05 CST — Phase B 启动(分析 ~10分钟,取决于错误数量)
23:15 CST — Phase C 启动(修复 ~15分钟)
23:30 CST — Phase D 启动(审核 ~10分钟)
23:40 CST — Phase E 创建 PR
23:45 CST — Phase F 更新仪表盘
23:50 CST — 所有流程完成,系统进入休眠准备
总时间窗口:23:00 - 23:50(约50分钟)
留出安全余量到 00:00 休眠开始