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")); });