test(FN-4429): complete Step 3 — userPaused scheduler dispatch guard

Fusion-Task-Id: FN-4429
Fusion-Task-Lineage: b010437b-0e58-43f6-81b3-40dcebbf0873
This commit is contained in:
Fusion
2026-05-14 09:40:23 -07:00
committed by gsxdsm
parent 1fdda7db32
commit 00bb1a508a
2 changed files with 57 additions and 0 deletions

View File

@@ -2673,6 +2673,55 @@ describe("Scheduler", () => {
});
});
describe("userPaused dispatch behavior", () => {
it("skips dispatch for todo task marked userPaused and re-enables after clearing", async () => {
const pausedTask = createMockTask({
id: "FN-UP-1",
column: "todo",
dependencies: [],
userPaused: true,
});
const activeTask = createMockTask({
id: "FN-UP-1",
column: "todo",
dependencies: [],
});
const listTasks = vi
.fn()
.mockResolvedValueOnce([pausedTask])
.mockResolvedValueOnce([activeTask]);
const getTask = vi
.fn()
.mockResolvedValueOnce(pausedTask)
.mockResolvedValueOnce(activeTask);
const updateTask = vi.fn().mockResolvedValue(undefined);
const moveTask = vi.fn().mockResolvedValue(undefined);
const store = createMockStore({
listTasks,
getTask,
updateTask,
moveTask,
getSettings: vi.fn().mockResolvedValue({ maxConcurrent: 1, groupOverlappingFiles: true }),
parseFileScopeFromPrompt: vi.fn().mockResolvedValue([]),
});
const scheduler = new Scheduler(store);
(scheduler as any).running = true;
await scheduler.schedule();
expect(moveTask).not.toHaveBeenCalled();
expect(updateTask).toHaveBeenCalledWith("FN-UP-1", { status: "queued" });
expect(store.logEntry).toHaveBeenCalledWith("FN-UP-1", "queued — user paused (manual move to todo)");
await scheduler.schedule();
expect(moveTask).toHaveBeenCalledWith(
"FN-UP-1",
"in-progress",
expect.objectContaining({ allocateWorktree: expect.any(Function) }),
);
});
});
describe("autopilot integration", () => {
it("watches missions with autopilotEnabled on start", () => {
const store = createMockStore();

View File

@@ -822,6 +822,14 @@ export class Scheduler {
continue;
}
if (task.userPaused === true) {
if (task.status !== "queued") {
await this.store.updateTask(task.id, { status: "queued" });
}
await this.logDispatchQueuedReason(task.id, "queued — user paused (manual move to todo)");
continue;
}
// Validate filesystem state before starting (only for tasks with satisfied deps)
const validation = await this.validateTaskFilesystem(task.id);
if (!validation.valid) {