Skip to content

fix: auto-restart dashboard after update when argv is recoverable - #41508

Closed
Variable85 wants to merge 2 commits into
NousResearch:mainfrom
Variable85:fix/dashboard-autorestart-after-update
Closed

fix: auto-restart dashboard after update when argv is recoverable#41508
Variable85 wants to merge 2 commits into
NousResearch:mainfrom
Variable85:fix/dashboard-autorestart-after-update

Conversation

@Variable85

@Variable85 Variable85 commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Preserve recoverable dashboard argv before stopping stale dashboard processes during hermes update
  • Auto-restart recovered dashboards after update, adding --no-open for headless/SSH safety
  • Restart systemd-managed dashboard services through systemctl restart <unit> instead of spawning an unmanaged clone that races the service for the port
  • Keep the manual restart fallback when argv recovery is unavailable or restart fails
  • Harden stale dashboard detection against shell-wrapper false positives and quoted Windows executable paths

Test Plan

  • git diff --check
  • python -m py_compile hermes_cli/main.py tests/hermes_cli/test_update_stale_dashboard.py
  • uv run --with pytest --with pytest-xdist --with pyyaml python -m pytest tests/hermes_cli/test_update_stale_dashboard.py tests/hermes_cli/test_dashboard_lifecycle_flags.py -q -o 'addopts='44 passed in 0.88s
  • Runtime verification on a Linux host with hermes-dashboard.service: /proc/<MainPID>/cgroup resolves to hermes-dashboard.service; helper returns hermes-dashboard.service
  • Runtime verification: local dashboard stayed active and curl http://127.0.0.1:9119/login returned dashboard HTML

Notes

  • LAN/public binds still require dashboard auth after the June 2026 hardening; this PR handles restart behavior, not credential provisioning.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard labels Jun 7, 2026
Preserve recoverable dashboard argv before stopping stale dashboard processes, then restart those dashboards after update while retaining the manual fallback when argv recovery or restart fails. Harden stale dashboard detection against shell-wrapper false positives and cover quoted Windows paths.
@Variable85
Variable85 force-pushed the fix/dashboard-autorestart-after-update branch from 56b75f7 to 93d997e Compare June 24, 2026 07:31

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling the update/dashboard mismatch; current main still stops stale processes and leaves a manual restart hint (hermes_cli/main.py:6094-6210), so the underlying problem is valid.

Problems

  • The new matcher only recognizes dashboard (hermes_cli/main.py:5649 in this PR). Current main also intentionally reaps hermes serve backends (hermes_cli/main.py:5881-5886), so this would regress stale serve cleanup.
  • The systemd path ignores user.slice (hermes_cli/main.py:5799; see the explicit expectation in tests/hermes_cli/test_update_stale_dashboard.py:507-510). It then falls back to detached spawning, which can race a user service configured with Restart=always. Existing gateway service support has explicit systemctl --user handling in hermes_cli/gateway.py:1999-2002.
  • Restart output is sent to Path.home() / '.hermes' at hermes_cli/main.py:5857, bypassing the active profile's HERMES_HOME.

Suggested changes

  • Preserve serve matching and test it.
  • Handle user- and system-scoped units via the scope-aware service helpers instead of treating user units as unmanaged.
  • Use get_hermes_home() for the restart log path.

Automated hermes-sweeper review.

Comment thread hermes_cli/main.py
# `python -m hermes_cli.main dashboard` and `hermes dashboard` both
# place the subcommand after this token. Permit global flags before
# the subcommand (e.g. `hermes --profile taste dashboard`).
if "dashboard" in tail:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This drops current-main support for hermes serve: main currently treats hermes serve, hermes_cli.main serve, and hermes_cli/main.py serve as stale backends too (hermes_cli/main.py:5881-5886). Preserve that command family here and add a regression test before replacing the existing matcher.

Comment thread hermes_cli/main.py
# cgroup v2: 0::/system.slice/hermes-dashboard.service
# cgroup v1/systemd: 1:name=systemd:/system.slice/foo.service
path = line.rstrip("\n").split(":", 2)[-1]
if not path.startswith("/system.slice/"):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A per-user systemd service appears under user.slice, so this branch makes it fall through to detached Popen rather than service restart. That can race a Restart=always unit. Please detect user scope and use systemctl --user; hermes_cli/gateway.py:1999-2002 already centralizes its environment setup.

Comment thread hermes_cli/main.py

restarted: list[list[str]] = []
failed: list[tuple[list[str], str]] = []
log_path = Path.home() / ".hermes" / "logs" / "gui.log"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use get_hermes_home() / 'logs' / 'gui.log' here. Path.home() / '.hermes' sends logs from an active named profile into the default profile, violating profile isolation.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform area/install-update Installer, updater, packaging, wheels, doctor labels Jul 14, 2026
teknium1 pushed a commit that referenced this pull request Jul 26, 2026
…update

Capture each manually-started dashboard/serve process's argv before the
stale-process kill (/proc/<pid>/cmdline on Linux, ps -o command= on macOS),
then respawn it detached after the update — headless (--no-open) with output
to logs/dashboard-restart.log under the active profile's HERMES_HOME.

Supervised PIDs keep their systemd-unit restart; --stop stays a plain stop.

Salvaged from PR #41508 with scope fixes: serve matching preserved, profile-
aware log path, restart only on the update path (restart_managed=True).
teknium1 pushed a commit that referenced this pull request Jul 26, 2026
…update

Capture each manually-started dashboard/serve process's argv before the
stale-process kill (/proc/<pid>/cmdline on Linux, ps -o command= on macOS),
then respawn it detached after the update — headless (--no-open) with output
to logs/dashboard-restart.log under the active profile's HERMES_HOME.

Supervised PIDs keep their systemd-unit restart; --stop stays a plain stop.

Salvaged from PR #41508 with scope fixes: serve matching preserved, profile-
aware log path, restart only on the update path (restart_managed=True).
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #72192 — your argv-capture/respawn work was applied onto current main with your authorship preserved in git history (8e1fb9e), with the review-noted adjustments folded in (serve matching kept, profile-aware log path via get_hermes_home(), capture gated to the update path). Thanks for being the first to tackle the manual-restart half.

@teknium1 teknium1 closed this Jul 26, 2026
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…update

Capture each manually-started dashboard/serve process's argv before the
stale-process kill (/proc/<pid>/cmdline on Linux, ps -o command= on macOS),
then respawn it detached after the update — headless (--no-open) with output
to logs/dashboard-restart.log under the active profile's HERMES_HOME.

Supervised PIDs keep their systemd-unit restart; --stop stays a plain stop.

Salvaged from PR NousResearch#41508 with scope fixes: serve matching preserved, profile-
aware log path, restart only on the update path (restart_managed=True).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install-update Installer, updater, packaging, wheels, doctor comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have 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 sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants