Skip to main content

Module transcript

Module transcript 

Source
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§

TranscriptData
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§

TranscriptError
Errors from transcript serialization/deserialization.

Functions§

read_transcript
Deserialize a transcript from the .brkt binary format.
render_transcript
Re-render a transcript against the given line tables.
write_transcript
Serialize a transcript to the .brkt binary format.