| name | bd-issue-pop |
| description | Pop a bead (epic) into a worktree branch, decompose it into child beads, then |
bd-issue-pop command
Apply this command workflow. Treat any text after its invocation as the command input.
Pop a bead (epic) into a worktree branch, decompose it into child beads, then
hand off to /do-work. Mirrors the gh flow: this command sets up, /do-work
does the work, and its last pass merges the PR and closes the epic.
Two stores, and keeping them separate matters. The epic's code lands on the
one bd-<id>-<slug> branch and merges via its single PR. The bead tracker
lives in the shared main-repo database — worktrees reach it through a
.beads/redirect — and persists with bd sync. Bead status never rides the
code branch.
Input
$ARGUMENTS
A bead ID. Without one, run bd list and ask which.
Phase 0-2 -- Sync, fetch, gather context
gh repo view --json nameWithOwner -q .nameWithOwner
git pull && bd sync
git branch --show-current
bd show <id>
Stop if you are not on main in the main checkout, or if the bead is already
done. Show the bead's title and description.
Read docs/VISION.yaml, docs/ARCHITECTURE.yaml, docs/road-map.yaml,
docs/constitutions/design.yaml where they exist, plus the READMEs relevant to
the bead. Probe the build tool once — its output gates every later mage step,
and a repo without mage skips them silently:
mage -l 2>/dev/null || true
Run the consistency check if one exists (mage audit, or mage analyze where
it is named that way) and mage stats if present. Summarize the project state.
Phase 3 -- Propose Breakdown
Decompose the bead into child beads — the beads-native equivalent of an epic's
sub-issues. For each child, specify:
- Title and type (documentation or code)
- Required Reading: mandatory list of files
- Files to Create/Modify: explicit file list
- Structure: Requirements, Design Decisions (optional), Acceptance Criteria
Estimated LOC for code children
- Dependencies: which sibling children must finish first
- Code task sizing: 300-700 lines of production code, no more than 5 files per child
Present the children and their dependency ordering explicitly (a short list or
a small graph — "C depends on A, B") for approval. This is the single
interactive pause. Do not create any beads until the user agrees.
If the natural breakdown is a single unit of work, say so — no child beads are
created; the parent bead is worked directly (the single-unit path in Phase 4).
Phase 4 -- Create the worktree and the bead graph
After approval, slug the title (kebab-case, ≤30 chars) and set up:
git checkout main
git fetch origin main
git merge --ff-only origin/main
git worktree add ../bd-<id>-<slug> -b bd-<id>-<slug>
cd ../bd-<id>-<slug>
bd sync
bd update <id> --status in_progress && bd sync
The fetch matters twice over here. git worktree add branches from whatever
main points at with no complaint about its age, and bd sync rebuilds the
bead graph from issues.jsonl — which lives on main, so a stale checkout
gives a stale graph as well as a stale base. --ff-only rather than pull: a
diverged main is a state to report, not one to resolve on the user's behalf.
Re-check the bead is still open here if the approval in Phase 3 took a while
(bd show <id>); the gh sibling learned that the hard way.
bd sync is what wires beads to the worktree: one database lives in the main
checkout, and the worktree reaches it through a local .beads/redirect. If
bd still cannot find it, write the relative path to the main repo's
.beads/ into that file — it is gitignored, never commit it.
Every bd change is tracker state in the shared database. Persist with
bd sync, which writes and pushes issues.jsonl; never git add .beads/ on
the code branch.
For a multi-child breakdown, create each child labelled with the parent id
— that label is what scopes /do-work's ready queue to this epic — then wire
the dependency edges so the parent stays blocked until its children finish:
bd create "<child title>" --label <id>
bd dep add <child-id> <prereq-child-id>
bd dep add <id> <child-id>
bd sync
For a single-unit breakdown, create no children; /do-work works the parent
bead directly.
Commit the marker on the branch and push:
git commit --allow-empty -m "Pop <id>: <title> into worktree
Children: <child ids> # omit when there are none
Skill: bd-issue-pop
Called-by: <invoking skill, or 'user'>"
git push -u origin bd-<id>-<slug>
Working the epic — run /do-work repeatedly
Popping built the worktree and the bead graph; /do-work does the work, one
ready child per pass, on the shared branch. It detects beads mode, takes the
next child from the parent-scoped queue (bd ready --label <id>), implements
it under the real-work bar (no stubs), records Actual LOC, and closes it with
bd update --status done, which unblocks its dependents.
Only ever implement beads belonging to this epic — never one from another
epic that happens to be ready.
One worktree, one PR per epic. A child too big to finish gets split into
siblings under this epic in the same worktree; /do-work never pops again.
When the last child closes, /do-work runs Phase 5 automatically.
Phase 5 -- Merge and Close the Epic
The last /do-work pass reaches this automatically after it closes the final
child. It opens the PR, merges it to main, closes the epic, and cleans up — no
manual step. (Verify first that every child is done and the work is real; do not
merge a stub branch.)
-
Close the epic in the tracker. All children are done, so its dependencies are
satisfied. This is a tracker update in the shared database, persisted with
bd sync — not a commit on the code branch (beads has no git auto-close, and
the code PR carries only code):
bd ready --label <id>
bd update <id> --status done
bd sync
-
Open a pull request against main for the code:
gh pr create --repo <owner>/<repo> \
--base main \
--head bd-<id>-<slug> \
--title "bd-<id>: <title>" \
--body "$(cat <<'EOF'
## Summary
<2-3 sentence summary of what this delivered>
## Changes
<bulleted list of what was produced>
## Test plan
<if a consistency-check target is available:>
- [ ] the consistency check (`mage audit` / `mage analyze`) passes
- [ ] All tests pass
- [ ] Documentation reviewed for consistency
Bead: <id>
Actual LOC: <n> (est <m>)
EOF
)"
-
Merge the pull request and delete the remote branch:
gh pr merge --repo <owner>/<repo> --merge --delete-branch
-
From the main repo directory, pull the merged code and sync beads (the tracker
already reflects the closed epic and children — bd sync reconciles it):
cd -
git pull origin main
bd sync
-
Remove the worktree and delete the local branch:
git worktree remove ../bd-<id>-<slug>
git branch -d bd-<id>-<slug>
-
Report the PR URL, that it merged, and that the epic and its children are
closed.
Skill Tracing
Each skill records provenance as git trailers on the commits it authors:
bd-issue-pop marker commits carry Skill: bd-issue-pop and Called-by: user.
do-work implementation commits carry Skill: do-work and Called-by: bd-issue-pop.