Skip to content

fix(windows): harden gateway scheduled task#45610

Merged
teknium1 merged 2 commits into
NousResearch:mainfrom
lEWFkRAD:fix/windows-gateway-reboot-survival
Jun 23, 2026
Merged

fix(windows): harden gateway scheduled task#45610
teknium1 merged 2 commits into
NousResearch:mainfrom
lEWFkRAD:fix/windows-gateway-reboot-survival

Conversation

@lEWFkRAD

@lEWFkRAD lEWFkRAD commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

  • Makes the Windows gateway Scheduled Task actually survive reboot/login by closing all three root causes in [Windows] Gateway does not survive reboot - .cmd wrapper killed by console control event + schtasks missing critical XML settings #45599, not just the schtasks-settings one.
  • Creates the task from XML with a logon delay, StartWhenAvailable, battery-safe settings, no 72-hour execution limit, and a RestartOnFailure policy (root cause Support passing morph snapshot id #2).
  • Resolves the detached uv-venv pythonw in the generated wrapper so the launcher does not respawn a console python.exe (root cause #2c).
  • Runs the task through a console-less wscript.exe -> pythonw.exe launcher instead of cmd.exe, so the logon-time CTRL_CLOSE_EVENT can no longer reap the gateway with STATUS_CONTROL_C_EXIT / 0xC000013A (root cause Terminal tool #1 - the one that produced the reported LastTaskResult after every reboot). RestartOnFailure cannot catch 0xC000013A (Windows treats it as a user cancel), so the console has to be eliminated at the source rather than retried.

Why the .vbs launcher
wscript.exe and pythonw.exe are both GUI-subsystem executables with no console, so the Scheduled Task action receives no console control events at logon. The .vbs sets HERMES_HOME / PYTHONIOENCODING / HERMES_GATEWAY_DETACHED / VIRTUAL_ENV / PYTHONPATH on the WScript.Shell process (chaining onto any runtime PYTHONPATH, mirroring the cmd wrapper's ;%PYTHONPATH%) and Runs pythonw directly, window style 0, async. The .cmd wrapper is kept for the Startup-folder fallback and direct /Run paths, so this is a single, scoped change to the reboot path.

Related Issue
Fixes #45599

Type of Change

  • Bug fix

Changes Made

  • Added _build_gateway_vbs_script() + _quote_vbs_string() (mirrors _build_gateway_cmd_script; reuses _resolve_detached_python).
  • _write_task_script() now also renders <task>.vbs next to <task>.cmd.
  • Scheduled Task <Exec> action now runs wscript.exe //B //Nologo "<vbs>" instead of cmd.exe /d /c "<cmd>".
  • Added regression tests for the console-less launcher, spaced-path quoting, runtime PYTHONPATH chaining, the VBScript quoter, and the wscript action in the install XML.

How to Test

  • (Windows) python -m pytest tests/hermes_cli/test_gateway_windows.py
  • python -m ruff check hermes_cli/gateway_windows.py tests/hermes_cli/test_gateway_windows.py
  • python -m py_compile hermes_cli/gateway_windows.py tests/hermes_cli/test_gateway_windows.py
  • python scripts/check-windows-footguns.py hermes_cli/gateway_windows.py tests/hermes_cli/test_gateway_windows.py
  • git diff --check

Checklist

  • Tests added/updated
  • Targeted tests pass (39 passed)
  • Lint passes (ruff)
  • Whitespace check passes
  • Windows footgun scan passes

Screenshots / Logs
Targeted suite:

39 passed in tests/hermes_cli/test_gateway_windows.py

Live wscript.exe -> pythonw.exe smoke test on Windows 11 (launcher built with the new _quote_vbs_string); the child process reported:

{
  "has_console": false,
  "HERMES_HOME": "C:\\Hermes Home",
  "HERMES_GATEWAY_DETACHED": "1",
  "VIRTUAL_ENV": "C:\\venv",
  "PYTHONPATH": "C:\\repo root",
  "cwd": "C:\\dev",
  "argv": ["...\\probe.py", "smoke-arg"]
}

has_console: false is the direct evidence that no console is allocated for the launcher or the gateway, so the logon CTRL_CLOSE_EVENT that produced 0xC000013A can no longer be delivered to it. Env (including spaced values) and cwd all propagate correctly.

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Summary

Verdict: Approved

Windows gateway hardening: replaces fragile schtasks /TR quoting with a clean Task Scheduler XML definition, adds restart-on-failure policy (PT1M, 999 retries), 30s logon delay, and proper cleanup of temp XML files. Correctly uses LeastPrivilege run level. Test coverage added for uv-safe base pythonw detection. No issues found.


Reviewed by Hermes Agent

@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists labels Jun 13, 2026
The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause #1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@lEWFkRAD

Copy link
Copy Markdown
Contributor Author

Approved by tonydwb. Clean Windows gateway task hardening with proper cleanup and restart policy. Ready for merge.

@lEWFkRAD

Copy link
Copy Markdown
Contributor Author

Approved by tonydwb. Windows-specific scope, safe standalone change.

@teknium1
teknium1 merged commit 433db17 into NousResearch:main Jun 23, 2026
T02200059 pushed a commit to T02200059/hermes-agent that referenced this pull request Jun 24, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause NousResearch#1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Jeff <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
kpadilha pushed a commit to kpadilha/hermes-agent that referenced this pull request Jun 24, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause #1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Jeff <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
pai-scaffolde pushed a commit to pai-scaffolde/hermes-agent that referenced this pull request Jun 28, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause #1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Jeff <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause #1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Jeff <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
liuchanchen pushed a commit to liuchanchen/hermes-agent that referenced this pull request Jul 3, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause #1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Jeff <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Methodician added a commit to Methodician/hermes-agent that referenced this pull request Jul 4, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause #1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Jeff <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause #1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Jeff <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause NousResearch#1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Jeff <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
kulikman pushed a commit to kulikman/hermes-agent that referenced this pull request Jul 16, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause #1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.


---------

Co-authored-by: Jeff <[email protected]>
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
* fix(windows): harden gateway scheduled task

* fix(windows): launch gateway scheduled task via console-less wscript

The Scheduled Task ran the gateway through cmd.exe, which allocates a
console. During logon Windows broadcasts CTRL_CLOSE_EVENT to console
process groups, reaping cmd.exe and the half-initialized gateway with
STATUS_CONTROL_C_EXIT (0xC000013A) - which Task Scheduler treats as a
user cancel, so RestartOnFailure never fires and the gateway vanishes on
every reboot (issue NousResearch#45599 root cause NousResearch#1).

Add a console-less .vbs launcher (wscript.exe -> pythonw.exe, both
GUI-subsystem) mirroring the gateway.cmd env + argv, and point the task
action at it. The .cmd stays for the Startup-folder fallback and /Run.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Jeff <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
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.

[Windows] Gateway does not survive reboot - .cmd wrapper killed by console control event + schtasks missing critical XML settings

5 participants