sync-upstream
A fork diverges from its upstream on purpose — renamed things, changed behaviour, dropped files. A merge doesn't know that. It resolves what it can and hands you the rest, and the danger isn't the conflicts it shows you: it's the files it merged cleanly by taking upstream's text back over a divergence you meant to keep.
So this skill has two halves, and the second is the one that earns it: resolve the marked conflicts, then hunt the silent ones.
1. Read the ledger first
The fork's divergences live in a ledger — a file listing each way this repo deliberately differs from upstream. Look for it at .agents/fork-divergences.md, then anywhere CLAUDE.md / AGENTS.md points. Read it before touching a single conflict; it is the primary source for every resolution below.
No ledger? Say so, work from what the diff and CLAUDE.md tell you, and write one at the end — the sweep in step 4 is worthless without it, and the next sync starts blind again.
2. Merge
If a merge is already in progress (git status shows unmerged paths), skip to step 3 — the human ran it themselves.
Otherwise: prefer the repo's own sync script if one exists (scripts/sync-upstream.sh or similar in package.json) — it knows which upstream paths this fork strips. Failing that, git fetch upstream && git merge upstream/main --no-commit --no-ff.
Record the merge base — git merge-base HEAD upstream/main — you need it in step 3.