Session Lifecycle State Machine Transitions in Background-Agents: Complete Technical Guide
Background-agents implements a finite-state machine for session management where SessionState transitions between active, archived, and terminal states through specific HTTP API endpoints, with automatic reactivation when new prompts are received.
The ColeMurray/background-agents repository enforces a rigorous session lifecycle state machine to ensure consistent session behavior across the platform. The primary state is stored in the status field of SessionState (type SessionStatus), defined in packages/shared/src/types/sessions.ts. This state machine governs how sessions move between operational states based on user actions and system events.
Core State Transitions
The control-plane HTTP API exercises three fundamental transitions that modify the session table’s status column. These transitions are enforced by the Durable Object implementation in packages/control-plane/src/session/durable-object.ts.
Archiving Active Sessions
Sessions transition from active to archived via an authorized API call. Only the participant who created the session may trigger this transition.
When a POST /internal/archive request is received, the Durable Object updates the session status to "archived", preventing new prompts from being processed. According to the integration tests in packages/control-plane/test/integration/session-lifecycle.test.ts, this operation immediately halts prompt processing for the session【/cache/repos/github.com/ColeMurray/background-agents/main/packages/control-plane/test/integration/session-lifecycle.test.ts#L36-L54】.
Restoring Archived Sessions
Archived sessions can be restored to active status through explicit unarchiving. The transition from archived to active requires a POST /internal/unarchive request from an authorized participant.
The test suite validates this behavior by first archiving a session, then posting to /internal/unarchive, and verifying the status returns to "active"【/cache/repos/github.com/ColeMurray/background-agents/main/packages/control-plane/test/integration/session-lifecycle.test.ts#L69-L95】. This ensures sessions can be reused without creating new instances.
Automatic Reopening via Prompts
Terminal sessions automatically reactivate when receiving new prompts. The transition from any terminal state—completed, failed, cancelled, or archived—to active occurs when any participant sends a POST /internal/prompt request.
The parameterized test "reopens … session back to active" forces sessions into each terminal status and confirms that new prompts reset the status to "active"【/cache/repos/github.com/ColeMurray/background-agents/main/packages/control-plane/test/integration/session-lifecycle.test.ts#L98-L122】. This enables a seamless "continue later" workflow where users can resume conversations regardless of previous terminal states.
Implementation Architecture
State Definitions
The SessionStatus enum is defined in packages/shared/src/types/statuses.ts, while SessionState is declared in packages/shared/src/types/sessions.ts with the status: SessionStatus field【/cache/repos/github.com/ColeMurray/background-agents/main/packages/shared/src/types/sessions.ts#L89-L104】. Valid statuses include:
active- Currently processing promptsarchived- Suspended but restorablecompleted- Finished successfullyfailed- Terminated with errorscancelled- Aborted by user or system
Control-Plane Enforcement
The Durable Object in packages/control-plane/src/session/durable-object.ts serves as the state machine authority. It validates participant authentication before permitting state changes and persists updates to the session table’s status column. This centralized enforcement ensures that archived sessions cannot accept new prompts until explicitly unarchived, while terminal states can be revived through prompt activity.
Practical Code Examples
// Archive a session (requires creator authorization)
await fetch('http://internal/internal/archive', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId: 'user-1' })
});
// session.status becomes "archived"
// Unarchive to restore active status
await fetch('http://internal/internal/unarchive', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId: 'user-1' })
});
// session.status becomes "active"
// Re-open any terminal session with a new prompt
await fetch('http://internal/internal/prompt', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
content: 'Resume conversation',
authorId: 'user-1',
source: 'web'
})
});
// session.status resets to "active" regardless of prior terminal state
Summary
- Active sessions transition to archived via
POST /internal/archive, stopping prompt processing until explicitly restored. - Archived sessions return to active via
POST /internal/unarchive, requiring participant authorization. - Terminal states (completed, failed, cancelled, archived) automatically revert to active when receiving new prompts via
POST /internal/prompt. - The state machine is enforced by the Durable Object in
packages/control-plane/src/session/durable-object.tsand validated by integration tests inpackages/control-plane/test/integration/session-lifecycle.test.ts. - State definitions reside in
packages/shared/src/types/sessions.tsandpackages/shared/src/types/statuses.ts.
Frequently Asked Questions
What triggers a session to transition from archived back to active?
A session transitions from archived to active when an authorized participant sends a POST /internal/unarchive request. Additionally, any new prompt sent to an archived session via POST /internal/prompt will automatically reactivate it, as the system treats archived as a terminal state that can be revived through user activity.
Where is the session status stored in the codebase?
The session status is stored in the status field of the SessionState interface, defined in packages/shared/src/types/sessions.ts as type SessionStatus【/cache/repos/github.com/ColeMurray/background-agents/main/packages/shared/src/types/sessions.ts#L89-L104】. The actual database persistence occurs in the Durable Object implementation at packages/control-plane/src/session/durable-object.ts, which updates the session table’s status column.
Can archived sessions receive new prompts without unarchiving?
No. Archived sessions cannot receive new prompts until they are explicitly unarchived or until a new prompt is sent, which automatically triggers the reopening transition. The state machine enforces that archived sessions block prompt processing until the status changes back to active, either through the unarchive endpoint or the automatic reactivation mechanism.
What are the valid terminal states that can be revived by new prompts?
The valid terminal states that automatically transition to active upon receiving a new prompt are completed, failed, cancelled, and archived. The integration tests in packages/control-plane/test/integration/session-lifecycle.test.ts verify that each of these states can be revived when any participant sends a POST /internal/prompt request【/cache/repos/github.com/ColeMurray/background-agents/main/packages/control-plane/test/integration/session-lifecycle.test.ts#L98-L122】.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →