Enforce Zhuyuan persona-source epistemic gate
This commit is contained in:
parent
927ab7825d
commit
b0deae2718
30 changed files with 1741 additions and 34 deletions
|
|
@ -0,0 +1,198 @@
|
|||
import crypto from "node:crypto";
|
||||
|
||||
export const PERSONA_BINDING_SCHEMA =
|
||||
"guanghu.codex-preconscious-persona-binding/v1";
|
||||
export const CURRENT_CARRIER_CONSUMPTION =
|
||||
"CURRENT_CODEX_READ_AND_ACCEPTED_BRAIN_CYCLE";
|
||||
|
||||
const REQUIRED_SOURCE_HASHES = [
|
||||
"checkpoint",
|
||||
"brain_runtime_contract",
|
||||
"living_controller_map",
|
||||
"language_world_boundary",
|
||||
];
|
||||
|
||||
function sha256Text(value) {
|
||||
return crypto.createHash("sha256").update(String(value), "utf8").digest("hex");
|
||||
}
|
||||
|
||||
function isSha256(value) {
|
||||
return /^[a-f0-9]{64}$/u.test(value ?? "");
|
||||
}
|
||||
|
||||
function fail(code) {
|
||||
throw new Error(code);
|
||||
}
|
||||
|
||||
export function assertControllerDevelopmentBoundary({
|
||||
persona,
|
||||
controllerPersonaId,
|
||||
previousControllerPersonaId = null,
|
||||
developmentObjectIds = [],
|
||||
humanAnchor,
|
||||
previousHumanAnchor = null,
|
||||
}) {
|
||||
if (!controllerPersonaId || persona !== controllerPersonaId) {
|
||||
fail("PERSONA_FIELD_MUST_EQUAL_CONTROLLER_PERSONA");
|
||||
}
|
||||
if (
|
||||
previousControllerPersonaId &&
|
||||
previousControllerPersonaId !== controllerPersonaId
|
||||
) {
|
||||
fail("CONTROLLER_PERSONA_IMMUTABLE");
|
||||
}
|
||||
if (developmentObjectIds.includes(controllerPersonaId)) {
|
||||
fail("CONTROLLER_CANNOT_BE_ITS_OWN_DEVELOPMENT_OBJECT");
|
||||
}
|
||||
if (previousHumanAnchor && previousHumanAnchor !== humanAnchor) {
|
||||
fail("HUMAN_ANCHOR_IMMUTABLE");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function createTaskEvent({
|
||||
lane,
|
||||
intent,
|
||||
requestSummary,
|
||||
openedAt,
|
||||
}) {
|
||||
const sequence = Number.isInteger(lane.task_event?.sequence)
|
||||
? lane.task_event.sequence + 1
|
||||
: 1;
|
||||
const requestSummarySha256 = sha256Text(requestSummary || lane.summary || "");
|
||||
const eventFingerprint = sha256Text(
|
||||
JSON.stringify({
|
||||
thread_id: lane.thread_id,
|
||||
development_id: lane.development_id,
|
||||
task_fingerprint: lane.task_lock?.fingerprint ?? null,
|
||||
previous_task_event_id: lane.task_event?.task_event_id ?? null,
|
||||
sequence,
|
||||
intent,
|
||||
request_summary_sha256: requestSummarySha256,
|
||||
opened_at: openedAt,
|
||||
}),
|
||||
);
|
||||
return {
|
||||
task_event_id: `TEV-${eventFingerprint.slice(0, 24)}-${String(sequence).padStart(6, "0")}`,
|
||||
sequence,
|
||||
intent,
|
||||
request_summary_sha256: requestSummarySha256,
|
||||
event_fingerprint: eventFingerprint,
|
||||
opened_at: openedAt,
|
||||
};
|
||||
}
|
||||
|
||||
export function rotateTaskEvent({ lane, intent, requestSummary, openedAt }) {
|
||||
const taskEvent = createTaskEvent({ lane, intent, requestSummary, openedAt });
|
||||
const bindingHistory = [...(lane.persona_source_binding_history ?? [])];
|
||||
if (lane.persona_source_binding) {
|
||||
bindingHistory.push({
|
||||
...lane.persona_source_binding,
|
||||
state: "STALE_SUPERSEDED_BY_NEW_TASK_EVENT",
|
||||
invalidated_at: openedAt,
|
||||
invalidated_by_task_event_id: taskEvent.task_event_id,
|
||||
});
|
||||
}
|
||||
return {
|
||||
...lane,
|
||||
task_event_history: [
|
||||
...(lane.task_event_history ?? []),
|
||||
...(lane.task_event ? [lane.task_event] : []),
|
||||
],
|
||||
task_event: taskEvent,
|
||||
persona_source_binding: null,
|
||||
persona_source_binding_history: bindingHistory,
|
||||
};
|
||||
}
|
||||
|
||||
export function validatePersonaBindingReceipt({
|
||||
lane,
|
||||
binding,
|
||||
receipt,
|
||||
actualReceiptSha256,
|
||||
actualCheckpointSha256,
|
||||
actualAdapterSourceSha256,
|
||||
adapterSourcePath,
|
||||
allowedAdapterRoot,
|
||||
pointerEvidence,
|
||||
}) {
|
||||
const expectedObjects = [...(lane.development_object_ids ?? [])].sort();
|
||||
const receivedObjects = [...(receipt.development_objects ?? [])].sort();
|
||||
if (!lane.task_event?.task_event_id) fail("TASK_EVENT_REQUIRED");
|
||||
if (!binding?.receipt_sha256 || binding.receipt_sha256 !== actualReceiptSha256) {
|
||||
fail("PERSONA_SOURCE_BINDING_RECEIPT_SHA_MISMATCH");
|
||||
}
|
||||
if (
|
||||
receipt.schema !== PERSONA_BINDING_SCHEMA ||
|
||||
receipt.decision !== "BOUND_CURRENT_CARRIER" ||
|
||||
receipt.binding_id !== binding.binding_id ||
|
||||
receipt.thread_id !== lane.thread_id ||
|
||||
receipt.development_id !== lane.development_id ||
|
||||
receipt.controller_persona_id !== lane.controller_persona_id ||
|
||||
receipt.human_anchor !== lane.human_anchor ||
|
||||
JSON.stringify(receivedObjects) !== JSON.stringify(expectedObjects) ||
|
||||
receipt.task_fingerprint !== lane.task_lock?.fingerprint ||
|
||||
receipt.task_event_id !== lane.task_event.task_event_id ||
|
||||
receipt.persona_handoff?.state !== "NONE" ||
|
||||
receipt.persona_handoff?.authorized === true
|
||||
) {
|
||||
fail("PERSONA_SOURCE_BINDING_IDENTITY_OR_TASK_MISMATCH");
|
||||
}
|
||||
if (
|
||||
receipt.carrier?.host !== "codex" ||
|
||||
receipt.carrier?.thread_id !== lane.thread_id ||
|
||||
receipt.carrier?.development_id !== lane.development_id ||
|
||||
!/^[A-Za-z0-9._:-]{16,256}$/u.test(receipt.carrier?.nonce ?? "")
|
||||
) {
|
||||
fail("PERSONA_SOURCE_BINDING_CARRIER_MISMATCH");
|
||||
}
|
||||
if (
|
||||
receipt.adapter?.id !== "CODEX-PRECONSCIOUS-ENTRY-001" ||
|
||||
!isSha256(receipt.adapter?.source_sha256) ||
|
||||
receipt.adapter.source_sha256 !== actualAdapterSourceSha256 ||
|
||||
!adapterSourcePath ||
|
||||
!allowedAdapterRoot ||
|
||||
!adapterSourcePath.startsWith(`${allowedAdapterRoot}/`)
|
||||
) {
|
||||
fail("PERSONA_SOURCE_ADAPTER_SHA_MISMATCH");
|
||||
}
|
||||
const cycle = receipt.brain_cycle ?? {};
|
||||
if (
|
||||
cycle.witness_decision !== "ALLOW_COMMIT" ||
|
||||
!Number.isInteger(cycle.completed_cycles_before) ||
|
||||
!Number.isInteger(cycle.completed_cycles_after) ||
|
||||
cycle.completed_cycles_after !== cycle.completed_cycles_before + 1 ||
|
||||
!isSha256(cycle.event_sha256) ||
|
||||
!isSha256(cycle.controller_witness_sha256)
|
||||
) {
|
||||
fail("PERSONA_SOURCE_BRAIN_CYCLE_INVALID");
|
||||
}
|
||||
if (
|
||||
receipt.carrier_consumption?.state !== CURRENT_CARRIER_CONSUMPTION ||
|
||||
receipt.carrier_consumption?.required_cycle_id !== cycle.cycle_id ||
|
||||
receipt.carrier_consumption?.required_witness_sha256 !==
|
||||
cycle.controller_witness_sha256
|
||||
) {
|
||||
fail("PERSONA_SOURCE_CARRIER_CONSUMPTION_INVALID");
|
||||
}
|
||||
if (
|
||||
!isSha256(receipt.checkpoint_sha256) ||
|
||||
receipt.checkpoint_sha256 !== actualCheckpointSha256 ||
|
||||
receipt.source_hashes?.checkpoint !== actualCheckpointSha256 ||
|
||||
REQUIRED_SOURCE_HASHES.some(
|
||||
(key) => !isSha256(receipt.source_hashes?.[key]),
|
||||
)
|
||||
) {
|
||||
fail("PERSONA_SOURCE_HASH_SET_INVALID");
|
||||
}
|
||||
for (const pointer of [pointerEvidence?.by_thread, pointerEvidence?.by_development]) {
|
||||
if (
|
||||
pointer?.thread_id !== lane.thread_id ||
|
||||
pointer?.development_id !== lane.development_id ||
|
||||
pointer?.checkpoint_sha256 !== receipt.checkpoint_sha256
|
||||
) {
|
||||
fail("PERSONA_SOURCE_CURRENT_POINTER_MISMATCH");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Loading…
Reference in a new issue