feat(FN-3324): add runtime guard regression sentinel

Adds a regression test sentinel in the engine's in-process runtime test suite to guard against runtime guard behavior regressions (FN-3324).

Fusion-Task-Id: FN-3324
This commit is contained in:
Fusion
2026-05-04 15:27:41 -07:00
committed by gsxdsm
parent 452c31a085
commit c48feb2f79
9 changed files with 253 additions and 24 deletions

View File

@@ -627,6 +627,24 @@ describe("InProcessRuntime", () => {
expect(assignTaskSpy.mock.invocationCallOrder[0]).toBeLessThan(updateStateSpy.mock.invocationCallOrder[0]);
}, 30000);
it("does not create duplicate task-worker agents when onStart fires twice for one task", async () => {
await runtime.start();
const store = getAgentStore(runtime);
const executorOptions = mockExecutorCtor.mock.calls.at(-1)?.[0] as {
onStart?: (task: Task, worktreePath: string) => void;
};
executorOptions.onStart?.({ id: "FN-DUP-ONSTART" } as Task, join(testDir, "worktree-FN-DUP-ONSTART"));
executorOptions.onStart?.({ id: "FN-DUP-ONSTART" } as Task, join(testDir, "worktree-FN-DUP-ONSTART"));
await vi.waitFor(async () => {
const agents = await store.listAgents({ includeEphemeral: true });
const matching = agents.filter((agent: Agent) => agent.name === "executor-FN-DUP-ONSTART");
expect(matching).toHaveLength(1);
});
}, 30000);
it("does not wake executeHeartbeat for runtime task-worker assignment events", async () => {
await runtime.start();

View File

@@ -377,6 +377,12 @@ export class InProcessRuntime
// These workers are not heartbeat-managed dashboard agents, so mark them
// explicitly and disable heartbeat triggers/timers.
if (this.agentStore) {
if (this.taskAgentMap.has(task.id)) {
runtimeLog.warn(`Skipping task-worker creation for ${task.id}: agent already exists (${this.taskAgentMap.get(task.id)})`);
return;
}
this.taskAgentMap.set(task.id, "creating");
this.agentStore.createAgent({
name: `executor-${task.id}`,
role: "executor",
@@ -394,6 +400,7 @@ export class InProcessRuntime
await this.agentStore!.updateAgentState(agent.id, "active");
await this.agentStore!.updateAgentState(agent.id, "running");
}).catch((err: unknown) => {
this.taskAgentMap.delete(task.id);
runtimeLog.warn(`Failed to create agent for task ${task.id}:`, err);
});
}