Detailed harness contract for websocket event families, transcript upsert/delta behavior, and extension lifecycle endpoints.
Use with harness-runtime-events.md for operational client/server integration work.
Runtime emit() normalizes to:
enqueue_resultaction_resulthandler_resulthandler_error
Action execution is first-wins reconciled within one emit pass.
orchestrator_job_queuedorchestrator_job_startedorchestrator_job_progressorchestrator_job_completedorchestrator_job_failedorchestrator_job_canceledsuggested_request_updated
approval/approval_resolvedtool_user_input_requested/tool_user_input_resolvedtool_call_requested/tool_call_resolved
codex-manager also emits raw compatibility envelopes for diagnostics/fallback routing:
notification(raw app-server notification payload)server_request(raw server-initiated request payload for unsupported methods)
For supported interactive request methods (approval/tool-input/tool-call), specialized events are emitted instead of server_request.
codex-manager emits focused websocket aliases for several high-value app-server notifications:
turn_plan_updatedturn_diff_updatedthread_token_usage_updatedapp_list_updated(global broadcast)mcp_oauth_completed(global broadcast)account_updated(global broadcast)account_login_completed(global broadcast)account_rate_limits_updated(global broadcast)
Connection and control frames:
- server sends
{"type":"ready","threadId":<initial|null>}immediately after connect - client may send
{"type":"subscribe","threadId":"<sessionId>"}to set/replace thread filter - client may send
{"type":"unsubscribe"}to clear thread filter - client may send
{"type":"ping"}and receives{"type":"pong"} - invalid command payloads receive
{"type":"error","message":"invalid websocket command"}
Event envelope shape:
- normal event frames are published as
{"type": "...", "threadId": "...|null", "payload": ...} - control frames (
ready,pong,error) do not carry normal event payloads
Thread-filter behavior:
- when a socket has a thread filter, it receives only events for that thread
- filtered sockets do not receive
threadId: nullevents unless event is published as global broadcast - global broadcast events bypass normal thread filters
- system-owned thread events are force-filtered and only delivered to sockets explicitly subscribed to that exact thread
Websocket delta event:
transcript_updatedwiththreadIdand upserted entry payload
Upsert API:
POST /api/sessions/:sessionId/transcript/upsert
Entry fields include:
messageId,turnId,role,type,content,status- optional
details,startedAt,completedAt
GET /api/agents/extensionsPOST /api/agents/extensions/reload
Lifecycle controls are governed by RBAC mode (disabled|header|jwt) and trust mode (disabled|warn|enforced).
agent_instruction payload can include supplementalTargets[] for terminal transcript reconciliation with deterministic fallback behavior.
- Harness event index:
harness-runtime-events.md - Event catalog and normalization:
harness-runtime-event-catalog.md - Extension lifecycle runbook:
../operations/agent-extension-lifecycle-and-conformance.md