From workbuddy
Merge a batch of approved workbuddy PRs into main: order them, resolve conflicts against design intent, validate post-merge health, and report. Use when the user asks to 'merge the batch', 'merge approved PRs', 'integrate finished issues', '批量合并', '处理冲突'; or when the merge-agent is invoked.
How this skill is triggered — by the user, by Claude, or both
Slash command
/workbuddy:merge-flowThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill codifies how to merge multiple approved workbuddy PRs into `main` safely, with design-intent judgment on conflicts.
This skill codifies how to merge multiple approved workbuddy PRs into main safely, with design-intent judgment on conflicts.
The caller provides:
prs: [#101, #102, #104] # PR numbers to merge (in no particular order)
repo: Lincyaw/workbuddy # target repo
base: main # base branch (default: main)
mode: auto | review-required # auto = proceed on safe resolutions; review-required = escalate all conflicts
Before touching any branch, analyze the batch as a whole. This is where design-intent reasoning happens — do it once upfront, not hunk-by-hunk during rebase.
For each PR, fetch its linked issue:
gh pr view <n> --json body,closingIssuesReferences
gh issue view <issue-num> --json title,body,labels
Compare issues pairwise. Duplicate signals:
For suspected duplicates, consult decisions.md and project-index.yaml to see if one is actually a re-filing of an older issue or a subset of a larger epic.
Output: a list of duplicate groups. Example:
group A: #87 ("heartbeat lease bug") + #88 ("worker submit failure")
— #88's root cause IS #87. Duplicates.
group B: #91 (dynamic config reload) — standalone
For each pair of PRs (within AND across duplicate groups), analyze diffs:
gh pr diff <n>
Overlap signals:
git diff --name-only, then grep for symbol namesClassify each overlap:
| Class | Example | Default resolution |
|---|---|---|
| Identical intent, one better | Both fix the same bug; PR A is 3 lines, PR B is 50 lines with refactor | Adopt PR A entirely, close PR B |
| Identical intent, equivalent quality | Both fix same bug with equally clean code | Adopt oldest-approved PR, close the other |
| Complementary | Both add distinct features to same file; changes don't semantically conflict | Merge both in order |
| Partially overlapping | PR A adds features X+Y; PR B adds Y+Z; both need Y | Cherry-pick the non-overlapping parts into a merge order: take A's X, take one side's Y, take B's Z |
| Contradictory design | PR A uses pattern P1; PR B uses pattern P2; incompatible architecturally | Escalate — human must pick the approach |
For each non-trivial overlap, the skill prescribes:
Record all decisions in the report (Phase 6) with rationale. For "close PR B" decisions, post a comment on the closing PR explaining why, linking to the kept PR, and thanking the author.
A revised merge plan:
plan:
merge:
- pr: 101 # after cherry-pick: take only files A.go, B.go
cherry_pick_from: [abc123, def456]
reason: "partial overlap with #102; keeping non-overlapping commits"
- pr: 102 # full merge
reason: "standalone"
close:
- pr: 105
reason: "duplicate of #101 with inferior implementation; fewer tests, larger diff"
comment_to_post: "..."
escalate:
- prs: [103, 104]
reason: "contradictory design choices for internal/store package layout"
question_for_human: "..."
If any item lands in escalate: with a class 5 (contradictory design), stop and surface the question to the invoker before touching any branch. Resolving design-level conflicts is a human decision.
If only merge: and close: items remain, proceed to Phase 1 with the revised plan.
For each PR in prs, verify:
gh pr view <n> --json reviewDecision returns APPROVEDgh pr checks <n> shows all required checks passingmain (no stale PRs targeting old branches)status:blocked label on linked issueSkip PRs that fail any precondition. Record reason in the report.
Determine merge order using a topological sort:
created_at (oldest first) so the second PR rebases onto the first.created_at order for reproducibility.Output a linear order. Cycles (A blocks B and B blocks A) are an error → escalate.
For each PR in order:
# 1. Fetch latest main
git fetch origin main
git checkout main
git pull --ff-only origin main
# 2. Try to rebase PR branch onto main (without pushing)
git fetch origin pull/<n>/head:pr-<n>-rebase
git checkout pr-<n>-rebase
git rebase main
If rebase succeeds cleanly → proceed to Phase 4 validation, then gh pr merge <n> --squash --rebase --delete-branch.
If rebase has conflicts → enter Phase 4 conflict resolution on the rebase, then:
git push -f origin pr-<n>-rebase:<original-branch>), wait for CI, then merge.git rebase --abort), comment on the PR with the conflict report, skip to next PR.Classify each conflict hunk:
| Class | Signature | Strategy |
|---|---|---|
| Trivial | Whitespace, import order, comment-only diffs | Prefer the PR's side; re-run goimports or equivalent formatter |
| Additive | Both sides add distinct code to the same region (e.g., both add a new case to a switch) | Merge both additions, preserve order by PR created_at |
| Same-intent | Both PRs do the same thing slightly differently (e.g., both fix the same bug) | Prefer the approach that aligns with CLAUDE.md conventions / decisions.md entries. Flag if unclear. |
| Competing-intent | PRs implement overlapping features with incompatible designs | Escalate. Do not silently pick one. |
| Structural | Conflicts span multiple files and involve architectural choices (new package layout, interface changes) | Escalate. |
Before resolving same-intent or competing-intent hunks, consult in this order:
CLAUDE.md — project conventions (e.g., "squash + rebase only", "2-agent first principle")decisions.md — recent architectural decisions with rationaleproject-index.yaml — requirement text for both PRs' linked issues; the resolution must satisfy both AC setsCLAUDE.md — if two resolutions are plausible, pick the one that advances primary targets (requirements coverage, test coverage, build health)Record your reasoning inline in the resolution commit message:
resolve: PR #101 vs PR #102 conflict in cmd/coordinator.go
Context: both PRs modify handleTaskResult. #101 adds tokenized auth check,
#102 adds metrics emission. Changes are orthogonal — merged both.
Design-intent basis: north-star reliability favors both; no competition.
After each successful merge (before proceeding to next PR):
git checkout main
git pull --ff-only origin main
go build ./...
go vet ./...
go test ./... -count=1
If validation fails:
git revert <merge-sha> and push, restoring main to green statestatus:developing to route back through dev-agentOutput a structured report:
## Merge Batch Report — <timestamp>
### Merged (N)
- #101 — clean rebase
- #102 — additive conflict auto-resolved (switch case)
- #104 — trivial conflict (imports)
### Reverted (M)
- #103 — merged then reverted: go test failed in internal/store
(revert SHA: abc123; issue re-opened for developing)
### Escalated / Skipped (K)
- #105 — competing-intent conflict with #101 in internal/launcher/permissions.go:
#101 uses env-var token only; #105 adds keyring fallback.
Design intent unclear — human decision needed. PR left open.
### Validation
- Final main SHA: def456
- go build: ok
- go test: ok (42 packages, 0 failures)
- go vet: ok
gh pr merge --squash --rebase.--delete-branch was specified by GitHub merge (which is fine).Report and exit. Do not attempt to salvage.
Re-rebase remaining PRs against new main. This is safe because main is always green (Phase 5 invariant).
If merging PR A causes failure, then reverting A also breaks (highly unusual):
The original author may have deleted their branch. Fetch via refs/pull/<n>/head (always available on GitHub).
A batch merge succeeded if:
prs is either: merged, reverted-and-re-queued, or escalated-with-reportmain is in a green state (build + test + vet pass) at the endnpx claudepluginhub lincyaw/workbuddy --plugin workbuddyProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.