Versioning¶
arkhe follows Semantic Versioning 2.0.0: MAJOR.MINOR.PATCH.
The version is still 0.x — see Before 1.0. The current release is
not written here, because it would go stale at every release; it is in the
changelog.
What the version covers¶
SemVer is only meaningful once you say what the public surface is. For a piece of infrastructure rather than a library, it is broader than "the functions we export".
| Part of the contract | Example of a breaking change |
|---|---|
| Resolution behaviour | An inflection stops answering; a status code changes; suffix passthrough stops resolving through an ancestor |
| REST API | A field is removed or renamed; a request that used to succeed now fails |
| Environment variables | A setting is renamed or removed; a default changes in a way that alters behaviour |
| CLI | A command or option is removed or renamed; output that scripts parse changes shape |
| Database schema | A migration that cannot be applied to an existing ledger, or that loses data |
| The invariants | Any of them weakening. See below |
Not covered: internal module layout, the admin interface's markup, log formats, and
anything under compose/ (those are demonstrations).
The invariants are part of the contract¶
These refusals are what arkhe is for. Weakening one is a major change even if no signature moves:
- a name that has been published becomes removable without a reason, without the ARK retyped, or from outside the caller's reach (removing one is possible — narrowly, and recorded; 0.4.0 opened that door on purpose and said so)
- a namespace becomes deletable
- a withdrawn name becomes mintable again
retiredbecomes reversible- minting can silently become an update
- reach becomes widenable by a request
- a person subject can hold an API key, or a machine subject can be named through an external login
A release that did any of those quietly would be worse than one that broke a function signature, because the damage would be to identifiers rather than to a build.
Migrations¶
A minor release may add a migration; it must never lose data. Every migration is
run upgrade → downgrade → upgrade against PostgreSQL before every release
(scripts/check.sh), because SQLite accepts
schemas PostgreSQL rejects.
The ledger cannot be rebuilt. Under NR a lost ARK cannot be minted again, so "restore from the source system" is not available to us the way it is to most services.
Before 1.0¶
While the version starts with 0, the minor number carries breaking changes:
0.1.0 → 0.2.0 may break, 0.0.1 → 0.0.2 should not.
1.0 will be tagged when:
- the ARK conformance record has no outstanding gaps,
- the schema has been stable across at least one real migration, and
- an organisation other than the first is running it.
Until then, pin an exact version.
Releasing¶
# 1. The version and the changelog (the section for it, and both link definitions)
vim pyproject.toml CHANGELOG.md CHANGELOG.ja.md && uv lock
# 2. Check, without releasing anything. This is the default
bash scripts/release.sh v0.1.0
# 3. Release: tag, push, and create the GitHub release
bash scripts/release.sh v0.1.0 --publish
# 4. Publish the documentation, so the changelog page catches up
bash scripts/deploy-docs.sh
Checking and releasing are separate on purpose. Step 2 is cheap and can be repeated;
a tag and a GitHub release cannot be taken back, so nothing is published without
--publish.
The script refuses to go on unless the tag matches pyproject.toml, both changelogs
carry a section and a link definition for the version, and the unreleased comparison
link has moved to the new one. Everything else follows from pyproject.toml — the
package, the OpenAPI document and the admin footer all read the version from there. A
0.x release is marked as a prerelease on GitHub, so the version number is not mistaken
for a stability claim.