Skip to content

DomVinyard/sync-guard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sync-guard

A Claude Code plugin that catches the multi-agent stale-write race at git push time — the failure mode where two sessions both push to the same branch, one's git pull --rebase succeeds cleanly, but the file contents it writes are stale from before the other session's push landed. Git sees no conflict. The push lands. Work silently regresses.

No published tool catches this. Worktrees, branch protection, file leases, and merge queues all miss it — they solve filesystem isolation, concurrent writes, or test-detectable regressions. This catches the content-staleness case directly.

What it does

Installs a pre-push git hook into whatever repo Claude Code is running in. On every push to a protected branch (default main):

  1. Tier 1 (exact-blob revert). For each file changed, hash the new content. Walk back 20 commits on the protected branch. If the new content matches any non-current historical blob → refuse the push. Near-zero false positives.

  2. Tier 2 (line-overlap revert). For each file, count lines being removed by the push and lines added to that file on the branch in the last 6 hours. If the overlap is ≥ 60% of the recently-added lines → refuse.

Either check firing prints a clear diagnostic naming the files and the suspected past state.

Bypass mechanisms:

  • git push --no-verify — standard git escape hatch.
  • Commit message starting with Revert: or Revert " — skip the check (deliberate revert).

Tunable via the plugin's configSchema:

  • SYNC_GUARD_PROTECTED_BRANCH (default main)
  • SYNC_GUARD_WINDOW_HOURS (default 6)
  • SYNC_GUARD_THRESHOLD_PCT (default 60)
  • SYNC_GUARD_SKIP_PATTERNS (default: common dependency lockfiles)

What ships

sync-guard/
├── .claude-plugin/
│   ├── plugin.json              # plugin manifest with tunable configSchema
│   └── marketplace.json         # community-marketplace submission metadata
├── hooks/
│   ├── hooks.json               # wires SessionStart → install.sh
│   └── session-start.sh         # idempotently installs lib/pre-push.sh into the active repo
├── lib/
│   └── pre-push.sh              # the two-tier detector
├── skills/
│   └── multi-agent-git/
│       └── SKILL.md             # auto-loaded discipline rules for agents
├── README.md
└── LICENSE

The bundled skill (multi-agent-git) is auto-loaded by Claude Code in any session where the plugin is active. It teaches the agent the in-session half of the defense — Edit-not-Write for existing files, re-Read after rebase, and how to respond when the hook fires.

Installation

Via Claude Code marketplace (recommended once published)

/plugin marketplace add DomVinyard/sync-guard
/plugin install sync-guard

Manual (for development)

Clone the repo and symlink it under .claude/plugins/ in your project, or copy to ~/.claude/plugins/sync-guard/ for user-level install:

git clone https://github.com/DomVinyard/sync-guard ~/.claude/plugins/sync-guard

Then start (or restart) any Claude Code session in a git repo. The SessionStart hook copies lib/pre-push.sh into that repo's .git/hooks/pre-push (idempotent, won't overwrite an existing hook unless it carries the sync-guard signature).

How it handles edge cases

  • Existing pre-push hooks: if .git/hooks/pre-push exists and isn't tagged with the sync-guard signature line, the installer leaves it alone and prints a one-line notice. You can manually compose the two hooks if needed.
  • Offline / fetch failures: if git fetch fails, the hook passes through with a notice rather than blocking. Offline pushes shouldn't be blocked.
  • Non-protected branches: only the branch named in SYNC_GUARD_PROTECTED_BRANCH is inspected. Feature-branch pushes go through unconditionally.
  • Binary files: skipped automatically (binary diffs aren't comparable line-by-line).
  • Lockfiles: the default skip pattern matches the common ones across pnpm, npm, yarn, bun, cargo, gem, composer, poetry, uv, and go. Extend SYNC_GUARD_SKIP_PATTERNS for project-specific generated files.
  • Renames: treated as add + delete in v1. Tier 1 may miss them. The in-session Edit rule covers most cases.

Why this exists

Logged on 2026-05-20: in a session on DomVinyard/dom.vin, a parallel Claude-on-the-Web session Write-overwrote two files using pre-merge content held in its context, silently undoing two recently-merged PRs. The push was a clean fast-forward. The regression deployed to production. After researching the space, no existing tool catches this failure mode at push time. This plugin closes that gap.

License

MIT. See LICENSE.

About

Claude Code plugin: pre-push detector for silent stale-write reverts on main — the multi-agent race no other tool catches.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages