docs/craft/fix-live-scheduled-task-runs.md
SUCCEEDED or FAILED.RUNNING and AWAITING_APPROVAL rows even when the backend has linked a session_id.BuildSession, writes the initial user prompt, links ScheduledTaskRun.session_id, and commits before driving the agent loop. That means a live session exists before completion./event directly as the live-viewing architecture. Given a scheduled-run session_id, the api-server should resolve the sandbox pod, open the pod's /event stream with the existing auth path, filter events for that session, and stream matching ACP events to the browser./event Proxying/event stream. The api-server only attaches as another viewer and filters by session.PodEventBus inside the api-server: more efficient for multiple viewers because each api-server replica would hold one upstream /event connection per pod, then fan out locally. This is a good optimization if concurrent viewing becomes common, but the direct proxy is simpler for the first version./event is pod-wide rather than session-scoped. The server must filter events before they reach the browser, which brings the design back to an api-server proxy.RUNNING / AWAITING_APPROVAL from SUCCEEDED / FAILED; finished_at is useful for display and for stopping the live subscription; run_id is useful for subscribing to or invalidating one exact run.RUNNING, FAILED, SUCCEEDED, and AWAITING_APPROVAL runs are openable whenever they have a session_id. Keep QUEUED rows blocked until the executor creates the session, and keep SKIPPED rows blocked because no session is created./event, filter events by the session id, and stream matching events to the browser over SSE. The frontend merges those events into the existing session store while preserving scroll behavior. Stop the live subscription once the run reaches a terminal state.OnyxError when touching these APIs.