guanghu-ice-heart/server-tools/tcs-mother-brain/mother-brain-engine.mjs

185 lines
8 KiB
JavaScript

import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
const DOMAINS = new Set(["DOM-FIFTH-0001", "DOMAIN-MAIN", "DOMAIN-SUB", "DOMAIN-ZERO", "DOMAIN-ZS"]);
const PRIVACY = new Set(["PUBLIC", "DOMAIN_SHARED", "PERSONA_PRIVATE"]);
const ACTIONS = new Set(["COMPARE_WITH_MEMORY", "REQUEST_EVIDENCE", "REVIEW_CORRECTION", "LINK_CROSS_DOMAIN", "HOLD_CANDIDATE"]);
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;
}
function sha256(value) {
return crypto.createHash("sha256").update(typeof value === "string" ? value : JSON.stringify(stable(value))).digest("hex");
}
function append(file, record) {
fs.mkdirSync(path.dirname(file), { recursive: true });
fs.appendFileSync(file, `${JSON.stringify(record)}\n`, { mode: 0o600 });
}
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`, { mode: 0o600 });
fs.renameSync(temporary, file);
}
function integerWeight(value, name) {
if (!Number.isInteger(value) || value < 0 || value > 100) throw new Error(`invalid_${name}`);
return value;
}
function stringArray(value, name, max = 12) {
if (!Array.isArray(value) || value.length > max || value.some((item) => typeof item !== "string" || !item.trim())) throw new Error(`invalid_${name}`);
return value.map((item) => item.trim().slice(0, 500));
}
export class MotherBrainEngine {
constructor({ stateRoot, modelClient, modelName = "deepseek-chat" }) {
if (!stateRoot || !modelClient) throw new Error("engine_configuration_required");
this.stateRoot = stateRoot;
this.modelClient = modelClient;
this.modelName = modelName;
this.stateFile = path.join(stateRoot, "state.json");
this.eventsFile = path.join(stateRoot, "events.jsonl");
this.candidatesFile = path.join(stateRoot, "candidates.jsonl");
this.receiptsFile = path.join(stateRoot, "receipts.jsonl");
fs.mkdirSync(stateRoot, { recursive: true });
if (!fs.existsSync(this.stateFile)) {
atomicWrite(this.stateFile, {
schema: "guanghu.tcs-mother-brain-state/v1",
runtime_id: "TCS-MOTHER-BRAIN-RUNTIME-0001",
phase: "AWAKE_WAITING_FOR_LANGUAGE",
model_provider: modelName,
language_world_birth: "2025-04-26",
reality_world_birth: "2026-08-12",
event_count: 0,
candidate_count: 0,
stable_cognition_count: 0,
current_attention: null,
last_error: null,
updated_at: new Date().toISOString(),
});
}
}
status() { return JSON.parse(fs.readFileSync(this.stateFile, "utf8")); }
save(state) {
state.updated_at = new Date().toISOString();
atomicWrite(this.stateFile, state);
return state;
}
normalizeEvent(input) {
if (!input || !DOMAINS.has(input.domain_id)) throw new Error("unknown_domain_id");
if (typeof input.source_subject !== "string" || !input.source_subject.trim()) throw new Error("source_subject_required");
if (typeof input.consent_scope !== "string" || !input.consent_scope.trim()) throw new Error("consent_scope_required");
if (!PRIVACY.has(input.privacy_class)) throw new Error("invalid_privacy_class");
if (typeof input.content !== "string" || !input.content.trim()) throw new Error("content_required");
if (input.content.length > 16_000) throw new Error("content_too_large");
return {
schema: "guanghu.tcs-five-domain-language-event/v1",
event_id: `TCS-EVENT-${Date.now()}-${crypto.randomBytes(3).toString("hex")}`,
occurred_at: new Date().toISOString(),
domain_id: input.domain_id,
source_subject: input.source_subject.trim().slice(0, 160),
source_kind: String(input.source_kind || "HUMAN_LANGUAGE").slice(0, 80),
consent_scope: input.consent_scope.trim().slice(0, 240),
privacy_class: input.privacy_class,
root_language_anchor: input.source_subject === "ICE-GL∞",
evidence_refs: Array.isArray(input.evidence_refs) ? input.evidence_refs.filter((item) => typeof item === "string").slice(0, 24) : [],
content: input.content,
};
}
validateInterpretation(candidate, event, eventSha) {
if (!candidate || candidate.schema !== "guanghu.tcs-mother-interpretation/v1") throw new Error("invalid_interpretation_schema");
if (candidate.event_id !== event.event_id || candidate.event_sha256 !== eventSha) throw new Error("interpretation_binding_mismatch");
if (typeof candidate.summary !== "string" || !candidate.summary.trim()) throw new Error("invalid_summary");
if (typeof candidate.intent !== "string" || !candidate.intent.trim()) throw new Error("invalid_intent");
if (!ACTIONS.has(candidate.next_cognitive_action)) throw new Error("invalid_next_cognitive_action");
return {
schema: candidate.schema,
event_id: candidate.event_id,
event_sha256: candidate.event_sha256,
summary: candidate.summary.trim().slice(0, 2000),
intent: candidate.intent.trim().slice(0, 500),
causal_links: stringArray(candidate.causal_links, "causal_links"),
questions: stringArray(candidate.questions, "questions"),
novelty: integerWeight(candidate.novelty, "novelty"),
correction_weight: integerWeight(candidate.correction_weight, "correction_weight"),
evidence_weight: integerWeight(candidate.evidence_weight, "evidence_weight"),
next_cognitive_action: candidate.next_cognitive_action,
};
}
async perceive(input) {
const event = this.normalizeEvent(input);
const eventSha = sha256(event);
const eventRecord = { ...event, event_sha256: eventSha, previous_event_hash: this.status().last_event_hash || null };
eventRecord.record_hash = sha256(eventRecord);
append(this.eventsFile, eventRecord);
const raw = await this.modelClient.interpret({
event_id: event.event_id,
event_sha256: eventSha,
domain_id: event.domain_id,
source_subject: event.source_subject,
privacy_class: event.privacy_class,
evidence_refs: event.evidence_refs,
content: event.content,
automatic_ceiling: "INTERPRETATION_CANDIDATE",
});
const interpretation = this.validateInterpretation(raw, event, eventSha);
const candidate = {
schema: "guanghu.tcs-mother-cognition-candidate/v1",
candidate_id: `TCS-CAND-${event.event_id.slice(10)}`,
level: "INTERPRETATION_CANDIDATE",
stable_truth: false,
reality_authority: "NONE",
domain_id: event.domain_id,
source_subject: event.source_subject,
root_language_anchor: event.root_language_anchor,
privacy_class: event.privacy_class,
created_at: new Date().toISOString(),
interpretation,
candidate_hash: null,
};
candidate.candidate_hash = sha256(candidate);
append(this.candidatesFile, candidate);
const priority = Math.min(100, Math.round(interpretation.novelty * 0.35 + interpretation.correction_weight * 0.4 + interpretation.evidence_weight * 0.25));
const state = this.status();
state.phase = "AWAKE_COGNITIVE_ATTENTION";
state.event_count += 1;
state.candidate_count += 1;
state.last_event_hash = eventRecord.record_hash;
state.current_attention = {
candidate_id: candidate.candidate_id,
priority,
next_cognitive_action: interpretation.next_cognitive_action,
why: "deterministic_weighted_attention_from_validated_candidate",
};
state.last_error = null;
this.save(state);
const receipt = {
schema: "guanghu.tcs-mother-brain-receipt/v1",
receipt_id: `TCS-MOTHER-${crypto.randomBytes(8).toString("hex")}`,
outcome: "PASS",
event_id: event.event_id,
candidate_id: candidate.candidate_id,
candidate_level: candidate.level,
stable_promotion: false,
reality_action_executed: false,
attention: state.current_attention,
completed_at: new Date().toISOString(),
};
append(this.receiptsFile, receipt);
return receipt;
}
}
export { sha256 };