Skip to content

Windows: lh run bootstrap fails unconditionally — control bus requires POSIX-only primitives (O_NOFOLLOW / O_DIRECTORY / fcntl / openat walk) #77

Description

@Art-Off-Man

Environment

  • lh-harness 0.1.7 (stock), Python 3.12, Windows 11
  • Every lh run bootstraps the ControlBus (cli.py:371) → the failure is unconditional, with or without --no-dashboard

What happens

The supervisor's control bus (supervisor/control_bus.py) relies on primitives that do not exist in Windows Python:

  • os.O_NOFOLLOW, os.O_DIRECTORY → absent (getattr(os, …, 0) returns 0 → the code raises OSError("secure control-bus path opening is unavailable")). Verified: 'O_NOFOLLOW' in dir(os)False.
  • fcntl.flock → module absent on Windows.
  • openat / dir_fd directory walk → not available.
  • Empirically, os.open(dir, O_RDONLY) on a directory raises PermissionError on Windows (needs FILE_FLAG_BACKUP_SEMANTICS).

Result: lh-harness is entirely unusable on Windows — no run can start. The dependency spans 4 files (control_bus, service, state, manager), so a per-site patch is too risky; a centralized Windows shim is the correct shape.

Why it matters

Windows is a first-class dev/ops platform; as shipped, the harness has zero Windows support. We maintain a locally-pinned fork to work around this (see below), which means we cannot track upstream releases.

Local mitigation (workaround, not a fix)

A pinned venv ("venv-pr66") built from fork xing-kj PR #66 @ 53982af (owner-approved after full diff review) provides:

  1. A centralized shim intercepting os.open + providing fcntl/flags/open-directory equivalents (file-locking layer).
  2. Job Object-based process-group management replacing SIGTERM/SIGKILL/killpg/start_new_session (process/signal layer, in service.py/local.py/process_group.py).

All our green runs used this venv. It is a fork + local patch: any upstream upgrade requires re-doing both layers.

Ask

Port the Windows support upstream so stock releases run on Windows:

  1. Centralized shim for the file-locking layer (intercept os.open, provide fcntl/O_NOFOLLOW/O_DIRECTORY/open-dir equivalents, handle FILE_FLAG_BACKUP_SEMANTICS for directory handles).
  2. Job Object–based process-group kill as the Windows backend for the signal/process layer (instead of SIGTERM/SIGKILL/killpg/start_new_session).
  3. Document the supported-OS matrix and add a Windows CI job so this cannot silently regress.

Happy to share the pinned-venv diff (PR #66 @53982af) as a starting point if useful.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions