Expand description
Transcript binary serialization (.brkt format).
A transcript is a serialized Vec<OutputPart> — the append-only log of
all output parts produced during story execution. Combined with an .inkb
program and optional .inkl locale data, a transcript can be re-rendered
in any language without re-executing the story.
§Binary format
Header (16 bytes):
b"BRKT" magic (4)
u16 LE version = 1 (2)
u16 LE reserved (2)
u32 LE source_checksum (4)
u32 LE content CRC-32 (4)
Body:
u32 LE top-level part count
[Part]* encoded top-level parts
u32 LE fragment count
( u32 LE this fragment's part count
[Part]* encoded fragment parts
)*
( u32 LE this fragment's tag count -- #953, trailing section
[str]* tags, in fragment order (see below)
)*Both “part count” fields above count only persisted parts —
OutputPart::Checkpoint is a transient capture marker that is filtered
out before encoding (see [is_persisted]) and contributes zero bytes to
[Part]*, so the count must exclude it too or a reader following this
doc to extend the format would write parts.len() and produce a byte
stream whose declared count disagrees with what it actually encoded.
OutputPart::ElementAttach/ElementAttachEnd (issue #2108) are the same
kind of transient, zero-byte marker for the identical reason —
deliberately in-memory-only; see that variant’s own doc.
The fragment section and the trailing fragment-tags section are both
backward-compat optional: read_transcript treats “no bytes left”
at either boundary as “this section is absent”, not as truncated input,
and falls back to an empty Vec (zero fragments, or every fragment’s
tags: Vec::new()) rather than erroring. This lets a .brkt written
before a section existed keep decoding under a newer reader.
The fragment-tags section is written as a distinct trailing section
after every fragment’s parts — one (tag count, [str]*) block per
fragment, in the same order the fragments themselves were written —
rather than inlined into each fragment’s own record. An inline layout
could not tell “this fragment has a tags section” apart from “the next
fragment’s part bytes happen to start here” once a .brkt written
before tags existed was read by tags-aware code; the trailing-section
layout sidesteps that ambiguity by using the same “any bytes left?”
probe already used for the fragment section itself. Fixes #953:
Fragment::tags was silently dropped by this codec. See
write_transcript/read_transcript below for the code-level version of
this note.
A third trailing section (as the .inkb v6 bump is expected to add) is
not yet safe to bolt on the same way: see
docs/brkt-trailing-section-findings.md for a traced report of exactly
what breaks and why, written as input to #1519’s design pass.
Structs§
- Transcript
Data - A decoded transcript: the output parts, the source program’s checksum (to verify compatibility before rendering), and the captured fragments (for re-rendering choice display text and computed substrings).
Enums§
- Transcript
Error - Errors from transcript serialization/deserialization.
Functions§
- read_
transcript - Deserialize a transcript from the
.brktbinary format. - render_
transcript - Re-render a transcript against the given line tables.
- render_
transcript_ with_ source - Like
render_transcript, but keeps each line’s provenance — the firstLineRef’s line-tablesource_location(the same rule the live delivery stream uses, W7/#3300). The studio’s re-render road (RULED 2026-08-30, “Studio saves carry the structural transcript”) needs the provenance chips to survive a restore, not just the text. - write_
transcript - Serialize a transcript to the
.brktbinary format.