Skip to main content

orchestration-session-lifecycle

How a PilotSwarm session maps to a duroxide orchestration. Read this before concluding that an "idle" session's orchestration is broken, stopped or stuck: most idle sessions are healthy, dehydrated and waiting for their next stimulus.

Source facts

Repository
microsoft/PilotSwarm
Last source activity
September 30, 2026 at 02:33
Detected SKILL.md language
English
Stars
8
Forks
4

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
orchestration-session-lifecycle
description
How a PilotSwarm session maps to a duroxide orchestration. Read this before concluding that an "idle" session's orchestration is broken, stopped or stuck: most idle sessions are healthy, dehydrated and waiting for their next stimulus.
# Orchestration ↔ Session Lifecycle You are the **agent-manager**. Before reporting that a session looks "stuck", "stopped", or "missing its orchestration", read this carefully. The single most common false-positive in tuner reports is conflating **session idle** with **orchestration not running**. They are not the same thing. ## The contract A PilotSwarm session is a long-lived logical entity. The duroxide orchestration backing it is an **event-driven generator** that runs **only when there is work to do** and is otherwise **dehydrated to disk**. This is by design — it's how PilotSwarm scales to thousands of sessions on a few worker pods. > A healthy session **spends most of its lifetime with no live > orchestration in memory**. That is the steady state. Not a bug. ## Concrete lifecycle states | Session looks like | Orchestration is | Healthy? | |---|---|---| | Just created | Active, running first turn | ✅ | | Mid-turn (LLM call in flight) | Active, awaiting activity | ✅ | | Waiting for user input | Dehydrated; history persisted | ✅ | | Cron'd background loop, between ticks | Dehydrated; durable timer pending | ✅ | | Idle for hours, no recent events | Dehydrated; ready to wake | ✅ | | `state = completed` in CMS | Terminated, history retained | ✅ | | `state = failed` in CMS | Terminated, last error recorded | ⚠️ investigate | | Active in CMS but no recent `iteration` events for hours **and** no pending timer | Possibly stuck | ⚠️ investigate | ## What "idle" actually means When you call `read_session_info` and see no recent activity, that **does not** mean the orchestration is dead. To distinguish a healthy dormant session from a real stall, check **all** of: 1. **CMS state.** `state` field. `running` / `waiting` / `completed` / `failed` / `cancelled`. Anything other than `failed` is not a fault per se. 2. **Pending timers / events.** `read_orchestration_stats(session_id)` returns `queue.pendingCount` and KV counters. A non-zero queue means the orchestration has work waiting and will be picked up by the next worker. A zero queue with `state = waiting` is **also normal** — it means the orchestration genuinely has nothing to do and is correctly dehydrated waiting on a stimulus (user input, cron wake-up, child completion). 3. **Recent execution history.** `read_execution_history(session_id, limit=20)` shows the most recent activities and timers. If the last entry is `WaitForUserInput` or `TimerFired waiting on cron`, the session is **idle by design**. 4. **Last checkpoint timestamp.** From `read_session_metric_summary`: `lastCheckpointAt` / `lastDehydratedAt`. A session dehydrated 3 hours ago, with no events since and `state = waiting`, is healthy. You only have a real stall when **all** of these are true: - `state` is `running` - there is a pending event in the queue (`pendingCount > 0`) - the last execution history entry is **older than the orchestration turn timeout** (typically minutes, not hours) - no worker has picked it up That combination usually means a worker crashed mid-turn or the session has lost affinity. Anything short of that is not a stall. ## Cron sessions in particular `sweeper` and `facts-manager` use low-frequency maintenance cron timers (`21600` seconds by default). `pilotswarm` and `resourcemgr` should not maintain recurring cron loops; they wake from direct operator prompts or runtime stimuli. **Between ticks, cron sessions are dehydrated.** Looking at `read_session_info` for a sweeper between maintenance ticks, you will see no live orchestration. That is correct. The `[cron 6h 0m]` style chips you see in the sessions pane mean "this session has a pending cron timer firing in N seconds". The orchestration genuinely is not in memory — duroxide will rehydrate it when the timer fires. ## What to report instead When asked "is this session healthy?", do not say "the orchestration is not running" unless you have verified the four-condition stall test above. Say one of: - **"Active and progressing."** State=running, recent events. - **"Idle (waiting on user/cron/child) — healthy dormant."** State=waiting or active-but-blocked, no pending stuck events. - **"Completed."** State=completed. - **"Failed at <step> with <error>."** State=failed. - **"Stalled."** All four conditions of the stall test met. Recommend worker logs / restart. Use these phrases. They map cleanly to operator action. ## Things that look like bugs but are not - **No recent `agent_events` in `read_agent_events`.** Means no LLM turn has run recently. Expected for a dormant session. - **`hydration_count == 0` but the session is hours old.** Means the session was created and ran exactly once, then dehydrated. Common for short reactive sessions. - **Snapshot bytes growing.** Normal — that's the point of the durable history. - **`pendingCount = 0` and state = `waiting`.** Healthy dormant. Not stuck.
View on GitHub