consensus-loop:merge
Squash-merge a worktree branch into the target branch with a structured commit message. Use after audit consensus and retrospective completion.
Merge Worktree
Squash-merge the current worktree branch back into the target branch. All WIP commits become one structured commit.
Who Runs This
This skill is invoked by the orchestrator after:
- Implementer's
[agree_tag]consensus reached - Implementer's WIP commit completed
- Retrospective protocol completed (session-gate released via
session-self-improvement-complete)
Execution Context
| Context | Behavior |
|---|---|
| Interactive | Report merge result → ask about cleanup |
| Headless | Merge → verify → report result → do NOT cleanup (orchestrator decides) |
In headless mode, do NOT ask "keep worktree or remove?" — report the result and exit. The orchestrator handles cleanup.
Current Context
- Git dir:
!git rev-parse --git-dir - Current branch:
!git branch --show-current - Recent commits:
!git log --oneline -20 - Working tree status:
!git status --short
Instructions
Follow phases in order. Do NOT skip phases.
Phase 1: Validation
-
Verify worktree:
git rev-parse --git-dirmust contain/worktrees/. If not → stop:"This skill must be run from inside a git worktree."
-
Verify retrospective complete: Check
.claude/retro-marker.jsonin the repo root:git -C "$(git rev-parse --git-common-dir)/.." cat-file -e HEAD:.claude/retro-marker.json 2>/dev/null || cat "$(git rev-parse --git-common-dir)/../.claude/retro-marker.json" 2>/dev/nullIf
retro_pendingistrue→ stop:"Retrospective not completed. Run retrospective first, then
session-self-improvement-complete." -
Identify current branch:
git branch --show-current -
Resolve target branch:
- If
$ARGUMENTSprovided → use as target - Otherwise → detect
mainormaster
- If
-
Find original repo root:
ORIGINAL_ROOT="$(git rev-parse --git-common-dir)/.." -
Clean working tree:
git status --porcelainmust be empty. If not → stop:"Uncommitted changes found. Commit or stash first."
Phase 2: Research
-
Commit history:
git log --oneline <target>..HEAD -
File change summary:
git diff <target>...HEAD --stat -
Full diff:
git diff <target>...HEAD— read carefully -
Read key files: For significantly changed files, use Read to understand full context
-
Categorize changes:
- Features (new functionality)
- Fixes (bug corrections)
- Refactors (code restructuring)
- Tests (new or updated)
- Docs (documentation)
- Chore (build, CI, tooling)
Phase 3: Generate Commit Message
Structure:
<type>(<scope>): <summary under 72 chars>
<body — what changed and why, grouped by category>
<footer — breaking changes, issue refs, co-authors>
Type rules:
feat— new functionalityfix— bug correctionrefactor— restructuring without behavior changetest— test additions/changes onlydocs— documentation onlychore— build, CI, tooling
Scope: the primary module affected (e.g., bus, security, orchestration, fe)
Body guidelines:
- Group changes by category with
###headers if multiple types - Reference file paths for significant changes
- Explain WHY, not just WHAT
- Include test results summary
Footer:
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Phase 4: Execute Merge
All commands use absolute paths or git -C — shell state does not persist between commands.
-
Squash merge (from original repo root):
git -C "${ORIGINAL_ROOT}" merge --squash <worktree_branch> -
Commit with generated message:
git -C "${ORIGINAL_ROOT}" commit -m "<generated_message>" -
Verify merge commit exists:
git -C "${ORIGINAL_ROOT}" log -1 --onelineThe output must show the new squash commit with the generated message. If not → merge failed — report error, do NOT proceed to cleanup.
-
Verify no uncommitted changes remain:
git -C "${ORIGINAL_ROOT}" status --porcelainMust be empty. If not → partial merge — report and stop.
-
Report result to orchestrator:
## Merge Complete - Branch: <worktree_branch> → <target_branch> - Commits squashed: N - Files changed: M - Commit: <short_sha> <first_line> - Verified: commit exists ✅, working tree clean ✅ Worktree can be removed with: `git worktree remove <worktree_path>`
Phase 5: Cleanup
Report to orchestrator with cleanup options:
**Worktree merged. Cleanup options:**
1. `git worktree remove <worktree_path> && git branch -d <worktree_branch>`
2. Keep worktree for reference
The orchestrator decides — this skill does not remove worktrees autonomously.
Commit Message Example
feat(bus): add event replay port for SSE reconnection
EventBus now supports replay_since(cursor, { team_id }) for
tenant-scoped event replay. InMemory uses ring buffer,
Redis uses XRANGE.
- src/bus/types.ts: ReplayableMessageBus interface
- src/bus/service.ts: ring buffer implementation (max 1000)
- src/bus/redis-bus.ts: XRANGE-based replay
- tests/bus/replay.test.ts: 12 tests
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Emergency Rollback
If post-merge verification fails (tests break, build fails):
- Identify the squash commit:
git log -1 --oneline→ note the SHA - Revert the merge commit:
git -C "${ORIGINAL_ROOT}" revert --no-edit <merge-sha> - Verify revert:
git -C "${ORIGINAL_ROOT}" diff HEAD~1..HEAD --statshows the inverse - Run tests: confirm the revert restores passing state
- Report to orchestrator:
## Emergency Rollback - Reverted: <merge-sha> (<commit message>) - Reason: <what failed> - Status: tests passing after revert - Action needed: task returns to `correcting` status - Update handoff: task status →
correcting, note rollback reason
Do NOT use git reset --hard — revert creates an audit trail. Hard reset loses history.
Exceptions
- Do NOT merge if
git status --porcelainshows uncommitted changes - Do NOT force-push after merge
- Do NOT delete the worktree without orchestrator decision
- Do NOT merge if
consensus-loop:verifyhas unresolved failures - Do NOT merge if retrospective is pending (
retro_pending: true) - Do NOT report success without verifying the squash commit exists in git log
- Do NOT proceed to cleanup if
git status --porcelainshows uncommitted changes