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:
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.Daily cap on the hard gate.
scripts/release-gate.shnow allows a finish past the hard score threshold when the latest v* tag is younger thanRELEASE_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 explicitvX.Y.Zargument overrides);release-due.shadvertises 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_jsonoutput 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/cicommits 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.shauto-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.