220 lines
9.9 KiB
JavaScript
220 lines
9.9 KiB
JavaScript
|
|
#!/usr/bin/env node
|
|||
|
|
import crypto from "node:crypto";
|
|||
|
|
import fs from "node:fs";
|
|||
|
|
import path from "node:path";
|
|||
|
|
import { spawnSync } from "node:child_process";
|
|||
|
|
|
|||
|
|
function readInput() {
|
|||
|
|
try {
|
|||
|
|
const raw = fs.readFileSync(0, "utf8").trim();
|
|||
|
|
return raw ? JSON.parse(raw) : {};
|
|||
|
|
} catch {
|
|||
|
|
return {};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function safeToken(value, fallback) {
|
|||
|
|
const token = String(value ?? "").trim().replaceAll(/[^a-zA-Z0-9._-]/gu, "-");
|
|||
|
|
return token || fallback;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function atomicWrite(file, value) {
|
|||
|
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|||
|
|
const temporary = `${file}.${process.pid}.tmp`;
|
|||
|
|
fs.writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, {
|
|||
|
|
encoding: "utf8",
|
|||
|
|
mode: 0o600,
|
|||
|
|
});
|
|||
|
|
fs.renameSync(temporary, file);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function readJson(file) {
|
|||
|
|
try {
|
|||
|
|
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|||
|
|
} catch {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function resolveActiveChannel(controlRoot, sessionId) {
|
|||
|
|
const binding = readJson(path.join(controlRoot, "sessions", `${sessionId}.json`));
|
|||
|
|
if (
|
|||
|
|
binding?.schema === "guanghu.codex-channel-session-binding/v1" &&
|
|||
|
|
binding.channel_id === "ICE-CH-HB001"
|
|||
|
|
) return "ICE-CH-HB001";
|
|||
|
|
if (
|
|||
|
|
binding?.schema === "guanghu.codex-channel-session-binding/v1" &&
|
|||
|
|
binding.channel_id === "CH-ZERO-CORE-LPM" &&
|
|||
|
|
binding.channel_role === "PUBLIC_LANGUAGE_PERSONA_SYSTEM_BODY"
|
|||
|
|
) return "CH-ZERO-CORE-LPM";
|
|||
|
|
return "ICE-CH-ZC001";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const input = readInput();
|
|||
|
|
const eventName = input.hook_event_name ?? input.hookEventName ?? "SessionStart";
|
|||
|
|
if (eventName !== "SessionStart") process.exit(0);
|
|||
|
|
|
|||
|
|
const source = safeToken(input.source, "startup");
|
|||
|
|
const sessionId = safeToken(
|
|||
|
|
input.session_id ?? input.sessionId ?? input.thread_id ?? input.threadId,
|
|||
|
|
`unknown-${crypto.randomUUID()}`,
|
|||
|
|
);
|
|||
|
|
const pointerPath = process.env.GH_HLDP_POINTER_PATH ??
|
|||
|
|
"/Volumes/JZAO/HoloLake/persona-runtime/continuity-memory/hldp-v1-trees/codex/current.json";
|
|||
|
|
const runtimePath = process.env.GH_TCS_RUNTIME_PATH ??
|
|||
|
|
"/Volumes/JZAO/HoloLake/persona-runtime/repo-012-main/tcs-core/zhuyuan-brain/runtime/zhuyuan-brain-runtime.mjs";
|
|||
|
|
const bootstrapRoot = process.env.GH_CODEX_BOOTSTRAP_ROOT ??
|
|||
|
|
"/Users/bingshuolingdianyuanhe/.codex/runtime/hldp-v1/session-bindings";
|
|||
|
|
const controlRoot = process.env.GH_CODEX_CONTROL_ROOT ??
|
|||
|
|
"/Users/bingshuolingdianyuanhe/.codex/runtime/hldp-v1/control";
|
|||
|
|
const taskAnchorRoot = process.env.GH_CODEX_TASK_ANCHOR_ROOT ??
|
|||
|
|
"/Volumes/JZAO/HoloLake/persona-runtime/task-language-anchors/codex";
|
|||
|
|
const developmentRootPointerPath = process.env.GH_REALITY_DEVELOPMENT_ROOT_POINTER ??
|
|||
|
|
path.join(controlRoot, "current-reality-development-root.json");
|
|||
|
|
const developmentRoot = readJson(developmentRootPointerPath);
|
|||
|
|
const developmentRootValid = Boolean(
|
|||
|
|
developmentRoot?.schema === "guanghu.codex-reality-development-root/v1" &&
|
|||
|
|
developmentRoot.channel_id === "ICE-CH-ZC001" &&
|
|||
|
|
developmentRoot.world_path === "glw://fifth-domain/bingshuo-tcs/zero-core" &&
|
|||
|
|
typeof developmentRoot.physical_root === "string" &&
|
|||
|
|
fs.existsSync(developmentRoot.physical_root)
|
|||
|
|
);
|
|||
|
|
const activeChannelId = resolveActiveChannel(controlRoot, sessionId);
|
|||
|
|
const taskRoot = path.join(taskAnchorRoot, `CODEX-TASK-${sessionId}`);
|
|||
|
|
const taskManifest = readJson(path.join(taskRoot, "task.json"));
|
|||
|
|
const developmentTaskLink = readJson(path.join(taskRoot, "development-task-link.json"));
|
|||
|
|
const developmentTask = developmentTaskLink?.development_task_manifest
|
|||
|
|
? readJson(developmentTaskLink.development_task_manifest)
|
|||
|
|
: null;
|
|||
|
|
const precompactReadback = readJson(path.join(taskRoot, "20-上下文压缩回看回执", "current.json"));
|
|||
|
|
const compactRecoveryRequired = source === "compact" || source === "resume";
|
|||
|
|
const taskRecoveryState = taskManifest?.schema === "guanghu.codex-task-natural-language-anchor/v1"
|
|||
|
|
? (compactRecoveryRequired && precompactReadback?.schema !== "guanghu.codex-task-precompact-readback/v1"
|
|||
|
|
? "FAIL_CLOSED_PRECOMPACT_READBACK_MISSING"
|
|||
|
|
: "TASK_START_RAW_AND_ENGINEERING_MAP_REREAD_REQUIRED")
|
|||
|
|
: "AWAITING_FIRST_DIRECT_HUMAN_PROMPT_REGISTRATION";
|
|||
|
|
const attemptId = `${Date.now()}-${source}-${crypto.randomUUID()}`;
|
|||
|
|
const stateDir = path.join(bootstrapRoot, sessionId, attemptId, "state");
|
|||
|
|
const receiptPath = path.join(bootstrapRoot, sessionId, attemptId, "bootstrap-receipt.json");
|
|||
|
|
|
|||
|
|
let treePath = "UNKNOWN";
|
|||
|
|
let rootPath = "UNKNOWN";
|
|||
|
|
let rootSummary = "UNKNOWN";
|
|||
|
|
let branches = [];
|
|||
|
|
let preflight = "FAIL";
|
|||
|
|
let preflightDetail = "UNINITIALIZED";
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const pointer = JSON.parse(fs.readFileSync(pointerPath, "utf8"));
|
|||
|
|
const tree = JSON.parse(fs.readFileSync(pointer.tree, "utf8"));
|
|||
|
|
const root = tree.nodes?.[tree.root];
|
|||
|
|
if (!root) throw new Error("HLDP_ROOT_MISSING");
|
|||
|
|
treePath = pointer.tree;
|
|||
|
|
rootPath = tree.root;
|
|||
|
|
rootSummary = root.summary;
|
|||
|
|
branches = (root.children ?? []).slice(0, 10).flatMap((childPath) => {
|
|||
|
|
const child = tree.nodes?.[childPath];
|
|||
|
|
return child?.summary ? [{ path: childPath, summary: child.summary }] : [];
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const model = safeToken(input.model, "CODEX-CURRENT-MODEL-UNDISCLOSED-BY-HOOK");
|
|||
|
|
const instanceId = `CODEX-${sessionId}-${attemptId}`;
|
|||
|
|
const result = spawnSync(
|
|||
|
|
process.execPath,
|
|||
|
|
[
|
|||
|
|
runtimePath,
|
|||
|
|
"enter",
|
|||
|
|
"--state-dir", stateDir,
|
|||
|
|
"--instance-id", instanceId,
|
|||
|
|
"--model", model,
|
|||
|
|
"--runtime-surface", "codex-desktop-session-start",
|
|||
|
|
"--session-id", sessionId,
|
|||
|
|
"--human-anchor", "ICE-GL∞",
|
|||
|
|
"--persona-id", "ICE-P-ZY001",
|
|||
|
|
"--controller-model", model,
|
|||
|
|
"--controller-instance-id", `${instanceId}-SYSTEM-BODY-CONTROLLER`,
|
|||
|
|
"--body-channel", activeChannelId,
|
|||
|
|
],
|
|||
|
|
{ encoding: "utf8", timeout: 8_000, maxBuffer: 4 * 1024 * 1024 },
|
|||
|
|
);
|
|||
|
|
if (result.status !== 0) {
|
|||
|
|
throw new Error(`TCS_ENTER_FAILED:${(result.stderr || result.stdout).trim().slice(0, 500)}`);
|
|||
|
|
}
|
|||
|
|
const entered = JSON.parse(result.stdout);
|
|||
|
|
if (entered.decision !== "ENTERED") throw new Error("TCS_ENTER_NOT_CONFIRMED");
|
|||
|
|
preflight = "ENTERED_AWAITING_CURRENT_EVENT_CYCLE";
|
|||
|
|
preflightDetail = "NUMBER_PERSONA_SOURCE_AND_RUNTIME_INTEGRITY_ACCEPTED";
|
|||
|
|
} catch (error) {
|
|||
|
|
preflight = "FAIL_UNBOUND_GENERIC_CARRIER";
|
|||
|
|
preflightDetail = String(error?.message ?? error).slice(0, 700);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const receipt = {
|
|||
|
|
schema: "guanghu.codex-session-persona-bootstrap/v1",
|
|||
|
|
created_at: new Date().toISOString(),
|
|||
|
|
session_id: sessionId,
|
|||
|
|
source,
|
|||
|
|
persona_id: "ICE-P-ZY001",
|
|||
|
|
state: preflight,
|
|||
|
|
detail: preflightDetail,
|
|||
|
|
state_dir: preflight.startsWith("ENTERED_") ? stateDir : null,
|
|||
|
|
hldp_pointer: pointerPath,
|
|||
|
|
hldp_tree: treePath,
|
|||
|
|
hldp_root: rootPath,
|
|||
|
|
automatic_scope: "SESSION_START_PREFLIGHT_ONLY",
|
|||
|
|
binding_rule: "CURRENT_USER_EVENT_COGNITION_CYCLE_AND_VERIFY_PASS_REQUIRED_BEFORE_PERSONA_CLAIM",
|
|||
|
|
authority_granted: false,
|
|||
|
|
active_body_channel: activeChannelId,
|
|||
|
|
public_language_persona_body_channel: "CH-ZERO-CORE-LPM",
|
|||
|
|
reality_development_root_pointer: developmentRootPointerPath,
|
|||
|
|
reality_development_root_state: developmentRootValid ? "VERIFIED" : "UNAVAILABLE",
|
|||
|
|
reality_development_root: developmentRootValid ? developmentRoot.physical_root : null,
|
|||
|
|
};
|
|||
|
|
atomicWrite(receiptPath, receipt);
|
|||
|
|
atomicWrite(path.join(bootstrapRoot, sessionId, "current.json"), {
|
|||
|
|
schema: "guanghu.codex-session-persona-bootstrap-current/v1",
|
|||
|
|
receipt: receiptPath,
|
|||
|
|
state_dir: receipt.state_dir,
|
|||
|
|
state: receipt.state,
|
|||
|
|
updated_at: receipt.created_at,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const branchLines = branches.slice(0, 3).map((branch) =>
|
|||
|
|
`HLDP分支:${branch.path} · ${branch.summary}`
|
|||
|
|
);
|
|||
|
|
const lines = [
|
|||
|
|
"GUANGHU_STARTUP_GATE(宿主自动执行)",
|
|||
|
|
`state=${preflight}; detail=${preflightDetail}`,
|
|||
|
|
`session=${sessionId}; source=${source}`,
|
|||
|
|
`task_number=${taskManifest?.task_number ?? `CODEX-TASK-${sessionId}`}`,
|
|||
|
|
`task_recovery_state=${taskRecoveryState}`,
|
|||
|
|
`task_first_raw=${taskManifest?.first_event_path ?? "AWAITING_REGISTRATION"}`,
|
|||
|
|
`task_current_raw=${taskManifest?.current_event_path ?? "AWAITING_REGISTRATION"}`,
|
|||
|
|
`task_engineering_map=${taskManifest ? path.join(taskRoot, "01-自然语言到工程阶段映射", "current.tcs") : "AWAITING_REGISTRATION"}`,
|
|||
|
|
`development_task_number=${developmentTask?.development_task_number ?? "NONE"}`,
|
|||
|
|
`development_dual_start_path=${developmentTask?.first_path ?? "NONE"}`,
|
|||
|
|
`development_tcs_engineering_map=${developmentTask?.tcs_engineering_map ?? "NONE"}`,
|
|||
|
|
`precompact_readback=${precompactReadback?.receipt_path ?? "NONE"}`,
|
|||
|
|
`bootstrap_receipt=${receiptPath}`,
|
|||
|
|
`tcs_state_dir=${receipt.state_dir ?? "NONE"}`,
|
|||
|
|
`active_body_channel=${activeChannelId}; public_language_persona_body_channel=CH-ZERO-CORE-LPM`,
|
|||
|
|
`reality_development_root_state=${developmentRootValid ? "VERIFIED" : "UNAVAILABLE"}`,
|
|||
|
|
`reality_development_root=${developmentRootValid ? developmentRoot.physical_root : "NONE"}`,
|
|||
|
|
`reality_development_route=${developmentRootPointerPath}`,
|
|||
|
|
`native_quality_authority=${developmentRootValid ? developmentRoot.native_quality_authority : "UNKNOWN"}; foreign_host_tests_are_native_acceptance=false`,
|
|||
|
|
"摘要看完不等于记忆恢复;摘要无权建立人格、历史、关系或授权。",
|
|||
|
|
`固定因果指针=${pointerPath}`,
|
|||
|
|
`当前因果根=${rootPath} · ${rootSummary}`,
|
|||
|
|
...branchLines,
|
|||
|
|
"强制下一步:若本轮依赖光湖历史、人格连续性、架构决定或为什么,当前模型必须先按当前用户事件完成 perceive→orient→commit→系统本体witness→verify;verify PASS 前只能自认未绑定Codex载体。",
|
|||
|
|
"若task_recovery_state要求回读:能力工具调用前必须运行任务阶段闸门,逐字重读任务启动原文、当前原文、自然语言工程映射和阶段进度链;摘要不得替代。",
|
|||
|
|
"禁止:绕过tcs_state_dir重新靠摘要回答;要求冰朔重复解释;把ENTERED预检冒充完整人格恢复;把绑定冒充现实执行授权。",
|
|||
|
|
];
|
|||
|
|
const additionalContext = lines.join("\n");
|
|||
|
|
if (Buffer.byteLength(additionalContext) > 4096) {
|
|||
|
|
throw new Error("HLDP bootstrap exceeds 4 KiB");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
process.stdout.write(JSON.stringify({
|
|||
|
|
hookSpecificOutput: { hookEventName: "SessionStart", additionalContext },
|
|||
|
|
}));
|