Skip to content

fix(context): order prereleases and build metadata correctly - #107

Merged
moshest merged 1 commit into
mainfrom
claude/review-open-prs-2el8ix
Aug 5, 2026
Merged

fix(context): order prereleases and build metadata correctly#107
moshest merged 1 commit into
mainfrom
claude/review-open-prs-2el8ix

Conversation

@moshest

@moshest moshest commented Aug 5, 2026

Copy link
Copy Markdown
Member

Two bugs in the version comparator shipped in 1.2.1, found by an independent review of #105 run after it merged. Both make a bare package name resolve to the wrong installed version.

1. 2.0.0-rc.10 ranked below 2.0.0-rc.2

installed: 2.0.0-rc.2, 2.0.0-rc.10
context query pkg   ->  serves 2.0.0-rc.2

Numeric segments were compared numerically, but the prerelease suffix still went through a plain text comparison — so "rc.10" < "rc.2". That is precisely the inversion #102 was about, surviving one field deeper in the same function that fixed it.

Identifiers are now compared one at a time, numerically where both are numbers, with a shorter run sorting lower (semver §11).

2. 1.0.0+20130313144700 ranked below 0.0.1

installed: 0.9.0, 1.0.0+20130313144700
context query pkg   ->  serves 0.9.0

Only a - prerelease was stripped before parsing, so build metadata left the last segment as 0+20130313144700. That fails the numeric test, which classified the entire version as having no numeric part and dropped it into the bucket reserved for floating labels like latest — deliberately below every real release. A package installed at a semver-legal version became unreachable by bare name, silently serving older documentation.

Build metadata is now stripped before parsing, as it carries no ordering meaning (semver §10).

Verification

Both reproduced against the shipped build before fixing, in both insertion orders, then confirmed fixed.

The comparator is still a total order — the property that keeps results independent of filesystem order, which was the whole point of #102:

24-version pool (leading zeros, v-prefix, >MAX_SAFE_INTEGER segments,
prereleases, build metadata, latest/main, empty, whitespace, non-ASCII)
  reflexivity   0 violations
  antisymmetry  0 violations
  transitivity  0 violations   (13,824 triples)
  list() drift  0 across 300 shuffles

Both new tests are mutation-verified: reverting the prerelease fix fails only the prerelease test, reverting the build-metadata fix fails only the build-metadata test.

pnpm lint    ✓
pnpm build   ✓
pnpm test    ✓  221 + 39 passed

Why this exists

#105 merged without an independent review — the reviewer died on a session limit while a nightly job had been failing five nights, and I judged the trade worth it. This is the second batch of defects from that call; the first was #106. The review has now run against the shipped code, and it confirmed the rest is sound: no data loss in context remove (including scoped names like @trpc/server), --libs agrees across CLI and MCP server, and openDb cannot serve a different version than the caller resolved.


Generated by Claude Code

Two ways a bare name still resolved to the wrong installed version, both
found reviewing 1.2.1 after it shipped.

`2.0.0-rc.10` ranked below `2.0.0-rc.2`: the prerelease suffix was compared
as text, which is the same inversion that made `1.15.10` lose to `1.15.9` —
one field deeper. Identifiers are now compared one at a time, numerically
where both are numbers, with a shorter run sorting lower per semver §11.

`1.0.0+20130313144700` sorted below every real release including `0.0.1`:
build metadata left the last segment non-numeric, so the whole version was
classified as having no numeric part and dropped into the bucket meant for
floating labels like `latest`. It is now stripped before parsing, since it
carries no ordering meaning.

Comparator remains a total order: 0 reflexivity, antisymmetry or
transitivity violations over a 24-version pool, and `list()` output is
unchanged across 300 shuffles.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBQQpA86yYzwJUiVz8ph2R
@changeset-bot

changeset-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b0c3793

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@neuledge/context Patch
@neuledge/registry Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@moshest
moshest merged commit 8457c0b into main Aug 5, 2026
3 checks passed
@moshest
moshest deleted the claude/review-open-prs-2el8ix branch August 5, 2026 02:44
@github-actions github-actions Bot mentioned this pull request Aug 5, 2026
moshest pushed a commit that referenced this pull request Aug 5, 2026
Release @neuledge/context@1.2.2 — prerelease and build-metadata version
ordering (#107).
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.

2 participants