# Upgrade Guide — v0.28.72

<!-- bump: patch -->

## What Changed

When the cloudflared quick tunnel fails all 5 initial startup attempts plus all 3 background retries (scheduled at 5m / 10m / 20m), the server now posts a notification to the Telegram Lifeline topic telling the user the tunnel is permanently unavailable until the server is restarted. Previously this event was a console-only `[tunnel] All retries exhausted` line that nobody reads in a running server, so the dashboard link silently never appeared and the user had no way to know recovery required a restart. The notification is a best-effort `sendToTopic` call on `TelegramAdapter`; if Telegram itself is failing the call is swallowed so it cannot throw out of startup. No retry cadence or other tunnel logic changed — this is a pure additive signal on an existing failure branch in `src/commands/server.ts`.

## What to Tell Your User

- **Tunnel failures stop being silent**: "If the dashboard link doesn't show up after I start, I'll send you a note so you know to restart me — no more guessing why the link never appeared."

## Summary of New Capabilities

| Capability | How to Use |
|-----------|-----------|
| Tunnel-exhaustion Lifeline notification | automatic |

## Evidence

Not reproducible in dev — the failure mode requires 8 consecutive cloudflared quick-tunnel start failures on a live host (5 initial + 3 background retries at 5/10/20 min). The fix site is the `else` branch of `scheduleRetry` in `src/commands/server.ts` immediately after the pre-existing `console.error('[tunnel] All retries exhausted …')` line. Verification plan: the next time a host's outbound to cloudflared is blocked long enough to burn all retries, the Lifeline topic will receive a message; the console log remains as a secondary signal. The added code block is guarded by `telegram?.getLifelineTopicId?.()` and wrapped in `try/catch` with `.catch(() => {})`, so it cannot throw out of server startup even if Telegram is simultaneously unhealthy.
