refactor: remove dead selfHealRuntimeRecords function from auto-recovery
guided-flow.ts has its own local implementation; the exported version in auto-recovery.ts was never imported anywhere. Removes 35 lines of dead code, the unused clearUnitRuntimeRecord import, and associated tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ef5006e16d
commit
ba6ea1c2fa
2 changed files with 0 additions and 125 deletions
|
|
@ -10,7 +10,6 @@
|
|||
import type { ExtensionContext } from "@gsd/pi-coding-agent";
|
||||
import { parseUnitId } from "./unit-id.js";
|
||||
import { atomicWriteSync } from "./atomic-write.js";
|
||||
import { clearUnitRuntimeRecord } from "./unit-runtime.js";
|
||||
import { clearParseCache } from "./files.js";
|
||||
import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
|
||||
import { isDbAvailable, getTask, getSlice, getSliceTasks } from "./gsd-db.js";
|
||||
|
|
@ -623,50 +622,6 @@ export function reconcileMergeState(
|
|||
return true;
|
||||
}
|
||||
|
||||
// ─── Self-Heal Runtime Records ────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Self-heal: scan runtime records in .gsd/ and clear stale ones.
|
||||
* Clears dispatched records older than 1 hour (process crashed before
|
||||
* completing the unit). deriveState() handles re-derivation — no need
|
||||
* for completion key persistence here.
|
||||
*/
|
||||
export async function selfHealRuntimeRecords(
|
||||
base: string,
|
||||
ctx: ExtensionContext,
|
||||
): Promise<void> {
|
||||
try {
|
||||
const { listUnitRuntimeRecords } = await import("./unit-runtime.js");
|
||||
const records = listUnitRuntimeRecords(base);
|
||||
let healed = 0;
|
||||
const STALE_THRESHOLD_MS = 60 * 60 * 1000; // 1 hour
|
||||
const now = Date.now();
|
||||
for (const record of records) {
|
||||
const { unitType, unitId } = record;
|
||||
|
||||
// Case 0 removed — roadmap checkbox auto-fix is no longer needed.
|
||||
// With DB-as-truth, stale checkboxes are fixed by repairStaleRenders().
|
||||
|
||||
// Clear stale dispatched records (dispatched > 1h ago, process crashed)
|
||||
const age = now - (record.startedAt ?? 0);
|
||||
if (record.phase === "dispatched" && age > STALE_THRESHOLD_MS) {
|
||||
clearUnitRuntimeRecord(base, unitType, unitId);
|
||||
healed++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (healed > 0) {
|
||||
ctx.ui.notify(
|
||||
`Self-heal: cleared ${healed} stale runtime record(s).`,
|
||||
"info",
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// Non-fatal — self-heal should never block auto-mode start
|
||||
void e;
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Loop Remediation ─────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {
|
|||
verifyExpectedArtifact,
|
||||
diagnoseExpectedArtifact,
|
||||
buildLoopRemediationSteps,
|
||||
selfHealRuntimeRecords,
|
||||
hasImplementationArtifacts,
|
||||
} from "../auto-recovery.ts";
|
||||
import { parseRoadmap, parsePlan } from "../parsers-legacy.ts";
|
||||
|
|
@ -572,85 +571,6 @@ test("verifyExpectedArtifact plan-slice fails after deleting a rendered task pla
|
|||
}
|
||||
});
|
||||
|
||||
// ─── selfHealRuntimeRecords — worktree base path (#769) ──────────────────
|
||||
|
||||
test("selfHealRuntimeRecords clears stale dispatched records (#769)", async (t) => {
|
||||
// selfHealRuntimeRecords now only clears stale dispatched records (>1h).
|
||||
// No completedKeySet parameter — deriveState is sole authority.
|
||||
const worktreeBase = makeTmpBase();
|
||||
const mainBase = makeTmpBase();
|
||||
t.after(() => {
|
||||
cleanup(worktreeBase);
|
||||
cleanup(mainBase);
|
||||
});
|
||||
|
||||
const { writeUnitRuntimeRecord, readUnitRuntimeRecord } = await import("../unit-runtime.ts");
|
||||
|
||||
// Write a stale runtime record in the worktree .gsd/runtime/units/
|
||||
writeUnitRuntimeRecord(worktreeBase, "run-uat", "M001/S01", Date.now() - 7200_000, {
|
||||
phase: "dispatched",
|
||||
});
|
||||
|
||||
// Verify the runtime record exists before heal
|
||||
const before = readUnitRuntimeRecord(worktreeBase, "run-uat", "M001/S01");
|
||||
assert.ok(before, "runtime record should exist before heal");
|
||||
|
||||
// Mock ExtensionContext with minimal notify
|
||||
const notifications: string[] = [];
|
||||
const mockCtx = {
|
||||
ui: { notify: (msg: string) => { notifications.push(msg); } },
|
||||
} as any;
|
||||
|
||||
// Call selfHeal with worktreeBase — should clear the stale record
|
||||
await selfHealRuntimeRecords(worktreeBase, mockCtx);
|
||||
|
||||
// The stale record should be cleared
|
||||
const after = readUnitRuntimeRecord(worktreeBase, "run-uat", "M001/S01");
|
||||
assert.equal(after, null, "runtime record should be cleared after heal");
|
||||
assert.ok(notifications.some(n => n.includes("Self-heal")), "should emit self-heal notification");
|
||||
|
||||
// Write a stale record at mainBase
|
||||
writeUnitRuntimeRecord(mainBase, "run-uat", "M001/S01", Date.now() - 7200_000, {
|
||||
phase: "dispatched",
|
||||
});
|
||||
await selfHealRuntimeRecords(mainBase, mockCtx);
|
||||
|
||||
// The record at mainBase should also be cleared by the stale timeout (>1h)
|
||||
const afterMain = readUnitRuntimeRecord(mainBase, "run-uat", "M001/S01");
|
||||
assert.equal(afterMain, null, "stale record at main base should be cleared by timeout");
|
||||
});
|
||||
|
||||
// ─── #1625: selfHealRuntimeRecords on resume clears paused-session leftovers ──
|
||||
|
||||
test("selfHealRuntimeRecords clears recently-paused dispatched records on resume (#1625)", async (t) => {
|
||||
// When pauseAuto closes out a unit but clearUnitRuntimeRecord silently fails
|
||||
// (e.g. permission error), selfHealRuntimeRecords on resume should still
|
||||
// clean up stale dispatched records that are >1h old.
|
||||
const base = makeTmpBase();
|
||||
t.after(() => cleanup(base));
|
||||
|
||||
const { writeUnitRuntimeRecord, readUnitRuntimeRecord } = await import("../unit-runtime.ts");
|
||||
|
||||
// Simulate a record left behind after a pause — aged >1h to be considered stale
|
||||
writeUnitRuntimeRecord(base, "execute-task", "M001/S01/T01", Date.now() - 3700_000, {
|
||||
phase: "dispatched",
|
||||
});
|
||||
|
||||
const before = readUnitRuntimeRecord(base, "execute-task", "M001/S01/T01");
|
||||
assert.ok(before, "dispatched record should exist before resume heal");
|
||||
assert.equal(before!.phase, "dispatched");
|
||||
|
||||
const notifications: string[] = [];
|
||||
const mockCtx = {
|
||||
ui: { notify: (msg: string) => { notifications.push(msg); } },
|
||||
} as any;
|
||||
|
||||
await selfHealRuntimeRecords(base, mockCtx);
|
||||
|
||||
const after = readUnitRuntimeRecord(base, "execute-task", "M001/S01/T01");
|
||||
assert.equal(after, null, "stale dispatched record should be cleared on resume (#1625)");
|
||||
});
|
||||
|
||||
// ─── #793: invalidateAllCaches unblocks skip-loop ─────────────────────────
|
||||
// When the skip-loop breaker fires, it must call invalidateAllCaches() (not
|
||||
// just invalidateStateCache()) to clear path/parse caches that deriveState
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue