Compile closed execution plans and checked artifact manifests
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
/** Process/module ABI shared by generated adapters. Values are decoded against the checked
|
||||
* operation/port schema by the coordinator, not trusted because this header parsed. */
|
||||
export const transactionPortAbi = "quixos-transaction-ports-v1";
|
||||
export type PortAction =
|
||||
| { kind: "state"; primitive: "read" | "write" | "edit" }
|
||||
| { kind: "edge"; primitive: "resolve" | "connect" | "disconnect" }
|
||||
| { kind: "interface"; operationId: string; key?: string }
|
||||
| { kind: "query" }
|
||||
| { kind: "creation"; key: string };
|
||||
export interface PortInvocation {
|
||||
abi: typeof transactionPortAbi;
|
||||
/** Coordinator-issued frame and invocation handles, not application object IDs. */
|
||||
frame: string;
|
||||
invocation: string;
|
||||
sequence: number;
|
||||
portId: string;
|
||||
action: PortAction;
|
||||
input: unknown;
|
||||
}
|
||||
export interface PackageInvocation {
|
||||
abi: typeof transactionPortAbi;
|
||||
frame: string;
|
||||
invocation: string;
|
||||
exportId: string;
|
||||
effect: "snapshot" | "transaction" | "remote";
|
||||
/** Capability arguments/receiver use the versioned managed-reference codec. */
|
||||
input: unknown;
|
||||
receiver: unknown | null;
|
||||
}
|
||||
export type InvocationReply =
|
||||
| { abi: typeof transactionPortAbi; invocation: string; status: "returned"; output: unknown }
|
||||
| { abi: typeof transactionPortAbi; invocation: string; status: "failed"; error: { code: string; message: string } };
|
||||
export type ServiceControl =
|
||||
| { abi: typeof transactionPortAbi; kind: "ready" }
|
||||
| { abi: typeof transactionPortAbi; kind: "cancel"; invocation: string }
|
||||
| { abi: typeof transactionPortAbi; kind: "shutdown" };
|
||||
/** ABI-only header check. LF-08 resolves handles and enforces the frame/port authority. */
|
||||
export function checkPortInvocation(value: unknown): PortInvocation {
|
||||
if (!value || typeof value !== "object" || Array.isArray(value) || Object.getPrototypeOf(value) !== Object.prototype)
|
||||
throw new Error("Invalid port invocation");
|
||||
const fields = value as Record<string, unknown>;
|
||||
const keys = ["abi", "frame", "invocation", "sequence", "portId", "action", "input"];
|
||||
if (
|
||||
Object.keys(fields).length !== keys.length ||
|
||||
keys.some((key) => !Object.hasOwn(fields, key)) ||
|
||||
fields.abi !== transactionPortAbi
|
||||
)
|
||||
throw new Error("Invalid port invocation fields or ABI");
|
||||
for (const key of ["frame", "invocation", "portId"])
|
||||
if (typeof fields[key] !== "string" || !fields[key] || fields[key].length > 4096)
|
||||
throw new Error(`Invalid port invocation ${key}`);
|
||||
if (!Number.isSafeInteger(fields.sequence) || (fields.sequence as number) < 1)
|
||||
throw new Error("Invalid port invocation sequence");
|
||||
const action = fields.action as Record<string, unknown>;
|
||||
if (
|
||||
!action ||
|
||||
typeof action !== "object" ||
|
||||
Array.isArray(action) ||
|
||||
Object.getPrototypeOf(action) !== Object.prototype
|
||||
)
|
||||
throw new Error("Invalid port action");
|
||||
const exact = (names: string[]) =>
|
||||
Object.keys(action).length === names.length && names.every((name) => Object.hasOwn(action, name));
|
||||
const identifier = (value: unknown) => typeof value === "string" && value.length > 0 && value.length <= 1024;
|
||||
const valid =
|
||||
action.kind === "state"
|
||||
? exact(["kind", "primitive"]) && ["read", "write", "edit"].includes(action.primitive as string)
|
||||
: action.kind === "edge"
|
||||
? exact(["kind", "primitive"]) && ["resolve", "connect", "disconnect"].includes(action.primitive as string)
|
||||
: action.kind === "interface"
|
||||
? (exact(["kind", "operationId"]) || (exact(["kind", "operationId", "key"]) && identifier(action.key))) &&
|
||||
identifier(action.operationId)
|
||||
: action.kind === "creation"
|
||||
? exact(["kind", "key"]) && identifier(action.key)
|
||||
: action.kind === "query" && exact(["kind"]);
|
||||
if (!valid) throw new Error("Invalid port action");
|
||||
return { ...fields, action: { ...action } } as unknown as PortInvocation;
|
||||
}
|
||||
Reference in New Issue
Block a user