Y2 Elite workspaces are rolling out for teams
Y2Y2Docs
Ontology & Fusion

Ledger Record Format

Record kinds, fields, the SHA-256 seal, identifiers, and every rule a ledger line must satisfy (format version 0)

A ledger is a sequence of lines. Each line is one record, serialized as canonical JSON: object keys sorted by UTF-16 code unit, no insignificant whitespace, and integers only. Every field is present; null marks an unknown time or number and "" an empty string field. The portable implementation is the @y2/ontology package.

Common fields

FieldTypeMeaning
v0Format version
seqintegerPosition in the log, starting at 1, contiguous
idstringRecord ID; the prefix names the kind
kindsubject, designator, observation, assertionRecord kind
recorded_attimeRecord time; strictly increasing along the log
prevhex or nullhash of the previous line; null on the first
hashhexSHA-256 of the canonical line without hash

Times are ISO 8601 in UTC with milliseconds, exactly as Date.prototype.toISOString prints them.

Records

Subject

FieldMeaning
classperson, organization, or system. A subject never changes class.

A subject has no name. Names and identifiers arrive as designators and claims.

Designator

FieldMeaning
designator_kindSee Vocabulary
valueThe canonical string
namespacePlatform, algorithm, registry, or exchange MIC; "" for kinds without one
normalizedCase-folded for names and handles; otherwise equal to value

One designator per (kind, namespace, normalized) in a ledger. A second line with the same key is rejected; reuse the existing ID.

Observation

FieldMeaning
methodOne passive method, or analyst-note
source_gradeprimary, secondary, or analytic (only for a note)
source_urlThe page; required for a retrieval, optional for a note
archive_urlA preserved copy, or null
retrieved_atRetrieval time; null on a note
content_hashSHA-256 of excerpt, or of an archived blob when archive_url is set
excerptA quote of 1–500 characters, or null when an archive holds the content
collectorA local label for the recorder, 1–80 characters, never a personal name in Y2
citesObservations a note connects; empty on a retrieval

Assertion

FieldMeaning
opassert or retract
predicate, from, toThe claim; see predicates
qualifierThe public role on member-of; "" otherwise
supersedesThe current head of the claim key, or null on the key's first line
confidenceInteger 0–100; null on a retraction
verificationA ladder state; null on a retraction
valid_from, valid_toValid-time interval, end exclusive; null is unknown, never guessed
evidence_refs1–20 earlier observations
noteUp to 1,000 characters of caveat

The claim key is predicate|from|to|qualifier. Each key has exactly one chain of lines.

Identifiers

Y2 derives record IDs with its public-ID strategy: a prefix and the first 24 hex characters of SHA-256 over the record type and the workspace ledger position.

KindPrefixExample
Subjectsbj_sbj_0123456789abcdef01234567
Designatordsg_dsg_0123456789abcdef01234567
Observationobv_obv_0123456789abcdef01234567
Assertionclm_clm_0123456789abcdef01234567

The offline format accepts any lowercase ID with the right prefix, such as sbj_ada in the fictional fixtures.

Rules

Each rule has a code. The API returns the codes in detail; the offline checker prints them per line.

CodeRule
shape.*Exact field set and field types for the kind
format.json, format.canonicalThe line is JSON in canonical form
chain.seq, chain.prev, chain.hashContiguous seq, prev links the previous hash, hash matches
chain.time, time.formatRecord time strictly increases; times use the exact format
id.format, id.duplicatePrefix matches the kind; IDs are unique
designator.*Canonical value for the kind and namespace; computed normalized; one row per key
observation.method, observation.gradePassive method; only a note is analytic
observation.url, observation.timeExact http(s) URL without userinfo; a retrieval has its URL and time, not after record time
observation.note, observation.citesA note cites earlier observations and has no retrieval time; a retrieval cites nothing
observation.excerpt, observation.hash, observation.preservationExcerpt 1–500 characters; hash matches the excerpt unless archived; keep an excerpt or an archive
assertion.endpointfrom and to match the predicate; distinct ends; same class for same-as and distinct-from
assertion.qualifierOnly member-of carries a lowercase role
assertion.chainFirst line supersedes nothing; later lines supersede the current head; no double retraction
assertion.evidence1–20 distinct earlier observations
assertion.confidence, assertion.intervalInteger 0–100; valid_from before valid_to
assertion.verificationThe state is one the evidence supports (see the ladder)
assertion.retractA retraction clears confidence, verification, and the interval
assertion.labelpreferred-label needs a live designated-by for the same pair

Example

The first two lines of the fictional fixture, wrapped here for reading:

{"class":"person","hash":"…","id":"sbj_ada","kind":"subject","prev":null,
 "recorded_at":"2026-03-01T10:00:00.000Z","seq":1,"v":0}
{"designator_kind":"published-name","hash":"…","id":"dsg_ada_name","kind":"designator",
 "namespace":"","normalized":"ada example","prev":"…","recorded_at":"2026-03-01T10:00:01.000Z",
 "seq":2,"v":0,"value":"Ada Example"}

The complete fixtures, fictional.ndjson and fictional-cyber-market.ndjson, are in packages/ontology/v0/examples in the Y2 repository.