ReviewOS

also looking at this

stacks/buddy

refactor: one update-type classifier, with the edge cases decided instead of accidental

#1439
Merged glennmichael123 wants to merge refactor/one-update-type into main
4 files +108 -116
8 days ago

Flagged in #1438: the codebase carried three parallel implementations of update-type classification — utils/helpers.getUpdateType (the one live paths import), a private Buddy.getUpdateType, and VersionResolver.getUpdateType. A three-reader workflow mapped their exact semantics, a synthesis produced a difference table, and two adversarial verifiers reproduced every claimed disagreement by executing all three against the real source (24-case matrix, zero refutations).

Where they disagreed, and what won

InputhelpersBuddy (private)VersionResolverDecided
v4 → v4.2.2patch ❌minorminorminor — Bun.semver.order('4.2.2','4') is -1, so helpers' upgrade guard misread a real bump as a downgrade
v1.0.0 → v2.0.0majormajorpatch ❌major — the resolver never stripped v, so a breaking change vanished
1.0.0-beta.1 → 1.0.0major ❌patchpatchpatch — helpers' major was an accidental fall-through that let excludeMajor block a beta graduation
latest → 1.0.0patchpatchmajor ❌patch — the resolver fabricated major from NaN parts
3.19-alpine → 3.20-alpineminorpatch ❌patch ❌minor — only helpers read the numeric core; the others returned patch as a failure artifact

The consolidation

  • helpers.getUpdateType is canonical — amended with numeric-only pad-to-3 before the semver guard (fixes short tags; suffixed tags deliberately pass through untouched), a patch fall-through instead of major (fixes prerelease movement), and its dead semver.satisfies fallback catch removed (nothing in that try block could throw).
  • Buddy's private copy is deleted; its three call sites (deps.yaml, GitHub Actions, Dockerfile scans) rebind to the already-imported helper. The verifier confirmed no behavioral change on the numeric/prerelease shapes those paths pass — except the deliberate suffixed-tag fix.
  • VersionResolver.getUpdateType delegates, keeping the package-root export source- and type-compatible.

Deliberate behavior deltas on live paths

  • GH Actions short-tag bumps (v4 → v4.2.2) stop reading as patch — an auto-merge conditioned on patch-only no longer waves them through.
  • Prerelease graduations stop reading as major — excludeMajor stops blocking them.
  • Suffixed Docker tag bumps classify by their numeric core (minor/major), so a patch strategy now correctly excludes them.

Tests

New matrix in test/version-classification.test.ts pins every decided case, plus a parity check that VersionResolver answers identically. bun test: 2232 pass / 0 fail; typecheck and pickier green. All pre-existing assertions in both version suites pass unchanged.

🤖 Generated with Claude Code

4 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.