test(engine): pin the contamination sweep's WIP bucket (15th resolver) (#3188)

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.
This commit is contained in:
gsxdsm
2026-07-31 08:59:26 -07:00
committed by GitHub
parent 24c565540e
commit 893b6421be

View File

@@ -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" });