From 2a37ee4e594fa670bc0507bc892dcb326bd785c3 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 13 Jun 2026 04:06:17 -0700 Subject: [PATCH] FN-6341: settle cli-agent re-entry test promise Stabilize the cli-agent re-entry regression test by awaiting the original run after the replacement session succeeds. - Keep the first cli-agent run promise instead of dropping it with void. - Assert the active task session still points at the first PTY before simulating re-entry. - Kill and await the first session at the end so no hub or store work outlives teardown. Files changed: packages/engine/src/__tests__/cli-agent-executor.test.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-6341 Fusion-Task-Lineage: 3e365f21-0d05-496a-adec-aa782aa83503 --- .../engine/src/__tests__/cli-agent-executor.test.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/engine/src/__tests__/cli-agent-executor.test.ts b/packages/engine/src/__tests__/cli-agent-executor.test.ts index d3f9609a0d..03954e2386 100644 --- a/packages/engine/src/__tests__/cli-agent-executor.test.ts +++ b/packages/engine/src/__tests__/cli-agent-executor.test.ts @@ -287,7 +287,7 @@ describe("cli-agent executor seam (U7)", () => { it("re-entry: a fresh run kills the prior live session and spawns a new PTY", async () => { const { executor } = makeExecutor(taskDetail()); // First run, left live (no done). - void (executor as any).runGraphCustomNode(cliNode, taskDetail(), {}); + const firstP = (executor as any).runGraphCustomNode(cliNode, taskDetail(), {}); await vi.waitFor(() => expect(state.ptys).toHaveLength(1)); lastPty().emitData("READY\r\n"); const firstId = await vi.waitFor(() => { @@ -299,6 +299,8 @@ describe("cli-agent executor seam (U7)", () => { // Let the first run's async injection settle (it drives the machine to busy // and would otherwise overwrite the killed reason mid-race). await vi.waitFor(() => expect(hub.getStateMachine(firstId)?.getState()).toBe("busy")); + const firstSession = (executor as any).activeCliTaskSessions.get("FN-100"); + expect(firstSession?.sessionId).toBe(firstId); // Drop the first run's active handle to simulate a graph re-entry without abort. (executor as any).activeCliTaskSessions.delete("FN-100"); @@ -314,6 +316,12 @@ describe("cli-agent executor seam (U7)", () => { hub.ingest(second.id, { kind: "done" }); const result = await secondP; expect(result.outcome).toBe("success"); + + // FN-6341: the original flake left this first run as a dropped `void` promise; + // settle the task-session after proving re-entry killed its PTY so no hub/store + // work can outlive afterEach's db.close(). + await firstSession.kill("killed"); + await expect(firstP).resolves.toMatchObject({ outcome: "failure", value: "cli-agent-killed" }); }); // ── Ceiling produces a typed surfaced value, not a hang ──────────────────────