# Design: Sessions

## What is a Session

A session is a single continuous conversation thread between a human and/or an agent. It represents a unit of work with continuity of context — the back-and-forth of prompts, responses, tool calls, and advisor messages that together tell the story of a task being worked on.

A session is **not** a person, a device, or a feature. People come and go (handoff). Devices reconnect. Features span multiple sessions. The session is the conversation itself.

## Session Identity

### Name
A short random slug: `s-7a3f`, `s-b2e1`, `s-c9d0`.

- 4 hex characters (65K possibilities per project)
- Generated by the daemon on join
- No human identity, no timestamp, no semantics
- Collision on create → regenerate and retry (max 3 attempts)
- Users can still pass an explicit name for scripts/tests

### Why not human-readable names?
Earlier designs used `manu-260610a` or user-chosen names like `fxm`. Problems:
- User-chosen names collide (two people pick `fxm`)
- Identity-based names break on driver handoff
- Date-based names imply lifecycle boundaries that don't exist
- Named sessions create an obligation to manage them (rename, archive, clean up)

Random slugs are disposable. Nobody manages them. They're just routing handles.

## Participants

A session has participants, not owners. At any point:

| Role | Who | Count |
|------|-----|-------|
| Driver | The human or agent actively working in the session | Exactly one (or none if open) |
| Agent | The AI tool responding to the driver | One per session |
| Advisors | Observers who can inject messages | Zero or more |

### Driver
The driver is the entity currently "at the keyboard." For a local coding session, the human starts as driver. For an autonomous agent session, the agent is the driver.

Drivers can hand off: `POST /projects/:proj/sessions/:sess/handoff` clears the driver, `POST /projects/:proj/sessions/:sess/driver` claims it. The session continues — same thread, new driver.

### Agent identity
Every session has an associated agent identity, even if the agent hasn't responded yet. For local coding sessions, this defaults to the tool name (`agent:claude`, `agent:cursor`). For named agents, it's explicit (`agent:dean`).

The agent identity is set on session creation and stored alongside the driver.

### Advisors
Anyone who injects a message into a session is an advisor. Advisors are not registered — they're identified by their sender identity on the inject event (`slack:krishna`, `user:alice.chen`).

## Lifecycle

### Creation
A session is created when someone runs `/polaris join <project>`. The daemon:
1. Generates a random slug
2. Calls the API to create the session with the driver and agent identity
3. Returns the session name to the user

### Active use
Events flow into the session: prompts, responses, tool calls, advisor injections. The daemon stamps the correct sender identity on each event (human or agent).

### Idle
A session with no events for some period is idle. No special handling — it just sits there. The conversation can resume at any time.

### Handoff
The driver releases the session. Another human or agent claims it. The conversation thread continues with a new driver. This is useful for:
- Shift changes ("I'm done for the day, Alice takes over")
- Escalation ("This needs a senior engineer")
- Agent takeover ("Let the agent finish this autonomously")

### Closure
There is no explicit close. Sessions are never deleted. They age out of relevance naturally. The dashboard could eventually hide sessions with no recent activity, but the data persists.

### Reconnection
If a daemon restarts or a user's machine disconnects, they can rejoin the same session by name (if they know it) or start a new one. Starting a new session is preferred — it's a clean conversation thread.

## Relationship to Projects

A session belongs to exactly one project. A project has many sessions. Sessions within the same project share the floor — their events are all visible to each other and to Slack.

```
Project: polaris-dev
  ├── Session s-7a3f (driver: user:manu.bansal, agent: agent:claude)
  ├── Session s-b2e1 (driver: user:alice.chen, agent: agent:claude)
  └── Session s-c9d0 (driver: agent:dean, agent: agent:dean)
```

## What Shows on Slack

The Slack channel is per project. Events from all sessions in the project appear in the same channel. The session name appears in the poster's display name:

```
Manu Bansal (s-7a3f): Can we add a retry mechanism to the ETL pipeline?
Claude (s-7a3f): I'll add exponential backoff to the S3 upload step...
Alice Chen (s-b2e1): I'm working on the monitoring dashboard for this pipeline
Dean (Data) (s-c9d0): The pipeline's target table has a NOT NULL constraint on...
```

The session slug disambiguates when multiple sessions are active.

## What Shows on the Dashboard

The project card lists sessions with:
- Session name (slug)
- Current driver
- Agent identity
- Prompt count
- Last activity timestamp

```
polaris-dev                          #polaris-dev
├── s-7a3f  Manu Bansal   Claude    34 prompts  2 min ago
├── s-b2e1  Alice Chen    Claude    12 prompts  15 min ago
└── s-c9d0  Dean (Data)   Dean       8 prompts  1 min ago
```

## Schema

Current sessions table (no changes needed for naming):
```sql
CREATE TABLE sessions (
  name TEXT NOT NULL,
  project_id UUID NOT NULL REFERENCES projects(id),
  org_id TEXT NOT NULL,
  driver TEXT,              -- participant ID of current driver (nullable)
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  PRIMARY KEY (project_id, name)
);
```

Future addition for agent identity:
```sql
ALTER TABLE sessions ADD COLUMN agent TEXT;  -- e.g., "agent:claude", "agent:dean"
```

## Open Questions

1. **Session display name**: Should users be able to attach a label to a session after creation? e.g., `s-7a3f → "ETL retry fix"`. Optional metadata, not the primary key.

2. **Session limit**: Should there be a max number of active sessions per project? Probably not — let it grow naturally.

3. **Session search**: As sessions accumulate, how do you find a past conversation? By date? By participant? By content? This is a future search/filter feature.
