# Review and merge a worker's branch safely

> Read what an isolated shard did, then integrate its branch through machinery that never forces and never guesses.

**Goal:** a worker says it's done. Check the work, then get the branch into your main line without surprises.

## What you need

- An isolated shard (or a parked `crystl/*` branch) with commits.
- Merging from the desktop is not gated. `crystl merge` from the CLI is a [Guild](/pricing/) control command.

## Steps

1. **Confirm it's actually finished.** A quiet worker is not necessarily a done one: it may be parked on its agent's own in-terminal approval prompt, which `crystl shards` and `crystl status` flag as `⏸ awaiting input`.
2. **Read the work before you take it.** Open the gem's **branches** button in the shard bar for the worktrees panel. **ACTIVE** rows show what each shard was asked to do, its branch, agent and model, idle time, and commit count. Or read the session itself with [history](/docs/scenario-recover-lost-context/).
3. **Merge from the shard tab.** An isolated shard with unmerged commits shows a **↑N** badge below its tab. Click it and pick the merge action. Every action names what it will touch, like **merge crystl/opal into main (3 commits)**, so there's no guessing which branch moves where. crystl rebases onto the target, fast-forward merges, cleans up the worktree, and closes the shard.
4. **Or merge from the CLI,** which is what an orchestrator uses:

   ```bash
   crystl merge --gem myapp --shard opal
   ```

   It returns a structured result: `success`, `nothingToMerge`, `dirty`, `conflicts`, `failed`, or `notIsolated`.

5. **Merge a parked branch** from the **PARKED** section of the same panel. Each row shows commit count, whether the worktree is dirty, and last-commit age, with **reattach**, **merge**, and **discard** actions. Reattach reopens the worktree as a shell and does not auto-start an agent, so you land at a prompt on the branch.

## What you'll see when it works

The merge badge disappears and the shard closes, or the CLI returns `success`. Results from the panel arrive as a notification with a green check on the button, so nothing gets typed into an unrelated shard's terminal.

**Nothing here ever forces.** The three refusals you'll actually meet:

- **nothing to merge**: the branch has no commits ahead of the target.
- **dirty**: uncommitted changes in the worktree. Commit or stash them in the shard, then merge.
- **conflicts**: the rebase hit conflicts and was aborted automatically. Resolve them in the shard with `git rebase {target}`, then merge from the badge. On a remote isolated shard, do it in the remote shard: you're already SSH'd into the right directory.

If several shards touched database schema or migration files at the same time, crystl warns you before merging. Merge one, regenerate migrations, then merge the next.

Closing a shard instead of merging doesn't lose anything. **Keep Branch** parks it in git as `crystl/{name}`, where the branches button can reattach, merge, or discard it later. The only path that deletes commits is choosing **Discard** on purpose.

## Go deeper

- [Merging back to main](/docs/isolated-sessions/#merging-back-to-main) for all three merge paths and conflict handling.
- [Your work is safe](/docs/isolated-sessions/#your-work-is-safe) for the rules crystl follows before removing anything.
- [Integration target](/docs/isolated-sessions/#integration-target) to merge onto a release line instead of `main`.

---
Source: https://crystl.dev/docs/scenario-review-and-merge-a-branch/
