fix(desktop): keep a surfaced terminal outage across focus and remount
Draft
PO
7d ago+84+84+01234567890123456789-8-8-0123456789
What & why
Problem
- A person whose terminal host is offline or unreachable loses the cause in the header each time they focus the window, switch tabs, or wake the laptop. The pane shows "Reconnecting…" with no reason for about 10 more failed dials (tens of seconds with backoff), then the cause comes back.
- The same reset re-arms the
terminal_connect_failedlatch, so one continuous outage sends the event again after each focus or tab switch. A few stuck terminals produce most of the events. The failure-to-input ratio in the report measures focus events more than outages. - The rise on 24–26 Oct was not a release or relay change. Most of it came from a very small number of terminals that repeated the event many times. Real host-offline and relay-unreachable failures stayed near their normal level.
Changes
- After an outage is diagnosed in a visible window, a resume (
forceReconnect) or a remount on the same endpoint (connectafterpark) keeps the failure count, the diagnosis and the telemetry latch. The redial still happens at once. If it attaches,attachedclears everything as before. If it fails, the cause shows again after the first failure, not after 10 more. - Kept as before:
| Event during a diagnosed outage | Before | After |
|---|---|---|
| Window focus / visibility / wake | Cause hidden for ~10 dials, event sent again | Cause back after 1 failed dial, no new event |
| Tab switch (park → connect, same terminal) | Same as above | Same as above |
| Re-point to another terminal / manual retry | Full reset | Full reset |
[!NOTE]
After this change, terminal_connect_failed counts outages more closely. Expect event volume to drop with no change in the number of affected people. Compare people affected, not raw events, against the old baseline.
Agent context
- Not in scope: the relay close-4404 ("stream expired") loop on one host, which shows as
stream-blocked. It needs relay-side logs. Also not in scope: host-offline and relay-unreachable failures that reflect real host or network state. The header already explains those.
How I tested it
bun test src/renderer/lib/terminal/inapps/desktop: all tests pass, including 4 new transport tests (resume before diagnosis, resume during an outage, remount on the same endpoint, remount on a new endpoint). The 2 "keeps the outage" tests fail onmain.bunx @biomejs/biome@2.4.2 checkon the changed files andbun run typecheckinapps/desktoppass. I did not run the rootbun run lint(the full repo script).- I did not check this in the running app. There is no session replay for the affected sessions. The header behavior is covered only by the unit tests through
lastDiagnosisand the log entries.
Checklist
- PR title follows conventional commits (
type(scope): subject) -
bun run lintandbun run typecheckpass (CI fails on lint warnings too) - "Allow edits from maintainers" is checked on fork PRs
- I have signed the CLA (the bot asks on your first PR)
Created with PostHog Desktop from this inbox report.
Origin
- Scout:
signals-scout-general - First signal: 2026-10-28
- Inbox report: open
- Task started by: auto-start, after the report was rated P2 and ready to fix
Summary by cubic
Keeps a diagnosed terminal outage visible and single-report across window focus, tab switches, and wake events, instead of resetting the failure budget and telemetry latch each time.
- A resume (
forceReconnect) or a remount on the same endpoint during a diagnosed outage now keeps the diagnosis, failure count, and telemetry latch; the cause returns after the first failed redial instead of after ~10. - Resumes before any diagnosis, new endpoints, terminated sessions,
disconnect(), and manualreconnect()still reset everything as before. terminal_connect_failednow tracks outages rather than focus events, so event volume drops with no change in affected people.