feat(FN-5449): merge fusion/fn-5449

This commit is contained in:
gsxdsm
2026-05-22 19:22:10 -07:00
parent ec6643e4d9
commit a96e2ab02b
2 changed files with 71 additions and 0 deletions

View File

@@ -681,6 +681,45 @@ describe("FN-5279 reliability interactions: merge reuse task worktree", () => {
reason: "missing-task-worktree",
source: "fresh",
});
const freshAcquire = audits.find((event) => event.mutationType === "merge:reuse-worktree-fresh-acquire");
expect(freshAcquire?.metadata).toMatchObject({
taskId: task.id,
reason: "missing-task-worktree",
expectedBranch: branch,
});
const freshAcquired = audits.find((event) => event.mutationType === "merge:reuse-worktree-fresh-acquired");
expect(freshAcquired?.metadata).toMatchObject({
taskId: task.id,
reason: "missing-task-worktree",
branch,
priorWorktreePath: null,
});
const freshAcquiredWorktreePath = (freshAcquired?.metadata as Record<string, unknown> | undefined)?.worktreePath;
expect(typeof freshAcquiredWorktreePath).toBe("string");
expect(freshAcquiredWorktreePath).toBe((fallback?.metadata as Record<string, unknown> | undefined)?.worktreePath);
const orderedFreshAcquireIndex = audits.findIndex(
(event) =>
event.mutationType === "merge:reuse-worktree-fresh-acquire" &&
(event.metadata as Record<string, unknown> | undefined)?.reason === "missing-task-worktree",
);
const orderedFreshAcquiredIndex = audits.findIndex(
(event) =>
event.mutationType === "merge:reuse-worktree-fresh-acquired" &&
(event.metadata as Record<string, unknown> | undefined)?.reason === "missing-task-worktree",
);
const orderedFallbackIndex = audits.findIndex(
(event) =>
event.mutationType === "merge:reuse-fallback-new-worktree" &&
(event.metadata as Record<string, unknown> | undefined)?.reason === "missing-task-worktree",
);
expect(orderedFreshAcquireIndex).toBeGreaterThanOrEqual(0);
expect(orderedFreshAcquiredIndex).toBeGreaterThanOrEqual(0);
expect(orderedFallbackIndex).toBeGreaterThanOrEqual(0);
expect(orderedFreshAcquireIndex).toBeLessThan(orderedFreshAcquiredIndex);
expect(orderedFreshAcquiredIndex).toBeLessThan(orderedFallbackIndex);
} finally {
await fixture.cleanup();
}

View File

@@ -6814,6 +6814,8 @@ export async function aiMergeTask(
| "merge:reuse-fallback-new-worktree"
| "merge:reuse-fallback-pruned-stale-registration"
| "merge:reuse-fallback-reused-existing-registration"
| "merge:reuse-worktree-fresh-acquire"
| "merge:reuse-worktree-fresh-acquired"
| "branch:auto-canonicalize-case",
metadata: Record<string, unknown>,
target: string,
@@ -6886,6 +6888,8 @@ export async function aiMergeTask(
reason: string,
diagnostics: Record<string, unknown>,
): Promise<void> => {
const priorWorktreePath = task.worktree ?? null;
// FN-5345/FN-5377: consult existing registration of `fusion/<id>` before
// creating a fresh worktree. If the branch is already registered at a
// usable extant path, rebind `task.worktree` to it (avoids FN-5083-class
@@ -7031,6 +7035,19 @@ export async function aiMergeTask(
}
}
await emitReuseHandoffAuditEvent(
"merge:reuse-worktree-fresh-acquire",
{
taskId,
reason,
expectedBranch,
priorWorktreePath,
integrationBranch: mergeTarget.branch,
diagnostics,
},
projectRootDir,
);
const acquisition = await acquireTaskWorktree({
task,
rootDir: projectRootDir,
@@ -7067,6 +7084,21 @@ export async function aiMergeTask(
rootDir,
integrationBranch: mergeTarget.branch,
});
await emitReuseHandoffAuditEvent(
"merge:reuse-worktree-fresh-acquired",
{
taskId,
reason,
branch: acquisition.branch,
worktreePath: acquisition.worktreePath,
source: acquisition.source,
priorWorktreePath: priorWorktreePath ?? null,
integrationRemote: integrationRemote ?? null,
integrationBranch: mergeTarget.branch,
diagnostics,
},
acquisition.worktreePath,
);
await emitReuseHandoffAuditEvent(
"merge:reuse-fallback-new-worktree",
{