---
url: /spec/v3.md
---
# v3 Reference Profile

Twilic v3 is the current documentation-first reference profile. The full normative document is maintained in the [twilic repository](https://github.com/twilic/twilic/blob/main/versions/v3.md).

## Reference Defaults

Unless an enclosing transport/profile explicitly declares otherwise, the v3 reference profile uses these defaults:

| Area | Default |
| --- | --- |
| Bound layout | `layout_kind = compact` |
| Schema identity | `schema_id` present in `SCHEMA_OBJECT`, `BOUND_STREAM`, and `SCHEMA_BATCH` |
| Bound stream count | `count` present in `BOUND_STREAM` |
| Schema batch count | `column_count` present in `SCHEMA_BATCH` |
| Schema batch field | `field_id` omitted in strict schema-order compact mode |
| Integer `auto` | resolved before `SCHEMA_OBJECT` or stream use; not left ambiguous on the wire |

One resolved schema identity must not refer to multiple incompatible `layout_kind` or resolved physical-encoding choices.

## Required Interoperability Surface

The v3 reference profile defines interoperable behavior for:

* Dynamic tag-table values where tags are unchanged from v2.
* Dynamic canonical integer encoding and message-local `key_id`, `str_id`, and `shape_id` allocation.
* `SCHEMA_OBJECT` compact Bound field payloads.
* `BOUND_STREAM` compact record bodies.
* `SCHEMA_BATCH` schema-order column batches.
* `PLAIN` and `DIRECT_BITPACK` payload grammars.

Other registered codec codes and stateful layouts are extension points unless a negotiated profile defines their exact payload grammar and state semantics.

## Compatibility

v3 is a clean break from v2 for Bound Profile field/record-body payloads. A v3 decoder is not required to decode v2 Bound payloads.

Dynamic Profile may remain v2-compatible where tags are unchanged.

Implementations that support multiple profiles or versions must use an explicit external profile and version discriminator. Payload auto-detection is not defined.

## Benchmark Contract

Benchmark reports should disclose byte buckets and framing assumptions.

* `BOUND_STREAM message bytes` include `0x0F`, schema/count when present, presence strategy, and record bodies.
* `raw record-body bytes` include only `record_body_*` and must report excluded framing separately.
* `SCHEMA_BATCH` batch bytes include `0x0E`, in-band `schema_id` when present, count, in-band `column_count` when present, column headers, presence, codec metadata, and payloads.
* Generic compression or trained dictionaries must report uncompressed Twilic too and include wrapper bytes, `dict_id`, dictionary metadata, distribution cost, or an explicit amortization policy.

Schema-shared comparisons must let baselines share schema under the same assumptions.
