Versioning and stability#
SwarmOps 0.1.0 is the first release, tagged v0.1.0. Every crate of the workspace is at version
0.1.0 (the workspace version), and none is published (publish = false). This page says what
users and agents may rely on, what they may not, and how a change to a public surface is made.
The release steps are in RELEASE.md.
Public surfaces#
What SwarmOps promises lives in bytes and in JSON, not in Rust APIs. From the strongest promise to the weakest:
- The hash contract. The canonical byte layouts of blobs, trees and changesets, and the
hash recipe
id = blake3("swarmops:<kind>:v1\0" ++ u64le(len) ++ payload)(storage-core spec §1). Every object id and every changeset id depends on them, so they never change, not even before 1.0. The golden vectors incrates/swarmops-core/tests/golden/pin the bytes and ids of representative objects, andjust checkfails if either moves. - The store format. The on-disk layout of a store, named by its
FORMATfile (swarmops-store 1): the object file header, the journal's frames and records, the index files and the ref files (storage-core spec §2, §3). A binary opens only a store whoseFORMATit knows; any other, the CLI refuses asE_NOT_A_REPO. - The command-line contract. One JSON envelope per run on stdout,
{ok, op, api, result | error{code, message, retryable, exit, details, hint}, meta}, withapi1; theE_*error codes, each with its fixed exit code (1 to 6, 3 for a conflict; 0 is success) and itsretryableflag; the commands, their flags and the grammar of their arguments, such as revisions and change lists (operations spec §0, §1); and the environment variablesSWARMOPS_REPO(operations spec §1, umbrella §4),SWARMOPS_FORMAT(operations spec §0),SWARMOPS_AGENT(operations spec §5) andSWARMOPS_RUN_ID, which no spec names yet (the README,docs/architecture.mdand the crate documentation describe it). - The API schema. The JSON Schema of every request and response type that
swarmops schemaprints (schema_for_allinswarmops-api), and theStoreOpsoperations it describes. - The MCP tools. The tools
swarmops mcplists, their names, theirinputSchema(each the request type's schema, kept a plain object, with theexpected_oldofref_setandref_deletenarrowed to a full changeset id) and their results (the same envelope the CLI prints). - The git export. The git commit each changeset exports to (storage-core spec §7): an
imported changeset's own commit while SwarmOps has not changed its lineage, and for any other
changeset the commit its trees, its signatures and its message render to, a native
changeset's message followed by SwarmOps' trailers (
SwarmOps-Changeset, and the land, review and squash trailers). That rendering is version 1 of thegit_oidderivation: git's tree order and modes, the commit layout, the signatures verbatim and the trailer block. It changes only as a new version, never in place, and every branch exported before a new version meets it as divergence, to be exported again once with--force: a deployment pipeline sees a rewritten history.
The contract surfaces (3 to 5) grow without breaking: a new field, a new optional argument, a new
command, a new error code or a new tool is not a breaking change. Clients must allow for that.
Requests and responses ignore fields they do not know (the operations spec forbids
deny_unknown_fields), and an unknown E_* code still carries its exit and retryable, so a
client can act on a code newer than its own table. A change is breaking when it removes or
renames a field, a command, a flag, a code or a tool; changes a field's type or meaning; changes
a code's exit code or retryable flag; or makes an optional input required.
Internal surfaces#
No compatibility is promised for:
- The Rust crate APIs, all nine of them (the eight product crates and
swarmops-testkit). They are internal to the workspace and unpublished;swarmops-api's types are a contract only through their JSON. - Performance. The spec's targets and the numbers in docs/perf.md are goals and measurements, not guarantees. A regression is a bug to fix, not a breaking change.
- Text meant for reading:
error.message, the wording ofhint,--humanoutput and anything on stderr. Thecode,exit,retryableand the keys ofdetailsare the contract; the words around them are not. - Test-only behaviour: the
test-hookscargo feature and theSWARMOPS_TEST_*variables. - Internal tuning that no layout records, such as how often the index is synced and checkpointed or when the sorted views are compacted.
Before 1.0#
- Versions follow Semantic Versioning, with the pre-1.0 reading that uv and ruff use: a minor bump (0.1 to 0.2) may break a public surface other than the hash contract, and a patch bump (0.1.0 to 0.1.1) breaks none. Every crate shares the workspace version.
- Every breaking change is called out under its version in CHANGELOG.md, with what to do about it.
- A store format change may need a store to be created again: there is no migration tool before
1.0. (It happened once during M1: once
initbegan to create every index file, stores created before that were refused.) The changelog says when. - From 1.0 on, the intent is that a release opens every store an earlier 1.x release wrote, or migrates it, and that a test proves it before each release.
How a breaking change is made#
- A new object layout gets a new kind/version header and its own golden vectors, beside the old ones. Objects already stored keep their bytes and their ids.
- A new store layout bumps
FORMAT. The first new journal record kind, for instance, makes the storeswarmops-store 2(storage-core spec §3): an older binary then refuses to open it rather than misread it, because there is no rule for skipping unknown records. The nextFORMAT(planned as 2, M6) adds a checksum to eachjournal.offentry and a frame header that carries the frame's sequence number and the previous frame's CRC; whichever version first changes the layout takes the next number. - A contract change shows up in a test the gate runs:
all__cli__schema_snapshot.snapholds the schema of every type, the MCP server's tool list and its discovery result have snapshots of their own, and each error code's exit code andretryableflag, which no schema holds, have a row inspec_row(crates/swarmops-api/tests/schema.rs). The gate fails until the snapshot or the row is updated in the same commit. That commit says that it changes the contract, and the changelog records it. A change that breaks the envelope or a response's shape also increments the envelope'sapinumber. - An error code that is removed is never reused for another meaning.