Skip to main content

Epic-Bound Session Architecture Specification

Version: 1.1.0 Status: DRAFT Created: 2025-12-28 Supersedes: MULTI-SESSION-SPEC.md (partial)

RFC 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 Epic-Bound Session architecture for CLEO, replacing the optional session model with a mandatory Epic-scoped session system. Every session is bound to an Epic (or parent task with subtasks), enabling structured work tracking, multi-agent coordination, and automatic session note aggregation on Epic completion.

Key Principles

PrincipleDescription
Epic-BoundEvery session MUST be scoped to an Epic or parent task
Session-Required WritesAdd, update, complete operations REQUIRE active session
Agent-Per-Task FocusOne agent per focused task, session-bound locking
Informative OutputsAll errors include context, suggestions, blockers
Registry-Based DiscoveryAgents browse available sessions before starting
4-State LifecycleActive → Suspended → Ended → Closed

Part 1: Session Lifecycle

1.1 State Diagram

                    ┌──────────────────┐
                    │   (not exists)   │
                    └────────┬─────────┘
                             │ session start --epic T001

┌─────────────────────────────────────────────────────────────┐
│                         ACTIVE                               │
│  - Agent working on tasks in scope                          │
│  - Focus locks held                                         │
│  - Write operations enabled                                 │
│  - lastActivity updated on operations                       │
└───────┬────────────────────────┬────────────────────────────┘
        │                        │
        │ suspend                │ end
        │ (reversible)           │ (reversible)
        ▼                        ▼
┌───────────────────┐    ┌────────────────────────────────────┐
│    SUSPENDED      │    │              ENDED                  │
│  - Paused work    │    │  - Full session notes required      │
│  - Focus released │    │  - Focus released                   │
│  - Resumable      │    │  - Resumable                        │
│  - Quick return   │    │  - Handoff notes for next agent     │
└───────┬───────────┘    └─────────────────┬──────────────────┘
        │                                  │
        │ resume                           │ resume
        │                                  │
        └──────────────┬───────────────────┘


               ┌───────────────┐
               │    ACTIVE     │
               │   (resumed)   │
               └───────────────┘

When ALL tasks completed:
┌─────────────────────────────────────────────────────────────┐
│                    COMPLETION PROMPT                         │
│  "All 5/5 tasks completed. Close session?"                  │
│  Options: [Close] [Add more tasks] [Review]                 │
└─────────────────────────────────────────────────────────────┘
                       │ close

┌─────────────────────────────────────────────────────────────┐
│                        CLOSED                                │
│  - All session notes aggregated to Epic                     │
│  - Session moved to history                                 │
│  - Epic marked complete                                     │
│  - NOT resumable                                            │
└─────────────────────────────────────────────────────────────┘

1.2 State Transitions

FromToCommandRequirements
(none)Activesession start --epic T001Epic exists, no active session for scope
ActiveSuspendedsession suspendFocus tasks updated with progress
ActiveEndedsession end --note "..."Session notes REQUIRED
SuspendedActivesession resume <id>Session exists, scope valid
EndedActivesession resume <id>Session exists, scope valid
Active/EndedClosedsession closeALL tasks in scope completed
Closed(none)N/ANOT reversible

1.3 State Definitions

ACTIVE
  • Agent is working on tasks within session scope
  • Focus locks can be acquired
  • Write operations (add, update, complete) are enabled
  • lastActivity timestamp updated on every operation
SUSPENDED
  • Work paused temporarily
  • Focus locks released (other agents can claim)
  • Session resumable with same context
  • Use case: “stepping away”, “waiting for review”
  • No session notes required (quick pause)
ENDED
  • Work session formally concluded
  • Session notes REQUIRED (handoff to next agent)
  • Focus locks released
  • Session resumable by same or different agent
  • Use case: “end of day”, “completed my portion”
CLOSED
  • Session permanently completed
  • All tasks in scope MUST be complete
  • Session notes aggregated to Epic/parent task
  • Epic automatically completed
  • Session archived to history
  • NOT resumable

Part 2: Session Binding

2.1 Binding Requirements

Every session MUST be bound to one of:
  • Epic (type: “epic”)
  • Main Task with Subtasks (type: “task” with children)
Sessions CANNOT be bound to:
  • Standalone tasks without children
  • Subtasks (they belong to parent’s session)

2.2 Session Start Flow

# Case 1: Explicit Epic
cleo session start --epic T001
 Creates session scoped to Epic T001 and all descendants

# Case 2: No Epic specified - Discovery Mode
cleo session start
 Shows available sessions:

┌─────────────────────────────────────────────────────────────┐
 Available Sessions
├──────────────────────────────────────────────────────────────
 1. [SUSPENDED] T001: Auth Implementation                    │
    Last: 2h ago by opus-1, 3/7 tasks done

 2. [ENDED] T015: API Refactor                              │
    Last: 1d ago by sonnet-3, 8/12 tasks done
    Note: "JWT validation remaining"

 3. [NEW] T023: Payment Integration (no session)            │
    0/5 tasks, priority: high
└─────────────────────────────────────────────────────────────┘
Select session [1-3] or 'q' to quit:

# Case 3: Epic already has active session
cleo session start --epic T001
 ERROR (E_SESSION_EXISTS):
  Epic T001 already has active session: session_20251228_...
  Agent: opus-1 | Started: 2h ago | Focus: T005

  To continue this session: cleo session resume session_20251228_...
  To view session details:  cleo session show session_20251228_...

2.3 Nested Session Hierarchy

When an Epic contains child Epics:
T001 (Epic: Auth System)
├── T002 (Task: Design)
├── T003 (Epic: OAuth Integration)  ← Can have sub-session
│   ├── T004 (Task: Google OAuth)
│   └── T005 (Task: GitHub OAuth)
└── T006 (Task: Testing)
  • T001 can have a session
  • T003 can have a NESTED session (child of T001’s session)
  • T003’s session is formally linked to T001’s session via parentSessionId
  • When T001’s session closes, all nested sessions MUST be closed first
{
  "sessionId": "session_20251228_child_abc",
  "parentSessionId": "session_20251228_parent_xyz",
  "scope": {
    "type": "epic",
    "rootTaskId": "T003"
  }
}

Part 3: Focus Locking

3.1 Focus Within Sessions

Focus is session-scoped, not global:
{
  "sessionId": "session_20251228_175354",
  "focus": {
    "currentTask": "T005",
    "lockedBy": "opus-1",
    "lockedAt": "2025-12-28T18:00:00Z"
  }
}

3.2 Focus Lock Rules

RuleBehavior
One agent per taskIf T005 focused by agent A, agent B cannot focus T005
Session-boundLock releases when session suspended/ended
Blocked task checkCannot focus task blocked by dependencies
Scope validationCannot focus task outside session scope

3.3 Focus Attempt Outcomes

# Success
cleo focus set T005
 [SESSION session_20251228_...] Focus set to T005: "Implement OAuth"

# Already focused by another agent
cleo focus set T005
 ERROR (E_TASK_CLAIMED):
  Task T005 is currently being worked by session session_20251228_other
  Agent: sonnet-3 | Since: 15m ago

  Available tasks in scope: T006, T007, T008

# Blocked by dependencies
cleo focus set T010
 ERROR (E_TASK_BLOCKED):
  Task T010 is blocked by incomplete dependencies:
  - T005: "Implement OAuth" (active, opus-1 working)
  - T006: "Write tests" (pending)

  Complete these tasks first, or focus an unblocked task.

# Outside session scope
cleo focus set T099
 ERROR (E_TASK_NOT_IN_SCOPE):
  Task T099 is not in session scope (Epic T001).
  Session scope contains: T001, T002, T003, T005, T006, T007

  To work on T099, start a new session for its Epic.

3.4 Parallel Focus (Multiple Agents)

Multiple agents can work on the same Epic session, each focusing different tasks:
Session: session_20251228_175354 (Epic: T001)
├── Agent opus-1:   Focus T005 (active)
├── Agent sonnet-3: Focus T006 (active)
└── Agent haiku-1:  Focus T007 (active)
Rules:
  • Each agent MUST have unique focus
  • No two agents can focus the same task
  • All agents share session context and notes

Part 4: Session Registry

4.1 Registry Structure

{
  "$schema": "../schemas/sessions.schema.json",
  "_meta": {
    "version": "2.0.0",
    "lastModified": "2025-12-28T17:53:54Z"
  },
  "sessions": [
    {
      "sessionId": "session_20251228_175354",
      "status": "active",
      "scope": {
        "type": "epic",
        "rootTaskId": "T001",
        "computedTaskIds": ["T001", "T002", "T003", "T005", "T006"]
      },
      "parentSessionId": null,
      "agents": [
        {
          "agentId": "opus-1",
          "focusTask": "T005",
          "joinedAt": "2025-12-28T17:53:54Z"
        }
      ],
      "notes": [
        {
          "timestamp": "2025-12-28T18:00:00Z",
          "agentId": "opus-1",
          "type": "progress",
          "content": "Started OAuth implementation"
        }
      ],
      "startedAt": "2025-12-28T17:53:54Z",
      "lastActivity": "2025-12-28T18:15:00Z"
    }
  ],
  "sessionHistory": []
}

4.2 Registry Commands

# List all sessions (minimal view)
cleo session list

┌────────────────────────────────────────────────────────────┐
 ID Epic Status Tasks
├──────────────────────────────┼────────┼───────────┼───────┤
 session_20251228_175354 T001 active 3/7
 session_20251227_120000 T015 ended 8/12
 session_20251225_090000 T008 suspended 2/4
└────────────────────────────────────────────────────────────┘

# Show session details
cleo session show session_20251228_175354

Session: session_20251228_175354
Epic: T001 - "Auth Implementation"
Status: active
Started: 2025-12-28 17:53:54 (2h ago)
Last Activity: 15m ago

Agents:
  opus-1: Focus T005 (15m)

Progress: 3/7 tasks completed (42%)
 T002: Design auth flow
 T003: Create models
 T004: Setup middleware
  🔄 T005: Implement OAuth (active - opus-1)
 T006: Write tests (blocked by T005)
 T007: Documentation
 T008: Integration tests

Session Notes:
  [opus-1 2h ago] Started OAuth implementation
  [opus-1 1h ago] Google OAuth complete, starting GitHub

Part 5: Write Operation Enforcement

5.1 Operations Requiring Session

OperationSession RequiredReason
addYESNew tasks MUST belong to session scope
updateYESTask modifications tracked to session
completeYESCompletion requires focus lock
focus setYESFocus is session-scoped
deleteYESDestructive ops need accountability
listNORead-only, but shows session context
showNORead-only, but shows session context
analyzeNORead-only analysis
phasesNORead-only

5.2 Enforcement Behavior

# No active session
cleo add "New task"
 ERROR (E_SESSION_REQUIRED):
  Write operations require an active session.

  To start a new session: cleo session start --epic <id>
  To resume a session:    cleo session resume <session-id>
  To list sessions:       cleo session list

# Session exists, task added to scope
cleo add "New task"
 [SESSION session_20251228_...] Created T099: "New task"
  Added to Epic T001 scope

5.3 Context-Aware Read Operations

Read operations show session context when available:
cleo show T005

[INFO] Active session: session_20251228_175354 (Epic: T001)
       Focus: T005 (you) | Other agents: sonnet-3 on T006

T005: Implement OAuth
Status: active
Priority: high
...

Part 6: Session Notes & Epic Completion

6.1 Note Types

TypeWhenRequired
progressDuring workEncouraged
blockerWhen blockedRequired if setting blocked status
handoffOn session endREQUIRED
completionOn session closeAuto-generated

6.2 Note Requirements

On Task Complete (within session):
  • Notes REQUIRED via --notes flag or interactive prompt
  • Notes attached to task’s notes array
On Session End:
  • Full session handoff notes REQUIRED
  • Command: cleo session end --note "Summary of work done"
  • Notes stored in session registry
On Session Close:
  • All session notes aggregated
  • Notes appended to Epic’s notes array
  • Session archived to history

6.3 Auto-Completion Flow

When all tasks in session scope are completed:
# Agent completes final task
cleo complete T008 --notes "Final integration tests passing"

 [SESSION session_20251228_...] Task T008 completed

  ┌────────────────────────────────────────────────────────┐
 ALL TASKS COMPLETED

 Epic T001: "Auth Implementation" (7/7 tasks done)      │

 Options:
 1. Close session (complete Epic, archive session)      │
 2. Add more tasks (extend scope)                       │
 3. Review tasks (inspect before closing)               │
  └────────────────────────────────────────────────────────┘

  Select [1-3]:

# If agent selects "Close session":
 Session notes attached to Epic T001
  Epic T001 marked complete
  Session archived to history

  [CLOSED] Session session_20251228_175354 completed successfully

6.4 Epic Notes Aggregation

On session close, Epic receives:
{
  "id": "T001",
  "status": "done",
  "notes": [
    {
      "timestamp": "2025-12-28T20:00:00Z",
      "type": "session_completion",
      "sessionId": "session_20251228_175354",
      "summary": "Auth implementation completed",
      "agentNotes": [
        {"agent": "opus-1", "note": "OAuth implementation complete"},
        {"agent": "sonnet-3", "note": "Tests passing at 95% coverage"}
      ],
      "tasksSummary": {
        "total": 7,
        "completed": 7,
        "agents": ["opus-1", "sonnet-3"]
      }
    }
  ]
}

Part 7: Error Codes

CodeNameExitDescription
30E_SESSION_EXISTS30Session already active for scope
31E_SESSION_NOT_FOUND31Session ID not found
32E_SCOPE_CONFLICT32Scope overlaps with another session
33E_SCOPE_INVALID33Invalid scope (no epic, empty, etc.)
34E_TASK_NOT_IN_SCOPE34Task not in session scope
35E_TASK_CLAIMED35Task focused by another agent
36E_SESSION_REQUIRED36Operation requires active session
37E_SESSION_CLOSE_BLOCKED37Cannot close, tasks incomplete
38E_FOCUS_REQUIRED38Operation requires focused task
39E_NOTES_REQUIRED39Session notes required for operation

Part 8: Command Reference

8.1 Session Commands

# Start new session (discovery mode)
cleo session start

# Start session for specific epic
cleo session start --epic T001

# Start with auto-focus (picks highest priority pending task)
cleo session start --epic T001 --auto-focus

# Suspend session (quick pause, no notes required)
cleo session suspend

# End session (formal end, notes required)
cleo session end --note "Completed OAuth, tests remaining"

# Resume suspended or ended session
cleo session resume <session-id>
cleo session resume --last --epic T001

# Close session (requires all tasks complete)
cleo session close

# List all sessions
cleo session list

# Show session details
cleo session show <session-id>

# Session status
cleo session status

8.2 Focus Commands (Session-Aware)

# Set focus (within current session)
cleo focus set T005

# Clear focus
cleo focus clear

# Show focus
cleo focus show

# Add progress note to focused task
cleo focus note "Completed Google OAuth"

# Set next action
cleo focus next "Start GitHub OAuth integration"

Part 9: Migration Path

Since this is the new DEFAULT behavior:

9.1 Existing Projects

For projects with existing .cleo/ directory:
  1. On first session start, migrate to new schema
  2. Create sessions.json with enhanced structure
  3. Existing _meta.activeSession migrated to full session entry
  4. Config updated with session.requireSession: true

9.2 Backward Compatibility

  • Read operations remain unchanged
  • Existing todo.json structure preserved
  • Session enforcement can be disabled via session.requireSession: false (NOT RECOMMENDED, only for legacy compatibility)

Part 10: Configuration

{
  "session": {
    "requireSession": true,
    "requireNotesOnEnd": true,
    "requireNotesOnComplete": true,
    "warnOnNoFocus": true,
    "allowNestedSessions": true,
    "allowParallelAgents": true,
    "sessionTimeoutHours": 72,
    "autoDiscoveryOnStart": true
  },
  "retention": {
    "autoEndActiveAfterDays": 7
  },
  "hierarchy": {
    "autoCompleteParent": false,
    "autoCompleteMode": "prompt"
  }
}
SettingDefaultDescription
requireSessiontrueWrite ops require session
requireNotesOnEndtrueNotes required on session end
requireNotesOnCompletetrueNotes required on task complete
warnOnNoFocustrueWarn if session started without focus
allowNestedSessionstrueChild epics can have sub-sessions
allowParallelAgentstrueMultiple agents in same session
sessionTimeoutHours72Hours before stale session warning (was 24h, now 72h)
autoDiscoveryOnStarttrueShow available sessions on session start
Retention Settings
SettingDefaultDescription
autoEndActiveAfterDays7Auto-end active sessions after N days of inactivity

10.1 Stale Session Handling

Sessions can legitimately run for extended periods (72+ hours) when agents work across multiple Claude conversations or during long-running development work. The stale session handling system balances this flexibility with automatic cleanup. Session Timeout Warning (72 hours) After sessionTimeoutHours (default: 72) of inactivity:
  • Session remains active but displays warning on status checks
  • Agent can continue working normally
  • No automatic state change occurs
  • Warning helps identify potentially abandoned sessions
cleo session status
 ⚠️ Session session_20251228_... has been inactive for 3d 5h
  Last activity: 2025-12-25T10:00:00Z
  Consider: session end --note "..." or session suspend
Stale Session Auto-End (7 days) After retention.autoEndActiveAfterDays (default: 7) of inactivity:
  • Active sessions are automatically transitioned to ended state
  • A system note is added documenting the auto-end
  • Focus locks are released
  • Session remains resumable (not closed)
  • Epic is NOT auto-completed
{
  "sessionId": "session_20251228_...",
  "status": "ended",
  "notes": [
    {
      "timestamp": "2026-01-04T10:00:00Z",
      "type": "system",
      "content": "Session auto-ended after 7 days of inactivity"
    }
  ]
}
Behavior Matrix
InactivityStatusWarningAuto-ActionResumable
< 72hActiveNoneNoneN/A
72h - 7dActiveYesNoneN/A
> 7dEndedN/AAuto-endYes
Why 72 hours (not 24)? Sessions often span multiple Claude conversations as agents:
  • Work on complex epics over multiple days
  • Wait for external dependencies (reviews, deployments)
  • Hand off between agent sessions
  • Resume after weekends or breaks
The 72-hour timeout provides flexibility for legitimate long-running work while still identifying potentially abandoned sessions. Configuration Examples
# Increase timeout for long-running projects
cleo config set session.sessionTimeoutHours 168  # 7 days warning

# Disable auto-end (not recommended)
cleo config set retention.autoEndActiveAfterDays 0

# More aggressive cleanup
cleo config set retention.autoEndActiveAfterDays 3

Part 11: Implementation Gaps (Current State)

11.1 What Exists

ComponentStatusLocationNotes
Library✅ Implementedlib/sessions.shFull multi-session functions
Schema✅ Completeschemas/sessions.schema.jsonReady for use
This Spec✅ DraftEPIC-SESSION (MDX) / docs/archive/specs-md/EPIC-SESSION-SPEC.md (archived)Vision document
Old Spec⚠️ Partialdocs/archive/specs-md/MULTI-SESSION-SPEC.md (archived)Predecessor, needs merge

11.2 What’s Missing

GapCurrent StateRequired Action
Config TemplateNo multiSession sectionAdd to templates/config.template.json
Init ScriptNo sessions.json creationUpdate scripts/init.sh
Default EnabledmultiSession.enabled: falseChange default to true
Session CommandsUse old single-session logicWire to lib/sessions.sh
Write EnforcementOperations don’t check sessionAdd guards to add/update/complete
Auto-CompleteImmediately completes EpicChange to prompt agent
Focus LockGlobal in todo.jsonMove to sessions.json per-session

11.3 Files Requiring Changes

Config Template (templates/config.template.json):
{
  "multiSession": {
    "enabled": true,
    "maxConcurrentSessions": 5,
    "maxActiveTasksPerScope": 1,
    "scopeValidation": "strict",
    "allowNestedScopes": true,
    "allowScopeOverlap": false
  },
  "session": {
    "requireSession": true,
    "requireNotesOnEnd": true,
    "requireNotesOnComplete": true,
    "warnOnNoFocus": true,
    "autoDiscoveryOnStart": true
  }
}
Init Script (scripts/init.sh):
  • Add init_sessions_file() call
  • Create .cleo/sessions.json with initial structure
  • Set multiSession.enabled: true in config
Session Script (scripts/session.sh):
  • Replace single-session logic with lib/sessions.sh calls
  • Implement discovery mode for session start
  • Add session close command (4th state)
  • Enhance error messages with context
Task Scripts (scripts/add.sh, scripts/update.sh, scripts/complete.sh):
  • Add session check at start
  • Error if no active session (E_SESSION_REQUIRED)
  • Log operations with session context
Complete Script (scripts/complete.sh):
  • Check if all tasks in scope complete
  • Prompt agent instead of auto-completing Epic
  • Trigger session close flow

11.4 Migration for Existing Projects

When user runs any cleo command on existing project:
  1. Detect: Check if .cleo/sessions.json exists
  2. Migrate: If not, check for _meta.activeSession in todo.json
  3. Create: Initialize sessions.json with migrated session (if any)
  4. Config: Add multiSession section to config.json if missing
  5. Warn: Inform user of migration on first use
# First command after upgrade
cleo session status
 [MIGRATION] Upgraded to Epic-Bound Sessions (v2.0)
  - Created .cleo/sessions.json
  - Migrated active session: session_20251228_175354
  - Updated config with multiSession settings

  Session system now requires Epic binding. See [EPIC-SESSION](./EPIC-SESSION)

Appendix A: Example Workflows

A.1 Solo Agent Workflow

# 1. Start session
cleo session start --epic T001 --auto-focus
 Session started, focus set to T005 (highest priority)

# 2. Work on task
cleo update T005 --notes "Starting OAuth"
# ... do work ...

# 3. Complete task
cleo complete T005 --notes "OAuth complete"
 Next highest priority: T006

# 4. Focus next
cleo focus set T006
# ... continue working ...

# 5. End session (end of day)
cleo session end --note "OAuth done, tests remaining"

A.2 Multi-Agent Workflow

# Agent 1 starts session
[opus-1]$ cleo session start --epic T001 --focus T005
 Session: session_abc

# Agent 2 joins same session
[sonnet-3]$ cleo session start --epic T001
 ERROR: Session exists for T001
  To join: cleo session resume session_abc

[sonnet-3]$ cleo session resume session_abc
 Joined session_abc, select task to focus

[sonnet-3]$ cleo focus set T006
 Focus set to T006 (T005 is with opus-1)

# Both agents work in parallel
[opus-1]$ cleo complete T005 --notes "Done"
[sonnet-3]$ cleo complete T006 --notes "Done"

# Final task
[opus-1]$ cleo focus set T007
[opus-1]$ cleo complete T007 --notes "All done"
 All tasks complete! Close session?

[opus-1]$ cleo session close
 Epic T001 completed, session archived

Appendix B: Informative Error Examples

All errors MUST be informative, not generic:
# BAD (generic)
ERROR: Cannot focus task

# GOOD (informative)
ERROR (E_TASK_CLAIMED):
Task T005 "Implement OAuth" is currently being worked.

Session: session_20251228_175354
Agent: sonnet-3
Since: 15 minutes ago
Progress: "Google OAuth complete, starting GitHub"

Available unblocked tasks in scope:
  T006: "Write unit tests" (pending, priority: medium)
  T007: "Update documentation" (pending, priority: low)

To focus an available task: cleo focus set <task-id>

Revision History

VersionDateAuthorChanges
1.0.02025-12-28Claude/UserInitial specification
1.1.02026-01-26Claude/UserSession timeout increased from 24h to 72h; added stale session handling (autoEndActiveAfterDays); added Part 10.1