Files
fusion/packages/engine/src/__tests__/executor-implicit-task-done-revise-guard.test.ts
gsxdsm eb113f3e33 FN-6068: fix engine executor test expectations for queued retries
Align engine executor tests with the current retry and worktree behavior.

- update implicit task-done refusal expectations to assert queued retry state resets
- update pause recovery coverage to expect requeued tasks instead of stuck-killed status
- stub the sandbox backend in worktree init tests and drop obsolete execSync assertions

Files changed:
 .../executor-implicit-task-done-budget.test.ts     | 11 ++++++-
 ...xecutor-implicit-task-done-revise-guard.test.ts | 11 ++++++-
 .../engine/src/__tests__/executor-pause.test.ts    |  5 +--
 .../engine/src/__tests__/executor-worktree.test.ts | 37 ++++++++++++++++------
 4 files changed, 50 insertions(+), 14 deletions(-)

Fusion-Task-Id: FN-6068

Fusion-Task-Lineage: b8ccabaa-7e5d-42dc-b522-6f4738b28db4
2026-06-09 02:27:43 -07:00

102 lines
3.9 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
import "./executor-test-helpers.js";
import { TaskExecutor, evaluateTaskDoneRefusal } from "../executor.js";
import { executorLog } from "../logger.js";
import { createMockStore, mockedExecSync, resetExecutorMocks } from "./executor-test-helpers.js";
function makeTask(overrides: Record<string, unknown> = {}) {
return {
id: "FN-4946-R",
title: "Implicit revise guard",
description: "",
column: "in-progress",
worktree: "/repo/.worktrees/swift-falcon",
branch: "fusion/fn-4946-r",
baseCommitSha: "abc123",
taskDoneRetryCount: 0,
dependencies: [],
steps: [{ name: "Step 1", status: "in-progress" as const }],
currentStep: 0,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
...overrides,
};
}
function refusal() {
return {
ok: false as const,
refusalClass: "pending-code-review-revise" as const,
reason: "Step 1 has pending REVISE",
message: "fn_task_done refused (pending-code-review-revise): Step 1 has pending REVISE",
};
}
describe("FN-4946 implicit completion + REVISE verdict interaction", () => {
beforeEach(() => {
resetExecutorMocks();
mockedExecSync.mockImplementation((cmd: string) => {
if (cmd.includes("rev-parse --show-toplevel")) return Buffer.from("/repo/.worktrees/swift-falcon\n");
if (cmd.includes("rev-parse --abbrev-ref HEAD")) return Buffer.from("fusion/fn-4946-r\n");
if (cmd.includes("rev-list --count")) return Buffer.from("1\n");
if (cmd.includes("rev-parse HEAD")) return Buffer.from("def456\n");
return Buffer.from("");
});
});
it("requeues with implicit-completion refusal shape and retry count", async () => {
const store = createMockStore();
const executor = new TaskExecutor(store as any, "/repo");
await (executor as any).handleImplicitTaskDoneRefusal(makeTask({ id: "FN-4946-R1" }), refusal());
expect(store.updateTask).toHaveBeenCalledWith("FN-4946-R1", expect.objectContaining({
status: "queued",
error: null,
taskDoneRetryCount: 1,
worktree: null,
branch: null,
paused: false,
pausedByAgentId: null,
sessionFile: null,
}));
expect(store.moveTask).toHaveBeenCalledWith("FN-4946-R1", "todo", { preserveProgress: true });
const refusalLogCall = store.logEntry.mock.calls.find(
([id, message]: [string, string]) => id === "FN-4946-R1" && message.includes("pending-code-review-revise"),
);
expect(refusalLogCall).toBeTruthy();
expect(executorLog.error).toHaveBeenCalledWith(expect.stringContaining("(implicit completion)"));
});
it("evaluateTaskDoneRefusal returns ok when REVISE exists only on already-done steps", () => {
const result = evaluateTaskDoneRefusal(
makeTask({ steps: [{ name: "Step 1", status: "done" }] }) as any,
{},
new Map([[0, "REVISE"]]),
);
expect(result.ok).toBe(true);
});
it("handles implicit refusal once without falling into no-fn_task_done exhaustion handling", async () => {
const store = createMockStore();
const executor = new TaskExecutor(store as any, "/repo");
await (executor as any).handleImplicitTaskDoneRefusal(makeTask({ id: "FN-4946-R2" }), refusal());
const retryCountUpdates = store.updateTask.mock.calls.filter(
([id, patch]: [string, Record<string, unknown>]) => id === "FN-4946-R2" && "taskDoneRetryCount" in patch,
);
expect(retryCountUpdates).toHaveLength(1);
expect(retryCountUpdates[0]?.[1]).toEqual(expect.objectContaining({ taskDoneRetryCount: 1 }));
const noFnTaskDoneEscalations = store.updateTask.mock.calls.filter(
([id, patch]: [string, Record<string, unknown>]) =>
id === "FN-4946-R2"
&& typeof patch.error === "string"
&& patch.error.includes("Agent finished without calling fn_task_done"),
);
expect(noFnTaskDoneEscalations).toHaveLength(0);
});
});