fix(FN-4976): clear stale self-owned activeSessionRegistry before FN-4811 check

Fusion-Task-Id: FN-4976
Fusion-Task-Lineage: b7d6e778-f6b1-4529-b04b-81352a11ddad
This commit is contained in:
Fusion (runfusion.ai)
2026-05-17 18:54:24 -07:00
committed by gsxdsm
parent f9cf3f1bde
commit d80894241e

View File

@@ -8880,6 +8880,15 @@ Backward compat fallback: if JSON is unavailable, you may still begin output wit
branch: string,
taskId: string,
): Promise<boolean> {
const activeSessionRecord = activeSessionRegistry.lookupByPath(worktreePath);
if (activeSessionRecord?.taskId === taskId) {
executorLog.warn(
`[FN-4976] ${taskId}: clearing stale self-owned activeSessionRegistry entry before cleanup for ${worktreePath}`,
);
activeSessionRegistry.unregisterPath(worktreePath);
await this.store.logEntry(taskId, "Cleared stale self-owned activeSessionRegistry entry", worktreePath);
}
// FN-4811: Hard liveness gate — refuse to remove a worktree that is currently bound to
// an active executor/merger session, regardless of git-level conflict classification.
// This is the canonical guard against the FN-4781/FN-4804 race where a startup cleanup
@@ -8905,18 +8914,6 @@ Backward compat fallback: if JSON is unavailable, you may still begin output wit
executorLog.warn(`${taskId}: failed to unlock conflicting worktree ${worktreePath} before cleanup: ${msg}`);
}
// Remove stale self-owned active-session entry if no live in-memory binding exists.
const activeSessionRecord = activeSessionRegistry.lookupByPath(worktreePath);
if (activeSessionRecord?.taskId === taskId && !this.hasActiveWorktreeBinding(taskId, worktreePath)) {
const reconcileResult = activeSessionRegistry.reconcileStaleSelfOwned(worktreePath, taskId);
if (reconcileResult.reconciled) {
await this.store.logEntry(taskId, "Reconciled stale self-owned active-session registration", worktreePath);
executorLog.log(
`[executor] reconciled stale self-owned active-session entry taskId=${taskId} worktreePath=${worktreePath} reason=${reconcileResult.reason}`,
);
}
}
// Remove the worktree
const settings = await this.store.getSettings();
const removeArgs = {