Skip to content

fix: detect macOS gateway service processes reliably - #11293

Open
rjsamson wants to merge 1 commit into
NousResearch:mainfrom
rjsamson:fix/macos-gateway-detection
Open

fix: detect macOS gateway service processes reliably#11293
rjsamson wants to merge 1 commit into
NousResearch:mainfrom
rjsamson:fix/macos-gateway-detection

Conversation

@rjsamson

@rjsamson rjsamson commented Apr 17, 2026

Copy link
Copy Markdown

Summary

Fixes false-negative gateway/cron status detection on macOS by making the manual process-table scan use a macOS-valid ps invocation.

Scope update (post-review): the original version of this PR also taught _get_service_pids() to parse plist-style launchctl list output. That half has since landed on main separately (_parse_launchd_pid_from_list_output(), with parser and probe coverage), so per the sweeper review this branch was rebased onto main and narrowed to only the process-scan fix.

Problem

On macOS, _scan_gateway_pids() falls back to ps when /proc is unavailable — which is always the case on macOS. The fallback invocation ps -A eww -o pid=,command= is rejected by macOS ps:

$ ps -A eww -o pid=,command=
ps: illegal argument: eww

so the scan silently found nothing, and commands like hermes cron status reported the gateway as down even while a launchd-managed gateway was alive.

What changed

  • _scan_gateway_pids() now selects ps -Aww -o pid=,command= on macOS and keeps the existing ps -A eww -o pid=,command= invocation everywhere else, so Linux behavior is untouched.
  • New regression tests (TestScanGatewayPidsPsSelection) exercise the fallback with /proc forced unavailable: one asserts the macOS argv, the other preserves the existing Linux argv assertion.

Notes

On macOS, ps -Aww cannot surface env vars the way Linux ps eww does, so gateways started with only HERMES_HOME=<path> in the environment (no --profile flag) won't be attributable to a named profile via _matches_current_profile. This is called out inline in the code; this PR does not attempt to change profile attribution behavior.

Tests

  • tests/hermes_cli/test_gateway_service.py::TestScanGatewayPidsPsSelection — 2 passed
  • Full-file run on a macOS dev box: 186 passed; the few failures observed are also present on unmodified main in that environment and are unrelated to this change.
  • Verified on macOS directly: ps -A eww -o pid=,command= exits 1 (illegal argument: eww), ps -Aww -o pid=,command= exits 0.

@BrennerSpear

Copy link
Copy Markdown
Contributor

I reproduced this locally on a live macOS launchd-managed Hermes install and wanted to add a +1 with a concrete repro.

Observed behavior:

  • hermes gateway status showed the launchd service loaded with a real live PID
  • hermes cron status incorrectly reported that the gateway was not running
  • launchctl list ai.hermes.gateway returned plist-style output with "PID" = ...; / "Label" = ...;, not the older tabular format
  • the macOS process scan path also needed a macOS-safe ps invocation for gateway PID discovery

I independently implemented the same fix and compared the overlapping open PRs. This PR looks like the strongest version of the fix to me: narrow scope, correct root-cause analysis, and focused regression coverage.

I opened a duplicate while investigating (#12849), but I’m closing it in favor of this one so maintainer attention stays on a single thread. Thanks for putting this together.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery comp/cli CLI entry point, hermes_cli/, setup wizard comp/cron Cron scheduler and job management labels Apr 25, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused macOS investigation and reproduction details. Current main still has the macOS process-scan gap: after the /proc path is unavailable, _scan_gateway_pids() runs ps -A eww -o pid=,command= at hermes_cli/gateway.py:499-505.

Problems

  • The plist parsing portion has already landed through e3db1ef92: _get_service_pids() now uses _parse_launchd_pid_from_list_output() at hermes_cli/gateway.py:151-166, with broader parser and probe coverage at tests/hermes_cli/test_gateway_service.py:1200-1253.
  • The proposed process-scan tests target an older find_gateway_pids() layout. On current main, scanning is in _scan_gateway_pids() and tries /proc before ps (hermes_cli/gateway.py:472-505).

Suggested changes

  • Salvage only the macOS-specific ps argv selection into _scan_gateway_pids().
  • Add tests for that function/path which force /proc unavailable, preserving the existing Linux argv assertion.

This is an automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026
macOS ps rejects the BSD `e` flag in `ps -A eww`, so whenever /proc is
unavailable (always true on macOS) _scan_gateway_pids() silently found
nothing and gateway/cron status reported a live gateway as down.

- select `ps -Aww -o pid=,command=` on macOS; keep `ps -A eww` on Linux
- add regression tests for both argv selections with /proc forced
  unavailable

The launchctl plist-parsing half of the original PR landed separately on
main (_parse_launchd_pid_from_list_output), so this branch now carries
only the process-scan fix, per review feedback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@rjsamson
rjsamson force-pushed the fix/macos-gateway-detection branch from 85b4574 to edc695d Compare July 28, 2026 16:43
@rjsamson

Copy link
Copy Markdown
Author

@teknium1 Thanks for the review — rescoped as suggested. Since the launchctl plist parsing already landed on main via _parse_launchd_pid_from_list_output(), I've rebased onto main and dropped that half entirely. The branch now carries only the macOS ps argv selection, applied to _scan_gateway_pids()'s fallback path: ps -Aww -o pid=,command= on macOS, unchanged ps -A eww elsewhere. The old find_gateway_pids()-era tests are replaced with a TestScanGatewayPidsPsSelection class that forces /proc unavailable and asserts the argv for both platforms, preserving the existing Linux assertion. Also confirmed on a live macOS box that ps -A eww -o pid=,command= fails with illegal argument: eww while the new invocation succeeds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/cron Cron scheduler and job management comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants