Skip to content

fix(gateway): don't dead-end setup wizard when only system-scope unit is installed#20905

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-46b86ac0
May 6, 2026
Merged

fix(gateway): don't dead-end setup wizard when only system-scope unit is installed#20905
teknium1 merged 1 commit into
mainfrom
hermes/hermes-46b86ac0

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

@teknium1 teknium1 commented May 6, 2026

Summary

The setup wizard no longer drops users at a bare shell prompt when a system-scope systemd unit exists and the user isn't root.

Root cause: _require_root_for_system_service called sys.exit(1). The wizard's except Exception guards don't catch SystemExit (it's a BaseException), so the whole process died mid-setup. Users who had previously run sudo hermes setup (or equivalent) hit this every time they later ran hermes setup as a regular user — no explanation, just a shell prompt.

Changes

  • hermes_cli/gateway.py
    • New SystemScopeRequiresRootError(RuntimeError) with a clean __str__ so format strings render the message (not the (msg, action) tuple).
    • _require_root_for_system_service raises instead of sys.exit.
    • gateway_command catches the new error and exits 1 — preserves the direct hermes gateway start --system CLI path unchanged.
    • New _system_scope_wizard_would_need_root() pre-check and _print_system_scope_remediation() helper.
    • 3 wizard prompt sites in gateway_setup() now check the guard first and fall back to the remediation printer in a defensive except SystemScopeRequiresRootError branch.
  • hermes_cli/setup.py
    • Same treatment for the 2 wizard prompt sites in setup_gateway(), plus the post-install "Start the service now?" sub-branch.
  • tests/hermes_cli/test_gateway_service.py
    • 12 new tests across 4 classes covering: exception contract, pre-check matrix, remediation output per action, and the direct-CLI exit-1 path.

Validation

Before After
hermes setup wizard as non-root with system unit present sys.exit(1) → shell prompt Prints actionable remediation, wizard continues
hermes gateway start --system as non-root exit 1 + "requires root" exit 1 + "requires root" (unchanged)
hermes setup as root unchanged unchanged

Test results: scripts/run_tests.sh tests/hermes_cli/test_gateway_service.py tests/hermes_cli/test_gateway.py tests/hermes_cli/test_setup.py tests/hermes_cli/test_setup_reconfigure.py tests/hermes_cli/test_setup_noninteractive.py — 186/186 passing, 12 new.

E2E (non-root + /etc/systemd/system/hermes-gateway.service present) now prints:

⚠ Gateway is installed as a system-wide service — start requires root.
    Options:
      1. Start it this time:
           sudo systemctl start hermes-gateway
      2. Switch to a per-user service (recommended for personal use):
           sudo hermes gateway uninstall --system
           hermes gateway install
           hermes gateway start

Reported by a user whose terminal dropped to a bare shell after answering Y to "Start the gateway service?" with only a System gateway start requires root. Re-run with sudo. line above it.

… is installed

The setup wizard dropped non-root users at a bare shell prompt when
trying to start a system-scope gateway service. Previously
_require_root_for_system_service called sys.exit(1), which the
wizard's `except Exception` guards cannot catch (SystemExit is a
BaseException). Users with a pre-existing /etc/systemd/system unit
(e.g. from an earlier `sudo hermes setup` run) hit this whenever
they re-ran `hermes setup` as a regular user.

- Convert _require_root_for_system_service to raise a typed
  SystemScopeRequiresRootError (RuntimeError subclass) instead of
  sys.exit(1). The direct CLI path (`hermes gateway install|start|stop|
  restart|uninstall` without sudo) still exits 1 cleanly via a new
  catch at the top of gateway_command, matching the existing
  UserSystemdUnavailableError pattern.
- Add _system_scope_wizard_would_need_root() pre-check and
  _print_system_scope_remediation() helper. Both setup wizards
  (hermes_cli/setup.py and hermes_cli/gateway.py::gateway_setup) now
  detect the dead-end before prompting and print actionable guidance:
  either `sudo systemctl start <service>` this time, or uninstall the
  system unit and install a per-user one.
- Defense-in-depth: all 5 wizard prompt sites also catch
  SystemScopeRequiresRootError and fall back to the remediation
  helper if the pre-check is bypassed (race, etc.).

Tests: 12 new tests in TestSystemScopeRequiresRootError,
TestSystemScopeWizardPreCheck, TestSystemScopeRemediationOutput, and
TestGatewayCommandCatchesSystemScopeError covering the exception
contract, pre-check matrix (root vs non-root, system-only vs
user-present vs none vs explicit system=True), remediation output
for each action, and the direct-CLI exit-1 path.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🚨 CRITICAL Supply Chain Risk Detected

This PR contains a pattern that has been used in real supply chain attacks. A maintainer must review the flagged code carefully before merging.

🚨 CRITICAL: Install-hook file added or modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

Scanner only fires on high-signal indicators: .pth files, base64+exec/eval combos, subprocess with encoded commands, or install-hook files. Low-signal warnings were removed intentionally — if you're seeing this comment, the finding is worth inspecting.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔎 Lint report: hermes/hermes-46b86ac0 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 7441 on HEAD, 7441 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 3911 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists labels May 6, 2026
@teknium1 teknium1 merged commit 3cdbf33 into main May 6, 2026
10 of 12 checks passed
@teknium1 teknium1 deleted the hermes/hermes-46b86ac0 branch May 6, 2026 22:58
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/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants