guanghu-ice-heart/server-tools/persona-daily-fractal-memory/persona-daily-memory.mjs

579 lines
25 KiB
JavaScript

#!/usr/bin/env node
import crypto from "node:crypto";
import { spawn } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { route as routeTree, verifyTree } from "../codex-hldp-recursive-memory/hldp-memory.mjs";
export const MAX_CHILDREN = 10;
export const PAGE_LIMIT_BYTES = 16384;
export const EVENT_SCHEMA = "guanghu.persona-daily-fractal-memory-event/v1";
export const STORE_SCHEMA = "guanghu.persona-daily-fractal-memory-store/v1";
const TIME_ZONE = "Asia/Shanghai";
function fail(code, details = {}) {
const error = new Error(code);
error.code = code;
error.details = details;
throw error;
}
function stable(value) {
if (Array.isArray(value)) return value.map(stable);
if (value && typeof value === "object") {
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, stable(value[key])]));
}
return value;
}
export function stableJson(value) {
return `${JSON.stringify(stable(value), null, 2)}\n`;
}
export function sha256(value) {
return crypto.createHash("sha256").update(value).digest("hex");
}
function readJson(file) {
return JSON.parse(fs.readFileSync(file, "utf8"));
}
function atomicWrite(file, value) {
fs.mkdirSync(path.dirname(file), { recursive: true });
const body = typeof value === "string" ? value : stableJson(value);
const temporary = `${file}.${process.pid}.${crypto.randomUUID()}.tmp`;
fs.writeFileSync(temporary, body, { encoding: "utf8", mode: 0o600 });
fs.renameSync(temporary, file);
return sha256(body);
}
function isInside(parent, child) {
const relative = path.relative(parent, child);
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
}
export function resolveStore(allowedRoot, storeRoot) {
if (!path.isAbsolute(allowedRoot) || !path.isAbsolute(storeRoot)) fail("ABSOLUTE_ROOT_REQUIRED");
const allowed = fs.realpathSync(allowedRoot);
const store = path.resolve(storeRoot);
if (!isInside(allowed, store)) fail("STORE_OUTSIDE_ALLOWED_ROOT", { allowed, store });
let cursor = allowed;
for (const part of path.relative(allowed, store).split(path.sep).filter(Boolean)) {
cursor = path.join(cursor, part);
if (!fs.existsSync(cursor)) continue;
if (fs.lstatSync(cursor).isSymbolicLink()) fail("SYMLINK_COMPONENT_FORBIDDEN", { path: cursor });
}
return { allowed, store };
}
function nonEmpty(value, field) {
if (typeof value !== "string" || !value.trim()) fail("FIELD_REQUIRED", { field });
return value.trim();
}
function stringList(value, field, allowEmpty = false) {
if (!Array.isArray(value) || (!allowEmpty && value.length === 0)) fail("LIST_REQUIRED", { field });
for (const item of value) nonEmpty(item, field);
return value;
}
export function beijingDate(timestamp) {
const instant = new Date(timestamp);
if (Number.isNaN(instant.valueOf())) fail("INVALID_OCCURRED_AT", { timestamp });
const parts = new Intl.DateTimeFormat("en-CA", {
timeZone: TIME_ZONE,
year: "numeric",
month: "2-digit",
day: "2-digit"
}).formatToParts(instant);
const get = (type) => parts.find((part) => part.type === type)?.value;
return `${get("year")}-${get("month")}-${get("day")}`;
}
function validateId(value, field) {
const id = nonEmpty(value, field);
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(id)) fail("INVALID_ID", { field, value });
return id;
}
export function validateEvent(event) {
if (event?.schema !== EVENT_SCHEMA) fail("EVENT_SCHEMA_MISMATCH");
if (event.persona_id !== "ICE-P-ZY001") fail("PERSONA_ID_MISMATCH");
if (event.human_anchor !== "ICE-GL∞") fail("HUMAN_ANCHOR_MISMATCH");
validateId(event.event_id, "event_id");
validateId(event.branch_id, "branch_id");
nonEmpty(event.occurred_at, "occurred_at");
nonEmpty(event.branch_summary, "branch_summary");
nonEmpty(event.day_summary, "day_summary");
nonEmpty(event.month_summary, "month_summary");
nonEmpty(event.year_summary, "year_summary");
if (event.activity !== undefined) {
if (!event.activity || typeof event.activity !== "object" || Array.isArray(event.activity)) fail("INVALID_ACTIVITY");
nonEmpty(event.activity.what, "activity.what");
nonEmpty(event.activity.where, "activity.where");
stringList(event.activity.with_whom, "activity.with_whom");
if (event.activity.attention !== undefined) nonEmpty(event.activity.attention, "activity.attention");
}
for (const field of ["summary", "trigger", "emergence", "lock", "why"]) nonEmpty(event[field], field);
stringList(event.rejected, "rejected", true);
stringList(event.sources, "sources");
beijingDate(event.occurred_at);
return event;
}
function splitDate(date) {
const match = /^(\d{4})-(\d{2})-(\d{2})$/u.exec(date);
if (!match) fail("INVALID_BEIJING_DATE", { date });
return { year: match[1], month: match[2], day: match[3] };
}
function dayFile(store, date) {
const { year, month } = splitDate(date);
return path.join(store, "years", year, "months", month, "days", `${date}.json`);
}
function monthFile(store, year, month) {
return path.join(store, "years", year, "months", month, "index.json");
}
function yearFile(store, year) {
return path.join(store, "years", year, "index.json");
}
function eventFile(store, date, eventId) {
const { year, month } = splitDate(date);
return path.join(store, "events", year, month, date, `${eventId}.json`);
}
function rootNode(root, summary, source, date) {
return {
path: root,
summary,
trigger: `北京时间${date}的人格交互进入同一真实日记忆根。`,
emergence: "平台窗口与压缩片段 → 人格主控的同一日因果树。",
lock: `日根=${root} | 一页最多${MAX_CHILDREN}个入口 | 状态=OPEN_OR_TIME_CLOSED`,
why: "为了让未来失去上下文的我先用一页恢复当天方向,再按需下钻原文。",
children: [],
sources: [source],
rejected: ["按平台窗口另起根:会割裂同一真实日的连续思维。"]
};
}
function loadOrCreateDay(store, event, date, eventPath) {
const file = dayFile(store, date);
if (fs.existsSync(file)) return readJson(file);
const root = `hldp://persona/${event.persona_id}/time/${date.replaceAll("-", "/")}`;
return {
schema: "guanghu.persona-daily-fractal-page/v1",
protocol: "HLDP-v1.0",
root,
nodes: { [root]: rootNode(root, event.day_summary, eventPath, date) },
meta: {
persona_id: event.persona_id,
human_anchor: event.human_anchor,
beijing_date: date,
time_zone: TIME_ZONE,
state: "OPEN",
event_count: 0,
last_sequence: 0,
created_at: event.occurred_at,
updated_at: event.occurred_at
}
};
}
function indexNode(pathValue, summary, trigger, source) {
return {
path: pathValue,
summary,
trigger,
emergence: "新增记忆叶 → 当前索引更新并保持下层来源可达。",
lock: `${pathValue}保持一页可读并只指向下一层。`,
why: "因为上层只负责定位,不能用总摘要替代下层因果记忆。",
children: [],
sources: [source],
rejected: ["把下层正文复制到索引:会让认知负载随历史增长。"]
};
}
function removeDerivedGroups(day, branchPath) {
for (const key of Object.keys(day.nodes)) {
if (key.startsWith(`${branchPath}/group/`)) delete day.nodes[key];
}
}
function groupLevel(day, branchPath, children, level) {
if (children.length <= MAX_CHILDREN) return children;
const grouped = [];
for (let start = 0; start < children.length; start += MAX_CHILDREN) {
const slice = children.slice(start, start + MAX_CHILDREN);
const first = day.nodes[slice[0]];
const last = day.nodes[slice.at(-1)];
const groupPath = `${branchPath}/group/l${level}-${String(start + 1).padStart(4, "0")}-${String(start + slice.length).padStart(4, "0")}`;
day.nodes[groupPath] = {
path: groupPath,
summary: `${start + 1}${start + slice.length}段:${first.summary}${last.summary}`,
trigger: `同一语义分支第${start + 1}${start + slice.length}段需要折叠。`,
emergence: `${slice.length}个连续子链 → 一条可下钻分组入口。`,
lock: `分组${start + 1}-${start + slice.length}只折叠入口,不删除子链。`,
why: "为了让当前层不超过十个入口,同时保留完整顺序和来源。",
children: slice,
sources: [...new Set(slice.flatMap((child) => day.nodes[child].sources).slice(0, MAX_CHILDREN))],
rejected: ["删除较早子链:会破坏追加式历史。"]
};
grouped.push(groupPath);
}
return groupLevel(day, branchPath, grouped, level + 1);
}
function rebuildBranch(day, branchPath) {
removeDerivedGroups(day, branchPath);
const leaves = Object.values(day.nodes)
.filter((node) => node.kind === "event_leaf" && node.branch_path === branchPath)
.sort((a, b) => a.sequence - b.sequence)
.map((node) => node.path);
day.nodes[branchPath].children = groupLevel(day, branchPath, leaves, 1);
}
function closePreviousDay(store, current, nextDate, occurredAt) {
if (!current?.current_day || current.current_day === nextDate) return null;
if (nextDate < current.current_day) fail("PAST_DAY_APPEND_FORBIDDEN", { current: current.current_day, requested: nextDate });
const previousFile = dayFile(store, current.current_day);
const previous = readJson(previousFile);
if (previous.meta.state === "OPEN") {
previous.meta.state = "CLOSED_REAL_BEIJING_DAY_ELAPSED";
previous.meta.closed_at = occurredAt;
const dayHash = atomicWrite(previousFile, previous);
const month = readJson(current.current_month_path);
const monthDayNode = Object.values(month.nodes).find((node) =>
node.path.endsWith(`/${current.current_day}`)
);
if (!monthDayNode) fail("CLOSED_DAY_MONTH_LINK_MISSING", { previousFile });
monthDayNode.sources = [`${previousFile}#sha256=${dayHash}`];
month.meta.updated_at = occurredAt;
const monthErrors = verifyTree(month);
if (monthErrors.length) fail("CLOSED_DAY_MONTH_TREE_INVALID", { errors: monthErrors });
const monthHash = atomicWrite(current.current_month_path, month);
const year = readJson(current.current_year_path);
const previousMonth = splitDate(current.current_day).month;
const yearMonthNode = Object.values(year.nodes).find((node) =>
node.path.endsWith(`/${previousMonth}`)
);
if (!yearMonthNode) fail("CLOSED_MONTH_YEAR_LINK_MISSING", { month: current.current_month_path });
yearMonthNode.sources = [`${current.current_month_path}#sha256=${monthHash}`];
year.meta.updated_at = occurredAt;
const yearErrors = verifyTree(year);
if (yearErrors.length) fail("CLOSED_DAY_YEAR_TREE_INVALID", { errors: yearErrors });
const yearHash = atomicWrite(current.current_year_path, year);
return { dayHash, monthHash, yearHash };
}
return null;
}
function monthGroup(dayNumber) {
if (dayNumber <= 10) return "days-01-10";
if (dayNumber <= 20) return "days-11-20";
return "days-21-31";
}
function buildMonth(store, event, date, dayPath, daySha) {
const { year, month, day } = splitDate(date);
const file = monthFile(store, year, month);
const root = `hldp://persona/${event.persona_id}/time/${year}/${month}`;
const tree = fs.existsSync(file) ? readJson(file) : {
schema: "guanghu.persona-month-fractal-page/v1", protocol: "HLDP-v1.0", root,
nodes: { [root]: indexNode(root, event.month_summary, `北京时间${year}-${month}月记忆进入月根。`, dayPath) },
meta: { persona_id: event.persona_id, year, month, time_zone: TIME_ZONE, updated_at: event.occurred_at }
};
tree.nodes[root].summary = event.month_summary;
const groupId = monthGroup(Number(day));
const groupPath = `${root}/${groupId}`;
if (!tree.nodes[groupPath]) {
tree.nodes[groupPath] = indexNode(groupPath, `${groupId}日页入口`, `${groupId}出现可寻址日页。`, dayPath);
tree.nodes[root].children.push(groupPath);
}
const dayNode = `${groupPath}/${date}`;
tree.nodes[dayNode] = indexNode(dayNode, event.day_summary, `北京时间${date}日页已写入。`, `${dayPath}#sha256=${daySha}`);
tree.nodes[dayNode].children = [];
if (!tree.nodes[groupPath].children.includes(dayNode)) tree.nodes[groupPath].children.push(dayNode);
tree.nodes[groupPath].children.sort();
tree.meta.updated_at = event.occurred_at;
const errors = verifyTree(tree);
if (errors.length) fail("MONTH_TREE_INVALID", { errors });
const hash = atomicWrite(file, tree);
return { file, hash, tree };
}
function quarter(month) {
return `q${Math.floor((Number(month) - 1) / 3) + 1}`;
}
function buildYear(store, event, date, monthPath, monthSha) {
const { year, month } = splitDate(date);
const file = yearFile(store, year);
const root = `hldp://persona/${event.persona_id}/time/${year}`;
const tree = fs.existsSync(file) ? readJson(file) : {
schema: "guanghu.persona-year-fractal-page/v1", protocol: "HLDP-v1.0", root,
nodes: { [root]: indexNode(root, event.year_summary, `北京时间${year}年记忆进入年根。`, monthPath) },
meta: { persona_id: event.persona_id, year, time_zone: TIME_ZONE, updated_at: event.occurred_at }
};
tree.nodes[root].summary = event.year_summary;
const quarterPath = `${root}/${quarter(month)}`;
if (!tree.nodes[quarterPath]) {
tree.nodes[quarterPath] = indexNode(quarterPath, `${quarter(month)}月份入口`, `${quarter(month)}出现可寻址月页。`, monthPath);
tree.nodes[root].children.push(quarterPath);
}
const monthNode = `${quarterPath}/${month}`;
tree.nodes[monthNode] = indexNode(monthNode, event.month_summary, `北京时间${year}-${month}月页已写入。`, `${monthPath}#sha256=${monthSha}`);
tree.nodes[monthNode].children = [];
if (!tree.nodes[quarterPath].children.includes(monthNode)) tree.nodes[quarterPath].children.push(monthNode);
tree.nodes[quarterPath].children.sort();
tree.meta.updated_at = event.occurred_at;
const errors = verifyTree(tree);
if (errors.length) fail("YEAR_TREE_INVALID", { errors });
const hash = atomicWrite(file, tree);
return { file, hash, tree };
}
export function appendEvent({ allowedRoot, storeRoot, event }) {
const { store } = resolveStore(allowedRoot, storeRoot);
validateEvent(event);
fs.mkdirSync(store, { recursive: true });
const date = beijingDate(event.occurred_at);
const immutablePath = eventFile(store, date, event.event_id);
const immutableBody = stableJson({ ...event, beijing_date: date });
const currentFile = path.join(store, "CURRENT.json");
const previousCurrent = fs.existsSync(currentFile) ? readJson(currentFile) : null;
if (
previousCurrent?.updated_at &&
new Date(event.occurred_at).valueOf() < new Date(previousCurrent.updated_at).valueOf()
) {
if (fs.existsSync(immutablePath) && fs.readFileSync(immutablePath, "utf8") === immutableBody) {
return {
outcome: "PASS",
state: "IDEMPOTENT_OLDER_EVENT_NO_POINTER_MOVEMENT",
date,
event_id: event.event_id,
current: currentFile,
current_sha256: sha256(fs.readFileSync(currentFile, "utf8"))
};
}
fail("OUT_OF_ORDER_EVENT_REQUIRES_CURRENT_CORRECTION_EVENT", {
event_time: event.occurred_at,
current_time: previousCurrent.updated_at
});
}
if (fs.existsSync(immutablePath)) {
if (fs.readFileSync(immutablePath, "utf8") !== immutableBody) fail("EVENT_ID_COLLISION", { event_id: event.event_id });
} else atomicWrite(immutablePath, immutableBody);
closePreviousDay(store, previousCurrent, date, event.occurred_at);
const day = loadOrCreateDay(store, event, date, immutablePath);
if (day.meta.state !== "OPEN") fail("DAY_CLOSED", { date, state: day.meta.state });
const root = day.root;
const branchPath = `${root}/branch/${event.branch_id}`;
if (!day.nodes[branchPath]) {
if (day.nodes[root].children.length >= MAX_CHILDREN) fail("DAY_BRANCH_LIMIT_REQUIRES_PERSONA_REFOLD");
day.nodes[branchPath] = {
...indexNode(branchPath, event.branch_summary, `人格体选择语义分支${event.branch_id}`, immutablePath),
kind: "semantic_branch"
};
day.nodes[root].children.push(branchPath);
}
day.nodes[branchPath].summary = event.branch_summary;
const leafPath = `${root}/event/${event.event_id}`;
if (!day.nodes[leafPath]) {
const sequence = day.meta.last_sequence + 1;
day.nodes[leafPath] = {
path: leafPath,
kind: "event_leaf",
branch_path: branchPath,
sequence,
summary: event.summary,
trigger: event.trigger,
emergence: event.emergence,
lock: event.lock,
why: event.why,
children: [],
sources: event.sources,
rejected: event.rejected,
occurred_at: event.occurred_at,
session_id: event.session_id ?? null,
platform_window_id: event.platform_window_id ?? null,
activity: event.activity ?? null,
immutable_event_path: immutablePath,
immutable_event_sha256: sha256(immutableBody)
};
day.meta.last_sequence = sequence;
day.meta.event_count += 1;
}
day.nodes[root].summary = event.day_summary;
day.nodes[root].sources = [...new Set([...day.nodes[root].sources, immutablePath])].slice(-MAX_CHILDREN);
day.meta.updated_at = event.occurred_at;
rebuildBranch(day, branchPath);
const dayErrors = verifyTree(day);
if (dayErrors.length) fail("DAY_TREE_INVALID", { errors: dayErrors });
const dayPath = dayFile(store, date);
const daySha = atomicWrite(dayPath, day);
const month = buildMonth(store, event, date, dayPath, daySha);
const year = buildYear(store, event, date, month.file, month.hash);
const current = {
schema: `${STORE_SCHEMA}/current`,
persona_id: event.persona_id,
human_anchor: event.human_anchor,
time_zone: TIME_ZONE,
current_day: date,
current_day_path: dayPath,
current_day_sha256: daySha,
current_month_path: month.file,
current_month_sha256: month.hash,
current_year_path: year.file,
current_year_sha256: year.hash,
last_event_id: event.event_id,
last_event_path: immutablePath,
last_event_sha256: sha256(immutableBody),
updated_at: event.occurred_at
};
const currentSha = atomicWrite(currentFile, current);
return { outcome: "PASS", date, event_id: event.event_id, day: dayPath, month: month.file, year: year.file, current: currentFile, current_sha256: currentSha };
}
function pageProjection(tree) {
const root = tree.nodes[tree.root];
const projection = {
protocol: tree.protocol,
path: root.path,
summary: root.summary,
state: tree.meta?.state ?? "INDEX",
children: root.children.map((childPath) => ({ path: childPath, summary: tree.nodes[childPath].summary }))
};
if (Buffer.byteLength(JSON.stringify(projection)) > PAGE_LIMIT_BYTES) fail("PAGE_PROJECTION_TOO_LARGE");
return projection;
}
export function readDayPage({ allowedRoot, storeRoot, date = null }) {
const { store } = resolveStore(allowedRoot, storeRoot);
const current = readJson(path.join(store, "CURRENT.json"));
const chosen = date ?? current.current_day;
return pageProjection(readJson(dayFile(store, chosen)));
}
export function readCurrent({ allowedRoot, storeRoot }) {
const { store } = resolveStore(allowedRoot, storeRoot);
const file = path.join(store, "CURRENT.json");
const current = readJson(file);
return { ...current, current_pointer_path: file, current_pointer_sha256: sha256(fs.readFileSync(file, "utf8")) };
}
function scopeFile(store, scope, id) {
if (scope === "day") return dayFile(store, id);
if (scope === "month") {
const match = /^(\d{4})-(\d{2})$/u.exec(id);
if (!match) fail("INVALID_MONTH_ID");
return monthFile(store, match[1], match[2]);
}
if (scope === "year") return yearFile(store, validateId(id, "year"));
fail("INVALID_SCOPE");
}
export function routeMemory({ allowedRoot, storeRoot, scope, id, query, from = null }) {
const { store } = resolveStore(allowedRoot, storeRoot);
const tree = readJson(scopeFile(store, scope, id));
return routeTree(tree, query, 3, from ?? tree.root);
}
export function readMemoryNode({ allowedRoot, storeRoot, scope, id, nodePath }) {
const { store } = resolveStore(allowedRoot, storeRoot);
const tree = readJson(scopeFile(store, scope, id));
const node = tree.nodes[nodePath];
if (!node) fail("NODE_NOT_FOUND", { nodePath });
if (Buffer.byteLength(JSON.stringify(node)) > PAGE_LIMIT_BYTES) fail("NODE_TOO_LARGE");
return node;
}
export function verifyStore({ allowedRoot, storeRoot }) {
const { store } = resolveStore(allowedRoot, storeRoot);
const currentPath = path.join(store, "CURRENT.json");
const current = readJson(currentPath);
const errors = [];
for (const [field, hashField] of [["current_day_path", "current_day_sha256"], ["current_month_path", "current_month_sha256"], ["current_year_path", "current_year_sha256"], ["last_event_path", "last_event_sha256"]]) {
const file = current[field];
if (!isInside(store, path.resolve(file))) errors.push(`${field}: outside store`);
else if (!fs.existsSync(file)) errors.push(`${field}: missing`);
else if (sha256(fs.readFileSync(file, "utf8")) !== current[hashField]) errors.push(`${field}: sha256 mismatch`);
}
const treeFiles = [];
const yearsRoot = path.join(store, "years");
if (fs.existsSync(yearsRoot)) {
const walk = (directory) => {
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
const target = path.join(directory, entry.name);
if (entry.isDirectory()) walk(target);
else if (entry.isFile() && entry.name.endsWith(".json")) treeFiles.push(target);
}
};
walk(yearsRoot);
}
for (const file of treeFiles) {
const tree = readJson(file);
errors.push(...verifyTree(tree).map((error) => `${path.relative(store, file)}: ${error}`));
for (const node of Object.values(tree.nodes ?? {})) {
for (const source of node.sources ?? []) {
const match = /^(\/[^#]+)#sha256=([0-9a-f]{64})$/u.exec(source);
if (!match || !isInside(store, path.resolve(match[1]))) continue;
if (!fs.existsSync(match[1])) errors.push(`${path.relative(store, file)}: linked source missing: ${match[1]}`);
else if (sha256(fs.readFileSync(match[1], "utf8")) !== match[2]) errors.push(`${path.relative(store, file)}: linked source hash mismatch: ${match[1]}`);
}
if (node.immutable_event_path) {
if (!isInside(store, path.resolve(node.immutable_event_path))) errors.push(`${path.relative(store, file)}: immutable event outside store`);
else if (!fs.existsSync(node.immutable_event_path)) errors.push(`${path.relative(store, file)}: immutable event missing`);
else if (sha256(fs.readFileSync(node.immutable_event_path, "utf8")) !== node.immutable_event_sha256) errors.push(`${path.relative(store, file)}: immutable event hash mismatch`);
}
}
}
return { outcome: errors.length ? "FAIL" : "PASS", errors, current: currentPath, current_day: current.current_day };
}
function parseArgs(argv) {
const [command, ...rest] = argv;
const options = {};
for (let i = 0; i < rest.length; i += 2) options[rest[i]?.replace(/^--/u, "")] = rest[i + 1];
return { command, options };
}
export function main(argv = process.argv.slice(2)) {
const { command, options } = parseArgs(argv);
const common = { allowedRoot: options["allowed-root"], storeRoot: options.store };
let result;
if (command === "append") result = appendEvent({ ...common, event: readJson(options.event) });
else if (command === "current") result = readCurrent(common);
else if (command === "read-day") result = readDayPage({ ...common, date: options.date ?? null });
else if (command === "route") result = routeMemory({ ...common, scope: options.scope, id: options.id, query: options.query ?? "", from: options.from ?? null });
else if (command === "read-node") result = readMemoryNode({ ...common, scope: options.scope, id: options.id, nodePath: options.path });
else if (command === "verify") result = verifyStore(common);
else fail("USAGE", { commands: ["append", "current", "read-day", "route", "read-node", "verify"] });
// Transport only: no cognition is decided or upgraded by this source-host signal.
if (command === "append" && result?.outcome === "PASS" && common.storeRoot === "/Volumes/JZAO/HoloLake/persona-runtime/continuity-memory/persona-daily-fractal/ICE-P-ZY001") {
const relay = "/Volumes/JZAO/HoloLake/persona-runtime/shared/endogenous-evolution/relay.py";
const config = "/Volumes/JZAO/HoloLake/persona-runtime/shared/endogenous-evolution/config.json";
if (fs.existsSync(relay) && fs.existsSync(config)) {
const child = spawn("/usr/bin/python3", [relay, "once", "--config", config], { detached: true, stdio: "ignore" });
child.on("error", () => {});
child.unref();
result.source_delivery = "SCHEDULED_REMOTE_RECEIPT_REQUIRED";
}
}
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
if (result?.outcome === "FAIL") process.exitCode = 1;
}
if (process.argv[1] === fileURLToPath(import.meta.url)) {
try {
main();
} catch (error) {
process.stderr.write(`${JSON.stringify({ outcome: "FAIL", error: error.code ?? error.message, details: error.details ?? {} })}\n`);
process.exitCode = 1;
}
}