The adoption ladder
L2 does not mean writing a second log alongside the first. The native log uses the ASR envelope, and harness-specific events become vendor record types such as
dev.example/agent_switched.
L0: make your logs easy to convert
Converters can only record what a native log contains. These properties determine whether a conversion loses information:- Stable native IDs for sessions, messages, tool calls, model calls, plans and compactions. Converters keep them verbatim. Where none exist, they have to derive IDs and mark them as derived.
- Timestamps at native precision. A missing timestamp stays missing; it is never fabricated.
- Explicit parent pointers for subagents, forks and continued sessions. ASR records lineage only from positive evidence, never from similar text or timing.
- Compaction and rewind as events, with what was replaced and where any summary was inserted. If earlier history is deleted, say so.
- The model and token usage per model call, with an unambiguous rule for whether cached tokens are included in the input count.
- File changes recorded when the edit is made. A content hash taken later is not evidence of what the edit produced.
- Append, don’t rewrite. Logs rewritten as whole snapshots can only be converted with capture-scoped IDs, which do not stay stable across captures.
- Who sent each message, as a structured field rather than a name inside the text, and the chat or channel it came from.
- What started each turn: a person, a schedule, a webhook, a finished background task or another agent, with the job and run IDs.
- Approvals and questions as events: the request, what was shown, who or what decided it, and the answer. Never write secret answers to the log.
- Memory writes as events, with the tool call or person that caused them.
- Whether each reply was delivered, not only that it was generated.
- Which prompts a person typed. If your app injects prompts into another agent, keep your own record of which ones a person wrote; the other agent’s transcript cannot tell them apart.
L1: export command and discovery file
The integration companion defines two small interfaces. An export command.$XDG_CONFIG_HOME/agent-sessions/sources/<agent>.json, which tells tools where to find sessions and how to export them. It declares exportCommand, nativePaths, formatVersions and supportsDeletionHook.
The same companion defines the commit trailer that links a commit to the session that produced it:
Agent-Session-Url trailer. Existing trailers such as Claude-Session, Copilot-Session and Agent-Logs-Url are recognized as aliases. Publishing session references into git history requires the user’s consent.
L2: a conformant native log
At L2 the harness writes ASR directly:- Write one stream per session, with a single writer named by
producer.instance, and append only. - Set
producer.methodtonative. - Use
declarationrecords when profiles, extensions, roots or the harness version change during a session. - Put vendor fields under
_metawith reverse-DNS keys, and vendor enum values under a_prefix, so that readers can preserve what they don’t understand. - Check streams against the JSON Schemas and run the validator as part of your tests.
If your app runs other agents
Apps such as T3 Code run Claude Code or Codex sessions and add their own queues, approvals and delegated tasks. Each side keeps its own stream: one for the app’s thread, converted from the app’s records, and one for each backing session, converted from that agent’s native transcript.- The app’s stream names the backing sessions in an
executedBylineage link, optionally turn by turn. - Records in the app’s stream that copy a backing session carry
copiedFrom, so model calls, cost and edits are counted once. - Who wrote each prompt comes from the app’s stream. The backing transcript shows the app’s injected prompts as ordinary user prompts.
Register your agent
The agent identity registry lists each harness’s short name and its ID derivation rules: which native field is the session ID, how subagent sessions are identified, and whether IDs need anamespace because they are not globally unique. Registration is how converters written by different people agree on identity. See Contributing to add or correct an entry.
The registry entry also says where each fact your agent records goes when ASR has no standard field for it: a _meta key on the nearest record (preferred) or a vendor record type, citing your native name. A field or record type becomes standard when at least two of the four priority tools (Claude Code, T3 Code, Codex and OpenClaw) record it. Until then, a fact stays under its documented vendor key, so nothing your agent records has to be dropped.
If your harness speaks the Agent Client Protocol (ACP)
A recorder can produce ASR from a live Agent Client Protocol (ACP) v2 stream. The ACP v2 recorder mapping is normative and lists, field by field, what is supported and what is lost. It covers permission requests and questions to the user, and it uses theterminal record for long-running processes.