refactor(sync): share the sync lock with /scc and /checkpoint
Extract the per-machine concurrency lock from sync.sh into a sourceable
lib (.claude/scripts/sync-lock.sh) plus a `run <cmd>` wrapper that locks
the current repo (same lock-dir basename, so it mutually excludes with
sync.sh in the ClaudeTools repo and self-scopes in any project repo).
sync.sh now sources it (behavior identical — verified by review). /scc
routes its commit+push through the locked, rebase-safe sync.sh (and drops
the bare YYYY-MM-DD-session.md filename for the per-session-unique one).
/checkpoint now stages+commits atomically under the repo lock so a
concurrent session in a shared worktree can't be swept in. Closes the
remaining commit paths that bypassed the lock shipped in a85c2cc.
This commit is contained in:
@@ -14,11 +14,10 @@ Please create a comprehensive git checkpoint with the following steps:
|
||||
- Run `git diff` to see detailed changes in tracked files
|
||||
- Run `git log -5 --oneline` to understand the commit message style of this repository
|
||||
|
||||
3. **Stage everything**:
|
||||
3. **Decide what will be staged** (do NOT stage yet):
|
||||
|
||||
- Add ALL tracked changes (modified and deleted files)
|
||||
- Add ALL untracked files (new files)
|
||||
- Use `git add -A` or `git add .` to stage everything
|
||||
- Identify all tracked changes (modified/deleted) and untracked (new) files via `git status`.
|
||||
- Staging is done **atomically with the commit, under the repo lock, in step 5** — do not run a separate `git add` here. This prevents a concurrent session in a shared worktree (e.g. ClaudeTools) from having its dirty files swept into this checkpoint.
|
||||
|
||||
4. **Draft commit message body via Ollama** (documentation engine):
|
||||
|
||||
@@ -49,7 +48,17 @@ print(res['message']['content'])
|
||||
- **Body**: Ollama draft (Claude reviews); Claude writes directly if Ollama unavailable
|
||||
- **Footer**: `Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>`
|
||||
|
||||
5. **Execute the commit**: Create the commit with the properly formatted message following this repository's conventions.
|
||||
5. **Execute the commit (locked)**: Write the final message (summary line + body + footer) to a temp file, then stage + commit **atomically under the repo's commit lock** so concurrent sessions can't interleave or get swept in:
|
||||
|
||||
```bash
|
||||
# MSG = path to the composed commit-message file; LOCK = the shared lock wrapper
|
||||
LOCK="${CLAUDETOOLS_ROOT:-/d/claudetools}/.claude/scripts/sync-lock.sh"
|
||||
bash "$LOCK" run bash -c 'git add -A && git commit -F "$1"' _ "$MSG"
|
||||
```
|
||||
- The lock is scoped to the **current repo** (`git rev-parse --show-toplevel`/.git), so this serializes correctly whether the checkpoint is in ClaudeTools (shares the same lock as `/sync` and `/scc`) or in a project repo (its own lock). The wrapper errors out (exit 2) if you're not in a git repo.
|
||||
- If it **exits 75**, another commit/sync holds the lock — wait briefly and retry, or report "checkpoint deferred".
|
||||
- This is a **local commit only** (no push), matching checkpoint's purpose.
|
||||
- `$CLAUDETOOLS_ROOT` should be set per-machine; the `/d/claudetools` fallback is for this box only — on Mac/Linux it resolves from the env var.
|
||||
|
||||
## Part 2: Verify Git Checkpoint
|
||||
|
||||
|
||||
@@ -6,24 +6,17 @@ Quick command to save session log, stage everything, and push to Gitea in one sh
|
||||
|
||||
1. **Save session log** - Create/update session log for today using the /save skill logic:
|
||||
- Determine correct location based on work context (project-specific or general `session-logs/`)
|
||||
- Use format `YYYY-MM-DD-session.md`
|
||||
- If file exists, append with `## Update: HH:MM` header
|
||||
- **Per-session-unique filename (mandatory)** — concurrent sessions share this worktree, so never use the bare `YYYY-MM-DD-session.md`. Use `YYYY-MM-DD-<user>-<topic>.md`; collision-guard + same-session-append rules are in `/save` (`save.md`).
|
||||
- Include: summary, credentials (unredacted), infrastructure, commands, files changed, pending tasks
|
||||
|
||||
2. **Stage all changes** - Run `git add -A` to stage everything including the new session log
|
||||
2. **Commit + push (locked, rebase-safe)** - Run `bash .claude/scripts/sync.sh`. This is the single serialized git path: it takes the per-machine sync lock (so it can't interleave with another session's sync/commit), reconciles git identity to `identity.json`, stages changes, commits, fetch + rebase, pushes — ClaudeTools then vault.
|
||||
- **Do NOT** run raw `git add -A` / `git commit` / `git push origin main` here — that bypasses the lock AND the fetch+rebase (the old flow raced and would reject on a stale push).
|
||||
- If `sync.sh` **exits 75**, another sync is in progress: report "sync deferred — your log is saved locally and will sync on the next run"; do not claim pushed.
|
||||
- Note: the discrete `scc:`-prefixed message is dropped in favour of one locked git path (commit lands under `sync.sh`'s auto message). If a custom message matters, revisit later (e.g. a `-m` arg on `sync.sh`).
|
||||
|
||||
3. **Commit** - Auto-commit with message:
|
||||
```
|
||||
scc: Session save and push from [hostname] at [timestamp]
|
||||
3. **Report** - Confirm what was saved, committed, and pushed (or deferred)
|
||||
|
||||
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
||||
```
|
||||
|
||||
4. **Push to Gitea** - Run `git push origin main`
|
||||
|
||||
5. **Report** - Confirm what was saved, committed, and pushed
|
||||
|
||||
6. **Reaffirm roles** - After push, briefly restate:
|
||||
4. **Reaffirm roles** - After push, briefly restate:
|
||||
- You are a COORDINATOR, not an executor
|
||||
- Delegate: DB -> Database Agent, code -> Coding Agent, git -> Gitea Agent, tests -> Testing Agent
|
||||
- Do yourself: simple responses, reading 1-2 files, planning, decisions
|
||||
|
||||
Reference in New Issue
Block a user