Skip to content

fix(release)!: the 0.x version scheme hits the MSI 255 ceiling -- 3 legal versions left, 6 PRs already unbuildable #522

Description

@MichaelTaylor3d

Task

dig-node is three merges away from being unable to release at all. Every native package build
validates the version through scripts/package-version.sh, which caps the MSI ProductVersion fields
at MAJOR <= 255, MINOR <= 255, PATCH <= 65535. The repo versions as 0.<minor>.<patch> with
the ever-incrementing counter in the minor field, so the scheme runs out at 0.255.x.

origin/main is at 0.252.4. Three legal minor slots remain — 0.253, 0.254, 0.255 — and all
three are already claimed by open PRs. After they merge, every subsequent PR fails four required
checks and no package can be built.

This is not a forecast. It is already happening.

Measured now

Six open PRs claim an unbuildable version and are red at the package gate today:

PR version buildable
#505 0.256.0 NO
#517 0.257.0 NO
#516 0.258.0 NO -> fixed here, retaken as 0.252.5
#515 0.262.0 NO
#519 0.263.0 NO
#518 0.264.0 NO

The three legal slots left, all claimed: #501 (0.253.0), #509 (0.254.0), #514 (0.255.0).

Failure, identical across .deb (linux-amd64), .deb (linux-arm64), .pkg (macos-universal) and
.msi (windows-x64) — run
33704504183:

package-version: minor version 258 exceeds the MSI ProductVersion limit of 255

Context

scripts/package-version.sh:70-72 is the gate, and it is correct — it should not be weakened.
Windows Installer either rejects an out-of-range ProductVersion field or silently truncates it,
which would make two different versions compare EQUAL and break the upgrade invariant that
packaging/windows/dig-node.wxs (AllowSameVersionUpgrades="yes") holds jointly with it (SPEC
11.5c). Its own comment already anticipated this exact wall:

Checked for BOTH channels - a stable 0.256.0 is just as unbuildable as a nightly one.

So the defect is not the validator. The defect is a release scheme that increments the one field
with a 255 ceiling
, while the patch field with 65535 of headroom stays at .0 on nearly every
release. dig-node has cut ~250 minor versions and is consuming the field roughly one per merge.

Scope

The deliverable is a version scheme that cannot run out, plus the migration of the six red PRs.
Options to weigh (this ticket does not pre-decide between them):

  1. Reset to 1.0.0. Buys 255 more minors, but only defers the same wall and asserts an API
    stability claim as a side effect of a packaging limit, which is the wrong reason to declare 1.0.
  2. Move the counter to the PATCH field — release as 0.253.<n> with 65535 of headroom. Smallest
    change, and correct SemVer for the fix-shaped commits that make up most releases anyway
    (CLAUDE.md 2.4: fix->patch, feat->minor). Note most of the six red PRs took a MINOR for a
    fix, which is what burned the field this fast.
  3. Map in package-version.sh — keep the marketing version and synthesize a legal, monotonic
    ProductVersion, as the nightly path already does with days-since-2020. Preserves the existing
    scheme but adds a second mapping that must stay monotonic forever.

Whichever lands, monotonicity is the invariant that cannot break: msiexec compares only
major.minor.build, so any mapping must be strictly increasing across every future release or
in-place upgrades silently stop working.

Evidence bar

Not done until a package build actually goes green on the chosen scheme, on all four targets, and a
test in scripts/tests/package-version.test.sh pins the ceiling behaviour so the next wall is a red
test rather than four red builds.

Not in scope

The absence_established fix on #516 that surfaced this. That PR retook 0.252.5 — a patch off
main, legal, correct SemVer for a fix, and deliberately NOT consuming one of the three remaining
minor slots.

Parent

Surfaced from #508. Needs a dig_ecosystem
orchestrator parent
per the no-orphans rule — it is release infrastructure rather than content
discovery, so dig_ecosystem#3128 is not the right epic. Flagged to the orchestrator.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:businessa person can DO something new, or money moves, or a shipped surface stops lying to them

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions