Nodes
A node is a block referenced with the dag-cbor codec (§4) whose
bytes are a canonical-CBOR map.
Every node has:
v— integer, MUST be1for this version. The value0is invalid and permanently reserved; wire versions start at 1. (The "Version 0" in this document's title numbers the specification draft, not the wire format it defines.)t— text string, the node type.
An unknown t, an unknown map field for the given type, or v ≠ 1 MUST be
rejected. (Strict v1: format evolution changes v; the mixed-version and
lowest-sufficient-version rules are in §15.1.)
Four node types exist:
t | meaning | fields |
|---|---|---|
"r" | root (commit) | e (REQUIRED): the root Entry (§7), usually a directory. OPTIONAL: ts (integer, unix seconds, MAY be negative), note (text ≤ 4096 bytes), prev (dag-cbor-codec Ref → previous root node). |
"d" | directory | Exactly one of: e — entries array (flat form; MAY be empty), or p — page index (paged form; MUST be non-empty). See §8. |
"ds" | directory segment | e — entries array, MUST be non-empty. Only ever referenced from a "d" page index. |
"f" | file node | sz — integer ≥ 0, total logical size; c — non-empty array of [size, Ref] pairs, each size ≥ 1, with sz = Σ sizes. See §9. |
The complete set of legal edges between node types:
A "d" dir carries exactly one of e (flat) or p (paged); nested
directories reach unbounded depth.
Entries array: an array of [name, Entry] pairs (each pair a 2-element
array), sorted strictly ascending by name order (§3.3). Readers MUST
reject unsorted arrays and duplicate names. Name rules: 1–255 UTF-8 bytes,
no /, no NUL (U+0000), not ., not ...
UTF-8-only naming is a design constraint of this format, not an accident of encoding: name identity is the UTF-8 byte sequence (§3.3), and there is no representation for other byte sequences. A writer ingesting a source filesystem whose native names are raw byte strings (POSIX) MUST reject the ingest of any name that is not valid UTF-8. It MUST NOT instead substitute (U+FFFD), strip, or transliterate bytes, since two names surviving such a repair could collide and silently merge entries. The same rule applies to symlink targets (§7.3).
Root node validation: e MUST be a valid Entry; ts MUST be an integer
(§2.3) when present; note MUST be a text string of at most 4096 UTF-8
bytes containing no U+0000; prev MUST be a dag-cbor-codec Ref, and the node it
resolves to MUST be an "r" node — checked when the history chain is
walked, not when the referencing root is validated (a block cannot see its
neighbors).