On this page· 4
Specification
- Revision 6.0
- file format 6
- Whole specification on one page
- The body is a sequence of lines, each one JSON object [RFC8259] encoded as UTF-8 and terminated by one LF.
- A writer MUST NOT emit empty lines, CR characters outside JSON strings, or a line containing a raw LF inside a JSON value (JSON strings escape LF as
\n). - A reader MUST reject a body that is not valid UTF-8 with
invalid_utf8. - A reader MUST skip empty lines and MUST strip one trailing CR before parsing a line. Skipped lines do not count as records.
- The marker line (§2) is not a record. It MUST appear only as the last line of the text section and only when an appendix exists; anywhere else it is
invalid_record. recordsin the header andrecord_countin the footer count the record lines.- A writer MUST NOT emit a JSON object with duplicate member names. A reader that meets one MUST either reject the line with
json, or keep the last value for the name; the reference reader keeps the last value (serde_json behaviour, measured in §10.4). Conformance tests do not exercise duplicates.
Every record line is a JSON object with:
k(REQUIRED): a JSON string, the record kind. A line without a stringkMUST be rejected withinvalid_record.v(OPTIONAL): a non-negative JSON integer, the per-kind format version. Absent means 1.- the kind's own members (§5).
A record is typed when its kind is in the typed registry (§5.1) and its v is at most the highest version this reader supports for that kind. Every typed kind is at version 1. Otherwise the record is opaque.
- A reader MUST parse a typed record against its schema (§5.1). A schema failure (missing REQUIRED member, wrong JSON type) MUST be reported as
json. - Members the schema does not name MUST be preserved in the record's
extramap and re-emitted after the declared members. - A writer MUST emit a typed record as:
kfirst, thenv, then the declared members in schema order, thenextramembers in the order they were read. OPTIONAL members whose value is absent are omitted, except those marked "always emitted" in §5.1. - Re-emitting a typed record normalises its values: a 32-bit float member (for example
salience,confidence) is re-emitted as the shortest decimal that round-trips the 32-bit value, and whitespace, escapes and number spelling follow §10.2. A typed round trip therefore preserves the value but MAY change the bytes.
A record MUST be kept opaque, not rejected, when either:
- its kind is not in the typed registry, including the reserved kinds of §5.2 and any future kind; or
- its kind is typed but its
vis higher than this reader supports.
For an opaque record, a reader MUST keep the whole JSON object, including k and v, and a writer MUST re-emit it with the same members, the same values, and the members in the order they were read (§10.1). This is the opaque round-trip rule. It guarantees JSON value equality and member order; it does not guarantee byte equality, because escapes and number spellings are re-emitted in the form of §10.2 (a JSON integer outside the 64-bit range, for example, becomes a binary64 number; §10.4).
Opaque records take part in sorting, merge and diff through the identity rules of §5.3.
© 2020-2026 Cintile Inc. All Rights Reserved.
Anyone may implement this format. Copying or republishing the text of this specification requires permission from Cintile Inc.