From 39a2e0481af751e8ccc1e317b98b168a6a8f27a9 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 31 Jul 2026 08:45:19 -0700 Subject: [PATCH] =?UTF-8?q?test(engine):=20pin=20the=20merged-review=20swe?= =?UTF-8?q?ep's=20HOLD=20bucket=20(14th=20resolver=20=E2=80=94=20the=20hal?= =?UTF-8?q?f=20my=20own=20test=20missed)=20(#3186)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fourteenth resolver from the coverage map on #3115, and it is the other half of a sweep **I converted and tested myself**. The file already pinned `mergedReviewColumns`. Blinding `mergedHoldColumns` back to `["todo"]` left all 71 tests green — no case put a merge-confirmed card in a renamed hold lane. ## The lane is not hypothetical A merge-confirmed card gets **rebounded to hold** by other recovery paths — a failed post-merge step, a requeue. So *merged but sitting in hold* is exactly the state this sweep's second bucket exists to finalize. Keyed on the id, that bucket read nothing on a renamed board and the card stayed unfinished **while its commit was already on the base branch**. ## The lesson, repeated This is #3138's finding again: a test that pins one resolver of a pair reads as covering the sweep. I wrote the earlier case, recorded the sweep as done, and it was half-done. **Only blinding each resolver separately finds this.** A single passing revert proves one guard — which is why the map is keyed by resolver, not by sweep. ## Measured 72 pass; blinding `mergedHoldColumns` fails exactly this case. **14 of 26 pinned** across 13 merged PRs. ## Verification `self-healing-query-filter-blindness` **72 passed** · `pnpm test:gate` full pass · lint — green. --- ...elf-healing-query-filter-blindness.test.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/engine/src/__tests__/self-healing-query-filter-blindness.test.ts b/packages/engine/src/__tests__/self-healing-query-filter-blindness.test.ts index 947063c56b..97becbb7a6 100644 --- a/packages/engine/src/__tests__/self-healing-query-filter-blindness.test.ts +++ b/packages/engine/src/__tests__/self-healing-query-filter-blindness.test.ts @@ -768,6 +768,41 @@ describe("self-healing sweeps are bounded by a hardcoded column QUERY, not by th "recover-merged-review", ); }); + /* + FNXC:WorkflowResolvedColumns 2026-07-31-18:20: + The HOLD half of the same sweep, and it was uncovered on the #3115 map. The case above pins + `mergedReviewColumns`; blinding `mergedHoldColumns` back to `["todo"]` left the whole file green, + because no case put a merge-confirmed card in a renamed hold lane. + + That lane is not hypothetical: a merge-confirmed card gets REBOUNDED to hold by other recovery paths + (a failed post-merge step, a requeue), so "merged but sitting in hold" is exactly the state this + sweep's second bucket exists to finalize. Keyed on the id, that bucket read nothing on a renamed + board and the card stayed unfinished with its commit already on the base branch. + */ + it("finalizes a merge-confirmed card stranded on a RENAMED hold lane", async () => { + const merged = { + ...shippedCard(), + id: "FN-MERGED-HOLD", + column: RENAMED_VOCAB.hold, + mergeDetails: { mergeConfirmed: true, commitSha: "abcdef1234567890" }, + } as unknown as Task; + const { store } = productionFaithfulStore([merged]); + const manager = new SelfHealingManager(store, { rootDir: "/repo" }); + const resolveTarget = vi.fn(async () => ({ branch: "main", source: "settings" })); + Object.assign(manager, { + resolveSelfHealingMergeTarget: resolveTarget, + isCommitReachableFromBranch: vi.fn(async () => false), + recordSharedGroupDefaultTargetGuard: vi.fn(async () => undefined), + }); + + await manager.recoverMergedReviewTasks(); + + expect(resolveTarget).toHaveBeenCalledWith( + expect.objectContaining({ id: "FN-MERGED-HOLD" }), + expect.anything(), + "recover-merged-review", + ); + }); it("ignores a merge-confirmed card sitting in the RENAMED wip lane", async () => { /* Non-vacuous companion: without it, a read returning every column would satisfy the case above. This