CBDF Specification: Meta Section
Version 1.1 (Phase II)Document: 02-Meta-Section • Date: 2026-07-13
1. Overview
The Meta section is the first section of every CBDF document. It is the document envelope: identity, routing, previews, format options, and (in local storage only) Tell/RAIDA attestations.
Meta is never compressed. Clients can read it without decompressing Styles/Text. In QMail, private Meta may be uploaded as Tell manifest file_type=0, separate from the public Tell notification.
2. Meta Format
[Pair Count: 2 bytes LE]
[Key ID: 1][Value Length: 1][Value: N bytes] × Pair Count
- Pair count includes every repeated key (e.g. each To recipient).
- Value length is 0–255 only. There is no extended-length sentinel. A length of
0xFFmeans 255 value bytes. Extended length would desynchronize deployed Phase I skippers. - Unknown keys: skip by reading key + length + value (forward compatible).
- Keys may appear in any order. Encoders SHOULD emit key 0 then key 30 early.
- Values larger than 255 bytes belong in Text, Resources, or extension sections — not Meta (without a future key-30 format bump).
3. Key Registry
3A. Phase I keys (deployed — must match qmail_cbdf.h)
| Key | Name | Size | Req | Description |
|---|---|---|---|---|
| 0 | Meta File Type | 1 | * | 0 generic, 1 qmail, 2 sms, 3 qweb, 4 presentation (rsv), 5 form (rsv), 6–255 rsv. Canonical document type. Key 34 is retired. |
| 1 | QMail ID (GUID) | 16 | * | Sender-assigned; equals Tell email_id |
| 2 | Subject | ≤255 | Plain UTF-8 | |
| 3 | Attachment Name | var | Repeated, attachment order | |
| 4 | Attachment Total Pages | 2 LE | Repeated dense; 0=legacy; >0 estimate | |
| 5 | Page Hash | 4 LE | Optional CRC32 per page | |
| 12 | Attachment Count | 1 | * | 0–255 |
| 13 | To Mailbox | 7 | * | Repeated |
| 14 | CC Mailbox | 7 | Repeated | |
| 19 | From Mailbox | 7 | * | Sender claim |
| 25 | Timestamp | 4 LE | * | Unix seconds; low 32 bits of key 41 when both present |
* = Required for QMail documents. Keys 6–11, 15–18, 20–24, 26–29 reserved.
3B. Phase II keys
| Key | Name | Size | Description |
|---|---|---|---|
| 30 | Version | 1 | Absent = Phase I; 1 = Phase II (required in v1) |
| 31 | Compression Type | 1 | 0 none, 1 zlib (MTI), 2 LZ4, 3 Zstd, 4 Brotli, 5 semantic (experimental) |
| 32 | Default Style Set | 1 | 0 explicit, 1 client default, 2–255 named sets |
| 33 | EOF Flag | 1 | 1 = meta-only document |
| 34 | RETIRED | — | Never emit; never reassign (was duplicate document type) |
| 35 | AI Summary | ≤255 | UTF-8 inbox summary / fallback |
| 36 | Preview Text | ≤255 | UTF-8 snippet; SHOULD on all v1 during transition |
| 37 | Subject Style ID | 1 | Text style index for inbox listing |
| 38 | Semantic Model | 20 | Only if compression=5: model id + version hash |
| 39 | Semantic Flags | 1 | Only if compression=5 |
| 40 | Text Offset | 4 LE | Optional. Offset from start of containing object to Text section length prefix. Uncompressed only; MUST be absent if key 31 ≠ 0 |
| 41 | Timestamp64 | 8 LE | Unix epoch seconds (not ms). Prefer over 25 |
| 42 | Required Features | 1–4 | Bitfield LE; trailing zeros omitted; absent=0. See §4 |
| 43 | Optional Features | 1–4 | Same shape; same bit registry |
| 44 | Content Language | ≤35 | BCP 47 UTF-8 (e.g. en, fr-CA) |
| 45 | Content Hash | 1+N | [alg:1][digest] — see §5 |
| 46 | Body Format | 1 | 0 native CBDF text/styles (also the default when absent), 1 plain UTF-8, 2 Markdown source UTF-8 (CommonMark), 3 HTML source UTF-8; 4–255 reserved. Private metadata; never added to Tell. Singleton, length MUST equal 1. |
| 47–199 | Reserved | Sender-written future keys | |
| 200–219 | Receiver Annotations | var | Never valid on the wire — see §7 |
| 220–255 | Reserved |
When key 33 = 1 (meta-only), keys 31/32/37/40/42/43 are meaningless and MUST be absent.
Body Format (key 46)
The sender MUST set key 46 from the intended compose format, not infer it from message contents. The private Meta object (Tell manifest file_type=0) carries this field; Tell packet layouts, tell_type and manifest file_type remain unchanged. Absent means native CBDF, preserving existing styled documents.
Values 1–3 use the existing Text section framing, with the source text carried literally inside STX/ETX. CBDF transport escaping/framing is decoded before interpreting the source. CBDF styles, list inference and automatic URL conversion MUST NOT alter this source. Normalize CRLF and bare CR to LF. The field describes the entire body, not attachments or the subject.
Receivers MUST preserve the original source for drafts, editing and forwarding. Rendering is a temporary view. Markdown uses CommonMark; optional extensions may vary by client. HTML clients MAY support a documented static subset. Scripts, active content and automatic external resource requests MUST be disabled.
Unknown or unsupported values MUST fall back to visibly labeled source text. Older clients MAY ignore key 46 and display all source as plain text; faithful formatted rendering is not required for compatibility. Duplicate key 46 or lengths other than 1 are malformed; receivers MUST NOT select an active renderer from a malformed field. Meta-only objects MUST omit key 46.
2E 01 02 ; key 46, value length 1, Markdown source
4. Feature Flags (keys 42 and 43)
Both keys are little-endian bitfields of 1–4 bytes with trailing zero bytes omitted. Absent key means 0.
| Key | Semantics |
|---|---|
| 42 Required | Document is not faithfully renderable without these features. Unsupporting client MUST warn and/or show labeled plain-text fallback — never silently pretend full fidelity. Not a security boundary. User accessibility settings always override (e.g. motion). |
| 43 Optional | Soft hints; use if supported, else silent fallback. |
Encoders MUST set bits only for features actually used (truthful encoding).
| Bit | Feature |
|---|---|
| 0 | Non-default / explicit styles beyond client default set |
| 1 | Images / non-empty Resources |
| 2 | Tables |
| 3 | Nav / structured item blocks |
| 4 | Custom fonts (IDs 4000–4094) |
| 5 | Font effects / animation |
| 6 | Frames / embedded documents |
| 7 | AI prompts |
| 8 | Semantic encoding |
| 9 | Extension sections present |
| 10 | Rare-tier styles |
| 11 | Catalog layout used (LayoutID ≥ 0x0100) |
| 12–31 | Reserved |
5. Content Hash (key 45)
[alg:1][digest:N]
alg 1 = MD5, N = 16
alg 2 = SHA-256, N = 32
0, 3–255 reserved
Canonical hash input (decompressed representation, hashed verbatim):
[StylesLen:4 LE][Styles bytes] FS [TextLen:4 LE][Text bytes]
[ResourcesLen:4 LE][Resources bytes]
This matches the decompressed Styles+Text blob (including the interior FS) plus the Resources section. Exclude Meta, outer FS markers, and Logic. When uncompressed, the Styles+Text portion is identical to the on-wire bytes after the first FS through Text.
6. Mailbox Address Format
All mailbox fields (To, CC, From, Verified Sender) are exactly 7 bytes:
| Offset | Size | Field |
|---|---|---|
| 0 | 2 | Coin Group (CloudCoin = 0x0006; canonical deployed bytes 00 06) |
| 2 | 1 | Denomination |
| 3 | 4 LE | Serial Number |
CloudCoin mailbox addresses MUST encode the coin-group field exactly as the deployed v0 encoder does: bytes 00 06 at offsets 0–1. This is the normative CBDF wire form for CloudCoin mailbox fields.
7. Tell Integration and Receiver Annotations
Claims vs attestations: Meta keys 0–199 are sender-written claims. The QMail Tell (Peek/Ping) carries RAIDA-confirmed GUID, sender, timestamp, locker, servers, and manifest. Integration is cross-check + annotate, never merge on the wire.
7A. Cross-check rules (receive time)
- GUID: Tell
email_id≠ key 1 → hard reject the object. - Sender: Tell ≠ key 19 → display Tell identity; flag Meta as conflicting claim. ("Unverified" is for documents with no Tell.)
- Timestamp: Tell is authoritative sent time; Meta 25/41 is sender clock; skew > 48h SHOULD be surfaced.
- Attachments: Tell manifest wins for downloadable set; Meta supplies display names.
- CRC: fail integrity → labeled plain-text fallback, never partial styled phishing render.
- Badges: verified UI derives only from Tell-derived annotations 200–219.
7B. Receiver annotation keys (200–219)
Written only by the receiving client into local storage. Tell multi-byte scalars are big-endian on the wire; re-encode to LE in annotations except raw opaque entries.
| Key | Name | Size | Content |
|---|---|---|---|
| 200 | Verified Sender | 7 | Mailbox LE from Tell |
| 201 | Verified Timestamp | 4 LE | Tell timestamp |
| 202 | Tell Type | 1 | 0 mail / 1 receipt / 2 deleted |
| 203 | Verification Status | 1 | bit0 GUID, 1 sender, 2 time, 3 manifest, 4 CRC |
| 204 | Total File Size | 4 LE | From Tell |
| 205 | Locker Code | 16 | Persist by default until downloads complete; SHOULD encrypt at rest; MAY wipe after complete |
| 206 | Server Location Entry | 32 | Repeated, raw Tell entry |
| 207 | Manifest Entry | 16 | Repeated, raw Tell v1 entry |
| 208 | Annotation Write Time | 8 LE | Optional |
| 209–219 | Reserved |
Anti-forgery (absolute)
Keys 200–219 MUST NOT appear on the wire. Clients MUST strip them on import/network receive before trust decisions, and MUST strip on send/forward/export. Locker, servers, and manifests MUST never be emitted in sender keys 0–199.
8. Styled Subject
- Key 2 — plain UTF-8 (search, notifications, extraction)
- Key 37 — text style for inbox listing
- SOH block inside Text — fully styled subject when opened
Plain-text extraction of the SOH block SHOULD equal key 2 (truncation aside). Clients MAY flag a mismatch as spoof risk.
9. Timestamp Policy
Key 41 = uint64 LE Unix seconds (not milliseconds). Key 25 remains required for Phase I compatibility and equals key 41's low 32 bits when both are present. Strict parsers verify truncation consistency and prefer key 41.