git-coworker-check

v2026.09.24

Detect coworker Claude agents in a shared checkout. Use when starting a session in a shared clone, before destructive git ops (stash, reset, checkout), or before bulk-edit / commit-loop workflows.

GitHub
安装命令
npx skhub add laurigates/git-coworker-check
Markdown
SKILL.md

/git:coworker-check

Detect another agent working in the same repo clone and warn before destructive operations that could destroy its uncommitted changes.

When to Use This Skill

Use this skill when...Use a worktree instead when...
Session starts in a clone that may already be in useYou control the session and can create git worktree add ../<task>
About to run git stash, git reset --hard, git checkout -- .You already know the working tree is yours alone
git status shows files you don't remember touchingBaseline + markers are already confirming you are alone
Bulk-edit / commit-loop fan-out about to start (per-plugin, per-package commits across many subdirectories)Each iteration is already isolated in its own worktree
A collision already happened and you need to recoverSee REFERENCE.md — Recovery section

See .claude/rules/agent-coworker-detection.md for the full rationale and signal design.

Bulk-edit / commit-loop precondition

Bulk-edit and commit-loop workflows (git-commit-workflow "Bulk-edit / per-plugin commit loops", per-package release-please loops, mass refactors) MUST run this check up front, before staging any files — not opportunistically partway through.

Why front-loaded, not opportunistic. A real divergence scenario from the field: two Claude sessions converged on the same trim-descriptions task. Session A used general-purpose subagents in the main checkout; session B used worktrees + per-plugin commits. Session B landed 11 clean per-plugin commits and stopped. Session A's first commit then grabbed all 30 remaining plugins in a single mega-commit, because session A had previously hit a git commit -a failure that left everything pre-staged, and session B's loop never noticed because it ran /git:coworker-check during its work rather than before. The end result was correct, but the commit history said docs(configure-plugin): ... for changes spanning 30 plugins.

The rule: the orchestrator stops before fan-out if the playing field is contended. Mid-loop checks let "the agent who happens to look first wins" — which is non-deterministic and produces misleading commit histories.

Verdict from up-front checkWhat to do
clearProceed with the bulk-edit / commit loop
drift_detectedInspect the new files. If they are yours from earlier in the session, proceed with explicit paths. If unknown, stop and ask.
worktree_leak_suspectedA child worktree-isolated agent is leaking an untracked file into the parent (issue #1319). Do not stage or stash the matching path. Wait for the child's commit, then re-run the check before continuing.
bare_flip_suspectedThe shared checkout was flipped to core.bare=true, or a leaked GIT_DIR / GIT_WORK_TREE env points away from the repo (issue #1692). Stop and recover before any further git ops — see the Recovery section. Do not start the loop.
coworker_detectedStop. Recommend git worktree add ../<repo>-<task> for a fresh isolated checkout, or wait for the other session to finish. Do not start the loop.

Worked example: detection enables defensive restoration (#1277)

A second positive scenario from the field — the "stop and inspect" rather than "stop and abort" branch. A description-trimming refactor agent ran in a checkout that already had ~7 active claude processes touching the same files. The coworker_detected verdict fired off the process-scan signal alone (the ps-based fallback, well before any taskwarrior coordination existed for this batch). Per the verdict-to-action table above, the agent did not stash or reset; it scoped its pass to the remaining 17 files and inspected the coworker's already-landed edits before writing.

That inspection caught a real regression: in git-fork-workflow, the coworker had cut the description from 358 → 240 chars and dropped the sibling cross-reference For creating upstream PRs, see git-upstream-pr. The agent re-added the line on its own pass. Eight other skills had a stale modified: date for the same reason and were stamped forward. No work was lost; a silent cross-reference regression became an explicit recovery. Evidence: issue #1277.

Context

  • Repo root: !git rev-parse --show-toplevel
  • Git dir: !git rev-parse --git-dir
  • Current status: !git status --porcelain=v2 --branch
  • Stash count: !git stash list
  • Existing markers: !find . -path './.git/.claude-session-*' -maxdepth 3

Parameters

Parse $ARGUMENTS for the mode flag. Default is --check.

FlagAction
--check (default)Run detection. Report verdict without writing anything.
--claimWrite a session marker and baseline snapshot for this session. Run at session start.
--releaseRemove this session's marker and baseline files. Run on session exit.

Execution

Execute this detection workflow:

Step 1: Resolve mode

Inspect $ARGUMENTS. If it contains --claim, go to Step 2a. If it contains --release, go to Step 2b. Otherwise (including empty), go to Step 3.

Step 2a: Claim (write marker + baseline)

Run:

bash ${CLAUDE_SKILL_DIR}/scripts/claim-session.sh --project-dir "$(pwd)"

Report the three file paths printed. These are the marker and baseline files — do not commit or delete them. They live inside .git/ and are not tracked.

Stop here.

Step 2b: Release (remove marker + baseline)

Run:

bash ${CLAUDE_SKILL_DIR}/scripts/release-session.sh --project-dir "$(pwd)"

No output is expected. Stop here.

Step 3: Detect coworkers

Look up the current session's baseline files (if --claim was run earlier this session). Then run detection. Pass --self-agent claude-${CLAUDE_SESSION_ID:0:8} so taskwarrior claims by this same session are reported as OWN_CLAIM_* rather than counted as coworkers:

bash ${CLAUDE_SKILL_DIR}/scripts/detect-coworkers.sh \
  --project-dir "$(pwd)" \
  --self-agent claude-${CLAUDE_SESSION_ID:0:8} \
  --baseline-status .git/.claude-baseline-$$.status \
  --baseline-stash .git/.claude-baseline-$$.stash

If no --claim was run, omit the --baseline-* flags — drift detection will return unknown but marker, process, and taskwarrior signals still work.

The taskwarrior signal is best-effort: when task or jq is not on PATH, the script reports TW_SCAN_METHOD=unavailable and the verdict falls back to the three git-side signals.

Step 4: Interpret the verdict

Parse the VERDICT= line from the script's output:

VerdictMeaningAction
clearNo coworker detectedProceed; still prefer explicit git add <paths> over git add -A
drift_detectedFiles appeared since baseline but no other process/marker/claim foundInspect NEW_STATUS_LINES — may be coworker or may be a forgotten earlier edit. Ask the user before stashing.
worktree_leak_suspectedUntracked file in parent matches a path held by a linked worktree (issue #1319)Do not stash or commit the matching path. Wait for the child worktree's commit to reclaim it. Avoid committing on the parent branch until child agents are done.
bare_flip_suspectedCORE_BARE=true on a shared working checkout, or a LEAKED_GIT_DIR / LEAKED_GIT_WORK_TREE env points away from the repo (issue #1692)Stop and recover. Flip core.bare back to false and/or unset the leaked env before any further git ops — see the Recovery section below. Recover any wiped untracked work from the reflog / agent worktree branches.
coworker_detectedAnother agent/process/taskwarrior claim is active in this cloneDo not stash, restore, or reset. Report the MARKER_PID / PROC_PID / TW_CLAIM_* entries. Recommend the user switch to a worktree.

The six signals are independent — any one of MARKER_COUNT > 0, PROC_COUNT > 0, or TW_CLAIM_COUNT > 0 raises coworker_detected. A non-zero WORKTREE_LEAK_COUNT on its own raises worktree_leak_suspected, and a non-zero BARE_FLIP_COUNT raises bare_flip_suspected (ranked first, since a bare flip breaks git for every linked worktree). OWN_CLAIM_* lines are this session's own taskwarrior claims and do not contribute to the count.

Step 5: Report findings

Print a short summary:

  1. Verdict
  2. Count of markers + processes + drift entries
  3. If non-clear, the specific PIDs or changed files
  4. Recommended next action (worktree, ask user, proceed with explicit paths)

Post-actions

  • On drift_detected or coworker_detected: do not run git stash, git reset --hard, git checkout -- ., or git clean in this session. Stage only explicit paths.
  • Suggest the user run git worktree add ../$(basename $(git rev-parse --show-toplevel))-<task> for a clean isolated checkout.

Integration

Other git-plugin skills should invoke this via SlashCommand before destructive operations or fan-out:

Before staging (or before starting a per-plugin commit loop):
Use SlashCommand to invoke `/git:coworker-check`.
If the verdict is not `clear`, stop and ask the user how to proceed.

Bulk-edit / commit-loop skills (git-commit-workflow, per-plugin release-please loops, mass refactors) must invoke this before staging any files — see the "Bulk-edit / commit-loop precondition" section above for why an opportunistic mid-loop check is insufficient.

Hook-based enforcement (blocking git stash / git reset --hard when a coworker is detected) belongs in hooks-plugin, not here.

Agentic Optimizations

ContextCommand
Cheapest detection (no baseline)bash scripts/detect-coworkers.sh --project-dir "$(pwd)"
Full detection with driftAdd --baseline-status + --baseline-stash from a --claim run
One-line verdict check... | awk -F= '/^VERDICT=/ {print $2}'

Recovery

Detection prevents corruption. When prevention fails — a coworker session moved HEAD between your steps, your commit landed on the wrong branch, your branch accumulated commits you didn't make — see REFERENCE.md for procedural recovery.

Quick triage:

SymptomAction
Your commit is on a branch you didn't expectREFERENCE.md § Scenario 1 (mixed-reset + git branch -f + cherry-pick)
About to git push -u a new branch, or it holds a commit you didn't authorREFERENCE.md § Shared-checkout branch isolation (origin/main..HEAD check; git branch -a --contains before any rewrite)
git switch carried unfamiliar WIP into the new branchREFERENCE.md § Scenario 2 (selective git checkout HEAD -- <paths>)
git stash list is shorter than you rememberREFERENCE.md § Scenario 3 (recover via git fsck --unreachable)
You force-pushed the polluted branch alreadyREFERENCE.md § Scenario 4 (only --force-with-lease mitigations)
Every git status/commit fails with "fatal: this operation must be run in a work tree"Bare-flip recovery below (core.bare false + unset leaked env)

Always run git reflog -20 first. The reflog is the ground truth for every HEAD move and ref update during the collision window — recovery procedures all begin from a clear reflog read.

Recovering from a bare flip / leaked GIT_DIR (issue #1692)

When detection returns bare_flip_suspected, the shared checkout was flipped to core.bare=true (or a GIT_DIR / GIT_WORK_TREE env was leaked) by a concurrent agent fleet. Recover before any further git ops:

  1. Flip core.bare back to false so the working tree is usable again:

    git config core.bare false
    

    If even git config refuses, drive it explicitly with the recovery override the issue used (note -c core.bare=false plus an explicit GIT_DIR/GIT_WORK_TREE):

    GIT_DIR=.git GIT_WORK_TREE=. git -c core.bare=false status
    
  2. Unset any leaked env reported as LEAKED_GIT_DIR / LEAKED_GIT_WORK_TREE so git stops targeting another tree:

    unset GIT_DIR GIT_WORK_TREE
    
  3. Recover wiped untracked work. A concurrent branch switch / reset can silently delete uncommitted, untracked files. Untracked files are not in the reflog, so check first for any copy a sibling agent committed — git fsck --unreachable and the agent worktree branches are the best source:

    git reflog -20
    git fsck --unreachable
    git worktree list
    git branch -a
    

    A file an agent worktree committed survives on its branch even when the parent's untracked copy was wiped. If no committed copy exists, the work is unrecoverable — which is why committing early matters.

Commit early to minimize untracked-file exposure

Untracked files are the only work a concurrent branch switch/reset can destroy with no recovery path (committed work survives in the reflog; untracked work does not). When many sibling worktrees are active in one clone — high LINKED_WORKTREE_COUNT, or a coworker_detected / bare_flip_suspected verdict — commit or stash new files promptly rather than leaving them untracked, and prefer working in your own git worktree add ../<repo>-<task> so a flip in the shared checkout cannot reach your tree.

Related Skills

  • /git:maintain — invokes this before any stash/clean operation
  • /git:commit — invokes this before staging when working in a shared checkout
  • git-commit-workflow — invokes this as a precondition for bulk-edit / per-plugin commit loops
  • git-branch-pr-workflow — recommends worktrees as the structural fix
  • /taskwarrior:task-claim — sister signal; writes the +ACTIVE claim that this skill now reads
  • /taskwarrior:task-release — drops the claim that contributes to TW_CLAIM_COUNT
发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

Sep 24, 2026

分类

未分类

许可证

MIT

源路径

git-plugin/skills/git-coworker-check

默认分支

main

最新提交

1668324

Tree SHA

b2d4cc3