Versioning¶
Murmurent uses CalVer: YYYY.M.MICRO (e.g. 2026.7.0). This page is the
policy; the running record of releases is CHANGELOG.md.
One number, one place¶
The version lives in exactly one place: the __version__ string in
src/murmurent/__init__.py. Everything else
reads from there:
pyproject.tomldeclaresdynamic = ["version"]and points[tool.hatch.version]at__init__.py, so the package metadata is never a second hand-maintained copy (it used to be maintained separately and drifted, withpyproject.tomlandmurmurent --versionreporting different versions).murmurent --versionprints__version__(viacli.py).core.repo_readystamps__version__into every murmurent-ready repo's.murmurent.yamlasbootstrap_version.Remote.murmurent_version()readsmurmurent --versionover SSH to detect cross-machine drift (host doctor, the dashboard host health check).
To cut a release, edit that one string. Nothing else.
Why CalVer, and when to bump¶
Murmurent isn't a library other packages pin against: it's installed by
git clone + uv tool install -e ., and lab members track main. What they
care about is "how stale is my install" and "do I need to run repo upgrade",
not SemVer's API-compatibility promise. CalVer answers the first directly.
The bump policy is tied to the upgrade mechanism:
- Bump on a structural release: a new commons agent, a marker/schema
change, a changed CLAUDE.md bootstrap stub: anything that should make existing
murmurent-ready repos want
murmurent repo upgrade. Add aCHANGELOG.mdentry and tag it. - Do NOT bump for agent-content edits: a tweak to an agent prompt, a rule's
wording, docs. Those reach every ready repo automatically through the
.claude/agentssymlinks into the commons clone; forcing arepo upgradewould be pure operator noise.
So the version bump carries real meaning: if the version changed, run
murmurent repo upgrade --all; if it didn't, you're already current.
MICRO starts at 0 and increments for a second structural release in the same
month (2026.7.0 → 2026.7.1); the next month resets (2026.8.0).
Note:
Readiness.needs_upgradecompares the stampedbootstrap_versionagainst the current version by string inequality, not "is older than". So any version change flips every already-bootstrapped repo toneeds_upgrade = Trueonce: the intended "a release shipped" signal. Re-stamp withmurmurent repo upgrade --all.
Releasing¶
Lightweight: there's no PyPI publish, so a "release" is a pointer for humans and
for the repo upgrade signal:
- Edit
__version__insrc/murmurent/__init__.py. - Move the
[Unreleased]notes inCHANGELOG.mdinto a dated[YYYY.M.MICRO]section. - Commit, then annotate + push a tag:
git tag -a v2026.7.0 -m "…"&&git push --tags. - Cut a GitHub Release from the tag (its notes can be the CHANGELOG section).
Schema versions are NOT the release version¶
Three integers version on-disk / on-wire artifact formats, and bump only when their own shape changes, never to match a release:
MARKER_SCHEMA(core/repo_ready.py): the.murmurent.yamlmarker shape.CARD_VERSION(core/identity_card.py): the identity-card shape.SIGNED_CARD_VERSION(core/idcert.py): the signed-card shape.
Keep them independent of __version__.