Root cause: when ngrok dies externally (pkill, crash, timeout), the server
still reports tunnelActive=true with a dead URL. pair-agent prints an
instruction block pointing at a dead tunnel. The remote agent gets
"endpoint offline" and the user has to manually restart everything.
Three-layer fix:
- Server /pair endpoint: probes tunnel URL before returning it. If dead,
resets tunnelActive/tunnelUrl and returns null (triggers CLI restart).
- Server /tunnel/start: probes cached tunnel before returning already_active.
If dead, falls through to restart ngrok automatically.
- CLI pair-agent: double-checks tunnel URL from server before printing
instruction block. Falls through to auto-start on failure.
4 regression tests verify all three probe points + CLI verification.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>