Skip to content

Agent Trace interop

Agent Trace is an open wire format for AI code attribution traces, published by Cursor as an RFC in January 2026.

Status (2026-08). Agent Trace’s original GitHub home went 404 and the multi-vendor momentum behind it has faded. The spec and schema still resolve at agent-trace.dev, frozen at v0.1.0. Selvedge vendors that schema and keeps the exporter — the records it emits stay valid and portable regardless of the standard’s fate — but we no longer describe it as a live, growing ecosystem.

Since v0.3.9, selvedge export --format agent-trace and selvedge import --format agent-trace ship — Selvedge round-trips Agent Trace v0.1.0 records. Agent Trace is the wire format; Selvedge is the live capture + query layer that emits it, with no runtime dependency on the upstream project.

Agent Trace standardizes the transport — how attribution data crosses tool boundaries. It doesn’t prescribe how individual agents capture that data, and it doesn’t provide a query layer.

Selvedge fills both gaps:

  • Capture — the MCP-server contract that agents call as they work
  • Query — the CLI + MCP read tools (blame, diff, history, changeset, search)

The two layers are orthogonal. You can have Selvedge without Agent Trace (you do, by default). You can have Agent Trace without Selvedge (consume from another producer). Together, you get cross-tool readable history that survives a tool migration.

What selvedge export --format agent-trace emits

Section titled “What selvedge export --format agent-trace emits”

Selvedge conforms to the real Agent Trace v0.1.0 record shape: line ranges live inside each file’s conversations[], wrapped in a tool / vcs envelope, with all Selvedge-specific data under the reverse-domain metadata["dev.selvedge"] namespace (there is no top-level contributors[] or extensions). The full mapping is in docs/agent-trace-interop.md.

{
"version": "0.1.0",
"id": "<uuid>",
"timestamp": "<rfc3339>",
"vcs": { "type": "git", "revision": "<sha>" },
"tool": { "name": "selvedge", "version": "<v>" },
"files": [
{
"path": "<repo-relative path>",
"conversations": [
{ "contributor": { "type": "ai" }, "ranges": [ { "start_line": 42, "end_line": 67 } ] }
]
}
],
"metadata": { "dev.selvedge": {} }
}

The mapping from a Selvedge ChangeEvent:

  • git_commitvcs.revision (vcs.type = "git")
  • producer identity → tool = { name: "selvedge", version }
  • agentconversations[].contributor.type (ai, else unknown); the agent name lands in metadata["dev.selvedge"].agent. model_id is not fabricated — Selvedge stores an agent name, not a models.dev id
  • entity_path (file-typed) → files[].path; diffconversations[].ranges[] via unified-diff hunk extraction
  • entity_path (non-file: column, env var, dependency, route) → metadata["dev.selvedge"].entity with an empty files[] — no native Agent Trace concept
  • change_type, reasoning, session_id, changeset_id, project, extra metadata — all under metadata["dev.selvedge"]

Honest fidelity. Entity-level events (a DB column, env var, dependency) and migration-imported events have no line range, so they carry metadata["dev.selvedge"].range_unknown: true and an empty files[] rather than a fabricated [1, 1] placeholder. --ndjson streams one record per line for large histories; --collapse-by-session merges a session’s events into a single record.

Selvedge events are exportable as Agent Trace records, and Agent Trace records can be read by:

  • Sentry / Datadog — link a stack trace to the Selvedge event for the column / env var / function involved
  • GitHub Copilot / Cursor — show “this change was made by claude-code in changeset:add-stripe-billing” inline as you read code
  • SOC 2 / EU AI Act audit tooling — emit an immutable, attributable trail of every AI-made change

You don’t have to wait for any of that to use Selvedge. The local SQLite file is the canonical store, and selvedge export --format agent-trace is opt-in — a portable, documented shape your history can travel in, independent of whether any particular standard wins.

You can. If you have a tool that already speaks Agent Trace and you don’t need the local query layer, skip Selvedge.

Selvedge wins when:

  1. You want a reasoning-quality validator. Agent Trace doesn’t prescribe one. Selvedge runs every incoming reasoning through selvedge.validation and surfaces weak/empty cases via selvedge stats.
  2. You want changesets. Agent Trace v0.1.0 doesn’t define first-class changeset semantics. Selvedge does, and carries them in metadata["dev.selvedge"].changeset_id.
  3. You want a CLI you can pipe. selvedge blame, selvedge diff, selvedge changeset — none of these have an Agent-Trace-native equivalent.
  4. You don’t want a network dependency. Selvedge is local SQLite; Agent Trace producers and consumers can be anywhere.
  • v0.3.x — Selvedge native MCP + CLI interface
  • v0.3.9selvedge export --format agent-trace and selvedge import --format agent-trace shipped (Agent Trace v0.1.0, opt-in and additive). Selvedge both emits and ingests Agent Trace v0.1.0 — export is full-fidelity, import is best-effort for foreign producers.
  • v0.3.12selvedge import --format git-notes — read-only one-way reader for Git-Notes-style attribution (interop, not substitute).
  • v0.4.0 — PostgreSQL backend + the MCP tool-rename/consolidation
  • v0.4.1 — HTTP transport + auth (Phase 3.1)
  • v1.0.0 — webhook events on schema changes, optional Agent-Trace-native push to a remote sink