ADR 0028 — Semver tiers within 0.x; no launch-gated version freeze

  • Status: Accepted (owner ruling 2026-07-17); Amended 2026-07-17 (#244)
  • Date: 2026-07-17
  • Tracking:

Amendment (2026-07-17, #244)

Two changes to the original decision:

  1. 0.x MINOR tier narrowed to breaking-only. The original text said “breaking or feat bumps MINOR”. The amended rule is: only a breaking change (type!: / BREAKING CHANGE) bumps MINOR within 0.x; feat: and every other releasable type (fix/ux/perf) bump PATCH. Post-1.0 mapping is unchanged. The cadence score weights are NOT affected - a feat still scores 3 pts while releasing as a patch.

  2. Daily cap on the hard gate. scripts/release-gate.sh now allows a finish past the hard score threshold when the latest v* tag is younger than RELEASE_GATE_DAILY_CAP_SECS (default 86400 = 24h), emitting an allow decision with a warning that names the daily cap and the score. The existing train-grace (60 min) rule is layered on top; the warning message distinguishes which rule admitted the finish when both apply.

Context

Until now the house rule froze minor and major below 1.0: every 0.x release was a patch bump, breaking changes were allowed to ship as patches, and standard Semantic Versioning was deferred to a future v1.0 launch (the “Pre-public patch versioning” section of the releasing runbook, encoded in release.sh and release-due.sh).

Two things broke that frame on 2026-07-17. First, v0.15.3: a release cut from a range containing nothing but documentation churn - the cadence half of that lesson is fixed by the releasable-scope filter (releasable-count.sh), which keeps doc piles from triggering releases at all. Second, the owner ruling that version numbers should carry meaning now rather than wait for a launch moment: the unreleased backlog held three features and five fixes, and under the freeze both would have shipped indistinguishably as “patch”.

Semver itself requires a declared public API for the tiers to be measurable against, and madtea’s contract already exists in practice: the parity suite freezes CLI/MCP naming, and the tool is in production use.

Decision

Semver tiers apply within 0.x, effective immediately. There is no launch-gated freeze.

  • 0.x: a breaking change (type!: / BREAKING CHANGE) bumps MINOR; feat: and every other releasable commit (fix/ux/perf) bump PATCH. Major stays 0 until a deliberate 1.0 decision - an owner call, never automation.
  • >= 1.0.0: standard SemVer - breaking bumps MAJOR, feat: bumps MINOR, everything else releasable bumps PATCH.
  • The tier is computed from the conventional-commit stream of the unreleased range by release.sh (an explicit vX.Y.Z argument overrides); release-due.sh advertises the same tier in its banner.
  • Declared public API - what “breaking” is measured against: CLI command names, flags, arguments, and exit codes; MCP tool names, actions, and parameter schemas; raw_json output shapes; config keys and env vars; the plugin manifest surface. Human-readable text output, internal packages, docs, and maintainer tooling are NOT part of the public API - their changes never force a tier.
  • Composes with the releasable-scope cadence rule: docs/chore/test/ style/ci commits never trigger a release and never influence the tier.

Consequences

  • Version numbers are informative immediately: a 0.x minor bump signals a breaking change; a patch is a safe upgrade (features included) - consumers pinning a 0.x minor get the protection semver can offer below 1.0.
  • Pre-1.0 breaking changes surface as minor bumps (the 0.x custom), not majors; features and fixes ship as patches; release notes remain the authoritative account of any break.
  • The “Pre-public patch versioning” section of the releasing runbook is replaced by “Versioning within 0.x”; release.sh auto-computes every tier and no longer refuses post-1.0 auto-computation.
  • The first release under this rule is v0.16.0 (the pending backlog carries breaking changes), not v0.15.4.
  • (Amendment #244) The hard gate allows finishes within 24h of the last tag with a warning, preventing the gate from blocking teams that already shipped today. The score weights and cadence nudge are unchanged.

Canonical source: docs/adr/0028-semver-tiers-within-0x.md in the madtea repo.