Skip to content
Registry StackDocsDevelopment (unreleased)

API stability and versioning

View as Markdown

Use this page to decide which Registry Stack surfaces you can build on across releases. It names the promised products and surfaces, the experimental ones, the rules a change to a covered surface follows, and how state moves from one release to the next. The promise takes effect at Registry Stack 1.0.0, when all five promised products reach 1.0 together.

Registry Stack 1.0 is one release with one Stack version and the tag vMAJOR.MINOR.PATCH. Base Registry Engine, Registry Evidence, Registry Casework, Registry Discovery and Registry Manifest reach 1.0 together. Discovery remains on the Stack release train through 1.0; independent product releases are deferred until after that cut.

Across Stack 1.x, patches do not break covered surface. A minor may remove HTTP or configuration surface deprecated in an earlier minor; removing deprecated SDK methods requires a major. Before 1.0, breaking changes require a minor release, a BREAKING: note and concrete migration steps. Patches remain compatible.

The Node and Python SDKs have one package version each. Compatibility is specified per product namespace. A breaking change to any promised SDK namespace requires a major version of the whole package, even if other namespaces are unchanged.

The promise covers five products: Base Registry Engine, Registry Evidence, Registry Casework, Registry Discovery, and Registry Manifest. For each, it covers the configuration files, identified by their apiVersion or schema version, and the HTTP API with its OpenAPI document and its problem code values. The linked references define each surface; if this page and a reference disagree, the reference wins.

ProductConfigurationHTTP API
Base Registry Engineregistry.yaml, module.yaml, and runtime.yaml, including the Rhai action handler ABI registry.action-plan/v1Base Registry Engine API
Registry EvidenceBundle and runtime filesRegistry Evidence API and problem types, including the signed JWS, unsigned JSON envelope, SD-JWT VC, and holder-bound issuance envelope response formats
Registry CaseworkCasework policy and runtime fileCasework API
Registry DiscoveryOrigins, evidence-type mappings, and runtime fileGET /v1/services and POST /v1/evidence-types/resolve
Registry Manifestregistry-manifest/v1 metadata documentsNone

Registry Evidence’s versioned routes are POST /v1/evidence, POST /v1/evidence/batch, and GET /v1/evidence-definitions. Its operational routes are /health, /ready, /openapi.json, /.well-known/evidence/jwks.json, and /.well-known/jwt-vc-issuer.

The promise also covers the client SDKs: the Node.js package @registrystack/client, the Python package registry-stack-client, and the Rust crate registry-stack-client taken from the release tag. In each, the breg, evidence, casework, and discovery namespaces are promised. The SDKs are additive-only across 1.x, because a version range on a published package, such as npm ^1.2.0 or pip ~=1.2, picks up minor releases automatically: a minor release may deprecate an SDK method, and its removal waits for 2.0. A member of a promised namespace that reaches an experimental surface is experimental with that surface: for example, the statistics methods of the breg namespace, and the scheduling variant of task grant bounds in the casework namespace. See the client API reference.

These surfaces stay outside the promise, including those whose release packaging is still held. Those with a v1alpha1 version string keep it, and each may change or be removed in any minor release without deprecation:

  • Registry Scheduling, and the scheduling namespace of the client packages
  • Registry Messaging, and the messaging namespace the client packages carry from v0.38.0
  • Registry Render, and the render SDK namespace. Render client packages are held out of releases
  • Registry Coordinator, and the coordinator namespace of the client packages. Its binaries and installer enter the Stack release roster from v0.44.0; its container image is not published yet
  • the shared record and auth SDK namespaces
  • breg-mcp and breg-review, the citizen services beside Base Registry Engine
  • evidence-oid4vci, the wallet-facing delivery service beside Registry Evidence, including its configuration, routes, and command-line flags
  • the Base Registry Engine statistics routes under /v1/statistics/, and the statisticalDatasets declarations behind them
  • the Base Registry Engine spatial adapter routes under /v1/gis
  • calling Evidence from a Base Registry Engine governed action handler: the action’s evidence declaration, and evidence::resolve inside the handler
  • the scheduling variant of a Casework task grant’s bounds

Registry Document Store is held out of the 1.0 release.

Before v1.0.0, one breaking release moves the promised products’ version strings from v1alpha1 to stable versions, so a v1alpha1 version string that a 1.x release reads or writes (in configuration, an API, or a schema) marks an experimental surface. The published registry-discovery-v1alpha1 profile resources stay published as history and are not an experimental surface.

Two surfaces get best effort: ctl JSON output and audit record schemas. They may change in a minor release with a release note and no deprecation window.

These surfaces are not covered:

  • Rust library crates. Every workspace crate is publish = false, and nothing is published to crates.io. A crate other than the registry-stack-client SDK may change in any release; pinning the repository by tag or commit gets exactly what you pinned.
  • Database internals.
  • Human-readable CLI text.
  • Log lines.

A surface this page does not name is outside the promise.

For an HTTP API:

  • removing or renaming a route, parameter, request field, or response field
  • changing the type, meaning, or optionality of an existing field
  • changing the status code or the media type of an existing response
  • removing or renaming a problem code, changing the stack-wide meaning of a released code, or changing an existing product-and-operation HTTP mapping for it
  • tightening authentication or scope requirements on an existing route, except as a security fix announced in the release notes

For configuration:

  • removing or renaming a key
  • narrowing the accepted values of an existing key
  • changing the meaning or the default of an existing key

For an SDK:

  • removing or renaming a method, type, or member
  • changing a method’s parameters or result incompatibly

New routes, optional request fields, response members, optional configuration keys, problem codes, and SDK methods are additive. Descriptions, summaries, and ordering inside an OpenAPI document, and problem detail strings, are not part of the contract.

Nothing changes meaning in place. The replacement ships first, then the old form is deprecated, then removed. For configuration, the replacement is a new apiVersion accepted alongside the old one.

A deprecation lasts at least one minor release. There is no time floor; a later revision of this policy may lengthen the window and never shortens it. During the window:

  • the product’s check command, or registry-manifest validate for Registry Manifest, reports the deprecated version as a warning
  • HTTP responses carry Deprecation and Sunset headers (RFC 9745 and RFC 8594), and the OpenAPI document marks the route or field deprecated: true
  • the release note carries a Deprecated entry naming the surface, its replacement, the earliest release that may remove it, and copyable upgrade steps
  • the docs page for the surface notes since vX.Y and names the replacement

A removal turns a retired configuration key into a refusal, never a silently ignored key, and its release note repeats the migration steps.

A security fix may tighten or remove surface without the full window when keeping the surface would leave deployments exploitable. The release notes document the removal, the shortened window, and the migration steps without details that put unpatched deployments at more risk.

Changes made before v1.0.0, including the Registry Relay retirement, predate these rules. A docs page with status: deprecated frontmatter is a superseded page, not a scheduled removal.

A client must ignore response members it does not recognize, and must not fail on a problem code it does not recognize; it handles that problem by its HTTP status. That rule is what lets a minor release add members and codes.

Signed payloads and governed, digest-verified artifacts keep their own closed formats. Casework clients keep review policy closures and their dependencies intact for digest verification before use.

For Base Registry Engine metadata, requiredCapabilities is the must-understand gate. An engine addition that changes how an existing member must be interpreted or executed must add a new requiredCapabilities value; every other additive member is ignorable. A client disables only the operation that names a capability it does not understand. The engine still authorizes every request at execution time.

Servers stay strict on requests and configuration: an unknown request member or configuration key is refused, not ignored. A configuration file that uses a key a later release introduced fails to load on an earlier binary, so pin configuration to the release you deploy.

Registry Evidence’s frozen Version 1 contracts under products/evidence/contracts/ are the artifacts that define its configuration and HTTP surfaces. Frozen means they change only under the rules on this page: Registry Evidence has the same promise and the same deprecation rule as the other promised products.

A WASM action handler is promised within the limits the WASM action handler guide states:

  • the project keys handler.type: wasm, the module path, and handler ABI registry.action-plan/v1
  • the guest byte ABI: a wasm32 core module with zero imports; the exports alloc, handle, result_ptr, result_len, and memory; the handle status codes 0 (success), 1 (malformed request), and 2 (internal error); the {"inputs": ...} request document; and the one JSON outcome document
  • the runtime wasmExecution keys maximumModuleBytes, maximumGuestMemoryBytes, and backend, with their documented ranges and defaults

Raising a limit is additive; lowering one is breaking. The fuel budget, which limit stops a call first, performance, backend speed, and the Wasmtime version are not promised. WASM hook handlers and the WASM handler SDK are outside the promise.

The native Base Registry Engine (BReg) Record type, Action, and Proposal replacement is a fresh-install boundary. It provides no conversion of state recorded by earlier Base Registry Engine releases. Normal package evolution applies within the native model.

For retained state contracts, each release reads the state its immediate predecessor wrote, except for the fresh baselines described in this section and v1.0.0. v1.0.0 is a fresh install, and no upgrade from a v0.x release to it is supported. For a minor release, the immediate predecessor is the last release of the previous line. For a patch release, it is the previous release of its own line; a patch release promises no direct path from a release before its line. Upgrade one release at a time, and complete each release’s upgrade steps before you start the next.

v0.40.0 does not upgrade state v0.39.0 wrote in place. Rewrite the configuration you carry over, rebuild packages, and apply them to new databases as the upgrade runbook describes. The forward state path starts at v0.40.0; subsequent pre-1.0 releases read the state their immediate predecessor wrote, subject to an explicitly documented product replacement. The fresh baselines below are such replacements, so a product’s state carries forward only from its latest baseline, and the predecessor rehearsal starts from the release that Enforcement names, not from v0.40.0.

Evidence’s normalized v0.42.0 model starts a new baseline. Retired split question/source projects and targets with bundled authority have no in-place conversion. Retain the previous deployment and audit, author evidence.yaml, a target, and complete target authority with the current tooling, then package and verify a fresh synthetic assertion before cutover. v0.43.0 continued this forward path from v0.42.0. The current predecessor rehearsal starts at v0.44.0, so bring older retained state through each intervening release first.

Casework’s review-only replacement requires a fresh database. It refuses the retired database containing WorkItem tables without converting or deleting its state. Drain or cancel old reviews, retain the old deployment and audit journal for reconciliation, and install the current model in a fresh database as the Casework upgrade step describes. The forward-state rehearsal does not claim that this replacement preserves old Casework work in place.

Messaging’s and Scheduling’s v0.42.0 schemas start new baselines. Each installs its complete schema as one baseline, and its plan, apply, and startup refuse a database whose ledger holds a pre-1.0 version, naming the fresh-install recovery. Retain the previous database and audit journal for reconciliation, and apply the current package to a fresh database as the upgrade runbook describes. Messages still queued, and Scheduling holds and appointments, in the previous database are not carried forward.

v0.44.0 starts Casework and Scheduling at a fresh baseline again. Each installs schema version 200, and its plan, apply, and startup refuse a ledger below version 200 as a pre-1.0 schema. BReg in v0.44.0 refuses a database holding the v0.43.0 attachment verification tables, at startup and in bregctl doctor with the code startup.database.pre-1-0-schema, and in bregctl plan and apply with apply.database.pre-1-0-schema. For each, retain the previous database and audit journal, and apply the current package to a fresh database; for BReg, rebuild the package with the v0.44.0 bregctl test and bregctl package (Check, test, package), then run bregctl apply --package DIR --initial. Casework reviews, Scheduling holds and appointments, and BReg records in the previous database are not carried forward. Messaging keeps its baseline: messagingctl apply migrates a v0.43.0 database forward in place.

Upgrades are forward-only: no release reads state a later release wrote. An ordinary release’s apply migrates the database in place, so to roll back, restore the backup taken before the upgrade and run the previous release. A fresh-baseline release such as v0.42.0 leaves the previous database untouched: run the previous release against it, and restore a backup only when it is damaged, as Roll back describes.

Registry Evidence, Registry Discovery, and Registry Manifest have no migrated state. Base Registry Engine, Casework, Scheduling, and Messaging each own migrated PostgreSQL state: bregctl apply activates a package and runs its migration, caseworkctl apply activates a Casework package and runs its migrations, and schedulingctl apply activates a Scheduling package and runs its migrations. messagingctl apply activates a Messaging package and runs its migrations. Read each release’s notes for the migration steps it needs. The v0.40.0 exception above applies to all four. The forward state path holds for an experimental surface, such as Scheduling or Messaging, while a release ships it, and a release that removes one says in its release notes what happens to the state that surface wrote. Base Registry Engine’s Beta pilot conditions are under What you need on its deployment page.

The promise is machine-checked where a checker exists:

  • Registry Evidence: root CI’s evidence-contracts job runs products/evidence/scripts/check-contracts.sh, which regenerates every contract artifact and fails on any byte difference from the committed copies. products/evidence/scripts/check-config-key-paths.sh holds the configuration reference in exact parity with the frozen schemas.
  • Registry Manifest: schema and renderer tests pin accepted inputs and deterministic artifacts.
  • Forward state path: the release upgrade rehearsal workflow runs release/scripts/rehearse-upgrade.py on every pull request that changes a release manifest, and on manual dispatch. It verifies the previous release’s binaries against the signed SHA256SUMS, writes messages and audit entries for eligible products, using disposable PostgreSQL for Messaging, upgrades with the binaries built from the pull request, and fails when captured views differ, retained tables lose rows, or an audit file loses entries. It starts from the newest published release at or below the workspace version, so it rehearses the immediate predecessor, and it refuses to start from a release before v0.44.0, the predecessor current source reads. v0.43.0 continued the path from the v0.42.0 Evidence, Messaging, and Scheduling baselines; v0.44.0 retained Evidence and Messaging state while starting the product baselines above. While no release from that floor onward is published, the rehearsal uses the binaries under test on both sides and reports that it has no published predecessor. This exercises the scenarios with the same build; it does not demonstrate compatibility between releases. Once a release on the forward state path is published, the default run downloads eligible product binaries from it. Default omissions record the unsupported transition; a focused unsupported product request refuses. BReg, Casework, and Scheduling state are not rehearsed. BReg and Casework have separate current-schema operator checks.

A change that a gate flags as breaking lands only in a release whose version permits it, with the deprecation and migration steps this page requires.