Skip to content

Latest commit

 

History

History
165 lines (123 loc) · 8.34 KB

File metadata and controls

165 lines (123 loc) · 8.34 KB

samkhya — Semantic Versioning Policy

samkhya follows Semantic Versioning 2.0.0 once v1.0.0 has shipped. The version number is MAJOR.MINOR.PATCH:

  • MAJOR — breaking changes to anything in the Public Surface table below.
  • MINOR — backwards-compatible additions to the Public Surface; bug fixes that change observable behavior in a way reviewers might call a soft break (e.g., a sketch's reported false-positive rate moves closer to the published Bloom CACM 1970 formula) ship in a MINOR.
  • PATCH — bug fixes that don't change observable behavior; doc improvements; internal refactors; test additions; performance work that does not alter the wire format or trait surface.

The leading v is part of the git tag only (v1.0.0); inside Cargo.toml, package.json, and the published crate, the bare version string (1.0.0) is used.


Historical pre-1.0 versioning

Before the first v1.0.0 tag, samkhya was in the pre-release iteration phase. Per Semver 2.0.0 §4, the public API was not considered stable; each pre-1.0 release could break surfaces between minor bumps in order to land the v1.0 shape. Pre-1.0 tags used v0.MAJOR.MINOR (e.g., v0.4.0) with no patch component.

The Public Surface has been locked since v1.0.0; subsequent breaks bump MAJOR, not MINOR.


Public Surface (the contract semver guards)

Everything below is in-scope for the semver contract. Anything not listed is internal and may change between any two patch releases without notice.

Category Item Why it's in-scope
Rust trait surfaces samkhya_core::residual::Corrector, samkhya_core::residual::CorrectionFeatures (field names + arity), samkhya_core::sketches::Sketch These are the integration seams every downstream engine plugs into.
Crate roots — re-exports The set of types re-exported at the root of every samkhya-* crate (the names downstream use samkhya_core::Foo; lines actually resolve to). A removed re-export breaks downstream builds.
Cargo features The set of feature names, the default-features value, and what each feature gates. Renaming a feature breaks every downstream Cargo.toml.
Puffin sidecar wire format Magic bytes, header layout, sketch-payload encoding, per-sketch serialize/from_bytes contract. Sidecars are written once and read many; old readers must keep working with new sidecars within the same MAJOR.
LLM inference server wire contract POST /infer request/response schema (field names, types, ranges), GET /health schema. Both Python (llm_infer_server.py) and TypeScript (llm_infer_server.ts) ports. Engines depend on this; the contract is what makes the corrector pluggable.
TabPFN inference server wire contract POST /infer + GET /health for samkhya-gpudb/scripts/tabpfn_infer_server.py. Same reason as LLM.
CLI argument surface samkhya-cli flag names, samkhya-bench flag names, exit-code semantics. Reproducer scripts in the wild hard-code these.
Sketch on-disk encoding HllSketch::from_bytes, BloomFilter::from_bytes, CountMinSketch::from_bytes, EquiDepthHistogram::from_bytes, CorrelatedHistogram2D::from_bytes — bytes written by version N must decode under version N+PATCH within the same MAJOR. Sketches are persisted into Puffin sidecars and replayed; cross-version readability is a hard requirement.
Environment variables SAMKHYA_LLM_BACKEND, SAMKHYA_LLM_MODEL, SAMKHYA_LLM_TEMPERATURE, SAMKHYA_LLM_MAX_TOKENS, SAMKHYA_LLM_HOST, SAMKHYA_LLM_PORT, SAMKHYA_LLM_LOCAL_URL, TABPFN_HOST, TABPFN_PORT, TABPFN_DEVICE, TABPFN_SUPPORT. Operator-facing knobs; renames break running deployments.
Default-feature MSRV The minimum rustc version on which every workspace crate compiles with its default feature set. Bumping the floor is a MINOR change with a release-notes call-out.
Optional-feature toolchain floors A higher floor imposed by an opt-in upstream engine dependency. Each exception is documented; raising one is a MINOR change.

Out of scope (free to change in any release)

  • Empirical numbers in bench-results/*.md — measurements are reproducible artifacts of a specific hardware + dataset; they evolve with each campaign and are not semver-stable.
  • Internal struct field layouts that are not pub at a crate root.
  • Internal helper modules (anything inside a mod foo; that isn't re-exported).
  • Test fixtures and dev-dependency versions.
  • Documentation text (the wire contract itself is stable; the prose explaining it is not).
  • The CSV → Parquet converter binary (samkhya-bench/src/csv_to_parquet.rs) — bench-internal tooling.
  • Internal corrector implementations like GbtCorrector's feature engineering or training procedure — what is stable is the Corrector trait; the implementation is free to change.

What constitutes a "break" inside the Public Surface

For Rust types and traits, a break is anything Cargo would flag as a semver violation under cargo-semver-checks:

  • Removing a pub item.
  • Renaming a pub item without a #[deprecated] re-export bridge.
  • Adding a required generic parameter or required method to a pub trait.
  • Tightening a function signature in any direction the caller can't satisfy.
  • Changing the variant set of a pub enum that is not marked #[non_exhaustive].

For wire protocols, a break is anything that would cause a correct-by-previous-spec client to receive a non-2xx response or parse failure that previously succeeded.


MSRV policy

The workspace rust-version is 1.85. CI checks every crate, including samkhya-py, on Rust 1.85 with default features. This is the v1.x default-feature compatibility guarantee.

Opt-in engine features may inherit a higher floor from the engine SDK they activate. Those combinations are tested separately on the pinned development toolchain. The current exception is samkhya-iceberg/iceberg, whose iceberg 0.9.1 dependency requires Rust 1.92. Cargo cannot encode a per-feature rust-version, so the exception is also documented beside the dependency in samkhya-iceberg/Cargo.toml.

Raising either the default-feature floor or a documented optional-feature floor is a MINOR change and must be called out in release notes. Lowering a floor is compatible.


Release gate

samkhya's release process gates every published version on explicit maintainer signal, regardless of what semver would mechanically permit. The release tag is never created automatically by CI; the maintainer signs the tag manually. There is no --auto-release mode in this project's CI, and there will not be one in v1.x.

This is intentional. Per-release human review is the last empirical gate before a number is locked into the supply chain.


Yanking

A published crate version that ships a wire-contract regression, a build break on a MSRV target, or a correctness bug in a sketch encoder may be yanked from crates.io. Yanked versions remain downloadable for pinned consumers but are excluded from default resolver semver selection. Every yank is accompanied by a follow-up PATCH release that fixes the underlying issue, and an entry in CHANGELOG.md documenting the yank and the fix.


Pre-release suffix

Pre-release builds use the standard Semver pre-release identifier syntax:

  • 1.0.0-rc.1, 1.0.0-rc.2, ... — release candidates before v1.0.0.
  • 1.x.0-alpha.N, 1.x.0-beta.N — feature previews after v1.0.0.

Pre-release identifiers sort lower than the corresponding release (1.0.0-rc.1 < 1.0.0), as Semver 2.0.0 §11 specifies. Cargo's default resolver excludes pre-releases unless the dependency explicitly opts in (version = "1.0.0-rc.1"); we rely on this.


Build metadata

samkhya does not use Semver build-metadata identifiers (the +abc suffix). Every published crate version has a deterministic content addressed by its MAJOR.MINOR.PATCH[-pre] string alone.


Reference