Skip to content

feat(gateway): add opt-in startup online notification - #24271

Open
leprincep35700 wants to merge 1 commit into
NousResearch:mainfrom
leprincep35700:feat/gateway-startup-online-notification
Open

feat(gateway): add opt-in startup online notification#24271
leprincep35700 wants to merge 1 commit into
NousResearch:mainfrom
leprincep35700:feat/gateway-startup-online-notification

Conversation

@leprincep35700

@leprincep35700 leprincep35700 commented May 12, 2026

Copy link
Copy Markdown
Contributor

Why

Hermes already emits a completion notification after /restart, but ordinary cold starts caused by Docker, systemd, or a host reboot remain silent. Operators with a dedicated home/back-channel need an explicit opt-in online signal without making startup pings noisy by default.

What changed

  • adds the global gateway_startup_notification runtime flag, defaulting to false;
  • reads the canonical nested configuration shape while preserving the original top-level form for backward compatibility;
  • keeps GATEWAY_STARTUP_NOTIFICATION as an override and resolves it through Hermes' profile-scoped secret environment;
  • reuses the existing thread-aware home-channel sender;
  • preserves planned-restart notifications;
  • keeps chat-originated /restart replies targeted to the original chat/topic and suppresses duplicate home-channel broadcasts;
  • gives a chat /restart marker priority when it coexists with a stale planned-restart marker, while consuming both one-shot markers on that boot;
  • documents the opt-in setting in cli-config.yaml.example.

Configuration

Canonical YAML:

gateway:
  gateway_startup_notification: true

Environment override:

GATEWAY_STARTUP_NOTIFICATION=true

The compatibility top-level YAML key remains accepted for existing users:

gateway_startup_notification: true

Validation

  • 186 passed: gateway config, restart notification, platform reconnect, and home-target environment suites;
  • 37 passed: complete restart-notification suite after the final rebase;
  • ruff check . passed;
  • Windows footgun scan passed across 757 files;
  • Python compilation and git diff --check passed;
  • isolated runtime smoke test passed with a dedicated worktree, virtualenv, and HERMES_HOME: nested config loaded, GatewayRunner.start() returned true, and GatewayRunner.stop() completed cleanly;
  • lifecycle tests call the real GatewayRunner.start() path and assert real adapter sends for default cold start, opted-in cold start, planned restart, chat /restart, and simultaneous chat/planned markers without duplicates or residual markers.

@leprincep35700
leprincep35700 force-pushed the feat/gateway-startup-online-notification branch from 2b0d68d to 7216148 Compare May 12, 2026 09:02
@leprincep35700

Copy link
Copy Markdown
Contributor Author

CI status note after the latest push:

  • Windows footguns (blocking) is now green after adding a line-level suppression for an already _IS_WINDOWS-guarded POSIX kill path.
  • ruff enforcement, ruff + ty diff, attribution, supply-chain scan, and Nix are green.
  • The current e2e red is the existing /new session-reset failure family on tests/e2e/test_platform_commands.py (reset_session called 0 times). I compared it with recent main runs and saw the same failures there, for example main run 25721950049 and 25716556968 show the same test_new_resets_session, test_new_then_status_reflects_reset, and test_new_is_idempotent failures across Telegram/Discord/Slack.

So I’m treating that e2e failure as upstream-wide noise rather than something caused by this gateway startup notification change.

@alt-glitch alt-glitch added type/feature New feature or request comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have labels May 12, 2026
@leprincep35700

Copy link
Copy Markdown
Contributor Author

Additional CI note for the broad test job:

The full test job is also red, but the failure set matches current main rather than this PR's touched area. I compared against recent main run 25721950049; it shows the same broad failures, including auxiliary provider priority, streaming config defaults, TTS media routing, update/verbose command tests, gateway restart PID tests, web-server plugin auth, context-halving tests, async httpx cache, and native vision fast-path.

The scoped validation for this PR remains green:

  • tests/gateway/test_restart_notification.py
  • targeted gateway config tests for gateway_startup_notification
  • Windows footgun checker
  • ruff / ruff + ty diff
  • Nix / builds / attribution / supply-chain checks

I’m leaving those broad failures out of scope for this focused startup-notification change.

@leprincep35700

Copy link
Copy Markdown
Contributor Author

Branch refreshed onto current main and the old legacy Tests / test timeout is gone on the new head.

  • New head: e9c3932da
  • Merge state: clean
  • Local validation rerun:
    • HERMES_HOME=$(mktemp -d /tmp/hermes-pr24271-home.XXXXXX) HERMES_CONFIG_DIR="$HERMES_HOME" /opt/venv/bin/python -m pytest tests/gateway/test_restart_notification.py tests/gateway/test_config.py -k 'startup_notification or GatewayConfigRoundtrip' -q -o addopts=19 passed, 61 deselected
    • /opt/venv/bin/python -m py_compile gateway/config.py gateway/run.py tests/gateway/test_config.py tests/gateway/test_restart_notification.py tests/gateway/restart_test_helpers.py
    • git diff --check

GitHub now shows the PR as clean with successful current checks.

@leprincep35700

Copy link
Copy Markdown
Contributor Author

Post-current-main reassessment:

I rechecked this after #36028 and #36188 landed.

Conclusion: this PR is now partially superseded and should be updated/downscoped rather than merged as-is.

What upstream now covers:

What this PR still uniquely adds:

  • An explicit opt-in gateway_startup_notification / GATEWAY_STARTUP_NOTIFICATION for ordinary cold starts/reboots where there is no planned restart marker.
  • That capability is still distinct if operators want “gateway online” on every normal boot.

Recommendation:

  • Rebase and downscope this PR if the project wants opt-in ordinary cold-start online notifications.
  • Updated behavior should be: send home-channel startup notification when planned_restart_marker OR gateway_startup_notification, keep default false, and do not reintroduce home-channel broadcasts for chat-originated /restart.
  • If the project only wants notifications for planned/service restarts, then this PR can be closed as no longer needed after fix(gateway): clean service restart flow #36188.

@leprincep35700
leprincep35700 force-pushed the feat/gateway-startup-online-notification branch 2 times, most recently from 408901c to 0aad64a Compare June 1, 2026 09:13
@leprincep35700

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and downscoped the behavior to fit the newer #36188 planned-restart flow.

  • New head: 0aad64ab5
  • Updated behavior: home-channel startup online notifications are sent when there is a non-chat planned restart marker or when gateway_startup_notification / GATEWAY_STARTUP_NOTIFICATION is explicitly enabled.
  • Default remains quiet for ordinary cold starts.
  • Chat-originated /restart remains routed to its precise originating chat/topic and does not get a duplicate home-channel broadcast.
  • Local validation:
    • /opt/venv/bin/python -m pytest tests/gateway/test_restart_notification.py tests/gateway/test_config.py -k 'startup_notification or gateway_startup_notification or planned_restart_notification' -q -o addopts='' --tb=short15 passed, 71 deselected
    • /opt/venv/bin/python -m py_compile gateway/config.py gateway/run.py tests/gateway/test_config.py tests/gateway/test_restart_notification.py tests/gateway/restart_test_helpers.py → OK
    • git diff --check → OK
  • Attribution was refreshed to the mapped GitHub noreply author email.

@leprincep35700
leprincep35700 force-pushed the feat/gateway-startup-online-notification branch 2 times, most recently from d43d727 to c04c679 Compare June 9, 2026 09:54
@leprincep35700
leprincep35700 force-pushed the feat/gateway-startup-online-notification branch 2 times, most recently from 6954711 to 4ff3b4c Compare June 25, 2026 13:14
@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages 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 13, 2026

@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 preserving the planned-restart and chat-originated /restart distinctions. The ordinary-cold-start gap is still real on current main: GatewayRunner.start() invokes the home-channel sender only when _planned_restart_notification_pending() is true (gateway/run.py:7272-7293).

Problems

  • The PR only bridges a top-level gateway_startup_notification (gateway/config.py:877-880 in PR head). Current gateway settings convention uses the nested gateway: section; current main already reads gateway.max_concurrent_sessions there (gateway/config.py:870-875). The nested startup setting would be ignored.
  • The added tests call the predicate directly (tests/gateway/test_restart_notification.py:48-83 in PR head), not the GatewayRunner.start() path that must invoke the sender.

Suggested changes

  • Support gateway.gateway_startup_notification as well as the compatibility top-level form, with a nested-config regression test.
  • Add a lifecycle-level startup test for default quiet, opt-in cold boot, planned restart, and chat /restart non-broadcast behavior.
  • Reconcile the env override with current profile-scoped config reads (gateway/config.py:169-189) if it remains part of the feature.

Automated hermes-sweeper review.

Comment thread gateway/config.py Outdated
@leprincep35700
leprincep35700 force-pushed the feat/gateway-startup-online-notification branch from 4ff3b4c to 540a65a Compare July 13, 2026 09:16
@leprincep35700

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review — all requested follow-ups are now included in 540a65a69.

Addressed

  • canonical nested config: gateway.gateway_startup_notification;
  • backward compatibility for the original top-level key;
  • GATEWAY_STARTUP_NOTIFICATION now resolves through the profile-scoped secret environment and preserves YAML for blank/invalid overrides;
  • lifecycle-level tests exercise the real GatewayRunner.start() path for:
    • ordinary cold start, default quiet;
    • ordinary cold start, opt-in home notification;
    • planned restart home notification;
    • chat-originated /restart, targeted to its original chat/topic with no duplicate home broadcast.

The lifecycle tests assert the real adapter sends and marker cleanup rather than only calling the predicate.

Validation

  • focused local gateway suites: 184 passed;
  • final restart-notification suite after rebase: 35 passed;
  • isolated worktree/virtualenv/HERMES_HOME runtime smoke: start and clean stop passed;
  • ruff, Windows footgun scan, Python compilation, and diff checks passed;
  • GitHub CI: all executed checks green, including all 8 Python test slices, E2E, lint, security/supply-chain checks, and Docker build checks.

The PR body has also been updated with the canonical configuration and current validation evidence. Ready for re-review.

@leprincep35700
leprincep35700 force-pushed the feat/gateway-startup-online-notification branch from 540a65a to 362f9e4 Compare July 13, 2026 09:49
@leprincep35700

leprincep35700 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Correction to my previous readiness note: two independent reviews completed just after that comment and identified valid edge cases, so the earlier “ready” status is superseded.

Fixed in 6a663caa5:

  • precedence is now explicitly environment > gateway.gateway_startup_notification (canonical) > top-level compatibility alias > default;
  • when chat /restart and planned-restart markers coexist, the precise chat route wins, no home broadcast is emitted, and both one-shot markers are consumed on the same boot;
  • GatewayRunner.start() now uses the captured marker state consistently;
  • new RED/GREEN lifecycle and configuration regressions cover both cases.

Updated local validation: 186 focused tests passed, including 37/37 restart-notification tests; ruff, Windows footgun, compilation, and diff checks pass. GitHub CI is rerunning on this corrected head; I will only mark it ready again once that run is fully green.

@leprincep35700
leprincep35700 force-pushed the feat/gateway-startup-online-notification branch from 362f9e4 to 6a663ca Compare July 13, 2026 10:01
@leprincep35700

Copy link
Copy Markdown
Contributor Author

Final readiness update for corrected head 6a663caa5:

  • both late-review findings are fixed and covered by RED/GREEN regressions;
  • independent final review: PASS, no blocking findings;
  • local focused validation: 186 passed, including 37/37 restart-notification tests;
  • GitHub CI on the current head: 23 success, 7 skipped, 1 neutral, 0 failed/pending; all eight Python slices, E2E, lint, security/supply-chain checks, and relevant Docker builds passed;
  • PR is currently mergeable with merge state clean.

The PR is now ready for re-review.

Support the canonical nested gateway config with legacy compatibility, honor profile-scoped environment overrides, and exercise the real GatewayRunner.start lifecycle for cold, planned, and chat-originated restarts.
@leprincep35700
leprincep35700 force-pushed the feat/gateway-startup-online-notification branch from 6a663ca to c9080d7 Compare July 13, 2026 20:54
@leprincep35700

Copy link
Copy Markdown
Contributor Author

Rebased cleanly onto current main (c44de9985) and revalidated the full focused Gateway surface. The opt-in cold-start notification remains distinct from planned/chat restart notifications; nested/legacy/profile-aware precedence and marker cleanup are covered.

Validation:

  • focused Gateway suite: 186 passed
  • Ruff + git diff --check: passed
  • independent final review: PASS

Updated head: c9080d72f8a8.

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

Labels

comp/gateway Gateway runner, session dispatch, delivery 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-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants