Expand description
Binary interface between the brink compiler and runtime.
This crate defines the types shared across the compiler/runtime boundary:
DefinitionId, opcodes, value types, line templates, and the top-level
StoryData container.
brink-runtime depends ONLY on this crate — nothing else from brink.
no_std + alloc: this crate builds without the standard library when
the default std feature is disabled (see docs/no-std-portability.md).
inkt/inkt-write (the .inkt text format, used by the intl pipeline)
are not part of the no_std surface — pest is std-oriented.
Modules§
- manifest_
field_ names - Shared JSON field-name constants for the host manifest file
(
docs/host-capability-manifest.md) — the single on-disk manifest that two independent Rust types deserialize, each reading only the subset of keys it needs (issue #911, BH follow-up deliverable 1):
Structs§
- Address
Def - An address pointing to a specific byte offset within a container.
- Address
Path - Maps a qualified author path (e.g.
knot,knot.stitch,knot.label,knot.stitch.label) to theDefinitionIdit addresses. - Alias
Entry - One old→new
DefinitionIdrename record (M-3,docs/modules-spec.md§5): the compiler emits one of these per#@was(old_name)directive — on a module, one entry per definition the renamed module currently owns; on a single definition, one entry for it. Rehydration (brink-runtime’sload_state) consults the table only on the miss path: a saved fn token, divert value, or visit-count key that the current program doesn’t recognize is looked up here before being treated as genuinely gone. - Call
Atom - A single call atom in an effect row’s direct part (
docs/effects-spec.md§2/§11): the name of anEXTERNALbinding (a call-kind), plus its capability-parameter slot and a reserved handle-parameter slot. - Choice
Flags - Flags packed into a
BeginChoiceinstruction. - Closure
EnvEntry - One bound-arg entry in a
ClosureValue’s env. - Closure
Value - The payload of a
Value::Closure— the fn token plus its bound-arg prefix (docs/t1c-spec.md§1/§6). - Container
Def - A compiled container (knot, stitch, gather, or anonymous flow block).
- Convention
Attach Field Def - Wire mirror of
brink_ir::ConventionAttachField. - Convention
Entry Def - One
@[convention]handler’s projected shape on the wire. Mirrorsbrink_ir::ConventionProjectionEntry, with one deliberate exception: there is nodispositionfield here, because every wire entry is, today, the single existingElementDisposition::Callcase — this format has no other disposition to distinguish yet, unlike the in-process type, which carries the field explicitly (ConventionProjectionEntry::disposition’s own “read what happened, don’t infer it from absence” reasoning) so a future second disposition doesn’t need a wire bump to become visible in-process. Adding a second disposition to this wire shape is exactly the kind of section-local-version bumpCONVENTIONS_PROJECTION_WIRE_VERSIONexists for — until then, this one field’s omission is a considered simplification of a currently-single-variant enum, not evidence of a lossy conversion elsewhere. - Conventions
Projection Def - The conventions projection, as it would ride the wire: every
@[convention]handler declared in the project’s one configured conventions module, ascending byorder— the same shapebrink_ir::ConventionsProjectioncarries in-process, with source spans stripped (a.inkb-loaded host has no source text to point a range at) anddispositionintentionally not carried — seeConventionEntryDef’s own doc for why. - Counting
Flags - Container-level structural flags: what the runtime counts for a container, plus the FS-3 “invisible” marker.
- Debug
Container Table - One container’s
DebugInfotable (docs/debugger-spec.md§2.2): theDebugInfosection’s NthDebugContainerTabledescribes the container atStoryData::containers[N]— addressed by the samecontainer_idxthe runtime’sContainerPositionuses, lockstep with theContainerssection, noDefinitionIdlookup needed on the read path. - Debug
Entry - One row in a container’s
DebugInfoentry table (docs/debugger-spec.md§2.2): maps a bytecode offset (within that container’s own bytecode) to the source range it was lowered from. Entries for one container are sorted ascending bybytecode_offsetso a reader can floor-lookup via binary search. - Debug
File Entry - One entry in the
DebugInfosection’s section-local file table (docs/debugger-spec.md§2.3). Index 0 is always the reserved synthetic sentinel (§2.5) —surface = Synthetic,path = ""— real files start at index 1. Paths are project-root-relative (root_relative_key), not process-cwd-relative or absolute. - Debug
Info Section - The
DebugInfosection (docs/debugger-spec.md§2,.inkbtag0x11): bytecode-offset → source-range map, plus the section-local file table it’s keyed against. Carried oncrate::StoryData::debug_infoasOption—Nonewhen not requested (dev/studio compiles and an explicit CLI debug flag opt in; release export never does, §1.2 ship policy) — distinct from the other “always present, possibly empty” section types, because presence here tracks whether debug info was requested, not merely whether any entry was produced. - Debug
Local Entry - One row in a container’s
DebugInfolocals table (docs/debugger-spec.md§3): a VM temp slot’s declared name, and optionally the source range it was declared at (for slot-reuse disambiguation). D7’s payload (docs/debugger-spec.md§3, issue #3185) — D6 emits the structural framing (an emptylocalsper container) but does not populate real entries; the wire shape ships now so D7 adds data without a layout change. - Definition
Id - A tagged 64-bit identifier for any definition in a compiled story.
- Direct
Effects - The direct part of a factored effect row (
docs/effects-spec.md§7/§11): the atoms a definition (and everything it statically calls) may perform, independent of any dispatch-cell narrowing. Mirrors the analyzer’s flatEffectRow, lowered to wire vocabulary (cells asDefinitionIds, call kinds asCallAtoms). - Dispatch
Entry - A per-dispatch entry in a factored effect row (
docs/effects-spec.md§7): the row a call through a dispatchcellcontributes, whether that dispatch is runtime-narrowable (its cell is not in the entry’s own write set), and the static fallback row used when narrowing does not apply. - Effect
RowEntry - One entry in the
EffectRowsDefinitionId → rowtable (T2-3,docs/effects-spec.md§11,docs/format-v4-rfc.md§2EffectRowsreservation): a factored effect row for one definition. - External
FnDef - An externally-bound function definition.
- Frame
Shape Def - The name-keyed frame shape for one
awaitsite (docs/flow-suspension-spec.md§4/§11): the static description of which locals cross the park at that site, so the runtime knows what to spill on park and restore on wake. - Global
VarDef - A global variable definition.
- Inkb
Index - Parsed header + offset table from an
.inkbfile. - Inkt
Parse Error - Error returned when parsing
.inkttext fails. - Line
Entry - One entry in a container’s line table.
- Line
Flags - Whitespace characteristics of a line, precomputed at compile time.
- LineId
- A reference to a specific line within a container.
- Line
Variant Group - One line-variant group (stage 1 of the shared-alternatives track,
issue #3273): the record that ties
dims.iter().product()consecutiveLineEntrys in a scope’s line table back to ONE authored source line whose inline alternatives were enumerated at recognition time. - ListDef
- A list (enum-like set) definition.
- List
Item Def - A single list item definition.
- List
Value - An ink list value: a set of list items plus their origin list definitions.
- Load
Report - What
Story::load_statecouldn’t apply, so a host can surface it rather than have data silently vanish. Globals whose name no longer exists are dropped (no slot to hold them) and reported here. Visit/turn counts are never dropped — counts for scopes the current program lacks are retained harmlessly (unused until/unless the scope returns), so they aren’t reported except when the miss-path alias lookup (M-3, docs/modules-spec.md §5) still can’t place them — seeunresolved_renamesfor a named scope, oranonymous_states_droppedfor an anonymous one. - Locale
Data - Complete locale overlay data from a
.inklfile. - Locale
Line Entry - A locale line entry — content + optional audio, no source metadata.
- Locale
Scope Table - A per-scope locale line table.
- NameId
- An index into the story name table.
- Ordered
Map removeshifts later entries down. Lookups are linear; that is the intended trade for small maps and stable ordering.- Param
Meta - Name + mode of one declared parameter of a container (T1c,
docs/t1c-spec.md§6). SeeContainerDef::params. - Projection
Value - The payload of a
Value::Projection— the root cell plus its ordered segment chain (docs/t1e-spec.md§1/§3). - Save
State - A persistent, name-keyed snapshot of a story’s game state.
- Scope
Line Table - Per-scope line table, stored separately from
ContainerDeffor locale overlay swapping (.inkl). - Section
Entry - An entry in the
.inkboffset table. - ShapeId
- Identifies a struct shape (TM-4,
docs/typed-mode-spec.md§6) within the compiled story’sStructShapessection (docs/format-spec.md, section tag0x0C). - Slot
Info - Metadata for a single interpolation slot in a template line.
- Source
Location - Source location of a line in the original
.inkfile. - Static
Site - Where a static-operand instruction’s operand sits:
buf[operand..end]holds theDefinitionId(or the linked layer’s replacement for it), andendis the offset of the next instruction. - Story
Data - The top-level compiled story: everything the runtime needs to execute.
- Struct
Shape Def - A
STRUCTshape definition (TM-4,docs/typed-mode-spec.md§6;StructShapessection,docs/format-spec.mdtag0x0C). - Suspended
Flow - The
FlowFrame— a parked flow’s durable, recompile-stable representation (docs/flow-suspension-spec.md§2, RULED). No instruction offsets ever serialize; recompile-stability rides container/DefinitionIdidentity, the same contract as the rest ofSaveState,#@was, and fn tokens. - Target
Site - Where a static-target instruction’s operand sits:
buf[operand..end]holds theDefinitionId(or the linked layer’s replacement for it), andendis the offset of the next instruction. - Visit
Entry - One visit/turn-count entry: a scope id and its count, plus (when the scope
is a named knot/stitch) an advisory author path for human inspection. The
idis the load key;pathis cosmetic. - Wake
Policy - A parked flow’s wake policy (
docs/flow-suspension-spec.md§2 point 4): await-site id + condition fn token + host-source discriminant, all name-stable. Seedocs/effects-spec.md§13.1 for the wake contract this plugs into (persistent-by-default policies,wake_once, host cancellation) — that contract’s runtime enforcement is FS-3/FS-4 scope; this type only carries the wire shape. - Weighted
Value - The payload of
Value::Map: an insertion-ordered map with scalar keys.
Enums§
- Binary
Kind - The binary operator a fused superinstruction applies
(
docs/optimizer-peephole.md§1). One byte on the wire; the mnemonic is what.inktprints. Exactly the operators that have a plain two-operand opcode of their own — a fused form is always spelled out as that opcode preceded byPushIntand/or followed byJumpIfFalse. - Capability
Param - The capability-parameter slot carried by every call atom in a factored
effect row (T2-3,
docs/effects-spec.md§11; ruled 2026-07-14,docs/t1d-spec.md§7). - Collect
Op - The collections+ operation selected by an
Opcode::Collectinstruction’s kind byte (NS-A7,docs/stdlib-spec.md§8, issue #1113). - Convention
Attach Def - Wire mirror of
brink_ir::ConventionAttachSchema— issue #2111 finding 1’s resolved field list, carried all the way to the wire shape rather than collapsing back to a bare name. - Convention
Mode Def - Wire mirror of
brink_ir::ConventionMode. - Decode
Error - Errors that can occur when decoding from bytes.
- Definition
Tag - Tag discriminant stored in the high byte of a
DefinitionId. - File
Surface - Which frontend parsed a
DebugInfofile-table entry’s file (docs/debugger-spec.md§2.3) —KindToken::rawis frontend-private (two independentProvenanceResolvernumberings), so a reader must know which resolver applies before interpreting an entry’skind_token. Recorded once per file (not per entry) since surface is a property of where the code came from, constant for every entry pointing at that file. - Global
Kind - The static-global instructions: each carries exactly one
DefinitionIdoperand naming the global variable it reads or writes.PushVarPointeris deliberately not one — its operand becomes aValue::VariablePointerthe story can hold and pass around, so it must stay an id. - Line
Content - The content of a single output line — either a plain string or a template with interpolation slots and plural selects.
- Line
Part - One segment of a
LineTemplate. - MapKey
- A scalar key for a
Value::Map. - Opcode
- A single VM instruction with its operands.
- Plural
Category - CLDR plural category.
- Proj
Segment - One path-projection segment (
docs/format-v4-rfc.md§1:segments: 0 = index i32, 1 = key value). Segment kind2 = rangeis RESERVED and never constructed in T1e (icebox #829 — sequence slices/ranges). - Schema
Type Def - Wire mirror of
brink_ir::SchemaTypeShape. - Section
Kind - Identifies a section within an
.inkbfile. - Select
Key - The key for matching a branch in a
LinePart::Select. - SeqVerb
Op - The fn-value verb selected by an
Opcode::SeqVerbinstruction’s kind byte (docs/stdlib-spec.md§4, issue #1679). - Sequence
Kind - The kind of sequence/shuffle container.
- Static
Kind - Every instruction whose sole
DefinitionIdoperand is static — a jump or call address, or a global variable — asOpcode::peek_staticclassifies it. - Target
Kind - The static-target instructions: each carries exactly one
DefinitionIdoperand, and that operand names the address the instruction jumps to or calls. SeeOpcode::peek_target. - TowerOp
- The tower operation selected by an
Opcode::Towerinstruction’s kind byte (NS-A8,docs/tower-mini-spec.md;docs/stdlib-spec.md§2b). - Value
- A runtime value in the ink VM.
- Value
Type - The runtime type of a
Value. - Wake
Source - The wake policy’s host-source discriminant
(
docs/flow-suspension-spec.md§2 point 4;docs/effects-spec.md§13.1). FS-1 records the discriminant only — the host-side wake plumbing (wake_when, dormant spawn, cancellation-to-false) is FS-4 scope; today onlySelf::Conditionis ever compiler-produced, but the format reservesSelf::Hostfor the host-driven wake sources §3 names as a future (PROPOSED-only) ink spelling, so the wire shape doesn’t need a breaking change to add it later.
Constants§
- CONVENTIONS_
PROJECTION_ WIRE_ VERSION - Section-local encoding version — independent of the whole-
.inkbVERSION, matching every other section-local-versioned table (EffectRows,AliasTable,FrameShapes) so this section’s own encoding can grow without a format-wide bump once it is wired in. - DEBUG_
FLAG_ IS_ STMT flagsbit 0: this entry marks a recommended stop location / the start of a statement (docs/debugger-spec.md§2.1’s DWARF-is_stmtdesign). v1 sets this on every entry (statement-level rows only); a later expression-level entry arrives with this bit unset, additively — no version bump, no reader change.- DEBUG_
FLAG_ PROLOGUE_ END flagsbit 1: this entry’s ownbytecode_offsetis the prologue-end landing point for a breakpoint set on the enclosing container (docs/debugger-spec.md§2.4) — past any leading parameter-bindingDeclareTemps / choice-output prologue bytes. At most one entry per container carries this bit.- DEBUG_
FLAG_ RESERVED_ MASK - Bits 2–7 of
flagsare reserved. Perdocs/debugger-spec.md§2.2’s explicit, ruled departure from this format’s default strict-rejection posture, aDebugInforeader must ignore any reserved bit it does not recognize rather than reject the entry — this constant exists so callers can mask deliberately (e.g. a round-trip test asserting v1 never sets a reserved bit) without hand-writing the mask twice. - MAX_
DECODE_ DEPTH - Maximum nesting depth permitted when decoding
VAL_ARRAY/VAL_MAPvalues. Generous for legitimate data but bounds worst-case recursion so a crafted file of nested single-element arrays (~5 bytes/level) cannot stack-overflow the reader (CLAUDE.md “guard against unbounded growth”; issue #553). - SAVE_
FORMAT_ VERSION - Current
SaveStateformat version. Bump when the format changes (independent of the story’s own content);versionlets a loader migrate. - SUSPENDED_
FLOW_ SECTION_ VERSION - Current suspended-flow section version, versioned independently of
SAVE_FORMAT_VERSION(docs/flow-suspension-spec.md§9 FS-1: “one new suspended-flow section, section-locally versioned”). Bump when theSuspendedFlowshape itself changes; the rest ofSaveStateis unaffected.
Traits§
- Plural
Resolver - Trait for resolving plural categories at runtime.
Functions§
- assemble_
inkb - Assemble a complete
.inkbfile from pre-encoded section buffers. - content_
hash - Compute a stable hash of source text — FNV-1a, 64-bit, over the UTF-8 bytes.
- read_
conventions_ projection - Read a conventions-projection section written by
write_conventions_projection.buf/offsetare a raw cursor, not an.inkb-indexed section range — this codec is not wired intocrate::inkb::InkbIndexyet (see this module’s own doc). - read_
inkb - Decode a
StoryDatafrom.inkbbinary format. - read_
inkb_ index - Parse the
.inkbheader and offset table without touching section data. - read_
inkl - Decode a
LocaleDatafrom.inklbinary format. - read_
inkt - Parse
.inkttext into aStoryData. - read_
section_ address_ paths - Read the address-paths section using a pre-parsed index.
- read_
section_ addresses - Read the addresses from a complete
.inkbfile using its index. - read_
section_ alias_ table - Read the M-3
AliasTablesection (docs/modules-spec.md§5) from a complete.inkbfile using its index. Absent section (a pre-M-3 file, or a story with no#@wasdirectives) decodes as empty, mirroringread_section_literal_pool. The section-local version byte is checked independently of the whole-fileVERSION— see [ALIAS_TABLE_SECTION_VERSION]. - read_
section_ containers - Read the containers from a complete
.inkbfile using its index. - read_
section_ debug_ info - see
crate::StoryData::debug_info’s doc for why presence itself is meaningful here. - read_
section_ effect_ rows - Read the T2-3
EffectRowssection (docs/effects-spec.md§11) from a complete.inkbfile using its index. Absent section (converter output, or a story compiled before this slice) decodes as empty, mirroringread_section_alias_table. The section-local version byte is checked independently of the whole-fileVERSION— see [EFFECT_ROWS_SECTION_VERSION]. - read_
section_ externals - Read the externals from a complete
.inkbfile using its index. - read_
section_ frame_ shapes - Read the FS-3
FrameShapessection (docs/flow-suspension-spec.md§4/§11) from a complete.inkbfile using its index. Absent section (every story compiled behind the E052 fence, and all converter output) decodes as empty, mirroringread_section_visibility. The section-local version byte is checked independently of the whole-fileVERSION— see [FRAME_SHAPES_SECTION_VERSION]. - read_
section_ line_ tables - Read the line tables from a complete
.inkbfile using its index. - read_
section_ list_ defs - Read the list definitions from a complete
.inkbfile using its index. - read_
section_ list_ items - Read the list items from a complete
.inkbfile using its index. - read_
section_ list_ literals - Read the list literals from a complete
.inkbfile using its index. - read_
section_ literal_ pool - Read the T1b literal pool from a complete
.inkbfile using its index. Absent section (older-shaped buffer within the same version) decodes as empty, mirroringread_section_list_literals. - read_
section_ name_ table - Read the name table from a complete
.inkbfile using its index. - read_
section_ struct_ shapes - Read the TM-4
StructShapessection from a complete.inkbfile using its index. Absent section decodes as empty, mirroringread_section_literal_pool. - read_
section_ variables - Read the variables from a complete
.inkbfile using its index. - read_
section_ visibility - Read the M-2b
Visibilitysection (tag0x0E) from a complete.inkbfile using its index — theDefinitionIds of every#@privatedefinition. Absent section decodes as empty (the all-public common case), mirroringread_section_struct_shapes. - write_
conventions_ projection - Write the conventions-projection section (no header framing beyond its
own section-local version byte, matching
CONVENTIONS_PROJECTION_WIRE_VERSION): entry count, then each entry in the order given. Callers sort/dedupe before calling — this function trusts its input’s order, the same posture every writer in this crate takes toward its own table. - write_
inkb - Encode a
StoryDatainto the.inkbbinary format with sectioned header. - write_
inkl - Encode a
LocaleDatainto the.inklbinary format. - write_
inkt - Write the textual (.inkt) representation of a compiled story.
- write_
section_ address_ paths - Write the address-paths section (no header framing).
- write_
section_ addresses - Write the addresses section (no header framing).
- write_
section_ alias_ table - Write the M-3
AliasTablesection (no header framing): a one-byte section-local version, then a flat list of old→newDefinitionIdpairs (docs/modules-spec.md§5). Entries are written in the order given — callers sort byoldfor the runtime’s binary-search lookup. - write_
section_ containers - Write the containers section (no header framing).
- write_
section_ debug_ info - write_
section_ effect_ rows - Write the T2-3
EffectRowssection (no header framing): a one-byte section-local version, then theDefinitionId → rowtable of factored effect rows (docs/effects-spec.md§11). One entry per knot/stitch — the host’s resume-scheduling estimate (§12.1). Entries are written in the order given; callers sort bydeffor determinism. - write_
section_ externals - Write the externals section (no header framing).
- write_
section_ frame_ shapes - Write the FS-3
FrameShapessection (no header framing): a one-byte section-local version, then one entry perawaitsite (docs/flow-suspension-spec.md§4/§11) — the site’s stableDefinitionId(the synthesized continuation container id) followed by its name-keyed crossing-local slots. Entries are written in the order given; callers sort bysitefor determinism. Callers emit this section only when non-empty. - write_
section_ line_ tables - Write the line tables section (no header framing).
- write_
section_ list_ defs - Write the list definitions section (no header framing).
- write_
section_ list_ items - Write the list items section (no header framing).
- write_
section_ list_ literals - Write the list literals section (no header framing).
- write_
section_ literal_ pool - Write the T1b literal pool section (no header framing) — a flat list of
content-hash-deduplicated constant
Values referenced byPushLiteral(idx)(docs/format-v4-rfc.md§2). Each entry uses the existing genericencode_value(the same recursiveVAL_ARRAY/VAL_MAPtree encoding as aGlobalVarDefdefault). - write_
section_ name_ table - Write the name table section (no header framing).
- write_
section_ struct_ shapes - Write the TM-4
StructShapessection (no header framing): one entry per declaredSTRUCT— shape id, name, then its ordered fieldNameIds (docs/format-v4-rfc.md§2). Empty (count 0) until a compiler milestone emits struct declarations — see the PR description’s scope note. - write_
section_ variables - Write the variables section (no header framing).
- write_
section_ visibility - Write the visibility section (no header framing): a count followed by the
DefinitionIdof every#@privatedefinition (M-2b). Callers only emit this section whenprivate_defsis non-empty.
Type Aliases§
- Line
Template - A sequence of literal and dynamic parts that compose an output line.