feat(cli): add --force-kill flag for Windows update (#63300) - #64386
feat(cli): add --force-kill flag for Windows update (#63300)#64386Phoenix0531-sudo wants to merge 1 commit into
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for addressing a real Windows update failure mode. The venv-holder guard still exists on current main (hermes_cli/main.py:9604-9609), so the underlying report remains relevant.
Problems
- The new call at
hermes_cli/main.py:9620kills the generic detector result before_pause_windows_gateways_for_update(). Current main deliberately snapshots unmapped gateway argv before force-killing so it can relaunch it (hermes_cli/main.py:9209-9214); the proposed ordering loses that state. The detector also explicitly says Desktop backends respawn and should be refused rather than killed (hermes_cli/main.py:9020-9022). - The new
taskkillinvocations build"/PID <pid>"as one argv element (hermes_cli/main.py:9153,:9159). The established primitive uses separate"/PID", str(pid)arguments plus/T /F(gateway/status.py:112). - No tests are included for the new flag or termination/update-resume behavior.
Suggested changes
- Preserve the existing gateway pause/snapshot/resume flow, and narrowly target only processes that can safely be stopped.
- Reuse the established Windows termination behavior and add Windows-gated regression coverage.
Automated hermes-sweeper review.
|
|
||
| # Graceful termination first (taskkill without /F = WM_CLOSE) | ||
| graceful = subprocess.run( | ||
| ["taskkill", *(f"/PID {pid}" for pid in pids)], |
There was a problem hiding this comment.
Please use the established taskkill argv shape: separate "/PID", str(pid) elements (and the existing tree-kill/no-window behavior where applicable). gateway/status.py:112 is the current Windows termination primitive and avoids encoding a switch and its value into one argv item.
| if _is_windows(): | ||
| force_kill = getattr(args, "force_kill", False) | ||
| if force_kill: | ||
| _kill_hermes_python_processes() |
There was a problem hiding this comment.
This runs before _pause_windows_gateways_for_update(), so a detected gateway is killed before that flow can snapshot its argv and arrange a restart. Current main treats that snapshot as load-bearing (hermes_cli/main.py:9209-9214); preserve the pause/resume flow and only target processes that can safely be stopped.
55e71cf to
62c3a11
Compare
415eba2 to
7aa5d05
Compare
|
Rebased onto latest
On the sweeper's note that "the detector says Desktop backends respawn and should be refused rather than killed" — that contract from Diff is 4 files / +259 −2. |
SummaryOne PR, #64386, addresses issue #63300 by adding a Windows Related pull requests
Suggested consolidationKeep #64386 open with a salvage path: retain its narrowly targeted non-Desktop lock-holder termination, preserved gateway relaunch state, established tree-kill primitive, and focused tests. Request contributor re-review of the revised diff; there are no duplicate PRs to close. Complex graphflowchart LR
classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
classDef best stroke-width:3px,stroke:#b45309
classDef target stroke-width:3px,stroke:#4338ca
I63300(["issue #63300 (open)"])
P64386["PR #64386 (open)"]
P64386 -->|best fix| I63300
class I63300 open
class P64386 open
class P64386 best
class P64386 target
click I63300 "https://github.com/NousResearch/hermes-agent/issues/63300"
click P64386 "https://github.com/NousResearch/hermes-agent/pull/64386"
Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed (state tag in the node label). Cross-PR triage: Reviewed 1 pull request and 1 issue in this complex. Each diff was read against this issue; Assessment working set: 15 kB of PR diffs, 3 kB of issue/PR text, 3 kB of discussion (2 comments), 2 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch. |
|
Friendly nudge on this one. The previous push (7aa5d05e) addressed the three findings from the July-16 sweeper review and GottZ's triage pass on Aug-3 flagged it as best fix for #63300. No CI has been queued on the branch since then — likely needs the fork-workflow approval to spin up the lint/pytest suite. A quick review (or just workflow approval so CI gives you a green signal to review against) would unblock this. |
On Windows, headroom proxy and tui_gateway workers run as python.exe
processes that hold .pyd file locks. The existing --force flag only
skips hermes.exe lock detection; these Python processes remain
invisible to the current guard and still block the update.
Changes:
- hermes_cli/subcommands/update.py: add --force-kill argument
- hermes_cli/update_cmd.py:
- add _kill_hermes_python_processes() to force-stop venv Python
processes via terminate_pid(force=True) before the dependency sync
- wire --force-kill into _cmd_update_impl() before the venv-holder
guard (after gateway pause/snapshot)
- update error message to mention --force-kill as alternative
- hermes_cli/main.py: re-export _kill_hermes_python_processes so
existing test surface (hermes_cli.main.<name>) keeps resolving
- tests/hermes_cli/test_update_concurrent_quarantine.py: add 5 tests
covering the kill helper (no-op when no holders, no-op off-Windows,
force-kills every holder PID, survives failures, decision-flag logic)
Closes NousResearch#63300
7aa5d05 to
37bd28f
Compare
Summary
On Windows,
hermes updatefails when Hermes-related Python processes(headroom proxy, tui_gateway workers) are running. These python.exe
processes hold .pyd file locks that the dependency installer (uv/pip)
cannot release, causing the update to fail partway and leave a broken
install.
The existing
--forceflag only skips thehermes.exeshim-lockdetector — it does not address the .pyd lock problem, and the existing
--force-venvflag merely bypasses the detection without actuallystopping the lock-holding processes.
This PR adds
--force-kill, which detects and terminates allHermes-related venv Python processes before proceeding with the update.
Changes
hermes_cli/subcommands/update.py--force-killCLI argumenthermes_cli/main.py_kill_hermes_python_processes()hermes_cli/main.py--force-killinto_cmd_update_impl()hermes_cli/main.py--force-killKey design decisions:
_detect_venv_python_processes()rather thanduplicating detection logic
taskkillsends WM_CLOSE first,then
taskkill /Ffor survivors--force/--force-venvchecks, soafter killing, those guards pass naturally
Backward compatibility
--forcecontinues to work unchanged (skips .exe lock check only)--force-venvcontinues to work unchanged (skips venv python check)--force-killis additive; no existing invocation is affected_is_windows())Testing
py_compileon both modified files passesupdate.pyis clean;main.pypre-existing formattingissues are unchanged
from hermes_cli.main import _kill_hermes_python_processesresolves correctly
Related issue
Closes #63300