Acquire installed portable operations with explicit authority and input coverage

This commit is contained in:
Timothy J. Aveni
2026-09-20 02:19:00 -07:00
parent 8fd800e69a
commit d9bd5b2800
18 changed files with 477 additions and 2 deletions
+1
View File
@@ -428,3 +428,4 @@ export {
PortableBindingError,
type PortableBindingOptions,
} from "./portable.js";
export * from "./portable-client.js";
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env node
import { readFile, writeFile } from "node:fs/promises";
import { generatePortableClientBindings } from "./portable-client.js";
async function main() {
const [plan, output, target = "browser", ...rest] = process.argv.slice(2);
if (!plan || !output || rest.length)
throw Error("usage: quixos-codegen-client EXECUTION_PLAN.json OUTPUT.ts [TARGET]");
await writeFile(output, generatePortableClientBindings(JSON.parse(await readFile(plan, "utf8")), { target }));
}
void main().catch((error) => {
console.error(error instanceof Error ? error.message : error);
process.exitCode = 1;
});
+68
View File
@@ -0,0 +1,68 @@
import { hexDigest, type ExecutionPlan } from "../execution-world/plan.js";
import { resultInterfaces } from "../execution-world/projections.js";
import { portableValueSchema, tsType, PortableBindingError } from "./portable.js";
/** Closed-world app descriptors. Handler bindings and application acquisition share the same public identities. */
export function generatePortableClientBindings(
plan: ExecutionPlan,
options: { target: string; runtimeModule?: string },
): string {
if (hexDigest(plan.definition) !== plan.digest) throw new PortableBindingError("client", "Invalid plan digest");
const workspace = plan.definition.workspace,
atoms = new Map<string, string[]>(),
unavailable: { key: string; reason: string }[] = [];
const seen = new Set<string>();
for (const operation of plan.definition.operations) {
if (operation.execution.kind === "remote" || !operation.execution.targets.includes(options.target)) {
unavailable.push({ key: operation.key, reason: "OPERATION_NOT_PORTABLE" });
continue;
}
let input: string, output: string;
try {
input = tsType(operation.input);
output = tsType(operation.output);
} catch (error) {
if (!(error instanceof PortableBindingError)) throw error;
unavailable.push({ key: operation.key, reason: "UNSUPPORTED_OPERATION_CODEC" });
continue;
}
const atom = workspace.atoms.find((a) => a.id === operation.atomId)!;
const iface = workspace.interfaceImports.find((i) => i.revisionId === operation.interfaceRevisionId)!;
const member = iface.members.find((m) => m.operations.some((o) => o.id === operation.operationId))!;
const facet = member.operations.find((o) => o.id === operation.operationId)!;
const name = `${iface.displayName}.${member.displayName}.${facet.displayName}`;
const alias = JSON.stringify([atom.displayName, name]);
if (seen.has(alias)) throw new PortableBindingError(alias, "Ambiguous application descriptor alias");
seen.add(alias);
const roots = resultInterfaces(plan, operation.key);
const descriptor = {
key: operation.key,
plan: plan.digest,
effect: operation.execution.kind,
input: portableValueSchema(operation.input),
output: portableValueSchema(operation.output),
resultInterfaces: roots,
};
const list = atoms.get(atom.displayName) ?? [];
list.push(
`${JSON.stringify(name)}: defineOperationDescriptor<${input}, ${output}, ${roots.map((r) => JSON.stringify(r)).join(" | ") || "never"}, ${JSON.stringify(operation.execution.kind)}>(${JSON.stringify(descriptor)})`,
);
atoms.set(atom.displayName, list);
}
const queries = new Map<string, string[]>();
for (const query of plan.definition.queries) {
const declaration = query.query.checked.declaration;
if (declaration.placement?.kind !== "replica") continue;
const pkg = workspace.packageImports.find((p) => p.revisionId === query.query.packageRevisionId)!;
const alias = JSON.stringify([pkg.displayName, declaration.displayName]);
if (seen.has(`query:${alias}`)) throw new PortableBindingError(alias, "Ambiguous query alias");
seen.add(`query:${alias}`);
const list = queries.get(pkg.displayName) ?? [];
list.push(
`${JSON.stringify(declaration.displayName)}: { id: ${JSON.stringify(query.id)}, plan: ${JSON.stringify(plan.digest)}, root: ${JSON.stringify(declaration.root.interface)}, rootKind: ${JSON.stringify(declaration.root.kind)} } as const satisfies ReplicaProjection<${JSON.stringify(declaration.root.interface)}, ${JSON.stringify(declaration.root.kind)}>`,
);
queries.set(pkg.displayName, list);
}
const groups = (entries: Map<string, string[]>) =>
[...entries].map(([name, values]) => `${JSON.stringify(name)}: {${values.join(",\n")}}`).join(",\n");
return `// Generated application descriptors. Regenerate; do not edit.\nimport { defineOperationDescriptor, type ManagedReference, type ReplicaProjection } from ${JSON.stringify(options.runtimeModule ?? "@quixos/camino-replica-core")};\nexport const planDigest = ${JSON.stringify(plan.digest)};\nexport const operations = {${groups(atoms)}} as const;\nexport const queries = {${groups(queries)}} as const;\nexport const unavailable = ${JSON.stringify(unavailable)} as const;\n`;
}
+1 -1
View File
@@ -52,7 +52,7 @@ export function portableValueSchema(type: ValueType): unknown {
"Unsupported portable value; use a supported record/reference contract (native edits and generic adapters have separate tasks)",
);
}
function tsType(type: ValueType): string {
export function tsType(type: ValueType): string {
portableValueSchema(type);
switch (type.kind) {
case "scalar":
+2
View File
@@ -8,3 +8,5 @@ export * from "./receipts.js";
export { generatePortableTypeScriptBindings } from "../bindings/portable.js";
export * from "./kernel.js";
export * from "./projections.js";
export { generatePortableClientBindings } from "../bindings/portable-client.js";
+44
View File
@@ -0,0 +1,44 @@
import { ExecutionPlanError, hexDigest, type ExecutionPlan, type PlannedQuery } from "./plan.js";
/** Contracts promised by a direct result. Interface dependencies are explicit; accidental
* overlap among today's implementations does not silently widen an exported interface contract. */
export function resultInterfaces(plan: ExecutionPlan, operationKey: string): string[] {
const operation = plan.definition.operations.find((operation) => operation.key === operationKey);
if (!operation) throw new ExecutionPlanError("UNKNOWN_OPERATION", operationKey, "No installed public operation");
if (operation.output.kind !== "object-ref") return [];
const expected = operation.output.expectation;
if (expected.kind === "atom")
return plan.definition.workspace.conformances
.filter((c) => c.atomId === expected.atomId)
.map((c) => c.interfaceRevisionId)
.sort();
const interfaces = new Map(plan.definition.workspace.interfaceImports.map((i) => [String(i.revisionId), i]));
const result = new Set<string>();
const visit = (id: string) => {
if (result.has(id)) return;
result.add(id);
for (const dependency of interfaces.get(id)?.requiredInterfaces ?? []) visit(dependency);
};
visit(expected.interfaceRevisionId);
return [...result].sort();
}
/** Compile-time observeResult compatibility. Observation does not grant read or mutation authority. */
export function checkResultProjection(plan: ExecutionPlan, operationKey: string, queryId: string): PlannedQuery {
if (hexDigest(plan.definition) !== plan.digest)
throw new ExecutionPlanError("INVALID_PLAN", "projection", "Plan digest mismatch");
const query = plan.definition.queries.find((q) => q.id === queryId);
if (!query) throw new ExecutionPlanError("UNKNOWN_PROJECTION", queryId, "No installed query");
const declaration = query.query.checked.declaration;
if (declaration.placement?.kind !== "replica" || declaration.root.kind !== "object")
throw new ExecutionPlanError(
"INVALID_RESULT_PROJECTION",
queryId,
"Result observation requires a direct-object replica declaration",
);
if (!resultInterfaces(plan, operationKey).includes(declaration.root.interface))
throw new ExecutionPlanError(
"RESULT_PROJECTION_MISMATCH",
operationKey,
`Result does not promise ${declaration.root.interface}`,
);
return query;
}