Sync Main
Rebase a session worktree branch onto the latest origin/main, resolve conflicts with a source-of-truth bias, force-push with leas…
---
name: sync-main
description: Rebase a session worktree branch onto the latest origin/main, resolve conflicts with a source-of-truth bias, force-push with lease, and actualize the linked PR. Use when the operator asks to run /sync-main, rebase or update a branch/worktree onto main, resolve rebase conflicts, force-push a rebased branch, or refresh the linked PR after a rebase.
---
# sync-main
Bring one `agent-quorum` session branch - and its worktree and linked PR - up to
date with `origin/main` by rebasing, resolving conflicts deliberately,
force-pushing with lease, and actualizing the PR. This rewrites history: it is
the history-rewriting counterpart to `/ship`, which only appends commits. Land
any dirty work with `/ship` first; this skill refuses to run on a dirty tree.
Follow `AGENTS.md` and `docs/development/conventions.md`. Use git, `pnpm`, and
`gh` directly. Never push, force-push, or change PR state without showing the
exact irreversible plan first; a plain `/sync-main` is intent to rebase and
force-push the current session branch, but still print the plan before the
force-push and the PR edits.
## Boundaries
- Rebase only. Never merge `main` into the branch, never `git pull`, never
`--abort` an in-progress rebase, and never `git reset --hard` / `git clean`
unless the operator explicitly asks.
- Force-push only with `--force-with-lease`, never a bare `--force`.
- Operate inside the target worktree. Run every git, file, and verify command
there; do not assume a persistent shell working directory between commands -
pass absolute paths or re-enter the worktree each time.
- Preserve the public contract and architecture boundaries while resolving: the
registry is the single source of truth for runner wiring, `core/` does not
spawn provider CLIs, and lower layers do not import higher layers.
- Committed artifacts stay in English. Report resolved absolute paths to the
operator.
## Arguments
```text
/sync-main
/sync-main --worktree <branch|path>
/sync-main --onto <ref> # default: origin/main
/sync-main --dry-run
/sync-main --no-push
/sync-main --no-pr
--dry-run inspects and prints the plan only. --no-push resolves the rebase
but stops before the force-push. --no-pr skips PR actualization. Unknown flags
are not passed through: stop, list the accepted arguments, and ask.
Worktree selection gate
When more than one session worktree may exist, target the right one before
touching a working tree. Follow the shared protocol in
docs/development/worktree-selection-gate.md; it is a silent no-op in a
single-worktree checkout.
- Default: enumerate candidate worktrees and present each with its branch and
path (verbatim), its recorded task description or
(no task description recorded), and an active-edit marker; act only on the operator-selected one. - Unambiguous skip: proceed in place when exactly one non-done candidate exists or the skill runs inside a linked session worktree; the primary checkout is a dispatch context, not a candidate.
--worktree <branch|path>bypasses the menu; match it exactly againstgit worktree list --porcelainand stop on zero or multiple matches.- Handoff: enter the selected worktree and confirm
git rev-parse --show-toplevelequals its path before any action. Reservegit -C <path>for read-only inspection of other candidates. Stop if handoff cannot be confirmed.
Step 0 - Preflight
Resolve, enter, and verify the target worktree, then run every command inside it.
git rev-parse --show-toplevel
git branch --show-current
git status --short --branch --untracked-files=all
- The branch should be a
session/*branch. Confirm with the operator before rebasing any other branch, and never rebasemainitself. - The working tree must be clean. If it is dirty, stop and tell the operator to
/shipor stash the changes first; do not rebase a dirty tree. - If a rebase is already in progress, do not start a new one - resume the conflict loop in Step 3:
test -d "$(git rev-parse --git-path rebase-merge)" && echo IN_PROGRESS || echo CLEAN
Fetch the base and measure divergence:
git remote get-url origin
git fetch origin --tags
git rev-parse origin/main
git rev-list --left-right --count HEAD...origin/main # left = ahead, right = behind
git log --oneline origin/main..HEAD # commits to replay
If behind is 0 the branch is already current: report it, skip Steps 1-5, and
go to the PR step if asked. Optionally reuse conflict resolutions across the
per-commit replay:
git config rerere.enabled true
Step 1 - Plan
Print the plan and stop in --dry-run. Otherwise proceed; pause for explicit
confirmation only before the force-push (Step 5) and the PR edits (Step 6).
WORKTREE <branch> @ <path>
ONTO origin/main @ <sha>
REPLAY <n> commit(s): <oneline list>
DIVERGENCE ahead <a> / behind <b>
PUSH force-with-lease | skipped (--no-push)
PR actualize #<n> | none | skipped (--no-pr)
Step 2 - Rebase
GIT_EDITOR=true git rebase origin/main # default
GIT_EDITOR=true git rebase <onto-ref> # when --onto <ref> was given
GIT_EDITOR=true keeps --continue non-interactive by reusing each commit
message. If git applies the commits cleanly, go to Step 4. If it stops on
conflicts, run Step 3 for the stopped commit, then continue; repeat until the
rebase completes. The second session commit can apply cleanly even when the
first conflicted - do not assume every commit conflicts.
Step 3 - Conflict resolution loop
Resolve each stopped commit with this playbook, then
GIT_EDITOR=true git rebase --continue. The goal is a working tree, not just
the absence of markers: never accept a merge that silently drops either side's
behavior.
Understand the sides first. During a rebase, HEAD / "ours" is the new base
plus the commits already replayed; "theirs" (the >>>>>>> side, labeled with
the commit being
```
Maintain Sync Main?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Sync Main on getagentictools](https://getagentictools.com/loops/eventbalancer-sync-main?ref=badge)