macOS Local Network Privacy attributes a socket to the executable launchd
spawned for the job. A bare venv Python has no application identity and is
not platform-entitled, so every LAN connect from the supervised gateway
failed with errno 65 (No route to host) while the same URL worked from
Terminal — and nehelper never showed a prompt that could grant it, so a
headless Mac had no way out.
Run the job through /usr/bin/osascript: `do shell script "exec …"` spawns
its child as osascript-responsible — an Apple platform binary — and the
child is exempt. Verified live on macOS 26.3.1 with a fresh ad-hoc binary
under the gui launchd domain: bare → 65, `/bin/sh -c exec` → 65,
`/usr/bin/time` → 65, osascript → reachable; an ad-hoc-signed helper .app
with NSLocalNetworkUsageDescription (the #115196 approach) stays denied with
no prompt even after lsregister, matching the #57812 dead-end table.
`do shell script` buffers the child's output until exit, so the shell
command redirects stdout/stderr to the log files the plist already routes;
`exec` keeps the gateway in the job's process group, so `launchctl bootout`
still delivers SIGTERM to it (live: stop → no orphan, restart → exit 75 →
KeepAlive respawn, stop → parked). The existing plist-staleness refresh
picks the new definition up on `hermes gateway install`/`start`.
Mechanism proposed by @leewaiho in #57812.
Co-authored-by: leewaiho <18321182+leewaiho@users.noreply.github.com>