Skip to content

Trace schema

Two related shapes carry trace information: ActivityFrame (used by the session-store interface) and NormalizedActivityEvent (the canonical normalized form across runtimes). They overlap heavily; the live event flowing on the bus is NormalizedActivityEvent, the persisted shape is ActivityFrame.

NormalizedActivityEvent

activity/NormalizedActivityEvent.ts:30-49:

ts
interface NormalizedActivityEvent {
  readonly requestId: string;
  readonly sessionId: string;
  readonly ts: number;
  readonly source: string;
  readonly runtimeKind: WorkerKind;       // 'internal' | 'claude-code' | 'codex' | 'deterministic'
  readonly kind: NormalizedActivityKind;  // 'prompt' | 'llm' | 'tool' | 'system' | 'worker'
  readonly phase: NormalizedActivityPhase;
  readonly seq?: number;
  readonly traceId?: string;
  readonly spanId?: string;
  readonly parentSpanId?: string;
  readonly targetKey?: string;
  readonly workerRef?: WorkerRef;
  readonly summary?: string;
  readonly target?: string;
  readonly op?: string;
  readonly data?: unknown;
  readonly durationMs?: number;
}

ActivityFrame (persisted shape)

IAgentSessionStore.ts:85-103:

ts
interface ActivityFrame {
  requestId: string;
  seq: number;
  ts: number;
  source: string;
  traceId?: string;
  spanId?: string;
  parentSpanId?: string;
  sessionId?: string;
  resumeId?: string;
  principalId?: string;
  kind: string;
  phase: string;
  summary?: string;
  target?: string;
  op?: string;
  data?: unknown;
  durationMs?: number;
}

The persisted shape adds resumeId (when this frame belongs to a resumed run), and principalId. It uses string types for kind / phase (the normalized version uses tagged unions).

NormalizedActivityKind

ts
type NormalizedActivityKind = 'prompt' | 'llm' | 'tool' | 'system' | 'worker';

NormalizedActivityPhase

ts
type NormalizedActivityPhase =
  | 'session.started'
  | 'turn.started'
  | 'thinking'
  | 'text'
  | 'tool.start'
  | 'tool.result'
  | 'command.executed'
  | 'file.changed'
  | 'approval.required'
  | 'approval.resolved'
  | 'response'
  | 'error'
  | 'cancelled'
  | `raw.${string}`;

The raw. template-literal phase passes through provider-specific events that have no normalized equivalent yet.

AgentEventOp (the bus emit)

ts
type AgentEventOp =
  | '$thinking'
  | '$token'
  | '$toolCallStarted'
  | '$toolCallCompleted'
  | '$response'
  | '$error'
  | '$cancelled';

These are the bus-side operation names that subscribers listen for. An AgentEventEmission carries both the op-and-payload form (for bus dispatch) and the normalized activity event (for persistence and replay).

Normalizer entry points

Source runtimeNormalizer file
Internal oracleevents synthesized directly inside InternalOracleRuntimeAdapter
Claude Codeactivity/ClaudeEventNormalizer.ts (normalizeClaudeEvent)
Codexactivity/CodexEventNormalizer.ts (normalizeCodexEvent)

Each normalizer takes a runtime-specific event plus ActivityNormalizerContext and returns NormalizedActivityEvent. The context carries the bus-side identifiers (sessionId, requestId, runtimeKind, sourceMount) that aren't present in the runtime-side event.

See also

Source: projects/matrix-3/packages/agents/src/activity/NormalizedActivityEvent.ts:1-95, projects/matrix-3/packages/agents/src/IAgentSessionStore.ts:85-103.