| name | syncwheel |
| description | Use Syncwheel for deterministic, multi-agent-safe Git maintenance — PR branches, dedicated worktrees, stacked PRs, and integration branches. Use whenever you are about to create a PR branch, manage a fork/upstream/integration or PR-stack workflow, prepare or rebuild a stacked PR, or coordinate Git work on a repo that other people or agents may touch concurrently or that contains a `.syncwheel/` directory. Also covers the decision of whether to commit the Syncwheel manifest (own repo) or keep it untracked (external contribution). |
| allowed-tools | ["Bash"] |
Syncwheel
Syncwheel makes Git maintenance deterministic and safe when many agents touch the
same repositories. Branch ownership, PR stacks, and the integration branch are
described in a manifest; Syncwheel reconciles Git to match it. Plain manual
git/worktree surgery is the exception path, used only when Syncwheel is
unavailable, blocked, or cannot express the needed recovery.
When to use (Syncwheel-first)
First, detect the regime. Before branch, worktree, integration, PR, recovery,
or handoff work in any Git repo, check whether it is Syncwheel-managed: a
.syncwheel/ directory or manifest is present, or a workspace/project guide says
so. When unsure, run syncwheel status. If it is managed — or the repo is shared,
fork/upstream, or touched by multiple agents — it is Syncwheel-first: do not reach
for manual git branch/worktree/integration surgery as the default path.
Reach for Syncwheel before any of these, not after:
- editing or handing off work in a Git repository that is shared, managed by
Syncwheel, or likely to be touched by multiple agents
- creating a PR branch or a stack of dependent PRs
- working in a repo that has a
.syncwheel/ manifest, or a
fork/upstream/integration/PR-stack workflow
- preparing changes in a dedicated worktree
- rebuilding or pushing PR branches / integration
- coordinating with other agents who may rebase the same branches
If the task involves a Git repo that has shared coordination risk, prefer
Syncwheel even when the visible edit is small. A local file change is not a
complete handoff by itself: before final response, report the Git state, required
checks, and the commit/push/PR decision or the explicit reason delivery remains
local.
The contract
The script owns: repo-state discovery, manifest validation, deterministic branch
and integration reconstruction. The agent owns: judgment, communication,
project-specific validation after a rebuild, and safe execution.
Locate the CLI
Syncwheel is available as the PATH syncwheel command. Install it with:
uv tool install "git+https://github.com/NestDevLab/syncwheel"
uv tool install --editable <local-clone>
syncwheel self update
If Agentwheel is available, install this skill into the local Codex runtime for
the target repo:
agentwheel install github:NestDevLab/syncwheel --adapter codex --local --target-root <repo> --skill syncwheel
syncwheel self status
If the PATH binary is not available (legacy host or vendored install), fall back to the checkout pointer:
SW="python3 ${SYNCWHEEL_REPO:?set SYNCWHEEL_REPO to the syncwheel checkout}/scripts/syncwheel.py"
$SW --version
$SW self status
Always run Syncwheel against the target repo: pass -r <repo-path-or-alias>
or run from inside the target repo's worktree.
Safe lifecycle (always dry-run first)
syncwheel status --fetch
syncwheel validate
syncwheel plan --json
syncwheel reconcile
syncwheel reconcile --apply --worktree-root <path>
syncwheel reconcile --apply --worktree-root <path> --push
syncwheel check
Short aliases are preferred when they make commands easier to scan:
syncwheel status -f -j
syncwheel plan -j
syncwheel reconcile -a -W .syncwheel/wt
syncwheel reconcile -a -P -W .syncwheel/wt
syncwheel repo tracking set git-tracked -a
syncwheel spoke ... is a readable alias for syncwheel stack ... when the
wheel metaphor helps, but the manifest field remains stacks.
Never mutate branches from a dirty worktree. Prefer a dedicated worktree for
every rebuild. Use --dry-run on rebuild/push commands. If the manifest and Git
disagree, fix the manifest or call out the conflict — do not claim a repo is
aligned while integration and PR branches still differ.
⚠️ Rebuilds can silently revert already-applied work. A stack rebuild /
int rebuild reconstructs the branch from the manifest's commit projection,
not from the branch's current remote tip. If the manifest points at a
pre-cleanup commit (or a range that misses a later fix), the rebuild force-pushes
the branch back to that older state and the cleanup/fix disappears — a real
regression mode (observed in practice: a cleaned-up file came back after a rebuild
off a stale projection). Always: before rebuilding, update the manifest with
syncwheel stack set <id> <rev-or-range> so the projection includes the latest commit;
and after every rebuild/sync/publish, diff the rebuilt branch against the expected
post-fix state to confirm earlier cleanups did not regress.
Authoring a new PR stack
syncwheel init
syncwheel repo tracking status
syncwheel repo tracking set git-tracked --apply
syncwheel stack create feature-a --branch pr/feature-a --base origin/main -u
git worktree add -b pr/feature-a ../repo-wt-feature-a origin/main
syncwheel stack set feature-a origin/main..HEAD
syncwheel validate && syncwheel plan --json
syncwheel stack push feature-a
-u is the short form of --include-in-integration.
Delivery lifecycle
Feature stacks are delivered through PRs into the intended delivery branch for
that repo or fork. That target may be main, an upstream/default branch, or a
release branch, but it must not be main-integration.
main-integration is a coordination branch for assembling and testing stacks
before delivery. Do not treat it as a PR target or deployment branch.
After the PR merges, fetch the remote and confirm the stack's content landed in
the delivery branch — by SHA, or, for a squash/rebase merge, by an empty
git diff <delivery_ref> <branch>. Align or rebuild main-integration from the
updated base, then run the housekeeping below to close the stack and reap its
worktree and branch.
Housekeeping: when and how to clean up
Worktrees, PR branches, and backup/* branches do not reap themselves — close the
loop or they accumulate. Clean up when any of these holds:
- a stack's PR has merged
syncwheel status shows a worktree or local branch not backing an active
manifest stack (orphans — common after an integration-scheme change)
backup/* branches have piled up
- before handing off a managed repo: leave only the active stacks' worktrees plus
the integration worktree
Procedure (never destroy unmerged or uncommitted work):
git fetch --all --prune
git diff --quiet <delivery_ref> <branch> && echo "content merged"
git worktree remove <worktree-path>
syncwheel stack close <id> -R merged --force
git branch -d <branch>
git worktree prune
Prune backup/* branches that are no longer a useful safety net, keeping the one
or two most recent. Never delete a branch that still carries unique unmerged
commits, and never force-remove a worktree with uncommitted or conflicted changes
— report it instead.
Decision: Syncwheel tracking policy
This is a repo-local Syncwheel policy, not a social guess. Before editing in,
branching, pushing, opening a PR for, recovering, or handing off a shared or
Syncwheel-managed Git repo, run:
syncwheel repo tracking status
If syncwheel_tracking is missing, stop before branch, push, PR, stack,
worktree, recovery work, or final handoff. Do not guess, do not default
silently, and do not continue with a provisional policy. Ask the maintainer/user
whether this repo should be git-tracked or local-only, then persist the
answer:
syncwheel repo tracking set git-tracked --apply
syncwheel repo tracking set local-only --apply
git-tracked → commit the manifest
Commit .syncwheel/manifest.json (and .syncwheel/manifests/README.md). Keep
personal overlays (*.local.json, profile.local.json) gitignored.
Benefits:
- the stack/integration topology is versioned and shared — every agent that
clones inherits the same deterministic plan
- reproducible across machines without out-of-band setup
- the manifest is the team's coordination contract
Use this when the repo wants Syncwheel itself tracked under Git. Syncwheel writes
a managed .gitignore block for local-only metadata and repo-local worktrees
under .syncwheel/wt/.
local-only → keep Syncwheel untracked
Exclude .syncwheel/ via .git/info/exclude (local, does
not touch the committed .gitignore).
Benefits:
- you still get worktree isolation, stacks, deterministic reconcile, and the
ledger
- you do not impose Syncwheel config on a maintainer who may not use it
- your PRs stay clean — only the real change is proposed
- coordination/recovery happens via the canonical remote +
resume
Use syncwheel repo tracking set ... --apply to migrate between modes. The CLI
edits only Syncwheel-managed ignore blocks; if manual .gitignore entries would
hide .syncwheel/manifest.json, stop and ask for a repository decision.
Handoff checklist
Before final response after touching a Git repo:
- run
git status --short --branch and state whether the worktree is clean,
intentionally dirty, or blocked
- run the repo's required validation, or name the exact validation not run and why
- for
git-tracked repos, commit and push the scoped work unless the user or
repository policy explicitly requires local-only delivery
- treat Syncwheel manifest changes from stack create/set/close or integration bookkeeping as
scoped work: commit and push them before handoff, or explicitly report the approved reason they remain local
- if the user asked to synchronize a repo with outstanding PRs/upstreams, fetch/prune first, inspect open PR heads, and verify each intended PR by both ancestry and diff:
git merge-base --is-ancestor <head> <base> and git diff --quiet <base>...<head>. If you integrate PR heads directly into main and push, re-query GitHub; GitHub may auto-mark those PRs merged once the base contains their head.
- when applying stashed local work after PR synchronization, expect fixture-only conflicts. Resolve by preserving the synchronized upstream behavior and reapplying only the scoped new feature/logging changes; then rerun tests before committing.
- if the user requested local-only edits, list the dirty files and the next
command/decision needed to finish delivery
- never treat unrelated dirty files as a reason to skip this checklist; isolate
your own changes and report unrelated residue separately
Manifest self-reference rule: treat manifest edits and Syncwheel-version
bumps as control-plane metadata, not as normal stack-owned product commits.
Keep them in an admin checkout or a dedicated maintenance PR that is excluded
from integration.stacks.
Multi-agent / multi-machine
A shared, committed manifest plus the append-only ledger is what lets many agents
coordinate deterministically. On a fresh machine or a new agent, recover shared
state with syncwheel resume instead of improvising branch ownership.
More
See docs/manifest-tracking.md for the full tracking policy, docs/ai-agents.md
and docs/agent-procedure.md for the agent contract, and docs/core-procedure.md
for the canonical recovery procedure. An automated post-merge cleanup path is
specified in docs/design/housekeeping-after-merge.md.