Every type on the wire.

Authority events are the record. Watch events say a scope changed. Hydrate records are derived pictures. Control messages are not part of the record. Commands are inbound intent, not events. Field rules live in the spec.

Core authority

run.started
The run enters running. Once per runId.
run.paused
Durable suspension. A blocking interrupt is followed immediately by pause with the same waitId.
run.resumed
The run returns to running.
run.stop.requested
Records the stop request and sets stopRequested.
run.finished
Successful terminal.
run.error
Failed terminal.
run.cancelled
Cancelled terminal.
interrupt.requested
Asks for a decision. scope is run or workflow. At most one open blocking interrupt per run.
interrupt.resolved
The decision. It closes the interrupt. It does not itself resume or finish the run or workflow. Expiry is decision=expired.
tool.call.started
A tool call began. executor is backend or client. This event is not permission to run a client tool.
tool.call.finished
The tool call ended.

Watch

session.revision
The session changed. Catch up. It does not consume sessionSequence.
run.revision
The run tree changed. Catch up.
workflow.revision
Workflow profile. The workflow changed.
node.revision
Graph profile. A node changed.
workspace.revision
Workspace-watch profile.
session.created
Workspace-watch profile. Requires the affected sessionId.
session.updated
Workspace-watch profile.
session.archived
Workspace-watch profile.

Workflow profile

narad.workflow/v1

workflow.started
The workflow began.
workflow.paused
Follows a workflow-scoped interrupt.requested in workflowSequence, with the same waitId and interruptId.
workflow.resumed
Follows resolution of a workflow-scoped interrupt, unless the backend emits a workflow terminal instead.
workflow.finished
Successful workflow terminal. Forbidden while any member run is open.
workflow.error
Failed workflow terminal.
workflow.cancelled
Cancelled workflow terminal.

Conversation profile

narad.conversation/v1

message.user.recorded
A user message. Requires messageId, messageScope (session, workflow, or run), and content.
message.text.started
An assistant or system message began. Requires messageId, role, and messageScope.
message.text.delta
A text fragment. Requires messageId and delta. Reducers apply it once.
message.text.completed
The text message closed. Requires messageId.
message.redacted
Changes display only. It does not erase the record.
reasoning.started
Reasoning began. Requires reasoningId.
reasoning.delta
A reasoning fragment.
reasoning.completed
Reasoning closed.
messages.snapshot
Hydrate, not an authority append. A transcript picture through a sessionSequence.

The default transcript shows session-scoped messages and the active, or most recently started, top-level run. Nested-run messages appear when a client opens that run.

Attachments and artifacts

attachment.added
An input was admitted. Raw bytes are not embedded in the event.
attachment.ready
The attachment is ready.
attachment.failed
The attachment failed.
attachment.removed
The attachment was removed.
artifact.added
An output was produced.
artifact.ready
The artifact is ready.
artifact.failed
The artifact failed.

State, UI, and graph

state.snapshot
narad.state/v1. Requires scope, revision, and state.
state.delta
An RFC 6902 patch. revision is baseRevision + 1.
state.compacted
Compaction through a session sequence.
ui.state.snapshot
narad.ui/v1. Same revision rules as state.
ui.state.delta
A UI patch.
view.opened
Requires viewId.
view.updated
operation is replace or patch.
view.closed
The view closed.
graph.snapshot
narad.graph/v1. Hydrate, not authority. A graph does not imply a workflow and does not change lifecycle.
graph.delta
A graph patch. On a gap, stop and request a snapshot.

Progress and extensions

progress.recorded
narad.progress/v1. Activity on a run. It does not open, pause, resume, or finish a run.
session.custom
Extension. Namespaced name and JSON value. It cannot close a run.
session.raw
Extension. Opaque payload. Untrusted.
workflow.custom
Workflow-scoped custom value.
workflow.raw
Workflow-scoped opaque payload.
run.custom
Run-scoped custom value.
run.raw
Run-scoped opaque payload.
node.custom
Node-scoped custom value.
node.raw
Node-scoped opaque payload.
trace.*
narad.trace/v1. Authorisation-gated. The spec does not enumerate each subtype here. Trace cannot affect lifecycle.
debug.*
narad.debug/v1. Same constraint as trace.

Control messages

No eventId, no authority sequence.

client.attached
The backend grants a leaseId for a clientExecutorId.
server.heartbeat
Backend to client. Liveness, not session state.
client.heartbeat
Client to backend. A valid heartbeat renews the lease. A missed heartbeat does not itself finish a run.
client.tool.execute
The only message that may run a client tool. Carries leaseId, executionToken, and an expiry. The client records the token before any side effect. A duplicate of an accepted token does not run again.
client.tool.finish
The client returns the token, outcome, and response. The backend checks the token before it appends tool.call.finished.