merge-resolver

Installation
SKILL.md

Merge Resolver

Resolve merge conflicts by analyzing git history and commit intent.

Quick Start

# Resolve conflicts for a specific PR
python3 .claude/skills/merge-resolver/scripts/resolve_pr_conflicts.py \
    --pr-number 123 --branch-name "fix/my-feature" --target-branch "main"

# Dry-run mode (no side effects)
python3 .claude/skills/merge-resolver/scripts/resolve_pr_conflicts.py \
    --pr-number 123 --branch-name "fix/test" --dry-run

Triggers

Trigger Phrase Operation
resolve merge conflicts Auto-detect branch/PR and resolve
fix conflicts on this branch Context-aware conflict resolution
PR has conflicts with main Merge-based conflict resolution
can't merge due to conflicts Analyze and fix blocking conflicts
resolve PR conflicts Resolve conflicts for a specific PR number

Process

Phase 1: Context Gathering

Step Action Verification
1.1 Fetch PR metadata via gh pr view PR metadata displayed
1.2 Checkout PR branch git branch --show-current matches
1.3 Attempt merge with base (--no-commit) Conflict markers created
1.4 List conflicted files git diff --name-only --diff-filter=U output

Phase 2: Analysis and Resolution

Step Action Verification
2.1 Classify files (auto-resolvable vs manual) Classification logged
2.2 Auto-resolve known patterns (accept --theirs) Files staged cleanly
2.3 For manual files: run git blame, analyze intent Commit messages captured
2.4 Apply manual resolutions per decision framework Conflict markers removed
2.5 Stage all resolved files git diff --check clean

Phase 3: Validation (BLOCKING)

Step Action Verification
3.1 Verify no remaining conflict markers git grep -n '<<<<<<<' -- returns no matches
3.2 Run session protocol validator validate_session_json.py exits 0
3.3 Run markdown lint npx markdownlint-cli2 exits 0
3.4 Commit merge resolution Commit SHA recorded
3.5 Push to remote Remote ref updated

Intent Classification

Classify each side's changes to determine resolution priority.

Type Indicators Priority
Security "security", "vuln", "CVE" in message Highest
Bugfix "fix", "bug", "patch", "hotfix" in message Highest
Feature "feat", "add", "implement"; new functionality Medium
Refactor "refactor", "cleanup", "rename"; no behavior change Medium
Style "style", "format", "lint"; whitespace only Lowest

Decision Framework

Scenario Resolution
Same intent, compatible changes Merge both
Bugfix vs feature Bugfix wins; integrate feature around it
Conflicting logic Prefer more recent or better-tested change
Style conflicts Accept either; prefer consistency with surrounding code
Deletions vs modifications Investigate why; deletion usually intentional

Session File Rules

CRITICAL: Session files from main are immutable audit records.

Action Correct Wrong
Session file conflict Accept --theirs, rename ours to next number Accept --ours (alters main's record)
Same-numbered session Keep both with different numbers Overwrite one version

See references/strategies.md for the full session file resolution workflow.

Auto-Resolvable Patterns

The script auto-resolves these by accepting the target branch version.

Pattern Rationale
.agents/sessions/*.json Session files from main are immutable audit records
.agents/* Session artifacts, constantly changing
.serena/* Serena memories, auto-generated
.claude/skills/*/*.md Skill definitions, main is authoritative
.claude/commands/* Command definitions, main is authoritative
.claude/agents/* Agent definitions, main is authoritative
templates/* Template files, main is authoritative
src/copilot-cli/* Platform agent definitions
src/vs-code-agents/* Platform agent definitions
src/claude/* Platform agent definitions
.github/agents/* GitHub agent configs
.github/prompts/* GitHub prompts
package-lock.json, yarn.lock, pnpm-lock.yaml Lock files; regenerate from main

Scripts

resolve_pr_conflicts.py

Resolves PR merge conflicts with auto-resolution for known file patterns.

python3 .claude/skills/merge-resolver/scripts/resolve_pr_conflicts.py \
    --pr-number <number> --branch-name <name> [--target-branch <branch>] \
    [--worktree-base-path <path>] [--dry-run]

Exit codes:

Code Meaning
0 Conflicts resolved successfully (and, if not --dry-run, pushed)
1 Non-auto-resolvable conflicts remain

When running with --dry-run, exit code 0 indicates that conflicts were fully auto-resolvable and the changes would have been pushed, but no changes were made because of dry-run mode.

Output format (JSON):

{
  "success": true,
  "message": "Successfully resolved conflicts for PR #123",
  "files_resolved": [".agents/HANDOFF.md"],
  "files_blocked": []
}

Security: Branch name validation prevents command injection. Worktree path validation prevents path traversal.

Anti-Patterns

Anti-Pattern Why It Fails Instead
Alter session files from main Breaks audit trail (immutable records) Accept --theirs, then rename our session file to the next available number
Push without session validation CI blocks with MUST violations Run validate_session_json.py first
Manual edit of generated files Lost on regeneration Edit template, run generator
Accept --ours for HANDOFF.md Branch version often stale Accept --theirs (main is canonical)
Merge lock files manually JSON corruption, broken deps Accept base, regenerate with npm install
Skip git blame analysis Wrong intent inference Always check commit messages
Resolve before fetching PR context Missing context, wrong base Always gh pr view first
Forget to stage .agents/ Dirty worktree CI failure Include all .agents/ changes

Verification

Success Criteria

Criterion Evidence
All conflicts resolved git diff --check returns empty
No merge markers remain git grep -n '<<<<<<<' -- returns no matches
Session protocol valid validate_session_json.py exits 0
Markdown lint passes npx markdownlint-cli2 exits 0
Push successful Remote ref updated

Completion Checklist

  • All conflicted files staged (git add)
  • No UU status in git status --porcelain
  • Session log exists at .agents/sessions/
  • Session end checklist completed
  • Serena memory updated
  • Merge commit created
  • Branch pushed to origin

Extension Points

Custom Auto-Resolvable Patterns

Add patterns to AUTO_RESOLVABLE_PATTERNS in resolve_pr_conflicts.py.

Custom Resolution Strategies

Add entries in references/strategies.md for domain-specific conflicts.

CI/CD Integration

- name: Resolve conflicts
  env:
    PR_NUMBER: ${{ github.event.pull_request.number }}
    HEAD_REF: ${{ github.head_ref }}
    BASE_REF: ${{ github.base_ref }}
  run: |
    python3 .claude/skills/merge-resolver/scripts/resolve_pr_conflicts.py \
      --pr-number "$PR_NUMBER" \
      --branch-name "$HEAD_REF" \
      --target-branch "$BASE_REF"

Related

  • Security: Branch name and path validation prevent injection and traversal
  • SESSION-PROTOCOL.md: Session end requirements (blocking gate)
  • strategies.md: Detailed resolution patterns for edge cases
  • merge-resolver-session-protocol-gap: Memory documenting root cause analysis

Why This Matters

Session protocol validation is a CI blocking gate. Pushing without completing session requirements causes CI failures with "MUST requirement(s) not met" errors.

Validation Commands

# 1. Ensure session log exists
SESSION_LOG=$(ls -t -- .agents/sessions/*.json 2>/dev/null | head -1)
if [ -z "$SESSION_LOG" ]; then
    echo "ERROR: No session log found."
    exit 1
fi

# 2. Run session protocol validator
python3 scripts/validate_session_json.py "$SESSION_LOG"

Session End Checklist (REQUIRED)

Req Step Status
MUST Complete session log (all sections filled) [ ]
MUST Update Serena memory (cross-session context) [ ]
MUST Run markdown lint [ ]
MUST Route to qa agent (feature implementation) [ ]
MUST Commit all changes (including .serena/memories) [ ]
MUST NOT Update .agents/HANDOFF.md directly [ ]

Common Failures

Error Cause Fix
E_TEMPLATE_DRIFT Session checklist outdated Copy canonical checklist from SESSION-PROTOCOL.md
E_QA_EVIDENCE QA row checked but no report path Add QA report or use "SKIPPED: docs-only"
E_DIRTY_WORKTREE Uncommitted changes Stage and commit all files including .agents/
Related skills

More from rjmurillo/ai-agents

Installs
1
GitHub Stars
24
First Seen
12 days ago