Versioning & Stability¶
Sandloom follows Semantic Versioning. This page defines what "public" means and the compatibility guarantees for each surface.
What is public¶
The stable, supported surface is the sandloom.sdk namespace
(ADR-0010) — the only framework code a
business module and its tests may import, together with generated contract
stubs and contract DTOs:
sandloom.sdk— the beginner names, re-exported from the modules below.sandloom.sdk.module,sandloom.sdk.app,sandloom.sdk.migrations,sandloom.sdk.tooling— module declaration, the app composition root, migration runners, CLI entry points.sandloom.sdk.web,sandloom.sdk.data,sandloom.sdk.tenant— routes, sessions and dependencies;Base,TenantScoped,db()and the read planner; tenant binding.sandloom.sdk.events,sandloom.sdk.effects,sandloom.sdk.contracts,sandloom.sdk.sagas,sandloom.sdk.projections— cross-module communication and effects.sandloom.sdk.authz,sandloom.sdk.security,sandloom.sdk.infra,sandloom.sdk.errors— authorization, token and session security, capabilities, exceptions.sandloom.sdk.testing(withsandloom.sdk.testing.fixturesandsandloom.sdk.testing.plugin) — the test kit.
Each module declares __all__ and __beginner__ (the beginner tier is a
subset); the SDK reference is generated from
them. public_api_baseline.json records every public name and
signature, and a change fails sandloom test (SANDLOOM-T008) until it is reviewed.
sandloom.driverkit is public for driver packages. Its contracts are versioned: a
breaking change is a new contract version, and a driver written for another major
version is refused at load (SANDLOOM-B022). A contract joins it only with a conformance
kit in sandloom.driverkit.testing. Calling a capability from a module is the stable
promise; implementing one moves with the contract version.
Everything else (sandloom.core.*, modules under sandloom.sdk whose name starts with
an underscore, sandloom.shared.authz, sandloom.shared.guards) is internal and
may change in any release without notice. sandloom check blocks imports of
internals from business modules (SANDLOOM-C002) and their tests (SANDLOOM-C013).
Compatibility guarantees¶
Public prereleases (a, b, rc) may change APIs between prerelease versions
without a deprecation window. Breaking changes must be listed in release notes
and include upgrade instructions. Pin the version used by your application and
review these changes before upgrading. This does not relax versioned event or
service-contract compatibility checks.
The guarantees below apply to releases without a prerelease suffix.
Within a major version (0.x while pre-1.0, x.y thereafter):
- No removal or breaking change to a public symbol's signature without a major bump. Additive changes (new optional parameters, new helpers) are minor.
- Deprecation before removal: a public symbol is marked deprecated for at least one minor release (with a documented replacement) before removal in the next major.
- Pre-1.0 caveat: at
0.x, minor versions may contain breaking changes; they are called out in the Changelog.
Release line and distributions¶
The framework, the sandloom distribution, has one release line (0.6.0,
0.7.0, …), recorded in the Changelog with an upgrade guide
per breaking release (e.g. Upgrading to 1.0).
The module packages sandloom-identity, sandloom-tenancy and
sandloom-billing (see Publishing) version
independently, like any third-party module: each has its own version and
changelog. The current published alpha is 0.7.0a6; each module depends on a compatible framework range,
sandloom>=0.7.0a6,<0.8 (for a 0.x framework the next minor is the next breaking
release). No module package depends on another. A module release that needs a
newer framework widens or moves its range; a framework minor release requires
each module package to release a version whose range admits it.
Third-party dependencies are ranges too (>=tested,<next breaking release);
exact versions live only in uv.lock. The sandloom new generator depends on
sandloom[redis,celery]>=0.7.0a6,<0.8 plus sandloom-<module>>=0.7.0a6,<0.8 for each
--with module, since the code it generates uses that release's API.
Event schema evolution¶
Event channels are versioned independently of the package, in the channel name
(<module>.<event>.vN). The compatibility policy is normative and enforced at
schema registration time — see
Event Contracts → Evolution policy.
In short: additive, optional changes are allowed in place within vN; any
breaking change requires a new vN+1 channel, and producers may dual-publish
during a migration window.
Service contract evolution¶
Sync service contracts (@contract("name.vN"), called through
Contract(REF)) carry the same major version in their name. A breaking
change to a contract's method signatures is a new vN+1 contract; the old
one is kept until consumers migrate.
Configuration¶
Settings (env vars) are part of the public surface. Renaming or removing a setting, or changing its default in a behavior-changing way, is a breaking change and is noted in the Changelog. New settings with safe defaults are additive.
Database migrations¶
Each module owns its own migration chain (per-module-per-database). Migrations are forward-only in production; a breaking schema change ships as an additive, backward-compatible migration plus a follow-up cleanup, never an in-place destructive change against live data.