Versioning policy
SemVer bump rules, deprecation policy, per-service current versions, deprecation labels in the OpenAPI spec.
How the three YieldFabric public API specs version, what triggers a major / minor / patch bump, and what guarantees a consumer can rely on.
Per-service versions, one platform
Each service has an independent info.version in its OpenAPI spec
and its own CHANGELOG. There is no platform-wide API version —
clients pin to the per-service versions they integrate against.
0.2.00.3.00.5.0All three use SemVer 2.0: MAJOR.MINOR.PATCH.
Bump rules
Patch (X.Y.Z → X.Y.Z+1)
Non-breaking corrections. No SDK regeneration required, no client changes required.
- Typo fix in a description
- Clarified prose
- Fixed example that didn't compile
- Regenerated code sample
- Updated error-catalogue prose (without adding/removing codes)
- Drift fix where the doc said X and the code did Y — bringing doc in line with code that hasn't changed
Minor (X.Y.Z → X.Y+1.0)
Additive, backward-compatible. SDK regeneration recommended but existing client code keeps working.
- New operation / endpoint
- New optional input field
- New optional response field
- New enum value (consumers should switch on known values and accept-but-ignore unknowns — see "Forward compatibility" below)
- New error code
- New example
- New guide
Major (X.Y.Z → X+1.0.0)
Breaking. Existing client code may fail. Requires migration.
- Renamed operation
- Removed operation, field, or enum value
- Required field became required (was optional)
- Optional field became required-in-some-contexts
- Type narrowing (e.g.
string→enum) - Auth requirement changed on an endpoint
- HTTP status code changed for an existing case
- Error code removed or renamed
Pre-1.0 caveat
All three services are currently pre-1.0 (0.x.y). SemVer
allows breaking changes on minor bumps below 1.0, but we don't do
that — the three services follow strict bump rules even pre-1.0
so consumers can rely on the contract.
The 0.x line will turn over to 1.0 when:
- The spec is considered stable for external consumers.
- SDKs are generated and shipped.
- The deprecation policy below has been exercised at least once (so we know the playbook works).
Cross-service version compatibility
The services are independently versioned but the platform deploys them together. When one public surface changes in a way another YF surface depends on, YieldFabric handles the rollout order:
- Producer ships a minor version exposing the new shape alongside the old.
- All consumers update to use the new shape.
- Producer ships a major version removing the old shape.
In practice this means breaking cross-surface changes need a deprecation cycle (see below).
Deprecation policy
When a field, operation, or error code is removed in a major bump, it follows this lifecycle:
deprecated → removed
↑ ↑
announce one minor version cycle later AT MINIMUM
The minimum deprecation window is one minor version cycle (typically 2-4 weeks for active services).
How a deprecation is announced:
- Spec annotation. OpenAPI 3.1 supports
deprecated: trueon operations anddeprecated: truein schemas. Both are honoured. - CHANGELOG entry under the minor version that adds the replacement, explicitly listing the deprecated thing and its replacement.
description:prose explaining the migration path.
Example:
/auth/old-endpoint:
post:
operationId: oldOperation
deprecated: true
summary: (DEPRECATED) Old shape — use POST /auth/new-endpoint instead.
description: |
Scheduled for removal in v1.0.0. Migrate to
`POST /auth/new-endpoint` (same input shape, returns the
replacement type).
Forward compatibility — what consumers should assume
Consumers SHOULD write code that survives minor bumps:
- Treat enums as open-ended. When you receive an enum value you don't recognise, accept-and-ignore (or surface as "unknown" in UI), don't throw. New enum values arrive on minor bumps.
- Don't deserialise into strict types that fail on unknown
fields. Use lenient deserializers (
#[serde(default)]on Rust,JsonSerializerwithoutdisallowUnknownPropertiesin TS, etc.). - Switch on error
code, not errormessage. Messages are free-form and may shift between releases. Codes are the stable contract. - Respect
Retry-Afterheaders. If introduced, they're authoritative even if not previously specified.
Consumers MAY assume:
- HTTP status codes don't change for existing error cases.
requiredfields stay required.- Operation IDs don't change.
Pinning recommendations
How to pin per audience:
^0.2); auto-take patches; review minors before deployingIn the JS workspace, OpenAPI specs aren't versioned as npm packages today. If/when SDKs ship, they'll follow standard npm SemVer.
Change logs as the canonical record
Each service's CHANGELOG.md is the authoritative version log.
Format:
## [X.Y.Z] — YYYY-MM-DD
### Added (minor)
- New endpoint / field / enum value with a 1-line description.
### Changed (minor — additive) or (major — breaking)
- What changed, why, migration path if breaking.
### Fixed (patch)
- Drift between doc and code; typo; example fix.
### Deprecated
- Things on the path to removal in the next major, with target version.
### Removed (major)
- Things gone; what replaces them.
Entries always lead with the change type. Major bumps surface the breaking changes at the top of the file with a "Breaking changes" header.
What's NOT versioned
- Repo-root
README.mdandCLAUDE.md. Internal docs; versioned implicitly by git history. docs/architecture/trees. Internal; same.docs/getting-started/. Tutorial content; live with the spec, not separately versioned.- Webhook payloads for outbound webhooks (when they exist).
Each webhook event type is versioned via an
event_versionfield in the payload, separately from the spec version.
Out of scope
- API gateway version (Apollo Router config). Operator concern, not consumer-facing.
- Database schema versions. Internal; never exposed to API consumers.
- Internal library versions. Workspace versioning, not API versioning.
See also
docs/getting-started/cross-service-walkthrough.md— how the services compose at the consumer level.- Per-service
CHANGELOG.mdfiles in each service'sdocs/api/.