A gateway autostarted by the Hermes_Gateway Scheduled Task descends from svchost.exe
hosting Task Scheduler's own SCM service (gateway <- cmd.exe <- svchost(Schedule) <-
services.exe). find_windows_gateway_services took "ancestor hosts exactly one running
service" as proof of supervision, so the updater ran `sc.exe stop Schedule`, hit
`OpenService FAILED 5: Access is denied` on a non-elevated shell and aborted every
update before the pull (#97208, #100645). `hermes update --plan` already reported the
same PID as `manual`; the pause path now agrees.
The salvaged commit gated on a Hermes-named service. This widens that to positive
ownership as data: `gateway_windows.hermes_owns_windows_service(name, binpath,
hermes_roots)` accepts a `hermes*` service name or a service binary under a Hermes root
(the checkout incl. its venv, the interpreter's Scripts dir, `<HERMES_HOME>/gateway-service`),
so an NSSM/`sc create` gateway service stays SCM-supervised whatever it is named, while
OS services are never candidates. Ownership is decided before status/pid are read, so a
non-Hermes service in a transitional state (BITS start_pending) no longer aborts the
update either; the shared-host ambiguity and indeterminate-status guards still apply to
every Hermes-owned candidate. The pure predicate lives in the Windows sibling module
(gateway.py is a facade) and is unit-tested on every host; the psutil ancestry test carries
`windows_only` with the reporter's exact process tree and a Hermes-owned control.
Refs #96860
Salvages #97220 (@fangliquanflq)