Repository navigation
Description
Summary
Version-range resolution in 0.2.1 can select a prerelease at the next major or minor boundary even when the requested range uses only stable versions.
For example, --from 1.0.0 can select 2.0.0-alpha.1 instead of an available 1.x stable release.
Code evidence at b742a99:
- Sources/Core/ProcessRunner.swift:213–229 constructs the major, minor, and explicit range bounds.
- Sources/Core/ProcessRunner.swift:251–268 filters only by >= lowerBound and < upperBound.
- Sources/Core/SourceRequirement.swift:127–152 correctly orders a prerelease before the corresponding stable release, but range eligibility has no separate prerelease policy.
git diff v0.2.0 v0.2.1 shows that PR #2, merged as e0ea185, introduced prerelease-aware ordering without changing the range filter. Previously, 2.0.0-alpha.1 was compared as 2.0.0 and excluded at the upper bound.
Related PR: #2
Impact: an existing stable-range request can begin installing a next-major or next-minor prerelease after upgrading the CLI.
Reproduction
Proposed steps; not executed for this report.
-
In a fresh temporary directory, create a Git repository containing SKILL.md with valid frontmatter:
--- name: demo description: Version range fixture ---
-
Commit the file and create tags 1.0.0, 1.5.0, and 2.0.0-alpha.1. They may all reference the same commit: the selected version alone demonstrates the defect.
-
Create a separate empty project directory and run:
skill add <absolute-temporary-source-path> \ --from 1.0.0 --scope project --agent codex --mode copy cat .agent/skills.resolved
-
Inspect pins[].state.version.
Additional boundary cases:
- Tags 1.0.0, 1.0.5, 1.1.0-alpha.1 with --up-to-next-minor-from 1.0.0.
- The same tags with --from 1.0.0 --to 1.1.0.
Use fresh project directories for independent cases.
Expected Behavior
A stable-only range excludes prerelease candidates and selects the highest eligible stable release: 1.5.0 in the major-range example and 1.0.5 in the minor-range examples.
If no eligible stable tag exists, report no matching version rather than silently opting into prereleases.
Keep SemVer comparison correct and preserve exact prerelease selection. Define range membership separately from ordering. Explicit prerelease-range behavior should remain covered and documented.
Completion checks:
- Cover stable-only major, minor, and explicit ranges with boundary prereleases.
- Preserve --exact prerelease/build-specific selection and existing explicit prerelease tests.
- Run swift test.
Actual Behavior
The current comparisons admit 2.0.0-alpha.1 because it is greater than 1.5.0 and less than 2.0.0. The resolver selects it and records it in state.version.
This is a range eligibility regression, not an incorrect SemVer sort order.
Tests/CoreTests/InstallWorkflowTests.swift:374–378 covers an explicitly prerelease range; lines 381–441 cover stable tags. Neither fixture covers stable-only ranges with prerelease candidates.
No duplicate issue was found. PR #2 is related history, not a fix for this regression; issue #4 is unrelated.
Environment
- skill version: 0.2.1; regression identified by comparison with v0.2.0.
- Source inspected: b742a99.
- Swift version: not obtained in the read-only sandbox.
- OS: macOS 27.0.1 (26A434).
- Architecture: arm64.
- Validation: static inspection and Git history comparison; reproduction not executed.
Decision needed
Define the prerelease policy for stable ranges. Proposed: stable ranges exclude prereleases by default; an explicit prerelease request is defined separately. Apply the rule in candidate admission, keeping correct SemVer ordering and exact-version support.
Activity