d0ea5f1722
The original implementation classified 502/503/504 only inside the readiness loop, but for OAuth-backed Cloud connections the WebSocket-ticket mint runs before waitForHermesReady. A server fault there was wrapped by gatewayTicketFailure into a generic message and the Cloud-down classifier was never reached. This closes that boundary and fixes a latent regex defect. - isServerSideHttpError: structured-first (err.statusCode for 502/503/504), legacy 'NNN:' prefix as fallback, non-Error inputs rejected. Also fixes the committed '\d' (double-escaped, matched a literal backslash) that made the function never detect a status prefix. - makeNousCloudBackendDownError: single factory for the actionable Cloud-down error (isCloudBackendDown/statusCode/detail/cause), shared by both the ticket-mint boundary and readiness exhaustion. - main.ts: run the Cloud classifier at mintGatewayWsTicket before the gatewayTicketFailure wrap; 401/403 still route to reauth. - connection-config.ts: gatewayTicketFailure preserves an integer statusCode from the source error; auth semantics unchanged. - boot-progress/IPC: carry isCloudBackendDown and statusCode through DesktopBootProgress so the renderer overlay (a PR-body promise) can key on the structured result rather than re-classifying the message string. Tests: backend-health (structured detection, non-Error rejection, factory shape/cause/guards, legacy fallback), connection-config (statusCode preserve, 401/403 reauth, integer-only copy), and an OAuth ticket-mint integration regression (Cloud 503 -> actionable Cloud-down; 401 -> reauth). Connection- config suite 80/80 green; backend-health sync tests green; the async readiness loop tests cannot run on this host (pre-existing local-run limitation) and are the CI gate. PR #85373 (#85335).