fix(auto): repair empty continue checkpoints
Some checks are pending
CI / detect-changes (push) Waiting to run
CI / docs-check (push) Blocked by required conditions
CI / lint (push) Blocked by required conditions
CI / build (push) Blocked by required conditions
CI / integration-tests (push) Blocked by required conditions
CI / windows-portability (push) Blocked by required conditions
CI / rtk-portability (linux, blacksmith-4vcpu-ubuntu-2404) (push) Blocked by required conditions
CI / rtk-portability (macos, macos-15) (push) Blocked by required conditions
CI / rtk-portability (windows, blacksmith-4vcpu-windows-2025) (push) Blocked by required conditions

This commit is contained in:
Mikael Hugo 2026-05-15 06:21:58 +02:00
parent 7e2f62ead3
commit 3464db441c
2 changed files with 51 additions and 1 deletions

View file

@ -1104,6 +1104,32 @@ export function assessAutonomousSolverTurn(
checkpoint,
};
}
if (
(checkpoint.outcome === "continue" || checkpoint.outcome === "decide") &&
(checkpoint.remainingItems?.length ?? 0) === 0
) {
const repairAttempts = getMissingCheckpointRepairAttempts(state).filter(
(attempt) => Number(attempt.iteration) === Number(state.iteration),
).length;
if (repairAttempts >= DEFAULT_MISSING_CHECKPOINT_REPAIR_ATTEMPTS) {
return {
action: "pause",
reason: "solver-empty-continue",
state,
repairAttempts,
maxRepairAttempts: DEFAULT_MISSING_CHECKPOINT_REPAIR_ATTEMPTS,
checkpoint,
};
}
return {
action: "missing-checkpoint-retry",
reason: "solver-empty-continue",
state,
repairAttempt: repairAttempts + 1,
maxRepairAttempts: DEFAULT_MISSING_CHECKPOINT_REPAIR_ATTEMPTS,
checkpoint,
};
}
// No-op detection: a continue with zero work is not real progress
if (
(checkpoint.outcome === "continue" || checkpoint.outcome === "decide") &&

View file

@ -324,7 +324,7 @@ describe("autonomous solver", () => {
outcome: "decide",
summary: "Low confidence — reconstructed best-effort.",
completedItems: ["Analysis done"],
remainingItems: [],
remainingItems: ["Continue from reconstructed plan"],
verificationEvidence: ["artifacts match expectations"],
pdd: pdd(),
});
@ -338,6 +338,30 @@ describe("autonomous solver", () => {
expect(result.action).toBe("continue");
});
test("assessAutonomousSolverTurn_empty_continue_requires_repair", () => {
const project = makeProject();
beginAutonomousSolverIteration(project, "execute-task", "M001/S01/T01");
appendAutonomousSolverCheckpoint(project, {
unitType: "execute-task",
unitId: "M001/S01/T01",
outcome: "continue",
summary: "Continue, but nothing remains.",
completedItems: ["Read files"],
remainingItems: [],
verificationEvidence: ["ls"],
pdd: pdd(),
});
const result = assessAutonomousSolverTurn(
project,
"execute-task",
"M001/S01/T01",
);
expect(result.action).toBe("missing-checkpoint-retry");
expect(result.reason).toBe("solver-empty-continue");
});
test("assessAutonomousSolverTurn_max_iterations_pauses_before_unbounded_retry", () => {
const project = makeProject();
beginAutonomousSolverIteration(project, "execute-task", "M001/S01/T01", {