Add independently owned reconnectable execution units (WI-03)

This commit is contained in:
Timothy J. Aveni
2026-09-21 12:44:36 -07:00
parent 884b12f759
commit 89414107f9
5 changed files with 395 additions and 2 deletions
+122
View File
@@ -0,0 +1,122 @@
import assert from "node:assert/strict";
import { test } from "node:test";
import { loadReaderWorkspace } from "./reader-fixture.js";
import { buildArtifactFixture } from "./artifact-fixture.js";
import { capabilityId as id, type WorkspaceRevision } from "../src/capability-model/types.js";
import {
compileExecutionPlan,
compileExecutionGroups,
checkExecutionWorld,
checkedWorldDigest,
type ExecutionInstallation,
type ExecutionEnvironment,
} from "../src/execution-world/index.js";
const environment: ExecutionEnvironment = {
placement: "service",
hostDigest: "a".repeat(64),
policyDigest: "b".repeat(64),
credentialGeneration: "config:1",
};
const prepare = async (workspace: WorkspaceRevision) => {
const plan = compileExecutionPlan(workspace);
const fixtures = plan.definition.packages.map((pkg) => buildArtifactFixture(plan, pkg.revision));
const world = await checkExecutionWorld(
plan,
fixtures.map((f) => f.manifest),
fixtures[0]!.read,
);
const installation: ExecutionInstallation = {
codec: "camino-execution-installation-v1",
plan: plan.digest,
world: checkedWorldDigest(world),
routes: {},
components: [],
packages: fixtures.map((f) => ({
revision: f.manifest.packageRevisionId,
root: "/fixture",
service: f.manifest.implementations[0]!,
module: f.manifest.implementations[1]!,
})),
};
const environments = Object.fromEntries(plan.definition.packages.map((pkg) => [pkg.revision, { ...environment }]));
return { plan, installation, environments, groups: () => compileExecutionGroups(plan, installation, environments) };
};
test("execution reuse ignores world/source/display changes and unrelated packages", async () => {
const workspace = await loadReaderWorkspace(),
original = await prepare(workspace);
const before = original.groups()[0]!.executionDigest;
workspace.sourceRootCommit = "f".repeat(40);
workspace.packageImports[0]!.displayName = "Renamed";
workspace.packageImports[0]!.source.commit = "e".repeat(40);
workspace.packageImports.push({
packageId: id.package("unrelated"),
revisionId: id.packageRevision("unrelated@1"),
displayName: "Other",
source: workspace.packageImports[0]!.source,
exports: [],
});
const after = await prepare(workspace);
assert.notEqual(after.plan.digest, original.plan.digest);
assert.equal(
after.groups().find((g) => g.logicalId === workspace.packageImports[0]!.packageId)!.executionDigest,
before,
);
original.environments[workspace.packageImports[0]!.revisionId]!.credentialGeneration = "config:2";
assert.notEqual(original.groups()[0]!.executionDigest, before);
original.environments[workspace.packageImports[0]!.revisionId]!.placement = "module";
assert.notEqual(original.groups()[0]!.executionDigest, before);
});
test("outbound provider changes invalidate consumers while caller changes preserve providers", async () => {
const workspace = await loadReaderWorkspace((name, text) =>
name === "DocumentData.qx" ? text.replace("queryable value content", "queryable portable value content") : text,
);
const revision = id.packageRevision("provider@1"),
exportId = id.packageExport("provider:content"),
portId = id.dependencyPort("provider:state");
workspace.packageImports.push({
packageId: id.package("provider"),
revisionId: revision,
displayName: "Provider",
source: workspace.packageImports[0]!.source,
exports: [
{
kind: "operation",
id: exportId,
displayName: "content",
mode: "call",
inputType: { kind: "builtin", name: "unit" },
outputType: { kind: "scalar", name: "string" },
execution: { kind: "snapshot", targets: ["browser", "server"] },
receiverRequirement: { kind: "exact-atom", atomId: id.atom("atom:reader:document") },
dependencyPorts: [
{
id: portId,
displayName: "state",
requirement: { kind: "state", valueType: { kind: "scalar", name: "string" }, primitives: ["read"] },
},
],
},
],
});
const owner = workspace.conformances.find((c) => c.interfaceRevisionId === "interface:reader:document-data@1")!;
owner.operationBindings.find((b) => b.operationId === "document:content:get")!.binding = {
kind: "package",
packageRevisionId: revision,
exportId,
dependencies: [{ portId, binding: { kind: "state", slotId: id.slot("slot:document:content") } }],
};
const prepared = await prepare(workspace);
const values = () => new Map(prepared.groups().map((g) => [g.logicalId, g.executionDigest]));
const before = values();
prepared.installation.packages.find((p) => p.revision === "package:reader-runtime@1")!.service!.contentDigest =
"c".repeat(64);
const callerChanged = values();
assert.equal(callerChanged.get("provider"), before.get("provider"));
assert.notEqual(callerChanged.get("package:reader-runtime"), before.get("package:reader-runtime"));
prepared.installation.packages.find((p) => p.revision === revision)!.service!.contentDigest = "d".repeat(64);
const providerChanged = values();
assert.notEqual(providerChanged.get("provider"), callerChanged.get("provider"));
assert.notEqual(providerChanged.get("package:reader-runtime"), callerChanged.get("package:reader-runtime"));
});
+16
View File
@@ -4,6 +4,22 @@ import { generatePortableTypeScriptBindings } from "../src/bindings/portable.js"
import { compileExecutionPlan } from "../src/execution-world/plan.js";
import { loadReaderWorkspace } from "./reader-fixture.js";
test("service bindings depend on their consumed contract, not workspace or source provenance", async () => {
const schema = compileExecutionPlan(await loadReaderWorkspace()).definition.bindingSchema;
const pkg = schema.packages[0]!;
const before = generatePortableTypeScriptBindings(schema, pkg.revisionId, { target: "server" });
const other = structuredClone(pkg);
other.revisionId = "unrelated@1" as typeof other.revisionId;
other.exports = [];
schema.packages.push(other);
pkg.source.commit = "b".repeat(40);
pkg.revisionId = "same-service-new-source@2" as typeof pkg.revisionId;
assert.equal(generatePortableTypeScriptBindings(schema, pkg.revisionId, { target: "server" }), before);
assert.doesNotMatch(before, /export const (bindingDigest|packageRevision)/);
pkg.exports[0]!.inputType = { kind: "scalar", name: "bool" };
assert.notEqual(generatePortableTypeScriptBindings(schema, pkg.revisionId, { target: "server" }), before);
});
test("reader portable bindings have selected facets, creation inputs and stable keyed calls", async () => {
const schema = compileExecutionPlan(await loadReaderWorkspace()).definition.bindingSchema;
const source = generatePortableTypeScriptBindings(schema, "package:reader-runtime@1", { target: "browser" });