# Session Fork vs In-Session Branch Navigation in Pi Web: Key Differences Explained

> Understand session fork vs in-session branch navigation in Pi Web. Learn how session fork creates new diverging files while in-session branch navigation switches within the same file.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: deep-dive
- Published: 2026-07-25

---

**Session fork creates a new `.jsonl` file that diverges from a specific entry while preserving the original session unchanged, whereas in-session branch navigation switches between logical branches within the same file using the `navigate_tree` command.**

Pi Web (agegr/pi-web) provides two distinct mechanisms for managing conversation history divergence. Understanding the difference between session fork and in-session branch navigation is essential for building applications that handle complex conversational workflows or require isolated experimental paths.

## What Is Session Fork in Pi Web?

According to [AGENTS.md](https://github.com/agegr/pi-web/blob/main/AGENTS.md#L122), a **session fork** creates a brand-new `.jsonl` file starting from a selected entry. This operation generates a unique session ID and writes a separate file to disk, leaving the original session file completely untouched. The forked session maintains a reference to its parent through the `parentSession` header, causing it to appear as a child node in the sidebar.

The RPC handler in [[`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts)](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts#L393) processes the `"fork"` command by serializing the conversation history up to the specified entry into a new physical file.

```typescript
// Create a new independent session from entry "abc123"
await sendAgentCommand(sessionId, {
  type: "fork",
  entryId: "abc123"
});

```

## What Is In-Session Branch Navigation?

**In-session branch navigation**, documented in [AGENTS.md](https://github.com/agegr/pi-web/blob/main/AGENTS.md#L124), allows users to switch between multiple conversation branches while remaining within the same `.jsonl` file. Unlike forking, this operation does not create new files; instead, it updates the active pointer to reference a different leaf in the conversation tree by calling `navigate_tree`.

The implementation in [[`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts)](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts#L430) handles the `"navigate_tree"` command to update the session's active branch context without file system duplication.

```typescript
// Switch to branch leaf "leaf456" within the current session file
await sendAgentCommand(sessionId, {
  type: "navigate_tree",
  targetId: "leaf456"
});

```

## Key Differences Between Fork and Branch Navigation

- **File Persistence**: **Session fork** creates a separate `<timestamp>_<uuid>.jsonl` file on disk, while **in-session branch navigation** only modifies the existing file's internal tree structure.
- **Sidebar Representation**: Forked sessions appear as distinct child nodes under the original session due to the `parentSession` header relationship. In-session branches maintain a single sidebar entry regardless of how many branches exist.
- **API Parameters**: Forking requires the `"fork"` command with an `entryId` parameter, whereas navigation uses `"navigate_tree"` with a `targetId` parameter, both sent to the Agent RPC endpoint (`/api/agent/[id]`).
- **Deletion Scope**: Deleting a forked session removes only the new `.jsonl` file, preserving the original. Deleting a session with branches removes all branches since they share the same underlying file.

## Implementation Details

### RPC Command Handling

The core logic resides in [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts). The fork command handler (around line 393) instantiates a new session file containing the truncated history. The navigation handler (around line 430) updates the session state to point to a different leaf node without file system operations.

### Frontend Integration

In [[`hooks/useAgentSession.ts`](https://github.com/agegr/pi-web/blob/main/hooks/useAgentSession.ts)](https://github.com/agegr/pi-web/blob/main/hooks/useAgentSession.ts), the application wraps these RPC calls for UI consumption. The fork operation typically sets a transient loading state before invoking the command, while the [`BranchNavigator`](https://github.com/agegr/pi-web/blob/main/components/BranchNavigator.tsx) component provides the interface for selecting alternate branches.

```typescript
// hooks/useAgentSession.ts - fork handler pattern
const forkFromEntry = async (entryId: string) => {
  setForkingEntryId(entryId);
  await sendAgentCommand(sessionId, { 
    type: "fork", 
    entryId 
  });
};

// Branch navigation handler
const navigateToBranch = async (leafId: string) => {
  await sendAgentCommand(sessionId, { 
    type: "navigate_tree", 
    targetId: leafId 
  });
};

```

## Summary

- **Session fork** creates a new `.jsonl` file with a unique ID, preserving the original session while establishing a parent-child relationship visible in the sidebar.
- **In-session branch navigation** switches between logical branches within the same file using the `navigate_tree` command, maintaining a single session entry in the UI.
- Forking is handled in [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts) via the `"fork"` command (line 393), while navigation uses `"navigate_tree"` (line 430).
- Use forking for permanent divergence that requires independent file management, and use branch navigation for temporary explorations within the same conversation context.

## Frequently Asked Questions

### When should I use a session fork instead of branch navigation?

Use a **session fork** when you need to create a permanent, independent copy of the conversation that can be deleted, renamed, or shared separately without affecting the original session. Use **in-session branch navigation** for temporary "what-if" scenarios or alternative response paths that should remain grouped under the same session file and sidebar entry.

### Does forking a session affect the original conversation history?

No. According to the [AGENTS.md](https://github.com/agegr/pi-web/blob/main/AGENTS.md#L122) specification, forking creates a completely new `.jsonl` file while leaving the original session file and its entire history intact. The original session continues to exist unchanged, and the forked version references it only through the `parentSession` metadata header.

### How do I programmatically navigate between branches in Pi Web?

Invoke the `sendAgentCommand` function with `type: "navigate_tree"` and provide the `targetId` parameter specifying the leaf entry ID of the desired branch. This command is processed by the RPC manager in [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts) around line 430 to update the active branch context without creating new files or modifying session metadata beyond the active pointer.

### Where are forked sessions stored compared to branched sessions?

Forked sessions are stored as separate `.jsonl` files in the sessions directory with unique timestamps and UUIDs, each containing a `parentSession` header linking back to the source. Branched sessions exist as multiple logical paths within a single `.jsonl` file, meaning all branches share the same physical storage location, session ID, and metadata.