What pinning a 1.x mnesis crate buys you. This document takes effect at the 1.0
release of the core crates; until that release every crate is 0.x and this is the
policy being frozen, not yet a promise in force.
| Tier | Crates | Promise |
|---|---|---|
| 1.0 (frozen) | mnesis, mnesis-macros, mnesis-store, mnesis-wake, mnesis-wake-nostd | Full semver: breaking changes only at a major release |
| 0.x (evolving) | mnesis-inmemory, mnesis-fjall, mnesis-postgres, mnesis-store-testing | Breaking changes allowed in any 0.(x+1) release, called out in release notes |
| Unpublished | workspace-hack, mnesis-nostd-smoketest, examples | No promise |
Coupling rules across the tiers:
mnesis-macrosis version-locked tomnesis(the serde/serde_derive pattern): they release together, always at the same version.- A
mnesismajor forces amnesis-storemajor — kernel types (Version,Events, the aggregate traits) appear in store APIs. - A
mnesis-storemajor forces a major of both wake crates — they implement its publicWakeSourcecontract in their public API. - Adapters are consumers: a core major forces nothing on a 0.x crate beyond a routine dependency bump.
- No 0.x type appears in the public API of a 1.0-tier crate, with one acknowledged exception listed under Public dependencies.
The public API of the 1.0-tier crates is:
- Every documented
pubitem — types, traits, functions, macros, and feature-gated items when their feature is enabled. - Documented trait semantics — behavior, not just signatures. The store
contract's promises (inclusive
read_streambound, exclusiveread_allbound — an intentional asymmetry — strict-after subscription resume,CaughtUpemitted exactly once, conflicting appends rejected with nothing landing, spurious wakes permitted) are API; themnesis-store-testingconformance kit is their executable form. Changing one is a breaking change even if every signature still compiles. - Documented
Send/Syncbounds on public types and on returned streams and futures.
Explicitly not public API:
- Anything
#[doc(hidden)]. - Sealed traits' internals (
RawItem,ConflictPredicate,KeyspaceConfig, …): implementing them outside this workspace is unsupported. - The exact text of
Display/Debugoutput, includingErrorIdtruncation rendering. Match on error variants, never on strings. - Adapter internals: on-disk key layouts, partition names, and connection/session behavior of the 0.x adapters.
- The conformance kit's check list: new checks may be added in any release. A new check failing an adapter is the kit doing its job, not a breaking change.
Three external crates appear in 1.0-tier public APIs; their major version is part of our contract, so a semver-incompatible bump of any of them is a mnesis major:
bytes(1.x) —Bytesin envelope and codec APIs.futures-core(0.3) —Streamin stream and subscription bounds. It is 0.x upstream but de-facto frozen; we treat0.3as its major and acknowledge it as the one 0.x type in a 1.0 surface.minicbor(2.x, behind thecborfeature) — the backup box's sink trait (minicbor::encode::Writebounds onChunkWriter/SectionWriter) and encode errors (WriteError::Encode).
Everything else (arrayvec, tokio, parking_lot, foldhash, event-listener, fjall, sqlx, …) is an implementation detail and may change in any release.
The event frame (mnesis-store's wire module) carries a leading format-version
byte; the CBOR backup box carries a format_version header field. The promise,
for both:
- Within 1.x: the default write format never changes (frame v2 today), and every 1.x release reads everything any 1.x release wrote.
- Across one major: 2.x may introduce and default to a new format, but must still read every format 1.x wrote — an in-place upgrade never needs a migration step.
- Beyond one major: export → CBOR box → import is the supported migration path.
- Unknown format versions always fail with a typed error
(
DecodeError::UnsupportedFrameVersionfor the frame,ChunkErrorfor the box) — never a misparse.
Adapters are 0.x: their key layouts and partitions may change in a 0.x release, but any such change ships with a documented migration path (export/import at minimum). The CBOR box is the durable interchange format; raw store bytes are not.
rust-version in every published Cargo.toml equals the pinned stable toolchain we
build and test with. Raising the MSRV is a minor change, never a patch. We
claim no trailing floor: the declared MSRV is the only supported toolchain lower
bound, and cargo enforces it.
All cargo features of the 1.0-tier crates are additive: enabling a feature
never changes or removes an existing item's signature. Adding a feature is a minor
change; changing a crate's default feature set is a major change. There are no
unstable features at 1.0; if one is ever introduced it will be named unstable-*
and excluded from this promise.
- Public error enums carry
#[non_exhaustive]: adding a variant is a minor change. Always match errors with a wildcard arm. - Public non-error enums (
Step,Hydrated,Atomicity, …) are deliberately exhaustive: adding a variant is a major change. Exhaustive matching that catches new domain states at compile time is a promised feature, not an oversight.
Nothing is removed silently:
- An item is removed only at a major release, and must have shipped with
#[deprecated(note = "…")]— naming its replacement — in at least one published minor release before that major. - 0.x crates: deprecated in at least one 0.x release before removal.