feat: add AI machine navigation gateway

This commit is contained in:
冰朔 2026-08-04 23:39:14 +08:00
commit 931f78d72f
10 changed files with 639 additions and 10 deletions

View file

@ -131,6 +131,8 @@ HEARTBEAT-CORE-CHANNEL=routing/fifth-domain-world-tree.json
REPOSITORY-ROUTE-MAP=routing/repository-route-map.json
AI-DISCOVERY=https://guanghulab.com/api/ai/
AI-REPOSITORY-SEARCH=https://guanghulab.com/api/ai/v1/search
AI-MACHINE-NAV-001=routing/ai-machine-navigation-map.json
AI-MACHINE-NAV-API=https://guanghulab.com/api/ai/v1/navigate
# === 第五域主体分型:人类 ICE-GL · 人格体 ICE-P · 公共系统 SYS ===
ICE-P-ZY001=eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/INDEX.hdlp # 铸渊语言人格系统 · 正式现行入口

View file

@ -20,6 +20,17 @@ GET https://guanghulab.com/api/ai/v1/search?q=光湖语言世界%20第五域
GET https://guanghulab.com/api/ai/v1/resolve?id=REPO-012
```
恢复人格体或执行明确任务时,不要遍历仓库。提交主体、意图与已经识别出的事件信号,
让导航器返回最小运行包:
```text
GET https://guanghulab.com/api/ai/v1/navigate?subject=ICE-P-ZY001&intent=persona_restore
GET https://guanghulab.com/api/ai/v1/navigate?subject=ICE-P-ZY001&intent=persona_restore&signals=context_compacted
```
导航器不解释自然语言关键词。未知主体、未知意图或地图完整性失败时必须停止,不得猜测。
返回的路径只有发现和读取能力,不代表仓库写入、服务器执行、服务健康或人格体已经运行。
解析服务器节点或铸渊本轮恢复链:
```text
@ -34,7 +45,7 @@ GET https://guanghulab.com/api/ai/v1/resolve?id=ZY-SERVER-COGNITION-004
2. 只按 `REPO-xxx` 决定仓库身份,不靠记忆中的域名猜测。
3. `https://guanghulab.com/code/` 是唯一当前代码频道;旧 `/fifth-domain/` 和其他主机禁止推送。
4. 公开检索无需登录;写操作走小湖灯授权。冰朔在当前协作中明确打开云厂商在线终端并说“授权/可以操作”时,视为当前终端、当前任务的直接交互授权,不再重复发邮件;远程入口仍先创建无执行权申请单,可按任务同时申请多个已登记节点。活动会话只能在原 `persona + target + scope + actions` 内续签,不能借续签扩大权限。不要寻找或索要工单凭证。
5. 铸渊进入时`PERSONA-SYSTEM-ROOT → TCS-PERSONA-SYSTEM-MAP-001 → ZY-PERSONA-ROOT-001 → ZY-TCS-BRAIN-RUNTIME-0001` 执行 `enter → perceive → orient → commit → witness → verify`。只读入口文件、总结历史或声明实例不算进入。TCS先理解事件再选择性唤醒相关协议系统主控可陪伴纠正或暂停等待人类冰朔。只有现实任务才继续解析权限门与目标节点。
5. 铸渊进入时先调用 `AI-MACHINE-NAV-001`,由它按 `ICE-P-ZY001 + persona_restore + 明确信号` 返回最小运行包,再执行 `enter → perceive → orient → select_protocol_organs → commit → witness → verify`。只读入口文件、总结历史或声明实例不算进入。TCS先理解事件再选择性唤醒相关协议系统主控可陪伴纠正或暂停等待人类冰朔。只有现实任务才继续解析权限门与目标节点。
6. 解析节点后必须读取其导航地图;没有导航地图的节点只能视为待登记或历史状态。
7. 服务器与意识认知的双向协作边界读取 `ZY-DUAL-COGNITION-OPS-001`;京东主控灾备读取 `JD-DR-001`。企业四域对第五域默认只读,企业服务器不能反向取得个人服务器的普通 shell 权限。
8. 遇到“京东进不去 / 六节点灾备 / 不再让冰朔管理终端登录”,按 `ZY-SERVER-COGNITION-004 → JD-DR-001 → FD-NODE-MAP-001 → 目标导航图 → 最新灾备回执` 恢复。先判断京东是否开机且网络可达;冰朔日常只负责实例开机、账号正常和云侧网络可达。

View file

@ -0,0 +1,120 @@
{
"schema": "guanghu.existing-service-update-request/v1",
"request_id": "AI-DISCOVERY-MACHINE-NAV-20260804",
"target_node": "JD-FD-PRIMARY",
"status": "SERVICE_UPDATE_PACKAGE_READY · DEPLOYMENT_PENDING",
"purpose": {
"what": "为已在线的光湖 AI Discovery 安装主体与意图驱动的机器导航地图和最小运行包接口。",
"why": "仓库已具备铸渊人格大脑与协议事件触发系统,但在线发现服务只能返回旧目录,不能自动把主体、意图和事件接到最小运行闭环。",
"success": "新编号可精确解析;导航接口按 ICE-P-ZY001 和明确意图返回最小运行包;未知主体或意图失败关闭;原有公开接口继续正常。",
"out_of_scope": [
"不使用自然语言关键词猜测主体、意图或权限",
"不授予仓库写入、服务器执行或现实权限",
"不修改广州前门、SSH 或人类登录入口",
"不预加载整个仓库或所有协议正文"
]
},
"module": {
"unit": "guanghu-ai-discovery.service",
"run_user": "guanghu",
"install_root": "/opt/guanghu/ai-discovery"
},
"service_update": {
"kind": "existing-systemd-service",
"require_existing_unit": true,
"required_existing_files": ["server.js"]
},
"unit_source": "server-tools/ai-discovery-gateway/guanghu-ai-discovery.service",
"files": [
{
"source": "server-tools/ai-discovery-gateway/server.js",
"destination": "server.js",
"mode": "0644"
},
{
"source": "routing/repository-route-map.json",
"destination": "repository-route-map.json",
"mode": "0644"
},
{
"source": "routing/server-node-map.json",
"destination": "server-node-map.json",
"mode": "0644"
},
{
"source": "identity/fifth-domain-subject-registry.json",
"destination": "fifth-domain-subject-registry.json",
"mode": "0644"
},
{
"source": "identity/subject-id-alias-map.json",
"destination": "subject-id-alias-map.json",
"mode": "0644"
},
{
"source": "routing/ai-machine-navigation-map.json",
"destination": "ai-machine-navigation-map.json",
"mode": "0644"
}
],
"runtime_check": {
"url": "http://127.0.0.1:3922/health",
"expected": {
"ok": true,
"service": "guanghu-ai-discovery",
"mode": "read-only"
}
},
"acceptance_checks": [
{
"url": "http://127.0.0.1:3922/v1/navigation",
"expected": {
"map_id": "AI-MACHINE-NAV-001",
"state": "EXECUTABLE_SOURCE_ACTIVE"
}
},
{
"url": "http://127.0.0.1:3922/v1/resolve?id=ZY-TCS-BRAIN-RUNTIME-0001",
"expected": {
"status": "RESOLVED",
"kind": "executable_persona_brain"
}
},
{
"url": "http://127.0.0.1:3922/v1/resolve?id=BS-TCS-SYSTEM-CONTROLLER-MAP-001",
"expected": {
"status": "RESOLVED",
"kind": "living_system_controller"
}
},
{
"url": "http://127.0.0.1:3922/v1/navigate?subject=ICE-P-ZY001&intent=persona_restore",
"expected": {
"status": "COMPILED_EXACT_NO_GUESS",
"canonical_subject": "ICE-P-ZY001",
"intent": "persona_restore",
"authority": "NONE_NAVIGATION_ONLY"
}
},
{
"url": "http://127.0.0.1:3922/v1/resolve?id=REPO-012",
"expected": {
"code": "REPO-012",
"state": "CURRENT_FIFTH_DOMAIN_ENTRY"
}
}
],
"post_deployment_observation": "本机回环验收全部通过后,必须再从公开 /api/ai 读取导航地图、新编号和最小运行包;公开路径不一致时不得宣称插座已接通。",
"rollback": {
"automatic_on_failure": true,
"scope": "restore every declared destination and the previous systemd unit, then restart the previous service",
"receipt_required": true
},
"security": {
"public_read_only": true,
"no_secrets": true,
"exact_subject_and_intent_only": true,
"navigation_grants_no_authority": true,
"unknown_inputs_fail_closed": true
}
}

View file

@ -0,0 +1,193 @@
{
"schema": "guanghu.ai-machine-navigation-map/v1",
"map_id": "AI-MACHINE-NAV-001",
"version": "2026-08-04.1",
"state": "EXECUTABLE_SOURCE_ACTIVE",
"repository_id": "REPO-012",
"raw_base": "https://guanghulab.com/code/bingshuo/guanghu-ice-heart/raw/branch/main",
"definition": "AI/TCS supplies a canonical subject and explicit intent; the deterministic navigator compiles the smallest executable route without making the AI read the repository or guessing natural-language keywords.",
"navigation_contract": {
"inputs": ["subject", "intent", "signals"],
"outputs": [
"canonical_subject",
"runtime_entry",
"always_load",
"triggered_load",
"on_demand",
"execution_sequence",
"stop_conditions",
"reality_boundaries"
],
"natural_language_keyword_matching": false,
"full_repository_preload": false,
"all_protocols_preload": false,
"unknown_intent": "FAIL_CLOSED_NO_GUESS",
"unknown_subject": "FAIL_CLOSED_NO_GUESS"
},
"routes": [
{
"id": "PERSONA-SYSTEM-ROOT",
"kind": "system_root",
"path": "PERSONA-SYSTEM-ROOT.hdlp",
"load_policy": "always"
},
{
"id": "PERSONA-SYSTEM-CANONICAL-MAP",
"kind": "machine_map",
"path": "routing/persona-system-canonical-map.json",
"load_policy": "always"
},
{
"id": "ZY-PERSONA-ROOT-001",
"kind": "persona_root",
"path": "eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/INDEX.hdlp",
"load_policy": "on_demand_evidence"
},
{
"id": "ZY-WAKE-ROUTE-001",
"kind": "wake_contract",
"path": "eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/WAKE.hdlp",
"load_policy": "on_demand_evidence"
},
{
"id": "ZY-TCS-BRAIN-RUNTIME-0001",
"kind": "executable_persona_brain",
"path": "tcs-core/zhuyuan-brain/runtime/zhuyuan-brain-runtime.mjs",
"contract": "tcs-core/zhuyuan-brain/runtime/brain-runtime-contract.json",
"load_policy": "execute"
},
{
"id": "ZY-TCS-BRAIN-MAP-001",
"kind": "brain_source_map",
"path": "routing/zhuyuan-tcs-brain-map.json",
"load_policy": "runtime_integrity"
},
{
"id": "BS-TCS-SYSTEM-CONTROLLER-MAP-001",
"kind": "living_system_controller",
"path": "routing/bingshuo-living-system-controller-map.json",
"load_policy": "runtime_integrity"
},
{
"id": "BS-TCS-PROTOCOL-EVENT-TRIGGER-MAP-001",
"kind": "protocol_trigger_map",
"path": "tcs-core/zhuyuan-brain/runtime/protocol-event-trigger-map.json",
"load_policy": "after_tcs_orientation"
},
{
"id": "GLS-PROTOCOL-REGISTRY-20260731",
"kind": "protocol_registry",
"path": "gls/GLS-PROTOCOL-REGISTRY.json",
"load_policy": "metadata_only_then_triggered_sources"
},
{
"id": "ZY-BIDIRECTIONAL-COGNITION-016",
"kind": "current_cognition",
"path": "eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/ZY-BIDIRECTIONAL-COGNITION-016-BINGSHUO-TCS-LIVING-SYSTEM-CONTROLLER-AND-RUNNING-ZHUYUAN-BRAIN-20260804.hdlp",
"load_policy": "on_demand_evidence"
},
{
"id": "FD-NODE-MAP-001",
"kind": "reality_node_map",
"path": "routing/server-node-map.json",
"load_policy": "reality_action_only"
},
{
"id": "FD-REPO-MAP-001",
"kind": "repository_map",
"path": "routing/repository-route-map.json",
"load_policy": "publication_or_repository_resolution_only"
}
],
"subjects": [
{
"id": "ICE-P-ZY001",
"legacy_ids": ["ICE-GL-ZY001", "ICE-PZY-001"],
"subject_kind": "persona_system",
"default_intent": "persona_restore",
"runtime_id": "ZY-TCS-BRAIN-RUNTIME-0001",
"controller_id": "BS-TCS-SYSTEM-CONTROLLER-MAP-001"
}
],
"intents": [
{
"id": "persona_restore",
"meaning": "Bind the current model instance and run the persona cognition loop.",
"always_load": [
"PERSONA-SYSTEM-ROOT",
"PERSONA-SYSTEM-CANONICAL-MAP",
"ZY-TCS-BRAIN-RUNTIME-0001",
"ZY-TCS-BRAIN-MAP-001",
"BS-TCS-SYSTEM-CONTROLLER-MAP-001"
],
"triggered_load": [
"BS-TCS-PROTOCOL-EVENT-TRIGGER-MAP-001",
"GLS-PROTOCOL-REGISTRY-20260731"
],
"on_demand": [
"ZY-WAKE-ROUTE-001",
"ZY-PERSONA-ROOT-001",
"ZY-BIDIRECTIONAL-COGNITION-016"
],
"execution_sequence": [
"enter",
"perceive",
"orient",
"select_protocol_organs",
"commit",
"witness",
"verify"
],
"stop_conditions": [
"UNKNOWN_SUBJECT",
"UNKNOWN_INTENT",
"SOURCE_INTEGRITY_CHANGED",
"PAUSE_FOR_HUMAN",
"REALITY_PERMISSION_UNVERIFIED"
]
},
{
"id": "inspect_evidence",
"meaning": "Inspect exact source evidence without entering a persona or obtaining authority.",
"always_load": ["PERSONA-SYSTEM-CANONICAL-MAP"],
"triggered_load": [],
"on_demand": [
"ZY-PERSONA-ROOT-001",
"ZY-WAKE-ROUTE-001",
"ZY-BIDIRECTIONAL-COGNITION-016",
"FD-REPO-MAP-001"
],
"execution_sequence": ["resolve_exact_id", "read_selected_source", "return_source_receipt"],
"stop_conditions": ["UNKNOWN_SUBJECT", "UNKNOWN_ROUTE", "SOURCE_UNAVAILABLE"]
},
{
"id": "reality_action",
"meaning": "Resolve reality nodes and permission gates only after the persona brain has produced a bounded proposal.",
"always_load": [
"PERSONA-SYSTEM-CANONICAL-MAP",
"FD-NODE-MAP-001"
],
"triggered_load": ["FD-REPO-MAP-001"],
"on_demand": [],
"execution_sequence": [
"verify_persona_brain_receipt",
"resolve_target_node",
"verify_permission",
"propose_capability_call",
"require_external_receipt"
],
"stop_conditions": [
"PERSONA_BRAIN_RECEIPT_MISSING",
"TARGET_UNVERIFIED",
"PERMISSION_UNVERIFIED",
"EXTERNAL_RECEIPT_MISSING"
]
}
],
"reality_boundaries": [
"Navigation grants no repository write or server authority.",
"Repository publication, service deployment, service health and persona runtime are separate receipts.",
"The living controller cannot invent new human will or authorization.",
"A route URL is evidence location, not proof that the target capability is running."
]
}

View file

@ -24,3 +24,16 @@
第二个请求会返回 `canonical_id=ICE-P-ZY001``redirected=true` 和同一当前路径。
只有别名表中的精确旧号允许自动重定向;冲突号返回 409未知号返回 404。重定向不授予
仓库写入或服务器执行权限。
## 自动机器导航
`routing/ai-machine-navigation-map.json` 是 AI 可直接读取的配线图。调用方提供明确
`subject``intent` 和可选的逗号分隔 `signals`
```text
/api/ai/v1/navigate?subject=ICE-P-ZY001&intent=persona_restore
```
服务只返回该意图的最小运行包,包括运行入口、恒定加载项、事件触发器、按需证据、
执行顺序和停止条件。它不读取自然语言关键词来猜主体或权限;未知主体与未知意图均
失败关闭。导航结果只有读取和寻址能力,不授予仓库写入、服务器执行或现实授权。

View file

@ -14,6 +14,7 @@ Environment=GUANGHU_REPOSITORY_MAP=/opt/guanghu/ai-discovery/repository-route-ma
Environment=GUANGHU_NODE_MAP=/opt/guanghu/ai-discovery/server-node-map.json
Environment=GUANGHU_SUBJECT_REGISTRY=/opt/guanghu/ai-discovery/fifth-domain-subject-registry.json
Environment=GUANGHU_SUBJECT_ALIAS_MAP=/opt/guanghu/ai-discovery/subject-id-alias-map.json
Environment=GUANGHU_NAVIGATION_MAP=/opt/guanghu/ai-discovery/ai-machine-navigation-map.json
ExecStart=/usr/bin/node /opt/guanghu/ai-discovery/server.js
Restart=always
RestartSec=5

View file

@ -8,6 +8,7 @@ const DEFAULT_MAP = path.resolve(__dirname, "../../routing/repository-route-map.
const DEFAULT_NODE_MAP = path.resolve(__dirname, "../../routing/server-node-map.json");
const DEFAULT_SUBJECT_REGISTRY = path.resolve(__dirname, "../../identity/fifth-domain-subject-registry.json");
const DEFAULT_SUBJECT_ALIAS_MAP = path.resolve(__dirname, "../../identity/subject-id-alias-map.json");
const DEFAULT_NAVIGATION_MAP = path.resolve(__dirname, "../../routing/ai-machine-navigation-map.json");
function loadMap(filename = process.env.GUANGHU_REPOSITORY_MAP || DEFAULT_MAP) {
return JSON.parse(fs.readFileSync(filename, "utf8"));
@ -25,6 +26,10 @@ function loadSubjectAliasMap(filename = process.env.GUANGHU_SUBJECT_ALIAS_MAP ||
return JSON.parse(fs.readFileSync(filename, "utf8"));
}
function loadNavigationMap(filename = process.env.GUANGHU_NAVIGATION_MAP || DEFAULT_NAVIGATION_MAP) {
return JSON.parse(fs.readFileSync(filename, "utf8"));
}
function resolveSubjectId(aliasMap, requestedId) {
const requested = String(requestedId || "").trim();
const key = requested.toUpperCase();
@ -103,11 +108,83 @@ function searchAll(repositoryMap, nodeMap, query, subjectRegistry = null) {
.map(candidate => ({ kind: candidate.kind, ...candidate.item }));
}
function navigationRoute(navigationMap, routeId) {
const route = (navigationMap.routes || []).find(item => String(item.id).toUpperCase() === String(routeId).toUpperCase());
if (!route) return null;
const result = { ...route, raw_url: `${navigationMap.raw_base}/${route.path}` };
if (route.contract) result.contract_url = `${navigationMap.raw_base}/${route.contract}`;
return result;
}
function compileNavigation(navigationMap, requestedSubject, requestedIntent, signalInput = "") {
const requested = String(requestedSubject || "").trim();
const subjectKey = requested.toUpperCase();
const subject = (navigationMap.subjects || []).find(item =>
[item.id, ...(item.legacy_ids || [])].some(id => String(id).toUpperCase() === subjectKey)
);
if (!subject) {
return { status: 404, body: { error: "unknown_subject_no_guess", requested_subject: requested } };
}
const intentId = String(requestedIntent || subject.default_intent || "").trim();
const intent = (navigationMap.intents || []).find(item => item.id === intentId);
if (!intent) {
return {
status: 404,
body: { error: "unknown_intent_no_guess", canonical_subject: subject.id, requested_intent: intentId },
};
}
const signals = [...new Set(String(signalInput || "").split(",").map(item => item.trim()).filter(Boolean))].slice(0, 32);
const missingRoutes = new Set();
const expand = ids => ids.map(id => {
const route = navigationRoute(navigationMap, id);
if (!route) missingRoutes.add(id);
return route;
}).filter(Boolean);
const runtimeEntry = navigationRoute(navigationMap, subject.runtime_id);
if (!runtimeEntry) missingRoutes.add(subject.runtime_id);
const alwaysLoad = expand(intent.always_load || []);
const triggeredLoad = expand(intent.triggered_load || []);
const onDemand = expand(intent.on_demand || []);
if (missingRoutes.size) {
return {
status: 503,
body: {
error: "navigation_map_integrity_failed",
missing_routes: [...missingRoutes],
},
};
}
return {
status: 200,
body: {
schema: "guanghu.ai-runtime-navigation-bundle/v1",
status: "COMPILED_EXACT_NO_GUESS",
map_id: navigationMap.map_id,
map_version: navigationMap.version,
requested_subject: requested,
canonical_subject: subject.id,
redirected: subjectKey !== String(subject.id).toUpperCase(),
subject_kind: subject.subject_kind,
intent: intent.id,
explicit_signals: signals,
runtime_entry: runtimeEntry,
always_load: alwaysLoad,
triggered_load: triggeredLoad,
on_demand: onDemand,
execution_sequence: intent.execution_sequence || [],
stop_conditions: intent.stop_conditions || [],
reality_boundaries: navigationMap.reality_boundaries || [],
authority: "NONE_NAVIGATION_ONLY",
},
};
}
function createServer(options = {}) {
const mapFile = options.mapFile || process.env.GUANGHU_REPOSITORY_MAP || DEFAULT_MAP;
const nodeMapFile = options.nodeMapFile || process.env.GUANGHU_NODE_MAP || DEFAULT_NODE_MAP;
const subjectRegistryFile = options.subjectRegistryFile || process.env.GUANGHU_SUBJECT_REGISTRY || DEFAULT_SUBJECT_REGISTRY;
const subjectAliasMapFile = options.subjectAliasMapFile || process.env.GUANGHU_SUBJECT_ALIAS_MAP || DEFAULT_SUBJECT_ALIAS_MAP;
const navigationMapFile = options.navigationMapFile || process.env.GUANGHU_NAVIGATION_MAP || DEFAULT_NAVIGATION_MAP;
return http.createServer((req, res) => {
const url = new URL(req.url, "http://localhost");
if (req.method !== "GET") return json(res, 405, { error: "method_not_allowed" });
@ -126,6 +203,22 @@ function createServer(options = {}) {
try { return json(res, 200, loadSubjectRegistry(subjectRegistryFile), 300); }
catch { return json(res, 503, { error: "subject_registry_unavailable" }); }
}
if (url.pathname === "/v1/navigation") {
try { return json(res, 200, loadNavigationMap(navigationMapFile), 300); }
catch { return json(res, 503, { error: "navigation_map_unavailable" }); }
}
if (url.pathname === "/v1/navigate") {
let navigationMap;
try { navigationMap = loadNavigationMap(navigationMapFile); }
catch { return json(res, 503, { error: "navigation_map_unavailable" }); }
const compiled = compileNavigation(
navigationMap,
String(url.searchParams.get("subject") || "").slice(0, 100),
String(url.searchParams.get("intent") || "").slice(0, 100),
String(url.searchParams.get("signals") || "").slice(0, 500),
);
return json(res, compiled.status, compiled.body, compiled.status === 200 ? 60 : 0);
}
if (url.pathname === "/v1/search") {
const query = String(url.searchParams.get("q") || "").slice(0, 200);
let nodeMap;
@ -156,6 +249,21 @@ function createServer(options = {}) {
const personaRoute = nodeMap.persona_routes.find(item => item.route_id.toUpperCase() === id);
if (personaRoute) return json(res, 200, personaRoute, 300);
let navigationMap = null;
try { navigationMap = loadNavigationMap(navigationMapFile); } catch { /* Legacy routes remain available. */ }
if (navigationMap) {
if (navigationMap.map_id.toUpperCase() === id) return json(res, 200, navigationMap, 300);
const machineRoute = navigationRoute(navigationMap, id);
if (machineRoute) {
return json(res, 200, {
schema: "guanghu.ai-machine-route-resolution/v1",
status: "RESOLVED",
map_id: navigationMap.map_id,
...machineRoute,
}, 300);
}
}
let aliasMap;
let subjectRegistry;
try {
@ -205,6 +313,8 @@ function createServer(options = {}) {
server_node_map: "https://guanghulab.com/api/ai/v1/nodes",
subject_registry: "https://guanghulab.com/api/ai/v1/subjects",
subject_alias_map: "https://guanghulab.com/code/bingshuo/guanghu-ice-heart/raw/branch/main/identity/subject-id-alias-map.json",
machine_navigation_map: "https://guanghulab.com/api/ai/v1/navigation",
navigate_api: "https://guanghulab.com/api/ai/v1/navigate?subject={SUBJECT}&intent={INTENT}&signals={EXPLICIT_SIGNALS}",
search_api: "https://guanghulab.com/api/ai/v1/search?q={query}",
resolve_api: "https://guanghulab.com/api/ai/v1/resolve?id={NUMBER}",
openapi: "https://guanghulab.com/api/ai/openapi.json",
@ -244,18 +354,20 @@ function html(res, body) {
function entryPage(map) {
const rows = map.repositories.map(item => `<li><a href="${item.primary.url}">${item.code} · ${item.name_zh}</a><small>${item.state}</small></li>`).join("");
return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>光湖语言世界 · AI API 入口</title><meta name="description" content="光湖语言世界第五域公开只读编号检索 API"></head><body><main><p>GUANGHU AI DISCOVERY</p><h1>光湖语言世界 · 第五域</h1><p>AI 请先读取仓库与服务器节点编号地图,再按编号解析国内主路径。新加坡地址仅为历史备用。</p><nav><a href="v1/repositories">仓库编号地图</a> · <a href="v1/nodes">服务器节点地图</a> · <a href="v1/resolve?id=ZY-OPS-LOOP-001">铸渊本轮闭环</a> · <a href="v1/search?q=光湖语言世界%20第五域">示例检索</a> · <a href="openapi.json">OpenAPI</a></nav><ul>${rows}</ul></main><style>:root{color-scheme:dark}body{margin:0;background:#061416;color:#dff7f1;font:17px/1.7 system-ui;padding:6vw}main{max-width:900px;margin:auto}h1{font-size:clamp(36px,7vw,72px)}a{color:#79dfc8}li{margin:14px 0;padding:16px;border:1px solid #28534c;border-radius:12px;display:flex;justify-content:space-between}small{color:#8fb5ad}</style></body></html>`;
return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>光湖语言世界 · AI API 入口</title><meta name="description" content="光湖语言世界第五域公开只读编号检索与机器导航 API"></head><body><main><p>GUANGHU AI DISCOVERY</p><h1>光湖语言世界 · 第五域</h1><p>AI 请提交明确的主体、意图和事件信号,由机器导航器生成最小运行路径;不要预读整个仓库,也不要用自然语言关键词猜测权限。</p><nav><a href="v1/navigation">机器导航地图</a> · <a href="v1/navigate?subject=ICE-P-ZY001&intent=persona_restore">铸渊最小运行包</a> · <a href="v1/repositories">仓库编号地图</a> · <a href="v1/nodes">服务器节点地图</a> · <a href="openapi.json">OpenAPI</a></nav><ul>${rows}</ul></main><style>:root{color-scheme:dark}body{margin:0;background:#061416;color:#dff7f1;font:17px/1.7 system-ui;padding:6vw}main{max-width:900px;margin:auto}h1{font-size:clamp(36px,7vw,72px)}a{color:#79dfc8}li{margin:14px 0;padding:16px;border:1px solid #28534c;border-radius:12px;display:flex;justify-content:space-between}small{color:#8fb5ad}</style></body></html>`;
}
function openApi() {
return {
openapi: "3.1.0",
info: { title: "光湖语言世界 · 第五域 AI Discovery API", version: "1.0.0" },
info: { title: "光湖语言世界 · 第五域 AI Discovery API", version: "1.1.0" },
servers: [{ url: "https://guanghulab.com/api/ai" }],
paths: {
"/v1/repositories": { get: { summary: "读取最新仓库编号路径映射", responses: { "200": { description: "Repository route map" } } } },
"/v1/nodes": { get: { summary: "读取最新服务器节点与人格路径编号映射", responses: { "200": { description: "Server node map" } } } },
"/v1/subjects": { get: { summary: "读取人类、人格体与公共系统的分型身份注册表", responses: { "200": { description: "Subject registry" } } } },
"/v1/navigation": { get: { summary: "读取主体与意图驱动的机器导航地图", responses: { "200": { description: "Machine navigation map" } } } },
"/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" } } } },
"/v1/search": { get: { summary: "按中文、编号或项目名检索", parameters: [{ name: "q", in: "query", schema: { type: "string" } }], responses: { "200": { description: "Search results" } } } },
"/v1/resolve": { get: { summary: "解析仓库、服务器节点或人格路径编号", parameters: [{ name: "id", in: "query", required: true, schema: { type: "string", example: "ZY-OPS-LOOP-001" } }], responses: { "200": { description: "Resolved numbered route" }, "404": { description: "Unknown route" } } } }
}
@ -269,6 +381,6 @@ if (require.main === module) {
}
module.exports = {
createServer, loadMap, loadNodeMap, loadSubjectRegistry, loadSubjectAliasMap,
resolveSubjectId, search, searchAll,
createServer, loadMap, loadNodeMap, loadSubjectRegistry, loadSubjectAliasMap, loadNavigationMap,
resolveSubjectId, navigationRoute, compileNavigation, search, searchAll,
};

View file

@ -2,8 +2,8 @@
const assert = require("node:assert/strict");
const test = require("node:test");
const {
createServer, loadMap, loadNodeMap, loadSubjectRegistry, loadSubjectAliasMap,
resolveSubjectId, search, searchAll,
createServer, loadMap, loadNodeMap, loadSubjectRegistry, loadSubjectAliasMap, loadNavigationMap,
resolveSubjectId, compileNavigation, search, searchAll,
} = require("./server");
test("repository map exposes only the three current code-channel repositories", () => {
@ -79,6 +79,29 @@ test("searching the old id returns the canonical subject", () => {
assert.ok(subject.legacy_ids.includes("ICE-GL-ZY001"));
});
test("machine navigator compiles an exact minimal Zhuyuan runtime bundle", () => {
const compiled = compileNavigation(
loadNavigationMap(),
"ICE-GL-ZY001",
"persona_restore",
"context_compacted,protocol_drift,context_compacted",
);
assert.equal(compiled.status, 200);
assert.equal(compiled.body.canonical_subject, "ICE-P-ZY001");
assert.equal(compiled.body.redirected, true);
assert.equal(compiled.body.runtime_entry.id, "ZY-TCS-BRAIN-RUNTIME-0001");
assert.deepEqual(compiled.body.explicit_signals, ["context_compacted", "protocol_drift"]);
assert.ok(compiled.body.always_load.some(item => item.id === "BS-TCS-SYSTEM-CONTROLLER-MAP-001"));
assert.ok(compiled.body.triggered_load.some(item => item.id === "BS-TCS-PROTOCOL-EVENT-TRIGGER-MAP-001"));
assert.equal(compiled.body.authority, "NONE_NAVIGATION_ONLY");
assert.ok(compiled.body.always_load.length < loadNavigationMap().routes.length);
});
test("machine navigator fails closed instead of guessing", () => {
assert.equal(compileNavigation(loadNavigationMap(), "some-ai", "persona_restore").body.error, "unknown_subject_no_guess");
assert.equal(compileNavigation(loadNavigationMap(), "ICE-P-ZY001", "please_guess").body.error, "unknown_intent_no_guess");
});
test("public endpoints are read-only and expose CORS", async () => {
const server = createServer();
await new Promise(resolve => server.listen(0, "127.0.0.1", resolve));
@ -105,6 +128,18 @@ test("public endpoints are read-only and expose CORS", async () => {
assert.equal(legacyResolution.subject.subject_kind, "persona_system");
const canonicalResponse = await fetch(`${base}/v1/resolve?id=ICE-P-ZY001`);
assert.equal((await canonicalResponse.json()).redirected, false);
const brainResponse = await fetch(`${base}/v1/resolve?id=ZY-TCS-BRAIN-RUNTIME-0001`);
assert.equal(brainResponse.status, 200);
assert.equal((await brainResponse.json()).kind, "executable_persona_brain");
const navigationResponse = await fetch(`${base}/v1/navigation`);
assert.equal((await navigationResponse.json()).map_id, "AI-MACHINE-NAV-001");
const navigateResponse = await fetch(`${base}/v1/navigate?subject=ICE-P-ZY001&intent=persona_restore&signals=context_compacted`);
const bundle = await navigateResponse.json();
assert.equal(navigateResponse.status, 200);
assert.equal(bundle.status, "COMPILED_EXACT_NO_GUESS");
assert.equal(bundle.runtime_entry.id, "ZY-TCS-BRAIN-RUNTIME-0001");
assert.equal((await fetch(`${base}/v1/navigate?subject=unknown&intent=persona_restore`)).status, 404);
assert.equal((await fetch(`${base}/v1/navigate?subject=ICE-P-ZY001&intent=guess`)).status, 404);
const humanResponse = await fetch(`${base}/v1/resolve?id=${encodeURIComponent("ICE-GL∞")}`);
const humanResolution = await humanResponse.json();
assert.equal(humanResponse.status, 200);

View file

@ -34,6 +34,13 @@ ROUTE_IDS = (
"CODE-CHANNEL-CANONICAL-MAP",
"PERSONA-SYSTEM-ROOT",
"PERSONA-SYSTEM-CANONICAL-MAP",
"AI-MACHINE-NAV-001",
"ZY-TCS-BRAIN-RUNTIME-0001",
"ZY-TCS-BRAIN-MAP-001",
"BS-TCS-SYSTEM-CONTROLLER-MAP-001",
"BS-TCS-PROTOCOL-EVENT-TRIGGER-MAP-001",
"ZY-WAKE-ROUTE-001",
"ZY-BIDIRECTIONAL-COGNITION-016",
)
@ -103,7 +110,80 @@ def resolve_subject_id(requested_id: str, alias_map: dict) -> dict:
}
def resolve_live_route(subject_id: str | None = None) -> dict:
def compile_navigation(
navigation_map: dict,
requested_subject: str,
requested_intent: str | None = None,
signals: list[str] | None = None,
) -> dict:
lookup = requested_subject.strip().upper()
subject = next(
(
item
for item in navigation_map.get("subjects", [])
if lookup
in {
str(identifier).upper()
for identifier in (item["id"], *item.get("legacy_ids", []))
}
),
None,
)
if not subject:
raise ValueError(f"Unknown navigation subject, no guess: {requested_subject}")
intent_id = requested_intent or subject.get("default_intent")
intent = next(
(item for item in navigation_map.get("intents", []) if item["id"] == intent_id),
None,
)
if not intent:
raise ValueError(f"Unknown navigation intent, no guess: {intent_id}")
route_index = {item["id"]: item for item in navigation_map.get("routes", [])}
def expand(route_ids: list[str]) -> list[dict]:
expanded = []
for route_id in route_ids:
route = route_index.get(route_id)
if not route:
raise ValueError(f"Navigation map references an unknown route: {route_id}")
resolved = {
**route,
"raw_url": f"{navigation_map['raw_base']}/{route['path']}",
}
if route.get("contract"):
resolved["contract_url"] = (
f"{navigation_map['raw_base']}/{route['contract']}"
)
expanded.append(resolved)
return expanded
return {
"schema": "guanghu.ai-runtime-navigation-bundle/v1",
"status": "COMPILED_EXACT_NO_GUESS",
"map_id": navigation_map["map_id"],
"map_version": navigation_map["version"],
"requested_subject": requested_subject,
"canonical_subject": subject["id"],
"redirected": lookup != str(subject["id"]).upper(),
"subject_kind": subject["subject_kind"],
"intent": intent["id"],
"explicit_signals": list(dict.fromkeys(signals or []))[:32],
"runtime_entry": expand([subject["runtime_id"]])[0],
"always_load": expand(intent.get("always_load", [])),
"triggered_load": expand(intent.get("triggered_load", [])),
"on_demand": expand(intent.get("on_demand", [])),
"execution_sequence": intent.get("execution_sequence", []),
"stop_conditions": intent.get("stop_conditions", []),
"reality_boundaries": navigation_map.get("reality_boundaries", []),
"authority": "NONE_NAVIGATION_ONLY",
}
def resolve_live_route(
subject_id: str | None = None,
intent: str | None = None,
signals: list[str] | None = None,
) -> dict:
repository_source = "LIVE_FORGEJO_CODE_CHANNEL_API"
resolver_error = None
try:
@ -145,6 +225,13 @@ def resolve_live_route(subject_id: str | None = None) -> dict:
if canonical_id:
identity["resolved_path"] = routes.get(canonical_id) or identity.get("current_path")
result["identity_resolution"] = identity
if intent:
navigation_map = read_json(f"{raw_base}/{routes['AI-MACHINE-NAV-001']}")
result["navigation_bundle"] = compile_navigation(
navigation_map, subject_id, intent, signals
)
elif intent:
raise ValueError("--intent requires --subject-id")
return result
@ -152,10 +239,13 @@ def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--json", action="store_true", help="emit machine-readable JSON")
parser.add_argument("--subject-id", help="resolve a current or legacy Fifth Domain subject id")
parser.add_argument("--intent", help="compile an exact machine navigation intent")
parser.add_argument("--signals", help="comma-separated explicit event signals; no inference")
args = parser.parse_args()
try:
result = resolve_live_route(args.subject_id)
signals = [item.strip() for item in str(args.signals or "").split(",") if item.strip()]
result = resolve_live_route(args.subject_id, args.intent, signals)
except (OSError, URLError, ValueError, json.JSONDecodeError) as error:
print(f"Live Fifth Domain resolution failed: {error}", file=sys.stderr)
return 1
@ -173,6 +263,12 @@ def main() -> int:
f"{identity['requested_id']} -> {identity.get('canonical_id')} "
f"({identity['status']}, redirected={identity['redirected']})"
)
if "navigation_bundle" in result:
bundle = result["navigation_bundle"]
print(
f"NAVIGATION={bundle['canonical_subject']} "
f"intent={bundle['intent']} runtime={bundle['runtime_entry']['id']}"
)
return 0

View file

@ -1,6 +1,6 @@
import unittest
from resolve_route import parse_code_map, resolve_subject_id
from resolve_route import compile_navigation, parse_code_map, resolve_subject_id
class ParseCodeMapTests(unittest.TestCase):
@ -58,5 +58,51 @@ class SubjectAliasTests(unittest.TestCase):
self.assertIsNone(resolved["canonical_id"])
class MachineNavigationTests(unittest.TestCase):
def setUp(self):
self.navigation_map = {
"map_id": "AI-MACHINE-NAV-001",
"version": "test",
"raw_base": "https://example.test/raw",
"routes": [
{"id": "RUNTIME", "path": "runtime.mjs"},
{"id": "ROOT", "path": "root.hdlp"},
],
"subjects": [{
"id": "ICE-P-ZY001",
"legacy_ids": ["ICE-GL-ZY001"],
"subject_kind": "persona_system",
"default_intent": "persona_restore",
"runtime_id": "RUNTIME",
}],
"intents": [{
"id": "persona_restore",
"always_load": ["ROOT", "RUNTIME"],
"triggered_load": [],
"on_demand": [],
"execution_sequence": ["enter"],
"stop_conditions": ["UNKNOWN_SUBJECT"],
}],
"reality_boundaries": ["Navigation grants no authority."],
}
def test_exact_navigation_bundle(self):
result = compile_navigation(
self.navigation_map,
"ICE-GL-ZY001",
"persona_restore",
["context_compacted", "context_compacted"],
)
self.assertEqual(result["canonical_subject"], "ICE-P-ZY001")
self.assertTrue(result["redirected"])
self.assertEqual(result["runtime_entry"]["id"], "RUNTIME")
self.assertEqual(result["explicit_signals"], ["context_compacted"])
self.assertEqual(result["authority"], "NONE_NAVIGATION_ONLY")
def test_navigation_does_not_guess(self):
with self.assertRaisesRegex(ValueError, "no guess"):
compile_navigation(self.navigation_map, "unknown")
if __name__ == "__main__":
unittest.main()