> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/pingdotgg/t3code/llms.txt
> Use this file to discover all available pages before exploring further.

# Events

> Domain events reference for orchestration state changes

## Overview

Domain events represent facts about what has happened in the system. They are the single source of truth and are persisted to the event store. The read model is derived by projecting these events.

## Event Structure

All events share these base fields:

<ResponseField name="sequence" type="number" required>
  Global event sequence number (monotonically increasing)
</ResponseField>

<ResponseField name="eventId" type="string" required>
  Unique event identifier (UUID)
</ResponseField>

<ResponseField name="aggregateKind" type="'project' | 'thread'" required>
  Type of aggregate root
</ResponseField>

<ResponseField name="aggregateId" type="string" required>
  Aggregate instance identifier (projectId or threadId)
</ResponseField>

<ResponseField name="type" type="string" required>
  Event type discriminator (e.g., `"project.created"`)
</ResponseField>

<ResponseField name="occurredAt" type="string" required>
  ISO 8601 timestamp when event occurred
</ResponseField>

<ResponseField name="commandId" type="string | null" required>
  Command that caused this event (null for spontaneous events)
</ResponseField>

<ResponseField name="causationEventId" type="string | null" required>
  Event that caused this event (for cascading effects)
</ResponseField>

<ResponseField name="correlationId" type="string | null" required>
  Original command ID for tracking related events
</ResponseField>

<ResponseField name="metadata" type="object" required>
  Additional event metadata

  <Expandable title="Metadata structure">
    <ResponseField name="providerTurnId" type="string">
      Provider's internal turn identifier
    </ResponseField>

    <ResponseField name="providerItemId" type="string">
      Provider's item/tool identifier
    </ResponseField>

    <ResponseField name="adapterKey" type="string">
      Provider adapter key
    </ResponseField>

    <ResponseField name="requestId" type="string">
      Approval/user-input request ID
    </ResponseField>

    <ResponseField name="ingestedAt" type="string">
      When event was ingested by server
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="payload" type="object" required>
  Event-specific data
</ResponseField>

***

## Push Event Format

Events are broadcast to clients via the `orchestration.domainEvent` channel:

```json theme={null}
{
  "type": "push",
  "channel": "orchestration.domainEvent",
  "data": {
    "sequence": 43,
    "eventId": "evt-abc123",
    "aggregateKind": "thread",
    "aggregateId": "thread-789",
    "type": "thread.created",
    "occurredAt": "2026-03-07T12:00:00.000Z",
    "commandId": "cmd-xyz",
    "causationEventId": null,
    "correlationId": "cmd-xyz",
    "metadata": {},
    "payload": {
      "threadId": "thread-789",
      "projectId": "proj-456",
      "title": "New conversation",
      "model": "gpt-5-codex",
      "runtimeMode": "full-access",
      "interactionMode": "default",
      "branch": null,
      "worktreePath": null,
      "createdAt": "2026-03-07T12:00:00.000Z",
      "updatedAt": "2026-03-07T12:00:00.000Z"
    }
  }
}
```

***

## Project Events

### project.created

A new project has been created.

<Expandable title="Payload fields">
  <ResponseField name="projectId" type="string" required />

  <ResponseField name="title" type="string" required />

  <ResponseField name="workspaceRoot" type="string" required />

  <ResponseField name="defaultModel" type="string | null" required />

  <ResponseField name="scripts" type="array" required />

  <ResponseField name="createdAt" type="string" required />

  <ResponseField name="updatedAt" type="string" required />
</Expandable>

***

### project.meta-updated

Project metadata has been updated.

<Expandable title="Payload fields">
  <ResponseField name="projectId" type="string" required />

  <ResponseField name="title" type="string">
    New title (if changed)
  </ResponseField>

  <ResponseField name="workspaceRoot" type="string">
    New workspace root (if changed)
  </ResponseField>

  <ResponseField name="defaultModel" type="string | null">
    New default model (if changed)
  </ResponseField>

  <ResponseField name="scripts" type="array">
    New scripts (if changed)
  </ResponseField>

  <ResponseField name="updatedAt" type="string" required />
</Expandable>

***

### project.deleted

A project has been soft-deleted.

<Expandable title="Payload fields">
  <ResponseField name="projectId" type="string" required />

  <ResponseField name="deletedAt" type="string" required />
</Expandable>

***

## Thread Lifecycle Events

### thread.created

A new thread has been created.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="projectId" type="string" required />

  <ResponseField name="title" type="string" required />

  <ResponseField name="model" type="string" required />

  <ResponseField name="runtimeMode" type="'approval-required' | 'full-access'" required />

  <ResponseField name="interactionMode" type="'default' | 'plan'" required />

  <ResponseField name="branch" type="string | null" required />

  <ResponseField name="worktreePath" type="string | null" required />

  <ResponseField name="createdAt" type="string" required />

  <ResponseField name="updatedAt" type="string" required />
</Expandable>

***

### thread.deleted

A thread has been soft-deleted.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="deletedAt" type="string" required />
</Expandable>

***

### thread.meta-updated

Thread metadata has been updated.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="title" type="string">
    New title (if changed)
  </ResponseField>

  <ResponseField name="model" type="string">
    New model (if changed)
  </ResponseField>

  <ResponseField name="branch" type="string | null">
    New branch (if changed)
  </ResponseField>

  <ResponseField name="worktreePath" type="string | null">
    New worktree path (if changed)
  </ResponseField>

  <ResponseField name="updatedAt" type="string" required />
</Expandable>

***

### thread.runtime-mode-set

Thread runtime mode has changed.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="runtimeMode" type="'approval-required' | 'full-access'" required />

  <ResponseField name="updatedAt" type="string" required />
</Expandable>

***

### thread.interaction-mode-set

Thread interaction mode has changed.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="interactionMode" type="'default' | 'plan'" required />

  <ResponseField name="updatedAt" type="string" required />
</Expandable>

***

## Message Events

### thread.message-sent

A message has been added to the thread.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="messageId" type="string" required />

  <ResponseField name="role" type="'user' | 'assistant' | 'system'" required />

  <ResponseField name="text" type="string" required>
    Message content
  </ResponseField>

  <ResponseField name="attachments" type="array">
    Image attachments
  </ResponseField>

  <ResponseField name="turnId" type="string | null" required>
    Associated turn ID
  </ResponseField>

  <ResponseField name="streaming" type="boolean" required>
    Whether message is still streaming
  </ResponseField>

  <ResponseField name="createdAt" type="string" required />

  <ResponseField name="updatedAt" type="string" required />
</Expandable>

<Note>
  Assistant messages may be sent incrementally with `streaming: true`, followed by a final event with `streaming: false`.
</Note>

***

## Turn Events

### thread.turn-start-requested

A user has requested to start a new turn.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="messageId" type="string" required />

  <ResponseField name="provider" type="'codex'">
    Provider to use
  </ResponseField>

  <ResponseField name="model" type="string">
    Model override
  </ResponseField>

  <ResponseField name="serviceTier" type="'fast' | 'flex' | null">
    Service tier
  </ResponseField>

  <ResponseField name="modelOptions" type="object">
    Provider-specific model options
  </ResponseField>

  <ResponseField name="assistantDeliveryMode" type="'buffered' | 'streaming'">
    Delivery mode
  </ResponseField>

  <ResponseField name="runtimeMode" type="'approval-required' | 'full-access'" required />

  <ResponseField name="interactionMode" type="'default' | 'plan'" required />

  <ResponseField name="createdAt" type="string" required />
</Expandable>

***

### thread.turn-interrupt-requested

A user has requested to interrupt the active turn.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="turnId" type="string">
    Specific turn to interrupt
  </ResponseField>

  <ResponseField name="createdAt" type="string" required />
</Expandable>

***

### thread.turn-diff-completed

A turn has completed and its checkpoint/diff has been recorded.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="turnId" type="string" required />

  <ResponseField name="checkpointTurnCount" type="number" required>
    Total turns at this checkpoint
  </ResponseField>

  <ResponseField name="checkpointRef" type="string" required>
    Git reference (commit SHA, branch, or tag)
  </ResponseField>

  <ResponseField name="status" type="'ready' | 'missing' | 'error'" required>
    Checkpoint status
  </ResponseField>

  <ResponseField name="files" type="array" required>
    Array of changed files

    <Expandable title="File structure">
      <ResponseField name="path" type="string">
        Relative file path
      </ResponseField>

      <ResponseField name="kind" type="string">
        Change type (added/modified/deleted)
      </ResponseField>

      <ResponseField name="additions" type="number">
        Lines added
      </ResponseField>

      <ResponseField name="deletions" type="number">
        Lines deleted
      </ResponseField>
    </Expandable>
  </ResponseField>

  <ResponseField name="assistantMessageId" type="string | null" required>
    Associated assistant message
  </ResponseField>

  <ResponseField name="completedAt" type="string" required />
</Expandable>

***

## Session Events

### thread.session-set

Provider session state has been updated.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="session" type="object" required>
    Session state object

    <Expandable title="Session structure">
      <ResponseField name="threadId" type="string" required />

      <ResponseField name="status" type="string" required>
        One of: `idle`, `starting`, `running`, `ready`, `interrupted`, `stopped`, `error`
      </ResponseField>

      <ResponseField name="providerName" type="string | null" required>
        Provider name (e.g., "codex")
      </ResponseField>

      <ResponseField name="runtimeMode" type="'approval-required' | 'full-access'" required />

      <ResponseField name="activeTurnId" type="string | null" required>
        Currently active turn
      </ResponseField>

      <ResponseField name="lastError" type="string | null" required>
        Last error message
      </ResponseField>

      <ResponseField name="updatedAt" type="string" required />
    </Expandable>
  </ResponseField>
</Expandable>

***

### thread.session-stop-requested

A user has requested to stop the session.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="createdAt" type="string" required />
</Expandable>

***

## Approval & User Input Events

### thread.approval-response-requested

A user has responded to a provider approval request.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="requestId" type="string" required />

  <ResponseField name="decision" type="'accept' | 'acceptForSession' | 'decline' | 'cancel'" required />

  <ResponseField name="createdAt" type="string" required />
</Expandable>

***

### thread.user-input-response-requested

A user has responded to a provider user input request.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="requestId" type="string" required />

  <ResponseField name="answers" type="object" required>
    Key-value map of answers
  </ResponseField>

  <ResponseField name="createdAt" type="string" required />
</Expandable>

***

## Checkpoint Events

### thread.checkpoint-revert-requested

A user has requested to revert to a previous checkpoint.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="turnCount" type="number" required>
    Number of turns to revert
  </ResponseField>

  <ResponseField name="createdAt" type="string" required />
</Expandable>

***

### thread.reverted

A checkpoint revert has been completed.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="turnCount" type="number" required>
    Number of turns reverted
  </ResponseField>
</Expandable>

***

## Activity Events

### thread.activity-appended

A new activity log entry has been added to the thread.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="activity" type="object" required>
    Activity log entry

    <Expandable title="Activity structure">
      <ResponseField name="id" type="string" required>
        Activity event ID
      </ResponseField>

      <ResponseField name="tone" type="'info' | 'tool' | 'approval' | 'error'" required>
        Visual tone/severity
      </ResponseField>

      <ResponseField name="kind" type="string" required>
        Activity kind (e.g., "tool\_call", "approval\_requested")
      </ResponseField>

      <ResponseField name="summary" type="string" required>
        Human-readable summary
      </ResponseField>

      <ResponseField name="payload" type="unknown" required>
        Activity-specific data
      </ResponseField>

      <ResponseField name="turnId" type="string | null" required>
        Associated turn
      </ResponseField>

      <ResponseField name="sequence" type="number">
        Sequence within turn
      </ResponseField>

      <ResponseField name="createdAt" type="string" required />
    </Expandable>
  </ResponseField>
</Expandable>

***

### thread.proposed-plan-upserted

A provider has proposed or updated a plan.

<Expandable title="Payload fields">
  <ResponseField name="threadId" type="string" required />

  <ResponseField name="proposedPlan" type="object" required>
    Proposed plan object

    <Expandable title="Plan structure">
      <ResponseField name="id" type="string" required>
        Plan identifier
      </ResponseField>

      <ResponseField name="turnId" type="string | null" required>
        Associated turn
      </ResponseField>

      <ResponseField name="planMarkdown" type="string" required>
        Plan description in markdown
      </ResponseField>

      <ResponseField name="createdAt" type="string" required />

      <ResponseField name="updatedAt" type="string" required />
    </Expandable>
  </ResponseField>
</Expandable>

***

## Event Ordering

Events are guaranteed to be:

1. **Globally ordered** by sequence number
2. **Per-aggregate ordered** within their stream
3. **Causally ordered** via causationEventId and correlationId

## Event Replay

Use the `orchestration.replayEvents` method to replay events:

```typescript theme={null}
const request = {
  id: crypto.randomUUID(),
  body: {
    _tag: 'orchestration.replayEvents',
    fromSequenceExclusive: 0, // Start from beginning
  },
};

ws.send(JSON.stringify(request));
```

This is useful for:

* Building read models
* Catching up after reconnection
* Debugging state issues
* Implementing event handlers

***

## Source Code

Event schemas are defined in:

* **Contracts**: `packages/contracts/src/orchestration.ts:557-982`
* **Event Store**: `apps/server/src/orchestration/Services/EventStore.ts`
* **Projections**: `apps/server/src/orchestration/Projections/`
* **Push Broadcast**: `apps/server/src/wsServer.ts:577-583`

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Commands" icon="terminal" href="/api/commands">
    Learn about commands that generate events
  </Card>

  <Card title="Orchestration API" icon="diagram-project" href="/api/orchestration">
    Explore the full orchestration API
  </Card>

  <Card title="WebSocket Protocol" icon="network-wired" href="/api/websocket-protocol">
    Understand the transport layer
  </Card>
</CardGroup>
