test(engine): pin the archive skip in branch reclaim — the first uncovered resolver whose failure deletes a branch (#3144)

Next entry from the verified coverage map on #3115 — and the first one
whose failure mode is **irreversible**.

## The gap

`reclaimArchivedColumns` was uncovered: blinding it back to the id
`archived` leaves all 825 self-healing tests green, because no fixture
in this suite puts a card in a renamed archive lane.

## Why it matters more than the other 22

That guard **skips** archived cards — their branches belong to archive
cleanup, not to branch reclaim. Keyed on the id, a card filed in a
renamed archive lane fails the skip, and this sweep reaches:

```
git branch -D "fusion/<id>"
```

Every other uncovered resolver I have pinned so far causes a wrong
lifecycle decision — a card not requeued, a lease not released, a
diagnostic not surfaced. All of those are recoverable from the task row.
**A deleted branch is not.**

## Measured

415 pass. Blinding `reclaimArchivedColumns` fails exactly this case, and
the assertion that fails is the one checking `git branch -D` was never
called — so the failure *is* the branch being deleted, not a proxy for
it.

## Progress on the map

Closed so far: `archiveStaleDoneTasks` ×2 (#3115),
`reconcileOrphanedPendingStepResults` (#3090),
`recoverDriftedAgentTaskLinks` (#3102), `reconcileTaskWorktreeMetadata`
wip (#3132), `reconcileDependencyBlockingLeases` ×2 (#3138), and this
one. **22 uncovered resolvers remain.**

Every sweep probed so far has been uncovered, and one
(`reconcileDependencyBlockingLeases`) was only half-covered by its own
first test — the branch short-circuited before the second resolver was
ever consulted. That is why I now blind each resolver separately rather
than trusting a single revert.

Next: `reconcileInReviewBranchRebind` (rebinds branches of live cards)
and the two remaining `reconcileTaskWorktreeMetadata` resolvers
(terminal, review).

## Verification

`self-healing.test.ts` **415 passed** · `pnpm test:gate` 13 + 161 + 487
+ 71 · lint — green.
This commit is contained in:
gsxdsm
2026-07-31 06:55:15 -07:00
committed by GitHub
parent db71b4fffb
commit 1136474a63

View File

@@ -11003,6 +11003,45 @@ describe("SelfHealingManager reclaimStaleActiveBranches (FN-4546)", () => {
}));
});
/*
FNXC:WorkflowResolvedColumns 2026-07-31-23:10:
`reclaimArchivedColumns` was UNCOVERED on the #3115 map: blinding it back to the id `archived` leaves
all 825 self-healing tests green, because no fixture here puts a card in a renamed archive lane.
This guard SKIPS archived cards — their branches belong to archive cleanup, not to branch reclaim.
Keyed on the id, a card filed in a renamed archive lane fails the skip and this sweep DELETES its
branch (`git branch -D`), which is not recoverable from the task row.
*/
it("does not reclaim the branch of a card filed in a RENAMED archive lane", async () => {
(store.listTasks as any).mockResolvedValueOnce([
{ id: "FN-1001", column: "vault", checkedOutBy: null, userPaused: false, worktree: null, branch: null },
]);
(store as unknown as { listWorkflowDefinitions: unknown }).listWorkflowDefinitions = vi.fn(async () => [{
ir: {
version: "v2",
id: "custom:renamed",
nodes: [],
edges: [],
columns: [
{ id: "building", name: "building", traits: [{ trait: "wip", config: { limitSetting: "maxConcurrent" } }] },
{ id: "vault", name: "vault", traits: [{ trait: "archived" }] },
],
},
}]);
mockedExecSync.mockImplementation((command: string) => {
if (command.includes("git branch --list 'fusion/*'")) return Buffer.from(" fusion/fn-1001\n");
if (command.includes("git rev-parse --verify") && command.includes("fusion/fn-1001")) return Buffer.from("abc123\n");
if (command.includes("git rev-list --count") && command.includes("fusion/fn-1001")) return Buffer.from("0\n");
return Buffer.from("");
});
const recovered = await manager.reclaimStaleActiveBranches();
expect(recovered).toBe(0);
/* The branch survives: deleting it is not recoverable from the task row. */
expect(mockedExecSync).not.toHaveBeenCalledWith(expect.stringContaining("git branch -D"), expect.anything());
});
it("does not delete branch with unique commits", async () => {
(store.listTasks as any).mockResolvedValueOnce([
{ id: "FN-1001", column: "todo", checkedOutBy: null, userPaused: false, worktree: null, branch: null },