MIC-B v2 Binary Format

Patent Pending: STARGA Inc. US Provisional Patent Application

MIC-B v2 is a compact binary format for Mind IR graphs, designed for efficient storage and fast parsing with direct memory mapping. The binary encoding is markedly more compact than the equivalent textual IR.

Canonical IR contract: IRModule (control flow included)

mic@1text
  • full IRModule, explicit IDs
  • RFC 0001 fixed-point form
round-trip
mic@3binary
  • magic MIC3, emit with --emit-mic3
  • the trace_hash anchor

Back-compat lineage: Graph dataflow shape (demoted, never the compiled-artifact IR)

mic@2 / mic@2.1text
  • implicit IDs, compact opcodes
  • mic@2.1 adds the MAP (RFC 0014)
lossless
MIC-B v2binary
  • magic MICB, ULEB128 varints
  • Graph shape, binary
this page
mind-model@2model-exchange artifact, byte-preserving renamePending
Solid boxes are the canonical IR contract; dashed boxes are the back-compat lineage. mindc 0.10.x, RFC 0021.

The evidence-chain MAP epilogue for mic@3 ships. It attaches via the same 0x4D sentinel, is emitted by mindc --emit-evidence, and its trace_hash is the SHA-256 of the canonical mic@3 bytes.

  1. canonical mic@3 bytesthe IRModule, serialised
  2. mindc --emit-evidenceappends the evidence_chain.* MAP
  3. MAP epilogueattached via the 0x4D sentinel
  4. trace_hashSHA-256 of the canonical mic@3 bytes
mindc verify <artifact> peels the MAP and recomputes the hash over the parsed IR body. Shipped in mindc 0.10.x.

RFC 0021 (canonical-IR unification) progress

  1. Step 1Shipped
  2. Step 2Shipped
  3. Step 3Shipped
  4. Step 4Shipped
  5. Step 5Pending
  6. Step 6Pending
  • Step 5: renames this lineage to mind-model@2, a model-exchange artifact decoupled from the IR contract, as a byte-preserving migration that is still pending.
Provenance

The trace_hash anchor on canonical mic@3 bytes comes from RFC 0016 GAP-1, re-anchored 2026-05-31. This status note reflects the post-RFC 0021 state of mindc 0.10.x: RFC 0021 steps 1 to 4 are shipped; step 5 (the rename to mind-model@2) is pending.

Key Features

More compact

than the mic@2 text format

mic@278 B
MIC-B~55 B

residual block example, below

ULEB128 varints

for space-efficient integers

300 = 0b00000100101100

AC101011000200000010

low group first; the top bit says “more follows”

String table deduplication

for repeated identifiers

[0]"128"stored once
T0 f16 [0, 0]T1 f16 [0]

three uses, one copy, from the example

Deterministic

same graph produces identical bytes

emit55 B→da317a29…
emit again55 B→da317a29…

SHA-256 of the example bytes: equal

Lossless roundtrip

with mic@2

mic@2GraphMIC-B

parse_mic2 / emit_micb and back, nothing lost

Wire Format Layout

  1. 0-3Magic: "MICB" (4 bytes ASCII)
  2. 4Version: 0x02
  3. 5+String Table
  4. ...Symbol Table
  5. ...Type Table
  6. ...Value Table
  7. ...Output (1 uleb128)
Offset, then content. A 5-byte fixed header (shaded), then the four tables and the output, with no padding between sections.

ULEB128 Encoding

Unsigned Little-Endian Base-128 encoding uses 7 bits per byte for data, with the MSB as a continuation flag:

ValueEncoded Bytes
0[0x00]
127[0x7F]
128[0x80, 0x01]
16383[0xFF, 0x7F]
16384[0x80, 0x80, 0x01]

Zigzag Encoding

Signed integers use zigzag encoding before ULEB128 for efficient representation of small negative values:

// Zigzag mapping
0  →  0
-1 →  1
1  →  2
-2 →  3
2  →  4
...

// Formula
encode(n) = (n << 1) ^ (n >> 63)
decode(z) = (z >> 1) ^ -(z & 1)

Table Structures

1. String Table

Interned strings for names and dimension tokens:

uleb128     count           # number of strings
repeat count:
  uleb128   byte_length     # UTF-8 byte length
  bytes     data            # UTF-8 content (no null terminator)

2. Symbol Table

References to symbolic dimension names:

uleb128     count           # number of symbols
repeat count:
  uleb128   string_idx      # index into string table

3. Type Table

Tensor type definitions:

uleb128     count           # number of types
repeat count:
  u8        dtype           # data type (see table)
  uleb128   rank            # number of dimensions
  repeat rank:
    uleb128 dim_str_idx     # index into string table

Data Type Encoding

ByteType
0f16
1f32
2f64
3bf16
4-7i8, i16, i32, i64
8-11u8, u16, u32, u64
12bool

4. Value Table

Values with implicit sequential IDs:

uleb128     count           # number of values
repeat count:
  u8        tag             # 0=Arg, 1=Param, 2=Node
  ...       payload         # tag-specific data

Arg/Param Payload (tag 0 or 1)

uleb128     name_str_idx    # index into string table
uleb128     type_idx        # index into type table

Node Payload (tag 2)

u8          opcode          # opcode byte
...         opcode_params   # opcode-specific parameters
uleb128     input_count     # number of inputs
repeat input_count:
  uleb128   input_id        # value ID (must be < current)

Opcode Encoding

ByteOpcodeExtra Params
0Matmulnone
1-4Add, Sub, Mul, Divnone
5Relunone
6Softmaxsleb128 axis
7-10Sigmoid, Tanh, GELU, LayerNormnone
11Transposeuleb128 n, n × sleb128
12Reshapenone
13-15Sum, Mean, Maxuleb128 n, n × sleb128 axes
16Concatsleb128 axis
17Splitsleb128 axis, uleb128 count
18Gathersleb128 axis
255Customuleb128 name_str_idx

Binary Example

Residual block Y = relu(X @ W + b) + X (~55 bytes vs 78 bytes mic@2 text):

  • Header5 B
  • Strings11 B
  • Symbols1 B
  • Types8 B
  • Values29 B
  • Output1 B
The hex dump below, measured: 55 bytes in total, more than half of them the value table.
4D 49 43 42 02              # Magic "MICB" + version 2
05                          # 5 strings
03 31 32 38                 # "128"
01 58                       # "X"
01 57                       # "W"
01 62                       # "b"
00                          # 0 symbols
02                          # 2 types
00 02 00 00                 # T0: f16 [128, 128]
00 01 00                    # T1: f16 [128]
07                          # 7 values
00 01 00                    # Arg("X", T0)
01 02 00                    # Param("W", T0)
01 03 01                    # Param("b", T1)
02 00 02 00 01              # Node(Matmul, [0, 1])
02 01 02 03 02              # Node(Add, [3, 2])
02 05 01 04                 # Node(Relu, [4])
02 01 02 05 00              # Node(Add, [5, 0])
06                          # Output: 6

Determinism Rules

  • String table uses first-seen insertion order
  • All tables maintain graph definition order
  • Varints use minimal encoding (no zero-padding)
  • No padding bytes between sections

Rust API

use mind::ir::compact::v2::{parse_micb, emit_micb, Graph, MicbError};
use std::io::Cursor;

// Parse MIC-B binary
let mut cursor = Cursor::new(bytes);
let graph = parse_micb(&mut cursor)?;

// Emit Graph to MIC-B binary
let mut output = Vec::new();
emit_micb(&graph, &mut output)?;

// Roundtrip is deterministic
let mut cursor2 = Cursor::new(&output);
assert!(graph.eq(&parse_micb(&mut cursor2)?));

Validation

Decoders MUST verify:

  • Magic bytes are exactly "MICB"
  • Version is 0x02
  • All string indices are in bounds
  • All type indices are in bounds
  • Node inputs reference earlier values only
  • Output references a valid value

Error Handling

On invalid input, decoders SHOULD:

  • Return an error with byte offset
  • Not panic or crash
  • Not allocate unbounded memory