ab9866bc64
Fourth reproduction on #48820: the updater's post-update resume respawned the gateway through _spawn_gateway_restart_watcher, the process died within seconds (parent Job Object denying CREATE_BREAKAWAY_FROM_JOB kills the child on job teardown), and "✓ Restarting Windows gateway profile(s)" was printed anyway — 12.5h of silent platform downtime, with zero trace because the watcher respawned with stdout/stderr=DEVNULL. Three surgical changes: 1. Watcher respawn stdio → logs/gateway-stdio.log (hermes_cli/gateway.py). The inlined watcher now routes the respawned gateway's stray stdout/stderr to the same sidecar log gateway_windows._spawn_detached uses (DEVNULL only as fallback), so a gateway killed moments after respawn leaves a trace. Direct implementation of the 4th repro's hardening suggestion (1). 2. Watcher respawn stamps _HERMES_GATEWAY_BREAKAWAY=1/0 exactly like the canonical _spawn_detached, so the respawned gateway's exit-diag / lifecycle records show whether it escaped the parent Job Object — a job-teardown kill is no longer indistinguishable from any other silent death. 3. Post-update resume verifies liveness before vouching (hermes_cli/update_cmd.py). _resume_windows_gateways_after_update now runs the same provisional-hit + 2s-confirmation liveness poll every other spawn path uses (gateway_windows._wait_for_gateway_ready, widened with all_profiles= for the fleet) before printing ✓, writes the #91675 start attestation for the verified PIDs, and fails the resume with a "restart could not be verified" warning + recovery hint when no stable gateway appears. Suggestion (2) of the 4th repro; closes the last silent-success hole in the family (#84185 fixed the cold-start leg, #91675 the direct-start leg; this is the relaunch leg). Live proof on windows-latest (wine2e lane): real kill-on-close Job Objects confirm breakaway children survive teardown and non-breakaway children die (the exact #48820 mechanism); the real watcher respawn cycle leaves the stdio trace + breakaway stamp; and the resume path refuses to print ✓ for a dead relaunch. Fixes the Bug-1 relaunch-trust leg of #48820.