CBDF Specification: Meta Section (QMail)
Version 1.0 (Phase I + Phase II)Document: 02-Meta-Section • Date: 2026-03-25
1. Overview
The Meta section is the first section of every CBDF document. It contains key/value pairs that describe the document's identity, routing, formatting options, and preview content.
For QMail beta, the Meta section is stored as the private file_type=0 object and is downloaded from the storage RAIDAs after the public Tell envelope is received. This lets an email client fetch subject, preview text, attachment names, and other display metadata without downloading the full body or attachments, while keeping those fields out of the beacon-visible Tell.
Important
The Meta section is NEVER compressed. It must always be readable without decompression so that clients can discover the compression type, format version, and preview content before deciding whether to download the rest.
QMail Privacy Boundary
Subject, preview text, attachment names, labels, and other human-readable display metadata are private recipient-facing data. They belong in this file_type=0 CBDF meta object, not in the QMail Tell envelope. The Tell envelope may contain GUIDs, file types, sizes, checksums, server locations, and the inbox-fee locker because the beacon must route and validate delivery.
2. Meta Section Format
[Pair Count: 2 bytes LE] [Key/Value pairs...]
Pair Count: A 16-bit little-endian unsigned integer (0-65535) indicating the total number of key/value pairs that follow. This count includes repeated keys (e.g., multiple To recipients each count as one pair).
The Meta section ends when either:
- All pairs indicated by Pair Count have been read, OR
- A SECTION_SEP (
0x1C) marker is encountered (start of Styles section), OR - EOF is reached (for standalone meta objects, normally
file_type=0; key 33 may also mark the object as meta-only).
3. Key/Value Pair Format
Each pair has the same structure:
| Field | Size | Description |
|---|---|---|
| Key ID | 1 byte | Identifies the field (see key table below) |
| Value Length | 1 byte | Length of the value in bytes (0-255) |
| Value | N bytes | The field data (format depends on Key ID) |
This gives a maximum value size of 255 bytes per pair.
Arrays
Fields that support multiple values (To, CC) are encoded as REPEATED KEYS -- each element is its own key/value pair with the same Key ID. The Pair Count includes every repeated entry individually.
Example: An email with 3 To recipients has 3 separate pairs, all with Key ID 13. The Pair Count includes all three.
4. Meta Key Table
4A. Phase I Keys
These keys are defined in Phase I and are fully backward-compatible. Phase II clients must support all Phase I keys.
| Key | Name | Size | Format | Req | Description |
|---|---|---|---|---|---|
0 | Meta File Type | 1 | uint8 | Category of this CBDF document (see the Meta File Type table below). 0 = Generic, 1 = QMail, 2 = SMS/simple text, 3 = QWeb. Lets a client know how to interpret the document before reading the rest of the meta. | |
1 | QMail ID | 16 | Raw bytes | * | GUID assigned by sender |
2 | Subject | Variable | UTF-8 string | Subject line (max 255 bytes) | |
3 | Attachment Name | Variable | UTF-8 string | Attachment Name (max 255 bytes) | |
4 | Attachment/External File Total Pages | 2 | uint16 LE | Total pages this attachment (or, in Phase III, external file) uses. When present, key 4 is emitted DENSELY: one key-4 pair for EVERY attachment, in the same order as key 3, so the n-th key-4 pair maps to attachment index n. A value of 0 means a legacy single-object (cmd-70) attachment; a value > 0 marks a paged (cmd-75) object and is the best-effort total page count (the receiver derives the authoritative count from the Tell manifest's original_size and stripe count). Dense encoding is required because positional mapping breaks if key 4 were sparse (e.g. attachment 0 legacy, attachment 1 paged). Page size is the fixed 256 KB constant, so it is not transmitted. Max 65,535 pages (matches the cmd-75 16-bit page number). | |
5 | Attachment/External File Page Hash | 4 | uint32 LE | Optional CRC32 of one page's data, for corruption detection and single-page re-fetch. Repeated once per page, in page order, grouped immediately after that file's key 4. Omit entirely to rely on the whole-file CRC carried in the Tell manifest. | |
12 | Attachment Count | 1 | uint8 | * | Number of attachments (0-255) |
13 | To Mailbox | 7 | Mailbox address | * | Recipient (repeated per recipient) |
14 | CC Mailbox | 7 | Mailbox address | CC recipient (repeated) | |
19 | From Mailbox | 7 | Mailbox address | * | Sender's address |
25 | Timestamp | 4 | uint32 LE | * | Unix epoch seconds |
Key IDs 15-18, 20-24, 26-29 are reserved for future Phase I extensions. Keys 6-11 are assigned to Phase III (see Section 4C). * = Required for all QMail documents.
Meta File Type values (key 0)
Key 0 (Meta File Type) tells the client what kind of CBDF document this is:
| Value | Type | Description |
|---|---|---|
0 | Generic Type | A generic CBDF document with no application-specific semantics. |
1 | QMail | A QMail email document (.qmail). |
2 | SMS / Simple Text | A short, simple text message (subject-only or meta-only style). |
3 | QWeb | A QWeb page document (.qweb). |
4–255 | Reserved | Reserved for future use. |
Relationship to key 34 (Document Type)
Key 0 (Meta File Type) and the Phase II key 34 (Document Type) describe overlapping concepts. Key 0 is the early, Phase I document-category marker; key 34 is the Phase II rendering hint. When both are present they should agree; key 0 is authoritative for top-level document category.
Key Notes
- Key 1 (QMail ID): A 16-byte GUID (128 bits) uniquely identifying this email. Used for message threading, deduplication, and delivery confirmation.
- Key 2 (Subject): UTF-8 encoded, truncated at 255 bytes. The styled version appears in the Text section marked with SUBJECT_START (
0x01). - Key 12 (Attachment Count): In Phase I, this is always 0.
- Key 25 (Timestamp): Seconds since Unix epoch (1970-01-01 00:00:00 UTC). 4-byte LE uint32. Rolls over in 2106.
4B. Phase II Keys (Key IDs 30-39)
These keys are new in Phase II. Phase I clients will ignore unknown keys (they skip Key ID + Value Length + Value bytes for any unrecognized key).
| Key | Name | Size | Format | Req | Description |
|---|---|---|---|---|---|
30 | Version | 1 | uint8 | * | Format version (see below) |
31 | Compression Type | 1 | uint8 | Compression algorithm | |
32 | Default Style Set | 1 | uint8 | Style set selection | |
33 | EOF Flag | 1 | uint8 | 1 = meta-only document | |
34 | Document Type | 1 | uint8 | Document category | |
35 | AI Summary | Variable | UTF-8 string | AI-generated summary | |
36 | Preview Text | Variable | UTF-8 string | First ~100 chars of body | |
37 | Subject Style ID | 1 | uint8 | Text style for subject | |
38 | Semantic Model | 20 | 4B ID + 16B hash | Model for semantic encoding | |
39 | Semantic Flags | 1 | Bitfield | Semantic encoding options |
Key IDs 40-255 are reserved for future use.
Detailed Key Descriptions
KEY 30 - VERSION (required):
0= Phase I (plain text only, no styles section)1= Phase II (styled text, resources, full CBDF)2-255= Future versions
A Phase I document has no Version key (the absence of key 30 implies version 0). Phase II documents MUST include this key.
KEY 31 - COMPRESSION TYPE:
| Value | Algorithm |
|---|---|
0 | None (no compression) |
1 | DEFLATE/zlib |
2 | LZ4 |
3 | Zstandard (Zstd) |
4 | Brotli |
5 | Semantic encoding |
6-255 | Reserved |
If absent, compression type = 0 (none).
KEY 32 - DEFAULT STYLE SET: 0 = Explicit styles, 1 = Client default, 2-255 = Named style set IDs. If absent, default = 0.
KEY 33 - EOF FLAG: 1 = This document consists of ONLY the Meta section. No FS separators, no body sections follow. Use for ultra-compact messages.
KEY 34 - DOCUMENT TYPE: 0 = Email (QMail), 1 = Web page (QWeb), 2 = Attachment/embedded document, 3-255 = Reserved.
KEY 35 - AI SUMMARY: A short AI-generated summary of the document content. UTF-8, max 255 bytes. Used for inbox preview and as a fallback for semantic encoding.
KEY 36 - PREVIEW TEXT: The first ~100 characters of the document body. REQUIRED when semantic encoding is active. Optional otherwise but recommended.
KEY 37 - SUBJECT STYLE ID: Index into the Text Styles sub-table. Allows styled subjects in inbox listings without opening the email.
KEY 38 - SEMANTIC MODEL: 20 bytes total: [Model ID: 4 bytes] + [Version Hash: 16 bytes]. Only present when Compression Type = 5.
KEY 39 - SEMANTIC FLAGS: Bitfield: Bit 0 = Lossy OK, Bit 1 = Exact words matter, Bits 2-7 = Reserved (must be 0). Only meaningful when Compression Type = 5.
4C. Phase III Keys
Phase III lets a client download files that are not part of the email — external objects such as style sheets, resources, code (e.g. JavaScript files), or even other emails that a person can forward. These keys describe how to locate and fetch such an external file from a QMail/File server, reusing the same paging mechanism as attachments (keys 4 and 5). In Phase I/II these same external-file references can be used for hyperlinks or links to style sheets, scripts, shared marked-up sections (page headers/footers), images, and more.
| Key | Name | Size | Format | Req | Description |
|---|---|---|---|---|---|
6 | External Total File Size | 4 | uint32 LE | Total size of the external file, in bytes. | |
7 | External File Type | 1 | uint8 | What the external file is: a style sheet, code, resource, or an attachment (file types 10–255). Same file-type encoding as upload/download. | |
8 | External File GUID | 16 | Raw bytes | Identifies the object to fetch, so the requester can tell the QMail/File server which file to get. | |
9 | Attachment Stripe Count | 1 | uint8 | Number of 32-byte server-location entries that follow the file header. Must equal stripe_count in the file header. | |
10 | Attachment Parity Algorithm | 1 | uint8 | Fault-tolerance algorithm ID. 0 = RAID-5 XOR (1 parity stripe). Reserved for future Reed-Solomon / GF(2^8) algorithms. The beacon uses this to compute the body-size estimate for total_file_size validation. | |
11 | Attachment Server Location Entries | 32 each | Raw bytes (repeated) | Helps the client find the external file. Each entry is 32 bytes; repeated once per stripe (see key 9). For the 32-byte layout, see QMail Tell — Address entries (N × 32 bytes). |
Key IDs 6–11 are reserved for these Phase III external-file features. They are not emitted by Phase I QMail clients.
5. Mailbox Address Format
All mailbox addresses (To, CC, From) are exactly 7 bytes:
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 2 bytes | Coin Group | Network ID, little-endian. CloudCoin = 0x0006 |
| 2 | 1 byte | Denomination | Coin denomination (e.g., 0x02) |
| 3 | 4 bytes | Serial Number | Little-endian uint32 |
Example: CloudCoin denomination 2, serial number 147352:
06 00 02 98 3F 02 00
(Group=0x0006 LE, Denom=0x02, SN=0x00023F98 LE)
6. Backward Compatibility
Phase I documents (version 0):
- Have no Version key (key 30 absent).
- Have no Phase II keys.
- Phase II parsers detect version 0 by the absence of key 30.
Phase II documents (version 1):
- MUST include key 30 (Version = 1).
- SHOULD include key 34 (Document Type) for proper rendering.
- MAY include any other Phase II keys.
- Phase I parsers will encounter unknown keys (30+) and skip them safely because the KLV format is self-describing.
Key ID ordering: Keys MAY appear in any order. Parsers must not assume a specific ordering. Encoders SHOULD place Version (30) and EOF Flag (33) early for fast detection.
7. Worked Examples
7A. Phase I Plain Text Email: "Hello World!"
Two To recipients, no CC, no attachments.
07 00 Pair count: 7
01 10 Key 1 (QMail ID), length 16
BF 7B 94 B3 91 A2 46 B5 GUID bytes 0-7
8E 48 54 5D D8 F1 31 01 GUID bytes 8-15
02 0C Key 2 (Subject), length 12
48 65 6C 6C 6F 20 57 6F "Hello Wo"
72 6C 64 21 "rld!"
0C 01 00 Key 12 (Attachments), length 1, value 0
0D 07 Key 13 (To Mailbox), length 7
06 00 02 98 3F 02 00 Group=6, Denom=2, SN=147352
0D 07 Key 13 (To Mailbox), length 7
06 00 02 2E 67 04 00 Group=6, Denom=2, SN=288558
13 07 Key 19 (From Mailbox), length 7
06 00 02 A0 78 E8 03 Group=6, Denom=2, SN=65566880
19 04 Key 25 (Timestamp), length 4
68 CF B6 AD Unix: 1758443181 (2025-09-21)
1C FS (end of Meta)
1C FS (end of Styles, empty)
02 STX
48 65 6C 6C 6F 20 57 6F "Hello Wo"
72 6C 64 21 "rld!"
Total: 79 bytes.
7B. Phase II Meta-Only Message: "Meeting at 3pm"
Ultra-compact notification, no body.
05 00 Pair count: 5
1E 01 01 Key 30 (Version), length 1, value 1
21 01 01 Key 33 (EOF Flag), length 1, value 1
01 10 Key 1 (QMail ID), length 16
AA BB CC DD EE FF 00 11 GUID bytes 0-7
22 33 44 55 66 77 88 99 GUID bytes 8-15
02 0E Key 2 (Subject), length 14
4D 65 65 74 69 6E 67 20 "Meeting "
61 74 20 33 70 6D "at 3pm"
13 07 Key 19 (From), length 7
06 00 02 A0 78 E8 03 Group=6, Denom=2, SN=65566880
Total: 52 bytes. No FS markers, no sections beyond meta.
7C. Phase II Styled Email with Preview
Email with compression, preview text, and AI summary.
0A 00 Pair count: 10
1E 01 01 Key 30 (Version=1)
22 01 01 Key 34 (Document Type=1, email)
1F 01 01 Key 31 (Compression=1, zlib)
01 10 Key 1 (QMail ID), length 16
[16 bytes GUID]
02 12 Key 2 (Subject), length 18
"Quarterly Report Q4"
0C 01 03 Key 12 (Attachments=3)
0D 07 [7 bytes] Key 13 (To)
13 07 [7 bytes] Key 19 (From)
19 04 [4 bytes] Key 25 (Timestamp)
23 32 Key 35 (AI Summary), length 50
"Revenue up 15%, marketing leads at 23% growth."
24 64 Key 36 (Preview Text), length 100
"The quarterly sales report shows a 15% increase in revenue across..."
After meta: FS + compressed(Styles + Text) + FS + Resources + FS
8. Implementation Notes (C)
The existing Phase I encoder (qmail_cbdf.c) uses these key IDs: Key 1 = GUID, Key 2 = Subject, Key 12 = Attachments, Key 13 = To, Key 14 = CC, Key 19 = From, Key 25 = Timestamp.
To extend for Phase II, the encoder should:
- Add key 30 (Version) as the first pair.
- Add key 34 (Document Type) for email vs web.
- Optionally add keys 31, 32, 33, 35, 36, 37.
- Keep all Phase I keys unchanged.
Parser key lookup:
static const char* cbdf_meta_key_name(uint8_t key_id) {
switch (key_id) {
case 1: return "QMail ID";
case 2: return "Subject";
case 12: return "Attachment Count";
case 13: return "To Mailbox";
case 14: return "CC Mailbox";
case 19: return "From Mailbox";
case 25: return "Timestamp";
case 30: return "Version";
case 31: return "Compression Type";
case 32: return "Default Style Set";
case 33: return "EOF Flag";
case 34: return "Document Type";
case 35: return "AI Summary";
case 36: return "Preview Text";
case 37: return "Subject Style ID";
case 38: return "Semantic Model";
case 39: return "Semantic Flags";
default: return "Unknown";
}
}
Key validation:
- Required keys (1, 12, 13, 19, 25, 30) must be present.
- Key 30 (Version) must be >= 1 for Phase II documents.
- Key 33 (EOF Flag) = 1 means no FS markers follow.
- Unknown keys (future extensions) must be silently skipped, not treated as errors.