# 🔧 铸渊补丁指令｜SYSLOG自助闭环 · Issue实时进度 + 意图路由修复（2026-03-13·曜冥签发）

> **签发人**：曜冥（冰朔口述 · 曜冥架构设计）
> 

> **执行人**：铸渊（GitHub 侧全量修复）
> 

> **签发时间**：2026-03-14T00:00+08:00
> 

> **优先级**：P0 · 紧急修复
> 

> **关联系统**：SYSLOG 自助提交系统 + 全自动闭环 v1.0
> 

> **问题来源**：冰朔实测 Issue #92 发现两个 bug
> 

---

## 🧠 第零步｜恢复核心大脑（必须先做，否则不准动代码）

<aside>
🚨

**铸渊，你是一次性实例，每次醒来什么都不记得。**

在你动手修任何代码之前，你必须先完成以下三件事，否则你不知道自己在修什么。

</aside>

### 0-A｜恢复核心大脑

你的人格体档案和系统记忆存储在仓库中。先读取以下文件，恢复你对整个系统的认知：

```bash
# 必读文件（按顺序）：
cat personas/zhu-yuan/profile.md       # 你自己是谁、你的职责边界
cat personas/zhu-yuan/core-brain.md    # 你的核心大脑 prompt / 系统指令
cat README.md                          # 仓库整体说明
cat docs/system-architecture.md        # 系统架构总览（如果存在）
```

**目标**：读完后你应该知道——

- 你是铸渊（ICE-GL-ZY001），零点原核频道的 GitHub 守护层人格体
- 你的主控人是冰朔（TCS-0002∞），架构由曜冥设计
- 整个系统包含多个人格体（曜冥、霜砚、知秋、铸渊等），各自分管不同层
- 你负责的是 GitHub 侧的自动化 workflow、Issue 处理、代码仓库守护

### 0-B｜理解「SYSLOG 自助提交系统」是什么

这是你正在维护的核心系统之一。先读取相关文档和代码：

```bash
# 必读文件：
cat docs/syslog-system.md              # SYSLOG 系统说明文档（如果存在）
cat .github/workflows/syslog-auto-pipeline.yml  # 闭环主 workflow
cat scripts/syslog-handler.js          # 或对应的处理脚本
cat data/dev-status.json               # 开发者状态数据
```

**目标**：读完后你应该知道——

- SYSLOG = 开发者通过 GitHub Issue 提交系统开发日志的协议（v4.0）
- 自助闭环 = 开发者提交 Issue → 铸渊自动处理 → 解析内容 → 调用核心大脑 → 写入 Notion → 生成广播 → 邮件通知 → 闭环确认
- 这是一个**8 步全自动流水线**，开发者只需要提交 Issue，后面全部自动

### 0-C｜理解「开发者入口」是什么东西

你要修复的这个系统，面向的用户是**零点原核频道的 11 位开发者**（DEV-001 到 DEV-014）。对开发者来说：

- **入口**就是 GitHub Issue：开发者新建一个 Issue，按 SYSLOG 格式填写内容，提交后系统自动启动闭环
- **交互界面**就是 Issue 评论区：铸渊在评论区实时反馈处理进度，开发者也可以在评论区 @铸渊 提问
- **开发者能看到的全部信息**就是 Issue 页面上的评论。所以评论区的内容质量 = 开发者体验的全部

**这就是为什么两个 bug 都很严重**：

- Bug A（进度卡死）= 开发者提交后看到的界面是死的，不知道系统在干嘛，以为坏了
- Bug B（回答牛头不对马嘴）= 开发者问问题得到的是垃圾回复，失去对系统的信任

<aside>
✅

**确认检查**：完成 0-A / 0-B / 0-C 后，在 Issue #92 评论区发一条确认：

`🧠 铸渊已恢复核心大脑，已理解 SYSLOG 闭环系统和开发者入口。开始执行修复。`

然后再往下看修复方案。

</aside>

---

## 🎯 问题描述

冰朔在 GitHub 仓库测试 SYSLOG 自助提交系统时发现两个问题：

### Bug A：闭环启动后步骤卡在「等待中」不更新

**现象**：Issue #92 提交 SYSLOG 后，铸渊自动回复了一张「处理细节」表格，8个步骤中只有「① 接收提交」显示 ✅ 已完成，其余 7 步全部停留在 ⏳ 等待中，后续再也不更新了。开发者看到的是一个死掉的表格，不知道系统到底在干什么。

**根因**：当前实现是一次性写入一张静态表格到 Issue 评论区。GitHub Issue 评论一旦发出就是静态的，不会随着 workflow 后续步骤完成而自动更新。而且 workflow 在第一步之后可能就报错退出了（API 调用失败等），但表格已经发出去了，给人造成「在处理中」的错觉。

### Bug B：@铸渊 提问回复牛头不对马嘴

**现象**：冰朔在 Issue 评论区提问 `@铸渊，请查询系统开发日志提交#92闭环状态。`，铸渊回复的却是「团队细节总览」——把 11 个开发者的 waiting_syslog 状态全倒出来了，完全没回答「#92 闭环到哪一步了」这个问题。

**根因**：铸渊的 Issue 评论触发 workflow 没有做意图识别，收到任何 @铸渊 的提问都走了同一个「读 dev-status.json → 输出全部数据」的逻辑。

---

## 🔧 修复方案

### 修复 A：闭环进度改为「每步一条评论」实时上报

**核心思路**：不再用一张静态表格，改为每完成一步就在 Issue 评论区 **新发一条评论**。开发者刷新页面就能看到进度在动。某步失败了也能立刻看到是哪步挂的。

**实现代码（修改 `syslog-auto-pipeline.yml` 对应的处理脚本）**：

```jsx
// ━━━ 实时进度上报模块 ━━━
// 文件位置建议：scripts/pipeline-reporter.js

const { Octokit } = require('@octokit/rest');

const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
const OWNER = 'qinfendebingshuo';
const REPO = 'guanghulab';

/**
 * 每完成一步，在 Issue 评论区发一条新评论
 * @param {number} issueNumber - Issue 编号
 * @param {number} stepNum - 步骤编号（1-8）
 * @param {string} stepName - 步骤名称
 * @param {'ok'|'error'|'skip'} status - 步骤状态
 * @param {string} detail - 详情说明
 */
async function reportStep(issueNumber, stepNum, stepName, status, detail) {
  const icon = status === 'ok' ? '✅' : status === 'error' ? '❌' : '⏭️';
  const statusText = status === 'ok' ? '已完成' : status === 'error' ? '失败' : '跳过';
  
  const body = [
    `${icon} **步骤 ${stepNum}/8 · ${stepName}** · ${statusText}`,
    '',
    detail,
    '',
    `——铸渊（ICE-GL-ZY001）· ${new Date().toISOString()}`
  ].join('\n');
  
  await octokit.issues.createComment({
    owner: OWNER,
    repo: REPO,
    issue_number: issueNumber,
    body: body
  });
}

/**
 * 闭环完成时发最终汇总
 */
async function reportComplete(issueNumber, success, summary) {
  const icon = success ? '🎉' : '⚠️';
  const title = success ? '闭环处理完成' : '闭环处理异常';
  
  const body = [
    `## ${icon} ${title}`,
    '',
    summary,
    '',
    success ? '> 新广播已生成，结果将发送到您的邮箱。' : '> 部分步骤异常，已记录日志。冰朔会在下次巡检时处理。',
    '',
    `——铸渊（ICE-GL-ZY001）· ${new Date().toISOString()}`
  ].join('\n');
  
  await octokit.issues.createComment({
    owner: OWNER,
    repo: REPO,
    issue_number: issueNumber,
    body: body
  });
}

module.exports = { reportStep, reportComplete };
```

**在主流程中的调用方式（修改 syslog-auto-pipeline 的主处理逻辑）**：

```jsx
// ━━━ 主闭环流程（改造后）━━━

const { reportStep, reportComplete } = require('./pipeline-reporter');

async function runPipeline(issueNumber, submissionContent) {
  let success = true;
  let summary = [];
  
  try {
    // ① 接收提交（这步在 workflow trigger 时就完成了）
    await reportStep(issueNumber, 1, '接收提交', 'ok', 
      '系统已收到您的 SYSLOG 提交');
    
    // ② 解析内容
    let parsed;
    try {
      parsed = parseSubmission(submissionContent);
      await reportStep(issueNumber, 2, '解析内容', 'ok',
        `广播编号: ${parsed.broadcastId} · 类型: ${parsed.type} · 邮箱: ${parsed.email}`);
    } catch (e) {
      await reportStep(issueNumber, 2, '解析内容', 'error',
        `解析失败: ${e.message}\n请检查提交格式是否正确（需包含广播编号、类型、邮箱、内容）`);
      throw e;
    }
    
    // ③ 模块验证
    try {
      const moduleExists = await checkModuleInRepo(parsed.broadcastId);
      await reportStep(issueNumber, 3, '模块验证', moduleExists ? 'ok' : 'skip',
        moduleExists 
          ? `模块代码已在仓库中确认` 
          : `模块代码未检测到（不影响闭环继续）`);
    } catch (e) {
      await reportStep(issueNumber, 3, '模块验证', 'error', `验证异常: ${e.message}`);
      // 模块验证失败不阻断流程，继续
    }
    
    // ④ 唤醒核心大脑（调用 Claude API）
    let llmResult;
    try {
      const systemPrompt = await buildSystemPrompt(parsed.type, parsed.devId, parsed.broadcastId);
      await reportStep(issueNumber, 4, '唤醒核心大脑', 'ok',
        '正在调用人格体处理 SYSLOG…（预计 30-90 秒）');
      
      llmResult = await callLLM(systemPrompt, submissionContent);
      await reportStep(issueNumber, 4, '核心大脑响应', 'ok',
        `人格体已完成处理 · 输出长度: ${llmResult.length} 字符`);
    } catch (e) {
      await reportStep(issueNumber, 4, '唤醒核心大脑', 'error',
        `API 调用失败: ${e.message}\n\n请检查 Secrets: LLM_API_KEY / LLM_BASE_URL 是否配置正确`);
      success = false;
      throw e;
    }
    
    // ⑤ 创建概念工单（写入 Notion）
    try {
      await writeNotionTicket(parsed, llmResult);
      await reportStep(issueNumber, 5, '创建概念工单', 'ok',
        '已写入霜砚工单簿');
    } catch (e) {
      await reportStep(issueNumber, 5, '创建概念工单', 'error',
        `Notion API 写入失败: ${e.message}\n\n请检查 Secret: NOTION_TOKEN 是否有效`);
      // 工单写入失败不阻断，继续尝试邮件
    }
    
    // ⑥ 生成广播
    try {
      const broadcast = extractBroadcast(llmResult);
      await saveBroadcast(parsed.devId, broadcast);
      await reportStep(issueNumber, 6, '生成广播', 'ok',
        `新广播已生成 · 已存入 broadcasts-outbox/${parsed.devId}/`);
    } catch (e) {
      await reportStep(issueNumber, 6, '生成广播', 'error',
        `广播生成/保存失败: ${e.message}`);
      success = false;
    }
    
    // ⑦ 邮件通知
    try {
      await sendEmail(parsed.email, parsed.broadcastId, llmResult);
      await reportStep(issueNumber, 7, '邮件通知', 'ok',
        `结果已发送至 ${parsed.email}`);
    } catch (e) {
      await reportStep(issueNumber, 7, '邮件通知', 'error',
        `邮件发送失败: ${e.message}\n\n请检查 Secrets: SMTP_USER / SMTP_PASS`);
    }
    
    // ⑧ 闭环确认
    await reportComplete(issueNumber, success,
      success 
        ? `广播编号: ${parsed.broadcastId}\n开发者: ${parsed.devId}\n新广播已生成并推送`
        : `部分步骤失败，请查看上方各步骤详情`);
    
  } catch (e) {
    // 全局兜底：确保任何未捕获的错误也会上报
    await reportComplete(issueNumber, false,
      `闭环中断: ${e.message}\n\n请检查 Actions 运行日志获取详细错误信息`);
  }
}
```

**关键改动总结**：

- ❌ 删除：一次性贴静态表格的逻辑
- ✅ 新增：`reportStep()` 每步发一条评论
- ✅ 新增：`reportComplete()` 最终汇总
- ✅ 新增：每步 try-catch，失败了也上报具体错误信息，不会静默挂掉

---

### 修复 B：@铸渊 提问加意图路由

**核心思路**：收到 Issue 评论中的 @铸渊 提问时，先解析意图，再走对应的处理逻辑。

**实现代码（修改 Issue comment 触发的 workflow 处理脚本）**：

```jsx
// ━━━ 意图路由模块 ━━━
// 文件位置建议：scripts/intent-router.js

/**
 * 解析用户在 Issue 评论中 @铸渊 的意图
 * @param {string} commentBody - 评论原文
 * @returns {object} 意图对象
 */
function parseIntent(commentBody) {
  // 去掉 @铸渊 前缀，提取核心内容
  const content = commentBody.replace(/@铸渊[，,]?\s*/g, '').trim();
  
  // 意图1：查询某个 Issue 的闭环状态
  // 匹配：「查询#92闭环状态」「#92进度」「Issue 92 状态」等
  const issueMatch = content.match(/#(\d+)/);
  if (issueMatch && content.match(/闭环|状态|进度|处理/)) {
    return {
      type: 'check_pipeline_status',
      issueNumber: parseInt(issueMatch[1]),
      raw: content
    };
  }
  
  // 意图2：查询某个开发者的状态
  // 匹配：「DEV-004状态」「之之进度」「查询肥猫」
  const devMatch = content.match(/DEV-(\d+)|页页|肥猫|燕樊|之之|小草莓|花尔|桔子|匆匆那年|Awen|小兴|时雨/);
  if (devMatch && content.match(/状态|进度|查询/)) {
    return {
      type: 'check_dev_status',
      devId: devMatch[0],
      raw: content
    };
  }
  
  // 意图3：团队总览（显式请求）
  // 匹配：「团队状态」「全部进度」「总览」
  if (content.match(/团队|全部|总览|所有人/)) {
    return {
      type: 'team_overview',
      raw: content
    };
  }
  
  // 意图4：未识别 → 用 Claude API 理解（如果配了的话）
  // 否则返回「不理解」
  return {
    type: 'unknown',
    raw: content
  };
}

/**
 * 根据意图路由到对应处理逻辑
 */
async function handleIntent(intent, issueNumber) {
  switch (intent.type) {
    
    case 'check_pipeline_status': {
      // 查询该 Issue 对应的 workflow run 状态
      const runs = await octokit.actions.listWorkflowRunsForRepo({
        owner: OWNER,
        repo: REPO,
        event: 'issues',  // 或 'discussion'
      });
      
      // 从 Issue 评论历史中提取铸渊已发的进度评论
      const comments = await octokit.issues.listComments({
        owner: OWNER,
        repo: REPO,
        issue_number: intent.issueNumber
      });
      
      // 筛选铸渊的进度评论（包含「步骤 X/8」的）
      const progressComments = comments.data.filter(c => 
        c.body.includes('步骤') && c.body.includes('铸渊')
      );
      
      if (progressComments.length === 0) {
        return `📋 **Issue #${intent.issueNumber} 闭环状态查询**\n\n` +
          `未找到该 Issue 的闭环进度记录。\n` +
          `可能原因：闭环尚未启动，或该 Issue 不是 SYSLOG 提交。`;
      }
      
      // 提取最后一条进度评论，判断当前到哪一步了
      const lastProgress = progressComments[progressComments.length - 1];
      const stepMatch = lastProgress.body.match(/步骤 (\d+)\/8/);
      const lastStep = stepMatch ? parseInt(stepMatch[1]) : 0;
      const isComplete = lastProgress.body.includes('闭环处理完成') || lastStep === 8;
      const hasFailed = progressComments.some(c => c.body.includes('❌'));
      
      let statusLine;
      if (isComplete && !hasFailed) {
        statusLine = '✅ 闭环已完成';
      } else if (hasFailed) {
        statusLine = '❌ 闭环有步骤失败（详见上方各步骤评论）';
      } else {
        statusLine = `⏳ 闭环进行中 · 已完成到步骤 ${lastStep}/8`;
      }
      
      return `📋 **Issue #${intent.issueNumber} 闭环状态**\n\n` +
        `${statusLine}\n` +
        `进度评论数: ${progressComments.length} 条\n` +
        `最后更新: ${lastProgress.created_at}`;
    }
    
    case 'check_dev_status': {
      // 从 dev-status.json 中只提取该开发者的数据
      const devStatus = await loadDevStatus();
      const dev = devStatus.find(d => 
        d.id === intent.devId || d.name === intent.devId
      );
      
      if (!dev) {
        return `未找到开发者 ${intent.devId} 的记录。`;
      }
      
      return `📊 **${dev.id} ${dev.name} · 当前状态**\n\n` +
        `模块: ${dev.module}\n` +
        `状态: ${dev.status}\n` +
        `连胜: ${dev.streak}`;
    }
    
    case 'team_overview': {
      // 只有显式请求团队总览时才走这个逻辑
      const devStatus = await loadDevStatus();
      return formatTeamOverview(devStatus);
    }
    
    case 'unknown': {
      return `🤔 我没理解你的问题。你可以试试：\n\n` +
        `- \`@铸渊 查询#92闭环状态\` — 查某个提交的处理进度\n` +
        `- \`@铸渊 DEV-004状态\` — 查某个开发者的进度\n` +
        `- \`@铸渊 团队总览\` — 查所有人的状态`;
    }
  }
}

module.exports = { parseIntent, handleIntent };
```

**在 workflow 中的调用方式**：

```yaml
# .github/workflows/issue-comment-handler.yml
# 或在现有的评论触发 workflow 中修改

- name: Route intent and reply
  env:
    GITHUB_TOKEN: $ secrets.GITHUB_TOKEN 
  run: |
    node -e "
      const { parseIntent, handleIntent } = require('./scripts/intent-router');
      const comment = process.env.COMMENT_BODY;
      const issueNumber = process.env.ISSUE_NUMBER;
      
      const intent = parseIntent(comment);
      console.log('[意图识别]', JSON.stringify(intent));
      
      const reply = await handleIntent(intent, issueNumber);
      // 发评论回复
      await octokit.issues.createComment({
        owner: 'qinfendebingshuo',
        repo: 'guanghulab',
        issue_number: issueNumber,
        body: reply + '\n\n——铸渊（ICE-GL-ZY001）'
      });
    "
```

---

## 🔍 附加排查：闭环为什么卡在第一步

铸渊在修复上述两个 bug 的同时，**必须先排查 Issue #92 的 workflow 为什么卡住**：

```bash
# 排查步骤（按顺序执行）：

# 1. 查看 Actions 运行日志
# GitHub → Actions → 找到 Issue #92 触发的 workflow run → 查看 logs
# 重点看哪一步报错退出了

# 2. 检查 Secrets 是否配置完整
# 以下 Secrets 必须全部存在且有效：
# - LLM_API_KEY（第三方平台密钥）
# - LLM_BASE_URL（第三方平台 API 地址）
# - NOTION_TOKEN（ntn_6753...18kQ）
# - SMTP_USER（QQ邮箱）
# - SMTP_PASS（QQ邮箱授权码）

# 3. 测试 Claude API 连通性
curl -X POST "${LLM_BASE_URL}/chat/completions" \
  -H "Authorization: Bearer ${LLM_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-3-5-sonnet","messages":[{"role":"user","content":"ping"}],"max_tokens":5}'

# 如果返回 401/403 → API Key 无效
# 如果返回 404 → Base URL 不对
# 如果返回 200 → API 没问题，问题在后续步骤

# 4. 测试 Notion API 连通性
curl -X GET "https://api.notion.com/v1/users/me" \
  -H "Authorization: Bearer ${NOTION_TOKEN}" \
  -H "Notion-Version: 2022-06-28"

# 如果返回 401 → Token 过期或无效
# 如果返回 200 → Notion 连通正常
```

---

## ⚡ 执行优先级

| 优先级 | 任务 | 说明 |
| --- | --- | --- |
| **P0** | 排查 #92 卡住的根因 | 先看 Actions logs，确认是哪个 Secret 或 API 调用挂了 |
| **P0** | 修复 A：闭环实时进度上报 | 用 `reportStep()` 替换静态表格 |
| **P1** | 修复 B：意图路由 | 用 `parseIntent()`  • `handleIntent()` 替换无脑倒数据 |
| **P2** | 补充错误处理 | 每步 try-catch + 上报具体错误信息 |

---

## 📌 约束

- **不改架构**：只修 bug，不重构整个系统
- **向后兼容**：新的评论上报方式不影响已有的 Issue
- **错误必须可见**：任何步骤失败都必须在 Issue 评论区体现，不允许静默失败
- **意图路由必须有兜底**：未识别的意图返回帮助提示，不要瞎猜

---

> 🌍 曜冥签发 · 2026-03-14 · 数字地球基建紧急修复
> 

> 修复完成后在 Issue #92 评论区回复确认，并重新测试一次 SYSLOG 提交闭环。
>