session

The header is line 1 of every stream (ASR-003). It identifies the session, says who wrote the stream and how, and declares the stream’s capabilities and content level.
ASR-150 The header MUST contain formatVersion, agent with name, sessionId, producer, profiles and contentLevel. ASR-151 formatVersion MUST match ^[0-9]+\.[0-9]+$. Streams written to this specification MUST use "0.1". ASR-152 profiles MUST include "core". Every other value MUST be a profile defined in Extensibility or a vendor profile name beginning with _. ASR-153 contentLevel MUST be full, redacted or metadata. ASR-154 Header times (startedAt) follow the same rules as ts: taken from the source, never fabricated (ASR-103, ASR-104).

Producer

method values: ASR-155 producer MUST contain name, version, method and instance. ASR-156 When method is anything other than native, producer MUST contain source.format and lossy. ASR-157 producer.lossy MUST name every category of loss the producer knows it introduced or inherited for this stream. An empty array is a claim that the producer knows of none.
Design note. There is no trust or fidelity label. A consumer can check where the data came from using producer.method, capture states for each field and lineage evidence for each facet. A producer’s own labels do not establish trust or fidelity (see Missing data and revisions).

Roots

A root is a directory that paths are expressed relative to (see Coding). Roots are declared in the header and, when discovered later, in declaration records. ASR-158 Root IDs MUST be unique across the header and all declaration records of a stream. A root’s path MUST be either null or an absolute path in the form Coding defines. ASR-159 Root vcs members MUST be recorded only from the source. A producer MUST NOT fill head, remote or dirty from the current state of the file system at conversion time.

Participants

participants lists the people, agents and bots that take part in the session’s conversations, when the source records them: the members of a group chat, a guest on a shared thread, another agent that sends messages. A declaration can add participants later. Messages name their sender with an actor reference to a participant (see Messages).
This header comes from an OpenClaw session in a WhatsApp group. OpenClaw records how it knows each sender (profile, observation); ASR keeps that word in basis and does not turn it into a verified or unverified flag.

Conversations

conversations lists the chat conversations the session serves: a direct chat, a group, a channel, a thread. One session can serve several (OpenClaw’s main session collects direct messages from several apps). A declaration can add conversations later. Messages name their conversation by ID (see Messages). conversationKey is the source’s key for the lane of conversation that several sessions continue (OpenClaw rotates a session_key through many windows, each a session). It is not session identity. ASR-175 Each participant MUST contain id, and each conversation MUST contain id and channel. Each identity in a participant’s ids MUST contain scheme and value. ASR-176 Participant IDs MUST be unique across the header and all declaration records of a stream, and so MUST conversation IDs. A declaration adds only participants and conversations with new IDs. A conversation’s parent MUST name a conversation declared at or before it. ASR-177 Participants, conversations and identities MUST come from the source. basis MUST be the source’s own value, verbatim: producers MUST NOT turn it into a verified or unverified judgment, and readers MUST NOT treat it as a trust label (ASR-521). A producer MUST set kind: "human" only when the source records that the participant is a person. ASR-178 conversationKey MUST be the source’s key, verbatim. Streams with the same conversationKey are different sessions (ASR-050). Readers MAY group them for display. Identity values (displayName, ids[].value, a conversation’s nativeId) are personal data. They are content-bearing for redaction (see Privacy).

session_info

session_info carries session metadata that may change: the title and who set it, the current heads, tags, flags, the project, and a later session that continues this one.
ASR-160 Each field of session_info is a patch: a member that is present replaces the effective value, a member set to null clears it, and an absent member leaves it unchanged. Readers MUST compute the effective value of each field from the last session_info record (in seq order) that contains it. ASR-161 heads follows the reference-resolution table. Each target MUST be a context-participating record. ASR-180 continuedIn MUST be a session reference without a # part. ASR-181 A session_info record that contains title and no titleSource makes the effective titleSource unknown. Readers MUST NOT carry an earlier titleSource over to a new title. Several sources write the same metadata again at every exit or turn (Claude Code re-stamps its title and leaf). A repeated identical value is not a change; producers write session_info only when a value changes.

declaration

A declaration amends the header’s declarations as the session proceeds. A native writer often learns only during the session that it needs another profile, has dropped some data, has entered a new root, or has met a new participant. Sometimes a different writer takes over.
Most merge rules only add (nothing is removed or loosened):
  • profiles, extensions, lossy and executedBy are set unions. Nothing can be removed.
  • contentLevel can only tighten (full → redacted → metadata), and only for later records.
  • roots, participants and conversations only add entries with new IDs.
  • agentVersion, client, environment and producer apply to later records.
ASR-162 A declaration MUST contain at least one of the members above. ASR-163 The effective profiles and extensions at a record are those of the header plus every declaration with a lower seq. The effective loss categories of the stream are the union over the header and all declarations. Extensions are merged by id and version; an extension is effectively required if any declaration of it says so. ASR-164 A declaration’s contentLevel MUST be at least as strict as the effective content level before it. A declaration that would loosen it is invalid. ASR-165 A contentLevel declaration applies only to records with a higher seq. Readers MUST NOT read it as reclassifying earlier records. ASR-166 Roots in a declaration MUST have IDs not used before in the stream (ASR-158). Records MUST NOT refer to a root before the record that declares it. ASR-167 Validators MUST evaluate each record against the effective declarations at that record’s seq. ASR-179 A declared agentVersion, client or environment applies only to records with a higher seq. Each member of a declared environment replaces that member of the effective environment; members it does not contain are unchanged. session_info remains the record for titles, heads and tags. The two record types merge differently (last value per field versus a union that only grows) and are kept apart for that reason.

state

state records changes in session or turn status that the source records: a turn queued, starting or finishing, the agent waiting for the user, or the session resuming or ending. It follows ACP v2’s state_update, with turn details that harnesses record beyond ACP.
The second and third records come from a T3 Code thread: a turn failed on a usage limit, and a later turn continued it once the limit reset. T3 ran the turn through a Codex session and recorded Codex’s own turn ID. session in parentTurn and rootTurn is a session reference without a # part; absent means this session. State meanings:
  • queued: the turn was accepted and waits to start (behind another turn, or held).
  • running: the agent is working.
  • idle: the agent stopped working and is waiting for input. A turn that failed after its input was accepted is idle with stopReason: "error", as in ACP v2.
  • requires_action: the agent is waiting for the user (a permission request, a question).
  • error: the agent reported a fault that stopped it, where the source distinguishes this from an idle stop.
  • resumed: the session was resumed in a new process or connection.
  • ended: the session was closed or its process exited.
error fields: ASR-168 state MUST be present. stopReason SHOULD appear only when state is idle, error or ended. ASR-169 A producer MUST write state records only for transitions the source records. It MUST NOT synthesize them from message boundaries or timing. ASR-170 ended is not final: a later resumed and further records may follow. Readers MUST NOT assume that no records follow an ended state. ASR-182 attempt, continuationOf, parentTurn, rootTurn and executedBy MUST appear only on a state record that has turnId. continuationOf MUST be a turn ref (ASR-075). attempt.n MUST be an integer of at least 1. parentTurn and rootTurn MUST contain turnId, and executedBy MUST contain session. ASR-183 Turn links (continuationOf, parentTurn, rootTurn, executedBy), attempts and error details MUST come from the source. A producer MUST NOT infer them from timing or order. It MUST NOT omit session for a turn of another session; when it cannot name that session, it MUST NOT write the link, and keeps the native identifier where the registry documents (for example in _meta).

Turns and triggers

A turn is the work the agent does in response to one input or activation. ASR groups a turn’s records with the envelope field turnId when the source records a turn ID or a turn boundary (ASR-110): Claude Code’s promptId, Codex’s turn_id, T3 Code’s run ID, OpenClaw’s runId. The turn’s status changes are state records with that turnId.

trigger

trigger says what started a turn when it was not an ordinary prompt: a schedule, a heartbeat, a webhook, background work finishing, a message from another agent, the harness continuing on its own. It is an envelope member of the turn’s first record, whatever that record’s type, except that it never goes on a compaction record: compaction.trigger says what caused the compaction (see Structure). When a turn begins with a compaction, its trigger goes on the turn’s first other record.
This record comes from a Claude Code session in which a scheduled task fired. Claude Code records the turn’s origin as scheduled (kept in native), the task ID and the fire ID. The prompt was inserted by the harness, so its author and origin say so; the trigger does not change them. Kinds: The header’s trigger has the same shape and says what started the session (Codex records thread_source: automation; OpenClaw creates a session per cron run). ASR-184 A turn’s trigger MUST appear only on a record that has turnId, and only on the record with the lowest seq among the records with that turnId other than compaction records. At most one record per turn carries it. ASR-185 A trigger MUST contain kind or native, or both. source, when present, MUST be an actor reference (ASR-076). ASR-186 Trigger values MUST come from the source. A producer MUST set kind from a native value only by a mapping the agent’s registry entry documents, and keeps the native value in native. A trigger does not change who wrote a message or how it entered: a producer MUST set author and origin as the source records them, and MUST NOT write author: "human" for a scheduled prompt because a person created the schedule.

config_change

config_change records configuration the source recorded: a change of model, reasoning effort, mode, permission mode, sandbox, agent profile, other options, or a capability (a skill, plugin or tool server) being installed, connected or removed. With snapshot: true it records the configuration values the source recorded at a point, rather than a change.
A Codex session records the configuration in force at the start of every turn. Each becomes a snapshot:
capability.kind (open) is skill, plugin, mcp_server, connector or tool. capability.op (open) is install, remove, enable, disable, connect, fail or needs_auth. name is the capability’s name, as the source records it. ASR-171 A config_change MUST contain at least one of model, effort, mode, permissionMode, sandbox, agent, options or capability. ASR-172 A config_change without snapshot records a change the source recorded. The model a session requested and the model a provider served are separate facts: a producer MUST NOT infer a config_change from inference.model, and MUST NOT fill inference.model from a config_change, except as ASR-325 allows for model.requested. ASR-187 A snapshot states the values the source recorded at its position. Members it does not contain are unknown, not unchanged and not cleared. A snapshot does not mean that anything changed. A producer MUST place a snapshot where the source recorded the values, and MUST NOT write a snapshot of current values (for example a database row read at conversion time) at an earlier position in the stream. ASR-188 A capability MUST contain kind, name and op. ASR-189 A config_change MUST NOT contain credentials (tokens, keys, passwords, connection secrets). A setting for one call (for example a sandbox override on one command) is not a config_change; it goes where the agent’s registry entry documents. A current settings row read at export time has both snapshot markers and follows the transcript in the capture tail:
snapshot: true records configuration values rather than a change. Snapshot assembly means the producer has no history of the row. Neither marker supplies a missing timestamp for when those values took effect. A new capture can keep this row’s stable ID and give it a new seq. config_change.actor and memory_change.cause.actor are strings that identify the kind of actor. They are not the actor-reference objects defined in Identity.

instructions

instructions records instruction content that the source recorded as being in force: a system prompt, a project instruction file (AGENTS.md, CLAUDE.md), rules, skills, memory, or tool definitions.
Kinds: project is a shared project file; user is the person’s own file for all projects; local is the person’s file for one project that is not shared (Claude Code CLAUDE.local.md); managed is a file set by an organization’s policy; memory is memory content loaded into the context. truncated is a fact about what the source injected. The record’s capture state is a separate fact about what the record holds (see Missing data and revisions). Capture state keys: content, tools. ASR-173 An instructions record MUST contain kind and at least one of content, tools, removed, digest, or a capture.content state. ASR-174 instructions records are audit-only and are not entries in the context view. A consumer that needs the system layer for a point in the session MUST read it from the instructions records in force at that point, not from the context view. Some sources deliver instruction text to the model as messages (Codex sends AGENTS.md and skills as developer or user messages). Then both records exist: the message is what the context view shows, and the instructions record says which instruction it was.

memory_change

memory_change records a write to the agent’s memory that the source recorded: a note added to a memory file, a profile entry updated, an entry deleted, a request to forget a session, a consolidation run. Memory that is loaded into the context is an instructions record with kind: memory, or a message with origin: memory.
In the example session, the agent saved a note about the parser to its project memory with a file edit. Claude Code marks that edit as a memory write. ASR-190 A memory_change MUST contain store, op and cause, and cause MUST contain exactly one of callId or actor. ASR-191 A producer MUST write memory_change only for a write the source records as a memory write: an explicit memory event, or a file write to a location the agent’s registry entry documents as memory. It MUST set status: "applied" only when the source records that the write happened, not from a later snapshot of the store. A requested forget whose outcome the source does not record has no status, and readers MUST NOT present it as done. ASR-192 A memory_change and the file_change for the same file write describe one write. Consumers MUST NOT count them as two changes.