| name | bip-epic-handoff |
| description | Worker self-spawns a follow-up issue and hands off to a new slot |
/bip-epic-handoff
Hand off work from a finishing worker session to a new slot. Run this
from a worker (not the conductor) when your current issue is done
and you know what should happen next.
Prerequisites — direction must be decided FIRST
Do not run this skill until you have a clear next direction.
If you have just finished an issue and are unsure what comes next:
- Think through what you learned, what's unresolved, and what the
logical next step is
- Write a prose proposal (2-4 sentences) describing the direction
and why it's the right next move
- Present it to the user and wait for confirmation
- Only after the user agrees, proceed with the handoff
This skill is for execution, not ideation. The thinking happens before
you invoke it.
Usage
/bip-epic-handoff [issue-number]
- With an issue number: spawn work for an existing issue
- Without: run
/bip-issue-next first to create the follow-up issue
Workflow
Step 1: Ensure current work is complete
Before handing off, verify:
- Current branch is pushed
- PR is created (or work was exploratory with no PR needed)
.epic-status.json phase is completed or quality-gate
If not, finish the current work first.
Step 2: Create follow-up issue (if needed)
If no issue number was provided:
/bip-issue-next
This drafts and creates the follow-up issue. Record the new issue
number as <N>.
Step 3: Update the EPIC body
Add the new issue to the EPIC dashboard so the conductor sees it.
Follow the EPIC body update pattern from /bip-epic:
- Pull the current EPIC body with conflict tracking (
updatedAt)
- Add the new issue to the status dashboard (unchecked)
- If the current issue's PR is ready, check its box
- Conflict-check and push
If the conflict check fails, report it and continue — the conductor
will reconcile on next poll.
Step 4: Select or create a slot
Read .epic-config.json from the repo root.
Finding the config: In clone mode, .epic-config.json is in each
clone's repo root. In worktree mode, it's in the main checkout
(the conductor's working directory, not the worktree). To find it:
MAIN_CHECKOUT=$(git worktree list | head -1 | awk '{print $1}')
cat "$MAIN_CHECKOUT/.epic-config.json"
Then select or create a slot:
Clone mode (local_worktrees absent or false):
CLONE_ROOT=$(jq -r .clone_root .epic-config.json)
for name in $(jq -r '.clone_names[]' .epic-config.json); do
branch=$(git -C "$CLONE_ROOT/$name" branch --show-current 2>/dev/null)
[ "$branch" = "main" ] && echo "$name"
done
Pick the first idle clone that is not the current clone. The
handoff should move work to a different slot so the current session
can wind down cleanly. If all other clones are busy, use the current
clone as a last resort (after confirming with the user). If all clones
including current are busy, offer to create a new clone using a name
from new_clone_names in the config.
Worktree mode (local_worktrees: true):
CLONE_ROOT=$(jq -r .clone_root "$MAIN_CHECKOUT/.epic-config.json")
SLOT="$CLONE_ROOT/issue-<N>"
SLUG=$(gh issue view <N> --json title -q '.title' | tr '[:upper:]' '[:lower:]' | awk '{for(i=1;i<=4&&i<=NF;i++) printf "%s%s",$i,(i<4&&i<NF?"-":"")}')
if [ -d "$SLOT" ]; then
echo "Worktree exists — will resume"
else
git -C "$MAIN_CHECKOUT" branch --list "<N>-*" | tr -d ' ' | xargs -r git -C "$MAIN_CHECKOUT" branch -D
git -C "$MAIN_CHECKOUT" worktree add "$SLOT" -b "<N>-$SLUG"
fi
Step 5: Prepare the slot
Clone mode:
SLUG=$(gh issue view <N> --json title -q '.title' | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9 ]//g' | awk '{for(i=1;i<=4&&i<=NF;i++) printf "%s%s",$i,(i<4&&i<NF?"-":"")}')
cd "$CLONE_ROOT/<clone-name>"
git checkout main && git pull --ff-only origin main
git checkout -b "<N>-$SLUG"
rm -f .epic-status.json .epic-worklog.md
The branch must be created before spawning. If the spawn starts
on main, any uncommitted work lands on main and is hard to rescue.
Worktree mode — just clear stale status files:
rm -f "$SLOT/.epic-status.json" "$SLOT/.epic-worklog.md"
Step 6: Compose prompt and spawn
Follow /bip-epic-spawn Steps 3-4 to compose the prompt:
- Read the new issue:
gh issue view <N>
- Compose the full prompt including:
- A branch guard as the first line:
IMPORTANT: Before doing any work, verify you are on branch <N>-<slug> (run "git branch --show-current"). If you are on main, run "git checkout -b <N>-<slug>" first. Never commit directly to main.
/bip-issue-work <N> as the core instruction
- Ralph-loop invocation block
- EPIC status protocol (
.epic-status.json fields, worklog format)
- Any phasing or gate criteria from the issue
- Use the Write tool to create
/tmp/spawn-<N>.txt with the
full prompt (do NOT use shell redirection — complex prompts break
zsh expansion)
Then launch with the correct flags for your mode:
CLONE_ROOT=$(jq -r .clone_root .epic-config.json)
bip spawn --prompt-file /tmp/spawn-<N>.txt \
--dir "$CLONE_ROOT/<clone-name>" \
--name "<N>-<clone-name>"
bip spawn --prompt-file /tmp/spawn-<N>.txt \
--dir "$CLONE_ROOT/issue-<N>" \
--name "<N>-issue-<N>"
IMPORTANT: Always use --prompt-file, never --prompt "$(cat ...)".
Always use --dir and --name — without them the tmux window gets
a wrong name and the session runs in the wrong directory.
Do NOT use raw tmux new-window / tmux send-keys / claude.
Always go through bip spawn.
Step 7: Clean up current slot (optional)
If the current issue's PR is merged:
- Worktree mode: the conductor will clean up on next poll
- Clone mode:
git checkout main && git pull --ff-only
Don't force-remove your own worktree while you're in it — just let
the conductor handle cleanup.
Step 8: Report
## Handoff Complete
- Finished: i<current> — <title>
- Spawned: i<N> — <title> → <slot-name>
- EPIC updated: i<epic-number> ✓ (or ✗ conflict, conductor will reconcile)
Conventions
Same as /bip-epic: iN/pN prefixes, full URLs on first mention.
Tmux windows named NNN-YYY where NNN is the issue number and YYY is the
clone/slot name (e.g. 281-cedar in clone mode, 281-issue-281 in worktree mode).
Layout config (issue #149)
.epic-config.json keeps working. The newer global layout: block in
~/.config/bip/config.yml configures worktree mode for non-EPIC bip spawn; see docs/guides/layout.md.