ac2e4207c1
The update hand-off spawned the detached updater, called unref(), and quit unconditionally after the 2.5s dwell. Node reports exec failures (ENOENT/EACCES) asynchronously via the child 'error' event, and a short-lived updater can die inside that window — in both cases the app vanished with no updater, no relaunch, and no evidence (the reported macOS incident, and the posix.sh early-death reports on the same thread). Add observeUpdaterHandoff(): watch the just-spawned child for 'error' and early 'exit' during the existing dwell (no added latency — the dwell doubles as the settle window). Clean exit 0 inside the window stays a success (the Windows `cmd start` wrapper exits immediately by design); a spawn error, non-zero exit, or signal death is a failed hand-off. On failure: - applyUpdates (Windows hand-off): don't quit — restart the backend and surface a structured error to the UI. - applyUpdatesPosixHandoff (mac/linux): don't quit — surface the error. - handOffWindowsBootstrapRecovery: return false so the caller falls through to its next recovery path instead of quitting into nothing. The pre-written update marker names the dead child pid, so readLiveUpdateMarker self-heals it; no marker cleanup needed. Children without an event interface settle ok after the window, keeping the observation a best-effort hardening rather than a new way to wedge an update. Covered by 7 new unit tests (spawn-error, non-zero exit, signal death, clean exit 0 wrapper, survival, double-settle, event-less child). Closes #66753