fix(engine): resume execution after review revise
This commit is contained in:
@@ -193,7 +193,7 @@ describe("Workflow Steps Execution", () => {
|
||||
});
|
||||
|
||||
describe("FN-5436: pending-review skip on no-fn_task_done exit", () => {
|
||||
it("parks in-review immediately when code review REVISE is pending", async () => {
|
||||
it("does not park in-review when code review REVISE requires more executor work", async () => {
|
||||
const store = createMockStore();
|
||||
const baseTask = {
|
||||
id: "FN-5436-A",
|
||||
@@ -240,22 +240,20 @@ describe("Workflow Steps Execution", () => {
|
||||
|
||||
await executor.execute(baseTask as any);
|
||||
|
||||
expect(mockedCreateFnAgent).toHaveBeenCalledTimes(1);
|
||||
expect(mockedCreateFnAgent).toHaveBeenCalledTimes(4);
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-5436-A", expect.objectContaining({
|
||||
status: "failed",
|
||||
error: "Agent finished without calling fn_task_done (after 3 retries)",
|
||||
}));
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-5436-A", "todo", { preserveProgress: true });
|
||||
expect(store.moveTask).not.toHaveBeenCalledWith("FN-5436-A", "in-review");
|
||||
expect(store.updateTask).not.toHaveBeenCalledWith("FN-5436-A", {
|
||||
status: "failed",
|
||||
error: "executor-exit-while-review-pending",
|
||||
});
|
||||
expect(store.updateTask).not.toHaveBeenCalledWith("FN-5436-A", expect.objectContaining({ taskDoneRetryCount: expect.anything() }));
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-5436-A", "in-review");
|
||||
expect(store.logEntry).toHaveBeenCalledWith(
|
||||
"FN-5436-A",
|
||||
expect.stringContaining("blocked on pending review (code-review-revise-outstanding)"),
|
||||
undefined,
|
||||
expect.objectContaining({ agentId: "executor" }),
|
||||
);
|
||||
expect(onError).not.toHaveBeenCalledWith(
|
||||
expect(onError).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ id: "FN-5436-A" }),
|
||||
expect.objectContaining({ message: "executor-exit-while-review-pending" }),
|
||||
expect.objectContaining({ message: "Agent finished without calling fn_task_done (after 3 retries)" }),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -710,6 +710,31 @@ describe("ProjectEngine merge error recovery", () => {
|
||||
expect(store.moveTask).toHaveBeenCalledWith(TASK_ID, "done");
|
||||
});
|
||||
|
||||
it("auto-finalizes merge-confirmed tasks with stale transient merging status", async () => {
|
||||
const store = makeStore({
|
||||
tasks: [
|
||||
makeTask({
|
||||
mergeDetails: { mergeConfirmed: true },
|
||||
status: "merging",
|
||||
error: "stale transient merge state",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const engine = createEngine(store);
|
||||
await runMergeCycle(engine);
|
||||
|
||||
expect(store.updateTask).toHaveBeenCalledWith(TASK_ID, { paused: false, status: null, error: null });
|
||||
expect(store.moveTask).toHaveBeenCalledWith(TASK_ID, "done");
|
||||
expect(store.updateTask).not.toHaveBeenCalledWith(
|
||||
TASK_ID,
|
||||
expect.objectContaining({
|
||||
status: "failed",
|
||||
error: expect.stringContaining("finalization blocked"),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("does not park merge-confirmed tasks as failed when finalize loses in-review ownership", async () => {
|
||||
const store = makeStore({
|
||||
tasks: [
|
||||
|
||||
@@ -4002,6 +4002,42 @@ describe("SelfHealingManager", () => {
|
||||
|
||||
managerWithRecovery.stop();
|
||||
});
|
||||
|
||||
it("auto-finalizes merge-confirmed tasks with stale transient merging status", async () => {
|
||||
const managerWithRecovery = new SelfHealingManager(store, {
|
||||
rootDir: "/tmp/test-project",
|
||||
});
|
||||
|
||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
||||
{
|
||||
id: "FN-354",
|
||||
column: "in-review",
|
||||
paused: false,
|
||||
status: "merging",
|
||||
error: "stale transient merge state",
|
||||
mergeDetails: {
|
||||
mergeConfirmed: true,
|
||||
mergedAt: "2026-01-01T00:00:00.000Z",
|
||||
},
|
||||
steps: [{ status: "done" }],
|
||||
workflowStepResults: [],
|
||||
log: [],
|
||||
},
|
||||
]);
|
||||
|
||||
const result = await managerWithRecovery.recoverMergedReviewTasks();
|
||||
|
||||
expect(result).toBe(1);
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-354", {
|
||||
paused: false,
|
||||
status: null,
|
||||
error: null,
|
||||
mergeRetries: 0,
|
||||
});
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-354", "done");
|
||||
|
||||
managerWithRecovery.stop();
|
||||
});
|
||||
});
|
||||
|
||||
describe("recoverStuckMergeDeadlocks", () => {
|
||||
|
||||
Reference in New Issue
Block a user