Skip to content

Stability

Tim Mcguinness edited this page Apr 24, 2026 · 1 revision

Stability and Versioning

VTX has three independent versioning surfaces. They evolve on separate cadences and have separate compatibility rules. This page documents the policy.

  • Public C++ API (headers under sdk/include/vtx/).
  • On-disk format (the .vtx file layout, including header, chunk encoding, and footer).
  • Schemas (the schema.json files produced by the Schema Creator and embedded in recorded files).

The maturity headline: VTX is pre-1.0. Until 1.0, any of the three surfaces can change incompatibly between releases. We try not to, and we call it out in CHANGELOG.md when we do.

Public C++ API

Policy after 1.0

Semantic versioning. Given a public release MAJOR.MINOR.PATCH:

  • PATCH bumps: bug fixes. No API changes. Drop-in upgrade.
  • MINOR bumps: additive API changes. New functions, new enums, new struct fields with safe defaults. Existing callers keep compiling and linking.
  • MAJOR bumps: breaking API changes. Removed or renamed symbols, changed signatures, changed semantics. A migration note lands in CHANGELOG.md.

Policy before 1.0

Minor bumps may include breaking changes. We try to keep them to recognisable boundaries (a release, a deprecation window) but will not guarantee ABI or source compatibility. Pin a specific tag if stability matters to you during this period.

What counts as "public"

  • Any header under sdk/include/vtx/ and the symbols declared in it.
  • Behaviour documented in this wiki, the repo docs/, or header comments.

Internal headers under sdk/src/ and anonymous-namespace / detail:: code are not public. Do not depend on them; they change without notice.

ABI

No ABI stability guarantee, at any version. The SDK is distributed as source and built per-project. Do not ship VTX as a shared library to consumers that build against mismatched headers.

On-disk format

Policy

Every .vtx file carries a format version in its header. Readers check this on open.

  • Minor format changes (new optional fields, new chunk types, new compression codecs announced via the header) are backward-compatible: newer readers read older files.
  • Major format changes bump the major format version. Older readers refuse to open newer-major files with a clear error. A conversion tool is shipped when a major bump happens.

What's stable

  • The four-section layout (header / schema / chunks / footer).
  • Little-endian encoding throughout.
  • VTXP / VTXF magic bytes.
  • Zstd as the chunk compression codec.

What's in flux pre-1.0

  • The exact byte layout of chunk metadata. Follow docs/FILE_FORMAT.md for the current layout.
  • The footer's index entry shape. The current design (time + frame index + byte offset + chunk length) is stable in intent; the concrete struct can still shift.
  • String-valued entity IDs are likely to become interned integer IDs in a future release. That change will be backward-compatible at read time (readers handle both forms). See Concepts, Strings.

What we will not do

  • Silent format changes. Every change that affects the on-disk bytes bumps the format version.
  • Reader hostility. An older reader encountering a newer file fails loudly, not quietly.

Schema evolution

Schemas define the property/type/bucket layout for a specific title or domain. They live outside the SDK (you author them) but the embedded schema in each file pins the schema a given capture was recorded against.

Backward-compatible changes

Safe. Older readers can decode files recorded with the new schema. Examples:

  • Adding a new property to an existing struct.
  • Adding a new struct.
  • Adding a new bucket.
  • Adding a new enum value.
  • Renaming display names (the human-readable label). The underlying property ID is what matters on disk.

Breaking changes

Not safe. Require a schema major-version bump. The Schema Creator detects these when you load an existing schema as a baseline and refuses to save a "next generation" that contains any of them:

  • Removing a property.
  • Changing a property's typeId to an incompatible type (e.g. Int32 to String).
  • Changing a property's ID.
  • Removing a struct or a bucket.
  • Moving a struct between buckets.

Forward compatibility

New fields in a newer schema are ignored by older readers: Protobuf drops unknown fields silently; FlatBuffers' vtable layout gives the same effect. An older reader sees the subset of the capture it knows about and keeps working. This is the main reason the SDK insists on schema-defined, evolvable formats and rejects schemaless options (Cereal, Bits).

Schema versions in the file

Each VTX file's header carries:

  • The SDK format version (see above).
  • The schema version the capture was recorded against.

A reader can refuse to open a capture whose schema version it cannot decode, or (with a compatible schema) decode only the subset it understands.

Deprecation process

After 1.0, a public API symbol or format field that we intend to remove goes through:

  1. Deprecation: marked with [[deprecated("...")]] (for code) or called out in docs/FILE_FORMAT.md (for format). Shipped in a minor release.
  2. Warning window: at least one minor release with the deprecation in place before removal.
  3. Removal: in the next major release.

Breaking changes do not skip the window. If we need to make one without a window (security issue, protocol-breaking bug), we will say so explicitly in CHANGELOG.md.

Reporting breakage

If you hit a compatibility problem that this page says shouldn't be possible, it's a bug. Open an issue with:

  • SDK version (tag or commit).
  • File format version from the header (or the file itself if you can share it).
  • Minimal reproducer.

Security-sensitive reports: follow SECURITY.md instead.

Clone this wiki locally