fix(FN-6035): fail execute on missing prepared worktree

This commit is contained in:
gsxdsm
2026-06-08 22:05:45 -07:00
parent 8d3b869ec1
commit fc8086c480
2 changed files with 33 additions and 3 deletions

View File

@@ -29,7 +29,9 @@ function selectedIr(): WorkflowIr {
function recordingPrimitives(
calls: string[],
overrides: Partial<Record<"prepare" | "execute" | "workflowStep", WorkflowNodeResult>> = {},
overrides: Partial<Record<"prepare" | "execute" | "workflowStep", WorkflowNodeResult>> & {
prepareData?: PreparedWorktree | null;
} = {},
observed: { prepared?: PreparedWorktree } = {},
): WorkflowRuntimePrimitives {
const prepared: PreparedWorktree = { worktreePath: "/tmp/fusion-worktree" };
@@ -40,7 +42,11 @@ function recordingPrimitives(
outcome: overrides.prepare?.outcome ?? "success",
value: overrides.prepare?.value,
contextPatch: overrides.prepare?.contextPatch,
data: overrides.prepare?.outcome === "failure" ? undefined : prepared,
data: overrides.prepare?.outcome === "failure"
? undefined
: overrides.prepareData === null
? undefined
: overrides.prepareData ?? prepared,
};
},
readArtifact: async () => undefined,
@@ -145,6 +151,30 @@ describe("WorkflowTaskRuntime", () => {
expect(workflowSelectionReads).toBe(1);
});
it("fails execute instead of skipping coding when prepare succeeds without worktree data", async () => {
const calls: string[] = [];
const runtime = new WorkflowTaskRuntime({
store: {
getTaskWorkflowSelection: () => ({ workflowId: "WF-001", stepIds: [] }),
getWorkflowDefinition: async () => ({ ir: selectedIr() }),
},
primitives: recordingPrimitives(calls, {
prepare: { outcome: "success", value: "prepared-without-data" },
prepareData: null,
}),
runCustomNode: async (node) => {
calls.push(`custom:${node.id}`);
return { outcome: "success" };
},
});
const result = await runtime.run(task, flagOff);
expect(result.disposition).toBe("failed");
expect(calls).toEqual(["custom:prepare", "prepare-worktree"]);
expect(result.visitedNodeIds).toEqual(["start", "prepare", "execute"]);
});
it("resolves an unselected task to the built-in coding workflow instead of falling back", async () => {
const calls: string[] = [];
const runtime = new WorkflowTaskRuntime({

View File

@@ -319,7 +319,7 @@ export function createPrimitivePromptLikeHandler(
const prepared = await primitives.prepareWorktree(primitiveCtx, context.task);
if (prepared.outcome !== "success" || !prepared.data) {
return {
outcome: prepared.outcome,
outcome: prepared.outcome === "success" ? "failure" : prepared.outcome,
value: prepared.value ?? "prepare-worktree-failed",
contextPatch: prepared.contextPatch,
};