Finishing a Development Branch
Announce: "Using finishing-a-development-branch skill to complete this work."
Invariant Principles
- Tests Gate Everything - Never present options until tests pass. Never merge without verifying tests on merged result.
- Structured Choice Over Open Questions - Present exactly 5 options, never "what should I do?"
- Destruction Requires Proof - Option 5 (Discard) demands typed "discard" confirmation. No shortcuts.
- Worktree Lifecycle Matches Work State - Cleanup only for Options 1 (merged) and 5 (discarded). Keep for Options 2, 3, and 4.
Inputs
| Input | Required | Description |
|---|---|---|
| Passing test suite | Yes | Tests must pass before this skill can proceed |
| Feature branch | Yes | Current branch with completed implementation |
| Base branch | No | Branch to merge into (auto-detected if unset) |
post_impl setting |
No | Autonomous mode directive (auto_pr, offer_options, stop) |
Outputs
| Output | Type | Description |
|---|---|---|
| Integration result | Action | Merge, PR, preserved branch, or discarded branch |
| PR URL | Inline | GitHub PR URL (Options 2, 3 only) |
| Worktree state | State | Removed (Options 1, 5) or preserved (Options 2, 3, 4) |
Autonomous Mode
Check context for autonomous mode indicators: "Mode: AUTONOMOUS", "autonomous mode", or post_impl preference.
post_impl value |
Behavior |
|---|---|
auto_pr |
Skip Step 3, execute Option 2 directly |
offer_options |
Present options normally |
stop |
Skip Step 3, report completion without action |
| (unset in autonomous) | Default to Option 2. Log: "Autonomous mode: defaulting to PR creation" |
Branch-Relative Documentation
Required behavior:
- Derive all changelog/PR/commit content from the merge base diff at time of writing.
- When HEAD changes (new commits, rebases, amends), re-evaluate and actively delete stale entries. Never accumulate entries session-by-session.
- Code comments describe the present. Git describes the past. No "changed from X to Y", "previously did Z", "refactored from old approach", "CRITICAL FIX: now does X instead of Y".
- Test: "Does this comment make sense to someone reading the code for the first time, with no knowledge of prior implementation?" If no, delete it.
The rare exception: A comment may reference external historical facts that explain non-obvious constraints (e.g., "SQLite < 3.35 doesn't support RETURNING"). Reframe as a present-tense constraint, not a change narrative.
Release Prep: Changelog and Version
When the user says "update changelog", "bump version", "make sure version is correct", or any variation, treat it as prepare this branch for release. Always do both changelog and version together.
Changelog
- Compute the branch diff:
git diff $(git merge-base HEAD <target>)...HEAD - Derive entries from that diff. Each logical user-facing change gets one entry.
- Use Keep a Changelog format with the project's existing categories (Added, Changed, Fixed, etc.).
- If bumping the version, entries go under the new version heading (e.g.,
## [1.2.3] - YYYY-MM-DD). If not bumping, entries go under[Unreleased]. - If the project does not have a CHANGELOG.md, check the project's AGENTS.md for changelog conventions before creating one.
Version Bump
- Compare the version in
pyproject.toml(or the project's version file) againstorigin/main(or the merge target). If already bumped, trust it. - If not bumped, infer the level from the branch diff:
- Major: Breaking changes to public API
- Minor: New features, new public API surface
- Patch: Bug fixes, documentation, internal refactors
- If you cannot confidently infer the level, ask the user.
- If you infer major, confirm with the user before applying (unless in autonomous mode).
"Make sure X is correct"
"Make sure changelog is correct" and "make sure version is correct" mean the same as "update changelog" and "bump version". Derive from the branch diff, fix what is wrong, add what is missing.
The Process
Step 1: Verify Tests
# Run project's test suite
npm test / cargo test / pytest / go test ./...
If tests fail:
Tests failing (<N> failures). Must fix before completing:
[Show failures]
Cannot proceed with merge/PR until tests pass.
STOP. Do not proceed to Step 2.
If tests pass: Continue to Step 2.
Step 2: Determine Base Branch
git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null
If the command fails or is ambiguous, ask: "This branch split from main - is that correct?"
Step 3: Present Options
Present exactly these 5 options:
Implementation complete. What would you like to do?
1. Merge back to <base-branch> locally
2. Push and create a Pull Request
3. Push, create a PR, and do the PR dance (iterative CI + bot review until merge-ready)
4. Keep the branch as-is (I'll handle it later)
5. Discard this work
Which option?
Don't add explanation - keep options concise.
Step 4: Execute Choice
Dispatch subagent with command: finish-branch-execute
Provide context: chosen option number, feature branch name, base branch name, worktree path (if applicable).
Step 5: Cleanup Worktree
Dispatch subagent with command: finish-branch-cleanup
Provide context: chosen option number, worktree path. Note: Option 4 skips cleanup entirely.
Quick Reference
| Option | Merge | Push | Keep Worktree | Cleanup Branch |
|---|---|---|---|---|
| 1. Merge locally | Yes | - | - | Yes |
| 2. Create PR | - | Yes | Yes | - |
| 3. Create PR + PR dance | - | Yes | Yes | - |
| 4. Keep as-is | - | - | Yes | - |
| 5. Discard | - | - | - | Yes (force) |
Anti-Patterns
Self-Check
IF ANY unchecked: STOP and fix.
Integration
Called by:
- executing-plans (Step 5) - After all batches complete
- executing-plans --mode subagent (Step 7) - After all tasks complete in subagent mode
Pairs with:
- using-git-worktrees - Cleans up worktree created by that skill
Converted and distributed by TomeVault — claim your Tome and manage your conversions.