Skip to content

[Bug]: native Windows canary premerge/smoke-suite renders repository-relative script paths with the host separator and fails the gate's own contract smokes #6450

Open

Description

@JasonBuildAI

Preflight

  • I searched existing issues and discussions for this behavior.

  • This report is not an unpatched security vulnerability.

  • The report and attachments contain no credentials or private/internal material.

  • Issue origin: observed or reproduced in a real environment

  • LoopX version or commit: f713e0f07 (main), source checkout on native Windows 11 (PowerShell, cp936 console)

  • Host or runtime surface: not host-specific (source-checkout tooling; reproduced on native Windows)

  • Area: build, packaging, installer, or CI (canary premerge validation and the public smoke suite)

Impact, First

The canary premerge gate and the public smoke suite render every repository-relative script path with the host path separator, while the catalog, the suite checks, the shipped contract smokes and the docs all declare the canonical python3 examples/<...>.py POSIX spelling.

On native Windows this makes loopx canary premerge — the risk-based validation set AGENTS.md mandates ("Before self-merging non-trivial LoopX changes, run loopx canary premerge --from-git-diff or an equivalent risk-based validation set") — red for every diff, and not because of the diff:

$ loopx canary premerge --changed-file loopx/quota.py --profile canary-runner --no-progress --format json
rc=1   gate: failed   risk_profile_run: 3 of 8 selected checks failed
  python3 examples/canary/catalog-run-e2e-smoke.py               rc=1
  python3 examples/canary/premerge-validation-gate-smoke.py      rc=1
  python3 examples/canary/smoke-suite-runner-smoke.py            rc=1
  • Who is harmed: every contributor or maintainer who validates a change from a Windows checkout. They cannot obtain a green mandated premerge gate, so they must hand-diff their failure set against a clean baseline to prove their own diff is neutral. That is the same cost issue [Bug]: the pinned top-level module budget is already exceeded on main (150 measured against 147) #5685 records for the module-budget gate ("every PR based on current main inherits that failure ... every contributor must diff failure sets"). Merged PR fix(benchmark): run the EdgeBench report adapter and suite on native Windows #6368 had to record these exact two smokes as manual | blocked pre-existing host failures in its validation table, and each new Windows-host work item pays it again.
  • How severe: it is not a display defect. The gate's own contract smokes reject the rendering, so the validation surface a PR is required to record (selected_commands, normalized.script, normalized.display_argv) is host-dependent: a Windows run and a Linux run of the same diff produce different command strings, and four shipped public smokes fail. docs/development/good-smokes.md treats a public smoke as a durable regression contract, not a host-conditional one.
  • How large: 3 of the 8 canary-runner risk-profile checks for any control-plane diff are the gate's own smokes, plus smoke-suite-subdir-discovery-smoke.py; and --suite full-public (release validation) sweeps the same family. The defect is invisible on POSIX hosts, where str(relative) and as_posix() are identical, so only the Windows lane can see it — and the Windows lane does not run this family.

Problem

Four shipped canary surfaces render a repository-relative path with str(path.relative_to(repo_root)):

  • loopx/canary/runner.py — the normalized check's script field and the _display_argv path entries;
  • loopx/canary/premerge.py — _display_argv and the public-boundary --scan-path rendering;
  • loopx/canary/planner.py — _display_path, used for catalog source entries.

Every other renderer in the same package already emits the canonical POSIX form: runner._smoke_script_relative, runner._smoke_script_filter_keys, runner._matches_modules and all of loopx/canary/maintainability_ratchet.py use .as_posix(), and loopx/canary/smoke_health.py even compensates for the inconsistent field with an explicit .replace("\\", "/"). The catalog itself declares python3 examples/..., and so does every command in docs/.

So the defect is not that the plan is un-runnable on Windows — argv keeps the absolute path and execution is unaffected. It is that the declared and recorded command identity of a check is host-dependent, which the contract smokes correctly refuse.

Minimal reproduction

On native Windows, from a source checkout at f713e0f07:

python examples/canary/smoke-suite-subdir-discovery-smoke.py
python examples/canary/smoke-suite-runner-smoke.py
python examples/canary/catalog-run-e2e-smoke.py
python examples/canary/premerge-validation-gate-smoke.py
loopx canary premerge --changed-file loopx/quota.py --profile canary-runner --no-progress --format json

Expected behavior

Repository-relative paths in the canary plan and its evidence use the repository's canonical POSIX spelling on every host, exactly as the catalog, the suite checks and the shipped contract smokes declare. All five commands above exit 0, and loopx canary premerge reports the same command identity for a diff whether it was validated on Windows or on Linux.

Actual behavior

All five commands fail on native Windows with the host separator in the plan payload:

$ python examples/canary/smoke-suite-subdir-discovery-smoke.py
AssertionError: {'...': 'selected_checks': [{'...': 'normalized': {'command': 'python3 examples/canary/smoke-suite-subdir-discovery-smoke.py',
  'display_argv': ['python3', 'examples\\canary\\smoke-suite-subdir-discovery-smoke.py'],
  'script': 'examples\\canary\\smoke-suite-subdir-discovery-smoke.py'}}]}
# assert 'examples\\canary\\smoke-suite-subdir-discovery-smoke.py' == 'examples/canary/smoke-suite-subdir-discovery-smoke.py'

$ python examples/canary/smoke-suite-runner-smoke.py
KeyError: 'examples/canary/canary-promotion-readiness-smoke.py'   # by_script is keyed by the host-spelled script field

$ python examples/canary/catalog-run-e2e-smoke.py
AssertionError: {'...': 'normalized': {'command': 'python3 examples/control_plane/promotion-readiness-readmodel-smoke.py',
  'display_argv': ['python3', 'examples\\control_plane\\promotion-readiness-readmodel-smoke.py'],
  'script': 'examples\\control_plane\\promotion-readiness-readmodel-smoke.py'}}

$ python examples/canary/premerge-validation-gate-smoke.py
AssertionError: 'python3 examples/control_plane/interaction-contract-state-machine-smoke.py' not in
  [..., 'python3 examples\\control_plane\\interaction-contract-state-machine-smoke.py', ...]

Note the payload is internally inconsistent: normalized.command keeps the declared POSIX form while normalized.display_argv and normalized.script carry the host separator, so any consumer that joins display_argv or keys on script disagrees with the check's own declared command. tests/test_smoke_suite.py already keys pytest ids on normalized["script"], so the ids differ per host there too.

Sanitized diagnostics

$ python --version
Python 3.12.12
$ loopx canary premerge --changed-file loopx/quota.py --profile canary-runner --no-progress --format json
gate: failed (preview_only); risk_profile_run: selected 8, failures 3

The three failures are examples/canary/catalog-run-e2e-smoke.py, examples/canary/premerge-validation-gate-smoke.py and examples/canary/smoke-suite-runner-smoke.py; each fails identically at the base revision and with no local changes. Other checks that failed on this host during the same run (examples/control_plane/hot-path-interface-budget-smoke.py, examples/control_plane/claude-goal-mode-hook-policy-smoke.py style POSIX-shim cases) are separate, pre-existing host failures and are not part of this report.

Additional context

  • Sibling, already-merged work: fix(benchmark): run the EdgeBench report adapter and suite on native Windows #6368 fixed the same class of "native Windows cannot run the documented check" gap for the EdgeBench report adapter, and recorded these two canary smokes in its own PR body as pre-existing host failures.
  • The contract this report relies on: the catalog's declared commands, loopx/canary/runner.py::_smoke_script_check, the four shipping smokes above, and the repo-relative POSIX convention used by loopx/canary/maintainability_ratchet.py and the CI workflows.

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