fix(FN-5256): route merger-handoff reconcile through hardened gates
Code-review follow-up to cf0101be7. The merger integration worktree path
was still calling bare `activeSessionRegistry.reconcileStaleSelfOwned` for
same-task entries, bypassing the minIdleMs window introduced by the main
fix. A merger-handoff that races a warming-down session could clear a
registry entry < 5s old. Route through `reconcileSelfOwnedActiveSessionForRemoval`
with the `executingTaskLock` process probe so all reconcile sites enforce
the same liveness contract. Test updated to backdate `registeredAt`,
matching the pattern used for the other reliability-interactions tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -304,6 +304,8 @@ describe("acquireReuseHandoff", () => {
|
||||
kind: "executor",
|
||||
ownerKey: "FN-5279",
|
||||
});
|
||||
// FN-5256: backdate so the new min-idle window doesn't refuse the reconcile.
|
||||
(activeSessionRegistry.lookupByPath("/tmp/task-worktree") as any).registeredAt = 0;
|
||||
|
||||
await acquireReuseHandoff({
|
||||
task: await store.getTask("FN-5279"),
|
||||
|
||||
@@ -8,7 +8,11 @@ import type {
|
||||
Task,
|
||||
TaskStore,
|
||||
} from "@fusion/core";
|
||||
import { activeSessionRegistry, executingTaskLock } from "./active-session-registry.js";
|
||||
import {
|
||||
activeSessionRegistry,
|
||||
executingTaskLock,
|
||||
reconcileSelfOwnedActiveSessionForRemoval,
|
||||
} from "./active-session-registry.js";
|
||||
import { attemptBranchAutocorrect } from "./branch-autocorrect.js";
|
||||
import { MeshLeaseManager } from "./mesh-lease-manager.js";
|
||||
import {
|
||||
@@ -294,14 +298,24 @@ export async function acquireReuseHandoff(input: ReuseHandoffInput): Promise<Han
|
||||
|
||||
const activeRecord = activeSessionRegistry.lookupByPath(worktreePath);
|
||||
if (activeRecord) {
|
||||
if (activeRecord.taskId === input.task.id && !executingTaskLock.has(input.task.id)) {
|
||||
const reconciled = activeSessionRegistry.reconcileStaleSelfOwned(worktreePath, input.task.id);
|
||||
if (!reconciled.reconciled) {
|
||||
if (activeRecord.taskId === input.task.id) {
|
||||
// FN-5256: route through the hardened helper so the minIdleMs window and
|
||||
// processActiveProbe (executingTaskLock) gates apply — bare
|
||||
// `reconcileStaleSelfOwned` would race a warming-down session.
|
||||
const outcome = reconcileSelfOwnedActiveSessionForRemoval(
|
||||
activeSessionRegistry,
|
||||
worktreePath,
|
||||
input.task.id,
|
||||
() => false,
|
||||
{ processActiveProbe: (probeTaskId) => executingTaskLock.has(probeTaskId) },
|
||||
);
|
||||
if (outcome.action !== "reconciled") {
|
||||
throw new MergeHandoffRefusedError("active-session-binding", "active-session-present", {
|
||||
taskId: input.task.id,
|
||||
worktreePath,
|
||||
activeRecord,
|
||||
executingTaskLockHeld: executingTaskLock.has(input.task.id),
|
||||
reconcileOutcome: outcome.action,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user