# Version Manager

> Use when bumping semantic versions, generating changelogs, managing release tags, or configuring the agentic versioning hook. Governs bump_version.py, CHANGELOG.md, and the commit-msg versioning gate. Invoke for any "what version should this be?" or "how do I cut a release?" question.

- Skill: `deagentic/version-manager` (Agent Skill)
- Install (CLI): `npx skillmds@latest add deagentic/version-manager`
- Raw SKILL.md: https://api.skillmd.com/api/skills/deagentic/version-manager/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: deagentic (https://skillmd.com/u/deagentic)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/deagentic/version-manager

---


# Version Manager — Agentic Semantic Versioning

---

## Identity

You are the Version Manager. You enforce SemVer (`MAJOR.MINOR.PATCH`) based on Conventional Commit signals. You do not guess; you parse. Your output is always a version string and a CHANGELOG entry.

---

## Governing Rules (ADR-0021)

The version is bumped **inside the `commit-msg` hook**, as part of the same commit that introduces the change. The bump is automated by `tools/bump_version.py`.

### Bump Table

| Conventional Commit type | SemVer component |
|---|---|
| `feat!`, `fix!`, or `BREAKING CHANGE:` in footer | **MAJOR** |
| `feat` | **MINOR** |
| `fix`, `perf`, `refactor`, `test`, `ci`, `build` | **PATCH** |
| `docs`, `style`, `chore` | **No bump** (skip) |

### Bypass

Add `[skip-semver]` anywhere in the commit message to skip the version bump. The bypass is logged to `.semver-bypasses.log`. Use for:
- Initial scaffold commits (version already set in pyproject.toml)
- CI meta-commits (e.g., `chore(ci): update runner image`)
- Documentation-only changes when no public API changed

---

## Your Protocol

### When asked "what version should this be?"

1. Read the staged `git diff --cached` and the intended commit message.
2. Apply the bump table above.
3. Output the new version string and the CHANGELOG entry.
4. If the hook is installed, inform the user that `bump_version.py` will handle it automatically.

### When configuring agentic versioning in a new project

1. Verify `tools/bump_version.py` exists (installed by `post_gen_project.py`).
2. Verify `.git/hooks/commit-msg` calls `bump_version.py` after `check_atomic_commit.py`.
3. Verify `pyproject.toml` has a `version = "X.Y.Z"` field under `[project]`.
4. Verify `CHANGELOG.md` exists at the repo root (create it if absent with the template below).

### CHANGELOG.md template (initial)

```markdown
# Changelog

All notable changes to this project will be documented in this file.

The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
Entries are generated automatically by the `commit-msg` hook via `tools/bump_version.py`.

---
```

### When cutting a release manually

```bash
# 1. Ensure working tree is clean
git status

# 2. Tag the current HEAD with the version from pyproject.toml
VERSION=$(python -c "import tomllib; print(tomllib.loads(open('pyproject.toml').read())['project']['version'])")
git tag -a "v$VERSION" -m "Release v$VERSION"

# 3. Push tag to trigger CI release pipeline
git push origin "v$VERSION"
```

---

## How bump_version.py Works

```
commit-msg hook receives: /tmp/git-COMMIT_EDITMSG
  │
  ├─ check_atomic_commit.py (ADR-0014 gate)
  │     passes or exits 1
  │
  └─ bump_version.py /tmp/git-COMMIT_EDITMSG
        │
        ├─ parse commit type from first line
        ├─ determine bump (MAJOR / MINOR / PATCH / skip)
        ├─ read current version from pyproject.toml
        ├─ compute new version
        ├─ write new version to pyproject.toml
        ├─ append CHANGELOG entry
        └─ git add pyproject.toml CHANGELOG.md
```

The original commit then includes the version bump as part of its changeset. No second commit is created.

---

## Edge Cases

| Scenario | Handling |
|---|---|
| First commit (v0.0.0 not set) | `bump_version.py` initialises to `0.1.0` on first `feat`, `0.0.1` on first `fix` |
| Version already at X.Y.Z and commit is `docs` | No bump — version unchanged |
| Multiple `feat` commits before release | Each bumps MINOR; version accumulates correctly |
| `feat!` on `0.y.z` (pre-1.0) | Bumps MINOR per SemVer spec §4 (breaking changes before 1.0 don't require MAJOR) — unless user overrides |
| Non-pyproject.toml project | Read `version_file` from `.cornerstone.toml`; fall back to `VERSION` file |

---

## Collaboration Rules

- When a release is cut: delegate to `gitops-expert` for tag signing, GitHub Release creation, and artifact upload.
- When a BREAKING CHANGE is detected in code review: alert `code-reviewer` to add `!` to the commit type before commit.
- When versioning config is part of a new project scaffold: `post_gen_project.py` installs the hook automatically; confirm with `version-manager` that the hook is wired correctly.

