Requirement keywords

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY” and “OPTIONAL” in this specification are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174) when, and only when, they appear in all capitals. Text marked “Design note”, examples, and the companion documents are non-normative.

Terminology

Stream. One UTF-8 JSON Lines file (or byte sequence) holding the records of exactly one session. Line 1 is the session header. Bundle. A directory, or an archive of one, that holds one or more streams, an authoritative manifest (bundle.json), and optionally blobs and native files. Record. One JSON object on one line of a stream. Every record has a type, a seq and a record ID (id). Entity. A logical thing that one or more records describe: a message, a tool call, a model call, a terminal, a plan, a compaction, a permission request, a question to the user. An entity is identified by its native entity key (for example messageId or callId). When a record is revised, the revision is a new record with the same entity key. Revision chain. A record and the records that supersede it, in order. The last record in the chain is the latest revision. Session key. The triple (agent, namespace, sessionId) that identifies a session. Session reference. The string form of a session key, optionally with a record reference. See Identity. Ref. A string that refers to a record or entity within a stream: either a record ID, or <entityKey>=<value>. See Identity. Source. The native data a converter reads: a harness’s log files, database, or protocol stream. Native. Belonging to the source, as the source wrote it. A native ID is the source’s own identifier, used verbatim. Producer. Any software that writes a stream. The header’s producer.method says how it obtained the data:
  • a native producer writes ASR as (or alongside) its own log;
  • a converter translates a source’s native logs after the fact;
  • a recorder captures a live harness protocol, such as an Agent Client Protocol (ACP) connection;
  • other methods are decoded, observer and import (see Session records).
Reader. Any software that reads streams. A storage tool is a reader that stores or rewrites streams in ASR format. A renderer displays them. Exporter. Software that writes something derived from a stream: a redacted stream for sharing, or a different format, such as an ATIF (Agent Trajectory Interchange Format) trajectory, OpenTelemetry spans or attribution notes. Context-participating record. A record of type message, tool_call, tool_result or compaction. Only these records form the conversation structure (see Structure). Audit-only record. Every other record. Audit-only records are facts about the session (usage, permissions, questions, memory writes, deliveries, file changes, commits, state) that never become a context predecessor. Turn. The work the agent does in response to one input or activation, identified by the envelope field turnId when the source records one (see Session records). Participant. A person, agent or bot that takes part in a conversation, declared in the header (see Session records). Active path. The sequence of context-participating entities obtained by following predecessors back from a head. Context view. The active path with rewinds and compactions applied: the recorded evidence of what the model’s context contained. It is not proof of the exact request. Capture state. A per-field statement of how completely a content-bearing field holds what the source captured (see Missing data and revisions). Profile. A named promise about what a producer records: when a particular kind of event happens, the producer emits the record or an explicit capture state (see Extensibility). Effective value. The value of a declared property (profiles, extensions, losses, content level, roots, participants, conversations, client, environment) at a given seq, after applying the header and all earlier declaration records.

JSON rules

Requirements on this page use IDs from the format block (ASR-040 to ASR-049). ASR-040 Member names are case-sensitive and MUST be spelled exactly as this specification defines them. Defined member names use lower camelCase (sessionId, callIdSource). Core enum values use lower snake_case (tool_result, allow_once). ASR-041 Every record MUST be an I-JSON object: valid UTF-8, no unpaired surrogates in strings, and no duplicate member names in any object. ASR-042 Counts, sizes, token numbers, seq and other integer-valued fields MUST be JSON integers between 0 and 253−1 inclusive, unless a field’s definition allows otherwise. Producers MUST NOT write them as strings or with a fractional part or exponent. ASR-043 null MUST appear only where this specification gives it a meaning (for example namespace: null, includesChildren: null, rewind.to: null, a root path: null, or a session_info field being cleared). Everywhere else an unknown value is expressed by omitting the member. ASR-044 Timestamps MUST be RFC 3339 date-time strings in UTC with the Z designator, with zero to nine fractional-second digits: 2026-10-26T14:02:11.204Z, 2026-10-26T14:02:11.204118930Z. ASR-045 Durations whose names end in Ms are non-negative JSON numbers of milliseconds. They MAY have a fractional part. ASR-046 Readers MUST compare strings (IDs, names, paths, enum values) by Unicode code point, without case folding or Unicode normalization. ASR-047 Decimal amounts (costs) are JSON numbers. Producers SHOULD write them with no more precision than the source reported. Field tables in this specification use these type names: “Req” in field tables means the member is required. “Open” next to an enum means unknown values are allowed and preserved (see Extensibility). Every enum in this specification is open unless stated otherwise.

Requirement IDs

Every normative statement that a validator, a fixture or a test can check has a stable ID of the form ASR-NNN, shown in bold at the start of the statement. IDs are allocated in blocks by page: IDs are never renumbered or reused. While the format is a 0.x draft, a requirement that is withdrawn is deleted from the text and from the requirement table, and its ID stays unused. From version 1.0, a withdrawn requirement keeps its row in the table with the status “Retired”. Gaps in the numbering are intentional. Each requirement has a check type:
  • schema: checkable on a single record with the JSON Schema (schema.json);
  • semantic: checkable by a validator over a whole stream or bundle, without outside input;
  • fixture: checkable only by running the implementation against a fixture and comparing its output or behavior with the expected result.

Examples

Examples are non-normative but MUST obey every rule in this specification. CI validates them.
  • A code block labeled jsonl contains complete stream lines. Each line is one complete record and validates against the schema on its own. The website shows these records expanded over several lines for reading; in a stream, each record is a single line.
  • A code block labeled json contains a fragment (an object member, a manifest, a part of a record). Fragments are illustrative.
  • Most examples come from one example session: a coding agent asked to “Fix the failing parser test” in a Git repository whose root has the ID app. Record IDs in that session follow the pattern r<seq> so that cross-references are easy to follow. This is an example convention only: record IDs are opaque.
  • Examples of features the example session does not have (scheduled turns, chat channels, an app that runs other agents) come from a session of a tool that records them, and the text says which tool.
  • Hashes, UUIDs and IDs in examples are invented. Paths such as /work/acme-app are placeholders.