Multi-Session Architecture Specification
Version: 1.0.0 Status: DRAFT Created: 2025-12-27 Related: FILE-LOCKING-SPEC.md, LLM-AGENT-FIRST-SPEC.mdRFC 2119 Conformance
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174].Executive Summary
This specification defines the multi-session architecture for cleo, enabling multiple concurrent LLM agents to work on different task groups within the same project. Each session maintains isolated focus state and scope boundaries while sharing the underlying task data.Key Capabilities
| Capability | Description |
|---|---|
| Concurrent Sessions | Multiple agents work simultaneously on different task groups |
| Scoped Isolation | Each session owns a defined subset of tasks (epic, taskGroup, phase) |
| Per-Scope Validation | Active task constraint applies per-scope, not globally |
| Session Lifecycle | Start, suspend, resume, end with full state preservation |
| Conflict Detection | Prevent scope overlaps and task contention |
| Audit Trail | Session-aware logging for debugging and accountability |
Part 1: Architecture Overview
1.1 File Structure
1.2 Data Ownership
| File | Owner | Locking |
|---|---|---|
sessions.json | Session lifecycle operations | Exclusive per operation |
todo.json | Task operations | Exclusive per operation |
| Both | Focus changes, task completion | Sequential (sessions → todo) |
1.3 Mode Selection
Part 2: Session Scope Model
2.1 Scope Types
| Type | Definition | Use Case |
|---|---|---|
task | Single task only | Atomic work unit |
taskGroup | Parent + direct children | Typical workflow unit |
subtree | Parent + all descendants | Large feature work |
epicPhase | Epic filtered by phase | Parallel phase work |
epic | Full epic tree | Broadest scope |
custom | Explicit task list | Maximum flexibility |
2.2 Scope Definition
2.3 Scope Computation
Tasks in scope are computed by:- Start with
rootTaskId - If
typeincludes descendants: traverse hierarchy - Apply
phaseFilter: include only matching phases - Apply
labelFilter: include only tasks with ALL labels - Apply
maxDepth: limit hierarchy depth - Apply
excludeTaskIds: remove explicit exclusions - Cache result in
computedTaskIds
2.4 Scope Validation
Before session start, validate:rootTaskIdexists in todo.json- Computed scope is non-empty
- No HARD conflicts with existing sessions
- SOFT conflicts handled per
scopeValidationconfig
Part 3: Conflict Detection
3.1 Conflict Types
| Type | Condition | Behavior |
|---|---|---|
| HARD | Same task claimed as currentTask by two sessions | BLOCK always |
| IDENTICAL | Two sessions with identical scope | BLOCK always |
| NESTED | One scope is subset of another | ALLOW if allowNestedScopes |
| PARTIAL | Scopes overlap but neither is subset | ALLOW if allowScopeOverlap |
| NONE | Scopes are disjoint | ALLOW always |
3.2 Validation Algorithm
3.3 Task Focus Validation
When setting focus within a session:- Lock sessions.json
- Verify task is in session’s
computedTaskIds - Verify no OTHER session has task as
currentTask - Set
session.focus.currentTask - Lock todo.json
- Set
task.status = "active" - Reset other active tasks in scope to “pending”
- Save both files
- Unlock in reverse order
Part 4: Session Lifecycle
4.1 State Diagram
4.2 Session Start
A session MUST have a focused task to start. This ensures every session has a clear purpose and trackable work context.- Sessions track “what is being worked on” - a session without focus has no purpose
- Enables session-to-task attribution in logs and audit trails
- Prevents orphaned sessions that consume scope but do nothing
- Allows resumption with clear context (“pick up where you left off”)
--auto-focus specified):
- Filter tasks in scope with status = “pending”
- Sort by: priority (critical > high > medium > low), then createdAt (oldest first)
- Select first task
- If no pending tasks in scope: ERROR (E_SCOPE_EMPTY)
- Lock sessions.json
- Validate scope (no conflicts)
- Compute
computedTaskIds - Validate focus task exists and is in scope
- If
--auto-focus: select focus task per algorithm above - Generate session ID
- Create session entry with status=“active” and
focus.currentTaskset - Update
_meta.totalSessionsCreated - Lock todo.json
- Set focused task status = “active”
- Save both files
- Update todo.json
_meta.activeSessionCount - Log
session_startwith scope and focus context - Unlock both
4.3 Session Suspend
- Lock sessions.json
- Set
status = "suspended",suspendedAt = now() - Preserve focus state (not cleared)
- Increment
stats.suspendCount - Save sessions.json
- Log
session_suspended - Unlock
4.4 Session Resume
- Lock sessions.json
- Validate session exists and is resumable
- Re-validate scope (tasks still exist)
- Set
status = "active", clearsuspendedAt - Increment
resumeCount - Restore focus from preserved state
- Save sessions.json
- Log
session_resumed - Unlock
4.5 Session End
- Lock sessions.json
- Create
sessionHistoryEntryfrom session - Remove from
sessionsarray - Add to
sessionHistoryarray - Clear focus in todo.json if needed
- Reset active task to “pending” if needed
- Update
_meta.activeSessionCount - Save both files
- Log
session_end - Unlock
Part 5: Focus Management
5.1 Per-Session Focus
Each session maintains independent focus:5.2 Focus Commands
5.3 Active Task Constraint
Single-Session Mode: One active task globally Multi-Session Mode: One active task per scopePart 6: Locking Strategy
6.1 Lock Files
| File | Lock File | FD Range |
|---|---|---|
| sessions.json | sessions.json.lock | 200-202 |
| todo.json | todo.json.lock | 203-205 |
| todo-log.jsonl | todo-log.jsonl.lock | 206-208 |
6.2 Lock Order
To prevent deadlock, ALWAYS acquire locks in this order:6.3 Multi-File Transactions
6.4 Transaction Pattern
Part 7: Backup Integration
7.1 Files to Backup
7.2 Session-Triggered Backups
| Event | Backup Type | Condition |
|---|---|---|
| Session start | safety | backupOnSessionEvents = true |
| Session suspend | safety | backupOnSessionEvents = true |
| Session end | safety | backupOnSessionEvents = true |
| Session resume | none | State preserved in sessions.json |
7.3 Session Backup Metadata
Part 8: CLI Commands
8.1 Session Management
8.2 Focus (Session-Aware)
8.3 Environment Variables
Part 9: Migration
9.1 Enable Multi-Session
9.2 Migration Steps
- Create sessions.json with empty sessions array
- If
._meta.activeSessionexists:- Create session entry with
scope: { type: "epic", rootTaskId: null }(full project) - Move
.focuscontents tosession.focus
- Create session entry with
- Set
._meta.multiSessionEnabled = true - Clear
._meta.activeSession - Set
._meta.activeSessionCount = 1(if migrated session)
9.3 Backward Compatibility
- Single-session mode remains default
- Existing projects work unchanged
- Multi-session is opt-in via config
.focusin todo.json preserved for fallback
Part 10: Error Codes
| Code | Constant | Meaning |
|---|---|---|
| 0 | E_SUCCESS | Operation completed |
| 8 | E_LOCK_FAILED | Lock acquisition failed |
| 30 | E_SESSION_EXISTS | Session already active (single-session mode) |
| 31 | E_SESSION_NOT_FOUND | Session ID not found |
| 32 | E_SCOPE_CONFLICT | Scope overlaps with existing session |
| 33 | E_SCOPE_INVALID | Scope definition invalid or empty |
| 34 | E_TASK_NOT_IN_SCOPE | Task not within session scope |
| 35 | E_TASK_CLAIMED | Task already claimed by another session |
| 36 | E_SESSION_SUSPENDED | Operation requires active session |
| 37 | E_MAX_SESSIONS | Maximum concurrent sessions reached |
Part 11: Implementation Phases
Phase 1: Schema & Config
- Create sessions.schema.json
- Add multiSession section to config.schema.json
- Update todo.schema.json with multi-session fields
- Update log.schema.json with new actions
Phase 2: Core Library
- Create lib/sessions.sh
- Add scope computation functions
- Add conflict detection functions
- Add lock_multi_file / unlock_multi_file to lib/file-ops.sh
Phase 3: Session Lifecycle
- Update scripts/session.sh for multi-session
- Implement session start with scope
- Implement session suspend/resume
- Implement session list/show/history
Phase 4: Focus Integration
- Update scripts/focus.sh for session-awareness
- Implement per-scope active task validation
- Update lib/validation.sh
Phase 5: Backup & Logging
- Update lib/backup.sh for sessions.json
- Update lib/logging.sh for scope context
- Implement session-triggered backups
Phase 6: Migration & Testing
- Create migration script
- Unit tests for scope computation
- Integration tests for concurrent sessions
- Documentation updates
Appendix A: Example Scenarios
A.1 Two Agents on Different Epics
A.2 Parallel Phase Work Within Epic
A.3 Nested Task Groups
Appendix B: Schema Quick Reference
sessions.json Structure
End of Specification
