Keep checked execution groups and public catalog preparation cooperative

This commit is contained in:
Timothy J. Aveni
2026-10-12 19:21:34 -07:00
parent a4ba6169a6
commit 47b316180d
6 changed files with 243 additions and 228 deletions
+172 -175
View File
@@ -6,7 +6,7 @@ import type {
PersistentAttachment, PersistentAttachment,
} from "../capability-model/types.js"; } from "../capability-model/types.js";
import { type ExecutionInstallation, type ExecutionGroupIdentity } from "./installation.js"; import { type ExecutionInstallation, type ExecutionGroupIdentity } from "./installation.js";
import { type ExecutionPlan, hexDigest, ExecutionPlanError } from "./plan.js"; import { type ExecutionPlan, hexDigest, hexDigestAsync, ExecutionPlanError } from "./plan.js";
export interface ExecutionEnvironment { export interface ExecutionEnvironment {
/** Explicit host placement. Merely including an optional module does not select it. */ /** Explicit host placement. Merely including an optional module does not select it. */
@@ -23,12 +23,12 @@ export interface InstalledExecutionGroup extends ExecutionGroupIdentity {
} }
/** Conservative outbound closure. Runtime graph values, reverse callers, source /** Conservative outbound closure. Runtime graph values, reverse callers, source
* provenance and the workspace epoch are deliberately absent from this identity. */ * provenance and the workspace epoch are deliberately absent from this identity. */
export function compileExecutionGroups( export async function compileExecutionGroups(
plan: ExecutionPlan, plan: ExecutionPlan,
installation: ExecutionInstallation, installation: ExecutionInstallation,
environments: Readonly<Record<string, ExecutionEnvironment>>, environments: Readonly<Record<string, ExecutionEnvironment>>,
): InstalledExecutionGroup[] { ): Promise<InstalledExecutionGroup[]> {
if (installation.plan !== plan.digest || hexDigest(plan.definition) !== plan.digest) if (installation.plan !== plan.digest || (await hexDigestAsync(plan.definition)) !== plan.digest)
throw new ExecutionPlanError("GROUP_PLAN_MISMATCH", plan.digest, "Expected one checked installation"); throw new ExecutionPlanError("GROUP_PLAN_MISMATCH", plan.digest, "Expected one checked installation");
const workspace = plan.definition.workspace; const workspace = plan.definition.workspace;
const packages = new Map(workspace.packageImports.map((p) => [p.revisionId as string, p])); const packages = new Map(workspace.packageImports.map((p) => [p.revisionId as string, p]));
@@ -82,178 +82,175 @@ export function compileExecutionGroups(
}; };
const bindingContract = (value: DependencyBinding) => const bindingContract = (value: DependencyBinding) =>
value.kind === "query" ? { ...value, packageRevisionId: logical(value.packageRevisionId) } : value; value.kind === "query" ? { ...value, packageRevisionId: logical(value.packageRevisionId) } : value;
return installation.packages const groups: InstalledExecutionGroup[] = [];
.filter((p) => !!implementations.get(p.revision)) for (const root of installation.packages.filter((p) => !!implementations.get(p.revision))) {
.map((root) => { const consumed = new Map<string, unknown>(),
const consumed = new Map<string, unknown>(), visited = new Set<string>(),
visited = new Set<string>(), visitedQueries = new Set<string>(),
visitedQueries = new Set<string>(), consumedPackages = new Set<string>();
consumedPackages = new Set<string>(); const remember = (key: string, value: unknown) => consumed.set(key, value);
const remember = (key: string, value: unknown) => consumed.set(key, value); const storage = (id: string) => {
const storage = (id: string) => { const value = attachments.get(id);
const value = attachments.get(id); if (!value) throw new ExecutionPlanError("GROUP_STORAGE_MISSING", id, "Uninstalled consumed storage");
if (!value) throw new ExecutionPlanError("GROUP_STORAGE_MISSING", id, "Uninstalled consumed storage"); remember(`storage:${id}`, attachmentContract(value));
remember(`storage:${id}`, attachmentContract(value)); };
}; // Deletion may visit related objects and their owned state. Conservatively
// Deletion may visit related objects and their owned state. Conservatively // include the connected schema component, including possible future edges.
// include the connected schema component, including possible future edges. const lifecycle = (atom: string) => {
const lifecycle = (atom: string) => { const visited = new Set<string>(),
const visited = new Set<string>(), pending = [atom];
pending = [atom]; const atoms = (constraint: Extract<PersistentAttachment, { kind: "edge" }>["endpoints"][number]["constraint"]) =>
const atoms = ( constraint.kind === "atom"
constraint: Extract<PersistentAttachment, { kind: "edge" }>["endpoints"][number]["constraint"], ? [constraint.atomId as string]
) =>
constraint.kind === "atom"
? [constraint.atomId as string]
: workspace.conformances
.filter((c) => c.interfaceRevisionId === constraint.interfaceRevisionId)
.map((c) => c.atomId as string);
while (pending.length) {
const current = pending.pop()!;
if (visited.has(current)) continue;
visited.add(current);
for (const owner of workspace.conformances.filter((c) => c.atomId === current))
for (const attachment of owner.privateAttachments) storage(attachment.id);
for (const attachment of attachments.values())
if (attachment.kind === "edge" && attachment.endpoints.some((e) => atoms(e.constraint).includes(current))) {
storage(attachment.id);
pending.push(...attachment.endpoints.flatMap((e) => atoms(e.constraint)));
}
}
};
const targets = (binding: DependencyBinding, atom: string): string[] => {
if (binding.kind === "interface" && binding.receiver === "input")
return workspace.conformances
.filter((c) => c.interfaceRevisionId === binding.interfaceRevisionId)
.map((c) => c.atomId);
if (!("via" in binding) || !binding.via) return [atom];
storage(binding.via.edgeTypeId);
const edge = attachments.get(binding.via.edgeTypeId);
if (!edge || edge.kind !== "edge")
throw new ExecutionPlanError("GROUP_EDGE_MISSING", atom, "Missing traversal edge");
const endpoint = edge.endpoints.find((e) => e.projectionId !== binding.via!.projectionId)!;
const constraint = endpoint.constraint;
return constraint.kind === "atom"
? [constraint.atomId]
: workspace.conformances : workspace.conformances
.filter((c) => c.interfaceRevisionId === constraint.interfaceRevisionId) .filter((c) => c.interfaceRevisionId === constraint.interfaceRevisionId)
.map((c) => c.atomId); .map((c) => c.atomId as string);
}; while (pending.length) {
const query = (revision: string, id: string) => { const current = pending.pop()!;
const key = JSON.stringify([revision, id]); if (visited.has(current)) continue;
if (visitedQueries.has(key)) return; visited.add(current);
visitedQueries.add(key); for (const owner of workspace.conformances.filter((c) => c.atomId === current))
const value = plan.definition.queries.find((q) => q.id === key); for (const attachment of owner.privateAttachments) storage(attachment.id);
if (!value) throw new ExecutionPlanError("GROUP_QUERY_MISSING", key, "Missing consumed query"); for (const attachment of attachments.values())
remember(`query:${JSON.stringify([logical(revision), id])}`, value.query.checked.definitionDigest); if (attachment.kind === "edge" && attachment.endpoints.some((e) => atoms(e.constraint).includes(current))) {
for (const operation of value.operations) visit(operation); storage(attachment.id);
}; pending.push(...attachment.endpoints.flatMap((e) => atoms(e.constraint)));
const dependencies = (entry: PackageExport, bindings: readonly BoundDependency[], atom: string) => { }
for (const bound of bindings) { }
const target = bound.binding, };
port = entry.dependencyPorts.find((p) => p.id === bound.portId)!; const targets = (binding: DependencyBinding, atom: string): string[] => {
if ("via" in target && target.via) storage(target.via.edgeTypeId); if (binding.kind === "interface" && binding.receiver === "input")
if (target.kind === "reflection") { return workspace.conformances
for (const selector of target.selectors) .filter((c) => c.interfaceRevisionId === binding.interfaceRevisionId)
remember("reflection:" + selector, portableReflectionValue(workspace, selector)); .map((c) => c.atomId);
} else if (target.kind === "state") storage(target.slotId); if (!("via" in binding) || !binding.via) return [atom];
else if (target.kind === "edge") storage(target.edgeTypeId); storage(binding.via.edgeTypeId);
else if (target.kind === "query") query(target.packageRevisionId, target.queryId); const edge = attachments.get(binding.via.edgeTypeId);
else if (target.kind === "interface" && port.requirement.kind === "interface") { if (!edge || edge.kind !== "edge")
const iface = workspace.interfaceImports.find((i) => i.revisionId === target.interfaceRevisionId)!; throw new ExecutionPlanError("GROUP_EDGE_MISSING", atom, "Missing traversal edge");
for (const targetAtom of targets(target, atom)) const endpoint = edge.endpoints.find((e) => e.projectionId !== binding.via!.projectionId)!;
for (const op of port.requirement.operations ?? const constraint = endpoint.constraint;
iface.members.flatMap((m) => m.operations.map((o) => o.id))) return constraint.kind === "atom"
visit(JSON.stringify([targetAtom, target.interfaceRevisionId, op])); ? [constraint.atomId]
} else if (target.kind === "creation") { : workspace.conformances
for (const seed of target.owners) { .filter((c) => c.interfaceRevisionId === constraint.interfaceRevisionId)
const owner = workspace.conformances.find( .map((c) => c.atomId);
(c) => c.atomId === target.atomId && c.interfaceRevisionId === seed.interfaceRevisionId, };
)!; const query = (revision: string, id: string) => {
remember(`birth:${owner.id}`, { const key = JSON.stringify([revision, id]);
id: owner.id, if (visitedQueries.has(key)) return;
atom: owner.atomId, visitedQueries.add(key);
interface: owner.interfaceRevisionId, const value = plan.definition.queries.find((q) => q.id === key);
initialization: owner.initialization ?? [], if (!value) throw new ExecutionPlanError("GROUP_QUERY_MISSING", key, "Missing consumed query");
}); remember(`query:${JSON.stringify([logical(revision), id])}`, value.query.checked.definitionDigest);
for (const attachment of owner.privateAttachments) storage(attachment.id); for (const operation of value.operations) visit(operation);
} };
} else const dependencies = (entry: PackageExport, bindings: readonly BoundDependency[], atom: string) => {
throw new ExecutionPlanError( for (const bound of bindings) {
"GROUP_DEPENDENCY_UNSUPPORTED", const target = bound.binding,
bound.portId, port = entry.dependencyPorts.find((p) => p.id === bound.portId)!;
"Cannot establish execution reuse for this dependency", if ("via" in target && target.via) storage(target.via.edgeTypeId);
); if (target.kind === "reflection") {
} for (const selector of target.selectors)
}; remember("reflection:" + selector, portableReflectionValue(workspace, selector));
const visit = (key: string) => { } else if (target.kind === "state") storage(target.slotId);
if (visited.has(key)) return; else if (target.kind === "edge") storage(target.edgeTypeId);
visited.add(key); else if (target.kind === "query") query(target.packageRevisionId, target.queryId);
const operation = operations.get(key); else if (target.kind === "interface" && port.requirement.kind === "interface") {
if (!operation) throw new ExecutionPlanError("GROUP_OPERATION_MISSING", key, "Missing consumed operation"); const iface = workspace.interfaceImports.find((i) => i.revisionId === target.interfaceRevisionId)!;
const binding = operation.binding; for (const targetAtom of targets(target, atom))
if (binding.kind === "package") { for (const op of port.requirement.operations ?? iface.members.flatMap((m) => m.operations.map((o) => o.id)))
const pkg = packages.get(binding.packageRevisionId)!; visit(JSON.stringify([targetAtom, target.interfaceRevisionId, op]));
const implementation = implementations.get(pkg.revisionId); } else if (target.kind === "creation") {
if (!implementation) for (const seed of target.owners) {
throw new ExecutionPlanError( const owner = workspace.conformances.find(
"GROUP_IMPLEMENTATION_MISSING", (c) => c.atomId === target.atomId && c.interfaceRevisionId === seed.interfaceRevisionId,
pkg.revisionId, )!;
"Consumed package has no selected server implementation", remember(`birth:${owner.id}`, {
); id: owner.id,
consumedPackages.add(pkg.packageId); atom: owner.atomId,
remember(`implementation:${pkg.packageId}`, { interface: owner.interfaceRevisionId,
digest: implementation.contentDigest, initialization: owner.initialization ?? [],
environment: environment(pkg.revisionId), });
}); for (const attachment of owner.privateAttachments) storage(attachment.id);
const entry = pkg.exports.find((e) => e.id === binding.exportId)!; }
const bindings = binding.dependencies.map((d) => ({ portId: d.portId, binding: bindingContract(d.binding) })); } else
const acceptance = (binding.acceptanceDependencies ?? []).map((d) => ({ throw new ExecutionPlanError(
portId: d.portId, "GROUP_DEPENDENCY_UNSUPPORTED",
binding: bindingContract(d.binding), bound.portId,
})); "Cannot establish execution reuse for this dependency",
const contract = { );
input: operation.input, }
output: operation.output, };
execution: operation.execution, const visit = (key: string) => {
scope: operation.scope, if (visited.has(key)) return;
binding: { visited.add(key);
package: pkg.packageId, const operation = operations.get(key);
export: binding.exportId, if (!operation) throw new ExecutionPlanError("GROUP_OPERATION_MISSING", key, "Missing consumed operation");
dependencies: bindings, const binding = operation.binding;
acceptanceDependencies: acceptance, if (binding.kind === "package") {
}, const pkg = packages.get(binding.packageRevisionId)!;
}; const implementation = implementations.get(pkg.revisionId);
// Deduplicate aliases of the same bound export, rather than keying its owner by reverse callers. if (!implementation)
remember(`binding:${hexDigest(contract)}`, contract); throw new ExecutionPlanError(
dependencies(entry, binding.dependencies, operation.atomId); "GROUP_IMPLEMENTATION_MISSING",
if (entry.acceptanceExportId) pkg.revisionId,
dependencies( "Consumed package has no selected server implementation",
pkg.exports.find((e) => e.id === entry.acceptanceExportId)!, );
binding.acceptanceDependencies ?? [], consumedPackages.add(pkg.packageId);
operation.atomId, remember(`implementation:${pkg.packageId}`, {
); digest: implementation.contentDigest,
} else { environment: environment(pkg.revisionId),
remember(`operation:${key}`, operation); });
if (binding.kind === "state") storage(binding.slotId); const entry = pkg.exports.find((e) => e.id === binding.exportId)!;
if (binding.kind === "edge") storage(binding.edgeTypeId); const bindings = binding.dependencies.map((d) => ({ portId: d.portId, binding: bindingContract(d.binding) }));
if (binding.kind === "lifecycle") lifecycle(operation.atomId); const acceptance = (binding.acceptanceDependencies ?? []).map((d) => ({
} portId: d.portId,
}; binding: bindingContract(d.binding),
for (const operation of plan.definition.operations) }));
if (operation.binding.kind === "package" && operation.binding.packageRevisionId === root.revision) const contract = {
visit(operation.key); input: operation.input,
const own = implementations.get(root.revision)!; output: operation.output,
const exports = packages.get(root.revision)!.exports.map(({ displayName: _name, dependencyPorts, ...entry }) => ({ execution: operation.execution,
...entry, scope: operation.scope,
dependencyPorts: dependencyPorts.map(({ displayName: _name, ...port }) => port), binding: {
})); package: pkg.packageId,
const entries = [...consumed].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)); export: binding.exportId,
return { dependencies: bindings,
logicalId: logical(root.revision), acceptanceDependencies: acceptance,
packageRevision: root.revision, },
executionDigest: `sha256:${hexDigest({ implementation: own.contentDigest, exports, environment: environment(root.revision), versions: plan.definition.versions, consumed: entries })}`, };
consumedPackages: [...consumedPackages].sort(), // Deduplicate aliases of the same bound export, rather than keying its owner by reverse callers.
}; remember(`binding:${hexDigest(contract)}`, contract);
dependencies(entry, binding.dependencies, operation.atomId);
if (entry.acceptanceExportId)
dependencies(
pkg.exports.find((e) => e.id === entry.acceptanceExportId)!,
binding.acceptanceDependencies ?? [],
operation.atomId,
);
} else {
remember(`operation:${key}`, operation);
if (binding.kind === "state") storage(binding.slotId);
if (binding.kind === "edge") storage(binding.edgeTypeId);
if (binding.kind === "lifecycle") lifecycle(operation.atomId);
}
};
for (const operation of plan.definition.operations)
if (operation.binding.kind === "package" && operation.binding.packageRevisionId === root.revision)
visit(operation.key);
const own = implementations.get(root.revision)!;
const exports = packages.get(root.revision)!.exports.map(({ displayName: _name, dependencyPorts, ...entry }) => ({
...entry,
dependencyPorts: dependencyPorts.map(({ displayName: _name, ...port }) => port),
}));
const entries = [...consumed].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
groups.push({
logicalId: logical(root.revision),
packageRevision: root.revision,
executionDigest: `sha256:${await hexDigestAsync({ implementation: own.contentDigest, exports, environment: environment(root.revision), versions: plan.definition.versions, consumed: entries })}`,
consumedPackages: [...consumedPackages].sort(),
}); });
}
return groups;
} }
+28 -20
View File
@@ -3,7 +3,7 @@ import path from "node:path";
import { loadCheckedArtifactWorld } from "./receipts.js"; import { loadCheckedArtifactWorld } from "./receipts.js";
import { contentArtifactUrl, loadArtifactWorld, type LoadedArtifactWorld } from "./files.js"; import { contentArtifactUrl, loadArtifactWorld, type LoadedArtifactWorld } from "./files.js";
import { selectArtifactImplementation, type ArtifactImplementation, type ComponentArtifact } from "./artifacts.js"; import { selectArtifactImplementation, type ArtifactImplementation, type ComponentArtifact } from "./artifacts.js";
import { ExecutionPlanError, hexDigest, type ExecutionPlan } from "./plan.js"; import { ExecutionPlanError, hexDigestAsync, type ExecutionPlan } from "./plan.js";
import { import {
publicOperationContract, publicOperationContract,
publicQueryContract, publicQueryContract,
@@ -41,13 +41,13 @@ export interface ClientContractCatalog {
}[]; }[];
} }
/** Explicit projection prevents accidental spreading of filesystem roots or private bindings. */ /** Explicit projection prevents accidental spreading of filesystem roots or private bindings. */
export function clientContractCatalog( export async function clientContractCatalog(
plan: ExecutionPlan, plan: ExecutionPlan,
installation: ExecutionInstallation, installation: ExecutionInstallation,
requestedPackages: readonly string[], requestedPackages: readonly string[],
checkedKernel?: InspectionKernel, checkedKernel?: InspectionKernel,
): ClientContractCatalog { ): Promise<ClientContractCatalog> {
if (installation.plan !== plan.digest || hexDigest(plan.definition) !== plan.digest) if (installation.plan !== plan.digest || (await hexDigestAsync(plan.definition)) !== plan.digest)
throw new ExecutionPlanError( throw new ExecutionPlanError(
"CATALOG_PLAN_MISMATCH", "CATALOG_PLAN_MISMATCH",
plan.digest, plan.digest,
@@ -112,6 +112,7 @@ export function createClientContractCatalog(
const revisions = plan.definition.workspace.packageImports.map((pkg) => pkg.revisionId); const revisions = plan.definition.workspace.packageImports.map((pkg) => pkg.revisionId);
const installed = new Set<string>(revisions); const installed = new Set<string>(revisions);
let catalog: ClientContractCatalog | undefined; let catalog: ClientContractCatalog | undefined;
let preparing: Promise<void> | undefined;
let release: (() => void) | undefined; let release: (() => void) | undefined;
let closed = false; let closed = false;
const freeze = (value: unknown, seen = new WeakSet<object>()) => { const freeze = (value: unknown, seen = new WeakSet<object>()) => {
@@ -121,7 +122,7 @@ export function createClientContractCatalog(
Object.freeze(value); Object.freeze(value);
}; };
return { return {
select(requestedPackages: readonly string[]): ClientContractCatalog { async select(requestedPackages: readonly string[]): Promise<ClientContractCatalog> {
if (closed) throw Error("CANDIDATE_METADATA_CLOSED"); if (closed) throw Error("CANDIDATE_METADATA_CLOSED");
for (const revision of requestedPackages) for (const revision of requestedPackages)
if (!installed.has(revision)) if (!installed.has(revision))
@@ -129,22 +130,29 @@ export function createClientContractCatalog(
if (!catalog) { if (!catalog) {
// Like other candidate admission charges, this is an allocation estimate, // Like other candidate admission charges, this is an allocation estimate,
// not a V8 heap limit. The process/cgroup ceiling bounds transient work. // not a V8 heap limit. The process/cgroup ceiling bounds transient work.
const reservation = metadata.reserve(32 * 1024 * 1024); preparing ??= (async () => {
try { const reservation = metadata.reserve(32 * 1024 * 1024);
const compiled = clientContractCatalog(plan, installation, revisions, checkedKernel); try {
const bytes = Buffer.byteLength(JSON.stringify(compiled)); const compiled = await clientContractCatalog(plan, installation, revisions, checkedKernel);
if (bytes > 8 * 1024 * 1024) throw Error("CANDIDATE_CATALOG_LIMIT"); if (closed) throw Error("CANDIDATE_METADATA_CLOSED");
freeze(compiled); const bytes = Buffer.byteLength(JSON.stringify(compiled));
// No await between reservations: replacing the transient upper bound if (bytes > 8 * 1024 * 1024) throw Error("CANDIDATE_CATALOG_LIMIT");
// with a smaller retained estimate cannot race another admission. freeze(compiled);
reservation(); // No await between reservations: replacing the transient upper bound
release = metadata.reserve(Math.max(64 * 1024, bytes * 4)); // with a smaller retained estimate cannot race another admission.
catalog = compiled; reservation();
} catch (error) { release = metadata.reserve(Math.max(64 * 1024, bytes * 4));
reservation(); catalog = compiled;
throw error; } catch (error) {
} reservation();
throw error;
}
})().finally(() => {
preparing = undefined;
});
await preparing;
} }
if (closed || !catalog) throw Error("CANDIDATE_METADATA_CLOSED");
const requested = new Set(requestedPackages); const requested = new Set(requestedPackages);
return { return {
inspections: catalog.inspections, inspections: catalog.inspections,
+7 -12
View File
@@ -1,22 +1,17 @@
import { compileInspectionTemplates, type InspectionKernel } from "./inspection.js"; import { compileInspectionTemplates, type InspectionKernel } from "./inspection.js";
import { hexDigest, type ExecutionPlan } from "./plan.js"; import { hexDigestAsync, type ExecutionPlan } from "./plan.js";
import { clientContractCatalog, type ExecutionInstallation } from "./installation.js"; import type { ClientContractCatalog } from "./installation.js";
import { publicOperationContract, publicQueryContract } from "./client-contracts.js"; import { publicOperationContract, publicQueryContract } from "./client-contracts.js";
/** Explicit public projection of checked inputs. Never serialize conformance /** Explicit public projection of checked inputs. Never serialize conformance
* storage or package ports, or recompile a historical Candidate at runtime. */ * storage or package ports, or recompile a historical Candidate at runtime.
export function publicDefinitionSnapshot( * The caller supplies that Candidate's checked, cached public catalog. */
export async function publicDefinitionSnapshot(
plan: ExecutionPlan, plan: ExecutionPlan,
installation: ExecutionInstallation,
kernel: InspectionKernel, kernel: InspectionKernel,
catalog: ClientContractCatalog,
) { ) {
const workspace = plan.definition.workspace; const workspace = plan.definition.workspace;
const catalog = clientContractCatalog(
plan,
installation,
installation.packages.map((pkg) => pkg.revision),
kernel,
);
const rows = { const rows = {
atoms: workspace.atoms.map((atom) => ({ id: atom.id, name: atom.displayName, documentation: atom.documentation })), atoms: workspace.atoms.map((atom) => ({ id: atom.id, name: atom.displayName, documentation: atom.documentation })),
interfaces: workspace.interfaceImports.map((iface) => ({ interfaces: workspace.interfaceImports.map((iface) => ({
@@ -95,5 +90,5 @@ export function publicDefinitionSnapshot(
{ id: string; [key: string]: unknown }[] { id: string; [key: string]: unknown }[]
>; >;
for (const entries of Object.values(publicRows)) entries.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)); for (const entries of Object.values(publicRows)) entries.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
return { codec: "camino-definitions-v1" as const, id: hexDigest(publicRows), rows: publicRows }; return { codec: "camino-definitions-v1" as const, id: await hexDigestAsync(publicRows), rows: publicRows };
} }
+8 -8
View File
@@ -45,7 +45,7 @@ const prepare = async (workspace: WorkspaceRevision) => {
test("execution reuse ignores world/source/display changes and unrelated packages", async () => { test("execution reuse ignores world/source/display changes and unrelated packages", async () => {
const workspace = await loadReaderWorkspace(), const workspace = await loadReaderWorkspace(),
original = await prepare(workspace); original = await prepare(workspace);
const before = original.groups()[0]!.executionDigest; const before = (await original.groups())[0]!.executionDigest;
workspace.sourceRootCommit = "f".repeat(40); workspace.sourceRootCommit = "f".repeat(40);
workspace.packageImports[0]!.displayName = "Renamed"; workspace.packageImports[0]!.displayName = "Renamed";
workspace.packageImports[0]!.source.commit = "e".repeat(40); workspace.packageImports[0]!.source.commit = "e".repeat(40);
@@ -59,13 +59,13 @@ test("execution reuse ignores world/source/display changes and unrelated package
const after = await prepare(workspace); const after = await prepare(workspace);
assert.notEqual(after.plan.digest, original.plan.digest); assert.notEqual(after.plan.digest, original.plan.digest);
assert.equal( assert.equal(
after.groups().find((g) => g.logicalId === workspace.packageImports[0]!.packageId)!.executionDigest, (await after.groups()).find((g) => g.logicalId === workspace.packageImports[0]!.packageId)!.executionDigest,
before, before,
); );
original.environments[workspace.packageImports[0]!.revisionId]!.credentialGeneration = "config:2"; original.environments[workspace.packageImports[0]!.revisionId]!.credentialGeneration = "config:2";
assert.notEqual(original.groups()[0]!.executionDigest, before); assert.notEqual((await original.groups())[0]!.executionDigest, before);
original.environments[workspace.packageImports[0]!.revisionId]!.placement = "module"; original.environments[workspace.packageImports[0]!.revisionId]!.placement = "module";
assert.notEqual(original.groups()[0]!.executionDigest, before); assert.notEqual((await original.groups())[0]!.executionDigest, before);
}); });
test("outbound provider changes invalidate consumers while caller changes preserve providers", async () => { test("outbound provider changes invalidate consumers while caller changes preserve providers", async () => {
@@ -108,15 +108,15 @@ test("outbound provider changes invalidate consumers while caller changes preser
dependencies: [{ portId, binding: { kind: "state", slotId: id.slot("slot:document:content") } }], dependencies: [{ portId, binding: { kind: "state", slotId: id.slot("slot:document:content") } }],
}; };
const prepared = await prepare(workspace); const prepared = await prepare(workspace);
const values = () => new Map(prepared.groups().map((g) => [g.logicalId, g.executionDigest])); const values = async () => new Map((await prepared.groups()).map((g) => [g.logicalId, g.executionDigest]));
const before = values(); const before = await values();
prepared.installation.packages.find((p) => p.revision === "package:reader-runtime@1")!.service!.contentDigest = prepared.installation.packages.find((p) => p.revision === "package:reader-runtime@1")!.service!.contentDigest =
"c".repeat(64); "c".repeat(64);
const callerChanged = values(); const callerChanged = await values();
assert.equal(callerChanged.get("provider"), before.get("provider")); assert.equal(callerChanged.get("provider"), before.get("provider"));
assert.notEqual(callerChanged.get("package:reader-runtime"), before.get("package:reader-runtime")); 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); prepared.installation.packages.find((p) => p.revision === revision)!.service!.contentDigest = "d".repeat(64);
const providerChanged = values(); const providerChanged = await values();
assert.notEqual(providerChanged.get("provider"), callerChanged.get("provider")); assert.notEqual(providerChanged.get("provider"), callerChanged.get("provider"));
assert.notEqual(providerChanged.get("package:reader-runtime"), callerChanged.get("package:reader-runtime")); assert.notEqual(providerChanged.get("package:reader-runtime"), callerChanged.get("package:reader-runtime"));
}); });
+16 -3
View File
@@ -7,6 +7,7 @@ import {
checkExecutionWorld, checkExecutionWorld,
checkedWorldDigest, checkedWorldDigest,
implementationDigest, implementationDigest,
clientContractCatalog,
hexDigest, hexDigest,
parsePackageArtifacts, parsePackageArtifacts,
artifactPath, artifactPath,
@@ -386,7 +387,13 @@ test("public reflection contains nominal contracts and callable descriptors with
routes: {}, routes: {},
}; };
const kernel = compileKernelProgram(plan) as import("../src/execution-world/inspection.js").InspectionKernel; const kernel = compileKernelProgram(plan) as import("../src/execution-world/inspection.js").InspectionKernel;
const snapshot = publicDefinitionSnapshot(plan, installation, kernel); const catalog = await clientContractCatalog(
plan,
installation,
installation.packages.map((pkg) => pkg.revision),
kernel,
);
const snapshot = await publicDefinitionSnapshot(plan, kernel, catalog);
assert.ok(snapshot.rows.interfaces.length); assert.ok(snapshot.rows.interfaces.length);
assert.ok(snapshot.rows.queries.length); assert.ok(snapshot.rows.queries.length);
assert.ok(snapshot.rows.conformances.length); assert.ok(snapshot.rows.conformances.length);
@@ -401,13 +408,19 @@ test("public reflection contains nominal contracts and callable descriptors with
assert.ok(!publicText.includes('"' + privateKey + '"'), privateKey); assert.ok(!publicText.includes('"' + privateKey + '"'), privateKey);
assert.ok(publicText.includes('"descriptor"')); assert.ok(publicText.includes('"descriptor"'));
assert.ok(publicText.includes('"scope":"class"')); assert.ok(publicText.includes('"scope":"class"'));
assert.equal(snapshot.id, publicDefinitionSnapshot(plan, installation, kernel).id); assert.equal(snapshot.id, (await publicDefinitionSnapshot(plan, kernel, catalog)).id);
// Historical checked availability must survive a newer host compiler. If // Historical checked availability must survive a newer host compiler. If
// reflection silently regenerates the Kernel, this evidence disappears. // reflection silently regenerates the Kernel, this evidence disappears.
const historical = structuredClone(kernel); const historical = structuredClone(kernel);
const installed = historical.operations.find((operation) => !operation.unsupported)!; const installed = historical.operations.find((operation) => !operation.unsupported)!;
assert.ok(installed); assert.ok(installed);
installed.unsupported = "CHECKED_HISTORICAL_UNSUPPORTED"; installed.unsupported = "CHECKED_HISTORICAL_UNSUPPORTED";
const historicalSnapshot = publicDefinitionSnapshot(plan, installation, historical); const historicalCatalog = await clientContractCatalog(
plan,
installation,
installation.packages.map((pkg) => pkg.revision),
historical,
);
const historicalSnapshot = await publicDefinitionSnapshot(plan, historical, historicalCatalog);
assert.match(JSON.stringify(historicalSnapshot.rows.conformances), /CHECKED_HISTORICAL_UNSUPPORTED/); assert.match(JSON.stringify(historicalSnapshot.rows.conformances), /CHECKED_HISTORICAL_UNSUPPORTED/);
}); });
+12 -10
View File
@@ -249,13 +249,13 @@ test("checked component-only artifacts install without a service and reject miss
assert.ok(installation.routes[installation.components[0]!.url]); assert.ok(installation.routes[installation.components[0]!.url]);
assert.equal(JSON.stringify(installation.components).includes(root), false); assert.equal(JSON.stringify(installation.components).includes(root), false);
assert.equal(JSON.stringify(installation.components).includes("slot:"), false); assert.equal(JSON.stringify(installation.components).includes("slot:"), false);
const catalog = clientContractCatalog(plan, installation, [pkg.revision]); const catalog = await clientContractCatalog(plan, installation, [pkg.revision]);
assert.equal(catalog.presentations[0]!.component, "component:card"); assert.equal(catalog.presentations[0]!.component, "component:card");
assert.equal(catalog.components[0]!.subject, "interface:Data@1"); assert.equal(catalog.components[0]!.subject, "interface:Data@1");
assert.equal(JSON.stringify(catalog).includes(root), false); assert.equal(JSON.stringify(catalog).includes(root), false);
assert.equal(JSON.stringify(catalog).includes("bindingSchema"), false); assert.equal(JSON.stringify(catalog).includes("bindingSchema"), false);
assert.throws(() => clientContractCatalog(plan, installation, ["absent"]), /UNINSTALLED_PACKAGE/); await assert.rejects(() => clientContractCatalog(plan, installation, ["absent"]), /UNINSTALLED_PACKAGE/);
assert.throws( await assert.rejects(
() => clientContractCatalog(plan, { ...installation, plan: "bad" }, [pkg.revision]), () => clientContractCatalog(plan, { ...installation, plan: "bad" }, [pkg.revision]),
/CATALOG_PLAN_MISMATCH/, /CATALOG_PLAN_MISMATCH/,
); );
@@ -268,14 +268,16 @@ test("checked component-only artifacts install without a service and reject miss
compileKernelProgram(plan) as InspectionKernel, compileKernelProgram(plan) as InspectionKernel,
); );
try { try {
assert.throws(() => prepared.select(["absent"]), /UNINSTALLED_PACKAGE/); await assert.rejects(() => prepared.select(["absent"]), /UNINSTALLED_PACKAGE/);
assert.equal(scope.bytes, 0, "Unknown requests do not allocate compiler metadata"); assert.equal(scope.bytes, 0, "Unknown requests do not allocate compiler metadata");
assert.deepEqual(prepared.select([pkg.revision]), catalog); const [first, coalesced] = await Promise.all([prepared.select([pkg.revision]), prepared.select([pkg.revision])]);
assert.deepEqual(first, catalog);
assert.equal(first.operations, coalesced.operations, "Concurrent preparation shares one metadata reservation");
const retained = scope.bytes; const retained = scope.bytes;
assert.ok(retained > 0); assert.ok(retained > 0);
assert.ok(retained < 32 * 1024 * 1024, "Small catalogs retain a proportional metadata charge"); assert.ok(retained < 32 * 1024 * 1024, "Small catalogs retain a proportional metadata charge");
const full = prepared.select([pkg.revision]); const full = await prepared.select([pkg.revision]);
const empty = prepared.select([]); const empty = await prepared.select([]);
assert.deepEqual(empty.components, []); assert.deepEqual(empty.components, []);
assert.deepEqual(empty.presentations, []); assert.deepEqual(empty.presentations, []);
assert.deepEqual(empty.moduleBindings, []); assert.deepEqual(empty.moduleBindings, []);
@@ -290,14 +292,14 @@ test("checked component-only artifacts install without a service and reject miss
}, },
}); });
try { try {
assert.deepEqual(prepared.select([pkg.revision]), full); assert.deepEqual(await prepared.select([pkg.revision]), full);
assert.equal(scope.bytes, retained, "Package projections do not accumulate cache entries"); assert.equal(scope.bytes, retained, "Package projections do not accumulate cache entries");
} finally { } finally {
Object.defineProperty(plan, "definition", { configurable: true, value: definition }); Object.defineProperty(plan, "definition", { configurable: true, value: definition });
} }
prepared.close(); prepared.close();
assert.equal(scope.bytes, 0); assert.equal(scope.bytes, 0);
assert.throws(() => prepared.select([pkg.revision]), /CANDIDATE_METADATA_CLOSED/); await assert.rejects(() => prepared.select([pkg.revision]), /CANDIDATE_METADATA_CLOSED/);
} finally { } finally {
prepared.close(); prepared.close();
scope.release(); scope.release();
@@ -305,7 +307,7 @@ test("checked component-only artifacts install without a service and reject miss
const tight = new CandidateMetadataBudget({ bytes: 1000, ownerBytes: 1000, candidates: 1 }); const tight = new CandidateMetadataBudget({ bytes: 1000, ownerBytes: 1000, candidates: 1 });
const tightScope = tight.acquire("catalog-test"); const tightScope = tight.acquire("catalog-test");
const refused = createClientContractCatalog(plan, installation, tightScope); const refused = createClientContractCatalog(plan, installation, tightScope);
assert.throws(() => refused.select([pkg.revision]), /CANDIDATE_METADATA_LIMIT/); await assert.rejects(() => refused.select([pkg.revision]), /CANDIDATE_METADATA_LIMIT/);
assert.equal(tightScope.bytes, 0); assert.equal(tightScope.bytes, 0);
refused.close(); refused.close();
tightScope.release(); tightScope.release();