ADR-0008: Adopt Semantic Versioning and a Change Classification Policy for Appcircle Releases¶
- Status: ✅ Accepted
- Date: 2026-03-02
- Owners: @osmank, @cagkan
- Deciders: Product + Engineering Leadership
- Related: Release Notes Process, Release Management, Backward Compatibility Policy
Context¶
Appcircle currently publishes releases in a way that does not consistently follow Semantic Versioning (SemVer). In practice, releases that include new features and even breaking changes are sometimes shipped as patch versions.
Evidence from recent release notes: - Version 3.29.9 is a patch release but includes 🆕 New Features and ⚠️ Breaking Changes in the same release. - Version 3.29.8 is also a patch release but includes multiple 🆕 New Features.
This causes: - Customer confusion and reduced trust in version numbers as a “risk signal”. - Harder upgrade planning (especially for self-hosted customers). - Operational risk: consumers may treat patch upgrades as “safe” but encounter breaking behavior. - Internal inconsistency: teams lack a shared “map” for what is a bugfix vs improvement vs feature vs breaking change.
We need: 1) A strict, enforceable SemVer policy for Appcircle. 2) A common change-classification map that determines version bump type. 3) A release note structure that reflects the classification consistently.
Decision Drivers¶
- Predictability and customer trust
- Upgrade safety for self-hosted and enterprise customers
- Clear communication of risk (breaking vs non-breaking)
- Ability to ship frequently without losing clarity
- Operational simplicity (automatable enforcement)
Decision¶
We will adopt Semantic Versioning (SemVer) and enforce it using a formal change-classification policy.
SemVer rules we will follow¶
- MAJOR (X.0.0): Breaking changes that require user action or can break existing integrations/behavior.
- MINOR (X.Y.0): Backward-compatible new functionality.
- PATCH (X.Y.Z): Backward-compatible bug fixes only.
Note
We may bundle multiple changes in one release, but the version bump MUST reflect the highest-impact change included.
Change Classification Map¶
1) Breaking Change → MAJOR¶
A change is Breaking if it can break any existing usage without opt-in.
Examples (non-exhaustive): - Removing a feature/behavior or changing defaults in a way that changes outcomes - Tightening permissions/roles in a way that blocks previously working flows - Changing an API contract (request/response fields, semantics, auth requirements) - Removing a supported artifact type or a supported workflow path
Example from release notes: “AAB files can no longer be published to Beta or Live channels …” is a breaking change (Breaking Changes: AAB Beta/Live restriction).
2) New Feature (Backward-Compatible) → MINOR¶
A change is a New Feature if it introduces new capability and existing behavior remains intact.
Examples: - New module capability, new workflow step, new integration option - New UI feature that doesn’t change existing semantics
Example from release notes: introduction of Manual/Auto Binary Re-sign for Enterprise App Store is a new feature (New Features: The Manual and Auto Binary Re-sign).
3) Improvement (Backward-Compatible Behavior/UX/Perf) → PATCH (or MINOR if user-visible capability expands)¶
A change is an Improvement if it: - Optimizes performance, stability, or user experience - Clarifies errors/messages - Improves UI/UX without changing behavior contracts
Rule: - If improvement only refines existing behavior → PATCH - If improvement adds user-visible capability or extends supported scenarios meaningfully → MINOR
4) Fix → PATCH¶
A Fix corrects a defect and does not change intended contract/behavior beyond the correction.
Release Note Structure Policy¶
Release notes must reflect the classification unambiguously:
- 🆕 New Features (MINOR or MAJOR)
- 💪 Improvements (PATCH or MINOR depending on capability expansion)
- 🐞 Fixes (PATCH)
- ⚠️ Breaking Changes (MAJOR only)
- 🚨 Announcements (non-version-impacting communications; e.g., external deprecations)
Warning
A release that contains any item under “⚠️ Breaking Changes” MUST be a MAJOR bump. Patch releases must not contain “🆕 New Features” or “⚠️ Breaking Changes”.
Considered Options¶
Option A — Keep current versioning, only improve release notes¶
- Pros: No engineering/process changes
- Cons: Does not solve risk signaling; version numbers remain unreliable; customers still impacted
Option B — Adopt SemVer without enforcement¶
- Pros: Low friction
- Cons: Regressions likely; teams drift; hard to keep consistent at scale
Option C — Adopt SemVer + enforce classification gates (Chosen)¶
- Pros: Predictable; automatable; improves customer trust; supports self-hosted safely
- Cons: Requires tooling and discipline; may increase MAJOR/MINOR frequency initially
Consequences¶
Positive¶
- Clear upgrade expectations (patch = low risk)
- Better internal alignment and planning
- Easier customer communications and support triage
Negative / Tradeoffs¶
- Some releases will require MINOR/MAJOR bumps that previously would have been PATCH
- Needs release-manager/maintainer time and CI checks
- Potential marketing perception: “many majors” (mitigated by better messaging)
Implementation Plan¶
Phase 0 — Decision & Ownership (Now)¶
1) Define ownership (effective immediately) - Release Manager owns the final change classification and version bump decision. - Engineering owners propose change classification in the PR (or equivalent change request).
Note
This ADR is primarily a policy decision. Tooling and automation will be implemented later as separate work items.
Phase 1 — Enforcement Tooling (Later / TBD)¶
2) Add a release gate (CI policy enforcement) - CI checks: - If release notes contain “⚠️ Breaking Changes” → block unless version bump is MAJOR - If “🆕 New Features” exists → block unless version bump is MINOR or MAJOR - PATCH releases allowed content: Improvements + Fixes only
Info
This is a future implementation step. Until implemented, the Release Manager enforces the rules via review and checklist.
3) Introduce a “Change Type” label in PRs
- Labels:
- type:fix
- type:improvement
- type:feature
- type:breaking
- Release notes generator (or manual checklist) aggregates by type.
Info
This is a future implementation step. Until implemented, engineering owners will indicate the proposed type in PR description.
Phase 2 — Process & Knowledge (Now → Ongoing)¶
4) Define “Deprecation Policy” (effective immediately)
- Deprecations must be announced at least N releases prior to removal
(default: 2 MINOR releases or 1 MAJOR release).
- Deprecations remain opt-in until removal, unless security requires immediate action.
5) Backfill guidance (ongoing) - Document examples and borderline cases. - Train teams on how to classify changes (short internal enablement).
Compliance & Exceptions¶
- Exceptions require explicit approval from Product + Architecture, documented in the release PR.
- Security emergency patches:
- Still follow SemVer. If behavior breaks compatibility, ship MAJOR with explicit security advisory.
Appendix A — Quick Decision Table¶
| Change Type | Backward Compatible? | Version Bump | Release Notes Section |
|---|---|---|---|
| Fix | Yes | PATCH | 🐞 Fixes |
| Improvement (no capability expansion) | Yes | PATCH | 💪 Improvements |
| New Feature | Yes | MINOR | 🆕 New Features |
| Breaking Change | No | MAJOR | ⚠️ Breaking Changes |
| Deprecation notice (no removal yet) | Yes | PATCH or MINOR | 🚨 Announcements + Deprecations |
| Removal of deprecated feature | No | MAJOR | ⚠️ Breaking Changes |