Add local-first execution contracts to the capability language

This commit is contained in:
Timothy J. Aveni
2026-09-19 22:09:40 -07:00
parent 757531bb63
commit 03ac7f8557
24 changed files with 3872 additions and 2760 deletions
+240
View File
@@ -0,0 +1,240 @@
import assert from "node:assert/strict";
import { test } from "node:test";
import { compileCapabilityResourceSource } from "../src/capability-language/index.js";
const source = { repository: "https://example.test/execution.git", commit: "a".repeat(40) };
const data = (execution = "snapshot targets [browser, server]") =>
compileCapabilityResourceSource(
`
interface Data id "interface:data" revision "interface:data@1" {
queryable portable value label id "member:label" : string {
get id "operation:label:get" execution ${execution};
}
operation refresh id "member:refresh" : unit -> unit { call id "operation:refresh"; }
}`,
{ source },
);
const program = (selection: string, execution = "snapshot targets [browser, server]") => {
const contract = data();
assert.ok(contract.ok, JSON.stringify(contract.diagnostics));
assert.equal(contract.resource.kind, "interface");
if (contract.resource.kind !== "interface") throw new Error("Expected interface");
return compileCapabilityResourceSource(
`
import interface Data;
package Reader id "package:reader" revision "package:reader@1" {
function label id "export:label" : unit -> string execution ${execution} requires {
interface data id "port:data" : Data ${selection};
};
}`,
{
source,
environment: {
interfaces: new Map([["Data", contract.resource.revision]]),
interfaceClosure: [contract.resource.revision],
},
},
);
};
test("portable contracts preserve exact selected operations and targets", () => {
const result = program("using [label.get]");
assert.ok(result.ok, JSON.stringify(result.diagnostics));
assert.equal(result.resource.kind, "package");
if (result.resource.kind !== "package") return;
const entry = result.resource.revision.exports[0]!;
assert.deepEqual(entry.execution, { kind: "snapshot", targets: ["browser", "server"] });
assert.deepEqual(entry.dependencyPorts[0]!.requirement, {
kind: "interface",
interfaceRevisionId: "interface:data@1",
operations: ["operation:label:get"],
});
});
test("portable dependency diagnostics reject remote defaults, missing targets, and broad acquisition", () => {
for (const [selection, execution, message] of [
["using [refresh.call]", "snapshot targets [browser]", "remote-only"],
["using [label.get]", "snapshot targets [arduino]", "arduino"],
["", "snapshot targets [browser]", "select"],
["using [label.get, label.get]", "snapshot targets [browser]", "duplicates"],
["using [label.set]", "snapshot targets [browser]", "Unknown"],
]) {
const result = program(selection!, execution);
assert.equal(result.ok, false);
assert.match(JSON.stringify(result.diagnostics), new RegExp(message!));
}
});
test("portable query getters and target declarations are checked", () => {
assert.equal(data("remote").ok, false);
assert.equal(data("transaction targets [browser]").ok, false);
assert.equal(data("snapshot targets [browser, browser]").ok, false);
});
test("snapshot exports reject mutable state ports but transactions admit them", () => {
const compile = (effect: string) =>
compileCapabilityResourceSource(
`
package Reader id "package:reader" revision "package:reader@1" {
function update id "export:update" : string -> unit execution ${effect} targets [browser, server] requires {
state storage id "port:value" : string [read, write];
};
}`,
{ source },
);
const snapshot = compile("snapshot");
assert.equal(snapshot.ok, false);
assert.match(JSON.stringify(snapshot.diagnostics), /write primitives/);
const transaction = compile("transaction");
assert.ok(transaction.ok, JSON.stringify(transaction.diagnostics));
});
test("query placement round-trips and local extents never claim complete membership", async () => {
const { compileQuery } = await import("../src/query/compile.js");
const { linkQueries } = await import("../src/query/link.js");
const { toBinary, fromBinary, fromJson } = await import("@bufbuild/protobuf");
const { InstalledQuerySchema } = await import("../src/gen/camino/schema_pb.js");
const { formatQx, parseQx, walkSyntax, applySourceEdits } = await import("../src/capability-language/index.js");
const contract = data();
assert.ok(contract.ok && contract.resource.kind === "interface");
const iface = contract.resource.revision;
const text = `import interface Data;
package Reader id "package:reader" revision "package:reader@1" {
query Visible id "visible" root workspace Data document "visible.graphql" operation "Visible" { replica; }
query Presentation id "presentation" root workspace Data document "presentation.graphql" operation "Presentation" { local from Visible; }
}`;
const environment = { interfaces: new Map([["Data", iface]]), interfaceClosure: [iface] };
const compiled = compileCapabilityResourceSource(formatQx(text), { source, environment });
assert.ok(compiled.ok && compiled.resource.kind === "package", JSON.stringify(compiled.diagnostics));
const pkg = compiled.resource.revision;
assert.deepEqual(
pkg.queries!.map((q) => q.placement),
[{ kind: "replica" }, { kind: "local", sourceQueryId: "visible" }],
);
const parsed = parseQx(text);
const clause = [...walkSyntax(parsed.root)].find(
(node) => node.kind === "queryClause" && text.slice(node.start, node.end).startsWith("local"),
)!;
const edited = applySourceEdits(text, [{ ...clause, text: "local from Missing;" }]);
assert.equal(compileCapabilityResourceSource(edited, { source, environment }).ok, false);
const admission = pkg.queries![0]!,
local = pkg.queries![1]!;
const document = (name: string, field: string) =>
`query ${name} { root { ${field}(first: 10) { entries { node { label } } } } }`;
pkg.checkedQueries = [
await compileQuery(admission, [iface], async () => document("Visible", "objects")),
await compileQuery(local, [iface], async () => document("Presentation", "availableObjects")),
];
await assert.rejects(
compileQuery(local, [iface], async () => document("Presentation", "objects")),
/Cannot query field "objects"/,
);
const remote = structuredClone(iface);
delete remote.members[0]!.operations[0]!.execution;
await assert.rejects(
compileQuery(local, [remote], async () => document("Presentation", "availableObjects")),
/browser snapshot getter/,
);
const { capabilityId } = await import("../src/capability-model/index.js");
const linked = linkQueries({
id: capabilityId.workspaceRevision("w@1"),
workspaceId: capabilityId.workspace("w"),
sourceRootCommit: "a".repeat(40),
parentRevisionIds: [],
atoms: [],
sharedAttachments: [],
interfaceImports: [iface],
packageImports: [pkg],
conformances: [],
constructors: [],
});
const wire = fromJson(InstalledQuerySchema, linked[1]!.runtime!);
const roundtrip = fromBinary(InstalledQuerySchema, toBinary(InstalledQuerySchema, wire));
assert.deepEqual(roundtrip.placement?.kind, { case: "localSourceQueryId", value: "package:reader@1:visible" });
});
test("generated interface ports expose only selected operations", async () => {
const { generateTypeScriptBindings } = await import("../src/bindings/index.js");
const contract = data();
const result = program("using [label.get]");
assert.ok(contract.ok && contract.resource.kind === "interface");
assert.ok(result.ok && result.resource.kind === "package");
const generated = generateTypeScriptBindings(
{
format: "quixos-bindings",
version: 1,
interfaces: [contract.resource.revision],
packages: [result.resource.revision],
},
"package:reader@1",
);
assert.match(generated, /label\.get/);
assert.doesNotMatch(generated.split("export type Results")[0]!, /refresh\.call/);
assert.doesNotMatch(generated.split("const specs")[1]!, /refresh\.call/);
});
test("workspace validation checks concrete package and storage effects", async () => {
const { makeValidCapabilityWorkspace, fixtureId } = await import("./fixtures/capability-model.js");
const { validateWorkspaceRevision } = await import("../src/capability-model/index.js");
const workspace = makeValidCapabilityWorkspace();
const named = workspace.interfaceImports.find((i) => i.revisionId === fixtureId.namedV1)!;
const setter = named.members.flatMap((m) => m.operations).find((o) => o.id === fixtureId.namedSet)!;
setter.execution = { kind: "snapshot", targets: ["browser"] };
assert.ok(validateWorkspaceRevision(workspace).some((i) => i.message.includes("bind write primitives")));
setter.execution.kind = "transaction";
assert.deepEqual(validateWorkspaceRevision(workspace), []);
const summary = workspace.interfaceImports.find((i) => i.revisionId === fixtureId.summaryV1)!;
summary.members[0]!.operations[0]!.execution = { kind: "snapshot", targets: ["browser"] };
assert.ok(
validateWorkspaceRevision(workspace).some(
(i) => i.path.includes(fixtureId.summaryGet) && i.message.includes("remote-only"),
),
);
});
test("generic selected ports preserve operation identities and execution through specialization", async () => {
const { specializePackageExport, capabilityId } = await import("../src/capability-model/index.js");
const iface = compileCapabilityResourceSource(
`interface Cell<value T> id "cell" revision "cell@1" {
value content id "content" : T { get id "content:get" execution snapshot targets [browser, server]; }
}`,
{ source },
);
assert.ok(iface.ok && iface.resource.kind === "interface", JSON.stringify(iface.diagnostics));
const pkg = compileCapabilityResourceSource(
`import interface Cell;
package P id "p" revision "p@1" {
function load<value T> id "read" : unit -> T execution snapshot targets [browser, server] requires {
interface cell id "cell" : Cell<T> using [content.get];
};
}`,
{
source,
environment: {
interfaces: new Map([["Cell", iface.resource.revision]]),
interfaceClosure: [iface.resource.revision],
},
},
);
assert.ok(pkg.ok && pkg.resource.kind === "package", JSON.stringify(pkg.diagnostics));
const definition = pkg.resource.revision.genericExports![0]!;
const specialized = specializePackageExport(
pkg.resource.revision,
definition,
[{ kind: "value", type: { kind: "scalar", name: "string" } }],
{
arguments: new Map(),
applyInterface: (id, args) => {
assert.equal(id, "cell@1");
assert.deepEqual(args, [{ kind: "value", type: { kind: "scalar", name: "string" } }]);
return capabilityId.interfaceRevision("cell:string");
},
implementsInterface: () => false,
},
);
assert.deepEqual(specialized.execution, { kind: "snapshot", targets: ["browser", "server"] });
assert.deepEqual(specialized.dependencyPorts[0]!.requirement.kind, "interface");
const requirement = specialized.dependencyPorts[0]!.requirement;
if (requirement.kind === "interface")
assert.deepEqual(requirement.operations, [capabilityId.operation("content:get")]);
});