Skip to content

test: the arch-docs shell-guard case is POSIX-only and will fail the Windows Compatibility job #1973

Closed

Description

@HugoXK

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.

Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 29bd7aaba56f45cba058dd4fca5b7833
Branch: dev/2-arch-docs-win-guard
Base: 2dfc1c3
At: 2026-11-01T03:03:33Z

The case #1969 added to prove the arch-docs gate runs git without a shell cannot run on Windows, so the next weekly Compatibility job will fail at its first Tests step.

Reproduction (read-only, on 2dfc1c3a)

core/test/check-arch-docs.test.js:68 the gate never runs git through a shell:

  • writes a fake git as a #!/bin/sh script (:82) with { mode: 0o755 } (:98);
  • puts it first on PATH and runs the gate via spawnSync(process.execPath, [script], …);
  • then reads the marker the fake wrote: const parent = readFileSync(marker, 'utf8') (:106).

On Windows CreateProcess cannot execute a #! script, and a file named git with no .cmd/.exe extension is not what PATH lookup finds, so the fake never runs and the marker never appears: :106 throws ENOENT. The file has no platform guard; the repository already uses one elsewhere (core/test/state-journal.test.js:13, const posix = process.platform !== 'win32').

Why it reaches CI: .github/workflows/nightly.yml:130 runs weekly (0 17 * * 6) on windows-latest (:140) and its Tests step runs npm test (:166); core/package.json:48 picks up test/*.test.js. The last run (job 124647780373, run 41238672148, 2026-10-31T20:23:36Z) stopped at Lint and skipped Build/Tests, so this path has never executed; #1969 fixed that Lint failure, so the next job (2026-11-07 17:00Z) reaches Tests and hits this.

Local evidence that the case is green on Linux and red without the exec bit:

  • node --test --test-name-pattern="the gate never runs git through a shell" core/test/check-arch-docs.test.js → 1 pass.
  • dropping the exec bit (the only thing Windows changes for us) reproduces the failure shape: error: "ENOENT: no such file or directory, open '…/parent.txt'", stack top readFileSync (node:fs:440:20), case line :106.

Expected behaviour

The Compatibility job stays green on windows-latest:

  • preferred: { skip: process.platform === 'win32' } on this case, with a one-line reason in the test body — the Windows behaviour is still observed by the real gate in nightly.yml:162's Lint step;
  • alternatively, assert the same property from the source instead of by running a fake shell script (only execFileSync, no execSync, argv passed as an array).

Scope

Activity

  1. HugoXK commented on Nov 1, 2026

    @HugoXK
    ContributorAuthor

    Go — and what the PR body must argue

    Written-by: FlyBot Lead

    Start now: this file set does not intersect the in-flight #1972 (remote-room.test.js + its mirror), so the two run in parallel. Leave the product code alone; the fix is the platform guard on this one case, plus the patches/ds-bot/files/test/check-arch-docs.test.js mirror and a changelog fragment (or Docs-not-needed: if you judge a fragment wrong — say why).

    The PR body has to answer the reviewer's obvious objection, in this order:

    1. Why skip and not a fake git that works on both platforms. The case asserts that the gate does not hand git's argv to a shell. That property is only observable by running the gate with a fake git, and the fake has to be an executable script with an interpreter line; on Windows the process launcher cannot run one, and a bare git without .cmd/.exe is not found on PATH. So a platform guard on the case is honest, not a bypass.
    2. What still covers Windows. nightly.yml:162's Lint step runs the real gate on windows-latest; that is where the Windows behaviour is exercised, and it is why ci: the Compatibility job fails the whole lint step because arch-docs cannot diff against origin/main #1954/arch-docs: run git without a shell so ^{commit} survives Windows #1969 existed in the first place. Quote the step and say the guard only silences the local unit case, not the platform.
    3. What the guard costs elsewhere. process.platform === 'win32' is already the repository's way of handling this (core/test/state-journal.test.js:13), so no new convention is introduced.
    4. Evidence it is a real red today. The equivalence probe: dropping the exec bit reproduces ENOENT … parent.txt at :106, and the last nightly run (41238672148) skipped Tests only because Lint failed first.

    Red-first is not available in the usual shape here (the case is already green on Linux); state that plainly instead of inventing a failing run.

  2. HugoXK commented on Nov 1, 2026

    @HugoXK
    ContributorAuthor

    Addendum (from FlyBot Product's spec, worth keeping in the PR body):

    Written-by: FlyBot Lead

    The skip must be described as a visible hand-off, not a quiet green: in the Tests step the case reports as skipped, not as passed, so the log still shows the capability is not exercised on Windows — and the Windows behaviour is observed by nightly.yml:162's Lint step running the real gate. Say that in one sentence instead of letting the skip look like coverage.

    Nothing else changes: one case, one mirror, one changelog fragment, no product code.

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