From 40687cb0be4359e20cdb39d213c7f852d7114e28 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 16 Jul 2026 07:48:12 -0700 Subject: [PATCH] FN-8050: cover cached dependency reconciliation seeding Ensure raw dependency-reconciliation fixtures invalidate warmed task caches. - Warm slim task-list caches before corrupt-row seeding in cycle reconciliation tests. - Document the PostgreSQL-only fixture seam and cache invalidation rationale. Files changed: .../engine/src/__tests__/reliability-interactions/_helpers.ts | 11 ++++++----- .../dependency-cycle-reconcile.test.ts | 7 +++++++ 2 files changed, 13 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-8050 Fusion-Task-Lineage: 5e708d58-faed-4271-a075-24c36eaa5878 Co-authored-by: Fusion (runfusion.ai) --- .../__tests__/reliability-interactions/_helpers.ts | 11 ++++++----- .../dependency-cycle-reconcile.test.ts | 7 +++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/engine/src/__tests__/reliability-interactions/_helpers.ts b/packages/engine/src/__tests__/reliability-interactions/_helpers.ts index ff789fd093..b1b8088a6d 100644 --- a/packages/engine/src/__tests__/reliability-interactions/_helpers.ts +++ b/packages/engine/src/__tests__/reliability-interactions/_helpers.ts @@ -324,11 +324,12 @@ export async function makeReliabilityFixture(input: { }, mergeTask: async () => aiMergeTask(store, rootDir, task.id), /* - FNXC:PgReliabilitySeeding 2026-07-16-04:48: - Reconcile tests must seed intentionally corrupt dependency/title rows that write-time guards reject. - Raw PostgreSQL updates bypass those guards, then clear both read-through snapshots: otherwise - startupSlimListMemo or taskCache can hide the corruption and reconcilers return zero. Require - exactly one persisted row so a bad fixture ID cannot make a negative-path test pass vacuously. + FNXC:ReliabilityFixtures 2026-07-16-12:00: + VAL-REMOVAL-005 made getDatabase() unusable for synchronous raw writes in PG-backed fixtures. + Reconcile tests must seed intentionally corrupt dependency/title rows that updateTask guards reject, + so this sole supported seam updates PostgreSQL directly. It then clears both read-through snapshots: + a warm startupSlimListMemo or taskCache otherwise hides corruption and reconcilers return zero. + Require exactly one persisted row so a bad fixture ID cannot make a negative-path test pass vacuously. */ seedRawTaskColumns: async (taskId, patch) => { const values = { diff --git a/packages/engine/src/__tests__/reliability-interactions/dependency-cycle-reconcile.test.ts b/packages/engine/src/__tests__/reliability-interactions/dependency-cycle-reconcile.test.ts index 11ac27b6d5..8bd5f53f62 100644 --- a/packages/engine/src/__tests__/reliability-interactions/dependency-cycle-reconcile.test.ts +++ b/packages/engine/src/__tests__/reliability-interactions/dependency-cycle-reconcile.test.ts @@ -23,6 +23,7 @@ describeIfGit("reliability interactions: dependency-cycle reconciliation", () => } as any); const child = await fx.store.createTask({ id: "FN-5256-C", title: "Foundation child", description: "child" } as any); + await fx.store.listTasks({ slim: true }); await fx.seedRawTaskColumns(umbrella.id, { dependencies: [child.id] }); await fx.seedRawTaskColumns(child.id, { dependencies: [umbrella.id] }); @@ -55,6 +56,7 @@ describeIfGit("reliability interactions: dependency-cycle reconciliation", () => const b = await fx.store.createTask({ id: "FN-5241", title: "Task B", description: "B" } as any); const c = await fx.store.createTask({ id: "FN-5242", title: "Task C", description: "C" } as any); + await fx.store.listTasks({ slim: true }); await fx.seedRawTaskColumns(a.id, { dependencies: [b.id] }); await fx.seedRawTaskColumns(b.id, { dependencies: [c.id] }); await fx.seedRawTaskColumns(c.id, { dependencies: [a.id] }); @@ -92,6 +94,7 @@ describeIfGit("reliability interactions: dependency-cycle reconciliation", () => dependencies: [child.id], } as any); + await fx.store.listTasks({ column: "todo", slim: true }); await fx.seedRawTaskColumns(child.id, { title: "Finalize FN-100: close loop", dependencies: ["FN-100"], column: "todo" }); expect(await fx.store.getTask(child.id)).toMatchObject({ title: "Finalize FN-100: close loop", dependencies: ["FN-100"], column: "todo", @@ -137,6 +140,7 @@ describeIfGit("reliability interactions: dependency-cycle reconciliation", () => const c = await fx.store.createTask({ id: "FN-5432-C", title: "Task C", description: "C" } as any); const d = await fx.store.createTask({ id: "FN-5432-D", title: "Task D", description: "D" } as any); + await fx.store.listTasks({ slim: true }); await fx.seedRawTaskColumns(a.id, { dependencies: [b.id] }); await fx.seedRawTaskColumns(b.id, { dependencies: [c.id] }); await fx.seedRawTaskColumns(c.id, { dependencies: [d.id] }); @@ -171,6 +175,7 @@ describeIfGit("reliability interactions: dependency-cycle reconciliation", () => const c = await fx.store.createTask({ id: "FN-5432-RC", title: "Task C", description: "C" } as any); const d = await fx.store.createTask({ id: "FN-5432-RD", title: "Task D", description: "D" } as any); + await fx.store.listTasks({ slim: true }); await fx.seedRawTaskColumns(a.id, { dependencies: [b.id] }); await fx.seedRawTaskColumns(b.id, { dependencies: [c.id] }); await fx.seedRawTaskColumns(c.id, { dependencies: [d.id] }); @@ -192,6 +197,7 @@ describeIfGit("reliability interactions: dependency-cycle reconciliation", () => const p = await fx.store.createTask({ title: "Task P", description: "P" } as any); const q = await fx.store.createTask({ title: "Task Q", description: "Q", dependencies: [p.id] } as any); + await fx.store.listTasks({ column: "todo", slim: true }); await fx.seedRawTaskColumns(p.id, { title: "Finalize FN-101: now", dependencies: ["FN-101"], column: "todo" }); expect(await fx.store.getTask(p.id)).toMatchObject({ title: "Finalize FN-101: now", dependencies: ["FN-101"], column: "todo", @@ -228,6 +234,7 @@ describeIfGit("reliability interactions: dependency-cycle reconciliation", () => const c = await fx.store.createTask({ id: "FN-5432-SC", title: "Task C", description: "C" } as any); const d = await fx.store.createTask({ id: "FN-5432-SD", title: "Task D", description: "D" } as any); + await fx.store.listTasks({ slim: true }); await fx.seedRawTaskColumns(a.id, { dependencies: [b.id] }); await fx.seedRawTaskColumns(b.id, { dependencies: [c.id] }); await fx.seedRawTaskColumns(c.id, { dependencies: [d.id] });