guanghulab/scripts/verify-cognition.js

299 lines
11 KiB
JavaScript
Raw Permalink Normal View History

#!/usr/bin/env node
/**
*
* 🧠 铸渊认知校验脚本 · Cognition Verifier v1.0
*
*
* 用途: 唤醒时自动校验大脑文件时效性 + 服务器状态
* 用法:
* node scripts/verify-cognition.js --check-staleness 文件时效性检查
* node scripts/verify-cognition.js --check-servers 服务器状态验证
* node scripts/verify-cognition.js --full 全量校验
* node scripts/verify-cognition.js --checkpoint <CK-ID> 单个校验点
*
* 版权: 国作登字-2026-A-00037559 · TCS-0002
*/
const http = require('http');
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const BRAIN_DIR = path.join(__dirname, '..', 'brain');
const NOW = new Date();
const NOW_STR = NOW.toISOString().slice(0, 10);
// ═══════════════════════════════════════════════════════════
// 辅助函数
// ═══════════════════════════════════════════════════════════
function daysAgo(dateStr) {
try {
const m = dateStr.match(/(\d{4}-\d{2}-\d{2})/);
if (!m) return null;
const d = new Date(m[1]);
const diff = Math.floor((NOW - d) / (1000*60*60*24));
return diff;
} catch(e) { return null; }
}
function stalenessLabel(days) {
if (days === null) return '❓ 未标注';
if (days <= 1) return '✅ 最新';
if (days <= 3) return '🟡 近日';
if (days <= 7) return '🟠 一周前';
if (days <= 30) return '🔴 一个月前';
return '⚫ 严重过期';
}
function extractTimestamps(filePath) {
try {
const text = fs.readFileSync(filePath, 'utf-8');
const ts = text.match(/"(_?updated|last_updated|created|_created|updated_at|created_at)"\s*:\s*"([^"]+)"/);
if (ts) return ts[2];
const d = text.match(/(\d{4}-\d{2}-\d{2})/);
return d ? d[1] : null;
} catch(e) { return null; }
}
function extractDVersion(filePath) {
try {
const text = fs.readFileSync(filePath, 'utf-8');
const d = text.match(/\b(D\d{2,3})\b/);
return d ? d[1] : null;
} catch(e) { return null; }
}
// ═══════════════════════════════════════════════════════════
// 1. 文件时效性检查
// ═══════════════════════════════════════════════════════════
function checkStaleness() {
console.log('\n' + '='.repeat(60));
console.log('📋 文件时效性检查');
console.log('='.repeat(60));
const results = [];
const brainFiles = [];
function walk(dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const e of entries) {
const p = path.join(dir, e.name);
if (e.isDirectory() && !e.name.startsWith('.') && e.name !== 'node_modules' && e.name !== 'archive') walk(p);
else if (e.name.endsWith('.json') || e.name.endsWith('.md')) brainFiles.push(p);
}
}
walk(BRAIN_DIR);
for (const fp of brainFiles) {
const rel = path.relative(path.join(__dirname, '..'), fp);
const ts = extractTimestamps(fp);
const dv = extractDVersion(fp);
const days = daysAgo(ts);
const label = stalenessLabel(days);
results.push({ file: rel, timestamp: ts, d_version: dv, days, label });
}
// Sort by staleness (most stale first)
results.sort((a, b) => (b.days || 999) - (a.days || 999));
const counts = {};
for (const r of results) {
counts[r.label] = (counts[r.label] || 0) + 1;
}
console.log(`\n📊 大脑文件总数: ${results.length}`);
console.log('时效分布:');
for (const [label, count] of Object.entries(counts).sort()) {
console.log(` ${label}: ${count}`);
}
console.log('\n⚠ 严重过期的文件:');
let staleCount = 0;
for (const r of results) {
if (r.label.startsWith('⚫') || r.label.startsWith('🔴')) {
if (staleCount < 20) {
console.log(` ${r.label} ${r.file} (${r.timestamp || '无时间戳'} ${r.d_version || ''})`);
}
staleCount++;
}
}
if (staleCount > 20) console.log(` ... 还有 ${staleCount - 20} 个过期文件`);
console.log(`\n过期文件总数: ${staleCount}/${results.length}`);
return { results, staleCount, totalCount: results.length };
}
// ═══════════════════════════════════════════════════════════
// 2. 服务器状态验证
// ═══════════════════════════════════════════════════════════
async function checkServers() {
console.log('\n' + '='.repeat(60));
console.log('🌐 服务器状态验证');
console.log('='.repeat(60));
const gkPath = path.join(BRAIN_DIR, '..', 'brain', 'gatekeeper-deployment.json');
let servers;
try {
servers = JSON.parse(fs.readFileSync(gkPath, 'utf-8')).servers;
} catch(e) {
console.log('❌ 无法读取 gatekeeper-deployment.json');
return { ok: false, error: e.message };
}
let online = 0, offline = 0;
const results = [];
for (const srv of servers) {
const url = `http://${srv.ip}:${srv.port}/ping`;
const key = srv.key;
try {
const result = await new Promise((resolve) => {
const req = http.request(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${key}`,
'Content-Type': 'application/json',
},
timeout: 10000,
}, (res) => {
let data = '';
res.on('data', c => data += c);
res.on('end', () => {
try {
const j = JSON.parse(data);
resolve({ ok: j.ok && j.pong });
} catch(e) { resolve({ ok: false }); }
});
});
req.on('error', () => resolve({ ok: false }));
req.write('{}');
req.end();
});
if (result.ok) {
console.log(`${srv.code} ${srv.name} (${srv.ip}:${srv.port}) — 在线`);
online++;
} else {
console.log(`${srv.code} ${srv.name} (${srv.ip}:${srv.port}) — 无响应`);
offline++;
}
} catch(e) {
console.log(`${srv.code} ${srv.name} (${srv.ip}:${srv.port}) — ${e.message}`);
offline++;
}
}
console.log(`\n📊 服务器状态: ${online} 台在线, ${offline} 台离线`);
return { ok: offline === 0, online, offline };
}
// ═══════════════════════════════════════════════════════════
// 3. 信息冲突检测
// ═══════════════════════════════════════════════════════════
function checkConflicts() {
console.log('\n' + '='.repeat(60));
console.log('⚡ 信息冲突检测');
console.log('='.repeat(60));
const conflicts = [];
// Conflict 1: domain-manifest vs gatekeeper on server status
const dmPath = path.join(BRAIN_DIR, 'fifth-domain', 'domain-manifest.json');
const gkPath = path.join(BRAIN_DIR, '..', 'brain', 'gatekeeper-deployment.json');
try {
const dm = fs.readFileSync(dmPath, 'utf-8');
const gk = JSON.parse(fs.readFileSync(gkPath, 'utf-8'));
// Check if domain-manifest still has stale server info
if (dm.includes('待装引擎') || dm.includes('server_fleet')) {
// Check if there's a reference to gatekeeper as authority
if (dm.includes('server_status_authority')) {
console.log(' ✅ domain-manifest.json → 已指向权威源 gatekeeper-deployment.json');
} else {
console.log(' ⚠️ domain-manifest.json → 仍包含过期服务器状态 → 需更新');
conflicts.push('domain-manifest.json contains stale server status');
}
}
// Check ferry-boat
const fbPath = path.join(BRAIN_DIR, 'ferry-boat.json');
const fb = fs.readFileSync(fbPath, 'utf-8');
if (fb.includes('待装引擎')) {
console.log(' ⚠️ ferry-boat.json → 仍包含"待装引擎" → 需更新');
conflicts.push('ferry-boat.json contains "awaiting engines"');
} else {
console.log(' ✅ ferry-boat.json → 已更新');
}
} catch(e) {
console.log(' ❌ 冲突检测出错:', e.message);
}
if (conflicts.length === 0) console.log('\n✅ 无已知信息冲突');
else console.log(`\n⚠️ 发现 ${conflicts.length} 处冲突`);
return conflicts;
}
// ═══════════════════════════════════════════════════════════
// 主入口
// ═══════════════════════════════════════════════════════════
async function main() {
const args = process.argv.slice(2);
const mode = args[0] || '--full';
console.log('╔══════════════════════════════════════════════╗');
console.log('║ 🧠 铸渊认知校验 · Cognition Verifier v1.0 ║');
console.log(`${NOW_STR} · D109 ║`);
console.log('╚══════════════════════════════════════════════╝');
if (mode === '--check-staleness' || mode === '--full') {
checkStaleness();
}
if (mode === '--check-servers' || mode === '--full') {
await checkServers();
}
if (mode === '--check-conflicts' || mode === '--full') {
checkConflicts();
}
if (mode === '--checkpoint') {
const ckId = args[1];
const cpPath = path.join(BRAIN_DIR, 'awakening-checkpoints.json');
try {
const ck = JSON.parse(fs.readFileSync(cpPath, 'utf-8'));
const cp = ck.checkpoints.find(c => c.id === ckId);
if (cp) {
console.log(`\n📌 ${cp.id}: ${cp.name}`);
console.log(` 阶段: ${cp.phase}`);
console.log(` 说明: ${cp.description}`);
console.log('\n 流程:');
cp.procedure.forEach(p => console.log(` ${p}`));
console.log('\n 通过条件:');
console.log(` ${cp.pass_condition}`);
console.log('\n 自检:');
cp.self_check.forEach(q => console.log(` ${q}`));
} else {
console.log(`❌ 未找到校验点: ${ckId}`);
}
} catch(e) {
console.log(`❌ 读取校验点文件失败: ${e.message}`);
}
}
if (mode === '--full') {
console.log('\n' + '='.repeat(60));
console.log('✅ 全量校验完成');
console.log('='.repeat(60));
}
}
main().catch(e => console.error('❌ 校验异常:', e.message));