fix: call selfHealRuntimeRecords before autoLoop to clear orphaned dispatched records (#1772)
When auto-mode dies after a subagent completes but before agent_end is processed, the runtime record stays permanently at "phase": "dispatched" with no recovery path. selfHealRuntimeRecords was only called from the manual guided-flow wizard, never from auto-loop startup. Add selfHealRuntimeRecords(basePath, ctx) before both autoLoop call sites in startAuto (resume path and fresh-start path) so stale dispatched records are cleared on every auto-mode entry. Closes #1727 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fe63ccad10
commit
b609c3b30b
2 changed files with 33 additions and 0 deletions
|
|
@ -115,6 +115,7 @@ import {
|
|||
formatHealthSummary,
|
||||
getConsecutiveErrorUnits,
|
||||
} from "./doctor-proactive.js";
|
||||
import { selfHealRuntimeRecords } from "./auto-recovery.js";
|
||||
import { clearSkillSnapshot } from "./skill-discovery.js";
|
||||
import {
|
||||
captureAvailableSkills,
|
||||
|
|
@ -1052,6 +1053,9 @@ export async function startAuto(
|
|||
);
|
||||
logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "progress");
|
||||
|
||||
// Clear orphaned runtime records from prior process deaths before entering the loop
|
||||
await selfHealRuntimeRecords(s.basePath, ctx);
|
||||
|
||||
await autoLoop(ctx, pi, s, buildLoopDeps());
|
||||
return;
|
||||
}
|
||||
|
|
@ -1082,6 +1086,9 @@ export async function startAuto(
|
|||
}
|
||||
logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, requestedStepMode ? "Step-mode started." : "Auto-mode started.", "progress");
|
||||
|
||||
// Clear orphaned runtime records from prior process deaths before entering the loop
|
||||
await selfHealRuntimeRecords(s.basePath, ctx);
|
||||
|
||||
// Dispatch the first unit
|
||||
await autoLoop(ctx, pi, s, buildLoopDeps());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1098,6 +1098,32 @@ test("auto.ts startAuto calls autoLoop (not dispatchNextUnit as first dispatch)"
|
|||
);
|
||||
});
|
||||
|
||||
test("startAuto calls selfHealRuntimeRecords before autoLoop (#1727)", () => {
|
||||
const src = readFileSync(
|
||||
resolve(import.meta.dirname, "..", "auto.ts"),
|
||||
"utf-8",
|
||||
);
|
||||
const fnIdx = src.indexOf("export async function startAuto");
|
||||
assert.ok(fnIdx > -1, "startAuto must exist in auto.ts");
|
||||
const fnEnd = src.indexOf("\n// ─── ", fnIdx + 100);
|
||||
const fnBlock =
|
||||
fnEnd > -1 ? src.slice(fnIdx, fnEnd) : src.slice(fnIdx, fnIdx + 5000);
|
||||
|
||||
// Both autoLoop call sites must be preceded by selfHealRuntimeRecords
|
||||
const healIdx = fnBlock.indexOf("selfHealRuntimeRecords");
|
||||
const loopIdx = fnBlock.indexOf("autoLoop(");
|
||||
assert.ok(healIdx > -1, "startAuto must call selfHealRuntimeRecords");
|
||||
assert.ok(healIdx < loopIdx, "selfHealRuntimeRecords must be called before autoLoop");
|
||||
|
||||
// Verify the second autoLoop call site also has selfHeal before it
|
||||
const secondLoopIdx = fnBlock.indexOf("autoLoop(", loopIdx + 1);
|
||||
if (secondLoopIdx > -1) {
|
||||
const secondHealIdx = fnBlock.indexOf("selfHealRuntimeRecords", healIdx + 1);
|
||||
assert.ok(secondHealIdx > -1, "second autoLoop call must also have selfHealRuntimeRecords");
|
||||
assert.ok(secondHealIdx < secondLoopIdx, "second selfHealRuntimeRecords must precede second autoLoop");
|
||||
}
|
||||
});
|
||||
|
||||
test("agent_end handler calls resolveAgentEnd (not handleAgentEnd)", () => {
|
||||
const hooksSrc = readFileSync(
|
||||
resolve(import.meta.dirname, "..", "bootstrap", "register-hooks.ts"),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue