fix: exclude unshared prereleases from range intersections - #901
ryanchou1994 wants to merge 1 commit into
Conversation
|
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 Baseline:
With PR #901:
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. |
intersects('>1.0.0 <2.0.0', '^2.0.0-0')currently returnstrue, although no version satisfies both ranges with the default prerelease rules. WithincludePrerelease: true,2.0.0-0is a valid intersection and the result should remaintrue.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: falsecase. The change is limited toRange.intersects; it does not change version ordering, the existing shared-prerelease path, or address every known intersection defect.Validation:
--jobs=2for its two-CPU allocation.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.