Most ASR software falls into one of five conformance classes. Requirements are numbered (ASR-NNN), and each one maps to a validator check.

Readers

  • Check the version. Read formatVersion from the header. Declare which major versions you support and fail explicitly on the others.
  • Tolerate damage. Ignore a partially written final line. A malformed line in the middle yields a diagnostic and a gap; never silently reconnect the context around it.
  • Order by seq. Timestamps are optional, may have different precisions and may come from different clocks.
  • Preserve what you don’t understand. Skip unknown record types and fields when interpreting, but keep them when storing or rewriting. Every enum is open.
  • Resolve references carefully. A reference to an entity, such as a callId or messageId, means its latest revision; a reference to a record id means exactly that revision. A supersedes record is a full replacement.
  • Pair tool calls as recorded. Duplicate native call IDs are never paired by order. A call without a result is dangling and its outcome is unknown. Orphan results, which have no matching call, are kept.
  • Don’t double-count. Records copied from an ancestor session can be searched and displayed, but their usage, cost, edits and commits are not attributed to the child session. The same applies when one app runs another agent: the app’s stream links to the backing session with executedBy, and its copies of that session’s records carry copiedFrom. Use either a usage_summary that covers the records being counted or the component records, never both. Never add parent and child totals when their scope is unknown.
  • Treat absence as unknown. A missing cost does not mean zero cost; missing lineage information does not mean the session is a root session; a missing trigger does not mean a person started the turn.
  • Find features by record type. Questions to the user are input_request records, delegation is subagent and plans are plan, whatever the tool was called. Don’t rely on a tool call’s name or kind to find them.
  • Don’t assume delivery. An assistant message means a reply was generated. Whether it reached anyone is a delivery record; without one, delivery is unknown.
  • Read senders from the record. from names who sent a message: a participant in a group chat, another session or an agent’s address. author: "human" says only that a person wrote it, not which person.
  • Compute the context view as specified. Follow predecessors back from a head, then apply rewinds and compactions in seq order. The result is a projection of the recorded evidence, not proof of what the model actually received. See Order, branches and context.
  • Display safely. Treat transcript content as untrusted input. Never execute it, fetch URIs automatically, or render it as active HTML.

Converters

  • Set producer.method to converter and list every feature you could not carry over in producer.lossy.
  • Keep native IDs verbatim. Where the source has none, derive deterministic IDs and mark them idSource: "derived". For sources rewritten as whole snapshots, mark positional IDs idScope: "capture". Never use paths, import time or content hashes as identity inputs.
  • Never fabricate IDs, timestamps, models, outcomes, durations, costs or token counts. Keep text exactly.
  • Fold incremental updates during streaming into one record and mark its assembly. When the source keeps a revision of an already-final fact, such as a tool status that changed, keep it as a supersedes chain, or declare folding it as a loss.
  • Write inference records only when the source identifies a model call.
  • Put facts that have no standard field where the agent registry says: a _meta key on the nearest record, or a vendor record type. Never drop a recorded fact to stay conformant.
  • Never record secret answers to questions, whether normalized, raw or in a blob.
  • Record lineage and copies only from positive evidence, with the evidence kind stated per facet.
  • Use capture states for truncated, masked, summarized or omitted content. A copy limited to part of the source is never labeled complete.
  • On re-export, never renumber records that were already exported.
  • Keep the source record in native (embedded or referenced) when you can.

Exporters

Companion specifications define the derived formats: An exporter that produces shareable output MUST apply a redaction policy and record which one it used. Redaction produces a new stream that carries derivedFrom and covers reachable blobs, native sidecars, unknown extensions, identifiers and embedded paths. When redaction and preservation conflict, redaction wins. See Privacy and security.

Storage tools

  • Store bundles as a directory or archive with an authoritative bundle.json manifest, sessions/, blobs/sha256/<hex> and, optionally, native/.
  • Never include native/ files in a shareable bundle by default.
  • Keep streams of unsupported major versions as opaque bytes.
  • Extract archives safely and set limits when parsing. Never run discovery commands automatically.

Validator and corpus

The reference validator checks syntax, semantics and unsupported features separately, against the JSON Schemas. It ships with conformance fixtures: every semantic requirement has at least one valid and one invalid case. The JSON Schemas (draft 2020-12) are published here: A golden corpus of sanitized real sessions from at least ten harnesses, plus adversarial fixtures, comes before Preview on the roadmap. So does getting two independent converters for the same five harnesses to agree on it. Version 1.0 requires the corpus and two independent implementations.