import { readFileSync } from "node:fs"; import { workflowSourceInputSchema } from "../source/workflow-source-structured.js"; import { prepareWorkflowTypedInput, workflowTypedInputProjection, type WorkflowInputValue, type WorkflowTypedInput, type WorkflowOperatorContext, } from "./workflow-input.js"; import { canonicalWorkflowJSON } from "./structured-results/schema.js"; /** * workflow-run-admission.ts — The ordered pre-execution admission of one run. * * ORDER IS THE CONTRACT, and it is the reason this is one module instead of four * helpers the runner could call in any sequence: * * 1. target binding — what workflow was asked for, resolved once by the host * 2. source snapshot — the exact bytes that will execute, hashed and retained * 3. workspace identity — which workspace this run may write, and whether resume * or an operator handoff proves the right to reuse it * 4. launch binding — the independent persisted authority a later resume reads * * Each step may only read what an earlier step established: a workspace is never * admitted before the script identity it is bound to exists, and the launch binding * is written only after both. * * What this module is NOT allowed to do, so that "refused" stays refused: * - it never calls the runner and never starts execution; * - it never claims the run or writes the journal prelude — those happen BEFORE * admission, so a refused run still leaves a visible run directory and journal; * - it never acquires the root lease or builds shared execution state — the runner * does that AFTER a successful admission, so no `agent_start` can precede one. * * It may import `workflow-run-resume.ts` (the resume authority); that module must * not import this one, and neither imports the runner. */ import path from "node:path"; import { realpathSync } from "node:fs"; import { assertWorkflowOutputDirRemoved } from "../catalog/workflow-meta.js"; import type { WorkflowContinuation } from "./workflow-artifacts.js"; import type { WorkflowBudget } from "./workflow-budget.js"; import { assertResolvedWorkflowTargetBinding, resolveWorkflowTarget, WORKFLOW_ENTRY_SUFFIX, type ResolvedWorkflowTarget, } from "./workflow-discovery.js"; import { assertWorkflowHandoffClaimEligibility, type WorkflowHandoffClaimLease } from "./workflow-handoff.js"; import { readInterruptedWorkflowResumeBinding, workflowRecoveryInputHash } from "./workflow-interrupted-recovery.js"; import { readWorkflowRunResult } from "./workflow-journal.js"; import { createWorkflowLaunchBinding, projectWorkflowLaunchBindingOntoResult, readWorkflowLaunchBinding, readWorkflowRootLineageId, workflowExecutionMigrationMessage, workflowLaunchBindingMatchesResult, writeWorkflowLaunchBinding, type WorkflowLaunchBinding, } from "./workflow-launch-binding.js"; import { assertWorkflowRunName, assertFreshWorkflowWorkspaceNamespace, assertFreshWorkflowWorkspaceNamespacePath, isLegacyWorkflowWorkspacePath, resolveWorkflowWorkspaceDirectory, resolveWorkflowWorkspaceDirectoryPath, resolveWorkflowWorkspaceDirectoryForReuse, resolveNamedWorkflowWorkspacePath, type WorkflowWorkspaceDirectory, } from "./workflow-output.js"; import { verifyWorkflowPersistedSnapshot } from "./workflow-persisted-binding.js"; import { isTaskWorkspaceName, WORKFLOW_PLANS_DIRNAME, WORKFLOW_ROOT_DIRNAME, WORKFLOW_WORKSPACES_DIRNAME, } from "./workflow-run-layout.js"; import { isPostCodeReviewTarget, persistedTargetIdentityKey, readWorkflowResumeWorkspaceIdentityFromResult, assertWorkflowHandoffWorkspaceReuse, targetIdentityKey, type WorkflowHandoffWorkspaceReuseBinding, type WorkflowResumeSourceBinding, type WorkflowResumeWorkspaceIdentity, type WorkflowSemanticInputIdentity, } from "./workflow-run-resume.js"; import { isPostCodeReviewTargetProjection } from "./workflow-saved-name.js"; import { createWorkflowScriptSnapshot, type WorkflowScriptIdentity } from "./workflow-script-identity.js"; import type { WorkflowRunnerCoordination } from "./workflow-saved-child.js"; const TASK_PLAN_REFS: ReadonlySet = new Set(["task/plan", "task/plan-light"]); /** Validate a host-owned target binding before any snapshot or import. */ export function assertWorkflowTargetBinding( binding: unknown, request: { name?: string; scriptPath?: string; script?: string }, projectRoot: string, workingDirectory = projectRoot, ): ResolvedWorkflowTarget { return assertResolvedWorkflowTargetBinding(binding, request, projectRoot, workingDirectory); } function workflowDefaultWorkspaceName(target: ResolvedWorkflowTarget): string { return target.kind === "name" ? target.ref : path.basename(target.path, WORKFLOW_ENTRY_SUFFIX); } /** The launch request fields admission reads. Deliberately narrower than the runner's options. */ export interface WorkflowRunAdmissionLaunch { targetBinding?: ResolvedWorkflowTarget; name?: string; scriptPath?: string; script?: string; input?: string; inputValue?: WorkflowInputValue; operatorAnswer?: string; workspaceDir?: string; /** @deprecated Legacy launch field; rejected by admission when supplied. */ outputDir?: string; runName?: string; continuation?: WorkflowContinuation; operatorHandoffClaim?: WorkflowHandoffClaimLease; operatorHandoffWorkspaceReuse?: WorkflowHandoffWorkspaceReuseBinding; recoverInterrupted?: boolean; } export interface WorkflowRunAdmissionRequest { projectRoot: string; workingDirectory: string; runId: string; runDir: string; /** Where the retained script snapshot is written for this run. */ runtimeDir: string; items: readonly string[]; budget: WorkflowBudget; noOperator?: true; /** Whether the caller asked for a resume at all, before the run id was validated. */ hasResume: boolean; /** The validated source run id, when this launch is a resume. */ resumeFromRunId?: string; requestedSemanticInput: WorkflowSemanticInputIdentity; inheritedCoordination?: WorkflowRunnerCoordination; launch: WorkflowRunAdmissionLaunch; } /** * What admission established before it finished, admitted or not. * * A refusal still reports this: the run's terminal result must project the same * workspace and handoff facts a refusal already committed to, exactly as it did * when these locals lived in the runner. */ export interface WorkflowRunAdmissionState { typedInput?: WorkflowTypedInput; interruptedRecovery: boolean; resumeSourceWorkspace?: WorkflowResumeWorkspaceIdentity; resumeSourceBinding?: WorkflowResumeSourceBinding; handoffReuseWorkspace?: WorkflowWorkspaceDirectory; stableWorkspace?: WorkflowWorkspaceDirectory; } export type WorkflowRunAdmissionOutcome = | (WorkflowRunAdmissionState & { admitted: true; target: ResolvedWorkflowTarget; scriptIdentity: WorkflowScriptIdentity; stableWorkspace: WorkflowWorkspaceDirectory; /** The directory binding a root run hands its coordination; lineage scopes every root checkpoint. */ coordinationDirectory: Pick; }) | (WorkflowRunAdmissionState & { admitted: false; error: string; /** Present only once the step that establishes it has passed. */ target?: ResolvedWorkflowTarget; scriptIdentity?: WorkflowScriptIdentity; }); /** * Run the four admission steps in order and return the validated data, or the * first refusal with exactly the evidence that was established when it happened. */ export async function admitWorkflowRun(request: WorkflowRunAdmissionRequest): Promise { const { projectRoot, workingDirectory, runId, runDir, runtimeDir, items, budget, noOperator, hasResume, resumeFromRunId, requestedSemanticInput, inheritedCoordination, launch: opts, } = request; let typedInput: WorkflowTypedInput | undefined; let selectedWorkspaceDir = inheritedCoordination?.workspace.relativePath ?? opts.workspaceDir; let interruptedRecovery = false; let resumeSourceWorkspace: WorkflowResumeWorkspaceIdentity | undefined; let resumeSourceBinding: WorkflowResumeSourceBinding | undefined; let handoffReuseWorkspace: WorkflowWorkspaceDirectory | undefined; let stableWorkspace: WorkflowWorkspaceDirectory | undefined = inheritedCoordination?.workspace; const state = (): WorkflowRunAdmissionState => ({ ...(typedInput === undefined ? {} : { typedInput }), interruptedRecovery, ...(resumeSourceWorkspace === undefined ? {} : { resumeSourceWorkspace }), ...(resumeSourceBinding === undefined ? {} : { resumeSourceBinding }), ...(handoffReuseWorkspace === undefined ? {} : { handoffReuseWorkspace }), ...(stableWorkspace === undefined ? {} : { stableWorkspace }), }); // --- 1. target binding --------------------------------------------------- let target: ResolvedWorkflowTarget; try { if (opts.outputDir !== undefined) { throw new Error( "workflow launch outputDir was removed; state exact file destinations in agent prompts; workspaceDir selects native runtime state only", ); } if (opts.targetBinding !== undefined) { target = assertWorkflowTargetBinding( opts.targetBinding, { ...(opts.name === undefined ? {} : { name: opts.name }), ...(opts.scriptPath === undefined ? {} : { scriptPath: opts.scriptPath }), ...(opts.script === undefined ? {} : { script: opts.script }), }, projectRoot, workingDirectory, ); } else { const targetInput: { name?: string; scriptPath?: string; script?: string } = {}; if (opts.name !== undefined) targetInput.name = opts.name; if (opts.scriptPath !== undefined) targetInput.scriptPath = opts.scriptPath; if (opts.script !== undefined) targetInput.script = opts.script; target = resolveWorkflowTarget(targetInput, projectRoot, workingDirectory); } if (opts.runName !== undefined) { if (opts.workspaceDir !== undefined) { throw new Error("workflow runName and workspaceDir are mutually exclusive"); } assertWorkflowRunName(opts.runName); } } catch (err) { return { admitted: false, error: err instanceof Error ? err.message : String(err), ...state() }; } // --- 2. source snapshot / script identity -------------------------------- let scriptIdentity: WorkflowScriptIdentity; try { scriptIdentity = createWorkflowScriptSnapshot(target.path, runtimeDir); assertWorkflowOutputDirRemoved(scriptIdentity.snapshotPath); const schema = workflowSourceInputSchema(readFileSync(scriptIdentity.snapshotPath, "utf8")); let operatorContext: WorkflowOperatorContext | undefined; const consumedOrigins = new Map(); const contextSourceId = opts.operatorHandoffClaim?.sourceRunId ?? resumeFromRunId; if (contextSourceId !== undefined) { const origin = readWorkflowLaunchBinding(projectRoot, contextSourceId); if (origin?.typedInput !== undefined) { consumedOrigins.set(contextSourceId, canonicalWorkflowJSON(origin)); if ( !workflowLaunchBindingMatchesResult(origin, readWorkflowRunResult(projectRoot, contextSourceId)) && opts.recoverInterrupted !== true ) throw new Error("typed input origin has no matching authoritative result"); operatorContext = opts.operatorHandoffClaim === undefined ? origin.typedInput.operatorContext : opts.operatorAnswer === undefined ? undefined : { originRunId: contextSourceId, operatorAnswer: opts.operatorAnswer }; if ( opts.operatorHandoffClaim !== undefined && canonicalWorkflowJSON(opts.inputValue) !== canonicalWorkflowJSON(origin.typedInput.value) ) throw new Error("typed input continuation must preserve the origin value"); } } if ( opts.operatorAnswer !== undefined && (opts.operatorHandoffClaim === undefined || operatorContext === undefined || typeof opts.operatorAnswer !== "string") ) throw new Error("typed input operatorAnswer requires a matching typed handoff claim"); if (operatorContext !== undefined) { const origin = readWorkflowLaunchBinding(projectRoot, operatorContext.originRunId); if (origin !== null) consumedOrigins.set(operatorContext.originRunId, canonicalWorkflowJSON(origin)); if ( origin?.typedInput === undefined || !workflowLaunchBindingMatchesResult(origin, readWorkflowRunResult(projectRoot, operatorContext.originRunId)) || origin.scriptIdentity.scriptSha256 !== scriptIdentity.scriptSha256 || canonicalWorkflowJSON(origin.typedInput.schema) !== canonicalWorkflowJSON(schema) || canonicalWorkflowJSON(origin.typedInput.value) !== canonicalWorkflowJSON(opts.inputValue) ) throw new Error("typed input operator context origin is invalid"); } typedInput = await prepareWorkflowTypedInput(opts, schema, operatorContext); for (const [originRunId, consumed] of consumedOrigins) { const origin = readWorkflowLaunchBinding(projectRoot, originRunId); if ( origin === null || canonicalWorkflowJSON(origin) !== consumed || (opts.recoverInterrupted !== true && !workflowLaunchBindingMatchesResult(origin, readWorkflowRunResult(projectRoot, originRunId))) ) throw new Error("typed input origin authority changed during admission"); } if (inheritedCoordination?.expectedChildSource !== undefined) { const actualCanonicalPath = realpathSync(target.path); const expected = inheritedCoordination.expectedChildSource; if (actualCanonicalPath !== expected.canonicalPath || scriptIdentity.scriptSha256 !== expected.scriptSha256) { throw new Error( `saved child workflow source changed before execution: ${JSON.stringify(target.ref)} ` + `(expected ${expected.canonicalPath}#${expected.scriptSha256}, ` + `got ${actualCanonicalPath}#${scriptIdentity.scriptSha256})`, ); } } } catch (err) { return { admitted: false, error: err instanceof Error ? err.message : String(err), target, ...state() }; } const taskPlanRef = target.source === "package" && target.kind === "name" ? target.ref : ""; if (TASK_PLAN_REFS.has(taskPlanRef) && !opts.input?.trim()) { return { admitted: false, error: `${taskPlanRef} requires the complete accepted draft as non-empty semantic input; no agent was started and no workflow source was written.`, target, scriptIdentity, ...state(), }; } // --- 3. workspace identity + admission, then 4. launch binding ----------- try { if (opts.recoverInterrupted !== undefined && typeof opts.recoverInterrupted !== "boolean") throw new Error("recoverInterrupted must be boolean"); if (opts.recoverInterrupted === true && resumeFromRunId === undefined) throw new Error("recoverInterrupted requires resumeFromRunId"); if (opts.operatorHandoffClaim !== undefined) { const sourceRunId = opts.operatorHandoffClaim.sourceRunId; const sourceBinding = readWorkflowLaunchBinding(projectRoot, sourceRunId); if (sourceBinding === null) throw new Error(workflowExecutionMigrationMessage(sourceRunId)); if (!workflowLaunchBindingMatchesResult(sourceBinding, readWorkflowRunResult(projectRoot, sourceRunId))) { throw new Error(`Cannot continue workflow: source run ${sourceRunId} has no valid host launch binding.`); } } if (opts.operatorHandoffWorkspaceReuse !== undefined) { if (opts.operatorHandoffClaim === undefined || opts.continuation === undefined) { throw new Error("Workflow handoff workspace reuse requires a validated claim and continuation"); } assertWorkflowHandoffClaimEligibility(opts.operatorHandoffClaim, { target, scriptIdentity }); handoffReuseWorkspace = assertWorkflowHandoffWorkspaceReuse( projectRoot, opts.operatorHandoffWorkspaceReuse, opts.operatorHandoffClaim, opts.continuation, target, ); } if (resumeFromRunId !== undefined) { let sourceResult = readWorkflowRunResult(projectRoot, resumeFromRunId); if (opts.recoverInterrupted === true) { sourceResult = readInterruptedWorkflowResumeBinding(projectRoot, resumeFromRunId, { target: { kind: target.kind, ref: target.ref, source: target.source }, scriptSha256: scriptIdentity.scriptSha256, recoveryInputSha256: workflowRecoveryInputHash({ ...(opts.input === undefined ? {} : { input: opts.input }), ...(typedInput === undefined ? {} : { typedInput }), items, budget, ...(noOperator === undefined ? {} : { noOperator }), }), }); interruptedRecovery = true; } if (sourceResult?.workspaceDirUnavailable !== undefined) { throw new Error( `Cannot resume workflow: source run ${resumeFromRunId} workspace identity is unavailable: ${sourceResult.workspaceDirUnavailable}.`, ); } if (sourceResult?.scriptIdentity?.executionSource === "snapshot") { try { verifyWorkflowPersistedSnapshot(projectRoot, resumeFromRunId, sourceResult.scriptIdentity); } catch (error) { throw new Error( `Cannot resume workflow: source run ${resumeFromRunId} has unusable retained snapshot: ${ error instanceof Error ? error.message : String(error) }.`, ); } } const currentOwner = isPostCodeReviewTarget(target, projectRoot); const sourceLaunchBinding = readWorkflowLaunchBinding(projectRoot, resumeFromRunId); if (sourceLaunchBinding === null) throw new Error(workflowExecutionMigrationMessage(resumeFromRunId)); if ( typedInput !== undefined && (sourceLaunchBinding.scriptIdentity.scriptSha256 !== scriptIdentity.scriptSha256 || sourceLaunchBinding.recoveryInputSha256 !== workflowRecoveryInputHash({ typedInput, items, budget, ...(noOperator === undefined ? {} : { noOperator }), })) ) throw new Error("Cannot resume workflow: typed input source, items or resolved launch inputs changed."); if ( (typedInput === undefined) !== (sourceLaunchBinding.typedInput === undefined) || (typedInput !== undefined && canonicalWorkflowJSON(workflowTypedInputProjection(typedInput)) !== canonicalWorkflowJSON(workflowTypedInputProjection(sourceLaunchBinding.typedInput!))) ) throw new Error("Cannot resume workflow: typed input or operator context differs from the source run."); if (sourceResult === null || !workflowLaunchBindingMatchesResult(sourceLaunchBinding, sourceResult)) { throw new Error(`Cannot resume workflow: source run ${resumeFromRunId} has no valid host launch binding.`); } sourceResult = projectWorkflowLaunchBindingOntoResult(sourceResult, sourceLaunchBinding); if (sourceResult?.runIdInvalid !== undefined || sourceResult?.runUnbound !== undefined) { throw new Error( `Cannot resume workflow: source run ${resumeFromRunId} is not bound to its persisted result envelope.`, ); } if (sourceResult?.scriptIdentityInvalid !== undefined) { throw new Error( `Cannot resume workflow: source run ${resumeFromRunId} has malformed script identity: ${sourceResult.scriptIdentityInvalid}.`, ); } const sourceOwner = isPostCodeReviewTargetProjection(sourceLaunchBinding.target, { projectRoot, resolvedPath: sourceLaunchBinding.scriptIdentity.sourcePath, }); if (sourceOwner !== currentOwner) { throw new Error( `Cannot resume workflow: source/current post-code-review ownership differs ` + `(source=${sourceOwner}, current=${currentOwner}).`, ); } if ( (sourceOwner || currentOwner || typedInput !== undefined) && persistedTargetIdentityKey( sourceLaunchBinding.target, projectRoot, sourceLaunchBinding.scriptIdentity.sourcePath, ) !== targetIdentityKey(target, projectRoot) ) { throw new Error( `Cannot resume post-code-review workflow: persisted source target does not match current target ` + `${JSON.stringify({ kind: target.kind, ref: target.ref, source: target.source })}.`, ); } resumeSourceBinding = { result: sourceResult, owner: sourceOwner, workspace: readWorkflowResumeWorkspaceIdentityFromResult(projectRoot, sourceResult, resumeFromRunId), launchBinding: sourceLaunchBinding, }; resumeSourceWorkspace = resumeSourceBinding.workspace; } if ( resumeSourceWorkspace?.explicit === true && selectedWorkspaceDir === undefined && !(target.kind === "name" && isTaskWorkspaceName(target.ref)) ) { throw new Error( "Cannot resume workflow: the source workspace was selected explicitly; repeat it with workspaceDir.", ); } const resumeSourceTargetMatches = resumeSourceBinding?.result.target !== undefined && persistedTargetIdentityKey( resumeSourceBinding.result.target, projectRoot, resumeSourceBinding.result.scriptIdentity?.sourcePath, ) === targetIdentityKey(target, projectRoot); if (opts.runName !== undefined && resumeSourceWorkspace !== undefined) { const expectedCurrent = [WORKFLOW_ROOT_DIRNAME, WORKFLOW_WORKSPACES_DIRNAME, opts.runName].join("/"); const expectedLegacy = [WORKFLOW_ROOT_DIRNAME, WORKFLOW_PLANS_DIRNAME, opts.runName].join("/"); if ( resumeSourceWorkspace.relativePath !== expectedCurrent && resumeSourceWorkspace.relativePath !== expectedLegacy ) { throw new Error( `Cannot resume workflow: runName ${JSON.stringify(opts.runName)} does not match the source workspace ` + `${JSON.stringify(resumeSourceWorkspace.relativePath)}.`, ); } } const resumeReuseWorkspace = resumeSourceWorkspace !== undefined && selectedWorkspaceDir === undefined && resumeSourceTargetMatches ? resolveWorkflowWorkspaceDirectoryForReuse(projectRoot, resumeSourceWorkspace, { create: false }) : undefined; if ( opts.runName !== undefined && resumeSourceWorkspace === undefined && handoffReuseWorkspace === undefined && inheritedCoordination === undefined ) { selectedWorkspaceDir = resolveNamedWorkflowWorkspacePath(projectRoot, opts.runName); } const reusedWorkspace = handoffReuseWorkspace ?? resumeReuseWorkspace ?? inheritedCoordination?.workspace; const candidateWorkspacePath = reusedWorkspace ?? resolveWorkflowWorkspaceDirectoryPath( projectRoot, selectedWorkspaceDir, workflowDefaultWorkspaceName(target), workingDirectory, { runId }, ); const reusesLegacyWorkspace = isLegacyWorkflowWorkspacePath(candidateWorkspacePath.relativePath); if ( resumeSourceWorkspace !== undefined && candidateWorkspacePath.relativePath !== resumeSourceWorkspace.relativePath ) { throw new Error( `Cannot resume workflow: workspaceDir must equal the source workspace ` + `${JSON.stringify(resumeSourceWorkspace.relativePath)} ` + `(got ${JSON.stringify(candidateWorkspacePath.relativePath)}).`, ); } const freshOwnerLaunch = inheritedCoordination === undefined && !hasResume && handoffReuseWorkspace === undefined && isPostCodeReviewTarget(target, projectRoot); if (freshOwnerLaunch) { assertFreshWorkflowWorkspaceNamespacePath({ projectRoot, workspace: candidateWorkspacePath }); } const resolvedWorkspace = reusedWorkspace ?? resolveWorkflowWorkspaceDirectory( projectRoot, selectedWorkspaceDir, workflowDefaultWorkspaceName(target), workingDirectory, { create: !hasResume && !reusesLegacyWorkspace, runId, }, ); if (freshOwnerLaunch) { assertFreshWorkflowWorkspaceNamespace({ projectRoot, workspace: resolvedWorkspace }); } if ( inheritedCoordination !== undefined && (resolvedWorkspace.identity !== inheritedCoordination.workspace.identity || resolvedWorkspace.physicalPath !== inheritedCoordination.workspace.physicalPath) ) { throw new Error( `saved child workspaceDir must equal the root workspaceDir ${JSON.stringify(inheritedCoordination.workspace.relativePath)}`, ); } if (resumeFromRunId !== undefined) { if (resumeSourceBinding === undefined) { throw new Error(`Cannot resume workflow: source run ${resumeFromRunId} has no validated binding.`); } if (resumeSourceBinding.owner || interruptedRecovery) { const sourceInput = resumeSourceBinding.launchBinding.semanticInput; if ( sourceInput.present !== requestedSemanticInput.present || sourceInput.sha256 !== requestedSemanticInput.sha256 ) { throw new Error("Cannot resume post-code-review: semantic input differs from the source run."); } } } if ( resumeSourceWorkspace !== undefined && (resumeSourceWorkspace.relativePath !== resolvedWorkspace.relativePath || resumeSourceWorkspace.physicalPath !== resolvedWorkspace.physicalPath || resumeSourceWorkspace.physicalIdentity !== resolvedWorkspace.identity) ) { throw new Error( `Cannot resume workflow: workspaceDir must equal the source workspace ` + `${JSON.stringify(resumeSourceWorkspace.relativePath)} ` + `(got ${JSON.stringify(resolvedWorkspace.relativePath)}).`, ); } stableWorkspace = inheritedCoordination?.workspace ?? resolvedWorkspace; // Persist the independent owner binding before acquiring the lease or // starting any child work. The result envelope written at terminal time is // only a projection and cannot be the source of resume/handoff authority. let rootLineageId = inheritedCoordination?.checkpointLineageId; if (inheritedCoordination === undefined) { const lineageRunId = resumeFromRunId ?? (handoffReuseWorkspace && opts.operatorHandoffWorkspaceReuse?.sourceRunId); rootLineageId = readWorkflowRootLineageId(projectRoot, runId, lineageRunId, resumeSourceBinding?.launchBinding); const launchBinding = createWorkflowLaunchBinding({ runId, rootLineageId, recoveryInputSha256: workflowRecoveryInputHash({ ...(opts.input === undefined ? {} : { input: opts.input }), ...(typedInput === undefined ? {} : { typedInput }), items, budget, ...(noOperator === undefined ? {} : { noOperator }), }), target: { kind: target.kind, ref: target.ref, source: target.source }, scriptIdentity, workspace: stableWorkspace, workspaceExplicit: handoffReuseWorkspace === undefined ? resumeSourceWorkspace?.explicit === true || opts.workspaceDir !== undefined : opts.operatorHandoffWorkspaceReuse?.explicit === true, semanticInput: requestedSemanticInput, ...(typedInput === undefined ? {} : { typedInput }), }); try { writeWorkflowLaunchBinding(runDir, launchBinding); } catch (error) { return { admitted: false, error: `Workflow launch binding was not persisted: ${error instanceof Error ? error.message : String(error)}`, target, scriptIdentity, ...state(), }; } } if (rootLineageId === undefined) throw new Error("Workflow checkpoint lineage was not established."); const coordinationDirectory = { workspace: stableWorkspace, checkpointLineageId: rootLineageId }; return { admitted: true, target, scriptIdentity, ...state(), stableWorkspace, coordinationDirectory }; } catch (err) { return { admitted: false, error: err instanceof Error ? err.message : String(err), target, scriptIdentity, ...state(), }; } }