Shell lifecycle states
Each shell session moves through five well-defined states: cold, booting, ready, running, idle. Two terminal states exist too: retired (operator-initiated) and dead (container crashed). The DO tracks transitions and exposes them via /health for diagnostics.
Overview
- Source of truth
- UltronShell DO storage
- Tick
- Reclaim sweep every 30s
- Idle reclaim threshold
- 10 minutes by default; configurable via env
- Crash detection
- HTTP 5xx from container health probe for 30s straight marks DEAD
- Retire trigger
- POST /sessions/:id/retire or session id removed from workspace policy
The five states
| State | What it means |
|---|---|
| COLD | No container running. /work persisted as an R2 snapshot. Next request triggers a boot. |
| BOOTING | Container has been requested from the platform. Restoring /work from R2. |
| READY | Container alive, /work restored, agent CLI ready to accept commands. |
| RUNNING | An agent invocation or exec call is in flight. The DO holds the inflight request id. |
| IDLE | Last call finished more than 0 but less than the idle threshold ago. Still warm. |
| RETIRED | Operator-initiated end. Snapshot taken, container released, DO drops state. |
| DEAD | Container crashed and could not be restored. Last snapshot kept. Surfaced as an alert. |
Transitions
The complete graph.
Boot path
Cold to running, end to end.
- 01Caller hits the workerPOST /run-claude with x-ultron-session header. Worker resolves to a DO instance.
- 02DO reads stateIf state is COLD, transition to BOOTING and request a container from the platform.
- 03Restore /workIf a snapshot exists at snapshots/<session>.tar.gz, download and untar into /work before forwarding any request.
- 04Mark READYSet startedAt + restoredAt. Forward the queued request to the container.
- 05Mark RUNNINGContainer picks up the request. DO records the inflight id.
- 06Return + snapshotContainer responds. DO marks IDLE. Auto-snapshot fires via ctx.waitUntil to capture the new /work state.
Idle and reclaim
An idle session is still useful: the next request hits a warm container. The reclaim sweeper runs every 30 seconds and checks every IDLE session against the idle threshold (default 10 minutes). When a session has been idle past that, the sweeper takes a final snapshot if /work has changed since the last one, then releases the container. The DO state moves to COLD; the next request will hit the boot path.
Retire
An operator can retire a session explicitly via POST /sessions/:id/retire. Used when the session is logically done (skill finished, agent reset, workspace deleted) and there is no value in warm-keeping. Retirement is atomic: snapshot, release container, drop DO state. The session id is reusable afterwards; the next request with that id starts cold.