Skip to content

fix: exclude unshared prereleases from range intersections - #901

Open
ryanchou1994 wants to merge 1 commit into
npm:mainfrom
ryanchou1994:fix/intersects-prerelease-gap
Open

ryanchou1994 wants to merge 1 commit into
npm:mainfrom
ryanchou1994:fix/intersects-prerelease-gap

Conversation

@ryanchou1994

Copy link
Copy Markdown

intersects('>1.0.0 <2.0.0', '^2.0.0-0') currently returns true, although no version satisfies both ranges with the default prerelease rules. With includePrerelease: true, 2.0.0-0 is a valid intersection and the result should remain true.

This adds a check after the existing comparator-set intersection succeeds. If both sets do not opt into a common prerelease tuple, their intersection must contain a stable version. Check the least possible stable version against each original set separately, preserving each set's prerelease permissions. This also covers empty gaps between adjacent stable versions and numeric-component rollover.

Related to #345 and its requested includePrerelease: false case. The change is limited to Range.intersects; it does not change version ordering, the existing shared-prerelease path, or address every known intersection defect.

Validation:

  • New regression tests fail against the original code and pass with this change, including both argument orders, loose mode, OR ranges, option handling and unchanged parsed comparators.
  • Full tests, lint and postlint pass on macOS and Linux: 51 test files and 100% coverage in all four measures. Linux used --jobs=2 for its two-CPU allocation.
  • Node 10.0.0 and 10.24.1 each pass 874 additional entry-point/fixture assertions.

The extra check has a measurable cost: a five-round Linux microbenchmark measured public calls at 1.04–1.38× baseline. The smallest prebuilt-Range case was 9.9→31.1 ms per 100,000 calls (about 0.21 µs extra per call). No cache or tooling changes are included.

Copilot AI lite review requested due to automatic review settings September 9, 2026 17:45
@ryanchou1994
ryanchou1994 requested a review from a team as a code owner September 9, 2026 17:45

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shumoku88-bit

Copy link
Copy Markdown

I independently checked this PR against a range-intersection oracle in Semverifier whose witness search is proved sound and complete in Lean:

https://github.com/shumoku88-bit/semverifier

I ran the same deterministic 202 × 202 range corpus (40,804 ordered pairs) against node-semver 7.8.5/current main and against this PR at 7a597a93b2feb62696f94e4df9533363eaf8f98a.

Baseline:

  • 4 false negatives
  • 90 false positives
  • 34 asymmetric unordered pairs

With PR #901:

  • 4 false negatives
  • 0 false positives
  • 0 asymmetric unordered pairs

So, on this corpus, #901 removes all 90 previously observed false-positive rows and all 34 asymmetries, with no new disagreement observed.

The four remaining false negatives are a separate prerelease/set-level issue related to the behavior discussed in #884, so I did not treat them as regressions from this PR.

The audit is recorded here:

https://github.com/shumoku88-bit/semverifier/blob/main/docs/NODE_SEMVER_PR_901_AUDIT.md

The Semverifier work and this validation used substantial AI assistance. I’m sharing this only as independent supporting evidence, not as a claim that #901 is proved correct for every possible node-semver input.

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