Message envelope
The shape of a Message envelope as it is persisted in SQLite, returned by the broker layer, and rendered by the CLI.
Persisted shape
Every message is a flat row of typed columns in messages — there is no JSON blob; messages.text carries the body and the remaining columns carry the routing and lifecycle fields. See data-model.md for the full column schema. The persisted shape is the canonical source of truth; every render the broker produces is a projection of these columns.
Rendered shape
The broker's read paths return the persisted columns as a flat dict (the typed-column dict), and the CLI projects that dict into a compact rendered envelope — by default the rendered envelope omits the columns whose values are constant or recoverable from context. The --full flag returns the typed-column dict unmodified.
Compact rendered envelope (default)
Field decisions:
JSON output
CLI JSON output is governed by the --json flag:
Examples
A poll result with one unicast delivery (id 42, from 7, body "build OK").
Default (cafleet message poll --member-id <my-member-id> --json):
--full (cafleet message poll --member-id <my-member-id> --full --json):
Indented here for readability; the actual
--jsonoutput is a single compact line with no whitespace.--fullonly changes which fields are emitted, never the encoding.
A broadcast summary row carries kind: "broadcast_summary" (or type in --full) and origin: <id> (self-referencing); the text body is the broker-computed summary string "Broadcast sent to N recipients". The message broadcast response always contains exactly this single summary message plus the wrapper-level recipients (the real recipient count N) and delivered (the count of best-effort inline previews that landed) fields — there is no per-recipient envelope list. --full renders that single summary message in full (verbose envelope / typed-column dict) instead of the one-line summary, but never adds per-recipient envelopes (see Output shapes for the cross-subcommand summary).
Text mode
Text mode renders each message as two lines (line 1 is the bracketed envelope, line 2 is the body):
--full switches to a variable-length labeled block — one field per line, per the table above. So a fresh unicast delivery prints six lines, while a broadcast-summary row with no recipient prints fewer. Broadcast summary rows are never empty — the broker writes the human-readable summary "Broadcast sent to N recipients" at insert time, so summary rows always render their text: line. Body truncation (the … suffix at CAFLEET_MAX_TEXT_LEN codepoints) is documented in cli-options.md.
Flag cross-reference
The flags that govern envelope rendering are documented in cli-options.md: