feat(sync): serialize sync.sh with a per-machine lock; per-session log filenames
Multiple concurrent Claude sessions (and the scheduled-task sync) were stepping on each other's git state. sync.sh now takes an atomic mkdir lock in .git/ around the whole run (stage/commit/fetch/rebase/push + vault), exits 75 (EX_TEMPFAIL = deferred) on contention instead of racing, and reclaims stale/dead-owner locks with a re-verify-before-clear guard (closes two TOCTOU races caught in review). /save now mandates per-session-unique log filenames (never the bare YYYY-MM-DD-session.md). Docs updated for the lock + deferred-exit semantics. Note: git add -A is still the catch-all sweep; full per-session commit isolation and routing /scc + /checkpoint through the lock are follow-ups.
This commit is contained in:
@@ -50,6 +50,8 @@ Invokes `bash .claude/scripts/sync.sh`, which:
|
||||
|
||||
The script is the single source of truth for git operations. Both `/sync` and `/save` invoke it.
|
||||
|
||||
**Concurrency:** the run is serialized by a per-machine lock (`.git/claudetools-sync.lock`) so two syncs (e.g. interactive + the scheduled-task sync, or two Claude sessions) can't interleave staging/commit/rebase/push. If another sync is already running, this run waits up to ~120s then **exits 75 (EX_TEMPFAIL = deferred, not a failure)** — report it as deferred, not synced; the next run catches up. Stale locks (owner process dead, or older than 10 min) are auto-reclaimed.
|
||||
|
||||
---
|
||||
|
||||
## Cross-user note handling (CRITICAL)
|
||||
|
||||
Reference in New Issue
Block a user