Skip to content

Trace replay

Trace replay means: take the activity-frame log of a past session, feed those frames back into the system, and compare new behavior to old. It's how a meta-harness validates that a prompt or tool change actually changed the agent's outputs rather than just the model's.

What you have to work with today

The platform persists everything you need to reconstruct a session:

ResourceLocation
Messages (full)session_messages SQLite rows
Tool args/resultsembedded in those rows (tool_args, tool_result)
Activity framesIAgentSessionStore.loadActivityFrames(sessionId, requestId?)
Snapshot at session startsession_state(session_id, key='snapshot')
REPL statesession_state(session_id, key='repl_state')
Prompt templates<host-home>/prompts/ if user-overridden, else bundled

Reconstructing means: load the snapshot, load the prior messages, load the frames, and replay either the LLM output (deterministic re-prompt) or the tool dispatches (deterministic invoke loop).

The $traceQuery accept

AgentsRoot.accepts.$traceQuery returns activity frames for (sessionId, requestId). This is the canonical read path.

bash
matrix invoke system.agents '$traceQuery' '{ "sessionId": "ses_…", "requestId": "req_…" }'

Returns { ok: true, frames: ActivityFrame[] }. Frames carry enough information (target/op/args for tool.call, result/durationMs for tool.result) to reconstruct what happened.

Replay strategies

Two strategies are useful in practice:

  1. Tool replay. Walk the frames in order; for each tool.call, re-invoke the same (target, op, args) and compare the result against the recorded tool.result.data. Differences indicate underlying-actor non-determinism (e.g. a search hit a different memory because new memories were added).

  2. Prompt replay. Reconstruct the system prompt + prior messages, then re-issue the prompt to the model with the same provider/model. The new response is compared against the recorded final response. Use temperature: 0 for any chance at determinism.

There is no built-in command for either today; both are programmable through the actor surface.

What's NOT wired

  • A first-class harness.replay op or CLI. You write it on top of $traceQuery and AgencyInvokeTool for now.
  • A diff renderer. Director's session view shows live frames but not "this run vs that run."
  • Replay against a different model. The recorded frames don't carry full prompt context — to replay against another model you must reconstruct the prompt yourself from the snapshot + prior messages + active prompt template.

Operator considerations

  • Replay is read-heavy. If you're replaying many sessions, RecordBackedSessionStore (against the observability record store) scales better than FileAgentSessionStore.
  • Replays produce new activity frames, even if the new run is identical to the old one. They don't share frames.
  • Replay against the live runtime competes for the same actor as production traffic. For comparisons, run replays in a sandbox Host (a separate --home).

See also

Source: projects/matrix-3/packages/agents/src/IAgentSessionStore.ts:79-80 (frame load API), projects/matrix-3/packages/agents/src/AgentsRoot.ts:103 ($traceQuery accept), projects/matrix-3/packages/agents/src/FileAgentSessionStore.ts and RecordBackedSessionStore.ts (the two backends).