Versioning and Release-Line Policy

August 31, 2026 ยท View on GitHub

Current Release Line

v2.0.0 is the current stable Base Bash release, backed by its verified canonical GA asset. v1.4.0 and earlier releases are historical references; the 5/5 initiative has one stable target and will not create a stable v1.5.0 or reset the version to 0.x.

Those choices would either hide breaking changes inside the current 1.x compatibility range or move version precedence backward.

Post-GA releases use one repository-owned v2 SemVer policy:

2.MINOR.PATCH
2.MINOR.PATCH-alpha.N
2.MINOR.PATCH-beta.N
2.MINOR.PATCH-rc.N

MINOR and PATCH are non-negative canonical decimal integers; N starts at 1 and has no leading zeroes. Build metadata and prerelease channels other than alpha, beta, and rc are not accepted by the release workflow. Prereleases do not receive compatibility shims. The stable SemVer compatibility contract began at v2.0.0 GA.

After GA, v2 is the only supported release line. Versions through v1.4.0 remain available as historical releases but no longer receive fixes or support. Additive features and fixes remain within 2.x; a breaking stable API change requires v3 or later.

Release Gates

The repository-owned scripts/release command is the mandatory entry point for every release inspection and publication attempt. It sources scripts/release-version-policy.sh before delegating read-only operations and dry runs to Base's guarded release command. The artifact builder and repository validation source the same policy.

Prerelease publication became available because #233 and the follow-up release-artifact contract landed. The reviewed v2.0.0-rc.1 artifact and the pre-GA work in #240 validated and rehearsed the exact release candidate across Base, Base Demo, Homebrew, vendored, and bundled paths. The canonical v2.0.0 archive, checksum manifest, SBOM, and provenance are now published and the first-party handoff is complete; future releases must preserve the same verified-asset contract.

The release policy is code reviewed, not an environment-variable or sentinel-file override. Maintainers can inspect any candidate without changing GitHub state:

scripts/release check --version 2.1.0 --manifest base_manifest.yaml
scripts/release plan --version 2.1.0 --manifest base_manifest.yaml
scripts/release publish --version 2.1.0 --manifest base_manifest.yaml --dry-run

The generic basectl release command is not a substitute for this guard. Its current manifest contract does not encode this repository's release line, artifact, provenance, or GA gates.

Before any real publication attempt, run the repository-owned tag preflight:

scripts/release refs --version 2.1.0

The preflight checks both the exact candidate tag in the local checkout and the same tag on origin. It fails closed when Git cannot inspect either side or when the tag is already present. Published tags are immutable; a stale local tag may be removed only after confirming that the remote ref is absent and that the local object is the withdrawn July 2026 commit documented below.

Withdrawn July 2026 Event

On July 2, 2026, PR #100 created commit 2d90249 with v2.0.0 metadata. A corresponding Homebrew PR #66 used GitHub's automatic tag-archive URL.

The next day, PR #103 and commit 6ce8af0 corrected the release line to v1.1.0. Homebrew PR #68 corrected the formula and added version_scheme 1 so Homebrew would accept the version-order correction.

The attempted v2.0.0 remote tag and GitHub Release are no longer present. The commits and pull requests remain part of the public history, and caches of the old automatic archive may still exist. The final v2 release therefore uses a newly verified canonical release asset rather than that automatic archive. The project will never silently retag or represent the withdrawn artifact as the final release.

Older local clones can retain the deleted lightweight tag. Inspect both sides before removing a stale local ref:

git ls-remote --tags origin refs/tags/v2.0.0
git show-ref --verify refs/tags/v2.0.0

If the remote command has no output and the local command finds the withdrawn ref at 2d90249eec35aa00d04513294ce0fb09042c3f3f, remove only that local tag:

git tag -d v2.0.0

Immutable Consumption

The complete checkout, archive, Homebrew, vendored, and standalone verification procedure is maintained in pinned-consumption.md.

Do not install from an unpinned default-branch checkout. Use the canonical v2.0.0 release asset and verify its checksum, or pin the stable source to the full commit resolved from the signed v2.0.0 tag:

git clone https://github.com/basefoundry/base-bash-libs.git vendor/base-bash-libs
git -C vendor/base-bash-libs checkout --detach \
  b4243765726c133499feeabdc50154f99c0fec12
test "$(git -C vendor/base-bash-libs rev-parse HEAD)" = \
  b4243765726c133499feeabdc50154f99c0fec12

Prerelease validation must likewise use an immutable prerelease tag resolved to its expected commit, a verified release asset, or a full commit. Release notes, bug reports, and CI fixtures should record the resolved commit in addition to the human-readable version.