Context
packages/loopover-miner/lib/attempt-cli.js:534 only sets worktreeResult.attemptOk = result.outcome === "submitted" after runAttemptPipeline returns normally. If it throws instead, execution jumps to the outer catch and line 534 never runs, leaving attemptOk undefined. The finally block then does cleanupWorktree(..., worktreeResult.attemptOk ?? true) — the ?? true default means a genuinely crashed attempt (which most needs post-mortem inspection) has its worktree deleted instead of retained. shouldRetainWorktree(attemptOk) in packages/loopover-engine/src/miner/worktree-plan.ts returns !attemptOk, and its header explicitly says a FAILED attempt's worktree is retained for post-mortem inspection. test/unit/miner-attempt-cli.test.ts:1521-1542 exercises this exact throw path but never asserts what cleanupAttemptWorktree was called with.
Requirements
- Track
attemptOk explicitly so an uncaught exception from runMinerAttempt defaults to false (retain), not true (remove) — e.g. wrap the runAttemptPipeline call to set attemptOk=false before rethrowing.
- Update the stale
finally-block comment (lines 672-675) to correctly describe the exception case, not just the "earlier blocked path" cases.
Deliverables
Test Coverage Requirements
99%+ Codecov patch coverage on every changed line and branch, plus a regression test that reproduces the exact failure mode described above and asserts it's fixed.
Expected Outcome
A crashed attempt's worktree is retained for post-mortem inspection, matching the documented retention policy.
Links & Resources
packages/loopover-miner/lib/attempt-cli.js:516-534,672-679, packages/loopover-engine/src/miner/worktree-plan.ts.
Context
packages/loopover-miner/lib/attempt-cli.js:534only setsworktreeResult.attemptOk = result.outcome === "submitted"afterrunAttemptPipelinereturns normally. If it throws instead, execution jumps to the outer catch and line 534 never runs, leavingattemptOkundefined. Thefinallyblock then doescleanupWorktree(..., worktreeResult.attemptOk ?? true)— the?? truedefault means a genuinely crashed attempt (which most needs post-mortem inspection) has its worktree deleted instead of retained.shouldRetainWorktree(attemptOk)inpackages/loopover-engine/src/miner/worktree-plan.tsreturns!attemptOk, and its header explicitly says a FAILED attempt's worktree is retained for post-mortem inspection.test/unit/miner-attempt-cli.test.ts:1521-1542exercises this exact throw path but never asserts whatcleanupAttemptWorktreewas called with.Requirements
attemptOkexplicitly so an uncaught exception fromrunMinerAttemptdefaults tofalse(retain), nottrue(remove) — e.g. wrap therunAttemptPipelinecall to setattemptOk=falsebefore rethrowing.finally-block comment (lines 672-675) to correctly describe the exception case, not just the "earlier blocked path" cases.Deliverables
attemptOkdefaults tofalseon an uncaught exception fromrunMinerAttemptcleanupAttemptWorktree/removeWorktreereceivesattemptOk: falsewhenrunMinerAttemptthrowsfinally-block commentTest Coverage Requirements
99%+ Codecov patch coverage on every changed line and branch, plus a regression test that reproduces the exact failure mode described above and asserts it's fixed.
Expected Outcome
A crashed attempt's worktree is retained for post-mortem inspection, matching the documented retention policy.
Links & Resources
packages/loopover-miner/lib/attempt-cli.js:516-534,672-679,packages/loopover-engine/src/miner/worktree-plan.ts.