UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

133 lines (132 loc) 5.42 kB
import { i as resolveGlobalSingleton } from "./global-singleton-Dc_stLtU.js"; import { c as isRecord } from "./record-coerce-DItp3I4t.js"; import { i as openOpenClawStateDatabase } from "./openclaw-state-db-BRTnL-D8.js"; import { yt as validateDecisionReceiptV1 } from "./src-BiL5aQto.js"; import { o as parseExecutionIdentityAdmissionToken } from "./execution-identity-admission-Ch95Lxwv.js"; import { i as recordExecutionDecisionFact, l as pseudonymizeExecutionIdentityRef } from "./execution-decision-facts-CuS1RntZ.js"; //#region src/audit/execution-decision-work.ts const EXECUTION_DECISION_WORK_MAX_BYTES = 16384; const EXECUTION_DECISION_RAW_REF_MAX_LENGTH = 4096; const state = resolveGlobalSingleton(Symbol.for("openclaw.executionDecisionWorkSink"), () => ({ sink: void 0 })); function isClosedPayloadRecord(value) { if (!isRecord(value)) return false; const prototype = Object.getPrototypeOf(value); return prototype === Object.prototype || prototype === null; } function hasOnlyKeys(value, allowed) { const allowedKeys = new Set(allowed); return Object.keys(value).every((key) => allowedKeys.has(key)); } function parseRawRef(params) { if (!isClosedPayloadRecord(params.value) || !hasOnlyKeys(params.value, ["namespace", "value"]) || typeof params.value.namespace !== "string" || !params.namespaces.includes(params.value.namespace) || typeof params.value.value !== "string" || params.value.value.length < 1 || params.value.value.length > EXECUTION_DECISION_RAW_REF_MAX_LENGTH) throw new Error("execution decision work violates its bounded ref contract"); return { namespace: params.value.namespace, value: params.value.value }; } function buildReceipt(params) { return { ...params.receipt, contextId: params.token.contextId, executionId: params.token.executionId, runId: params.token.runId, action: { ...params.receipt.action, ...params.resourceRef ? { resourceRef: params.resourceRef } : {}, ...params.targetRef ? { targetRef: params.targetRef } : {} } }; } /** Revalidate closed work before queue cloning, key access, or database access. */ function parseExecutionDecisionWork(value) { if (!isClosedPayloadRecord(value) || !hasOnlyKeys(value, [ "workVersion", "token", "receipt", "refs" ]) || value.workVersion !== 1 || !isClosedPayloadRecord(value.receipt) || !hasOnlyKeys(value.receipt, [ "schemaVersion", "receiptId", "actionId", "occurredAt", "action", "decision", "enforcement", "source", "missingEvidence", "remediation" ]) || !isClosedPayloadRecord(value.receipt.action) || !hasOnlyKeys(value.receipt.action, [ "family", "operation", "summary" ])) throw new Error("execution decision work violates its bounded contract"); const token = parseExecutionIdentityAdmissionToken(value.token); let refs; if (value.refs !== void 0) { if (!isClosedPayloadRecord(value.refs) || !hasOnlyKeys(value.refs, ["resource", "target"])) throw new Error("execution decision work violates its bounded ref contract"); refs = { ...value.refs.resource !== void 0 ? { resource: parseRawRef({ value: value.refs.resource, namespaces: ["credential-profile"] }) } : {}, ...value.refs.target !== void 0 ? { target: parseRawRef({ value: value.refs.target, namespaces: ["model-route", "session"] }) } : {} }; } const receipt = value.receipt; const candidate = buildReceipt({ token, receipt, ...refs?.resource ? { resourceRef: "private-resource-ref" } : {}, ...refs?.target ? { targetRef: "private-target-ref" } : {} }); if (!validateDecisionReceiptV1(candidate)) throw new Error("execution decision work receipt violates DecisionReceiptV1"); const encoded = JSON.stringify(value); if (Buffer.byteLength(encoded, "utf8") > EXECUTION_DECISION_WORK_MAX_BYTES) throw new Error("execution decision work exceeds 16 KiB"); return { workVersion: 1, token, receipt, ...refs ? { refs } : {} }; } /** Project raw private refs at the audit owner, then persist only the bounded receipt. */ function processExecutionDecisionWork(value, options = {}) { const work = parseExecutionDecisionWork(value); const db = openOpenClawStateDatabase(options).db; const resourceRef = work.refs?.resource ? pseudonymizeExecutionIdentityRef({ db, kind: "credential", scope: work.refs.resource.namespace, value: work.refs.resource.value }) : void 0; const targetRef = work.refs?.target ? pseudonymizeExecutionIdentityRef({ db, kind: "target", scope: work.refs.target.namespace, value: work.refs.target.value }) : void 0; const receipt = buildReceipt({ token: work.token, receipt: work.receipt, ...resourceRef ? { resourceRef } : {}, ...targetRef ? { targetRef } : {} }); if (!validateDecisionReceiptV1(receipt)) throw new Error("execution decision work projection violates DecisionReceiptV1"); return recordExecutionDecisionFact(receipt, options); } /** Install the current process writer sink; callers never create a second writer. */ function configureExecutionDecisionWorkSink(sink) { state.sink = sink; return () => { if (state.sink === sink) state.sink = void 0; }; } /** Offer one private work item to the lifecycle-owned FIFO. */ function recordExecutionDecisionWork(work) { return state.sink?.(work) ?? false; } //#endregion export { recordExecutionDecisionWork as i, parseExecutionDecisionWork as n, processExecutionDecisionWork as r, configureExecutionDecisionWorkSink as t };