Skip to content

Release 2.1.139 (2026-07-14)

Bug fixes

  • keep interactive cloud sessions off the shared SSH control master (#2345) (#2350) Interactive off-platform (IAP/ssh) sessions dropped frequently with "Shared connection to X closed" (exit 255). The "Shared" wording is diagnostic: OpenSSH prints it only for a multiplexed slave whose master went away.\n\nSince #2202 (2026-07-08), _cloud_session reaps any master on the (host, cwd)-keyed control socket at session start via an unconditional ssh -O exit, which force-kills the master and every channel on it with no live-client check. Because exec_session rode that same shared socket, any concurrent session or command against the same box from the same dir — a parallel agent, a second terminal, or --resume (#2285) — tore the master out from under a live PTY.\n\nFix: exec_session now opens its own dedicated connection (mux=False, no ControlPath) while run/pipe/popen keep multiplexing. The interactive session is immune to the reap and never inherits a wedged master; ConnectTimeout/ServerAlive keepalive bounding is retained. The provisioning-burst optimization (#2098) is preserved where it earns its keep.\n\nRejected ssh -O check before -O exit: it only confirms the master process is alive, so a network-wedged master still reports healthy and cannot be told apart from a live-in-use one.\n\nRef #2345

  • freeze a branch after report-ready — refuse post-ready commits/pushes (#2351)

  • feat(pr-workflow): add post-report-ready freeze signal and deliberate unfreeze

Introduce lib/pr_workflow/freeze: a frozen worktree is one whose state is status=ready and not yet submitted (mirroring worktrees._probe_pr_workflow's pr_prepared), with a drift check against the recorded head_sha and an actionable refusal message pointing at the follow-up-issue path.

Add engine.apply_unfreeze plus a 'vrg-pr-workflow unfreeze' subcommand as the single sanctioned, explicit way to reopen a frozen branch: it drops status back to implementing while retaining the recorded PR metadata, and refuses once the PR is already submitted. Re-running report-ready to correct prose still works.

  • surface merged-but-dirty worktrees as needs-attention (#2352) A merged/closed PR whose worktree is not removable (dirty tree, or a reused branch name that withheld the merged verdict per #1719) was miscounted into 'active' by _summary and hidden behind a '0 cruft' message. A real Mac run showed four stuck merged worktrees reported as '4 active ... 0 cruft'.

Add a needs_attention flag to WorktreeStatus, set in classify_worktree when the PR is merged/closed but the worktree is not removable. _summary now counts these in a dedicated needs-attention bucket, never as active or stalled, and prints a pointer to the notes. gather_worktree_status emits an actionable note for the merged-but-dirty case showing the count and offending paths so the human can see it is just build output.

CI Evidence: All gates passed — full audit bundle available. Download →