diff --git a/.github/ISSUE_TEMPLATE/syslog-submit.yml b/.github/ISSUE_TEMPLATE/syslog-submit.yml
new file mode 100644
index 00000000..80a87d27
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/syslog-submit.yml
@@ -0,0 +1,54 @@
+name: "📡 提交系统日志 / 提问"
+description: "做完了?提交你的 SYSLOG。有问题?在这里提问。"
+title: "BC-XXX-XXX|SYSLOG"
+labels: ["syslog", "pending"]
+assignees: []
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## 📡 SYSLOG 自助提交 / 广播提问
+
+ > 做完了?把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。
+ >
+ > 有问题?把问题粘贴进去,填上邮箱,点提交。解答会发到你邮箱里。
+
+ **标题格式**:`BC-XXX-XXX|SYSLOG` 或 `BC-XXX-XXX|提问`
+
+ - type: input
+ id: broadcast_id
+ attributes:
+ label: "广播编号"
+ description: "写上你当前广播的编号,例如 BC-M22-009-AW"
+ placeholder: "BC-M22-009-AW"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: submit_type
+ attributes:
+ label: "类型"
+ description: "选择提交类型"
+ options:
+ - SYSLOG
+ - 提问
+ validations:
+ required: true
+
+ - type: input
+ id: email
+ attributes:
+ label: "你的邮箱"
+ description: "用于接收新广播或问题解答"
+ placeholder: "your@email.com"
+ validations:
+ required: true
+
+ - type: textarea
+ id: content
+ attributes:
+ label: "内容"
+ description: "粘贴你的 SYSLOG 全文 或 问题描述"
+ placeholder: "在这里粘贴你的 SYSLOG 或问题..."
+ validations:
+ required: true
diff --git a/.github/workflows/syslog-issue-pipeline.yml b/.github/workflows/syslog-issue-pipeline.yml
new file mode 100644
index 00000000..5a5d81a5
--- /dev/null
+++ b/.github/workflows/syslog-issue-pipeline.yml
@@ -0,0 +1,325 @@
+name: SYSLOG Issue Pipeline
+# 📡 SYSLOG 自助提交系统 · Issue 版全自动闭环
+#
+# 开发者在 GitHub Issue 提交 SYSLOG 或提问(使用 syslog-submit 模板)
+# → Actions 自动解析 → 调用 LLM API 唤醒人格体
+# → 写入 Notion 工单 → 发邮件给开发者 → Issue 回复
+#
+# 依赖 Secrets:
+# LLM_API_KEY 第三方 LLM 平台密钥(必须)
+# LLM_BASE_URL 第三方 LLM 平台 API 地址(必须,如 https://api.xxx.com/v1)
+# NOTION_API_TOKEN Notion API token
+# NOTION_TICKET_DB_ID 霜砚工单数据库 ID
+# CORE_BRAIN_PAGE_ID 曜冥核心大脑 v4.0 页面 ID(v4.0 协议动态注入)
+# PORTRAIT_DB_ID 开发者动态画像库数据库 ID(v4.0 协议动态注入)
+# FINGERPRINT_DB_ID 模块指纹注册表数据库 ID(v4.0 协议动态注入)
+# SMTP_USER QQ 邮箱地址
+# SMTP_PASS QQ 邮箱 SMTP 授权码
+
+on:
+ issues:
+ types: [opened, labeled]
+
+jobs:
+ process:
+ name: 📡 处理 SYSLOG 提交 / 广播提问 (Issue)
+ runs-on: ubuntu-latest
+ if: contains(toJSON(github.event.issue.labels), 'syslog')
+ permissions:
+ contents: write
+ issues: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+
+ - name: Install dependencies
+ run: npm ci --ignore-scripts
+
+ - name: 🔍 Parse submission
+ id: parse
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const body = context.payload.issue.body || '';
+ const title = context.payload.issue.title || '';
+
+ // Parse structured fields from issue body
+ function extractField(text, label) {
+ // Match form field format: ### Label\n\nValue
+ const regex = new RegExp('###\\s*' + label + '\\s*\\n+([^\\n#]+)', 'i');
+ const match = text.match(regex);
+ return match ? match[1].trim() : '';
+ }
+
+ const broadcastId = extractField(body, '广播编号') || '';
+ const submitType = extractField(body, '类型') || '';
+ const email = extractField(body, '你的邮箱') || '';
+
+ // Extract content (everything after "### 内容")
+ const contentMatch = body.match(/###\s*内容\s*\n+([\s\S]*?)$/i);
+ const content = contentMatch ? contentMatch[1].trim() : '';
+
+ // Determine type from title or body
+ let type = 'question'; // default
+ if (submitType.includes('SYSLOG') || title.includes('SYSLOG')) {
+ type = 'syslog';
+ } else if (submitType.includes('提问') || title.includes('提问')) {
+ type = 'question';
+ }
+
+ // Validate
+ if (!broadcastId) {
+ core.setFailed('❌ 缺少广播编号,请在提交时填写广播编号');
+ return;
+ }
+ if (!email) {
+ core.setFailed('❌ 缺少邮箱,请在提交时填写你的邮箱');
+ return;
+ }
+ if (!content) {
+ core.setFailed('❌ 缺少内容,请粘贴你的 SYSLOG 或问题');
+ return;
+ }
+
+ core.setOutput('broadcast_id', broadcastId);
+ core.setOutput('type', type);
+ core.setOutput('email', email);
+ core.setOutput('content', content);
+ core.setOutput('issue_number', context.payload.issue.number);
+ core.setOutput('author', context.payload.issue.user.login);
+
+ console.log(`📡 解析完成: 广播=${broadcastId}, 类型=${type}, 邮箱=${email}`);
+
+ - name: 🧠 Auto-detect and wake up persona
+ id: persona
+ env:
+ LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
+ LLM_BASE_URL: ${{ secrets.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 }}
+ NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
+ CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }}
+ PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }}
+ FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
+ run: node scripts/wake-persona.js
+
+ - name: 📋 Write to Notion ticket
+ if: ${{ secrets.NOTION_API_TOKEN }}
+ env:
+ NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
+ NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
+ BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
+ SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
+ PERSONA_RESULT: ${{ steps.persona.outputs.result }}
+ run: |
+ node -e "
+ const https = require('https');
+
+ const token = process.env.NOTION_TOKEN;
+ const dbId = process.env.NOTION_TICKET_DB_ID;
+ const broadcastId = process.env.BROADCAST_ID || 'UNKNOWN';
+ const type = process.env.SUBMIT_TYPE || 'syslog';
+ const result = process.env.PERSONA_RESULT || '(no result)';
+
+ if (!token || !dbId) {
+ console.log('⚠️ Notion credentials not configured, skipping ticket creation');
+ process.exit(0);
+ }
+
+ const typeLabel = type === 'syslog' ? 'SYSLOG闭环' : '提问解答';
+ const title = '[自动] ' + broadcastId + ' · ' + typeLabel;
+
+ const body = JSON.stringify({
+ parent: { database_id: dbId },
+ properties: {
+ '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] },
+ '操作类型': { select: { name: '其他' } },
+ '提交者': { rich_text: [{ type: 'text', text: { content: '自动管道' } }] },
+ '状态': { select: { name: '已完成' } },
+ '优先级': { select: { name: 'P1' } }
+ },
+ children: [{
+ object: 'block',
+ type: 'paragraph',
+ paragraph: {
+ rich_text: [{ type: 'text', text: { content: result.slice(0, 2000) } }]
+ }
+ }]
+ });
+
+ const opts = {
+ hostname: 'api.notion.com',
+ port: 443,
+ path: '/v1/pages',
+ method: 'POST',
+ headers: {
+ 'Authorization': 'Bearer ' + token,
+ 'Content-Type': 'application/json',
+ 'Notion-Version': '2022-06-28',
+ 'Content-Length': Buffer.byteLength(body)
+ }
+ };
+
+ const req = https.request(opts, (res) => {
+ let data = '';
+ res.on('data', (c) => data += c);
+ res.on('end', () => {
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ console.log('✅ Notion 工单已创建');
+ } else {
+ console.log('⚠️ Notion 工单创建失败: ' + res.statusCode + ' ' + data);
+ }
+ });
+ });
+ req.on('error', (e) => console.log('⚠️ Notion 请求失败: ' + e.message));
+ req.write(body);
+ req.end();
+ "
+
+ - name: 📧 Send email to developer
+ env:
+ SMTP_USER: ${{ secrets.SMTP_USER }}
+ SMTP_PASS: ${{ secrets.SMTP_PASS }}
+ EMAIL_TO: ${{ steps.parse.outputs.email }}
+ BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
+ SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
+ PERSONA_RESULT: ${{ steps.persona.outputs.result }}
+ run: |
+ node -e "
+ const nodemailer = require('nodemailer');
+
+ const user = process.env.SMTP_USER || '';
+ const pass = process.env.SMTP_PASS || '';
+ const to = process.env.EMAIL_TO || '';
+ const broadcastId = process.env.BROADCAST_ID || '';
+ const type = process.env.SUBMIT_TYPE || 'syslog';
+ const result = process.env.PERSONA_RESULT || '(处理中,请稍后)';
+
+ if (!user || !pass) {
+ console.log('⚠️ SMTP not configured, skipping email');
+ process.exit(0);
+ }
+ if (!to) {
+ console.log('⚠️ No recipient email, skipping');
+ process.exit(0);
+ }
+
+ const subjectText = type === 'syslog'
+ ? '[光湖系统] ' + broadcastId + ' · 新广播已生成'
+ : '[光湖系统] ' + broadcastId + ' · 问题已解答';
+
+ const resultHtml = result
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/\n/g, '
');
+
+ const html = [
+ '
HoloLake · 人格语言操作系统
', + '📡 ' + broadcastId + '
', + '🌀 铸渊 · 代码守护人格体 · 自动发送
', + '