Problem
Nothing outside the Runtime process can tell whether a task is actually running. The rail infers it from streaming, which only knows about turns the local renderer sent, so a task running under a bot channel or in a second window reads as idle.
SessionSummary.runningTurnIds looks like the answer and is documented as the runtime's projection of the runs it holds. It does not reach Desktop:
SessionManager.listSessions() (packages/runtime/src/session-manager.ts) is the only path that attaches it.
- Runtime Host's catalog does not call that;
session-catalog-coordinator.ts reads storage directly via listCatalogPage().
- The wire projection's field list (
packages/runtime-host/src/protocol/session-catalog.ts) does not include it, and the projection function does not add it.
- Desktop Main's converter (
runtime-host-session-catalog-ipc-main.ts) copies persisted fields only.
The identifier appears nowhere in packages/runtime-host/src or apps/desktop/src/main outside a test fixture. #3033 removed a read of it that could never fire.
What is needed
Host should project live-run state as part of the catalog, versioned, and the projection has to distinguish known-empty from unknown. Collapsing those two is what lets a persisted status: 'running' left behind by a crash pulse forever: with no way to say "the Host holds no run for this task", a reader cannot tell "not running" from "no information".
Metadata mutation responses describe a header alone and legitimately omit live state, so whatever carries it must not be erased when a summary is replaced wholesale (use-app-shell-session-list.ts).
Runtime Host is the sole authority for execution, so this belongs there and needs its own review.
Context
Found by Codex in the adversarial review of #3033.
Problem
Nothing outside the Runtime process can tell whether a task is actually running. The rail infers it from
streaming, which only knows about turns the local renderer sent, so a task running under a bot channel or in a second window reads as idle.SessionSummary.runningTurnIdslooks like the answer and is documented as the runtime's projection of the runs it holds. It does not reach Desktop:SessionManager.listSessions()(packages/runtime/src/session-manager.ts) is the only path that attaches it.session-catalog-coordinator.tsreads storage directly vialistCatalogPage().packages/runtime-host/src/protocol/session-catalog.ts) does not include it, and the projection function does not add it.runtime-host-session-catalog-ipc-main.ts) copies persisted fields only.The identifier appears nowhere in
packages/runtime-host/srcorapps/desktop/src/mainoutside a test fixture. #3033 removed a read of it that could never fire.What is needed
Host should project live-run state as part of the catalog, versioned, and the projection has to distinguish known-empty from unknown. Collapsing those two is what lets a persisted
status: 'running'left behind by a crash pulse forever: with no way to say "the Host holds no run for this task", a reader cannot tell "not running" from "no information".Metadata mutation responses describe a header alone and legitimately omit live state, so whatever carries it must not be erased when a summary is replaced wholesale (
use-app-shell-session-list.ts).Runtime Host is the sole authority for execution, so this belongs there and needs its own review.
Context
Found by Codex in the adversarial review of #3033.