fix(FN-5633): fail loudly when an executed, never-merged task has no branch
The AI merge path treated a missing task branch as a benign no-op. That's correct when the task was never executed or already merged (branch cleaned up on a re-process), but if the task WAS executed (a baseCommitSha was recorded) and has no recorded merge, the branch should still exist — its work appears lost. Now that case throws instead of silently marking the task done; the benign cases still finalize as a no-op (reason "already-merged" / "no-branch"). Tests: executed+never-merged → throws; already-merged → no-op done; never-executed → no-op done. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -185,6 +185,39 @@ describe("runAiMerge", () => {
|
||||
expect(git(dir, "rev-parse main")).toBe(mainBefore);
|
||||
});
|
||||
|
||||
it("fails loudly when an executed, never-merged task has no branch (possible lost work)", async () => {
|
||||
const { dir } = initRepoWithBranch({ branch: "fusion/fn-1" });
|
||||
// branch points at a ref that doesn't exist; task was executed (baseCommitSha) and never merged.
|
||||
const { store } = makeStore(dir, { branch: "fusion/ghost", baseCommitSha: "0123456789abcdef" });
|
||||
|
||||
await expect(runAiMerge(store, dir, "FN-1", { manual: true }, {
|
||||
mergeAgent: vi.fn(), reviewAgent: vi.fn(async () => "REVIEW_VERDICT: approve"),
|
||||
})).rejects.toThrow(/work appears lost/);
|
||||
expect(store.moveTask).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("finalizes as a no-op when an already-merged task's branch is gone (re-process)", async () => {
|
||||
const { dir } = initRepoWithBranch({ branch: "fusion/fn-1" });
|
||||
const { store } = makeStore(dir, { branch: "fusion/ghost", baseCommitSha: "0123456789abcdef", mergeDetails: { mergeConfirmed: true } });
|
||||
|
||||
const result = await runAiMerge(store, dir, "FN-1", { manual: true }, {
|
||||
mergeAgent: vi.fn(), reviewAgent: vi.fn(),
|
||||
});
|
||||
expect(result.noOp).toBe(true);
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-1", "done");
|
||||
});
|
||||
|
||||
it("finalizes as a no-op when a never-executed task has no branch", async () => {
|
||||
const { dir } = initRepoWithBranch({ branch: "fusion/fn-1" });
|
||||
const { store } = makeStore(dir, { branch: "fusion/ghost" }); // no baseCommitSha → never executed
|
||||
|
||||
const result = await runAiMerge(store, dir, "FN-1", { manual: true }, {
|
||||
mergeAgent: vi.fn(), reviewAgent: vi.fn(),
|
||||
});
|
||||
expect(result.noOp).toBe(true);
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-1", "done");
|
||||
});
|
||||
|
||||
it("throws a clear error when the task's target branch has no local ref", async () => {
|
||||
const { dir } = initRepoWithBranch({ branch: "fusion/fn-1" });
|
||||
const { store } = makeStore(dir, { baseBranch: "release/9.9" }); // never created locally
|
||||
|
||||
Reference in New Issue
Block a user