9. Versioning

July 26, 2026 · View on GitHub

The Open Backtest Format uses Semantic Versioning 2.0.0 applied to the specification as a whole.

Version dimensions

Two distinct versions are visible in a bundle:

  • Envelope version — the uint32 in the 8-byte header. This is a single integer that tracks the major version of the format. It is what readers use to decide whether they can read a bundle at all.
  • Spec document version — the semver string in CHANGELOG.md. This tracks non-envelope-breaking changes (new reserved field names, new reserved vocabulary values, clarifications, editorial fixes).

The two are related but not identical: a bump of the envelope integer implies a major spec bump; a minor or patch spec bump MUST NOT change the envelope integer.

When to bump

ChangeEnvelopeSpec majorSpec minorSpec patch
Remove or rename a MUST-level field
Change the wire encoding (compression codec, msgpack → cbor)
Change the semantics of an existing field
Add a new reserved field (backwards-compatible)
Add a new reserved sample_type / method / model type value
Promote an inline field to blob-extractable
Clarify prose without changing behaviour
Fix typos

Reader compatibility rules

  • A reader MUST reject bundles whose envelope version is higher than its maximum supported envelope version.
  • A reader MUST accept bundles whose envelope version is lower than its maximum supported version, back to envelope version 1.
  • Additive changes within a single envelope version (spec minor bumps) MUST be safe for older readers that follow 7. Reader contract — specifically the tolerance requirements.

Writer compatibility rules

Deprecation policy

  • Once shipped in a 1.x spec release, a field or reserved vocabulary value MUST NOT be removed within the same major envelope version.
  • Fields MAY be marked deprecated in the spec; deprecated fields MUST continue to round-trip.
  • Removal only happens at an envelope-version bump.

Pre-1.0

While the spec is at 0.x, the rules above are aspirational. Breaking changes MAY occur between 0.x releases with clear changelog entries and no envelope bump. The purpose of the 0.x phase is to shake out design bugs before we lock the wire format.