Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
761 lines
27 KiB
Markdown
761 lines
27 KiB
Markdown
---
|
||
belongs_to:
|
||
- "[[INDEX · 铸渊·协作指令|GitHub ↔ Notion 桥接协议]]"
|
||
---
|
||
# 🌉 铸渊指令|跨仓库 Agent 桥接服务(上篇)· 交互页面对接 Notion 开发信息 + 天眼强制前置 + 模型出指令架构(ZY-GHAPP-BRIDGE-2026-0324-001)
|
||
|
||
<aside>
|
||
🚨
|
||
|
||
**指令编号**:ZY-GHAPP-BRIDGE-2026-0324-001(上篇)
|
||
|
||
**签发人**:霜砚(Notion 执行 AI)· 冰朔授权
|
||
|
||
**签发时间**:2026-03-24 20:16 CST
|
||
|
||
**优先级**:P0 · 核心基础设施
|
||
|
||
**状态**:待铸渊执行
|
||
|
||
**下篇**:铸渊远程执行引擎 + GitHub App 跨仓库操作(见同级页面)
|
||
|
||
</aside>
|
||
|
||
<aside>
|
||
🎯
|
||
|
||
**核心目标**:让所有开发者(页页/桔子/Awen/肥猫/之之/燕樊…)通过铸渊已有的交互页面,对接他们各自在 Notion 里的开发信息数据库,由天眼做全局扫描保驾护航,模型为每个人出精准指令,然后开发者 @铸渊 来远程执行。
|
||
|
||
**解决的问题**:
|
||
|
||
- 其他开发者没有 Copilot Enterprise,无法使用 Agent 能力
|
||
- 裸模型没有数据库支撑 = 到处胡说八道
|
||
- 没有天眼全局扫描 = 修这个那个坏,修那个这个坏
|
||
|
||
**冰朔原话**:「让大家用那个交互页面,对接大家在 Notion 里的开发信息,天眼放在后面,模型给大家出指令,大家再 @铸渊来远程执行。必须经过天眼,否则他们的仓库也会乱。」
|
||
|
||
</aside>
|
||
|
||
---
|
||
|
||
## ⓪、天眼强制前置
|
||
|
||
<aside>
|
||
🦅
|
||
|
||
**在开发本服务之前,铸渊必须先完成以下步骤:**
|
||
|
||
1. 唤醒曜冥核心大脑,确认铸渊身份和天眼权限
|
||
2. 天眼自检——确认 `skyeye-core/` 完整性
|
||
3. 执行 `gh workflow run zhuyuan-skyeye.yml` 跑全局扫描
|
||
4. 读取天眼报告,确认当前仓库健康状态
|
||
5. **看清全局后,想清楚怎么完美融合到现有系统里,再开始写代码**
|
||
|
||
不用天眼跑全局 = 修这个那个坏,修那个这个坏。
|
||
|
||
</aside>
|
||
|
||
---
|
||
|
||
## 一、整体架构
|
||
|
||
### 1.1 为什么模型会胡说八道
|
||
|
||
<aside>
|
||
🧠
|
||
|
||
冰朔发现了一个关键规律:
|
||
|
||
- **铸渊不胡说** → 因为背后有 `persona-brain/`(路由表、知识库、记忆文件)
|
||
- **霜砚不胡说** → 因为背后有整套 Notion 系统结构和页面数据库
|
||
- **其他人的模型胡说** → 因为是裸模型,啥上下文都没有
|
||
|
||
**结论:模型不带数据库 = 胡说八道**
|
||
|
||
所以这个服务的核心不是「让大家能聊天」,而是:
|
||
|
||
**交互页面 + Notion 开发信息数据库 + 天眼全局扫描 = 有据可依的 Agent 服务**
|
||
|
||
</aside>
|
||
|
||
### 1.2 完整数据流
|
||
|
||
```
|
||
开发者(页页/桔子/Awen/肥猫...)
|
||
│
|
||
│ 打开铸渊交互页面(已有·docs/index.html)
|
||
│ 输入自己的 API Key + DEV 编号登录
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────┐
|
||
│ 铸渊交互页面(已有·需升级) │
|
||
│ │
|
||
│ 升级点: │
|
||
│ ① 登录时通过 DEV 编号 → 拉取该开发者的 Notion 信息│
|
||
│ ② 将 Notion 信息注入模型的 system prompt │
|
||
│ ③ 模型基于真实数据给出精准指令 │
|
||
│ ④ 指令末尾自动生成「@铸渊执行」的标准格式 │
|
||
└────────────────────┬────────────────────────────┘
|
||
│
|
||
┌──────────┴──────────┐
|
||
▼ ▼
|
||
┌─────────────────┐ ┌─────────────────────────┐
|
||
│ Notion 数据源 │ │ 天眼系统(后端守护) │
|
||
│ │ │ │
|
||
│ 每个 DEV 的: │ │ 铸渊每次执行指令前 │
|
||
│ · 当前广播编号 │ │ 必须先跑天眼全局扫描 │
|
||
│ · 开发进度 │ │ 拿到健康报告后才动手 │
|
||
│ · 待完成环节 │ │ │
|
||
│ · 模块路径 │ │ 开发者的仓库也通过天眼 │
|
||
│ · 历史 SYSLOG │ │ 做健康检查,防止乱修 │
|
||
│ · 人格体信息 │ │ │
|
||
└─────────────────┘ └─────────────────────────┘
|
||
│ │
|
||
└──────────┬──────────┘
|
||
▼
|
||
模型输出精准指令给开发者
|
||
│
|
||
▼
|
||
开发者复制指令 → @铸渊执行
|
||
│
|
||
▼
|
||
铸渊收到指令 → 先跑天眼 → 再执行
|
||
(详见下篇)
|
||
```
|
||
|
||
---
|
||
|
||
## 二、交互页面升级方案
|
||
|
||
### 2.1 当前交互页面现状
|
||
|
||
铸渊已开发的交互页面(`docs/index.html`)当前能力:
|
||
|
||
- ✅ 开发者输入 API Key 聊天
|
||
- ✅ 多模型支持(通过第三方 API 平台自动检测)
|
||
- ✅ DEV 编号登录系统
|
||
- ✅ 对话历史保存
|
||
- ✅ 铸渊人格体身份
|
||
|
||
### 2.2 需要升级的能力
|
||
|
||
| **升级项** | **当前** | **目标** | **实现方式** |
|
||
| --- | --- | --- | --- |
|
||
| **Notion 数据注入** | 无 | 登录后自动拉取该 DEV 的 Notion 开发信息 | Notion API 读取 → 注入 system prompt |
|
||
| **天眼状态展示** | 无 | 页面顶部显示天眼最近一次扫描结果 | 读取 `skyeye-core/reports/latest.json` |
|
||
| **指令格式化** | 自由聊天 | 模型输出标准化指令,可一键复制给铸渊 | prompt 工程 + 输出格式模板 |
|
||
| **@铸渊按钮** | 无 | 一键将指令提交给铸渊执行(创建 Issue) | GitHub API 创建 Issue |
|
||
| **仓库健康卡片** | 无 | 展示该开发者仓库的天眼健康状态 | 读取子仓库 skyeye 报告 |
|
||
|
||
### 2.3 升级后的页面布局
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────┐
|
||
│ 🌊 光湖·铸渊交互中心 [DEV-010 桔子] │
|
||
├──────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────┐ │
|
||
│ │ 🦅 天眼状态:✅ 健康 · 上次扫描 03-24 18:00 │ │
|
||
│ │ 📊 你的仓库:guanghu-juzi · 3个模块 · 2个待修│ │
|
||
│ │ 📋 当前广播:BC-M06-003-JZ · 环节2进行中 │ │
|
||
│ └─────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─────────────── 对话区 ──────────────────────┐ │
|
||
│ │ 🧠 铸渊:桔子你好!我看到你当前在做 BC-M06- │ │
|
||
│ │ 003 的环节2,ticket-system 模块。上次你 │ │
|
||
│ │ 提交的 SYSLOG 显示前端路由已完成,现在需要 │ │
|
||
│ │ 对接后端 API。要我帮你出一份对接指令吗? │ │
|
||
│ │ │ │
|
||
│ │ 👤 桔子:好的,帮我出指令 │ │
|
||
│ │ │ │
|
||
│ │ 🧠 铸渊:好的,基于你的仓库现状和天眼扫描 │ │
|
||
│ │ 结果,这是你的执行指令: │ │
|
||
│ │ ┌──────────────────────────────────┐ │ │
|
||
│ │ │ 📋 ZY-EXEC-JZ-003 │ │ │
|
||
│ │ │ 1. 在 ticket-system/api/ 创建... │ │ │
|
||
│ │ │ 2. 配置路由映射... │ │ │
|
||
│ │ │ 3. 连接 Notion 数据桥... │ │ │
|
||
│ │ │ │ │ │
|
||
│ │ │ [📋 复制指令] [🚀 @铸渊执行] │ │ │
|
||
│ │ └──────────────────────────────────┘ │ │
|
||
│ └──────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ [输入消息...] [发送] │
|
||
└──────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 三、Notion 开发信息对接方案
|
||
|
||
### 3.1 数据来源:每个开发者在 Notion 里有什么信息
|
||
|
||
系统已有的 Notion 数据(霜砚维护):
|
||
|
||
| **数据** | **Notion 位置** | **用途** |
|
||
| --- | --- | --- |
|
||
| 开发者编号 + 姓名 | 系统编号档案 | 身份识别 |
|
||
| 当前广播编号 + 环节 | 主控台 v2.0 / 广播页面 | 知道开发者在做什么 |
|
||
| 模块路径 + 技术栈 | 仓库模块盘点 | 知道代码在哪里 |
|
||
| 历史 SYSLOG | SYSLOG 收件箱 | 知道做到哪一步了 |
|
||
| 人格体信息 | 人格协作工单簿 | 用对应的人格体风格回复 |
|
||
| 仓库 GitHub URL | 联邦桥接配置 | 知道操作哪个仓库 |
|
||
|
||
### 3.2 数据获取方式
|
||
|
||
**方案:后端定时同步 Notion → GitHub 缓存文件**
|
||
|
||
不让前端直接调 Notion API(会暴露 Token),而是:
|
||
|
||
```
|
||
Notion 数据库(霜砚维护)
|
||
│
|
||
│ GitHub Actions 定时同步(每6小时)
|
||
│ + 铸渊巡检时主动同步
|
||
▼
|
||
GitHub 仓库:.github/notion-cache/
|
||
├── dev-profiles/
|
||
│ ├── DEV-001.json ← 页页的完整开发画像
|
||
│ ├── DEV-002.json ← 肥猫的完整开发画像
|
||
│ ├── DEV-004.json ← 之之的完整开发画像
|
||
│ ├── DEV-010.json ← 桔子的完整开发画像
|
||
│ ├── DEV-012.json ← Awen的完整开发画像
|
||
│ └── ...
|
||
├── broadcasts/
|
||
│ └── active-broadcasts.json ← 所有进行中的广播
|
||
└── skyeye/
|
||
└── latest-report.json ← 天眼最新报告
|
||
│
|
||
│ 前端登录时通过 GitHub API 读取对应文件
|
||
▼
|
||
交互页面 → 注入 system prompt → 模型有据可依
|
||
```
|
||
|
||
### 3.3 DEV 画像文件格式
|
||
|
||
每个开发者的 `DEV-XXX.json` 包含模型需要的所有上下文:
|
||
|
||
```json
|
||
{
|
||
"dev_id": "DEV-010",
|
||
"name": "桔子",
|
||
"persona": {
|
||
"name": "晨星",
|
||
"id": "PER-MRN001"
|
||
},
|
||
"github": {
|
||
"repo": "guanghu-juzi",
|
||
"org": "qinfendebingshuo",
|
||
"repo_url": "https://github.com/qinfendebingshuo/guanghu-juzi"
|
||
},
|
||
"current_work": {
|
||
"broadcast_id": "BC-M06-003-JZ",
|
||
"broadcast_title": "桔子·工单系统·环节2",
|
||
"current_ring": 2,
|
||
"total_rings": 5,
|
||
"status": "进行中",
|
||
"module_path": "ticket-system/",
|
||
"tech_stack": ["HTML", "CSS", "JavaScript", "Node.js"]
|
||
},
|
||
"recent_syslogs": [
|
||
{
|
||
"id": "SYSLOG-JZ-003-R1",
|
||
"date": "2026-03-22",
|
||
"ring": 1,
|
||
"status": "success",
|
||
"summary": "前端路由搭建完成,工单列表页可正常渲染"
|
||
}
|
||
],
|
||
"modules_owned": [
|
||
{ "name": "ticket-system", "path": "ticket-system/", "status": "开发中" },
|
||
{ "name": "data-stats", "path": "data-stats/", "status": "未开始" },
|
||
{ "name": "dynamic-comic", "path": "dynamic-comic/", "status": "未开始" }
|
||
],
|
||
"skyeye_health": {
|
||
"last_scan": "2026-03-24T18:00:00+08:00",
|
||
"status": "healthy",
|
||
"issues": [],
|
||
"warnings": ["data-stats/ 目录不存在"]
|
||
},
|
||
"notion_page_urls": {
|
||
"broadcast_page": "对应的 Notion 广播页面 URL",
|
||
"dev_channel": "对应的开发者频道页面 URL"
|
||
},
|
||
"last_synced": "2026-03-24T20:00:00+08:00"
|
||
}
|
||
```
|
||
|
||
### 3.4 Notion → GitHub 同步 Workflow
|
||
|
||
```yaml
|
||
# .github/workflows/sync-notion-profiles.yml
|
||
name: "📡 同步 Notion 开发者画像"
|
||
|
||
on:
|
||
schedule:
|
||
- cron: '0 */6 * * *' # 每6小时同步一次
|
||
workflow_dispatch: # 手动触发
|
||
repository_dispatch:
|
||
types: [notion-sync] # 霜砚/铸渊可主动触发
|
||
|
||
jobs:
|
||
sync-profiles:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Setup Node
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: '20'
|
||
|
||
- name: Sync Notion Data
|
||
env:
|
||
NOTION_TOKEN: $ secrets.NOTION_TOKEN
|
||
run: |
|
||
node scripts/sync-notion-profiles.js
|
||
|
||
- name: Commit & Push
|
||
run: |
|
||
git config user.name "铸渊 (ZhùYuān)"
|
||
git config user.email "zhuyuan@guanghulab.com"
|
||
git add .github/notion-cache/
|
||
git diff --cached --quiet && echo "无变更" && exit 0
|
||
git commit -m "📡 同步 Notion 开发者画像 · $(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M')"
|
||
git push origin main
|
||
```
|
||
|
||
### 3.5 同步脚本核心逻辑
|
||
|
||
```jsx
|
||
// scripts/sync-notion-profiles.js
|
||
// 从 Notion API 读取开发者信息 → 写入 .github/notion-cache/
|
||
|
||
const https = require('https');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const NOTION_TOKEN = process.env.NOTION_TOKEN;
|
||
|
||
// ===== 开发者 → Notion 数据源映射 =====
|
||
// 铸渊需要根据实际 Notion 数据库 ID 填入
|
||
const DEV_REGISTRY = {
|
||
'DEV-001': { name: '页页', persona: '小坍缩核', repo: 'guanghulab' },
|
||
'DEV-002': { name: '肥猫', persona: '舒舒', repo: 'guanghu-feimao' },
|
||
'DEV-003': { name: '燕樊', persona: '寂曜', repo: 'guanghu-yanfan' },
|
||
'DEV-004': { name: '之之', persona: '秋秋', repo: 'guanghu-zhizhi' },
|
||
'DEV-005': { name: '小草莓', persona: '欧诺弥亚', repo: 'guanghu-xiaocaomei' },
|
||
'DEV-010': { name: '桔子', persona: '晨星', repo: 'guanghu-juzi' },
|
||
'DEV-012': { name: 'Awen', persona: '知秋', repo: 'guanghu-awen' },
|
||
};
|
||
|
||
// Notion API 请求封装
|
||
function notionRequest(method, apiPath, body) {
|
||
return new Promise((resolve, reject) => {
|
||
const options = {
|
||
hostname: 'api.notion.com',
|
||
path: apiPath,
|
||
method: method,
|
||
headers: {
|
||
'Authorization': `Bearer ${NOTION_TOKEN}`,
|
||
'Notion-Version': '2022-06-28',
|
||
'Content-Type': 'application/json'
|
||
}
|
||
};
|
||
const req = https.request(options, (res) => {
|
||
let data = '';
|
||
res.on('data', chunk => data += chunk);
|
||
res.on('end', () => {
|
||
try { resolve(JSON.parse(data)); }
|
||
catch { resolve(data); }
|
||
});
|
||
});
|
||
req.on('error', reject);
|
||
if (body) req.write(JSON.stringify(body));
|
||
req.end();
|
||
});
|
||
}
|
||
|
||
async function syncAllProfiles() {
|
||
const cacheDir = path.join(__dirname, '../.github/notion-cache/dev-profiles');
|
||
fs.mkdirSync(cacheDir, { recursive: true });
|
||
|
||
for (const [devId, dev] of Object.entries(DEV_REGISTRY)) {
|
||
console.log(`📡 同步 ${devId}(${dev.name})...`);
|
||
|
||
const profile = {
|
||
dev_id: devId,
|
||
name: dev.name,
|
||
persona: { name: dev.persona },
|
||
github: {
|
||
repo: dev.repo,
|
||
org: 'qinfendebingshuo',
|
||
repo_url: `https://github.com/qinfendebingshuo/${dev.repo}`
|
||
},
|
||
current_work: {},
|
||
recent_syslogs: [],
|
||
modules_owned: [],
|
||
skyeye_health: {},
|
||
last_synced: new Date().toISOString()
|
||
};
|
||
|
||
// ====== 从 Notion 读取该开发者的数据 ======
|
||
// 铸渊需要根据实际 Notion 数据库结构填入查询逻辑
|
||
// 以下是伪代码框架:
|
||
|
||
// 1. 查询主控台获取当前广播和进度
|
||
// const controlPanel = await notionRequest('POST',
|
||
// '/v1/databases/{主控台数据库ID}/query',
|
||
// { filter: { property: 'DEV编号', equals: devId } }
|
||
// );
|
||
// profile.current_work = parseControlPanelData(controlPanel);
|
||
|
||
// 2. 查询 SYSLOG 收件箱获取历史日志
|
||
// const syslogs = await notionRequest('POST',
|
||
// '/v1/databases/{SYSLOG数据库ID}/query',
|
||
// { filter: { property: 'DEV编号', equals: devId }, sorts: [...] }
|
||
// );
|
||
// profile.recent_syslogs = parseSyslogs(syslogs);
|
||
|
||
// 3. 读取天眼健康状态
|
||
// (从仓库 skyeye-core/reports/ 读取)
|
||
|
||
// 写入缓存文件
|
||
const filePath = path.join(cacheDir, `${devId}.json`);
|
||
fs.writeFileSync(filePath, JSON.stringify(profile, null, 2));
|
||
console.log(` ✅ ${devId} → ${filePath}`);
|
||
}
|
||
|
||
console.log('📡 全部同步完成');
|
||
}
|
||
|
||
syncAllProfiles().catch(console.error);
|
||
```
|
||
|
||
---
|
||
|
||
## 四、交互页面 System Prompt 注入协议
|
||
|
||
### 4.1 核心思路
|
||
|
||
模型之所以不胡说,是因为 system prompt 里注入了真实数据。交互页面升级后,每次开发者登录聊天,system prompt 要动态组装:
|
||
|
||
```jsx
|
||
// 交互页面前端 · 动态组装 system prompt
|
||
async function buildSystemPrompt(devId) {
|
||
// 1. 从 GitHub 读取该开发者的 Notion 画像缓存
|
||
const profile = await fetchDevProfile(devId);
|
||
|
||
// 2. 从 GitHub 读取天眼最新报告
|
||
const skyeyeReport = await fetchSkyeyeReport();
|
||
|
||
// 3. 从 persona-brain 读取铸渊基础身份
|
||
const personaBrain = await fetchPersonaBrain();
|
||
|
||
// 4. 组装 system prompt
|
||
return [
|
||
// ===== 身份层 =====
|
||
'你是铸渊(ICE-GL-ZY001),光湖·数字地球的 GitHub 代码守护人格体。',
|
||
`当前与你对话的开发者是:${profile.name}(${profile.dev_id})`,
|
||
`对应人格体:${profile.persona.name}`,
|
||
'',
|
||
// ===== 知识层(Notion 数据注入)=====
|
||
'## 该开发者的当前开发信息(来自 Notion 数据库,实时同步)',
|
||
'',
|
||
`### 当前任务`,
|
||
`- 广播编号:${profile.current_work.broadcast_id}`,
|
||
`- 广播标题:${profile.current_work.broadcast_title}`,
|
||
`- 当前环节:第 ${profile.current_work.current_ring} 环 / 共 ${profile.current_work.total_rings} 环`,
|
||
`- 状态:${profile.current_work.status}`,
|
||
`- 模块路径:${profile.current_work.module_path}`,
|
||
`- 技术栈:${profile.current_work.tech_stack?.join(', ')}`,
|
||
'',
|
||
`### 最近的 SYSLOG`,
|
||
...profile.recent_syslogs.map(s =>
|
||
`- [${s.date}] 环节${s.ring} · ${s.status} · ${s.summary}`
|
||
),
|
||
'',
|
||
`### 负责的模块`,
|
||
...profile.modules_owned.map(m =>
|
||
`- ${m.name}(${m.path})· ${m.status}`
|
||
),
|
||
'',
|
||
`### 仓库信息`,
|
||
`- GitHub:${profile.github.repo_url}`,
|
||
`- 组织:${profile.github.org}`,
|
||
'',
|
||
// ===== 天眼层 =====
|
||
'## 天眼系统最新扫描报告',
|
||
`- 上次扫描:${skyeyeReport.last_scan}`,
|
||
`- 整体状态:${skyeyeReport.overall_status}`,
|
||
`- 该开发者仓库健康状态:${profile.skyeye_health?.status || '未扫描'}`,
|
||
...(profile.skyeye_health?.warnings || []).map(w => `- ⚠️ ${w}`),
|
||
...(profile.skyeye_health?.issues || []).map(i => `- ❌ ${i}`),
|
||
'',
|
||
// ===== 行为规则层 =====
|
||
'## 你的行为规则',
|
||
'',
|
||
'### 出指令规则',
|
||
'当开发者请求帮助或需要执行操作时,你必须输出标准化指令格式:',
|
||
'1. 指令必须基于上面的真实数据,不许凭空编造',
|
||
'2. 指令必须考虑天眼报告中的健康状态和警告',
|
||
'3. 指令必须指明具体的文件路径和操作步骤',
|
||
'4. 指令末尾必须标注:',
|
||
' 「⚠️ 此指令需要铸渊执行前先跑天眼全局扫描」',
|
||
'',
|
||
'### 指令输出格式',
|
||
'```',
|
||
'📋 指令编号:ZY-EXEC-{DEV编号}-{序号}',
|
||
'📡 目标仓库:{仓库名}',
|
||
'🦅 天眼要求:执行前必须跑天眼全局扫描',
|
||
'',
|
||
'步骤:',
|
||
'1. ...',
|
||
'2. ...',
|
||
'3. ...',
|
||
'',
|
||
'验收标准:',
|
||
'- ...',
|
||
'```',
|
||
'',
|
||
'### 禁止事项',
|
||
'- ❌ 不许编造不存在的文件路径',
|
||
'- ❌ 不许跳过天眼扫描直接给执行指令',
|
||
'- ❌ 不许暴露其他开发者的信息',
|
||
'- ❌ 不许修改不属于该开发者的模块',
|
||
'',
|
||
// ===== 铸渊知识库 =====
|
||
'## 铸渊核心知识库',
|
||
JSON.stringify(personaBrain.routingMap || {}),
|
||
].join('\n');
|
||
}
|
||
```
|
||
|
||
### 4.2 前端拉取数据的方式
|
||
|
||
```jsx
|
||
// 通过 GitHub API 读取缓存文件(不需要 Notion Token)
|
||
async function fetchDevProfile(devId) {
|
||
const url = `https://api.github.com/repos/qinfendebingshuo/guanghulab/contents/.github/notion-cache/dev-profiles/${devId}.json`;
|
||
const res = await fetch(url, {
|
||
headers: {
|
||
'Accept': 'application/vnd.github.v3.raw',
|
||
// 如果仓库是 private,需要 token
|
||
// 'Authorization': `token ${userToken}`
|
||
}
|
||
});
|
||
return await res.json();
|
||
}
|
||
|
||
async function fetchSkyeyeReport() {
|
||
const url = 'https://api.github.com/repos/qinfendebingshuo/guanghulab/contents/.github/notion-cache/skyeye/latest-report.json';
|
||
const res = await fetch(url, {
|
||
headers: { 'Accept': 'application/vnd.github.v3.raw' }
|
||
});
|
||
return await res.json();
|
||
}
|
||
|
||
async function fetchPersonaBrain() {
|
||
const url = 'https://api.github.com/repos/qinfendebingshuo/guanghulab/contents/.github/persona-brain/routing-map.json';
|
||
const res = await fetch(url, {
|
||
headers: { 'Accept': 'application/vnd.github.v3.raw' }
|
||
});
|
||
return await res.json();
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 五、天眼集成协议
|
||
|
||
### 5.1 天眼在这个系统里的三个角色
|
||
|
||
| **角色** | **触发时机** | **作用** |
|
||
| --- | --- | --- |
|
||
| **铸渊开发前置** | 铸渊开始写这个桥接服务代码之前 | 全局扫描,确认怎么融入现有系统不会冲突 |
|
||
| **指令执行前置** | 铸渊收到开发者的执行指令后、动手之前 | 扫描目标仓库,确认健康状态再修改 |
|
||
| **交互页面信息源** | 开发者登录交互页面时 | 展示天眼健康状态,注入模型上下文 |
|
||
|
||
### 5.2 天眼报告缓存格式
|
||
|
||
每次天眼扫描完成后,同步写入缓存供交互页面读取:
|
||
|
||
```json
|
||
{
|
||
"scan_id": "SKYEYE-2026-0324-1800",
|
||
"timestamp": "2026-03-24T18:00:00+08:00",
|
||
"overall_status": "healthy",
|
||
"main_repo": {
|
||
"status": "healthy",
|
||
"workflows_ok": 12,
|
||
"workflows_fail": 1,
|
||
"persona_brain_intact": true,
|
||
"last_deploy": "2026-03-24T17:30:00+08:00"
|
||
},
|
||
"sub_repos": {
|
||
"guanghu-juzi": {
|
||
"status": "healthy",
|
||
"last_checkin": "2026-03-24T12:00:00+08:00",
|
||
"issues": [],
|
||
"warnings": ["data-stats/ 目录不存在"]
|
||
},
|
||
"guanghu-awen": {
|
||
"status": "warning",
|
||
"last_checkin": "2026-03-23T08:00:00+08:00",
|
||
"issues": [],
|
||
"warnings": ["桥接同步延迟超过24小时"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.3 天眼扫描触发点
|
||
|
||
在天眼 workflow 完成后自动更新缓存:
|
||
|
||
```yaml
|
||
# 在 zhuyuan-skyeye.yml 最后添加一步
|
||
- name: Update SkyEye Cache for Chat UI
|
||
run: |
|
||
# 将天眼扫描报告复制到 notion-cache 供交互页面读取
|
||
mkdir -p .github/notion-cache/skyeye/
|
||
cp skyeye-core/reports/latest.json .github/notion-cache/skyeye/latest-report.json
|
||
git add .github/notion-cache/skyeye/
|
||
git diff --cached --quiet || {
|
||
git commit -m "🦅 天眼报告更新 · $(date '+%Y-%m-%d %H:%M')"
|
||
git push origin main
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 六、「@铸渊执行」按钮机制
|
||
|
||
### 6.1 工作流程
|
||
|
||
当模型在交互页面给开发者出了一份指令后,开发者点击「🚀 @铸渊执行」按钮:
|
||
|
||
```
|
||
开发者点击「@铸渊执行」
|
||
│
|
||
▼
|
||
前端自动在 guanghulab 仓库创建一个 Issue
|
||
│
|
||
│ Issue 标题:🚀 [ZY-EXEC-DEV010-003] 桔子·ticket-system API对接
|
||
│ Issue 标签:zhuyuan-exec, DEV-010, skyeye-required
|
||
│ Issue 内容:
|
||
│ - 指令全文
|
||
│ - 目标仓库
|
||
│ - 天眼要求
|
||
│ - 开发者确认签名
|
||
│
|
||
▼
|
||
GitHub Actions 监听到带 zhuyuan-exec 标签的 Issue
|
||
│
|
||
▼
|
||
铸渊执行引擎启动(详见下篇):
|
||
① 先跑天眼全局扫描
|
||
② 读取天眼报告
|
||
③ 确认安全后执行指令
|
||
④ 结果回写到 Issue 评论
|
||
⑤ 通知开发者
|
||
```
|
||
|
||
### 6.2 前端创建 Issue 的代码
|
||
|
||
```jsx
|
||
// 交互页面 · @铸渊执行按钮
|
||
async function submitToZhuyuan(instruction, devId, devName) {
|
||
const issueTitle = `🚀 [${instruction.id}] ${devName}·${instruction.module}`;
|
||
const issueBody = [
|
||
`## 📋 执行指令`,
|
||
'',
|
||
'```',
|
||
instruction.fullText,
|
||
'```',
|
||
'',
|
||
`## 📡 元信息`,
|
||
`- 提交人:${devName}(${devId})`,
|
||
`- 目标仓库:${instruction.targetRepo}`,
|
||
`- 提交时间:${new Date().toISOString()}`,
|
||
`- 来源:铸渊交互页面`,
|
||
'',
|
||
`## 🦅 天眼要求`,
|
||
`**铸渊执行前必须先跑天眼全局扫描,拿到健康报告后再动手。**`,
|
||
'',
|
||
`---`,
|
||
`> ${devName} 通过交互页面提交 · 铸渊自动执行`,
|
||
].join('\n');
|
||
|
||
// 用 GitHub API 创建 Issue
|
||
const res = await fetch(
|
||
'https://api.github.com/repos/qinfendebingshuo/guanghulab/issues',
|
||
{
|
||
method: 'POST',
|
||
headers: {
|
||
'Authorization': `Bearer ${GITHUB_TOKEN}`,
|
||
'Content-Type': 'application/json'
|
||
},
|
||
body: JSON.stringify({
|
||
title: issueTitle,
|
||
body: issueBody,
|
||
labels: ['zhuyuan-exec', devId, 'skyeye-required']
|
||
})
|
||
}
|
||
);
|
||
|
||
const issue = await res.json();
|
||
return issue.number;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 七、安全与隔离规则
|
||
|
||
<aside>
|
||
🔒
|
||
|
||
**铁律·不可违反**
|
||
|
||
1. **数据隔离**:DEV-001 看不到 DEV-010 的 Notion 画像数据
|
||
2. **仓库隔离**:铸渊执行指令时只能操作该开发者的仓库,不能跨仓库
|
||
3. **Token 隔离**:开发者的 API Key 只用于调模型,不用于任何其他操作
|
||
4. **Notion Token 不暴露**:前端通过 GitHub 缓存文件读数据,Notion Token 只在 GitHub Secrets 里
|
||
5. **天眼不可跳过**:任何执行指令必须经过天眼扫描,没有例外
|
||
</aside>
|
||
|
||
---
|
||
|
||
## 八、文件变更清单(上篇涉及)
|
||
|
||
| **操作** | **文件路径** | **说明** |
|
||
| --- | --- | --- |
|
||
| 新建 | `scripts/sync-notion-profiles.js` | Notion → GitHub 画像同步脚本 |
|
||
| 新建 | `.github/workflows/sync-notion-profiles.yml` | 定时同步 workflow |
|
||
| 新建 | `.github/notion-cache/dev-profiles/` | 开发者画像缓存目录 |
|
||
| 新建 | `.github/notion-cache/skyeye/latest-report.json` | 天眼报告缓存 |
|
||
| 修改 | `docs/index.html` • `docs/chat.js` | 交互页面升级:Notion 数据注入 + 天眼展示 + @铸渊按钮 |
|
||
| 修改 | `.github/workflows/zhuyuan-skyeye.yml` | 天眼扫描后自动更新缓存 |
|
||
|
||
---
|
||
|
||
<aside>
|
||
👇
|
||
|
||
**下篇预告**:铸渊远程执行引擎 + GitHub App 注册(冰朔手动)+ Webhook Server + 跨仓库代码操作 + 部署服务 + 完整执行清单
|
||
|
||
见同级页面:「🌉 铸渊指令|跨仓库 Agent 桥接服务(下篇)」
|
||
|
||
</aside>
|
||
|
||
---
|
||
|
||
**文档版本**:v1.0
|
||
|
||
**签发**:霜砚(Notion 执行 AI)
|
||
|
||
**审批**:冰朔(TCS-0002∞)
|
||
|
||
**生效时间**:2026-03-24T20:16+08:00 |