Skip to content

fix(ci): resolve Windows script-spec separator/mocked-path class (pm-s5pe) - #317

Merged
unbraind merged 3 commits into
mainfrom
fix/windows-script-spec-separator-class
Jun 20, 2026
Merged

unbraind merged 3 commits into
mainfrom
fix/windows-script-spec-separator-class

Conversation

@unbraind

Copy link
Copy Markdown
Owner

Summary

Closes the residual windows-latest failures pm-dita (#316) left behind. After the shebang SyntaxError class was eliminated, the remaining ~28 failures across five tests/unit/scripts/** specs were a distinct, pre-existing path-separator / mocked-path class (tracked in pm-s5pe).

The gate scripts are already Windows-correct — static-quality-gate normalizes every reported path via relativeToRepo, and docs-skills-gate builds its logical relative paths with path.posix. Only the specs mismatched native vs POSIX separators. Every change here is test-only + CI; there is zero production change.

Failure classes & fixes

Spec Root cause Fix
static-quality-gate (walkFiles, resolveRelativeImport, checkOrphanSourceModules) POSIX-keyed node:fs mocks never match the drive-lettered backslash candidates real node:path builds on Windows (C:\repo\src\dep.ts vs /repo/src/dep.ts) new harness.mockPosixPath() forces node:path → path.posix in the three mocked-fs helper tests — the inverse of the existing runtime-schema-path-win32-guard; node:path added to the harness builtinUnmocks
docs-skills-gate (collectMarkdownFiles) readdir mock keyed on /docs while the gate passes native absolute paths normalize separators in the mock comparison
bundle-cli + contracts-snapshot stringContaining("dist/cli.js") / ("tests/fixtures/contracts/full.json") compared against the script's native-separator output compare against path.join(...) so the expectation matches per host
smoke-npx-from-pack mocks keyed on bare npm/npx, but resolveCommand appends .cmd on win32 → npm pack returns empty → "npm pack did not produce a tarball name" baseCommand() strips a trailing .cmd in all mocks

CI hardening

Re-broadened the per-PR windows-regression job from a hand-picked subset to the full tests/unit/scripts/ directory (plus the two non-scripts guards), and locked the command in ci-workflow-contract.spec.ts. A fresh Windows-only script regression now fails a required per-PR check rather than only the nightly. (Acceptance criteria from pm-s5pe.)

Verification (Linux)

  • 4774 tests pass; coverage literal 100/100/100/100
  • quality:static, docs-skills-gate --links-only, contracts:check, security:scan green
  • isolated temp-dir smoke (init/create/update/list/close/validate) clean

mockPosixPath() forces POSIX on every host, so the Linux helper-test run reproduces the Windows execution path exactly; the windows-regression job is the final Windows oracle.

🤖 Generated with Claude Code

…s5pe)

After pm-dita (#316) eliminated the shebang SyntaxError class, the residual
windows-latest failures across five `tests/unit/scripts/**` specs were a
distinct, pre-existing path-separator / mocked-path class. The gate scripts
themselves are already Windows-correct (static-quality-gate normalizes every
reported path via `relativeToRepo`; docs-skills-gate builds logical paths with
`path.posix`); only the specs mismatched native vs POSIX separators. All fixes
are test-only + CI — zero production change.

Failure classes and fixes:

1. static-quality-gate (`walkFiles`, `resolveRelativeImport`,
   `checkOrphanSourceModules`): POSIX-keyed `node:fs` mocks never match the
   drive-lettered backslash candidates real `node:path` builds on Windows
   (e.g. `C:\repo\src\dep.ts` vs `/repo/src/dep.ts`). Added
   `harness.mockPosixPath()` to force `node:path` → `path.posix` in those three
   mocked-fs helper tests — the inverse of the existing
   `runtime-schema-path-win32-guard`. Registered `node:path` in the harness
   `builtinUnmocks` so it is leak-free.

2. docs-skills-gate (`collectMarkdownFiles`): the `readdir` mock keyed on
   `/docs` while the gate passes native absolute paths; normalize separators in
   the mock comparison.

3. bundle-cli + contracts-snapshot: `stringContaining("dist/cli.js")` /
   `("tests/fixtures/contracts/full.json")` assertions compared against the
   script's native-separator output; compare against `path.join(...)` so the
   expectation matches per host.

4. smoke-npx-from-pack: `execFileSync` mocks keyed on bare `npm`/`npx`, but the
   script's `resolveCommand` appends `.cmd` on win32, so `npm pack` returned
   empty and every case failed with "npm pack did not produce a tarball name".
   Added `baseCommand()` to strip a trailing `.cmd` in all mocks.

Re-broadened the per-PR `windows-regression` job to the full
`tests/unit/scripts/` directory (plus the two non-scripts guards) and locked
the command in `ci-workflow-contract.spec.ts`, so a fresh Windows-only script
regression now fails a required per-PR check rather than only the nightly.

Verified on Linux: 4774 tests pass, coverage literal 100/100/100/100,
quality:static + docs-skills + contracts:check + security:scan green, isolated
temp-dir smoke (init/create/update/list/close/validate) clean. `mockPosixPath`
forces POSIX on every host, so the Linux helper-test run reproduces the Windows
path exactly; the windows-regression job is the final oracle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WiNZNrE3rjftCC1udbBLGt
@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@unbraind

Copy link
Copy Markdown
Owner Author

/gemini review

@unbraind

Copy link
Copy Markdown
Owner Author

@codex review

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @unbraind, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jun 20, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request resolves Windows-specific test failures caused by path separator mismatches and mocked-path issues. Key changes include introducing a mockPosixPath() helper in the test harness to force POSIX path semantics on node:path during mocked filesystem tests, normalizing directory separators in the docs-skills-gate spec, using path.join for native path assertions in bundle-cli and contracts-snapshot specs, and stripping the .cmd suffix from commands in smoke-npx-from-pack mocks. Additionally, the windows-regression CI job has been broadened to cover the entire tests/unit/scripts/ directory. There are no review comments, so no feedback is provided.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request resolves several Windows-specific test failures caused by path-separator mismatches and mocked-path issues. It introduces a mockPosixPath helper in the script harness to force POSIX path semantics in unit tests that use POSIX-keyed filesystem mocks. Additionally, it normalizes directory separators in docs-skills-gate.spec.ts, uses native path.join for path assertions in bundle-cli.spec.ts and contracts-snapshot.spec.ts, and strips the .cmd suffix from commands in smoke-npx-from-pack.spec.ts mocks. Finally, the Windows regression CI job is expanded to run all script unit tests. There are no review comments, so I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

…ock (pm-s5pe)

Broadening the windows-regression job to the full tests/unit/scripts/ directory
surfaced a second Windows-only class the nightly had under-reported: three
docs-skills-gate specs that the original pm-s5pe triage missed.

1. Line endings (the two real-fs + the seeded-fixture full-mode tests): with no
   `.gitattributes`, a windows-latest checkout converts tracked text files to
   CRLF, so the gate reads real SKILL.md files as `---\r\n` and
   `extractFrontmatter`'s `startsWith("---\n")` delimiter check fails, reporting
   valid skills as missing frontmatter. Added a repo-root `.gitattributes`
   (`* text=auto eol=lf`) so every platform checks out text files with LF,
   matching Linux/macOS. The repo is POSIX-authored with zero CRLF files today,
   so there is no renormalization churn.

2. Mocked SKILL.md path (the two full-mode mock tests): the `readFile` mock keyed
   on `/.agents/skills/<name>/SKILL.md` with forward slashes only, so on Windows
   the gate's native backslash path missed the regex and fell back to non-skill
   content. Normalize separators before matching.

Verified on Linux: docs-skills-gate + harness + ci-workflow-contract specs pass;
the production gate scripts are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WiNZNrE3rjftCC1udbBLGt
@unbraind

Copy link
Copy Markdown
Owner Author

Pushed follow-up commit (fcf0c12): the broadened windows-regression job exposed a second class — CRLF line endings (no .gitattributes) breaking docs-skills-gate's extractFrontmatter on Windows checkout, plus a forward-slash-only SKILL.md mock regex. Fixed via repo-root .gitattributes (LF normalization) + separator-agnostic mock. Re-requesting reviews. @coderabbitai full review

@unbraind

Copy link
Copy Markdown
Owner Author

/gemini review

@unbraind

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jun 20, 2026 •

Copy link
Copy Markdown

@unbraind Acknowledged — triggering a fresh full review to cover the follow-up commit (fcf0c12) with the .gitattributes LF normalization and separator-agnostic SKILL.md mock regex fix.

✅ Action performed

Full review finished.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses several Windows-specific test failures related to path separators, mocked paths, and line endings. Key changes include adding a .gitattributes file to enforce LF line endings across all platforms, introducing a mockPosixPath() helper in the script harness to force POSIX path semantics in tests with POSIX-keyed filesystem mocks, updating hardcoded path assertions to use path.join, normalizing separators in file system mocks, and stripping .cmd suffixes from command names in smoke-npx-from-pack mocks. Additionally, the windows-regression CI job has been re-broadened to cover the entire tests/unit/scripts/ directory. There are no review comments, so no further feedback is provided.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Closes pm-s5pe (Windows script-spec separator/mocked-path + line-endings class)
now that the broadened windows-regression job is green on the windows-latest
oracle. Regenerates CHANGELOG.md from closed tracker state, which also picks up
the previously-undrafted pm-dita (#316) Unreleased entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WiNZNrE3rjftCC1udbBLGt
@unbraind

Copy link
Copy Markdown
Owner Author

Final commit (d816281): closed pm-s5pe and regenerated CHANGELOG.md (also picks up the pm-dita #316 Unreleased entry that fixes the changelog:pm:check gate). The broadened windows-regression job passed green on the prior commit (run 27869550898, job 82479200219). @coderabbitai full review

@unbraind

Copy link
Copy Markdown
Owner Author

/gemini review

@coderabbitai

coderabbitai Bot commented Jun 20, 2026 •

Copy link
Copy Markdown

@unbraind Acknowledged — triggering a fresh full review to cover the final commit (d816281) with the pm-s5pe closure and regenerated CHANGELOG.md. Great to hear the broadened windows-regression job came back green!

✅ Action performed

Full review finished.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request resolves several Windows-specific test failures across various script specifications. Key changes include adding a .gitattributes file to enforce LF line endings (preventing CRLF issues on Windows), introducing a mockPosixPath() helper to the test harness to force POSIX path semantics in tests using mocked filesystems, normalizing path separators in mocks, updating path assertions to use path.join(), and stripping .cmd suffixes from mocked Windows commands. The CI workflow has also been broadened to run the full scripts test suite on Windows. There are no review comments, and I have no additional feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@coderabbitai

coderabbitai Bot commented Jun 20, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jun 20, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@unbraind, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 53 minutes and 12 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 8244886f-656c-411f-b07b-01844681461c

📥 Commits

Reviewing files that changed from the base of the PR and between 0d32922 and d816281.

📒 Files selected for processing (13)
  • .agents/pm/history/pm-s5pe.jsonl
  • .agents/pm/issues/pm-s5pe.toon
  • .gitattributes
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • tests/helpers/scriptModule.ts
  • tests/integration/ci-workflow-contract.spec.ts
  • tests/unit/helpers/scriptModule.spec.ts
  • tests/unit/scripts/bundle-cli.spec.ts
  • tests/unit/scripts/contracts-snapshot.spec.ts
  • tests/unit/scripts/release/docs-skills-gate.spec.ts
  • tests/unit/scripts/release/static-quality-gate.spec.ts
  • tests/unit/scripts/smoke-npx-from-pack.spec.ts
📝 Walkthrough

Walkthrough

Two Windows CI failure classes are fixed: (1) POSIX path separator mismatches in mocked tests, addressed by a new mockPosixPath() harness method, inline backslash normalization in mocks, and .cmd-stripping in smoke-npx mocks; (2) CRLF line-ending failures, fixed via a new .gitattributes enforcing eol=lf. The windows-regression CI job is also broadened to run the full tests/unit/scripts/ directory.

Changes

Windows CI Compatibility Fixes

Layer / File(s) Summary
Repo-wide LF enforcement
.gitattributes
Adds text=auto eol=lf rule with comments to prevent CRLF on Windows checkouts, fixing extractFrontmatter delimiter failures in gate scripts.
mockPosixPath() harness method and unit test
tests/helpers/scriptModule.ts, tests/unit/helpers/scriptModule.spec.ts
Adds mockPosixPath() to ScriptHarness: mocks node:path to return path.posix, adds node:path to the afterEach unmock list, and validates the behavior with a new unit test asserting sep === "/".
Apply mockPosixPath() in static-quality-gate tests
tests/unit/scripts/release/static-quality-gate.spec.ts
Adds harness.mockPosixPath() before resolveRelativeImport, checkOrphanSourceModules, and walkFiles test cases.
Platform-safe path assertions
tests/unit/scripts/bundle-cli.spec.ts, tests/unit/scripts/contracts-snapshot.spec.ts
Replaces hardcoded POSIX path strings in writeFile assertions with path.join(...) calls; removes an unused void path; statement.
Backslash normalization in docs-skills-gate mocks
tests/unit/scripts/release/docs-skills-gate.spec.ts
Normalizes \ to / in three mocked readdir/readFile callbacks before suffix checks and skill-directory regex matching.
.cmd suffix stripping in smoke-npx mocks
tests/unit/scripts/smoke-npx-from-pack.spec.ts
Introduces baseCommand() to strip trailing .cmd, applied in buildExecFileSync and four inline execFileSync mocks so Windows .cmd variants resolve to the same npm/npx branches.
CI windows-regression job broadened + contract locked
.github/workflows/ci.yml, tests/integration/ci-workflow-contract.spec.ts
Changes the scripts/run-tests.mjs invocation from an explicit file list to the tests/unit/scripts/ directory, and updates the workflow contract test to match.
CHANGELOG and agent issue records
CHANGELOG.md, .agents/pm/issues/pm-s5pe.toon, .agents/pm/history/pm-s5pe.jsonl
Adds Unreleased/Fixed CHANGELOG entries for both fixes; updates agent issue to closed with resolution notes, touched-file list, and close reason.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • unbraind/pm-cli#311: Modifies the same windows-regression CI job and ci-workflow-contract.spec.ts assertions around the Windows test command.
  • unbraind/pm-cli#316: Overlaps strongly in the windows-regression CI gating and tests/helpers/scriptModule.ts harness changes for Windows-safe script module imports.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The linked issue #39 addresses agent read-path token efficiency and pm get --full support, which is completely unrelated to this PR's Windows path-separator/mocked-path fixes in test specs. Review and correct the linked issue. This PR fixes Windows CI test failures (pm-s5pe) and should not reference issue #39 which concerns agent command efficiency.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: resolving Windows script-spec separator/mocked-path failures (issue pm-s5pe).
Description check ✅ Passed The description comprehensively explains the Windows CI failures, root causes, specific fixes per test file, CI hardening changes, and verification results. It is directly related to the changeset.
Out of Scope Changes check ✅ Passed All changes are in-scope: test specs, test helpers, CI workflow configuration, .gitattributes, and CHANGELOG. Every change directly addresses Windows path-separator/mocked-path failures or CI hardening as documented.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@unbraind
unbraind merged commit bdd745e into main Jun 20, 2026
16 checks passed
@unbraind
unbraind deleted the fix/windows-script-spec-separator-class branch June 20, 2026 11:44
unbraind added a commit that referenced this pull request Jun 20, 2026
Record final-green CI, bot-review, telemetry, and Sentry verification on the
closed pm-s5pe item after merging PR #317.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WiNZNrE3rjftCC1udbBLGt
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.

1 participant