fix: avoid false offline results in Electron instance probes (#3415)

* fix: avoid false offline results in Electron instance probes

Use Chromium networking with one abortable deadline per direct-host attempt. Retry unreachable selector probes once while preserving identity, auth and compatibility checks, and clean up response bodies on every exit.

Add regression coverage and document the native probe invariants.

* fix: declare Electron probe's zod dependency

Declare the existing workspace zod version as an Electron runtime dependency so probe imports do not rely on root hoisting. Update only the matching lockfile workspace entry, without changing resolved versions or parsing behavior.
This commit is contained in:
Jordi Ibáñez
2026-09-09 17:44:38 +03:00
committed by GitHub
parent 03697190ff
commit 70e04fc15f
9 changed files with 501 additions and 118 deletions
+25
View File
@@ -19,6 +19,8 @@ The preload bridge exposes desktop-only APIs to the web UI through `window.__OPE
| File | Purpose |
|------|---------|
| `main.mjs` | Electron main process, app lifecycle, windows, menus, deep links, native IPC handlers, updates, local server startup |
| `electron-host-probe.mjs` | Chromium direct-host probes, identity checks, attempt deadlines, and response cleanup |
| `host-probe-policy.mjs` | Selector fast attempt and unreachable-only retry policy |
| `startup-url-selection.mjs` | Pure bundled/HMR startup probe and loopback connection-limit policy |
| `preload.mjs` | Safe bridge from the rendered UI to Electron IPC |
| `ssh-manager.mjs` | SSH host import, connection lifecycle, tunnel/port forwarding helpers |
@@ -33,6 +35,29 @@ The preload bridge exposes desktop-only APIs to the web UI through `window.__OPE
## Development
### Direct-host probe invariants
After app readiness, direct-host probes use Chromium `net.fetch`, not Node fetch.
Each attempt shares one deadline across optional `/health` identity verification,
`/api/version`, and `/auth/session`, including JSON body reads. The fast attempt
has a 2-second budget. The selector retries once with a 10-second budget only
after Unreachable. Reported latency is the final attempt's application-probe
duration, excluding an earlier failed attempt. It is not raw network ping.
Probes never follow redirects. A redirected identity check returns Wrong Service
before any bearer-bearing request. An explicit server ID mismatch also stops the
probe. Electron 43 reports a manual redirect as a rejected fetch rather than a
3xx response; the identity gate handles both forms. Identity requests carry
neither the client token nor custom headers;
version and session requests use sanitized custom headers and the client bearer
token. Older servers without identity metadata remain supported. HTTP 401 and
403 mean authentication is required, not that the instance is offline.
Every exit aborts the attempt's requests and cancels unused response bodies before
clearing the deadline timer. This includes early HTTP classifications and a
successful session response whose body is not needed. TLS verification remains
enabled. These rules do not change relay probing or the preload/IPC contract.
From the repo root:
```bash