--- belongs_to: - "[[INDEX · 铸渊·协作指令|GitHub ↔ Notion 桥接协议]]" --- # 🌙 铸渊指令|天眼夜间自动修复引擎(上篇)—— 架构·扫描·分析·修复核心 --- --- ## 一、指令背景 当前天眼系统(v2.0)定位为 **审计扫描工具**:扫描 → 报告 → 等待人类下指令 → 铸渊修复。 **核心问题:** 如果冰朔不主动发现报错、不下指令,bug 会无限期存在。天眼能看到问题但不能解决问题。 **本次升级目标:** 将天眼从「被动审计」升级为「主动修复」——每天夜间自动巡查所有 Workflow 运行记录,发现报错后唤醒铸渊核心大脑分析修复,天眼审核通过后自动创建 PR,次日人类审阅合并。 --- ## 二、系统架构全景图 ```mermaid flowchart TD A["⏰ CRON 触发
每天 23:00 CST"] --> B["🔭 Phase A:天眼夜间巡查
scan-nightly-errors.yml"] B --> C{"发现报错?"} C -->|"无报错"| D["✅ 写入仪表盘
今日无异常"] C -->|"有报错"| E["🧠 Phase B:报错智能分析
analyze-errors"] E --> F["⚒️ Phase C:铸渊自动修复
auto-repair-engine"] F --> G["🔭 Phase D:天眼审核修复代码
tianyan-review"] G --> H{"审核通过?"} H -->|"通过"| I["📦 Phase E:创建 PR
fix/auto-repair-YYYYMMDD"] H -->|"未通过"| J["🔄 回退重试
最多2轮"] J --> F I --> K["📊 Phase F:更新仪表盘
待合并修复 N 个"] K --> L["☀️ Phase G:人类晨间审阅
冰朔查看仪表盘 → 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 触发条件 ```yaml 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 调用参数 ```yaml 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` ```yaml 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<> $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 休眠开始 ``` ---