From 893b6421bee2697b20258ce4499a158fa5db9f0d Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 31 Jul 2026 08:59:26 -0700 Subject: [PATCH] test(engine): pin the contamination sweep's WIP bucket (15th resolver) (#3188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fifteenth resolver from the coverage map on #3115. Every case in this file seeds the candidate in `in-review`, so only the review bucket was exercised — blinding `contaminationWipColumns` left the file green. ## Why the WIP bucket matters A card sent back for a fix **re-enters execution while its branch still carries the foreign commits**, so contamination is discovered there as often as in review. Keyed on the id, that bucket read nothing on a renamed board and the card kept a branch built on someone else's work — which is what this sweep exists to re-anchor. ## Two facts the fixture had to learn, both from failing first - **This is an ACTION site and deliberately skips a card whose own board cannot be read**, rather than guessing from the project union. A fake with only `listWorkflowDefinitions` resolves the default IR, the card is reported unclassifiable, and the case fails for a reason unrelated to the resolver under test. The per-task selection readers are required. - **The WIP bucket's predicate is not the review bucket's.** It additionally requires `paused === true` with `pausedReason` of `branch-cross-contamination` or `branch-conflict-unrecoverable`. A card merely resting in the wip lane is not a candidate — the FN-5704 manual-review contract this sweep mirrors. Neither is guessable from the resolver. Both came from the test failing twice, and I would have shipped something that exercised nothing had the first version passed. ## Measured 3 pass; blinding `contaminationWipColumns` fails exactly this case. **15 of 26 pinned** across 14 merged PRs. ## Verification `self-healing-foreign-only-contamination` **3 passed** · `pnpm test:gate` full pass · lint — green. --- ...healing-foreign-only-contamination.test.ts | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packages/engine/src/__tests__/self-healing-foreign-only-contamination.test.ts b/packages/engine/src/__tests__/self-healing-foreign-only-contamination.test.ts index 06d6626ef9..ce919acf1e 100644 --- a/packages/engine/src/__tests__/self-healing-foreign-only-contamination.test.ts +++ b/packages/engine/src/__tests__/self-healing-foreign-only-contamination.test.ts @@ -47,6 +47,52 @@ describe("SelfHealingManager.recoverForeignOnlyContaminatedInReviewTasks", () => vi.clearAllMocks(); }); + /* + FNXC:WorkflowResolvedColumns 2026-07-31-18:50: + `contaminationWipColumns` was UNCOVERED on the #3115 map. Every case in this file seeds the + candidate in `in-review`, so only the review bucket is exercised and blinding the WIP resolver back + to `["in-progress"]` leaves the file green. + + The WIP bucket is a real source of candidates: a card sent back for a fix re-enters execution while + its branch still carries the foreign commits, so contamination is discovered there as often as in + review. Keyed on the id that bucket read nothing on a renamed board, and the card kept a branch + built on someone else's work — which is what this sweep exists to re-anchor. + */ + it("recovers a foreign-only candidate resting in a RENAMED wip lane", async () => { + store.listTasks.mockImplementation(async ({ column }: { column: string }) => ( + column === "building" + ? [mkTask({ id: "FN-WIP", column: "building", paused: true, pausedReason: "branch-cross-contamination" })] + : [] + )); + const RENAMED_IR = { + version: "v2", + id: "custom:renamed", + nodes: [], + edges: [], + columns: [ + { id: "building", name: "building", traits: [{ trait: "wip", config: { limitSetting: "maxConcurrent" } }] }, + { id: "checking", name: "checking", traits: [{ trait: "merge" }] }, + ], + }; + /* + The per-task readers are REQUIRED, not incidental. This sweep is an ACTION site: it deliberately + SKIPS a card whose own board cannot be read rather than guessing from the project union, so a fake + with only `listWorkflowDefinitions` resolves the default IR, the card is reported unresolvable, and + the case would fail for a reason that has nothing to do with the resolver under test. + */ + store.listWorkflowDefinitions = vi.fn(async () => [{ id: "custom:renamed", ir: RENAMED_IR }]); + store.getTaskWorkflowSelection = vi.fn(() => ({ workflowId: "custom:renamed", stepIds: [] })); + store.getTaskWorkflowSelectionAsync = vi.fn(async () => ({ workflowId: "custom:renamed", stepIds: [] })); + store.getWorkflowDefinition = vi.fn(async () => ({ ir: RENAMED_IR })); + mocked.classifyForeignOnlyContamination.mockResolvedValue({ kind: "foreign-only-no-own-work" }); + mocked.recoverForeignOnlyContamination.mockResolvedValue({ recovered: true, subtype: "reanchor" }); + + const manager = new SelfHealingManager(store, { rootDir: process.cwd() }); + + expect(await manager.recoverForeignOnlyContaminatedInReviewTasks()).toBe(1); + expect(mocked.recoverForeignOnlyContamination).toHaveBeenCalledOnce(); + }); + it("recovers foreign-only in-review candidates", async () => { store.listTasks.mockImplementation(async ({ column }: { column: string }) => column === "in-review" ? [mkTask()] : []); mocked.classifyForeignOnlyContamination.mockResolvedValue({ kind: "foreign-only-no-own-work" });