Wire format
This page documents Orleans.Lattice.Schema 9.9.0, in the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at wire-format.md, and llms.txt lists every page.Schema versioning stamps each stored value with a small,
fixed-layout envelope header so a reader can tell which schema version a value was
written at before it interprets the body. This page documents that header. The
layout is frozen: it is on-disk and on-the-wire contract, and it never changes
for a given FormatVersion.
Envelope header
An envelope is a 10-byte big-endian header followed by the plain value body:
| Offset | Size | Field | Value / meaning |
|---|---|---|---|
| 0 | 1 | Magic |
0xFE - a reserved discriminator that is not a valid UTF-8 lead byte. |
| 1 | 1 | FormatVersion |
0x01 - the envelope-format version (distinct from the per-value schema version). |
| 2..5 | 4 | schema id | uint, big-endian - which logical schema family the value belongs to. |
| 6..9 | 4 | schema version | uint, big-endian - the version the body's shape conforms to. |
| 10.. | n | body | The plain value bytes (UTF-8 / JSON). |
The relevant constants are LatticeSchemaEnvelope.Magic,
LatticeSchemaEnvelope.FormatVersion, and LatticeSchemaEnvelope.HeaderLength.
The same static class reads and writes the header: IsEnveloped reports whether a
value is at least HeaderLength bytes long and starts with the magic and the
recognised format version, TryReadHeader returns the schema id and version of
an enveloped value, Encode prepends a header to a plain body, and StripToBody
returns the bytes after the header (it checks only that the value is at least
HeaderLength bytes long).
Default omission
The envelope is default-omitted. A value written to an opted-out tree (one
with no version config), or a legacy value written before its tree opted in,
carries zero extra bytes - its byte shape is byte-for-byte identical to a plain
lattice value. Version 0 is the reserved "unversioned" sentinel, represented by
the absence of a config: the LatticeSchemaVersionConfig constructor rejects a
target version of 0, and a local whole-value write to an opted-in tree is always
stamped at its target version (an already-stamped value is kept as-is). This is what keeps
versioning zero-overhead when unused and keeps a migration incremental: stamped and
un-stamped values coexist in the same tree.
Why 0xFE
0xFE is never a valid UTF-8 lead byte, so a stored UTF-8 or JSON body never
begins with it. That makes an un-stamped legacy value unambiguously distinguishable
from a stamped one on read: the decoder treats a value that does not start with the
magic and a recognised format version as an unstamped body and returns it verbatim.
Discriminator caveat. The single-byte magic cleanly disambiguates UTF-8 / JSON bodies. An arbitrary binary blob whose first bytes legitimately begin with the magic-and-format-version pattern cannot be perfectly distinguished from a real envelope. Schema versioning therefore targets text / UTF-8 payloads; do not enable it on trees storing arbitrary opaque binary values.
Forward compatibility
A value stamped with a newer schema version than a reader's target version - or
one whose stored version cannot be upcast to the target - surfaces
NotSupportedException on read, the same behaviour as an unknown compressor. This
is deliberate: rather than silently mis-decode, the reader fails loudly so an
operator upgrades the reader's registry or target version.
An unrecognised format version is handled differently: it does not throw.
The envelope check requires both the magic byte and the recognised
FormatVersion (0x01), so a value whose second byte is any other format version
fails the check, is treated as an un-stamped (plain) body, and is passed through
verbatim. The reserved FormatVersion byte therefore lets a future header shape
coexist with 0x01: a reader that does not recognise the newer format falls
through and returns the payload unchanged rather than failing.
See also
- Schema versioning - the capability that writes the envelope.