Skip to content

Session Lifecycle

Z-M-Huang edited this page May 2, 2026 · 5 revisions

Session Lifecycle

contractVersion: 1.1.0

A session is the unit of stud-cli's work. It has a well-defined sequence of states from start to close, persisted by the active Session Store.


States

stateDiagram-v2
    [*] --> Idle : launched
    Idle --> Active : first turn
    Active --> Active : next turn
    Active --> Persisted : snapshot written
    Persisted --> Active : next turn
    Persisted --> Closed : explicit close
    Persisted --> Resumed : --continue
    Resumed --> Active : first post-resume turn
    Active --> Closed : crash / explicit close
    Closed --> [*]
Loading
State Meaning
Idle The session is loaded — extensions are active, manifest is recorded, but no turn has started yet.
Active A turn is in progress.
Persisted The session is durable at the last snapshot. Safe to close or walk away.
Resumed The session was reloaded from a snapshot and is re-hydrating before first turn.
Closed The session is done. Extensions have been disposed.

Transitions

Transition Triggered by Work
Idle → Active First RECEIVE_INPUT, or — for an SM-driven session — the scheduler entering the entry stage's Setup. Emit SessionTurnStart.
Active → Active Next user input, or — for an SM-driven session — the scheduler entering the next sequential stage execution or the next parallel fan-out group's spawn after the previous turn's snapshot commits. Complete the previous turn; snapshot; emit SessionTurnStart.
Active → Persisted Turn completion → snapshot acknowledged by the active Session Store. Write state slots; emit SessionPersisted.
Persisted → Active Next input (user turn, or SM-driven next stage from Next()).
Persisted → Closed /save-and-close, explicit shutdown, or SIGTERM after drain. Dispose extensions in reverse topological order.
Persisted → Resumed Startup with --continue. Load snapshot; restore manifest-backed fields; re-hydrate extensions.
Resumed → Active First turn after resume. Same as Idle → Active post-hydration.
Active → Closed Crash or explicit close during a turn. Turn is abandoned — the snapshot reflects the pre-turn state.

Idle: what has already happened

Reaching Idle requires:

  1. Project root is resolved. For the launch parser default this is exactly <cwd>/.stud; there is no ancestor walk.
  2. Extension discovery, validation, and activation have completed for the new session.
  3. The slim session manifest has been recorded.
  4. The active Session Store has opened and accepted the manifest.

If any critical startup step fails, the session never reaches Idle.


Resumed: always-core-works (Q-2)

Resume reads the slim manifest and any referenced state slots, then runs in this order:

  1. Validate that the current Session Store matches the store that wrote the session (cross-store mismatch is a hard Session.ResumeMismatch, per invariant #4).
  2. Load the four manifest fields unconditionally: messages, smState, mode, projectRoot. The transition only blocks on this four-field parse; nothing else.
  3. Re-hydrate extensions through their lifecycle.
  4. Attempt to restore the attached SM, if any.
  5. If an extension needed for auxiliary behavior is missing or fails, it is silently absent. Core resume still proceeds.
  6. Transition to Active at first input.

The key v1 rule is always-core-works: core resume never fails due to extension drift. The four manifest fields are loaded unconditionally and the conversation continuation runs even when one or more extensions are absent or failing. Missing extensions are silently absent.

SM backward compatibility is the SM author's responsibility. Drift in the persisted smState shape between SM versions is an SM-author concern; a shape mismatch reported by the SM does not abort resume of the conversation — it aborts the SM's own continuation. Core does not interpret smState shape; it delivers the slot to the SM and lets the SM author decide how to handle drift.


Persisted: safe to walk away

A session in Persisted is the canonical durable state. --continue from a persisted session restores the same message history and session-fixed fields, subject to the same-store invariant.


Closed: shutdown order

Shutdown drains in-flight work when possible, writes the final acknowledged snapshot, deactivates extensions, disposes them, and closes the Session Store. A crash skips the graceful path; the last acknowledged snapshot remains authoritative.


Events emitted per state

Event When
SessionStarted On reaching Idle.
SessionTurnStart On entering Active for a turn.
SessionTurnEnd On completing a turn before snapshot.
SessionPersisted On Active → Persisted.
SessionResumeStarted On beginning Resumed.
SessionResumed On Resumed → Active (first post-resume turn).
SessionClosed On reaching Closed.

Child sessions (subagents)

A session may open child sessions through the bundled delegate tool on behalf of its LLM. A child session has its own lifecycle following the same Idle → Active → {Closed | Halted | Aborted} shape, but is ephemeral in v1 — it does not transition through Persisted and is not resumed across crashes. The child inherits the parent's mode, provider/model, interactor set, project trust, and --yolo posture at spawn; it does not inherit an attached SM. See Subagent Sessions for the full child-session spec.

The orchestrator-session lifecycle here governs only the parent session. Parent-session cancel cascades to every running child session before the parent itself is torn down (Concurrency and Cancellation).


Related pages


Changelog

1.0.0 — initial

  • Session lifecycle: four states (Idle → Active → Persisted → {Closed | Resumed}) with documented triggers and emitted Session* events.
  • Always-core-works resume: the four manifest fields (messages, smState, mode, projectRoot) load unconditionally and core resume never fails due to extension drift.
  • SM backward compatibility across smState shape drift is the SM author's concern, not core's.
  • Cross-store resume hard-fail (Session.ResumeMismatch) is the only resume-blocking guard alongside corrupt manifests.

1.1.0 — Child sessions (subagents)

  • New "Child sessions (subagents)" section documents how a session may open child sessions through the bundled delegate tool. Child sessions follow the same Idle → Active → {Closed | Halted | Aborted} shape but are ephemeral in v1 — no Persisted, no resume.
  • Cancellation cascade: parent-session cancel cascades to every running child session before parent teardown. Cross-link to Concurrency and Cancellation § Cancellation scopes.
  • Inheritance from parent at spawn: mode, provider/model, interactor set, project trust, --yolo, projectRoot. Attached SM is not inherited.
  • No removal or shape change to existing parent-session lifecycle; additive on top of 1.0.0.

Introduction

Reading

Core runtime

Contracts

Category contracts

Context

Security

Runtime behavior

Operations

Providers (bundled)

Integrations

Reference extensions

Tools

UI

Session Stores

Loggers

Providers

Hooks

Context Providers

Commands

Case studies

Flows

Maintainers

Clone this wiki locally