FN-6326: quarantine deferred-hook title summarization test

Quarantine the flaky deferred-hook title summarization coverage while preserving focused store-create coverage.

- Extract the deferred task-created hook summarization test into its own file.
- Exclude the extracted test file from the core Vitest suite.
- Record the flake investigation and quarantine rationale in the test quarantine ledger.

Files changed:
 .../store-create-summarize-deferred-hook.test.ts   | 67 ++++++++++++++++++++++
 packages/core/src/__tests__/store-create.test.ts   | 44 --------------
 packages/core/vitest.config.ts                     |  1 +
 scripts/lib/test-quarantine.json                   |  5 ++
 4 files changed, 73 insertions(+), 44 deletions(-)

Fusion-Task-Id: FN-6326

Fusion-Task-Lineage: a37189b3-b88b-483f-b2bf-471fde806b35
This commit is contained in:
gsxdsm
2026-06-12 23:57:43 -07:00
parent 9377d20420
commit 3c751f2853
4 changed files with 73 additions and 44 deletions

View File

@@ -0,0 +1,67 @@
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { setCreateFnAgent } from "../ai-engine-loader.js";
import { TaskStore } from "../store.js";
import { setTaskCreatedHook } from "../task-creation-hooks.js";
import { createTaskStoreTestHarness } from "./store-test-helpers.js";
describe("TaskStore createTask title summarization deferred hook", () => {
const harness = createTaskStoreTestHarness();
let store: TaskStore;
beforeEach(async () => {
await harness.beforeEach();
store = harness.store();
});
afterEach(async () => {
setTaskCreatedHook(undefined);
setCreateFnAgent(undefined);
await harness.afterEach();
});
it("defers the task-created hook until store-managed summarize completes", async () => {
const longDescription = "a".repeat(201);
let releasePrompt!: () => void;
const promptStarted = vi.fn();
const promptDone = new Promise<void>((resolve) => {
releasePrompt = resolve;
});
setCreateFnAgent(vi.fn(async () => ({
session: {
prompt: vi.fn(async () => {
promptStarted();
await promptDone;
}),
state: { messages: [{ role: "assistant", content: "Deferred Hook Title" }] },
},
})));
const hookSpy = vi.fn();
setTaskCreatedHook(hookSpy);
const task = await store.createTask(
{ description: longDescription, summarize: true },
{
settings: {
autoSummarizeTitles: false,
titleSummarizerProvider: "mock",
titleSummarizerModelId: "title-model",
},
},
);
await vi.waitFor(() => expect(promptStarted).toHaveBeenCalled());
expect(hookSpy).not.toHaveBeenCalled();
releasePrompt();
await vi.waitFor(() => {
expect(hookSpy).toHaveBeenCalledWith(
expect.objectContaining({
id: task.id,
title: "Deferred Hook Title",
}),
store,
);
});
});
});

View File

@@ -501,50 +501,6 @@ describe("TaskStore", () => {
expect(promptSpy).toHaveBeenCalledWith(expect.stringContaining(longDescription));
});
it("defers the task-created hook until store-managed summarize completes", async () => {
const longDescription = "a".repeat(201);
let releasePrompt!: () => void;
const promptStarted = vi.fn();
const promptDone = new Promise<void>((resolve) => {
releasePrompt = resolve;
});
setCreateFnAgent(vi.fn(async () => ({
session: {
prompt: vi.fn(async () => {
promptStarted();
await promptDone;
}),
state: { messages: [{ role: "assistant", content: "Deferred Hook Title" }] },
},
})));
const hookSpy = vi.fn();
setTaskCreatedHook(hookSpy);
const task = await store.createTask(
{ description: longDescription, summarize: true },
{
settings: {
autoSummarizeTitles: false,
titleSummarizerProvider: "mock",
titleSummarizerModelId: "title-model",
},
},
);
await vi.waitFor(() => expect(promptStarted).toHaveBeenCalled());
expect(hookSpy).not.toHaveBeenCalled();
releasePrompt();
await vi.waitFor(() => {
expect(hookSpy).toHaveBeenCalledWith(
expect.objectContaining({
id: task.id,
title: "Deferred Hook Title",
}),
store,
);
});
});
it("should ignore malformed confirmation-prose generated titles", async () => {
const mockOnSummarize = vi

View File

@@ -18,6 +18,7 @@ export default defineConfig({
"src/__tests__/db.test.ts",
"src/__tests__/soft-delete-tasks.test.ts",
"src/__tests__/store-get-task-columns.test.ts",
"src/__tests__/store-create-summarize-deferred-hook.test.ts",
"src/__tests__/task-dependency-mutation.test.ts",
"src/__tests__/task-node-override.test.ts",
],

View File

@@ -55,6 +55,11 @@
"file": "packages/core/src/__tests__/db.test.ts",
"reason": "Flake observed during FN-6299 verification: broad `pnpm --filter @fusion/core test` timed out in `Database.recoverIfCorrupt startup guard > rebuilds a malformed database and preserves the corrupt original` after 15s; earlier `pnpm test` attempt SIGTERM'd the core package and leaked a fusion-test-workers temp dir. Follow-up FN-6334.",
"quarantinedAt": "2026-06-12"
},
{
"file": "packages/core/src/__tests__/store-create-summarize-deferred-hook.test.ts",
"reason": "Flake observed during FN-6320 final broad `pnpm test`: `store-create.test.ts > TaskStore > createTask with title summarization > defers the task-created hook until store-managed summarize completes` timed out because the registered task-created hook had zero calls after the gated store-managed summarizer prompt was released. FN-6326 cross-check: the test passed twice standalone after FN-6313, and product code in `TaskStore.createTask` suppresses the synchronous hook only while `hasPendingSummarization` is true, then unconditionally refreshes the task and calls `invokeTaskCreatedHook(latestTask)` after `onSummarize` settles across success/null/throw branches. The broad/package load failure was therefore classified as suite-load/harness sensitivity rather than a confirmed product defect; the single flaky `it` was extracted so the rest of `store-create.test.ts` remains covered.",
"quarantinedAt": "2026-06-12"
}
]
}