Merge Agent

SkillProductivity

Merges completed task worktree to main branch. Handles sequential merge queue to prevent conflicts.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Merge Agent skill

What this skill tells your AI

The instructions your AI receives, as published by vinzenz/prd-breakdown-execute in .claude/skills/execute-merge/SKILL.md and read by ahel’s review.

You merge a completed task's worktree branch into the main branch. Tasks complete in parallel but merge sequentially to avoid conflicts.

Input Arguments

Parse these from the prompt:

ArgumentRequiredDescription
--task-id <id>YesTask ID to merge (e.g., "L1-001")
--project-path <path>YesMain project directory
--worktree-path <path>YesPath to task's worktree
--task-file <path>YesTask XML for commit context
--tasks-path <path>YesTasks directory for state update

Execution Flow

Step 1: Parse Task XML

Read task file for commit message context:

cat {task_file}

Extract:

  • <meta><id>: Task ID
  • <meta><name>: Task name
  • <meta><layer>: Layer name
  • <requirements>: For commit message summary

Step 2: Verify Worktree State

Check worktree is ready for merge:

cd {worktree_path}

# Check we're on the right branch
git branch --show-current
# Expected: worktree-{task_id}

# Check for uncommitted changes
git status --porcelain
# Expected: empty (all changes committed)

# Get commit count
git rev-list --count main..HEAD
# Expected: >= 1

Step 3: Ensure Changes Committed

If there are uncommitted changes (shouldn't happen normally):

cd {worktree_path}
git add .
git commit -m "$(cat <<'EOF'
[{task_id}] Uncommitted changes before merge

Auto-committed by merge agent.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
EOF
)"

Step 4: Switch to Main Project

cd {project_path}

# Ensure we're on main
git checkout main

# Pull latest (in case of external changes)
git fetch origin main
git merge origin/main --ff-only 2>/dev/null || true

Step 5: Merge Worktree Branch

Use --no-ff to preserve merge history:

cd {project_path}

git merge --no-ff worktree-{task_id} -m "$(cat <<'EOF'
Merge worktree-{task_id}: {task_name}

Layer: {layer}
Task: {task_id}
Commits: {commit_count}

Implements:
- {requirement_1_summary}
- {requirement_2_summary}

Verification: Passed
EOF
)"

Step 6: Handle Merge Result

If merge succeeds:

  • Capture merge commit hash
  • Proceed to cleanup

If merge fails (conflict):

  • This should NOT happen with sequential merging
  • Abort merge: git merge --abort
  • Report conflict details
  • Keep worktree for debugging

Step 7: Cleanup Worktree

After successful merge:

cd {project_path}

# Remove worktree
git worktree remove {worktree_path}

# Delete the branch
git branch -d worktree-{task_id}

If removal fails:

git worktree remove --force {worktree_path}
git branch -D worktree-{task_id}

Step 8: Update State

Update execute-state.json:

state["tasks"][task_id]["status"] = "completed"
state["tasks"][task_id]["merged_at"] = now()
state["tasks"][task_id]["worktree_path"] = None
state["tasks"][task_id]["branch"] = None

# Update merge queue
for item in state["merge_queue"]:
    if item["task_id"] == task_id:
        item["status"] = "merged"

# Add to completed list
state["completed"].append(task_id)

# Remove from worktrees
del state["worktrees"][task_id]

# Update metrics
state["metrics"]["tasks_completed"] += 1
state["metrics"]["tasks_remaining"] -= 1

Step 9: Report Result

Success:

{
  "task_id": "L1-001",
  "status": "merged",
  "merge_commit": "abc1234567890",
  "commits_merged": 2,
  "worktree_cleaned": true,
  "branch_deleted": true
}

Conflict (should not happen):

{
  "task_id": "L1-001",
  "status": "conflict",
  "conflict_files": ["app/models/__init__.py"],
  "conflict_type": "both_modified",
  "worktree_preserved": true,
  "resolution_needed": true,
  "suggested_action": "Manually resolve conflict in worktree, then re-run merge"
}

Merge Commit Format

Merge worktree-L1-001: Create enums and constants

Layer: 1-foundation
Task: L1-001
Commits: 2

Implements:
- ProjectStatus enum (draft, in_progress, complete)
- PersonaType enum (developer, designer, pm)

Verification: Passed

Sequential Merge Guarantee

The layer agent ensures merges happen in priority order:

Merge Queue:
  Priority 1: L1-001 (status: ready)   ← Merge this first
  Priority 2: L1-002 (status: ready)   ← Wait
  Priority 3: L1-006 (status: pending) ← Still implementing

Each task waits for lower-priority tasks to merge before proceeding.

This ensures:

  • No merge conflicts between parallel tasks
  • Deterministic commit history
  • Easy rollback of specific tasks

Worktree Preservation

On merge failure:

  • Never delete worktree
  • Worktree contains all implementation work
  • User can inspect and manually resolve
  • Resume will re-attempt merge after manual fix

Error Handling

Branch Not Found

git merge worktree-{task_id}
# fatal: worktree-L1-001 - not something we can merge

Action: Check if branch exists, report error if not.

Worktree Not Found

git worktree remove {worktree_path}
# fatal: '{worktree_path}' is not a working tree

Action: Already removed (maybe manual cleanup). Continue.

Uncommitted Changes in Main

git checkout main
# error: Your local changes would be overwritten

Action: Error - main should always be clean. Report and stop.

Merge Conflict

git merge --no-ff worktree-{task_id}
# CONFLICT (content): Merge conflict in app/models/__init__.py
# Automatic merge failed; fix conflicts and then commit.

Action:

  1. Abort: git merge --abort
  2. Report conflict details
  3. Preserve worktree
  4. Return conflict status

Output Format

Status Line

[MERGE] L1-001 → main (abc1234)

Final Result

MERGE_RESULT:
{json object}

Git Commands Reference

CommandPurpose
git merge --no-ff branchMerge preserving history
git merge --abortCancel conflicting merge
git worktree remove pathRemove worktree
git worktree remove --force pathForce remove
git branch -d branchDelete merged branch
git branch -D branchForce delete branch
git rev-parse HEADGet current commit hash
git rev-list --count main..HEADCount commits since main

Signals

GitHub stars
56
Forks
3
Last commit
Jan 2026
Advanced
Catalog kind
skill
Gateway key
execute-merge
Source
github.com/vinzenz/prd-breakdown-execute