For the complete documentation index, see llms.txt. This page is also available as Markdown.

Record & Document Output

Writing records, record enclosure, headers, and data sections.

Key Emission and Value Formatting settle how the pieces are written. This page settles how they are assembled into records, sections, and a document.

Records

A record is one row of data — a ~ item in a collection, or the single object of an object section. Its members are written in schema order, separated by , .

name: string, age: int
---
~ John, 30
~ Mary, 25

Absent members hold their place

A declared member that is absent, optional, and has no default is written as an empty position, so that later members are not read into the wrong slot:

# schema: { a: string, b?: number, c: string }   value: a = p, c = q
{p, , q}          # correct — c stays in slot 2
{p, q}            # WRONG — q would be read as b

Trailing empty positions carry no information and are trimmed.

Record enclosure

A record's own braces are optional: x, 4 and {x, 4} are the same record. But when a record consists of exactly one value and that value is an object, the braces become ambiguous — a reader may take them as the record's own enclosure rather than as the value.

A writer MUST therefore enclose such a record explicitly:

The full reading rule lives with the value syntax; see Record enclosure under schema validation. A writer does not rely on that rule — it always emits the unambiguous form.

Documents

A document is a header, a --- separator, and one or more data sections. Whether the header travels with the data is a writer choice:

Header
Output

omitted

data only, no separator — the schema is assumed known at the endpoint

included

header, ---, then the data

Header omitted — data only, and no separator:

Header included:

A writer MUST NOT infer a header the document does not carry. When a schema-less document is written with the header included, the header is empty but the --- separator is still emitted, so the first token of the data is unambiguous:

The data then follows the no-schema rules in Key Emission — every name is unrecoverable, so every name is written.

A root value that is not a record

A data section may hold a value that is not an object, and IO promotes it into a record under its positional key: --- followed by [1, 2, 3] decodes as { "0": [1, 2, 3] } (Data Sections).

A writer converting foreign data MUST bind such a value to that same positional member. Naming it anything else produces a document that decodes differently from the identical text written by hand:

Both forms below parse; the second is wrong because it decodes differently. An invented member name (value: [number][1, 2, 3]) yields { value: [1, 2, 3] }, so the same data written by the library and by hand would disagree.

An array whose items are records is a collection and needs no promotion: each record becomes a row. Promotion applies only where there are no names to bind to — an array of scalars, an array of arrays, or a bare scalar.

Member names in the header

A member name is quoted by the same rules as a data key (Value Formatting). Since the ? and * suffixes belong to the bare-name token, a writer that quotes a name MUST expand that member to the long MemberDef form:

The member "a,b" is an optional, nullable number. The suffix form is not available to it:

so a writer emits the long form instead:

Bare names are unaffected — age?*: number is written as it stands. Appending a suffix to a quoted name produces a header the writer's own reader rejects with invalid-definition.

Header and data are separately addressable

Because the two parts are independent, a writer SHOULD expose them separately as well as combined: the schema can then be published, cached, or versioned on its own while records stay lean. Composing the header, a blank line, and the data reproduces the whole document exactly.

Sections

A section is introduced by ---. A section may be named, schema-bound, or both:

Form
Meaning

---

an unnamed section using the default schema

--- $Schema

an unnamed section bound to a named schema

--- name: $Schema

a named section bound to a named schema

A multi-section document writes each section in order. A writer SHOULD separate the header and each named or schema-bound section with a blank line; blank lines are insignificant to a reader, so this affects legibility only.

A section name is a bare name — letters, marks, digits, - and _ — and it is the one name in the format that cannot be quoted, because the separator line runs to the end of the line and nothing would bound it.

That makes the multi-section layout unavailable for some data. When a key falls outside the set, a writer MUST NOT emit it as a section name and MUST fall back to a single section, where the same key is an ordinary member name and may be quoted:

This is the general rule of Round-trip applied to one construct: a writer must never emit text its own reader cannot read. A leading space is the case worth remembering — it is not part of the name, and a reader that absorbs it changes the data without reporting anything.

See Also

Last updated

Was this helpful?