---
name: finishing-a-development-branch
description: Close out a completed development branch: verify tests, then present merge, PR, keep, or discard options and execute the choice with safe worktree cleanup. Use when implementation is done and the work needs integrating. Not for executing the plan itself: use executing-plans. Not for commit and branching discipline during development: use git-workflow-and-versioning.
license: MIT
metadata:
  author: TechTide AI (Alex Cinovoj)
  provenance: rewritten from patterns in obra/superpowers (MIT)
  category: Delivery & Handoff
---

# Finishing a Development Branch

Tests pass first, then the user picks from a fixed menu, then you execute exactly that choice. No open-ended "what next?", no cleanup that destroys work, no merge on red.

## Workflow

1. **Verify tests.** Run the project suite (`npm test`, `pytest`, `cargo test`, `go test ./...`). Failures: show them, state "cannot merge or PR until tests pass", and stop. Do not present options over a red suite.
2. **Detect the environment.** Compare `git rev-parse --git-dir` with `git rev-parse --git-common-dir` (resolve both with `pwd -P`). Equal: normal repo. Different with a named branch: worktree you may need to clean up. Different with detached HEAD: externally managed workspace, reduced menu, never clean up.
3. **Determine the base branch.** `git merge-base HEAD main || git merge-base HEAD master`, or ask: "This branch split from main, correct?"
4. **Present the fixed menu.** Normal repo or named-branch worktree, exactly these four: 1) merge back to base locally, 2) push and create a PR, 3) keep the branch as-is, 4) discard this work. Detached HEAD, exactly three: push as new branch and PR, keep as-is, discard. No explanations attached, keep it terse.
5. **Execute the choice.** Read references/option-playbooks.md before executing, it has the exact command sequence and cleanup rules per option. The invariants: merge before any cleanup, re-run tests on the merged result, worktree survives for options 2 and 3, discard requires the user to type `discard`.
6. **Clean up only what you own.** Only options 1 and 4 clean up, and only worktrees under `.worktrees/` or `worktrees/`. Anything else was created by the host environment: leave it alone. Always `cd` to the main repo root before `git worktree remove`, then `git worktree prune`.

## Quick reference

| Option | Merge | Push | Keep worktree | Delete branch |
|--------|-------|------|---------------|---------------|
| 1 Merge locally | yes | - | - | yes, after cleanup |
| 2 Create PR | - | yes | yes | - |
| 3 Keep as-is | - | - | yes | - |
| 4 Discard | - | - | - | yes, force, after typed confirm |

## Good vs bad

**Bad:** Tests are failing but the diff "looks fine", so you present the menu, the user picks merge, and main is now broken. Then you remove the worktree the user needed for the follow-up PR.

**Good:** Suite is green, you detect a named-branch worktree under `.worktrees/`, present the four options, user picks PR. You push with `-u`, report the branch name, and leave the worktree in place for review iteration.

## Verification

After executing option 1, run `git status` on the base branch and the test suite. Expect: clean tree, merged commits present in `git log`, suite green, feature branch deleted, worktree removed and `git worktree list` no longer shows it. Anything else: stop, report the exact failing step, do not continue cleanup.

## Completion checklist

- [ ] Test suite run and green before the menu
- [ ] Environment detected (repo vs worktree vs detached HEAD)
- [ ] Exact fixed menu presented, right count of options
- [ ] Chosen option executed per the playbook
- [ ] Discard confirmed by the user typing `discard`, if chosen
- [ ] Worktree cleanup only for options 1 and 4, only owned worktrees
- [ ] Branch deletion after worktree removal, never before

Any box unchecked: not done. Fix or say so.

## Red flags

Verbatim excuses that precede destroyed work or broken main:

- "Tests are probably flaky, I'll merge anyway"
- "I'll clean up the worktree now to be tidy" (on option 2 or 3)
- "They said discard in spirit, close enough" (no typed confirmation)
- "I'll force-push to fix the history"
- "This worktree looks stale, I'll remove it" (not under `.worktrees/`)

Closure rule: destructive actions (discard, worktree removal, branch force-delete) require the exact preconditions in the playbook, met literally, or they do not happen.

## Footguns

- **Deleting the branch before the worktree.** `git branch -d` fails because the worktree still references it. Fix: merge, remove worktree, then delete branch, in that order.
- **Running `git worktree remove` from inside the worktree.** Fails or half-completes. Fix: `cd` to the main repo root first (`git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel`).
- **Cleaning harness-owned workspaces.** Removing a worktree the platform created leaves phantom state it cannot recover from. Fix: provenance check, only `.worktrees/` and `worktrees/` paths are yours.
- **Merging without re-testing the merged result.** The branch was green, main moved, the merge is red. Fix: run the suite on the merge commit before deleting anything.
