1.9 KiB
1.9 KiB
Event Stream Contract
Status
Planned for the next milestone. The Phase 1 web skeleton does not implement the event stream yet.
Intended Endpoint
GET /api/events/stream
Transport Choice
- start with Server-Sent Events rather than websockets
- keep the stream read-only and cursor-based
- let the frontend use events to invalidate or refresh TanStack Query caches
Query Parameters
after_event_id: optional monotonic cursorrun_id: optional run filter for run-scoped pagesthread_id: optional thread filter for timeline views
Event Envelope
Each SSE message should carry one JSON object with this shape:
{
"event_id": 42,
"event_type": "task_blocked",
"run_id": "run_web_001",
"task_id": "T1",
"thread_id": "thr_123",
"summary": "Need the API shape",
"payload": {
"source": "orch"
},
"created_at": "2026-03-20T09:30:00Z"
}
Expected First Event Types
task_addedtask_readytask_dispatchedtask_runningtask_blockedtask_answeredtask_donetask_failedthread_claimthread_updatethread_replythread_resultcouncil_talliedcouncil_report_persisted
Cursor Rules
event_idis the only resume cursor- the server should emit events in ascending
event_idorder - reconnect clients should pass the last processed
event_id - the server should not depend on in-memory subscriptions for correctness
Frontend Usage
- run detail pages should subscribe with
run_id - thread views may subscribe with
thread_id - the client should prefer refetch/invalidate behavior over complex local reducers in the first realtime slice
Backend Notes
- source data should come from the existing shared
eventstable orchdshould treat the stream as a projection over persisted events, not as a separate ephemeral bus- if filtering becomes expensive later, move filtering logic into a dedicated query layer without changing the wire contract