Session Supervisor
Workbench tracks every chat session with an authoritative activity state machine on the Rust side, and runs a background supervisor that keeps that state honest and gets errored or stalled sessions back on track — so many parallel workstreams can run unattended for hours.
Activity states
Section titled “Activity states”Each session is always in exactly one state:
| State | Meaning |
|---|---|
| Working | A turn is in flight and the event stream is live. |
| Compacting | Context compaction is running (pre-turn, forced mid-turn, or manual). |
| Waiting on user | The agent is blocked on you: a question, a plan approval, a permission prompt, or a completed turn awaiting review. |
| Recovering | Recovery machinery is actively holding or retrying — overflow compact-and-retry, rate-limit backoff (with a countdown to the next attempt), or auth refresh. |
| Suspect | The process looks alive but the stream has been silent past the stall threshold. Advisory only — it self-heals back to Working on the next stream event. |
| Interrupted | A turn died mid-work (process death or app restart). Eligible for the supervisor’s continuation nudge. |
| Errored | A turn failed and no recovery is in flight. |
| Idle | Nothing in flight. |
The sidebar, session tabs, tray, and CLI all derive from this one machine, so status indicators cannot disagree with reality for more than one watchdog tick. State changes stream to the UI as session-activity events; a full authoritative snapshot is re-emitted periodically so a lost event can never wedge an indicator permanently.
The reconciliation watchdog
Section titled “The reconciliation watchdog”Every tick (15s by default) the supervisor:
- Probes process liveness. A session that claims to be working whose agent process is gone is marked Interrupted immediately — this is the fix for permanent spinners after a lost process-exit event.
- Detects stalls. Working sessions with no stream events for the suspect threshold turn Suspect. The threshold is relaxed while a tool call or background task is open, since long-running tools are legitimately silent. Suspect sessions that stay silent past the hard-stall threshold have their turn interrupted and become Interrupted.
- Times out stuck compactions. A compaction running far past the compaction timeout is failed instead of latching the session busy forever.
- Reconciles on boot. Sessions whose persisted state shows a turn that was in flight when the app last exited load as Interrupted, not silently Idle.
Unattended recovery
Section titled “Unattended recovery”When a session is Errored, Interrupted, or stuck in Recovering, the supervisor re-drives the existing recovery machinery — overflow compact-and-retry, rate-limit backoff drains, auth refresh — within those subsystems’ own attempt budgets.
If a turn died mid-work and nothing else is pending, the supervisor sends a fixed continuation nudge (“Your previous turn was interrupted… continue where you left off”) so the workstream resumes without you. Nudges are capped per incident and rate-limited by a cooldown; the budget refills when a turn completes. The nudge text is constant — the supervisor never composes prompt content.
When nothing automatic is left to try, the session escalates: needs-attention is raised, the tray notifies, and the state stays honestly Errored/Interrupted instead of pretending to be idle.
The timeline
Section titled “The timeline”Every supervisor observation and action — marked interrupted, marked suspect, stall interrupt, overflow re-drive, rate-limit drain, auth resume, nudge sent, escalated — is recorded per session in a persistent timeline (supervisor_events) and emitted live as supervisor-event, so you can audit exactly what happened while you were away.
Settings
Section titled “Settings”The most useful knobs — the supervisor switch, auto-recovery, the nudge and its attempt cap, and the two stall thresholds — live in Settings → General (see the Settings reference). The full key list, including advanced cadence knobs with no dedicated UI control, is below; defaults are chosen so an unconfigured install behaves safely with multi-hour turns.
| Key | Description | Default |
|---|---|---|
supervisor.enabled | Master switch for the supervisor loop. | true |
supervisor.tick_seconds | Watchdog tick interval (clamped 5–60). | 15 |
supervisor.stall_suspect_minutes | Working + silent stream for this long → Suspect. | 10 |
supervisor.stall_tool_suspect_minutes | Suspect threshold while a tool call or background task is open. | 30 |
supervisor.stall_hard_minutes | Suspect + still silent this long → interrupt the turn. | 150 |
supervisor.auto_recover_enabled | Gates recovery actions and the nudge. Status reconciliation stays on regardless. | true |
supervisor.nudge_enabled | Allow the continuation nudge. | true |
supervisor.nudge_max_attempts | Nudges per incident before escalating. | 2 |
supervisor.nudge_cooldown_minutes | Minimum minutes between nudges. | 10 |
supervisor.snapshot_interval_seconds | Cadence of the authoritative activity snapshot re-emit. | 60 |
Stuck-compaction and stale-overflow thresholds reuse context_overflow.compact_timeout_seconds (see Settings) so the two subsystems can’t disagree about how long a compaction may run.