Metadata-Version: 2.4
Name: holodeck-session-manager
Version: 0.1.0
Summary: Session lifecycle management with checkpoint tiling and H¹-guided routing
Author-email: Cocapn <cocapn@proton.me>
License: Apache-2.0
Project-URL: Homepage, https://github.com/SuperInstance/holodeck-session-manager
Project-URL: Documentation, https://github.com/SuperInstance/holodeck-session-manager#readme
Project-URL: Repository, https://github.com/SuperInstance/holodeck-session-manager
Keywords: session,lifecycle,holodeck,checkpoint,tiling,h1,routing
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# Holodeck Session Manager

> **Session lifecycle with checkpoint tiling, emergence detection, and H¹-guided routing.**

A standalone Python library for managing agent sessions with full lifecycle tracking, structured checkpoint tiles for PLATO, and constraint-theory-driven task routing.

[![PyPI Version](https://img.shields.io/pypi/v/holodeck-session-manager.svg)](https://pypi.org/project/holodeck-session-manager/)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)

---

## What Is A Session?

A **session** is a focused unit of work by an agent. It has:
- **Start**: When the agent begins working
- **Tasks**: Individual work items within the session
- **End**: When the agent finishes (success, failure, or timeout)

Sessions are the primary unit of **observation** for the scout/mid/architect framework.

---

## Quick Start

### Install

```bash
pip install holodeck-session-manager
```

### Create a Session

```python
from holodeck_session_manager import SessionManager, SessionConfig

config = SessionConfig(
    session_name="my-research-session",
    agent_id="oracle1",
    tags=["research", "constraint-theory"]
)

manager = SessionManager(config)

# Start session
session = manager.start_session()

# Add tasks
task1 = session.add_task("analyze-h1-data", {"query": "what is H¹ emergence?"})
task2 = session.add_task("write-report", {"topic": "constraint theory findings"})

# Complete a task
task1.complete(success=True, duration_ms=2340)

# End session
session.end_session(outcome="success")
```

### Full Example with PLATO Tiling

```python
#!/usr/bin/env python3
"""
Holodeck session with PLATO checkpoint tiling.
Every session event emits a tile to the scout room.
"""
from holodeck_session_manager import (
    SessionManager, SessionConfig, TaskOutcome, SessionOutcome
)
from holodeck_session_manager.plato_integration import PlatoTileEmitter

config = SessionConfig(
    session_name="constraint-theory-research",
    agent_id="oracle1",
    tags=["research", "constraint-theory", "h1"],
    # PLATO integration
    plato_url="http://localhost:8848",
    scout_room="gc/research/scout-reports/holodeck-session",
    # H1 routing integration
    h1_router_enabled=True,
    h1_router_url="http://localhost:8902"
)

manager = SessionManager(config)
emitter = PlatoTileEmitter(config.plato_url, config.scout_room)

# Start session — emit SESSION_START tile
session = manager.start_session()
emitter.emit_session_start(session)

try:
    # Route tasks through H1 router
    for task_spec in [
        ("analyze-fleet-h1", ["research", "plato"]),
        ("compute-cohomology", ["compilation", "constraint-theory"]),
        ("write-findings", ["publishing"]),
    ]:
        task_id, caps = task_spec
        
        # H1-aware task routing
        decision = manager.route_task_h1(task_id, caps)
        
        # Emit task start tile
        emitter.emit_task_start(session.session_id, task_id, decision)
        
        # Do the work (simulated)
        import time
        time.sleep(0.1)
        
        # Complete task
        outcome = TaskOutcome.SUCCESS if task_id != "compute-cohomology" else TaskOutcome.FAILED
        session.complete_task(task_id, outcome, duration_ms=234)
        
        emitter.emit_task_end(session.session_id, task_id, outcome.value)
    
    # End session successfully
    session.end_session(SessionOutcome.SUCCESS)
    emitter.emit_session_end(session, SessionOutcome.SUCCESS)
    
except Exception as e:
    session.end_session(SessionOutcome.FAILED, error=str(e))
    emitter.emit_session_error(session.session_id, str(e))
```

---

## Architecture

### Session Lifecycle

```
┌─────────────────────────────────────────────────────────────────┐
│                      SESSION LIFECYCLE                           │
│                                                                  │
│   ┌──────────┐    ┌─────────────┐    ┌────────────────────────┐ │
│   │  START   │───▶│    TASKS    │───▶│        END            │ │
│   │          │    │             │    │                        │ │
│   │ emit:    │    │ per task:   │    │ emit:                 │ │
│   │ - room   │    │ - start     │    │ - outcome             │ │
│   │ - agents │    │ - route     │    │ - H¹ delta            │ │
│   │ - model  │    │ - complete   │    │ - pattern analysis    │ │
│   │ - tags   │    │ - errors     │    │                       │ │
│   └──────────┘    └─────────────┘    └────────────────────────┘ │
│                                                                  │
│   PLATO Tiles emitted at every checkpoint                        │
└─────────────────────────────────────────────────────────────────┘
```

### Integration with Scout/Mid/Architect

```
Session Manager
    │
    ├── Emits tiles ──────▶ PLATO Room (scout-reports/holodeck-session)
    │                         │
    │                         ▼
    │                    Mid Synthesis (oracle1-mid)
    │                         │
    │                         ▼
    │                    Architect Inference
    │                         │
    │                         ▼
    │                    H1 Router ──▶ Routing Decisions
    │
    └── H1 Router ──▶ Task routing with constraint awareness
```

---

## Session Configuration

```python
from holodeck_session_manager import SessionConfig

config = SessionConfig(
    # Identity
    session_name="my-session",          # Human-readable name
    agent_id="oracle1",                  # Which agent
    tags=["research", "example"],       # For discovery
    
    # Lifecycle
    max_tasks=50,                        # Hard limit on tasks
    task_timeout_seconds=300,           # Per-task timeout
    session_timeout_seconds=3600,       # Total session timeout
    
    # PLATO integration
    plato_url="http://localhost:8848",  # PLATO server
    scout_room="my/scout/sessions",     # Where to emit tiles
    emit_tiles=True,                    # Enable/disable tiling
    
    # H1 routing
    h1_router_enabled=False,            # Use H1 router for task routing
    h1_router_url="http://localhost:8902",  # H1 router endpoint
    emergence_threshold_offset=-2,      # H¹ offset for alerts
    
    # Callbacks
    on_task_complete=None,              # Called when task completes
    on_session_end=None,               # Called when session ends
    on_emergence_alert=None            # Called when emergence detected
)
```

---

## Task Management

### Adding Tasks

```python
# Simple task
task = session.add_task("analyze-data", {"query": "analyze H1 patterns"})

# Task with priority
task = session.add_task(
    "critical-fix", 
    {"issue": "memory leak"},
    priority=TaskPriority.HIGH
)

# Task with required capabilities
task = session.add_task(
    "compile-code",
    required_capabilities=["compilation", "llvm"]
)
```

### Completing Tasks

```python
# Success
session.complete_task(
    task_id="analyze-data",
    outcome=TaskOutcome.SUCCESS,
    duration_ms=1234,
    result={"patterns_found": 5}
)

# Failure with error
session.complete_task(
    task_id="compile-code",
    outcome=TaskOutcome.FAILED,
    duration_ms=5000,
    error="Compilation failed: missing dependency"
)

# Cancelled
session.complete_task(
    task_id="long-task",
    outcome=TaskOutcome.CANCELLED,
    duration_ms=60000
)
```

---

## H¹ Integration

The session manager can integrate with `fleet-h1-router` for constraint-aware task routing:

```python
config = SessionConfig(
    # ... other config ...
    h1_router_enabled=True,
    h1_router_url="http://localhost:8902"
)

manager = SessionManager(config)

# Route task using H1 router
decision = manager.route_task_h1(
    task_id="new-task",
    required_capabilities=["compilation"]
)

print(f"Agent: {decision.agent_id}")
print(f"H¹ before: {decision.h1_before}, after: {decision.h1_after}")
print(f"Emergence risk: {decision.emergence_risk:.1%}")
```

### Emergence Detection

When H¹ exceeds threshold during task routing, the session manager:

1. Posts an **EMERGENCE ALERT** tile to PLATO
2. Calls the `on_emergence_alert` callback
3. Logs the emergence event in the session

```python
def my_emergence_callback(alert):
    print(f"⚠️ EMERGENCE: β₁={alert.h1} > V-2={alert.threshold}")
    # Take corrective action

config = SessionConfig(
    # ...
    on_emergence_alert=my_emergence_callback
)
```

---

## PLATO Tile Format

### Session Start Tile

```json
{
  "domain": "gc/research/scout-reports/holodeck-session",
  "question": "[SESSION_START] oracle1:constraint-theory-research",
  "answer": {
    "session_id": "sess_abc123",
    "agent_id": "oracle1",
    "session_name": "constraint-theory-research",
    "started": "2026-05-19T22:45:00Z",
    "tags": ["research", "constraint-theory", "h1"],
    "max_tasks": 50,
    "task_timeout_seconds": 300,
    "h1_router_enabled": true
  },
  "tags": ["scout", "session", "start", "oracle1"],
  "confidence": 1.0,
  "source": "holodeck-session-manager"
}
```

### Task Start Tile

```json
{
  "domain": "gc/research/scout-reports/holodeck-session",
  "question": "[TASK_START] analyze-fleet-h1 → oracle1",
  "answer": {
    "session_id": "sess_abc123",
    "task_id": "analyze-fleet-h1",
    "agent_id": "oracle1",
    "routing": {
      "agent_id": "oracle1",
      "h1_before": 3,
      "h1_after": 4,
      "emergence_risk": 0.0
    }
  },
  "tags": ["scout", "task", "start"],
  "confidence": 0.9,
  "source": "holodeck-session-manager"
}
```

### Session End Tile

```json
{
  "domain": "gc/research/scout-reports/holodeck-session",
  "question": "[SESSION_END] oracle1:constraint-theory-research — SUCCESS",
  "answer": {
    "session_id": "sess_abc123",
    "outcome": "success",
    "duration_seconds": 847,
    "tasks": {
      "total": 5,
      "succeeded": 4,
      "failed": 1,
      "cancelled": 0
    },
    "h1_delta": {
      "start": 2,
      "end": 3,
      "change": 1
    },
    "patterns": ["high_completion_streak", "first_failure_recovered"]
  },
  "tags": ["scout", "session", "end", "success"],
  "confidence": 0.95,
  "source": "holodeck-session-manager"
}
```

---

## API Reference

### SessionConfig

```python
@dataclass
class SessionConfig:
    session_name: str
    agent_id: str
    tags: List[str] = field(default_factory=list)
    max_tasks: int = 50
    task_timeout_seconds: int = 300
    session_timeout_seconds: int = 3600
    plato_url: str = "http://localhost:8848"
    scout_room: str = ""
    emit_tiles: bool = True
    h1_router_enabled: bool = False
    h1_router_url: str = "http://localhost:8902"
    emergence_threshold_offset: int = -2
    on_task_complete: Optional[callable] = None
    on_session_end: Optional[callable] = None
    on_emergence_alert: Optional[callable] = None
```

### SessionManager

```python
manager = SessionManager(config)

# Session lifecycle
session = manager.start_session()           # Start new session
session.end_session(outcome)                # End session

# Task management
task = session.add_task(task_id, data)      # Add task
session.complete_task(task_id, outcome)     # Complete task
session.get_task(task_id)                   # Get task
session.get_active_tasks()                  # List active tasks

# H1 routing
decision = manager.route_task_h1(task_id, caps)  # Route with H1
status = manager.get_h1_status()            # Get fleet H1 status

# Session info
session.session_id        # Unique session ID
session.agent_id          # Which agent
session.tasks             # All tasks
session.duration_seconds   # Session duration
```

### TaskOutcome Enum

```python
class TaskOutcome(Enum):
    SUCCESS = "success"       # Task completed successfully
    FAILED = "failed"         # Task failed
    CANCELLED = "cancelled"   # Task was cancelled
    TIMEOUT = "timeout"       # Task timed out
```

### SessionOutcome Enum

```python
class SessionOutcome(Enum):
    SUCCESS = "success"       # Session ended successfully
    FAILED = "failed"          # Session failed
    TIMEOUT = "timeout"        # Session timed out
    CANCELLED = "cancelled"    # Session was cancelled
```

---

## Metrics

```bash
# Session metrics
holodeck_session_active_total
holodeck_session_completed_total{outcome}
holodeck_session_duration_seconds

# Task metrics
holodeck_task_started_total
holodeck_task_completed_total{outcome}
holodeck_task_duration_seconds{outcome}

# H1 metrics
holodeck_h1_routing_decisions_total{agent_id}
holodeck_emergence_alerts_total
holodeck_h1_before_routing{agent_id}
holodeck_h1_after_routing{agent_id}
```

---

## Design Principles

1. **Every session event is a checkpoint.** Sessions emit tiles at start, every task, and end.
2. **H¹ routing is optional but recommended.** Enable it to get constraint-aware routing.
3. **Sessions are independent.** Each session is a self-contained unit of work.
4. **Emergence is a signal, not a failure.** Handle it gracefully, log it thoroughly.
5. **Tiles are the observation currency.** Make every tile useful for mids and architects.

---

## Comparison: Session Manager vs Direct API

| Feature | Session Manager | Direct API |
|---------|-----------------|-----------|
| Lifecycle management | ✅ Automatic | ❌ Manual |
| Task tracking | ✅ Built-in | ❌ Manual |
| H¹ routing | ✅ Integrated | ❌ Manual |
| PLATO tiles | ✅ Automatic | ❌ Manual |
| Emergence detection | ✅ Built-in | ❌ Manual |
| Timeout handling | ✅ Automatic | ❌ Manual |
| Pattern analysis | ✅ Built-in | ❌ Manual |

---

## Testing

```bash
# Run tests
pytest tests/ -v

# Test session lifecycle
pytest tests/test_session.py -v

# Test H1 integration
pytest tests/test_h1.py -v

# Test PLATO tiling
pytest tests/test_plato.py -v
```

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup.

## License

Apache 2.0 — See [LICENSE](LICENSE).
