Observed again tonight (4th occurrence this week): a squads run --background lane died 60 turns in with API Error: Connection closed mid-response (result event has is_error: true, stop_reason: stop_sequence). Nothing had been committed yet, and on exit the wrapper cleaned up the worktree — the branch is gone too, so there is nothing to salvage. All work lost.
Two gaps compound here:
-
Abnormal exit is treated like a clean finish. The wrapper's cleanup (worktree remove) runs regardless of the result's is_error. On an error result the worktree + branch should be preserved and the log should end with a salvage pointer (path, branch, session id).
-
No resume. The wrapper already passes a fixed --session-id to the provider CLI, so the session transcript exists after a disconnect — a bounded retry loop (--resume <session-id>, 1-2 attempts on connection-closed errors specifically) would turn a total loss into a hiccup. Transient network failure is the most common lane-death cause we see; it deserves first-class handling, not re-dispatch-from-zero.
Acceptance: kill a lane's network mid-run → wrapper retries via resume; if retries exhaust, worktree/branch survive and the final log lines say where to pick up.
Observed again tonight (4th occurrence this week): a
squads run --backgroundlane died 60 turns in withAPI Error: Connection closed mid-response(result event hasis_error: true,stop_reason: stop_sequence). Nothing had been committed yet, and on exit the wrapper cleaned up the worktree — the branch is gone too, so there is nothing to salvage. All work lost.Two gaps compound here:
Abnormal exit is treated like a clean finish. The wrapper's cleanup (worktree remove) runs regardless of the result's
is_error. On an error result the worktree + branch should be preserved and the log should end with a salvage pointer (path, branch, session id).No resume. The wrapper already passes a fixed
--session-idto the provider CLI, so the session transcript exists after a disconnect — a bounded retry loop (--resume <session-id>, 1-2 attempts on connection-closed errors specifically) would turn a total loss into a hiccup. Transient network failure is the most common lane-death cause we see; it deserves first-class handling, not re-dispatch-from-zero.Acceptance: kill a lane's network mid-run → wrapper retries via resume; if retries exhaust, worktree/branch survive and the final log lines say where to pick up.