Orchestrata Ultimate / Specs / 006-session-management

006-session-management: Session Management

Session Management provides comprehensive lifecycle management for orchestrator work sessions including session opening/closing with full audit trail, fact emission and persistence to dual storage (Redis + Neo4j), portfolio management across multiple projects, context persistence and recovery, carryover task tracking between sessions, and session handover with state preservation.

At a glance

Item Value
Spec directory specs/006-session-management/
Status line in the spec Complete
Requirement IDs defined 144
With a @traces citation in src/ 144 (100.0%)
With a @traces citation in tests/ 19 (13.2%)
Tracked files 11
RTM page 006-session-management

Reading this spec

Session Management governs the lifecycle of orchestrator work sessions. It tracks all work across sessions with full auditability, so that work continues after a crash or a planned shutdown, development patterns can be analysed historically, and portfolio-level insight spans multiple projects.

The scope is seven user stories: open session, close session and emit facts (priority 1), then session recovery, carryover tasks, portfolio management and context persistence (priority 2). The functional requirements are grouped as core session lifecycle, fact emission and storage, portfolio management, context and carryover, recovery and handover, local context file sync, and archive and integrity.

The central design decision is dual storage. Redis is the hot path, with sub-50ms session operations and active session state. Neo4j is the cold path, holding the full audit trail, historical queries and graph relationships. Prolog provides session governance, constraint checking and policy enforcement.

In the code, the largest tracers are orchestrata_ultimate/session/controller/_core, orchestrata_ultimate/session/redis_store, orchestrata_ultimate/session/fact_emitter, orchestrata_ultimate/session/prolog_interface and orchestrata_ultimate/session/context. The per-requirement view is on the RTM page.

The spec's status line reads Complete. It tracks 11 files and defines 144 requirement IDs, every one of them traced in the source. The full text follows below.

Measured coverage is 144 of 144 requirements cited by at least one @traces in src/ (100.0%), spread over 39 modules; the module citing the most of them is orchestrata_ultimate/session/controller/_core (53 requirements). In tests/, 19 requirements are cited by a test-side @traces.

Coverage gaps: none on the citation measure, every requirement has at least one citing src/ symbol. Test-side citations are thinner than code-side ones (19 against 144).

Requirements

Checkbox is the state recorded in the requirements checklist; Traced by is the count of src/ symbols whose @traces names the ID.

ID Done Requirement Traced by
REQ-006-US-001-001 yes User can create a new session with a unique session ID 2
REQ-006-US-001-002 yes System generates session ID automatically if not provided 3
REQ-006-US-001-003 yes Session creation includes timestamp and initial state 4
REQ-006-US-001-004 yes Session is registered in the Prolog fact database 2
REQ-006-US-001-005 yes Session creation completes in < 50ms 2
REQ-006-US-001-006 yes Verification: session_exists(SessionID) returns true 2
REQ-006-US-002-001 yes User can explicitly close a session 9
REQ-006-US-002-002 yes System removes session from active sessions list 4
REQ-006-US-002-003 yes Session facts are retracted from Prolog database 7
REQ-006-US-002-004 yes Session cleanup completes successfully 5
REQ-006-US-002-005 yes Session resources are released 4
REQ-006-US-002-006 yes Verification: session_exists(SessionID) returns false after closure 3
REQ-006-US-002-007 no [DRAFT — derived-from-code, UNRATIFIED]: When ending a session, the system auto-detects git-modified files and logs them as session artifacts 3
REQ-006-US-002-008 no [DRAFT — derived-from-code, UNRATIFIED]: When ending a session, the system auto-detects commits made since session start and logs them as work-log entries 2
REQ-006-US-002-009 no [DRAFT — derived-from-code, UNRATIFIED]: When ending a session, the system runs test collection and records the collected test count on session state 2
REQ-006-US-002-010 no [DRAFT — derived-from-code, UNRATIFIED]: When ending a session, the user can interactively commit (and optionally push) pending git changes 1
REQ-006-US-003-001 yes User can query current session state 8
REQ-006-US-003-002 yes System returns all facts associated with session 7
REQ-006-US-003-003 yes Query includes session metadata (ID, timestamp, status) 4
REQ-006-US-003-004 yes Query execution completes in < 10ms 3
REQ-006-US-003-005 yes Results are formatted correctly (JSON/Prolog terms) 8
REQ-006-US-003-006 yes Verification: Query returns expected session data 3
REQ-006-US-004-001 yes User can emit facts to current session 6
REQ-006-US-004-002 yes Facts are immediately available in Prolog database 5
REQ-006-US-004-003 yes Fact emission includes source attribution 3
REQ-006-US-004-004 yes Fact emission completes in < 10ms 3
REQ-006-US-004-005 yes Multiple facts can be emitted in single operation 7
REQ-006-US-004-006 yes Verification: Emitted facts can be queried immediately 3
REQ-006-US-005-001 yes System maintains session-specific context 8
REQ-006-US-005-002 yes Context includes conversation history 2
REQ-006-US-005-003 yes Context includes emitted facts 2
REQ-006-US-005-004 yes Context is isolated per session 3
REQ-006-US-005-005 yes Context persists throughout session lifetime 3
REQ-006-US-005-006 yes Verification: Context queries return session-specific data only 4
REQ-006-US-006-001 yes System triggers on_session_start hook 15
REQ-006-US-006-002 yes System triggers on_session_end hook 4
REQ-006-US-006-003 yes Hooks can execute custom logic 2
REQ-006-US-006-004 yes Hook execution does not block session operations 1
REQ-006-US-006-005 yes Hook failures are logged but do not crash system 2
REQ-006-US-006-006 yes Verification: Hooks are called with correct parameters 3
REQ-006-US-007-001 yes System supports multiple concurrent sessions 2
REQ-006-US-007-002 yes Each session has isolated state 3
REQ-006-US-007-003 yes Sessions do not interfere with each other 3
REQ-006-US-007-004 yes Session switching is supported 4
REQ-006-US-007-005 yes Session list can be queried 6
REQ-006-US-007-006 yes Verification: Multiple sessions can be active simultaneously 3
REQ-006-FR1-001 yes System generates unique session IDs 2
REQ-006-FR1-002 yes Session IDs follow format: session_YYYYMMDD_HHMMSS_UUID (constants.py:generate_session_id()) 2
REQ-006-FR1-003 yes Session IDs are collision-resistant 2
REQ-006-FR1-004 yes Session IDs are human-readable 2
REQ-006-FR1-005 yes Verification: Generated IDs are unique across 1000+ sessions 2
REQ-006-FR2-001 yes Session state is stored in Prolog fact database 2
REQ-006-FR2-002 yes State includes: session ID, timestamp, status, metadata 2
REQ-006-FR2-003 yes State is queryable via Prolog interface 2
REQ-006-FR2-004 yes State updates are atomic 2
REQ-006-FR2-005 yes Verification: State persists across multiple queries 3
REQ-006-FR3-001 yes Facts are tagged with session ID 9
REQ-006-FR3-002 yes Facts include timestamp of emission 6
REQ-006-FR3-003 yes Facts include source attribution 4
REQ-006-FR3-004 yes Facts are queryable by session ID 5
REQ-006-FR3-005 yes Verification: Facts are correctly associated with sessions 4
REQ-006-FR4-001 yes Each session has separate fact namespace 3
REQ-006-FR4-002 yes Queries are scoped to current session by default 3
REQ-006-FR4-003 yes Cross-session queries are explicitly supported 4
REQ-006-FR4-004 yes Session isolation prevents fact leakage 3
REQ-006-FR4-005 yes Verification: Session A cannot access Session B facts without explicit permission 4
REQ-006-FR5-001 yes Closed sessions retract all associated facts 6
REQ-006-FR5-002 yes Session resources are released on closure 5
REQ-006-FR5-003 yes Cleanup is atomic (all-or-nothing) 3
REQ-006-FR5-004 yes Failed cleanup attempts are logged 3
REQ-006-FR5-005 yes Verification: No memory leaks after 1000+ session cycles 3
REQ-006-FR6-001 yes Invalid session IDs return clear error messages 5
REQ-006-FR6-002 yes Operations on closed sessions fail gracefully 5
REQ-006-FR6-003 yes Prolog errors are caught and logged 3
REQ-006-FR6-004 yes System remains stable after errors 3
REQ-006-FR6-005 yes Verification: System continues operating after error conditions 2
REQ-006-FR7-001 yes Session creation: < 50ms 3
REQ-006-FR7-002 yes Fact emission: < 10ms 2
REQ-006-FR7-003 yes Session query: < 10ms (Redis LRANGE + filter, validated in benchmarks) 3
REQ-006-FR7-004 yes Session closure: < 50ms (pipeline cleanup, validated in benchmarks) 3
REQ-006-FR7-005 yes Concurrent operations: 100+ sessions without degradation 2
REQ-006-FR7-006 yes Verification: Performance benchmarks pass 3
REQ-006-FR8-001 yes Python API: emit_fact(session_id, fact_term) 7
REQ-006-FR8-002 yes Supports Prolog term strings 3
REQ-006-FR8-003 yes Supports structured fact dictionaries 7
REQ-006-FR8-004 yes Returns success/failure status 2
REQ-006-FR8-005 yes Verification: API calls succeed with valid inputs 1
REQ-006-FR9-001 yes Python API: query_session(session_id, query_term) 5
REQ-006-FR9-002 yes Returns list of matching facts 5
REQ-006-FR9-003 yes Supports complex Prolog queries 6
REQ-006-FR9-004 yes Returns empty list for no matches 3
REQ-006-FR9-005 yes Verification: Queries return correct results 4
REQ-006-FR10-001 yes Python API: open_session(session_id=None) 3
REQ-006-FR10-002 yes Python API: close_session(session_id) 4
REQ-006-FR10-003 yes Python API: get_session_info(session_id) 4
REQ-006-FR10-004 yes Returns session metadata 7
REQ-006-FR10-005 yes Verification: APIs work as documented 3
REQ-006-FR11-001 yes Hooks are registered via Python API 5
REQ-006-FR11-002 yes Hook signature: hook_function(session_id, **kwargs) (SessionHook protocol in hook_registry.py) 3
REQ-006-FR11-003 yes Hooks execute synchronously during lifecycle events 2
REQ-006-FR11-004 yes Hook failures are logged 2
REQ-006-FR11-005 yes Verification: Hooks execute with correct parameters 3
REQ-006-FR12-001 yes All session operations are logged 5
REQ-006-FR12-002 yes Logs include: session ID, operation, timestamp, result 2
REQ-006-FR12-003 yes Performance metrics are captured 7
REQ-006-FR12-004 yes Errors are logged with stack traces 2
REQ-006-FR12-005 yes Verification: Logs are complete and accurate 5
REQ-006-FR13-001 yes Session management exposed via MCP protocol 1
REQ-006-FR13-002 yes MCP tools can manage sessions (create, get, close) 3
REQ-006-FR13-003 yes MCP clients can query session state and facts 3
REQ-006-FR13-004 yes MCP tool schemas follow standard format 1
REQ-006-FR13-005 yes MCP integration verified with comprehensive tests 1
REQ-006-FR14-001 yes context.json is machine-readable source of truth 7
REQ-006-FR14-002 yes context.md rendered from context.json via Jinja2 3
REQ-006-FR14-003 yes Atomic writes — both files updated or neither 2
REQ-006-FR14-004 yes context.history.md is canonical archive filename 2
REQ-006-FR14-005 yes Auto-archive when session count exceeds SESSION_LIMIT 3
REQ-006-FR14-006 yes Schema defined by ContextData Pydantic model 6
REQ-006-FR14-007 yes Sync integrity — gapless ascending session numbers 8
REQ-006-FR15-001 yes Auto-archive on session close 3
REQ-006-FR15-002 yes Append-only to context.history.md 2
REQ-006-FR15-003 yes Idempotent archive operation 3
REQ-006-FR16-001 yes Gap detection in session numbering 2
REQ-006-FR16-002 yes Duplicate detection across files 2
REQ-006-FR16-003 yes Sync validation (context.md matches context.json render) 3
REQ-006-FR16-004 yes History continuity (no overlapping ranges) 4
REQ-006-FR17-001 yes Scan git history for lost sessions 2
REQ-006-FR17-002 yes Extract session data from historical commits 2
REQ-006-FR17-003 yes Append with [RECOVERED] annotation 2
REQ-006-FR17-004 yes Non-destructive (never overwrites) 4
REQ-006-FR18-001 yes archive command triggers archive 2
REQ-006-FR18-002 yes archive --verify runs integrity check 3
REQ-006-FR18-003 yes archive --recover runs git recovery 3
REQ-006-FR18-004 yes archive --stats shows statistics 5
REQ-006-FR18-005 yes status command shows current state 18
REQ-006-FR18-006 yes list command shows all sessions 8
REQ-006-FR18-007 no [DRAFT — derived-from-code, UNRATIFIED]: overview command runs a one-shot startup digest reporting infra health, session state, last test verdict, rulings staleness, git status, and project status in seven independently-isolated sections, always exiting 0 with per-section error reporting rather than aborting on subsystem failure 1
REQ-006-FR19-001 no task add adds a deferred/carryover work item (text + optional priority) to the active session 1
REQ-006-FR19-002 no task done &lt;index> marks a carryover task done by index, persisting completion to context.json 2
REQ-006-FR19-003 no task list lists all carryover tasks with index, state, and priority 1
REQ-006-FR19-004 no task status shows aggregate carryover-task statistics by state 1
REQ-006-NFR9-001 yes Archive completes in < 500ms 2
REQ-006-NFR9-002 yes Verification completes in < 1s 1
REQ-006-NFR9-003 yes Git scan max 200 commits 2

Code that traces this spec

Module Symbols Requirements
orchestrata_ultimate/context/providers/mission_context 1 2
orchestrata_ultimate/core/protocols/decoupling 1 1
orchestrata_ultimate/governance/prolog_gate 1 1
orchestrata_ultimate/kernel/session_manager 2 1
orchestrata_ultimate/orchestrator/fact_graph 2 2
orchestrata_ultimate/orchestrator/fact_manager 6 9
orchestrata_ultimate/orchestrator/fact_store 2 3
orchestrata_ultimate/session/archive 6 9
orchestrata_ultimate/session/carryover 1 1
orchestrata_ultimate/session/checkpoint 1 1
orchestrata_ultimate/session/cli/achievements 3 2
orchestrata_ultimate/session/cli/archive 3 6
orchestrata_ultimate/session/cli/kg 2 1
orchestrata_ultimate/session/cli/lifecycle 29 10
orchestrata_ultimate/session/cli/main 2 7
orchestrata_ultimate/session/cli/overview 1 1
orchestrata_ultimate/session/cli/tasks 5 4
orchestrata_ultimate/session/constants 1 6
orchestrata_ultimate/session/context 27 21
orchestrata_ultimate/session/controller/_core 19 53
orchestrata_ultimate/session/exceptions 3 8
orchestrata_ultimate/session/fact_emitter 11 27
orchestrata_ultimate/session/facts 10 5
orchestrata_ultimate/session/graph_store 6 7
orchestrata_ultimate/session/handover 6 4
orchestrata_ultimate/session/hook_registry 8 12
orchestrata_ultimate/session/hooks/session_auto_start_hook 13 1
orchestrata_ultimate/session/hooks/session_pre_close_hook 4 6
orchestrata_ultimate/session/interfaces 11 14
orchestrata_ultimate/session/kg_context 2 2
orchestrata_ultimate/session/mcp_tools 9 13
orchestrata_ultimate/session/models 7 10
orchestrata_ultimate/session/portfolio 2 8
orchestrata_ultimate/session/prolog_facts 7 10
orchestrata_ultimate/session/prolog_interface 13 21
orchestrata_ultimate/session/recovery 1 2
orchestrata_ultimate/session/redis_store 23 42
orchestrata_ultimate/session/sync 5 3
orchestrata_ultimate/session/types 10 14

Checklists

checklists/constitutional.md

Constitutional Checklist - Session Management

Document: plans/prolog-orchestrator-design.md (Constitutional AI Principles) Date: 2026-01-13 Status: Implementation Phase


Article IX: Session Management (PRIMARY FOCUS)
Section 1: Session Lifecycle
Section 2: Fact Emission
Section 3: Session Isolation
Section 4: Hook System

Article I: Prolog as Constitutional Foundation
Prolog Integration
Fact Representation

Article II: Transparency and Auditability
Operation Logging
State Visibility

Article III: Modularity and Composability
Module Boundaries
API Design

Article IV: Graceful Error Handling
Error Recovery
Error Messages

Article V: Performance Under Constraint
Performance Targets
Resource Management

Article VI: Incremental Development
Implementation Strategy
Testing at Each Stage

Article VII: Human-Readable Outputs
Query Results
Logging Format

Article VIII: Integration with Orchestrator
Tool Integration
MCP Integration

Article X: Testing as Constitutional Requirement
Test Coverage
Test Quality

Article XI: Documentation as Code
Code Documentation
System Documentation

Completion Criteria

Constitutional compliance is complete when:


Notes

checklists/requirements.md

The requirement list above comes from this file; 135 of 144 checkbox items are ticked.

checklists/testing.md

Testing Checklist - Session Management

Document: specs/006-session-management/testing.md Date: 2026-01-13 Status: Implementation Phase


Performance Benchmarks
Session Open Performance (< 50ms)

Test Implementation:

def test_session_open_performance():
    start = time.perf_counter()
    session_id = session_manager.open_session()
    duration = (time.perf_counter() - start) * 1000
    assert duration < 50, f"Session open took {duration}ms (target: 50ms)"
Fact Emission Performance (< 10ms)

Test Implementation:

def test_fact_emission_performance():
    session_id = session_manager.open_session()
    start = time.perf_counter()
    session_manager.emit_fact(session_id, "test_fact(value)")
    duration = (time.perf_counter() - start) * 1000
    assert duration < 10, f"Fact emission took {duration}ms (target: 10ms)"
Session Query Performance (< 10ms)
Session Close Performance (< 50ms)

Unit Tests
Session Lifecycle Tests
Fact Emission Tests
Session Query Tests
Session Isolation Tests
Error Handling Tests

Integration Tests
Prolog Interface Integration
Hook System Integration
Multi-Session Integration
Tool Integration

Stress Tests
Load Testing
Memory Testing
Concurrency Testing

Edge Case Tests
Boundary Conditions
Error Conditions
Recovery Testing

Test Infrastructure
Test Fixtures
Test Utilities
Test Data

Continuous Testing
Pre-Commit Tests
CI/CD Tests
Regression Tests

Test Metrics
Coverage Metrics
Performance Metrics
Quality Metrics

Completion Criteria

Testing is complete when:


Notes

Other tracked files

Full spec text

Verbatim from specs/006-session-management/spec.md; headings are pushed down two levels.

SPEC-006: Session Management

Metadata


Overview

What

Session Management provides comprehensive lifecycle management for orchestrator work sessions including session opening/closing with full audit trail, fact emission and persistence to dual storage (Redis + Neo4j), portfolio management across multiple projects, context persistence and recovery, carryover task tracking between sessions, and session handover with state preservation.

Why

Track all work across sessions with full auditability, enabling:

How

Dual-storage architecture:


User Scenarios & Stories

US-001: Open Session (P1)

As a developer I want to open a new work session with clear goals and context So that my work is tracked and I can resume if interrupted

Acceptance Criteria:

Example:

session = await session_manager.open_session(
    portfolio="orchestrator-ai",
    goals=["Implement session management", "Add fact emission"],
    context={"branch": "master", "cwd": "/workspace/orchestrator-ai"}
)
# Returns: Session(id="sess_20260113_143022_a1b2c3", status="open", ...)

US-002: Close Session (P1)

As a developer I want to close a session with summary of work completed So that session state is preserved and work is documented

Acceptance Criteria:

Example:

await session_manager.close_session(
    session_id="sess_20260113_143022_a1b2c3",
    status=SessionStatus.COMPLETED,
    summary="Implemented session management with fact emission",
    carryover_tasks=["Add Prolog integration tests"]
)

US-003: Emit Facts (P1)

As a session manager I want to emit structured facts about session events So that Prolog can reason about session state and enforce governance

Acceptance Criteria:

Example:

await fact_emitter.emit(
    fact_type="task_started",
    session_id="sess_20260113_143022_a1b2c3",
    task_id="task_001",
    description="Implement fact emission",
    timestamp=datetime.now()
)

US-004: Session Recovery (P2)

As a developer I want to recover from a crashed session So that I can resume work without losing context

Acceptance Criteria:

Example:

recovered = await session_manager.recover_last_session()
# Returns: Session with context={"crash_detected": True, "previous_session": "sess_..."}

US-005: Carryover Tasks (P2)

As a developer I want to track incomplete tasks across sessions So that nothing is forgotten between work periods

Acceptance Criteria:

Example:

carryover = await session_manager.get_carryover_tasks(
    portfolio="orchestrator-ai",
    status="pending"
)
# Returns: [Task(id="task_042", description="Add Prolog tests", priority="P2")]

US-006: Portfolio Management (P2)

As a developer working on multiple projects I want to track sessions across different portfolios So that I can see work distribution and switch contexts effectively

Acceptance Criteria:

Example:

stats = await portfolio_manager.get_stats("orchestrator-ai")
# Returns: PortfolioStats(sessions=47, total_duration_hours=12.3, completion_rate=0.87)

US-007: Context Persistence (P2)

As a developer I want to store arbitrary context with sessions So that session-specific state is preserved

Acceptance Criteria:

Example:

await session_manager.update_context(
    session_id="sess_20260113_143022_a1b2c3",
    key="git_branch",
    value="feature/session-management"
)

Functional Requirements

Core Session Lifecycle

FR-001: Session Opening (P1)

FR-002: Session Closing (P1)

FR-003: Active Session Tracking (P1)

Fact Emission & Storage

FR-004: Fact Emission (P1)

FR-005: Fact Storage (P1)

FR-006: Prolog Integration (P1)

Portfolio Management

FR-007: Portfolio Registration (P2)

FR-008: Portfolio Statistics (P2)

Context & Carryover

FR-009: Context Management (P2)

FR-010: Carryover Task Management (P2)

Recovery & Handover

FR-011: Session Recovery (P2)

FR-012: Session Handover (P3)

Local Context File Sync

FR-013: Local Context File Sync (P1)

Archive, Integrity & Recovery

FR-014: Automated Session Archive (P1)

FR-015: Context Integrity Verification (P1)

FR-016: Git-Based Session Recovery (P2)

FR-017: Session CLI Interface (P2)


Non-Functional Requirements

Performance

NFR-001: Response Time

NFR-002: Throughput

NFR-003: Scalability

Reliability

NFR-004: Data Durability

NFR-005: Availability

NFR-006: Fault Tolerance

Security

NFR-007: Authentication

NFR-008: Authorization


Technical Design

Architecture
┌─────────────────────────────────────────────────────────────┐
│                    Orchestrator AI                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────┐         ┌─────────────────┐          │
│  │  Session        │────────▶│  Fact Emitter   │          │
│  │  Manager        │         │                 │          │
│  └─────────────────┘         └─────────────────┘          │
│         │                             │                    │
│         │                             ▼                    │
│         │                    ┌─────────────────┐          │
│         ├───────────────────▶│     Redis       │          │
│         │                    │   (Hot Path)    │          │
│         │                    └─────────────────┘          │
│         │                             │                    │
│         │                             │ Async Batch Write  │
│         │                             ▼                    │
│         │                    ┌─────────────────┐          │
│         └───────────────────▶│    Neo4j        │          │
│                              │  (Cold Path)    │          │
│                              └─────────────────┘          │
│                                       │                    │
│                                       ▼                    │
│                              ┌─────────────────┐          │
│                              │     Prolog      │          │
│                              │  (Governance)   │          │
│                              └─────────────────┘          │
└─────────────────────────────────────────────────────────────┘
Data Models

Session Model:

class Session:
    id: str                      # sess_YYYYMMDD_HHMMSS_uuid
    portfolio_id: str
    status: SessionStatus        # open, closed, crashed
    goals: List[str]
    context: Dict[str, Any]
    opened_at: datetime
    closed_at: Optional[datetime]
    duration_seconds: Optional[int]
    completion_status: Optional[CompletionStatus]
    summary: Optional[str]
    carryover_tasks: List[str]

Fact Model:

class Fact:
    id: str                      # fact_uuid
    type: str                    # session_opened, task_started, etc.
    session_id: str
    timestamp: datetime
    data: Dict[str, Any]
    emitted_to_redis: bool
    persisted_to_neo4j: bool

Portfolio Model:

class Portfolio:
    id: str                      # portfolio_uuid
    name: str
    path: str
    description: str
    created_at: datetime
    total_sessions: int
    total_duration_seconds: int
Redis Schema

Keys:

Indexes:

Neo4j Schema

Nodes:

Relationships:

Indexes:

CREATE INDEX session_id_idx FOR (s:Session) ON (s.id)
CREATE INDEX fact_session_idx FOR (f:Fact) ON (f.session_id)
CREATE INDEX portfolio_name_idx FOR (p:Portfolio) ON (p.name)
Prolog Integration

Fact Format:

session_opened('sess_20260113_143022_a1b2c3', 'orchestrator-ai', '2026-01-13T14:30:22Z').
task_started('sess_20260113_143022_a1b2c3', 'task_001', 'Implement fact emission').
context_updated('sess_20260113_143022_a1b2c3', 'git_branch', 'master').
session_closed('sess_20260113_143022_a1b2c3', 'completed', 3600).

Governance Rules:

% Only one active session per portfolio
:- session_opened(S1, Portfolio, _), session_opened(S2, Portfolio, _), 
   S1 \= S2, status(S1, open), status(S2, open).

% Session must have goals
:- session_opened(SessionID, _, _), \+ goals(SessionID, _).

% Carryover tasks must be from closed sessions
:- carryover_task(TaskID, FromSession, _, _), status(FromSession, open).

API Specification

SessionManager
class SessionManager:
    async def open_session(
        self,
        portfolio: str,
        goals: List[str],
        context: Optional[Dict[str, Any]] = None
    ) -> Session:
        """Open a new session with specified goals and context."""
        
    async def close_session(
        self,
        session_id: str,
        status: CompletionStatus,
        summary: str,
        carryover_tasks: Optional[List[str]] = None
    ) -> Session:
        """Close an existing session with completion status."""
        
    async def get_session(self, session_id: str) -> Optional[Session]:
        """Retrieve session by ID from Redis or Neo4j."""
        
    async def get_active_session(self, portfolio: str) -> Optional[Session]:
        """Get currently active session for portfolio."""
        
    async def recover_last_session(self) -> Optional[Session]:
        """Recover last active session after crash."""
        
    async def update_context(
        self,
        session_id: str,
        key: str,
        value: Any
    ) -> None:
        """Update session context and emit fact."""
FactEmitter
class FactEmitter:
    async def emit(
        self,
        fact_type: str,
        session_id: str,
        **kwargs
    ) -> str:
        """Emit a fact to Redis and queue for Neo4j."""
        
    async def get_facts(
        self,
        session_id: str,
        fact_type: Optional[str] = None
    ) -> List[Fact]:
        """Retrieve facts for session from Redis."""
        
    async def flush_to_neo4j(self) -> int:
        """Flush queued facts to Neo4j, return count."""
PortfolioManager
class PortfolioManager:
    async def register_portfolio(
        self,
        name: str,
        path: str,
        description: str = ""
    ) -> Portfolio:
        """Register a new portfolio."""
        
    async def get_portfolio(self, portfolio_id: str) -> Optional[Portfolio]:
        """Retrieve portfolio by ID."""
        
    async def get_stats(self, portfolio_id: str) -> PortfolioStats:
        """Get portfolio-level statistics."""
        
    async def list_sessions(
        self,
        portfolio_id: str,
        limit: int = 50
    ) -> List[Session]:
        """List sessions for portfolio."""

Success Criteria

Primary Success Metrics

Performance:

Reliability:

Functionality:

Acceptance Tests

Test 1: Session Open/Close Cycle

session = await session_manager.open_session(
    portfolio="test-portfolio",
    goals=["Test session lifecycle"]
)
assert session.status == SessionStatus.OPEN
assert session.portfolio_id == "test-portfolio"

await session_manager.close_session(
    session_id=session.id,
    status=CompletionStatus.COMPLETED,
    summary="Test completed successfully"
)
closed = await session_manager.get_session(session.id)
assert closed.status == SessionStatus.CLOSED
assert closed.duration_seconds > 0

Test 2: Fact Emission & Retrieval

fact_id = await fact_emitter.emit(
    fact_type="task_started",
    session_id=session.id,
    task_id="task_001",
    description="Test task"
)
assert fact_id.startswith("fact_")

facts = await fact_emitter.get_facts(session.id, fact_type="task_started")
assert len(facts) == 1
assert facts[0].data["task_id"] == "task_001"

Test 3: Session Recovery

# Simulate crash by not closing session properly
session = await session_manager.open_session(
    portfolio="test-portfolio",
    goals=["Test recovery"]
)
original_id = session.id

# Simulate crash and recovery
recovered = await session_manager.recover_last_session()
assert recovered is not None
assert recovered.context["previous_session"] == original_id

Integration Points

Component Integration
orchestrata-kernel Session state queries
orchestrata-governance Prolog fact validation
orchestrata-cxp Session-scoped message routing
orchestrata-knowledge Neo4j persistence

Dependencies

External Systems

Redis (Required)

Neo4j (Required)

Prolog (Optional)


Open Questions & Decisions

Q1: Session Timeout Configuration

Decision: Use 24 hours as default, allow per-portfolio configuration

Q2: Neo4j Batch Size

Decision: Start with 100, benchmark and adjust based on production load

Q3: Prolog Governance Strictness

Decision: Configurable per rule, default to warnings for non-critical rules

Q4: Redis vs Neo4j for Queries

Decision:

Q5: Session Recovery Strategy

Decision: Create new session with link to crashed session, preserving audit trail


References

Implementation Files

Revision History

Date Version Author Changes
2026-01-13 1.0 Mohamed Initial specification
2026-03-07 1.1 Mohamed Standardized format, added numbered requirements