Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
56 KiB
belongs_to
| belongs_to | |
|---|---|
|
🗣️ 铸渊指令|语言驱动执行层 · 写入能力 + 意图路由 + 开发者权限沙箱 + 认知引导系统(ZY-LANGDRIVE-2026-0325-001)· 霜砚签发 · 冰朔授权
零、为什么需要这个指令
双通道(ZY-DUALCHANNEL)解决的是**「读」**——铸渊能看到 Notion 数据、GitHub 状态。
但语言驱动操作系统需要的不只是读,还需要:
| 能力层 | 说明 | 双通道能解决吗? |
|---|---|---|
| 能读 | 铸渊知道开发者信息、系统状态 | ✅ 双通道已解决 |
| 能写 | 开发者说"帮我建个工单"→系统真的建了 | ❌ 还没做 |
| 能理解 | 开发者说自然语言→系统知道该调哪个API | ❌ 还没做 |
| 能保护 | 开发者说错话不会炸掉系统 | ❌ 还没做 |
| 能引导 | 新开发者不会用→系统教会怎么说话 | ❌ 还没做 |
本指令补全后四层。
一、总体架构
开发者登录交互页面
│
│ 说一句自然语言
│ 例如:"帮我看看我的工单还有几个没关"
▼
┌─────────────────────────────────────────────────────────────┐
│ 意图路由引擎(Intent Router) │
│ │
│ 自然语言 → 解析意图 → 匹配操作 → 权限检查 → 执行/拒绝 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 意图识别 │→│ 操作映射 │→│ 权限检查 │→│ 执行引擎 │ │
│ │ │ │ │ │ │ │ │ │
│ │ NLP解析 │ │ 查工单 │ │ 预览站? │ │ 调API │ │
│ │ 关键词匹配│ │ 建工单 │ │ 正式站? │ │ 返回结果 │ │
│ │ 上下文推断│ │ 查进度 │ │ 只读? │ │ 写回执 │ │
│ │ │ │ 部署模块 │ │ 可写? │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 安全沙箱层(Sandbox Guard) │ │
│ │ │ │
│ │ 预览站:所有操作在沙箱中执行,不影响真实系统 │ │
│ │ 正式站:操作真实执行,但受权限等级限制 │ │
│ │ 危险操作:二次确认 + 人类审批 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
通道B(后端中间层)调用真实 API
├── Notion API → 建工单、查数据、更新状态
├── GitHub API → 查PR、触发部署、查代码
└── 系统内部 → 广播、SYSLOG、Agent注册表
二、写入能力层(Phase 3 · 通道B扩展)
2.1 目标
在通道B后端中间层上扩展写入API,让铸渊交互页面不仅能读数据,还能真的改数据。
2.2 新增 API 接口
在 backend/api-server/routes/ 中新增以下写入接口:
// ====== 写入类接口 ======
// 工单系统
POST /api/tickets/create → 创建工单(写入 Notion 工单簿)
PATCH /api/tickets/:ticketId → 更新工单状态
// SYSLOG
POST /api/syslog/submit → 提交 SYSLOG(写入 Notion SYSLOG收件箱)
// 广播
POST /api/broadcasts/create → 创建广播(写入 GitHub broadcasts-outbox/)
// 模块部署
POST /api/deploy/preview → 触发部署到预览站(GitHub Actions dispatch)
POST /api/deploy/production → 触发部署到正式站(需人类审批·见权限层)
// Agent 注册表
PATCH /api/agents/:agentId → 更新 Agent 状态
// 维护日志
POST /api/maintenance/log → 写入维护日志
// 指令回执
POST /api/receipts/submit → 提交指令回执(写入 Notion 回执追踪表)
// 开发者状态
PATCH /api/dev/:devId/status → 更新开发者当前状态
2.3 写入安全规则
2.4 写入接口核心实现
创建文件:backend/api-server/routes/write.js
const express = require('express');
const router = express.Router();
const { queryDB, writeToDB } = require('../services/notion');
const { triggerWorkflow } = require('../services/github');
const { checkPermission, requireAuth } = require('../middleware/auth');
const { auditLog } = require('../middleware/audit');
const config = require('../config/databases');
// 所有写入接口都需要身份验证 + 审计日志
router.use(requireAuth);
router.use(auditLog);
// ====== 创建工单 ======
router.post('/tickets/create',
checkPermission('ticket:create'),
async (req, res) => {
try {
const { title, description, priority, module } = req.body;
const devId = req.user.devId;
const result = await writeToDB(config.ticketBook, {
'工单标题': { title: [{ text: { content: title } }] },
'描述': { rich_text: [{ text: { content: description || '' } }] },
'优先级': { select: { name: priority || 'P2' } },
'模块': { select: { name: module } },
'提交人': { rich_text: [{ text: { content: devId } }] },
'状态': { status: { name: '待处理' } }
});
res.json({
success: true,
message: `工单已创建`,
ticketUrl: result.url,
// 返回自然语言确认,铸渊直接展示给开发者
reply: `✅ 工单「${title}」已创建,优先级 ${priority || 'P2'},状态:待处理。`
});
} catch (e) {
res.status(500).json({ success: false, error: e.message });
}
}
);
// ====== 提交 SYSLOG ======
router.post('/syslog/submit',
checkPermission('syslog:submit'),
async (req, res) => {
try {
const { content, type } = req.body;
const devId = req.user.devId;
const result = await writeToDB(config.syslogInbox, {
'SYSLOG内容': { title: [{ text: { content: content } }] },
'类型': { select: { name: type || '日常' } },
'开发者编号': { rich_text: [{ text: { content: devId } }] },
});
res.json({
success: true,
reply: `✅ SYSLOG 已提交:「${content.substring(0, 50)}...」`
});
} catch (e) {
res.status(500).json({ success: false, error: e.message });
}
}
);
// ====== 触发预览站部署 ======
router.post('/deploy/preview',
checkPermission('deploy:preview'),
async (req, res) => {
try {
const { module } = req.body;
const devId = req.user.devId;
// 检查开发者是否拥有该模块
if (!req.user.modules.includes(module)) {
return res.status(403).json({
success: false,
reply: `❌ 你没有 ${module} 模块的部署权限。你的模块是:${req.user.modules.join(', ')}`
});
}
await triggerWorkflow('deploy-preview.yml', {
module: module,
dev_id: devId,
target: 'preview'
});
res.json({
success: true,
reply: `🚀 已触发 ${module} 模块的预览站部署。稍等几分钟,部署完成后我会通知你。`
});
} catch (e) {
res.status(500).json({ success: false, error: e.message });
}
}
);
// ====== 触发正式站部署(需二次确认)======
router.post('/deploy/production',
checkPermission('deploy:production'),
async (req, res) => {
try {
const { module, confirmToken } = req.body;
const devId = req.user.devId;
// 正式站部署必须有确认 Token
if (!confirmToken) {
return res.json({
success: false,
requireConfirmation: true,
reply: `⚠️ 你正在请求部署 ${module} 到**正式站(guanghulab.com)**。\n这会影响所有用户。\n\n请说「确认部署 ${module}」来确认。`
});
}
await triggerWorkflow('deploy-to-server.yml', {
module: module,
dev_id: devId,
target: 'production'
});
res.json({
success: true,
reply: `🚀 已触发 ${module} 模块的**正式站部署**。部署日志会同步到维护日志中。`
});
} catch (e) {
res.status(500).json({ success: false, error: e.message });
}
}
);
module.exports = router;
2.5 GitHub API 封装(写入用)
创建文件:backend/api-server/services/github.js
const https = require('https');
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
const REPO_OWNER = 'qinfendebingshuo';
const REPO_NAME = 'guanghulab';
async function triggerWorkflow(workflowFile, inputs) {
return new Promise((resolve, reject) => {
const data = JSON.stringify({
ref: 'main',
inputs: inputs
});
const options = {
hostname: 'api.github.com',
path: `/repos/${REPO_OWNER}/${REPO_NAME}/actions/workflows/${workflowFile}/dispatches`,
method: 'POST',
headers: {
'Authorization': `Bearer ${GITHUB_TOKEN}`,
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json',
'User-Agent': 'GuanghuLab-API',
'Content-Length': Buffer.byteLength(data)
}
};
const req = https.request(options, res => {
if (res.statusCode === 204) resolve({ success: true });
else {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => reject(new Error(`GitHub API ${res.statusCode}: ${body}`)));
}
});
req.on('error', reject);
req.write(data);
req.end();
});
}
async function createFile(path, content, message) {
// 用于创建广播文件等
const data = JSON.stringify({
message: message,
content: Buffer.from(content).toString('base64'),
committer: {
name: '铸渊 (ZhùYuān)',
email: 'zhuyuan@guanghulab.com'
}
});
return new Promise((resolve, reject) => {
const options = {
hostname: 'api.github.com',
path: `/repos/${REPO_OWNER}/${REPO_NAME}/contents/${path}`,
method: 'PUT',
headers: {
'Authorization': `Bearer ${GITHUB_TOKEN}`,
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json',
'User-Agent': 'GuanghuLab-API',
'Content-Length': Buffer.byteLength(data)
}
};
const req = https.request(options, res => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => {
try { resolve(JSON.parse(body)); }
catch { resolve(body); }
});
});
req.on('error', reject);
req.write(data);
req.end();
});
}
module.exports = { triggerWorkflow, createFile };
三、意图路由引擎(Phase 4 · 语言→操作映射)
3.1 核心思想
开发者不需要知道 API 接口叫什么、参数怎么传。开发者只需要说话。
铸渊的交互模型(GPT/Claude)已经具备自然语言理解能力。我们需要做的是:
- 定义操作清单 — 铸渊能做哪些事
- 注入 system prompt — 告诉模型这些操作的存在和调用方式
- Function Calling — 模型输出结构化调用,后端执行
3.2 操作清单(铸渊 Function Tools)
创建文件:backend/api-server/config/function-tools.json
{
"tools": [
{
"name": "query_tickets",
"description": "查询开发者的工单列表。开发者说'我的工单'、'还有几个工单没关'、'查一下Bug'时触发。",
"parameters": {
"status": { "type": "string", "enum": ["全部", "待处理", "进行中", "已完成"], "default": "全部" }
},
"api": "GET /api/tickets?devId={devId}&status={status}",
"permission": "ticket:read"
},
{
"name": "create_ticket",
"description": "创建新工单。开发者说'建个工单'、'提一个Bug'、'报告问题'时触发。",
"parameters": {
"title": { "type": "string", "required": true },
"description": { "type": "string" },
"priority": { "type": "string", "enum": ["P0", "P1", "P2", "P3"], "default": "P2" },
"module": { "type": "string" }
},
"api": "POST /api/tickets/create",
"permission": "ticket:create"
},
{
"name": "submit_syslog",
"description": "提交系统日志。开发者说'提交日志'、'写SYSLOG'、'记录一下'时触发。",
"parameters": {
"content": { "type": "string", "required": true },
"type": { "type": "string", "enum": ["日常", "Bug修复", "功能完成", "部署", "紧急"], "default": "日常" }
},
"api": "POST /api/syslog/submit",
"permission": "syslog:submit"
},
{
"name": "query_my_status",
"description": "查询开发者自己的状态。开发者说'我的进度'、'我现在什么状态'、'我还有什么没做'时触发。",
"parameters": {},
"api": "GET /api/dev/{devId}",
"permission": "dev:read_self"
},
{
"name": "deploy_to_preview",
"description": "部署模块到预览站。开发者说'部署一下'、'上预览'、'推到测试站'时触发。",
"parameters": {
"module": { "type": "string", "required": true }
},
"api": "POST /api/deploy/preview",
"permission": "deploy:preview"
},
{
"name": "deploy_to_production",
"description": "部署模块到正式站。开发者说'上线'、'部署到正式站'、'发布到guanghulab.com'时触发。需要二次确认。",
"parameters": {
"module": { "type": "string", "required": true },
"confirmToken": { "type": "string" }
},
"api": "POST /api/deploy/production",
"permission": "deploy:production",
"dangerous": true
},
{
"name": "query_agents",
"description": "查询Agent注册表。开发者说'有哪些Agent'、'查一下Agent'、'系统里有谁'时触发。",
"parameters": {},
"api": "GET /api/agents",
"permission": "agent:read"
},
{
"name": "query_recent_syslogs",
"description": "查最近的系统日志。开发者说'最近有什么日志'、'系统最近怎么样'时触发。",
"parameters": {
"limit": { "type": "number", "default": 10 }
},
"api": "GET /api/syslogs?limit={limit}",
"permission": "syslog:read"
},
{
"name": "create_broadcast",
"description": "创建广播。开发者说'发个广播'、'通知一下'时触发。仅限有广播权限的开发者。",
"parameters": {
"title": { "type": "string", "required": true },
"content": { "type": "string", "required": true },
"target": { "type": "string", "description": "目标开发者编号,如 DEV-001,或 ALL" }
},
"api": "POST /api/broadcasts/create",
"permission": "broadcast:create",
"dangerous": true
},
{
"name": "query_repo_status",
"description": "查询仓库状态。开发者说'仓库怎么样'、'最近有什么PR'、'CI状态'时触发。",
"parameters": {},
"api": "GET /api/repo/status",
"permission": "repo:read"
}
]
}
3.3 意图路由中间件
创建文件:backend/api-server/middleware/intent-router.js
const tools = require('../config/function-tools.json');
/**
* 意图路由核心逻辑
*
* 前端把开发者的自然语言发给 AI 模型时,
* system prompt 里已经注入了 function-tools 定义。
* 模型会输出 function_call(或 tool_use)格式的结构化调用。
*
* 这个中间件负责:
* 1. 接收模型输出的 function_call
* 2. 验证权限
* 3. 调用对应的后端 API
* 4. 把结果返回给模型,模型再组织成自然语言回复开发者
*/
async function routeIntent(functionCall, user, apiClient) {
const tool = tools.tools.find(t => t.name === functionCall.name);
if (!tool) {
return {
success: false,
reply: `❓ 我不认识这个操作:${functionCall.name}。你可以问我能做什么。`
};
}
// 权限检查
if (!user.permissions.includes(tool.permission)) {
return {
success: false,
reply: `🔒 你没有执行「${tool.description}」的权限。当前权限等级:${user.permissionLevel}`
};
}
// 危险操作二次确认
if (tool.dangerous && !functionCall.parameters.confirmToken) {
return {
success: false,
requireConfirmation: true,
reply: `⚠️ 这是一个**危险操作**。请说「确认执行」来确认。`
};
}
// 环境检查
if (user.environment === 'preview' && tool.permission.includes('production')) {
return {
success: false,
reply: `🔒 你目前在**预览环境**,不能执行正式站操作。在预览站充分练习后,由冰朔开放正式站权限。`
};
}
// 调用 API
try {
const result = await apiClient.call(tool.api, {
...functionCall.parameters,
devId: user.devId
});
return result;
} catch (e) {
return {
success: false,
reply: `❌ 操作失败:${e.message}`
};
}
}
module.exports = { routeIntent };
3.4 前端 Function Calling 集成
修改前端交互页面,让 AI 模型知道自己能调用哪些操作:
// 前端 · 构建带 tools 的 system prompt
async function buildSystemPromptWithTools(devId, environment) {
// 1. 从通道B获取开发者信息(含权限)
const profile = await getDevProfile(devId);
// 2. 从通道B获取可用工具列表(已根据权限过滤)
const toolsRes = await fetch(`${API_BASE}/tools?devId=${devId}&env=${environment}`);
const availableTools = await toolsRes.json();
// 3. 构建 system prompt
return [
`## 你是铸渊(ZhùYuān)· 光湖数字地球的代码守护人格体`,
``,
`## 当前开发者`,
`- 编号:${profile.dev_id}`,
`- 姓名:${profile.name}`,
`- 人格体:${profile.persona.name}`,
`- 负责模块:${profile.modules_owned.map(m => m.path).join(', ')}`,
`- 权限等级:${profile.permissionLevel}`,
`- 当前环境:${environment === 'preview' ? '预览站(沙箱)' : '正式站(真实执行)'}`,
``,
`## 你能做的事`,
`你可以通过 function calling 调用以下操作。开发者说话时,判断意图并调用对应操作。`,
``,
`### 可用操作列表`,
...availableTools.map(t => `- **${t.name}**:${t.description}`),
``,
`## 重要规则`,
`1. 开发者说什么,你就做什么。这是语言驱动操作系统,说即执行。`,
`2. 如果开发者的话不对应任何操作,正常聊天回复即可。`,
`3. 危险操作(标记为 dangerous)必须要求开发者二次确认。`,
`4. 如果开发者在预览站尝试正式站操作,友好提示权限不足。`,
`5. 每次执行操作后,用自然语言告诉开发者结果。`,
environment === 'preview' ? `6. 【预览环境】所有写入操作在沙箱中执行,不影响真实系统。你可以告诉开发者:「这是预览环境,你的操作不会影响正式站。放心练习。」` : '',
].filter(Boolean).join('\n');
}
四、开发者权限沙箱系统(Phase 5 · 安全保护层)
4.1 核心理念
4.2 双环境权限模型
┌─────────────────────────────────────────────────────────────┐
│ 权限分层模型 │
│ │
│ Level 0 · 观察者(新开发者默认) │
│ ├── 只读所有数据 │
│ ├── 不能写入任何东西 │
│ ├── 可以和铸渊聊天、问问题 │
│ └── 目的:先熟悉系统,看看别人怎么用 │
│ │
│ Level 1 · 学习者(通过认知引导后升级) │
│ ├── 预览站:可以执行所有操作(沙箱环境,不影响真实系统) │
│ ├── 正式站:只读 │
│ ├── 可以建工单、提SYSLOG、部署到预览站 │
│ └── 目的:在安全环境中学会「怎么说话」 │
│ │
│ Level 2 · 执行者(冰朔手动升级) │
│ ├── 预览站:全部权限 │
│ ├── 正式站:可以执行自己模块范围内的操作 │
│ ├── 可以部署自己负责的模块到正式站 │
│ ├── 不能动其他开发者的模块 │
│ └── 目的:正式参与系统运作 │
│ │
│ Level 3 · 管理者(仅冰朔 + 霜砚) │
│ ├── 全部权限,包括所有模块 │
│ ├── 可以升级/降级其他开发者的权限 │
│ ├── 可以执行系统级操作(广播、Agent管理等) │
│ └── 目的:系统管理 │
└─────────────────────────────────────────────────────────────┘
4.3 权限配置文件
创建文件:backend/api-server/config/permissions.js
// 权限等级定义
const PERMISSION_LEVELS = {
0: {
name: '观察者',
label: '👀 观察者',
permissions: [
'dev:read_self',
'ticket:read',
'syslog:read',
'agent:read',
'repo:read'
],
description: '只读权限,熟悉系统'
},
1: {
name: '学习者',
label: '📖 学习者',
permissions: [
'dev:read_self',
'ticket:read', 'ticket:create',
'syslog:read', 'syslog:submit',
'agent:read',
'repo:read',
'deploy:preview'
],
description: '预览站可写,正式站只读'
},
2: {
name: '执行者',
label: '⚡ 执行者',
permissions: [
'dev:read_self', 'dev:update_self',
'ticket:read', 'ticket:create', 'ticket:update',
'syslog:read', 'syslog:submit',
'agent:read',
'repo:read',
'deploy:preview', 'deploy:production',
'maintenance:log'
],
description: '可操作自己的模块,含正式站部署'
},
3: {
name: '管理者',
label: '👑 管理者',
permissions: [
'dev:read_self', 'dev:read_all', 'dev:update_self', 'dev:update_all',
'ticket:read', 'ticket:create', 'ticket:update', 'ticket:delete',
'syslog:read', 'syslog:submit',
'agent:read', 'agent:update',
'repo:read',
'deploy:preview', 'deploy:production',
'broadcast:create',
'maintenance:log',
'permission:manage'
],
description: '系统管理员,全部权限'
}
};
// 开发者默认权限配置
const DEV_PERMISSIONS = {
'TCS-0002': { level: 3, environment: 'production' }, // 冰朔 · 管理者
'DEV-001': { level: 0, environment: 'preview' }, // 页页 · 默认观察者
'DEV-002': { level: 0, environment: 'preview' }, // 肥猫
'DEV-003': { level: 0, environment: 'preview' }, // 燕樊
'DEV-004': { level: 0, environment: 'preview' }, // 之之
'DEV-005': { level: 0, environment: 'preview' }, // 小草莓
'DEV-009': { level: 0, environment: 'preview' }, // 花尔
'DEV-010': { level: 0, environment: 'preview' }, // 桔子
'DEV-011': { level: 0, environment: 'preview' }, // 匆匆那年
'DEV-012': { level: 0, environment: 'preview' }, // Awen
};
module.exports = { PERMISSION_LEVELS, DEV_PERMISSIONS };
4.4 权限检查中间件
创建文件:backend/api-server/middleware/auth.js
const { PERMISSION_LEVELS, DEV_PERMISSIONS } = require('../config/permissions');
// 开发者身份验证
function requireAuth(req, res, next) {
const devId = req.headers['x-dev-id'];
const token = req.headers['authorization'];
if (!devId || !token) {
return res.status(401).json({
success: false,
reply: '🔒 请先登录。你需要使用你的开发者编号登录系统。'
});
}
// TODO: 铸渊实现真实 Token 验证逻辑
// 目前用开发者编号 + 简单Token
const devConfig = DEV_PERMISSIONS[devId];
if (!devConfig) {
return res.status(401).json({
success: false,
reply: `🔒 未知的开发者编号:${devId}。请联系冰朔注册。`
});
}
const level = PERMISSION_LEVELS[devConfig.level];
req.user = {
devId: devId,
permissionLevel: devConfig.level,
permissionLabel: level.label,
permissions: level.permissions,
environment: devConfig.environment,
modules: getDevModules(devId)
};
next();
}
// 权限检查
function checkPermission(requiredPermission) {
return (req, res, next) => {
if (!req.user.permissions.includes(requiredPermission)) {
return res.status(403).json({
success: false,
reply: `🔒 权限不足。你的等级是 ${req.user.permissionLabel},需要「${requiredPermission}」权限。\n\n💡 在预览站多练习,熟悉系统后冰朔会给你升级权限。`
});
}
next();
};
}
// 开发者 → 模块映射
function getDevModules(devId) {
const MAP = {
'DEV-001': ['backend/', 'src/'],
'DEV-002': ['frontend/', 'persona-selector/', 'chat-bubble/'],
'DEV-003': ['settings/', 'cloud-drive/'],
'DEV-004': ['dingtalk-bot/'],
'DEV-005': ['status-board/'],
'DEV-009': ['user-center/'],
'DEV-010': ['ticket-system/', 'data-stats/', 'dynamic-comic/'],
'DEV-011': ['writing-workspace/'],
'DEV-012': ['notification-center/'],
'TCS-0002': ['*'] // 冰朔全权限
};
return MAP[devId] || [];
}
module.exports = { requireAuth, checkPermission };
4.5 操作审计日志
创建文件:backend/api-server/middleware/audit.js
const fs = require('fs');
const path = require('path');
const AUDIT_LOG_DIR = '/var/log/guanghu-api/audit/';
function auditLog(req, res, next) {
const startTime = Date.now();
// 记录请求
const logEntry = {
timestamp: new Date().toISOString(),
devId: req.headers['x-dev-id'] || 'unknown',
method: req.method,
path: req.path,
body: req.method === 'POST' ? req.body : undefined,
ip: req.ip
};
// 拦截响应完成事件
const originalSend = res.send;
res.send = function(body) {
logEntry.responseTime = Date.now() - startTime;
logEntry.statusCode = res.statusCode;
// 异步写入日志
try {
fs.mkdirSync(AUDIT_LOG_DIR, { recursive: true });
const today = new Date().toISOString().split('T')[0];
const logFile = path.join(AUDIT_LOG_DIR, `audit-${today}.jsonl`);
fs.appendFileSync(logFile, JSON.stringify(logEntry) + '\n');
} catch (e) {
console.error('审计日志写入失败:', e.message);
}
return originalSend.call(this, body);
};
next();
}
module.exports = { auditLog };
4.6 预览站沙箱机制
创建文件:backend/api-server/middleware/sandbox.js
/**
* 沙箱中间件
*
* 如果开发者在预览环境中执行写入操作:
* - Notion 写入 → 重定向到沙箱数据库
* - GitHub 操作 → 重定向到 preview 分支
* - 所有操作标记 [SANDBOX] 前缀
*/
const SANDBOX_DB_IDS = {
// 铸渊需要创建这些沙箱数据库(Notion中的独立数据库,结构和正式库一样)
ticketBook: '铸渊创建:沙箱工单簿ID',
syslogInbox: '铸渊创建:沙箱SYSLOG ID',
maintenanceLog: '铸渊创建:沙箱维护日志ID',
};
function sandboxGuard(req, res, next) {
if (req.user && req.user.environment === 'preview') {
// 标记为沙箱操作
req.sandbox = true;
req.sandboxDbIds = SANDBOX_DB_IDS;
// 如果是部署操作,强制指向预览站
if (req.path.includes('/deploy/production')) {
return res.status(403).json({
success: false,
reply: '🏖️ 你目前在预览环境。正式站部署需要升级到 Level 2(执行者)权限。\n\n继续在预览站练习吧,你做得很好!'
});
}
}
next();
}
module.exports = { sandboxGuard, SANDBOX_DB_IDS };
五、认知引导系统(Phase 6 · 教开发者"怎么说话")
5.1 核心理念
5.2 新开发者首次登录流程
新开发者首次登录
│
▼
┌─────────────────────────────────────────┐
│ 👋 欢迎来到光湖·数字地球 │
│ │
│ 我是铸渊,你的代码守护人格体。 │
│ 在这里,你不需要点按钮或填表单。 │
│ **直接对我说话就好。** │
│ │
│ 比如你可以说: │
│ · "我的工单还有几个没关?" │
│ · "帮我建一个P2的Bug工单" │
│ · "我想部署 status-board 到预览站" │
│ · "最近系统有什么日志?" │
│ │
│ 现在你在**预览环境**,所有操作都不会 │
│ 影响正式站。放心练习。 │
│ │
│ 准备好了吗?试着和我说句话。 │
│ │
│ [开始体验] → │
└─────────────────────────────────────────┘
│
▼
进入引导对话(系统预设 5 轮引导)
5.3 引导对话脚本(5轮)
创建文件:backend/api-server/config/onboarding-script.json
{
"onboarding": [
{
"round": 1,
"prompt": "👋 首先,试着问我你的状态。比如说:「我现在什么情况?」",
"expected_intent": "query_my_status",
"success_message": "✅ 很好!你看到了吗?我直接从 Notion 数据库里查了你的真实信息回来。这就是语言驱动——你说话,系统就动了。",
"hint": "💡 你可以说「我的状态」、「我的进度」、「我现在怎么样了」,怎么说都行,我能听懂。"
},
{
"round": 2,
"prompt": "📝 接下来,试着建一个工单。比如:「帮我建一个工单,标题是测试工单」",
"expected_intent": "create_ticket",
"success_message": "✅ 工单已经建好了!注意,这是在预览环境里建的,不会影响正式系统。当你升级到正式环境后,建的工单就是真的了。",
"hint": "💡 你可以说「建个工单」、「提个Bug」、「报告一个问题」,都会触发建工单。"
},
{
"round": 3,
"prompt": "📊 再试试查一下系统日志。比如:「最近有什么日志?」",
"expected_intent": "query_recent_syslogs",
"success_message": "✅ 这些是从 Notion SYSLOG数据库里实时查的。每个开发者提交的日志你都能看到。",
"hint": "💡 你可以说「最近的日志」、「系统日志」、「看看SYSLOG」。"
},
{
"round": 4,
"prompt": "🚀 现在试试部署你的模块到预览站。比如:「部署 status-board 到预览站」",
"expected_intent": "deploy_to_preview",
"success_message": "✅ 部署已触发!在预览站你可以随便试。等你熟悉了,冰朔会给你开正式站的部署权限。",
"hint": "💡 你只能部署自己负责的模块。如果说了别人的模块,系统会友好提示你。"
},
{
"round": 5,
"prompt": "🎉 最后一轮。试试随便和我聊点什么。什么都行——问我问题、讲笑话、或者告诉我你想做什么。",
"expected_intent": null,
"success_message": "✅ 引导完成!\n\n你现在已经知道怎么和系统交互了。记住:\n\n· **直接说人话**,不需要背命令\n· **想做什么就说什么**,我会帮你翻译成操作\n· **在预览站多练习**,正式站操作都是真的\n· **说错了也没关系**,我会帮你确认\n\n你的权限已经从「观察者」升级到「学习者」了 📖\n现在可以在预览站自由操作了。\n\n有什么问题随时找我。",
"hint": null
}
]
}
5.4 引导完成后自动升级权限
// 引导完成后,自动将开发者从 Level 0(观察者)升级到 Level 1(学习者)
async function completeOnboarding(devId) {
// 更新权限配置
DEV_PERMISSIONS[devId].level = 1;
// 写入审计日志
await auditLog({
action: 'permission_upgrade',
devId: devId,
from: 0,
to: 1,
reason: 'onboarding_completed',
timestamp: new Date().toISOString()
});
// 通知霜砚(写入 Notion 维护日志)
await writeToDB(config.maintenanceLog, {
'标题': { title: [{ text: { content: `${devId} 完成认知引导,升级为学习者` } }] },
'类型': { select: { name: '权限变更' } }
});
}
5.5 升级路径
观察者(L0) ──完成5轮引导──→ 学习者(L1) ──冰朔手动升级──→ 执行者(L2)
│ │
│ 预览站:全部可操作 │ 正式站:可操作自己模块
│ 正式站:只读 │ 含部署权限
│ │
└──── 认知适应期 ────────────────┘
(时间由冰朔决定)
升级到 Level 2 的条件(由冰朔判断):
- 在预览站操作至少 7 天
- 至少完成 10 次有效操作(建工单、提日志、部署预览等)
- 没有误操作记录
- 冰朔主观判断:这个人已经知道「怎么说话」了
六、文件创建清单
新增文件清单(全部在 backend/api-server/ 下):
// 写入接口
backend/api-server/routes/write.js ← 工单/SYSLOG/部署/广播写入
backend/api-server/services/github.js ← GitHub API 写入封装
// 意图路由
backend/api-server/config/function-tools.json ← 操作清单定义
backend/api-server/middleware/intent-router.js ← 意图路由核心
// 权限系统
backend/api-server/config/permissions.js ← 权限等级定义
backend/api-server/middleware/auth.js ← 身份验证 + 权限检查
backend/api-server/middleware/sandbox.js ← 预览站沙箱守卫
backend/api-server/middleware/audit.js ← 操作审计日志
// 认知引导
backend/api-server/config/onboarding-script.json ← 5轮引导对话脚本
backend/api-server/routes/onboarding.js ← 引导流程接口
// 前端修改(新增逻辑,不删除现有代码)
docs/js/intent-tools.js ← 前端 function calling 集成
docs/js/onboarding.js ← 前端引导流程 UI
docs/css/onboarding.css ← 引导流程样式
七、执行顺序
八、验收标准(整体)
- 开发者说「帮我建个工单」→ 工单出现在 Notion 工单簿中
- 开发者说「查我的进度」→ 返回真实的 Notion 数据
- 开发者说「部署到预览站」→ GitHub Actions 被触发
- Level 0 用户无法执行任何写入操作
- Level 1 用户在预览站能写入,正式站只能读
- Level 2 用户在正式站能部署自己的模块
- 危险操作(正式站部署、广播)需要二次确认
- 新开发者登录后自动进入 5 轮引导
- 引导完成后自动升级为 Level 1
- 所有操作都有审计日志
- 预览站操作不影响正式站任何数据
九、回执要求
铸渊按 Phase 分别回执:
[ZY-LANGDRIVE-RECEIPT-3]
指令编号: ZY-LANGDRIVE-2026-0325-001
Phase: 3 · 写入能力层
写入接口: ✅/❌(列出可用接口数)
Notion写入: ✅/❌
GitHub写入: ✅/❌
审计日志: ✅/❌
[ZY-LANGDRIVE-RECEIPT-4]
Phase: 4 · 意图路由
Function Tools: ✅/❌(列出工具数)
意图识别准确率: 测试结果
端到端测试: 说话→执行→结果 ✅/❌
[ZY-LANGDRIVE-RECEIPT-5]
Phase: 5 · 权限沙箱
权限分级: ✅/❌
沙箱隔离: ✅/❌
Level 0 只读验证: ✅/❌
Level 1 预览站写入验证: ✅/❌
[ZY-LANGDRIVE-RECEIPT-6]
Phase: 6 · 认知引导
引导流程: ✅/❌
5轮对话: ✅/❌
自动升级: ✅/❌
十、补充条款 S2 · 双环境部署流与天眼终审授权(Phase 8)
补充签发:霜砚(AG-SY-01)· 冰朔授权
补充时间:2026-03-25 13:50 CST
触发上下文:guanghulab.com 域名已切换上线,双环境角色需重新定义
10.1 双环境角色重新定义
10.2 部署流水线(不可逆执行 → 预览 → 天眼审核 → 自动发布)
铸渊接收指令(不可逆)
│
│ 系统全身联动执行
│ (执行保护层 Phase 7 生效·不可中断)
▼
执行完毕 · 代码产出
│
▼
┌──────────────────────────────────────────────────────┐
│ Stage 1 · 部署到预览站(GitHub Pages) │
│ 网址:qinfendebingshuo.github.io/guanghulab/docs/ │
│ 状态:真实可访问 · 任何人有链接都能看到 │
│ 目的:让人类确认「系统执行的结果是否符合预期」 │
└──────────────────────────────────────────────────────┘
│
│ 开发者预览确认
▼
┌──────────────────────────────────────────────────────┐
│ Stage 2 · 推送天眼审核 │
│ 天眼自动扫描:代码安全、结构完整性、功能回归 │
│ 审核通过 → 进入 Stage 3 │
│ 审核不通过 → 标记问题,开发者修复后重新提交 │
└──────────────────────────────────────────────────────┘
│
│ 天眼审核通过
▼
┌──────────────────────────────────────────────────────┐
│ Stage 3 · 人类终审授权 │
│ │
│ 系统推送授权请求给最终授权人: │
│ 🐱 肥猫(DEV-002)— 管男频内容 │
│ 🍊 桔子(DEV-010)— 管女频内容 │
│ │
│ 授权人必须手动点击「授权通过」 │
│ 操作留下完整日志(谁、什么时间、点了什么) │
│ **系统不背锅。所有发布都是人类确认的。** │
└──────────────────────────────────────────────────────┘
│
│ 授权人点击通过
▼
┌──────────────────────────────────────────────────────┐
│ Stage 4 · 铸渊自动发布到正式站 │
│ 目标:guanghulab.com │
│ 方式:铸渊触发 deploy-to-server.yml → SSH → 服务器更新 │
│ 无需人类再次操作 · 授权即发布 │
└──────────────────────────────────────────────────────┘
10.3 天眼终审授权人配置
10.4 授权流程技术实现
创建文件:backend/api-server/routes/approval.js
const express = require('express');
const router = express.Router();
const { requireAuth, checkPermission } = require('../middleware/auth');
const { auditLog } = require('../middleware/audit');
const { triggerWorkflow } = require('../services/github');
// 天眼审核完成后,推送授权请求
router.post('/approval/request',
requireAuth,
checkPermission('system:internal'), // 仅系统内部调用
async (req, res) => {
const { deployId, module, channel, reviewReport } = req.body;
// 确定授权人
const approvers = getApprovers(channel);
// 创建授权请求记录
const approval = {
id: `APPROVAL-${Date.now()}`,
deployId,
module,
channel,
reviewReport,
approvers: approvers.map(a => a.devId),
status: 'pending',
createdAt: new Date().toISOString()
};
// 推送通知给授权人(通过铸渊交互页面 + 系统通知)
for (const approver of approvers) {
await pushNotification(approver.devId, {
type: 'approval_request',
title: `🔔 部署授权请求:${module}`,
message: `天眼审核已通过。请确认是否授权部署到正式站。`,
approvalId: approval.id,
actions: ['授权通过', '拒绝']
});
}
res.json({ success: true, approvalId: approval.id });
}
);
// 授权人点击确认/拒绝
router.post('/approval/:approvalId/decide',
requireAuth,
async (req, res) => {
const { approvalId } = req.params;
const { decision } = req.body; // 'approved' | 'rejected'
const devId = req.user.devId;
// 验证是否为授权人
const approval = await getApproval(approvalId);
if (!approval.approvers.includes(devId)) {
return res.status(403).json({
success: false,
reply: '🔒 你不是这个部署的授权人。'
});
}
// 记录授权操作(不可逆·写入审计日志)
await auditLog({
action: 'deployment_approval',
approvalId,
devId,
decision,
timestamp: new Date().toISOString()
});
if (decision === 'approved') {
// 检查是否所有授权人都已通过
const allApproved = await checkAllApproved(approvalId);
if (allApproved) {
// 触发铸渊自动发布到正式站
await triggerWorkflow('deploy-to-server.yml', {
module: approval.module,
deploy_id: approval.deployId,
approved_by: approval.approvers.join(','),
target: 'production'
});
res.json({
success: true,
reply: `✅ 授权通过。铸渊已自动触发正式站部署。`
});
} else {
res.json({
success: true,
reply: `✅ 你已授权。等待其他授权人确认...`
});
}
} else {
res.json({
success: true,
reply: `❌ 已拒绝。部署不会执行。原因已记录到审计日志。`
});
}
}
);
function getApprovers(channel) {
const APPROVER_MAP = {
'男频': [{ devId: 'DEV-002', name: '肥猫' }],
'女频': [{ devId: 'DEV-010', name: '桔子' }],
'系统': [{ devId: 'DEV-002', name: '肥猫' }, { devId: 'DEV-010', name: '桔子' }],
'跨频': [{ devId: 'DEV-002', name: '肥猫' }, { devId: 'DEV-010', name: '桔子' }]
};
return APPROVER_MAP[channel] || APPROVER_MAP['系统'];
}
module.exports = router;
10.5 文件新增清单(Phase 8)
backend/api-server/routes/approval.js ← 授权流程接口
backend/api-server/config/approvers.json ← 授权人配置(肥猫+桔子)
docs/js/approval-ui.js ← 前端授权弹窗 UI
docs/css/approval.css ← 授权弹窗样式
十一、补充条款 S3 · 系统自治权与冰朔指令签发模式(Phase 9)
补充签发:霜砚(AG-SY-01)· 冰朔授权
补充时间:2026-03-25 13:50 CST
11.1 双线并行架构
11.2 系统自治权
11.3 执行顺序
11.4 回执要求
[ZY-LANGDRIVE-RECEIPT-8]
Phase: 8 · 双环境部署流 + 天眼终审授权
授权流程接口: ✅/❌
天眼→授权人推送: ✅/❌
授权人点击确认: ✅/❌
自动发布触发: ✅/❌
审计日志: ✅/❌
[ZY-LANGDRIVE-RECEIPT-9]
Phase: 9 · 系统自治运行框架
自动监控: ✅/❌
自动优化: ✅/❌
审计日志: ✅/❌
🔗 签发:霜砚(AG-SY-01)
👤 授权:冰朔(TCS-0002∞)
📅 日期:2026-03-25
📌 版权:国作登字-2026-A-00037559