Skip to main content

Execution events, session timelines, traces, forks, and approvals

Orka records durable execution events for normal Kubernetes Job-backed Tasks. The event system does not require Agent Substrate. Substrate-backed workspaces can emit the same event contract later, but task eventing, session aggregation, trace APIs, fork/checkpoint, and approval read models work against the standard controller, API server, SQLite store, and worker event client.

Event model​

Events are appended to a task stream:

(namespace, streamType=task, streamID=<taskName>, seq)

seq is monotonically increasing per task stream. Task status remains the Kubernetes summary state; events are the durable detailed history.

Important fields:

FieldMeaning
seqPer-task event sequence.
typeStable event type such as TaskStarted, ToolCallCompleted, ApprovalRequested, or TaskForkCreated.
severitydebug, info, warning, or error. Unknown producer values normalize to info.
taskNameSource task name.
sessionNameOptional session tag used by session aggregation.
toolName / toolCallIDTool correlation keys.
summary, content, contentTextSanitized event payload surfaces.
truncationIndicates payload truncation without exposing removed data.

The persisted stream type accepted by the internal append API is task. Session streams are currently a read model derived from task events tagged with sessionName.

Task event list API​

GET /api/v1/tasks/:id/events?namespace=<ns>&after=0&limit=100&type=ToolCallCompleted

Response:

{
"namespace": "default",
"streamType": "task",
"streamID": "my-task",
"afterSeq": 0,
"latestSeq": 3,
"events": [
{"seq": 1, "type": "TaskStarted", "severity": "info", "taskName": "my-task"}
]
}

after=N returns events where task seq > N. limit is capped by the server maximum. Repeated type filters are supported by the HTTP API.

Task SSE stream API​

GET /api/v1/tasks/:id/stream?namespace=<ns>&after=<last-seq>

Each event frame uses the task sequence as the SSE id:

id: 2
event: execution_event
data: {"seq":2,"type":"WorkerStarted"}

When a terminal task event (TaskSucceeded, TaskFailed, TaskCancelled) is observed, the stream sends a final stream_complete frame and closes:

id: 3
event: stream_complete
data: {"lastSeq":3,"type":"TaskSucceeded"}

Reconnect by passing the last observed SSE id as after.

Session event aggregation​

Session timelines aggregate task events whose sessionName equals the session id:

GET /api/v1/sessions/:id/events?namespace=<ns>&after=0&limit=100
GET /api/v1/sessions/:id/stream?namespace=<ns>&after=<session-seq>

Session seq is a stable read-model cursor ordered by event append order. Delayed events with older producer timestamps do not renumber previously delivered session events.

Each session event includes both the session cursor and the source task cursor:

{
"seq": 2,
"streamType": "session",
"streamID": "session-1",
"taskName": "task-b",
"taskSeq": 1,
"taskStreamID": "task-b",
"type": "WorkerStarted"
}

Session streams do not close on task terminal events because a session can have more tasks later.

Task trace API​

This is Orka's event-derived task trace read model. It is separate from OpenTelemetry distributed traces: orka task trace reads stored execution events through the Orka API, not your OTLP collector/backend.

GET /api/v1/tasks/:id/trace?namespace=<ns>

The trace API builds a read model from the task event stream. It groups:

  • model requests,
  • tool calls,
  • child task references,
  • workspace preparation events,
  • artifact upload events,
  • errors and warnings,
  • the terminal event.

Unpaired completion/failure events are preserved in rawUnpaired with warnings instead of failing the request.

CLI:

orka task trace '<task>'
orka task trace '<task>' -o json

Fork/checkpoint MVP​

POST /api/v1/tasks/:id/fork?namespace=<ns>
Content-Type: application/json

{
"afterSeq": 5,
"newTaskName": "my-task-fork",
"agentRef": {"name": "reviewer"},
"prompt": "Continue from this conversation point and inspect the failed tool call."
}

MVP behavior:

  • validates the source task and namespace;
  • validates afterSeq as 0, latest, or an existing task event sequence;
  • creates a sibling/child Task with provenance annotations:
    • orka.ai/fork-source-task,
    • orka.ai/fork-source-seq,
    • orka.ai/fork-context-truncated;
  • emits TaskForkRequested and TaskForkCreated events;
  • includes a bounded, sanitized fork context in the API response;
  • starts with fresh workspace data unless executionCheckpoint selects a saved data checkpoint.

afterSeq selects conversation history only. For a source Task using a class-backed Substrate workspace with DataOnly suspension, executionCheckpoint restores saved data into an independent workspace. Session reuse gives the fork its own Session. Supply the Ready checkpoint's exact name, UID, and digest:

POST /api/v1/tasks/:id/fork?namespace=<ns>
Content-Type: application/json
Idempotency-Key: before-refactor-branch-1

{
"afterSeq": 5,
"prompt": "Continue from the saved workspace data.",
"executionCheckpoint": {
"name": "before-refactor",
"uid": "CHECKPOINT_UID",
"digest": "sha256:CHECKPOINT_DIGEST"
}
}

Replace the UID and digest placeholders with the checkpoint's metadata.uid and status.digest. The caller needs use on both the workspace class and the named checkpoint in the Task namespace. See checkpoint export and restore and the authorization reference.

Idempotency-Key enables retry recovery only when newTaskName is omitted. Send an explicit afterSeq and keep it fixed; omitting it selects the latest event, which may change between attempts. For the same source Task, namespace, and sequence, requests that pass validation and authorization behave as follows:

RequestResponse
First successful creation201 Created with the new Task name.
Same key and identical checkpoint selection, including omission on both requests200 OK with the existing Task name and no duplicate fork events.
Same key with a changed checkpoint name, UID, or digest, or with the checkpoint added or removed409 Conflict.

Use a new key for a different fork. An explicit newTaskName that already exists returns 409 Conflict, even when an Idempotency-Key is supplied.

CLI:

orka task fork '<task>' --after 5 --agent reviewer --prompt "Continue from here"

Durable approvals MVP​

Workers and the v2 tool broker emit ApprovalRequested. The internal event submission endpoint (SubmitExecutionEvent) rejects worker-submitted terminal approval events with 403 Forbidden ("terminal task and approval events must use controller-owned paths").

The approval lifecycle event types carried on the task stream are:

  • ApprovalRequested,
  • ApprovalApproved,
  • ApprovalDeclined,
  • ApprovalExpired,
  • ApprovalCancelled,
  • ApprovalExecutionUpdated.

The four terminal types (ApprovalApproved, ApprovalDeclined, ApprovalExpired, ApprovalCancelled) are appended only by controller-owned paths — for example the decision endpoint below — never by worker submissions. The v2 broker also owns ApprovalExecutionUpdated, which records execution separately from the reviewer decision. Worker submissions of this event are rejected.

Pending/current approvals are derived from the event stream:

GET /api/v1/tasks/:id/approvals?namespace=<ns>

A user can append a decision event:

POST /api/v1/tasks/:id/approvals/:approvalID/decision?namespace=<ns>
Content-Type: application/json

{"decision":"approve","reason":"safe to create PR"}

CLI:

orka task approvals '<task>'
orka task approve '<task>' '<approvalID>' --reason "looks safe"
orka task decline '<task>' '<approvalID>' --reason "not safe"

See human approval for v2 tools for the AgentKit and Foundry flow, bounded waiting, safe previews, and recovery.

Redaction and truncation​

Workers redact before submitting events, and the store sanitizes again before persistence. Public APIs and SSE frames return sanitized payloads only. Fake values matching bearer tokens, JWT-like strings, API keys, cookies, GitHub tokens, Anthropic/OpenAI tokens, and transaction-token headers must be redacted before they appear in SQLite rows or public responses.

Metrics​

Execution event metrics intentionally avoid task names, session names, event ids, tool call ids, and other high-cardinality labels.

Available metrics include:

  • orka_execution_events_appended_total{stream_type,event_type}
  • orka_execution_event_append_failures_total{stream_type,event_type}
  • orka_execution_event_append_duration_seconds{stream_type,event_type,result}
  • orka_execution_event_list_requests_total{scope,result}
  • orka_execution_event_list_duration_seconds{scope,result}
  • orka_execution_event_stream_connections_current{scope}
  • orka_execution_event_stream_reconnects_total{scope}
  • orka_execution_event_stream_errors_total{scope,reason}
  • orka_execution_event_redactions_total{stream_type,event_type}
  • orka_execution_event_truncations_total{stream_type,event_type}

Example PromQL:

sum(rate(orka_execution_events_appended_total[5m])) by (event_type)
sum(rate(orka_execution_event_append_failures_total[5m])) by (event_type)
histogram_quantile(0.95, sum(rate(orka_execution_event_append_duration_seconds_bucket[5m])) by (le, event_type))
sum(orka_execution_event_stream_connections_current) by (scope)
sum(rate(orka_execution_event_stream_reconnects_total[15m])) by (scope)
sum(rate(orka_execution_event_stream_errors_total[5m])) by (scope, reason)
sum(rate(orka_execution_event_redactions_total[1h])) by (event_type)

Troubleshooting​

SymptomChecks
Missing eventsConfirm task exists, event store enabled, worker has internal API URL/token, and sessionName is set for session timelines.
Stuck workerCheck task events for TaskStarted without WorkerStarted, then inspect pod scheduling/logs.
Model failureUse trace API; ModelRequestFailed appears in errors.
Tool failureUse trace API; failed tool calls are grouped by toolCallID.
Result missingConfirm terminal event and status.resultRef.available; event history does not replace result storage.
Stream reconnect duplicatesReconnect with the last observed SSE id as after; task streams use task seq, session streams use session seq.
Event store failureCheck /readyz, API logs for append/list failures, and the execution event metrics above.