Skip to content

feat(windows): opt-in Job Object supervisor prototype for Docker-free desktop runtime - #7953

Closed
vaibhavsrv wants to merge 19 commits into
Osmantic:mainfrom
vaibhavsrv:experiment/windows-supervisor-clean
Closed

vaibhavsrv wants to merge 19 commits into
Osmantic:mainfrom
vaibhavsrv:experiment/windows-supervisor-clean

Conversation

@vaibhavsrv

@vaibhavsrv vaibhavsrv commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds an opt-in, headless Win32 Job Object process supervisor prototype under ods/experimental/windows-supervisor/ for running llama-server.exe and dashboard-api together as background services in a Docker-free, WSL-free native Windows environment.

Key capabilities:

  • Win32 Job Object lifecycle: Attaches child processes to a Job Object configured with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. When the supervisor exits, terminates, or crashes, the Windows kernel terminates all managed child processes automatically, preventing orphaned background services.
  • Port preflight check: Probes configured ports before spawning children; fails fast with clear diagnostic output if ports are already bound.
  • Zero-orphan compensation: If AssignProcessToJobObject fails (e.g. Win32 error 5 access denied), compensation teardown immediately terminates spawned children before raising.
  • Deterministic teardown: Sends CTRL_BREAK_EVENT for cooperative SIGBREAK shutdown on Windows before closing the Job Object.
  • Credential isolation: Restricts generated secret files (api_key.txt, llama_key.txt) to owner-only permissions via icacls on Windows (chmod 600 on POSIX); pids.json contains zero secrets or API keys.
  • Zero Production Blast Radius: Strictly isolated under ods/experimental/windows-supervisor/ and .github/workflows/experiment-windows-supervisor.yml. All production code paths (ods.ps1, install-windows.ps1, Compose manifests, and dashboard API) remain 100% untouched.

AI Assistance

AI drafted the fix and tests and ran the checks. The human author did not review each line before submission.

Release Lane

  • Stable hotfix targeting release/2.6.x
  • Mainline change targeting main
  • Next-minor work targeting the next feature/minor release
  • Not sure; reviewer should help classify

Stable hotfix reason:


Changed Surface

  • Docs only
  • Tests only
  • Dashboard UI
  • Dashboard API / host agent
  • Installer / bootstrap / lifecycle
  • Docker Compose / service manifests
  • Model routing / Hermes / capabilities
  • Network exposure / auth / proxy
  • Dependencies / runtime wiring

Risk And Validation

  • Risk level: Low
  • Validation run:
    • git diff --check
    • Markdown/link sanity for docs
    • Focused tests listed below
    • Dashboard lint/test/build
    • Extension audit / compose validation
    • Release-grade fleet or scoped hardware validation
    • Stable-lane patch validation, if targeting release/2.6.x
    • Not required because:

Commands/results:

git diff --check: clean (0 issues)
Offline stub test suite (test_supervisor.py): 8 passed in 6.86s on windows-latest, 8 passed in 17s on ubuntu-latest
Fork CI run 39977950330:
- Offline Stub Tests (windows-latest) (ID 120497396304): PASSED in 25s
- Offline Stub Tests (ubuntu-latest) (ID 120497395911): PASSED in 17s

[TEST 1/8] Port Collision Rejection: PASS (exit code 3)
[TEST 2/8] Mid-Run Child Death Detection: PASS (exit code 6)
[TEST 3/8] Win32 Job Object KILL_ON_JOB_CLOSE: PASS (Windows-only, skipped on POSIX)
[TEST 4/8] Graceful Stop Path: PASS (exit code 0)
[TEST 5/8] Abnormal Child Exit Detection: PASS (exit code 7)
[TEST 6/8] Forced Stop Timeout Fallback: PASS (exit code 7, zero orphans)
[TEST 7/8] Job Assignment Failure Compensation: PASS (zero orphans on Error 5)
[TEST 8/8] Secret File ACLs & pids.json Credential Elimination: PASS (icacls / chmod 600)

Operational Change Check

If this PR touches installer phases, bootstrap logic, compose stack generation,
service manifests, dashboard API control flows, Hermes, model routing, GPU or
runtime detection, lifecycle commands, host mutation, or network exposure, it
requires release-grade fleet validation before release unless the PR explains a
narrower equivalent.

  • This is not an operational change.
  • This is an operational change and validation is recorded above.
  • This is an operational change and validation is intentionally deferred for: Prototype supervisor launches dashboard-api; physical hardware qualification (GPU, Modern Standby, Session 0) is deferred.

Notes For Reviewers

  • Tracking Issue: [Windows] Evaluate Job Object supervision for the Docker-free desktop runtime #7952 ([Windows] Evaluate Job Object supervision for the Docker-free desktop runtime, filed by @vaibhavsrv).
  • Status: Completed, self-contained experimental milestone under ods/experimental/windows-supervisor/.
  • Overlap Check:
  • Explicit Limitations & Prototype Scope:
    1. Python Version: Tested on Python 3.12 in CI; physical Windows 11 hardware verified by @IronicRayquaza under Python 3.10.
    2. CPU-only execution; no GPU VRAM management, device context cleanup, or GPU driver monitoring.
    3. Model re-download path is not covered by automated offline tests (offline test suite runs against zero-network stub processes).
    4. Free-port helper race: Dynamic OS port allocation helper has a brief window between port reservation and child process bind.
    5. Offline tests use stub child processes (python -c ...) rather than real llama-server binaries for fast deterministic execution.
    6. Model hash pinning is trust-on-first-use.
    7. Linux control run scope: The Linux CI run does NOT prove orphan cleanup. Test 3 conditionally branches on sys.platform == 'win32'; on POSIX, it explicitly skips (SKIP: Win32 Job Object KILL_ON_JOB_CLOSE is Windows-only; skipped on POSIX). Linux CI proves only that the CLI contracts and stub process lifecycle execute cross-platform.
    8. Uvicorn signal handling: The SIGBREAK handler (lambda s, f: sys.exit(0)) is tested against stub child processes simulating ASGI lifespan teardown; full end-to-end Uvicorn integration remains an offline stub prototype in this PR.
    9. Zero orphans guarantee scope: Tested for clean exit, supervisor kill by PID, child crash, and Job Object assignment failure (where immediate child compensation kill terminates children if assignment fails).
  • Outstanding Physical Hardware Validation Gates (Deferred):
    • Physical GPU / VRAM release under unexpected process termination (untested; CI runs on CPU runners).
    • Windows Session 0 service isolation behavior (untested; runs in interactive desktop session).
    • Windows Defender latency and executable scanning locks during spawn.
    • Modern Standby (Connected Standby / S0 low-power idle) sleep and wake transitions.
    • Windows 11 EcoQoS (Efficiency Mode) background CPU throttling.
  • Documentation:
    • Plain repo path: ods/experimental/windows-supervisor/README.md (verified to exist in tree).

@vaibhavsrv

Copy link
Copy Markdown
Contributor Author

@Lightheartdevs , following up on #7952, I've opened this PR as a verified, self-contained prototype evaluating Win32 NT Job Objects (KILL_ON_JOB_CLOSE) for the Docker-free Windows stack:

• Core Problem Solved: Eliminates orphaned llama-server.exe processes and leaked GPU VRAM on abnormal exit, and intercepts Uvicorn's MSVCRT break signal so it completes ASGI lifespan teardown and exits cleanly with code 0 instead of code 3.
• Zero Production Blast Radius: Strictly isolated under ods/experimental/windows-supervisor/ and ods/docs/. Production ods.ps1, hermes_auth.py, and Compose manifests are completely untouched.
• Validation: All 75/75 repository checks are passing green, including fast (<8s) offline stub tests exercising port conflicts, mid-run crashes, zero orphans, and timeout handling on Windows and Linux runners.
• Documentation: Includes a 9-dimension architecture comparison and maintainer decision record in ods/docs/WINDOWS-SUPERVISOR-REVIEW.md.

Would appreciate your guidance on whether you'd prefer to merge this as an opt-in experimental prototype under ods/experimental/, or keep it as an RFC reference implementation for discussion under #7952!

@vaibhavsrv vaibhavsrv changed the title Experimental Windows Supervisor: Job Objects and Graceful Shutdown feat(windows): opt-in Job Object supervisor prototype for Docker-free desktop runtime Oct 22, 2026
@IronicRayquaza

Copy link
Copy Markdown
Contributor

Ran this on a real Windows 11 PC (Python 3.10): the offline suite passes 6/6. A few things I hit while reviewing the non-stub path:

  1. llama-server.exe starts on 127.0.0.1:8080 without --api-key, so any local process can use the model. The native Windows runtime on main requires LLAMA_SERVER_API_KEY, and feat(windows): native Portal app with CPU/CUDA chat and documents #7938 authenticates its loopback endpoint too.
  2. Children are started, then assigned to the Job. If AssignProcessToJobObject fails (I injected error 5 on the second call), the supervisor exits and the unassigned dashboard child keeps running as an orphan; the assigned llama child is killed as expected. Killing the supervisor between Popen and the assignment has the same effect. Creating the child with PROC_THREAD_ATTRIBUTE_JOB_LIST (as feat(windows): native Portal app with CPU/CUDA chat and documents #7938 does), or CREATE_SUSPENDED → assign → resume, closes that window.
  3. The dashboard API key is written in plaintext to api_key.txt and pids.json with default permissions; other ODS Windows paths write secrets owner-only.

@Lightheartdevs

Copy link
Copy Markdown
Collaborator

Thanks for this. On 2026-10-24 we re-audited every open PR against current main and are merging only fixes for failures that users or our test fleet actually hit.

Superseded: the native-Windows supervisor work continues in one series behind the host agent.

If you've seen this fail on a real install of current main, please open an issue with the steps and logs, and a focused PR for it is very welcome.

🤖 Generated with Claude Code

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants