Repository navigation
fix(windows): recover stale host-agent PIDs without stopping foreign processes - #7390
Merged
Lightheartdevs merged 3 commits intoOct 8, 2026
Conversation
This was referenced Oct 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An old host-agent PID receipt can refer to another application's process. Windows
agent start,stop,restartand installer phase 07 previously stopped that numeric PID unconditionally;agent stopalso stopped every listener on the configured port.Stop a process only when its actual Windows command line runs this installation's exact
bin/ods-host-agent.pyas Python's fully qualified script argument. Relative and drive-relative arguments cannot prove ownership because CIM does not expose the target working directory. Keep a process handle through inspection and termination. Discard stale PID receipts and continue the normal start/restart/reinstall path, including when process metadata is unavailable. Foreign listeners remain running.This is the smaller follow-up requested in #7266. It replaces that closed implementation; it does not bring back its task/Startup ownership framework or its refusal to recover from stale receipts.
Refs #7296. This PR addresses its process-termination concern; the issue's broader task/Startup persistence scope is not claimed as resolved.
Why this matters
A stale PID or ordinary port collision must not cause routine ODS lifecycle commands to terminate an unrelated application. The fix also keeps recovery available: stale receipts no longer imply refusing to start or reinstall the owner's agent.
Overlap check
Inspected current-main host-agent lifecycle callers, shipped Python/task launchers, the closed #7266 scope and its maintainer feedback. Searched open and closed PRs for host-agent lifecycle, stale PID and
ods-host-agent.pid; the exact receipt search returned no additional scope. Existing native llama-server PID checks concern a separate runtime. No production files removed by the Tauri or Lemonade retirements are restored.AI Assistance
The human contributor and Codex collaborated on this PR. The contributor provided project direction, scope decisions and environment setup; Codex assisted implementation, analysis, native tests, independent agent review and PR preparation. Commands reported below were executed by Codex. Specific personal verification by the contributor is not inferred from these command receipts. The contributor remains responsible for final changes and validation claims; independent maintainer review remains required.
Release Lane
mainChanged Surface
The production change is one 36-line process helper and its four cleanup callers. Existing scheduled-task/Startup registration paths remain in use.
Risk And Validation
Risk: High — Windows host process termination.
Base:
132d36a11ba258ebec23ce0ab316ac6d76165f86. Exact candidate:f3f8725bf944c38bca6dc5b9d5282766a4ac586f. Native Windows x64, Python 3.14.2, Windows PowerShell 5.1 and PowerShell 7.6.6.agent stopterminates the live foreign Python fixture named in the PID receipt.ods/tests/test-windows-host-agent-stale-pid.ps1: 21 checks passed on each PowerShell version after the audit repair, including foreign relative and drive-relative script arguments. Exercises real Python processes and CIM, foreign receipt/listener preservation, exact owned process/listener termination, start/restart/reinstall recovery, malformed receipts, apython -clookalike and failed metadata inspection.ods/tests/contracts/test-windows-uninstall-leftovers.ps1: 52 passed on each PowerShell version.ods/tests/contracts/test-windows-runtime-recovery.ps1: passed on Windows PowerShell 5.1.py -3launcher: the host agent records its Python child PID, and the child's real CIM command line matches the exact-script grammar. Its affected runtime/uninstall contracts passed.git diff --checkpassed. Commit identity gate passed for the single candidate commit. CI Bash/Python/BATS inventory passed: 1169 tests accounted for, 1150 executed and 19 documented exclusions. The PowerShell workflow directly executes the new native test twice and checks PowerShell test coverage separately.CI executes the new native regression on Windows with both PowerShell 7 and 5.1 through
.github/workflows/lint-powershell.yml.Final hosted CI on
f3f8725bf944c38bca6dc5b9d5282766a4ac586f: all 69 checks passed, with no failed or pending checks. Both new Windows native regression steps completed successfully (PowerShell 7 and 5.1).Operational Change Check
Native process/CIM operations are real. Task Scheduler, Startup and health probes in the lifecycle regression are isolated fixtures; this is not a full installed login-persistence or fresh-install/reinstall run. Full Windows release fleet and independent human/maintainer review remain required before release. No running ODS installation was changed by this maintenance.
Notes For Reviewers
Uncertain ownership authorizes no process termination. Recovery drops the stale receipt and follows the existing launch path. A foreign process still occupying the port may prevent the replacement from binding, but remains untouched for the operator to resolve.
Rollback: revert this scoped change. There is no data migration or credential change.
Audit integration: current main was merged before the repair. The new regression reproduced a foreign-process termination from the old relative-path comparison; the candidate preserves both fixtures. Fresh CI for the repaired head is pending.