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–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.
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.