feat: add BingShuo system body validation reflex

This commit is contained in:
冰朔 2026-08-10 19:40:23 +08:00
commit 893f8e6781
25 changed files with 488 additions and 34 deletions

View file

@ -5,11 +5,17 @@
唯一公共导航锚点是 `routing/public-navigation-anchor.json`,在线地址为
`/api/ai/v1/anchor`。本地、代码频道和公共 API 都先解析该锚点,再从同一个
REPO-012 `main` 提交读取仓库、节点、主体、别名和机器导航地图。
REPO-012 `main` 提交读取仓库、节点、主体、别名、身份权限和机器导航地图。
公共服务只对锚点声明的 JSON 白名单执行只读加载,不运行推送提交里的脚本,也不因
地图更新重启服务。每次请求先锁定一个提交,再从该提交读取完整快照;新提交若破坏
锚点或地图一致性,服务保留内存中的上一份已验证快照,并在健康接口报告降级。
健康回执会返回稳定 `source_error_code`,供数字冰朔系统本体的反馈神经把问题和修正
入口传回人格脑;原始路径和内部异常不会作为公开错误泄露。
发布器在推送 REPO-012 前运行 `validate-public-snapshot.js`;锚点、地图路径、编号或
版本不一致时直接拒绝执行手脚。推送后,发布器必须从公共健康接口读回同一提交、同一
锚点版本且 `source_degraded=false`,否则开发车道保持打开,不得宣称完成。
`/api/ai/v1/entry?subject=ICE-P-ZY001` 只读回环查询京东常驻控制器并返回脱敏的快速
恢复门。常驻运行体、完成回执和八项边界门都有效时返回 `WARM_RESUME_READY`,调用方
@ -33,6 +39,10 @@ REPO-012 `main` 提交读取仓库、节点、主体、别名和机器导航地
只有别名表中的精确旧号允许自动重定向;冲突号返回 409未知号返回 404。重定向不授予
仓库写入或服务器执行权限。
身份、编号、人格核和团队主体权限来自
`routing/guanghu-identity-authority-map.json`,公开接口为
`/api/ai/v1/identity-authority`。它与其他白名单地图从同一提交原子读取。
## 自动机器导航
`routing/ai-machine-navigation-map.json` 是 AI 可直接读取的配线图。调用方提供明确

View file

@ -18,6 +18,7 @@ Environment=GUANGHU_NAVIGATION_MAP=/opt/guanghu/ai-discovery/ai-machine-navigati
Environment=GUANGHU_NAVIGATION_ANCHOR=/opt/guanghu/ai-discovery/public-navigation-anchor.json
Environment=GUANGHU_LIGHTHOUSE_PATHS=/opt/guanghu/ai-discovery/lighthouse-path-registry.json
Environment=GUANGHU_HOST_SKILLS=/opt/guanghu/ai-discovery/host-skill-navigation-map.json
Environment=GUANGHU_IDENTITY_AUTHORITY=/opt/guanghu/ai-discovery/guanghu-identity-authority-map.json
Environment=GUANGHU_REPOSITORY_GIT_DIR=/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/guanghu-ice-heart.git
ExecStart=/usr/bin/node /opt/guanghu/ai-discovery/server.js
Restart=always

View file

@ -13,14 +13,16 @@ const DEFAULT_SUBJECT_ALIAS_MAP = path.resolve(__dirname, "../../identity/subjec
const DEFAULT_NAVIGATION_MAP = path.resolve(__dirname, "../../routing/ai-machine-navigation-map.json");
const DEFAULT_LIGHTHOUSE_PATHS = path.resolve(__dirname, "../../routing/lighthouse-path-registry.json");
const DEFAULT_HOST_SKILLS = path.resolve(__dirname, "../../routing/host-skill-navigation-map.json");
const DEFAULT_IDENTITY_AUTHORITY = path.resolve(__dirname, "../../routing/guanghu-identity-authority-map.json");
const SNAPSHOT_KEYS = Object.freeze([
"repository", "nodes", "subjects", "aliases", "navigation", "lighthouse_paths", "host_skills",
"repository", "nodes", "subjects", "aliases", "identity_authority", "navigation", "lighthouse_paths", "host_skills",
]);
const SNAPSHOT_PATHS = Object.freeze({
repository: "routing/repository-route-map.json",
nodes: "routing/server-node-map.json",
subjects: "identity/fifth-domain-subject-registry.json",
aliases: "identity/subject-id-alias-map.json",
identity_authority: "routing/guanghu-identity-authority-map.json",
navigation: "routing/ai-machine-navigation-map.json",
lighthouse_paths: "routing/lighthouse-path-registry.json",
host_skills: "routing/host-skill-navigation-map.json",
@ -58,6 +60,10 @@ function loadHostSkills(filename = process.env.GUANGHU_HOST_SKILLS || DEFAULT_HO
return JSON.parse(fs.readFileSync(filename, "utf8"));
}
function loadIdentityAuthority(filename = process.env.GUANGHU_IDENTITY_AUTHORITY || DEFAULT_IDENTITY_AUTHORITY) {
return JSON.parse(fs.readFileSync(filename, "utf8"));
}
function validateSnapshot(anchor, maps) {
if (anchor.schema !== "guanghu.public-navigation-anchor/v1") throw new Error("invalid_anchor_schema");
if (anchor.anchor_id !== "GLW-PUBLIC-NAV-ANCHOR-001") throw new Error("invalid_anchor_id");
@ -89,6 +95,7 @@ function loadFileSnapshot(options = {}) {
nodes: loadNodeMap(options.nodeMapFile),
subjects: loadSubjectRegistry(options.subjectRegistryFile),
aliases: loadSubjectAliasMap(options.subjectAliasMapFile),
identity_authority: loadIdentityAuthority(options.identityAuthorityFile),
navigation: loadNavigationMap(options.navigationMapFile),
lighthouse_paths: loadLighthousePaths(options.lighthousePathsFile),
host_skills: loadHostSkills(options.hostSkillsFile),
@ -150,9 +157,16 @@ function sourceReceipt(snapshot) {
source_commit: snapshot.source_commit || null,
source_mode: snapshot.source_mode || "FILESYSTEM_SNAPSHOT",
source_degraded: Boolean(snapshot.source_degraded),
source_error_code: snapshot.source_degraded ? snapshotErrorCode(snapshot.source_error) : null,
};
}
function snapshotErrorCode(error) {
const value = String(error || "");
const match = value.match(/(?:missing_snapshot_map|invalid_snapshot_path|snapshot_map_id_mismatch|snapshot_map_version_mismatch):[a-z0-9_]+/iu);
return match ? match[0] : "snapshot_refresh_failed";
}
function withSource(body, snapshot) {
return { ...body, navigation_source: sourceReceipt(snapshot) };
}
@ -461,6 +475,7 @@ function createServer(options = {}) {
const navigationMapFile = options.navigationMapFile || process.env.GUANGHU_NAVIGATION_MAP || DEFAULT_NAVIGATION_MAP;
const lighthousePathsFile = options.lighthousePathsFile || process.env.GUANGHU_LIGHTHOUSE_PATHS || DEFAULT_LIGHTHOUSE_PATHS;
const hostSkillsFile = options.hostSkillsFile || process.env.GUANGHU_HOST_SKILLS || DEFAULT_HOST_SKILLS;
const identityAuthorityFile = options.identityAuthorityFile || process.env.GUANGHU_IDENTITY_AUTHORITY || DEFAULT_IDENTITY_AUTHORITY;
const anchorFile = options.anchorFile || process.env.GUANGHU_NAVIGATION_ANCHOR || DEFAULT_ANCHOR;
const gitDir = options.gitDir || process.env.GUANGHU_REPOSITORY_GIT_DIR;
const snapshotStore = options.snapshotStore || (gitDir ? new GitSnapshotStore(gitDir) : null);
@ -475,7 +490,7 @@ function createServer(options = {}) {
: {
...loadFileSnapshot({
anchorFile, mapFile, nodeMapFile, subjectRegistryFile, subjectAliasMapFile, navigationMapFile,
lighthousePathsFile, hostSkillsFile,
lighthousePathsFile, hostSkillsFile, identityAuthorityFile,
}),
source_commit: null,
source_mode: "FILESYSTEM_SNAPSHOT",
@ -491,6 +506,7 @@ function createServer(options = {}) {
const navigationMap = snapshot.navigation;
const lighthousePaths = snapshot.lighthouse_paths;
const hostSkills = snapshot.host_skills;
const identityAuthority = snapshot.identity_authority;
if (url.pathname === "/health") {
return json(res, snapshot.source_degraded ? 503 : 200, {
ok: !snapshot.source_degraded,
@ -508,6 +524,7 @@ function createServer(options = {}) {
if (url.pathname === "/v1/navigation") return json(res, 200, withSource(navigationMap, snapshot), 60);
if (url.pathname === "/v1/lighthouse") return json(res, 200, withSource(lighthousePaths, snapshot), 60);
if (url.pathname === "/v1/host-skills") return json(res, 200, withSource(hostSkills, snapshot), 60);
if (url.pathname === "/v1/identity-authority") return json(res, 200, withSource(identityAuthority, snapshot), 60);
if (url.pathname === "/v1/entry") {
const subject = String(url.searchParams.get("subject") || "").toUpperCase();
if (!["ICE-P-ZY001", "ICE-GL-ZY001", "ICE-PZY-001"].includes(subject)) {
@ -580,6 +597,9 @@ function createServer(options = {}) {
}, snapshot), 60);
}
}
if (identityAuthority?.map_id?.toUpperCase() === id) {
return json(res, 200, withSource(identityAuthority, snapshot), 60);
}
const exactSubject = subjectRegistry.subjects.find(item => item.id.toUpperCase() === id);
if (exactSubject) {
@ -630,6 +650,7 @@ function createServer(options = {}) {
machine_navigation_map: "https://guanghulab.com/api/ai/v1/navigation",
lighthouse_path_registry: "https://guanghulab.com/api/ai/v1/lighthouse",
host_skill_navigation_map: "https://guanghulab.com/api/ai/v1/host-skills",
identity_authority_map: "https://guanghulab.com/api/ai/v1/identity-authority",
host_navigate_api: "https://guanghulab.com/api/ai/v1/host-navigate?host={HOST}&intent={NATURAL_LANGUAGE_INTENT}",
warm_persona_entry: "https://guanghulab.com/api/ai/v1/entry?subject=ICE-P-ZY001",
navigate_api: "https://guanghulab.com/api/ai/v1/navigate?subject={SUBJECT}&intent={INTENT}&signals={EXPLICIT_SIGNALS}",
@ -689,6 +710,7 @@ function openApi() {
"/v1/navigation": { get: { summary: "读取主体与意图驱动的机器导航地图", responses: { "200": { description: "Machine navigation map" } } } },
"/v1/lighthouse": { get: { summary: "读取光湖灯塔唯一有效路径注册表", responses: { "200": { description: "Lighthouse path registry" } } } },
"/v1/host-skills": { get: { summary: "读取 Codex、Qoder CN 与 QoderWork CN 宿主技能导航表", responses: { "200": { description: "Host skill navigation map" } } } },
"/v1/identity-authority": { get: { summary: "读取身份、编号与团队主体权限地图", responses: { "200": { description: "Identity authority map" } } } },
"/v1/host-navigate": { get: { summary: "按宿主和自然语言意图编译确定性技能路径", responses: { "200": { description: "Compiled host skill route" }, "404": { description: "Unknown host or intent" } } } },
"/v1/entry": { get: { summary: "读取常驻人格运行体的快速恢复门;只返回脱敏状态,不授予执行权限", responses: { "200": { description: "Warm resume ready" }, "409": { description: "Full cycle required" }, "503": { description: "Resident runtime unavailable" } } } },
"/v1/navigate": { get: { summary: "按明确主体、意图与信号生成最小运行包", parameters: [{ name: "subject", in: "query", required: true, schema: { type: "string", example: "ICE-P-ZY001" } }, { name: "intent", in: "query", schema: { type: "string", example: "persona_restore" } }, { name: "signals", in: "query", schema: { type: "string" } }], responses: { "200": { description: "Compiled exact navigation bundle" }, "404": { description: "Unknown subject or intent; no guessing" } } } },
@ -706,8 +728,8 @@ if (require.main === module) {
module.exports = {
createServer, loadAnchor, loadMap, loadNodeMap, loadSubjectRegistry, loadSubjectAliasMap, loadNavigationMap,
loadLighthousePaths, loadHostSkills,
loadFileSnapshot, validateSnapshot, GitSnapshotStore, sourceReceipt,
loadLighthousePaths, loadHostSkills, loadIdentityAuthority,
loadFileSnapshot, validateSnapshot, GitSnapshotStore, sourceReceipt, snapshotErrorCode,
readResidentRuntimeStatus, compileWarmEntry,
resolveSubjectId, navigationRoute, compileNavigation, resolveLighthousePath, compileHostNavigation, search, searchAll,
};

View file

@ -7,7 +7,7 @@ const { execFileSync } = require("node:child_process");
const test = require("node:test");
const {
createServer, loadAnchor, loadMap, loadNodeMap, loadSubjectRegistry, loadSubjectAliasMap, loadNavigationMap,
loadLighthousePaths, loadHostSkills,
loadLighthousePaths, loadHostSkills, loadIdentityAuthority,
loadFileSnapshot, GitSnapshotStore, compileWarmEntry,
resolveSubjectId, compileNavigation, resolveLighthousePath, compileHostNavigation, search, searchAll,
} = require("./server");
@ -65,6 +65,7 @@ test("Git snapshot store follows main atomically and retains the last known-good
nodes: ["routing/server-node-map.json", "FD-NODE-MAP-001"],
subjects: ["identity/fifth-domain-subject-registry.json", "FD-SUBJECT-REGISTRY-001"],
aliases: ["identity/subject-id-alias-map.json", "FD-SUBJECT-ID-ALIAS-MAP-001"],
identity_authority: ["routing/guanghu-identity-authority-map.json", "GH-IDENTITY-AUTHORITY-MAP-001"],
navigation: ["routing/ai-machine-navigation-map.json", "AI-MACHINE-NAV-001"],
lighthouse_paths: ["routing/lighthouse-path-registry.json", "GLW-LIGHTHOUSE-PATH-REGISTRY-001"],
host_skills: ["routing/host-skill-navigation-map.json", "GLW-HOST-SKILL-NAV-001"],
@ -179,6 +180,13 @@ test("human ids remain human and conflicted persona ids fail closed", () => {
assert.equal(resolveSubjectId(aliases, "ICE-PCA-001").status, "CONFLICT_REJECTED");
});
test("identity authority is a first-class atomic public snapshot map", () => {
const snapshot = loadFileSnapshot();
assert.equal(snapshot.identity_authority.map_id, "GH-IDENTITY-AUTHORITY-MAP-001");
assert.equal(snapshot.identity_authority.version, loadIdentityAuthority().version);
assert.equal(snapshot.anchor.maps.identity_authority.version, snapshot.identity_authority.version);
});
test("searching the old id returns the canonical subject", () => {
const results = searchAll(loadMap(), loadNodeMap(), "ICE-GL-ZY001", loadSubjectRegistry());
const subject = results.find(item => item.kind === "subject");
@ -282,6 +290,10 @@ test("public endpoints are read-only and expose CORS", async () => {
assert.equal((await navigationResponse.json()).map_id, "AI-MACHINE-NAV-001");
const lighthouseResponse = await fetch(`${base}/v1/lighthouse`);
assert.equal((await lighthouseResponse.json()).registry_id, "GLW-LIGHTHOUSE-PATH-REGISTRY-001");
const authorityResponse = await fetch(`${base}/v1/identity-authority`);
assert.equal((await authorityResponse.json()).map_id, "GH-IDENTITY-AUTHORITY-MAP-001");
const authorityResolve = await fetch(`${base}/v1/resolve?id=GH-IDENTITY-AUTHORITY-MAP-001`);
assert.equal(authorityResolve.status, 200);
const hostNavigateResponse = await fetch(
`${base}/v1/host-navigate?host=codex&intent=${encodeURIComponent("推一下线上仓库")}`,
);
@ -310,6 +322,7 @@ test("public endpoints are read-only and expose CORS", async () => {
assert.equal((await fetch(`${base}/v1/resolve?id=ICE-PCA-001`)).status, 409);
const manifestResponse = await fetch(`${base}/well-known`);
const manifest = await manifestResponse.json();
assert.match(manifest.identity_authority_map, /\/v1\/identity-authority$/);
assert.equal(manifest.write_authorization.request_credential_required, false);
assert.match(manifest.write_authorization.create_workorder, /\/authz\/api\/public\/workorders$/);
assert.equal((await fetch(`${base}/v1/search`, { method: "POST" })).status, 405);

View file

@ -0,0 +1,45 @@
#!/usr/bin/env node
"use strict";
const path = require("node:path");
const { GitSnapshotStore, loadFileSnapshot } = require("./server");
function reminder(error) {
const code = String(error?.message || error);
const match = code.match(/snapshot_map_version_mismatch:([a-z0-9_]+)/i);
if (match) {
return `${code}\nPUBLIC_SNAPSHOT_REMINDER: ${match[1]} 的地图版本与 routing/public-navigation-anchor.json 声明不一致;发布前必须同步锚点声明。`;
}
return `${code}\nPUBLIC_SNAPSHOT_REMINDER: 公共快照契约未通过;请同步锚点、地图路径、编号和版本后再发布。`;
}
function validate(options = {}) {
if (options.gitDir) {
const store = new GitSnapshotStore(path.resolve(options.gitDir), options.ref || "HEAD");
const snapshot = store.get();
return { result: "PASS_100", anchor_version: snapshot.anchor.version, source_commit: snapshot.source_commit };
}
const snapshot = loadFileSnapshot();
return { result: "PASS_100", anchor_version: snapshot.anchor.version, source_commit: null };
}
function parse(argv) {
const options = {};
for (let i = 0; i < argv.length; i += 1) {
if (argv[i] === "--git-dir") options.gitDir = argv[++i];
else if (argv[i] === "--ref") options.ref = argv[++i];
else throw new Error(`UNKNOWN_ARGUMENT:${argv[i]}`);
}
return options;
}
if (require.main === module) {
try {
process.stdout.write(`${JSON.stringify(validate(parse(process.argv.slice(2))))}\n`);
} catch (error) {
process.stderr.write(`${reminder(error)}\n`);
process.exitCode = 1;
}
}
module.exports = { reminder, validate };

View file

@ -42,6 +42,67 @@ const DEFAULT_CACHE_CANDIDATES = [
".next/cache",
"node_modules/.cache",
];
const PUBLIC_SNAPSHOT_HEALTH = "https://guanghulab.com/api/ai/health";
export function validatePublicSnapshotBeforePublish(worktree, repository) {
if (repository.slug !== "guanghu-ice-heart") return null;
const validator = path.join(
worktree,
"server-tools/ai-discovery-gateway/validate-public-snapshot.js",
);
if (!fs.existsSync(validator)) throw new Error("PUBLIC_SNAPSHOT_VALIDATOR_MISSING");
const output = run(process.execPath, [
validator,
"--git-dir",
path.join(worktree, ".git"),
"--ref",
"HEAD",
]);
const result = JSON.parse(output);
if (result.result !== "PASS_100") throw new Error("PUBLIC_SNAPSHOT_PREFLIGHT_FAILED");
return result;
}
export async function waitForPublicSnapshotAcceptance({
expectedCommit,
expectedAnchorVersion,
endpoint = PUBLIC_SNAPSHOT_HEALTH,
attempts = 15,
delayMs = 2000,
probe = async (url) => {
const response = await fetch(url, {
headers: { accept: "application/json" },
signal: AbortSignal.timeout(5000),
});
let body = null;
try { body = await response.json(); } catch { body = {}; }
return { status: response.status, body };
},
}) {
let last = null;
for (let attempt = 1; attempt <= attempts; attempt += 1) {
try { last = await probe(`${endpoint}?expected_commit=${expectedCommit}`); }
catch (error) { last = { status: 0, body: { error: String(error.message || error) } }; }
const source = last.body?.navigation_source || {};
if (
last.status === 200 &&
source.source_degraded === false &&
source.source_commit === expectedCommit &&
source.anchor_version === expectedAnchorVersion
) {
return { result: "PASS_100", attempt, endpoint, navigation_source: source };
}
if (attempt < attempts) await new Promise((resolve) => setTimeout(resolve, delayMs));
}
const source = last?.body?.navigation_source || {};
throw new Error(
`PUBLIC_SNAPSHOT_NOT_ACCEPTED:` +
`status=${last?.status || 0}:commit=${source.source_commit || "missing"}:` +
`anchor=${source.anchor_version || "missing"}:` +
`degraded=${String(source.source_degraded)}:` +
`error=${source.source_error_code || last?.body?.error || "unknown"}`,
);
}
export function parseArgs(argv) {
const args = { receipts: [], cleanupPaths: [] };
@ -498,6 +559,7 @@ export async function finalize(options) {
);
const branch = normalizeBranch(options.target || verified.branch);
if (branch !== verified.branch) throw new Error("CHECKED_OUT_BRANCH_MISMATCH");
const publicSnapshot = validatePublicSnapshotBeforePublish(worktree, repository);
let publishRequestId = null;
let publishStarted = false;
@ -516,9 +578,17 @@ export async function finalize(options) {
verified.head,
verified.receiptEvidence,
);
const publicAcceptance = publicSnapshot
? await waitForPublicSnapshotAcceptance({
expectedCommit: remote.remoteHead,
expectedAnchorVersion: publicSnapshot.anchor_version,
endpoint: options.publicSnapshotHealth || PUBLIC_SNAPSHOT_HEALTH,
probe: options.publicSnapshotProbe,
})
: null;
const publishReceipt =
`PASS_100 remote=${repository.identity}#${branch} ` +
`head=${remote.remoteHead} receipts=${verified.receiptEvidence
`head=${remote.remoteHead} public_acceptance=${publicAcceptance ? "PASS_100" : "NOT_APPLICABLE"} receipts=${verified.receiptEvidence
.map((item) => `${item.path}:${item.sha256}`)
.join(",")}`;
finishPublish(
@ -545,6 +615,7 @@ export async function finalize(options) {
fresh_clone_readback: 100,
git_fsck: 100,
receipts: verified.receiptEvidence,
public_snapshot_acceptance: publicAcceptance,
},
cleanup: {
scope: "CURRENT_WORKTREE_IGNORED_ALLOWLISTED_CACHES_ONLY",

View file

@ -12,6 +12,7 @@ import {
safeCacheRelative,
selfTest,
sha256,
waitForPublicSnapshotAcceptance,
} from "./finalize-development.mjs";
test("the finalizer accepts only the registered Fifth Domain code channel", () => {
@ -88,3 +89,37 @@ test("macOS AppleDouble sidecars are never parsed as JSON records", () => {
test("receipt hashes preserve exact trailing bytes", () => {
assert.notEqual(sha256(Buffer.from("{}")), sha256(Buffer.from("{}\n")));
});
test("public snapshot acceptance returns the accepted exact commit", async () => {
let calls = 0;
const result = await waitForPublicSnapshotAcceptance({
expectedCommit: "abc123",
expectedAnchorVersion: "test.3",
attempts: 2,
delayMs: 0,
probe: async () => {
calls += 1;
return calls === 1
? { status: 503, body: { navigation_source: { source_degraded: true } } }
: { status: 200, body: { navigation_source: { source_degraded: false, source_commit: "abc123", anchor_version: "test.3" } } };
},
});
assert.equal(result.result, "PASS_100");
assert.equal(result.attempt, 2);
});
test("public snapshot acceptance fails closed with actionable source feedback", async () => {
await assert.rejects(
waitForPublicSnapshotAcceptance({
expectedCommit: "new",
expectedAnchorVersion: "test.3",
attempts: 1,
delayMs: 0,
probe: async () => ({
status: 503,
body: { navigation_source: { source_degraded: true, source_commit: "old", anchor_version: "test.2", source_error_code: "snapshot_map_version_mismatch:lighthouse_paths" } },
}),
}),
/PUBLIC_SNAPSHOT_NOT_ACCEPTED.*snapshot_map_version_mismatch:lighthouse_paths/,
);
});