skills/mav-bp-versioning/SKILL.md
Versioning and deprecation conventions for projects producing libraries, APIs, or SDKs. Covers semantic versioning, changelog maintenance, deprecation policies, and breaking change management. Applied when releasing or reviewing versioned artifacts.
npx skillsauth add thermiteau/maverick mav-bp-versioningInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Ensure all versioned artifacts follow semantic versioning, maintain changelogs, and handle breaking changes and deprecations responsibly. Consumers of your library, API, or SDK depend on predictable version semantics to manage their own software safely.
These standards apply primarily to projects that produce versioned artifacts consumed by others:
Internal applications (web apps, backend services with no external API consumers) may use simplified versioning (e.g., date-based versions, git SHAs, or auto-incrementing build numbers) since they do not have external compatibility contracts. However, if an internal service exposes an API consumed by other internal services, the API versioning standards in this skill still apply to that API surface.
All versioned artifacts must follow Semantic Versioning 2.0.0 (MAJOR.MINOR.PATCH):
| Component | When to increment | Example |
| --------- | ----------------- | ------- |
| MAJOR | Incompatible API changes — removing or renaming public functions, changing behaviour, removing endpoints, changing data formats | 1.4.2 -> 2.0.0 |
| MINOR | Backwards-compatible new functionality — new functions, new endpoints, new optional parameters, new configuration options | 1.4.2 -> 1.5.0 |
| PATCH | Backwards-compatible bug fixes — fixing incorrect behaviour, security patches, performance improvements with no API change | 1.4.2 -> 1.4.3 |
A change is breaking if any existing consumer code could fail, produce different results, or require modification after upgrading:
Breaking changes are sometimes necessary, but they must be handled deliberately.
| Section | Contents | | ------- | -------- | | Overview | Summary of breaking changes and why they were made | | Step-by-step migration | Ordered instructions for updating consumer code | | Before/after examples | Code snippets showing old usage and new usage | | Automated migration | Codemods or scripts if available | | Timeline | When the old version will stop receiving patches |
Every project with versioned releases must maintain a changelog that is readable by humans, not just a dump of commit messages.
Use one of these approaches:
| Approach | File/Location | Tooling |
| -------- | ------------- | ------- |
| CHANGELOG.md | Root of repository | Manual or generated via conventional-changelog, changelogen, git-cliff |
| GitHub Releases | GitHub release page | Manual or generated via release-please, semantic-release, GitHub auto-generated notes |
| Both | CHANGELOG.md + GitHub Releases | Best practice for public packages — CHANGELOG.md for repository readers, GitHub Releases for registry/notification consumers |
Each version entry should contain:
## [1.5.0] - 2025-03-15
### Added
- New `export()` function for batch data retrieval (#142)
- Support for custom retry policies in HTTP client (#155)
### Changed
- Default timeout increased from 5s to 30s (#160)
### Deprecated
- `fetchAll()` is deprecated in favour of `export()` — will be removed in 2.0.0 (#142)
### Fixed
- Connection pool leak when requests timeout (#148)
- Incorrect pagination cursor encoding for Unicode content (#151)
### Security
- Updated `xmlparser` dependency to fix CVE-2025-XXXX (#153)
Deprecation is a contract with consumers: "this will go away, here is your notice and here is what to use instead."
Use the language's built-in deprecation mechanism:
# Python
import warnings
def old_function():
warnings.warn(
"old_function() is deprecated, use new_function() instead. "
"Will be removed in 2.0.0.",
DeprecationWarning,
stacklevel=2,
)
return new_function()
// TypeScript/JavaScript — JSDoc
/**
* @deprecated Use `newFunction()` instead. Will be removed in 2.0.0.
*/
export function oldFunction(): void {
return newFunction();
}
// Java
@Deprecated(since = "1.5.0", forRemoval = true)
public void oldMethod() {
newMethod();
}
// Rust
#[deprecated(since = "1.5.0", note = "Use new_function() instead")]
pub fn old_function() {
new_function()
}
Deprecated entry in the release that introduces the deprecationFor versions that are not yet stable, use SemVer pre-release identifiers:
| Stage | Format | Meaning |
| ----- | ------ | ------- |
| Alpha | 2.0.0-alpha.1, 2.0.0-alpha.2 | Early development, API may change significantly, not for production use |
| Beta | 2.0.0-beta.1, 2.0.0-beta.2 | Feature-complete, API mostly stable, suitable for testing but not production |
| Release Candidate | 2.0.0-rc.1, 2.0.0-rc.2 | Production-ready candidate, only critical fixes before final release |
npm publish --tag next, pip install package==2.0.0a1, etc. so that default installs get the stable versionalpha.1, alpha.2, alpha.3This skill covers artifact versioning — the version number of a package, library, or release.
The mav-bp-api-design skill covers API endpoint versioning — URL path versioning (/v1/users), header-based versioning, and API deprecation processes.
The two are related but distinct:
1.5.0 may expose an API at /v2/ — the artifact version and API version are independent| Pattern | Issue | Fix |
| ------- | ----- | --- |
| Breaking change with only a minor or patch bump | SemVer violation | Bump major version |
| Removed function with no prior deprecation | Consumer breakage without notice | Deprecate first, remove in next major |
| Changelog not updated with code change | Missing release documentation | Add changelog entry in the same PR |
| Deprecation message with no replacement named | Unhelpful deprecation | State what to use instead and when removal happens |
| Pre-release published to default registry tag | Unstable version installed by default | Use --tag next or equivalent |
| Version bump without changelog entry | Consumers cannot understand what changed | Add changelog entry before release |
| Code removal in minor/patch release | Breaking change in non-major version | Move removal to next major version |
| No migration guide for major version | Consumers blocked on upgrade | Write a migration guide with before/after examples |
| Deprecated code no longer functions | Broken deprecation contract | Fix deprecated code path — it must work until removal |
| Multiple breaking changes across minor releases | Death by a thousand cuts for consumers | Batch breaking changes into a single major release |
development
--- name: do-test description: Write or update tests for a code change. Operates in two modes: `unit` (module-scoped, fast, deterministic) and `integration` (crosses module / service / database boundaries). Intended to be invoked once per testable change from inside a do-issue-* or do-epic phase. Mode is required. argument-hint: mode: unit or integration user-invocable: true disable-model-invocation: false --- **Depends on:** mav-bp-unit-testing, mav-bp-integration-testing, mav-local-verificati
development
Implement a focused code change. Use this skill as the wrapper for any implementation work so the Maverick workflow report captures what was done and so the agent applies the project's coding standards before editing. Intended to be invoked once per task from inside a do-issue-* or do-epic phase, not standalone.
testing
How to stack a PR on top of an unmerged sibling branch, and how to retarget it to the repo's default branch once the sibling merges. Prevents orphan-merge incidents when a dependent story is ready before its parent.
development
Claim, lease, heartbeat, and release protocols for when multiple Claude Code instances may act on the same issue or epic concurrently. GitHub labels and marker comments are the coordination surface; local state is a cache.