Keep cold Candidate verification cooperative with controller renewals

This commit is contained in:
Timothy J. Aveni
2026-10-12 18:24:38 -07:00
parent 755c008a88
commit a48fccc328
5 changed files with 93 additions and 11 deletions
+12 -8
View File
@@ -1,7 +1,7 @@
import { graphExecutionRepresentation } from "./graph-execution.js";
import { lstat } from "node:fs/promises";
import { join } from "node:path";
import { hexDigest, ExecutionPlanError, type ExecutionPlan } from "./plan.js";
import { hexDigest, hexDigestAsync, ExecutionPlanError, type ExecutionPlan } from "./plan.js";
import {
loadExecutionInstallation,
createClientContractCatalog,
@@ -50,7 +50,7 @@ export async function loadCheckedInstallationCandidate(
const input = await readJson(root, "candidate.json", scope);
try {
const { executionContracts: _legacyContracts, ...workspace } = input.value;
return hexDigest(workspace);
return await hexDigestAsync(workspace);
} finally {
input.releaseTree();
}
@@ -72,8 +72,8 @@ export async function loadCheckedInstallationCandidate(
const [plan, artifacts, source, entryRequest, kernel, queries] = values;
if (
plan?.definition?.codec !== "camino-execution-plan-v1" ||
hexDigest(plan.definition) !== plan.digest ||
workspaceDigest !== hexDigest(plan.definition.workspace)
(await hexDigestAsync(plan.definition)) !== plan.digest ||
workspaceDigest !== (await hexDigestAsync(plan.definition.workspace))
)
throw new ExecutionPlanError(
"CANDIDATE_PLAN_MISMATCH",
@@ -117,7 +117,11 @@ export async function loadCheckedInstallationCandidate(
["kernel", kernel, "camino-kernel-program-v1"],
["queries", queries, "camino-query-program-v1"],
] as const)
if (program?.codec !== codec || program.plan !== kernel.plan || hexDigest(program) !== artifacts.programs?.[name])
if (
program?.codec !== codec ||
program.plan !== kernel.plan ||
(await hexDigestAsync(program)) !== artifacts.programs?.[name]
)
throw new ExecutionPlanError(
"CANDIDATE_PROGRAM_MISMATCH",
name,
@@ -129,8 +133,8 @@ export async function loadCheckedInstallationCandidate(
await (async () => {
const input = await readJson(root, "graph-execution.json", scope);
try {
const digest = hexDigest(input.value);
if (digest !== hexDigest(expectedGraph) || artifacts.execution !== digest)
const digest = await hexDigestAsync(input.value);
if (digest !== (await hexDigestAsync(expectedGraph)) || artifacts.execution !== digest)
throw new ExecutionPlanError(
"CANDIDATE_EXECUTION_MISMATCH",
root,
@@ -164,7 +168,7 @@ export async function loadCheckedInstallationCandidate(
return {
reference,
workspace: plan.definition.workspace.workspaceId,
world: hexDigest(expectedGraph),
world: await hexDigestAsync(expectedGraph),
plan: kernel.plan as string,
graphExecution: expectedGraph,
provenance,