From f755f44734de09aada4994e12d93f75fec91405d Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 31 Jul 2026 09:13:21 -0700 Subject: [PATCH] test(engine): pin the completion fan-out's review dependent bucket (16th resolver) (#3190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sixteenth resolver from the coverage map on #3115. `completedReviewColumns` reads the **dependents** resting in review when a blocker completes. No case in this file put a dependent in a renamed review lane, so blinding it left all 13 tests green. ## What the literal costs A dependent sitting in review is never read, so its `blockedBy` is never cleared when the blocker finishes. **It stays blocked by work that is already done** — the most visible form of this class, because the board simply stops moving. ## Measured 14 pass; blinding `completedReviewColumns` fails exactly this case. ## Note for anyone continuing the map `completedHoldColumns` in this same sweep measured as **already covered**, so only the review bucket was owed. Three buckets, three resolvers, covered independently — the same per-resolver granularity that found the missing halves in #3138 and #3186, where my own earlier tests pinned one resolver of a pair and I had recorded the sweep as done. **16 of 26 pinned** across 15 merged PRs. ## Verification `self-healing-completion-fanout` **14 passed** · `pnpm test:gate` full pass · lint — green. ## Summary by CodeRabbit * **Bug Fixes** * Fixed task completion reconciliation for workflows with renamed lanes. * Dependent tasks in review lanes are now correctly unblocked when their blocker moves to a custom completion lane. * **Tests** * Added regression coverage for custom workflow lane configurations. --- .../self-healing-completion-fanout.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/engine/src/__tests__/self-healing-completion-fanout.test.ts b/packages/engine/src/__tests__/self-healing-completion-fanout.test.ts index cb6acb06b8..342caf23b1 100644 --- a/packages/engine/src/__tests__/self-healing-completion-fanout.test.ts +++ b/packages/engine/src/__tests__/self-healing-completion-fanout.test.ts @@ -260,6 +260,33 @@ describe("the task:moved fan-out resolves the board's own lanes", () => { mgr.stop(); }); + /* + FNXC:WorkflowResolvedColumns 2026-07-31-19:30: + `completedReviewColumns` was UNCOVERED on the #3115 map. It reads the DEPENDENTS resting in review + when a blocker completes; no case here put a dependent in a renamed review lane, so blinding it left + the file green. + + What the literal costs: a dependent sitting in review is never read, so its `blockedBy` is never + cleared when the blocker finishes. It stays blocked by work that is already done — the most visible + form of this class, because the board simply stops moving. + */ + it("clears blockedBy for a dependent resting in the board's own review lane", async () => { + const blocker = makeTask("FN-BLOCKER", { column: "shipped" }); + const dependent = makeTask("FN-DEP", { column: "checking", blockedBy: "FN-BLOCKER", status: "queued" }); + const store = createStore([blocker, dependent]) as unknown as TaskStore & EventEmitter; + (store as unknown as { listWorkflowDefinitions: unknown }).listWorkflowDefinitions = + vi.fn(async () => [{ id: "wf-renamed", ir: RENAMED_IR }]); + const mgr = new SelfHealingManager(store, { rootDir: "/repo" }); + + await mgr.reconcileCompletedTask("FN-BLOCKER"); + + expect(store.updateTask).toHaveBeenCalledWith( + "FN-DEP", + expect.objectContaining({ blockedBy: null }), + ); + mgr.stop(); + }); + it("rebinds the branch on a move into the board's own review lane", async () => { const t = makeTask("FN-R2", { column: "checking" }); const store = renamedStore(t);