# Ticket 5.3 — Session Forking

**Phase**: 5 — OpenCode-Specific Features
**Priority**: Medium
**Depends on**: 2.3, 4.3

## Description

Allow users to fork (branch) a conversation at any point, creating a new session that inherits history up to that message. OpenCode supports this natively via `POST /session/:id/fork`.

## Acceptance Criteria

### AC1: Fork button on messages

```gherkin
Given a session with multiple messages
When the user hovers over an assistant message
Then a "Fork from here" button appears
```

### AC2: Fork creates a new session

```gherkin
Given the user clicks "Fork from here" on message #5
When the fork is processed
Then a new session is created via POST /session/:id/fork
And the new session contains messages 1-5 from the original
And the browser switches to the new session
And a status message shows: "Forked from 'Auth Feature'"
```

### AC3: Fork appears in session list

```gherkin
Given a session was forked from "Auth Feature"
When the session list is displayed
Then the forked session shows an indicator: "Forked from Auth Feature"
And the parent session is still accessible
```

### AC4: Fork history is independent

```gherkin
Given session "Fork" was forked from "Original"
When the user sends a new message in "Fork"
Then the response goes into "Fork" only
And "Original" is not modified
```

## Testable Components

| Component | Test Type | What to Assert |
|-----------|-----------|----------------|
| Fork API call | Unit | Constructs correct POST to /session/:id/fork |
| Fork button | E2E | Appears on hover over eligible messages |
| Fork flow | E2E | Clicking fork creates new session, switches to it with history |
| Fork indicator | E2E | Session list shows fork origin for forked sessions |
| Fork independence | Fixture | Messages in forked session don't appear in original |

## Reference

- OpenCode fork API: `POST /session/:id/fork`
- OpenCode session children: `GET /session/:id/children`
