claude-code - 💡(How to fix) Fix Process-level "active session in this repo" tracking, with built-in cross-repo + multi-tmux collision guards [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#60672Fetched 2026-05-20 03:52:31
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
labeled ×3

Claude Code has no native concept of "this git repo has another Claude session active right now." The only state shared between sessions is the filesystem itself (git index, HEAD, working tree). As a result, every long-time user who runs more than one Claude session in adjacent contexts (multi-repo workflow, scheduled background agent, parallel tmux panes) eventually hits a collision where one session moves HEAD or stashes work in a repo another session is actively using.

I'm filing this after the third confirmed incident in 16 days. Each time I wrote a new behavioral rule in my project CLAUDE.md to prevent the next instance of that exact shape; each new rule was a band-aid that did not prevent the next collision. Behavioral rules in project config can't compose with arbitrary new agents (background, scheduled, third-party MCP, future-Claude-feature). The primitive needs to live in the platform.

Root Cause

Articulated by me today: "no matter how tempting it is to have multiple windows open with the same repo I spend more time on cleanup even if they intend not to touch each other." The pain is no longer episodic — it's a continuous tax on doing multi-domain work, because every operation in any repo that has even one other session attached carries non-zero collision risk that I have to keep mentally tracked.

Code Example

~/.claude/sessions.lock  (or per-repo .git/.claude-active-session)
  Schema:  {session_id, repo_root, tmux_pane?, started_at, last_seen}
  TTL:     30 min (configurable via setting)

New env exposed to hooks:
  CLAUDE_SESSION_ID         (stable across that session)
  CLAUDE_PRIMARY_REPO       (resolved at boot)
  CLAUDE_OTHER_SESSIONS_IN_PRIMARY_REPO  (JSON list, refreshed on each tool call)

Hook lifecycle:
  - SessionStart: claim the lock for $CLAUDE_PRIMARY_REPO
  - SessionEnd:   release the lock
  - PreToolUse (Bash): inspect $CLAUDE_OTHER_SESSIONS_* before running HEAD-moving git ops

New CLI:
  claude-code locks list                  # show all active locks across all repos
  claude-code locks release <repo>        # admin release (cleanup)
RAW_BUFFERClick to expand / collapse

Summary

Claude Code has no native concept of "this git repo has another Claude session active right now." The only state shared between sessions is the filesystem itself (git index, HEAD, working tree). As a result, every long-time user who runs more than one Claude session in adjacent contexts (multi-repo workflow, scheduled background agent, parallel tmux panes) eventually hits a collision where one session moves HEAD or stashes work in a repo another session is actively using.

I'm filing this after the third confirmed incident in 16 days. Each time I wrote a new behavioral rule in my project CLAUDE.md to prevent the next instance of that exact shape; each new rule was a band-aid that did not prevent the next collision. Behavioral rules in project config can't compose with arbitrary new agents (background, scheduled, third-party MCP, future-Claude-feature). The primitive needs to live in the platform.

Concrete failure modes (all from one user's machine over 16 days)

Incident 1 — 2026-05-03: two interactive tmux sessions, same repo, stash collision

Two tmux sessions (CLEO, CLE_ENG) were both attached to my CLEO repo. Session A had uncommitted edits to cleo_email_analyst.py. Session B opened the same repo in another pane, ran git stash to clear the working tree to checkout a branch, and never restored. Session A's edits appeared lost; recovery required walking the stash list + reflog. The two Claude sessions had no way to know about each other.

Band-aid I shipped: a ~/.claude/CLAUDE.md global rule "one tmux session per repo, period."

Incident 2 — 2026-05-14: cross-repo automation moved HEAD out from under a live session

During a multi-repo rollout, my CLEO session ran git checkout -b feat/cleo-event-emit against the primary working trees of LIT, MLOG, 2026-Budget, and synaptic-systems-growth. All four of those repos had live tmux sessions attached and uncommitted work in progress. My LIT session was on qa/leave-v7-defensive-refutation-2026-05-10; the cross-repo automation switched LIT's HEAD to main while I was mid-edit. Recovery required git reflog on every affected repo.

Band-aid I shipped: a ~/.claude/CLAUDE.md global rule "cross-repo automation must use isolated worktrees under /tmp/" and a local block-main-writes.sh hook extension to refuse cross-repo HEAD-moving ops without a # allow-cross-repo annotation.

Incident 3 — 2026-05-19: continuous operational tax

Articulated by me today: "no matter how tempting it is to have multiple windows open with the same repo I spend more time on cleanup even if they intend not to touch each other." The pain is no longer episodic — it's a continuous tax on doing multi-domain work, because every operation in any repo that has even one other session attached carries non-zero collision risk that I have to keep mentally tracked.

What's missing in the platform

A process-level lock that:

  1. Every Claude session boot CLAIMS a lock on its primary repo. The lock identifies which session it is (whatever stable identifier Claude can expose — session id, tmux pane id, etc.) and a timestamp.
  2. Every HEAD-moving git op CHECKS the lock before executing — both for the current repo (refuse if another session holds the lock) and for any -C <other-repo> / cross-repo target (refuse unless the operator has explicitly acknowledged).
  3. Locks expire on a reasonable TTL (30 min works well for me) so a crashed/forgotten session doesn't hold a lock forever.
  4. Locks are visible — a session can ask "which other sessions are in this repo right now?" and get a real answer instead of a tmux ls heuristic.

This is a ~50-line piece of platform code. I've implemented a local-only version (~/.claude/scripts/repo-session-lock.sh, called from the SessionStart hook + block-main-writes.sh) and it works for my topology. But it doesn't help anyone else, and it can't enforce against agents that don't call into my hooks.

Why the user-layer fix isn't sufficient

  • Background agents (scheduled tasks, MCP servers, CLI invocations from other tools) don't call my SessionStart hook.
  • Future Claude Code features (worktree auto-creation, multi-pane orchestration, etc.) won't know about my user-layer scripts.
  • Every new user has to discover the failure pattern, write their own band-aid, and live with the residual risk.
  • The most ergonomic place to put the lock is at the same layer that knows "I just spawned a Claude session in <dir>" — i.e., the Claude Code launcher itself.

Proposed minimal platform shape

~/.claude/sessions.lock  (or per-repo .git/.claude-active-session)
  Schema:  {session_id, repo_root, tmux_pane?, started_at, last_seen}
  TTL:     30 min (configurable via setting)

New env exposed to hooks:
  CLAUDE_SESSION_ID         (stable across that session)
  CLAUDE_PRIMARY_REPO       (resolved at boot)
  CLAUDE_OTHER_SESSIONS_IN_PRIMARY_REPO  (JSON list, refreshed on each tool call)

Hook lifecycle:
  - SessionStart: claim the lock for $CLAUDE_PRIMARY_REPO
  - SessionEnd:   release the lock
  - PreToolUse (Bash): inspect $CLAUDE_OTHER_SESSIONS_* before running HEAD-moving git ops

New CLI:
  claude-code locks list                  # show all active locks across all repos
  claude-code locks release <repo>        # admin release (cleanup)

The HEAD-mover guard could be the same shape as the existing block-main-writes.sh pattern — Claude Code already supports PreToolUse hooks and the override-annotation pattern works well for legitimate one-shot cross-repo ops.

Documentation references

If it helps to see what a user-layer band-aid looks like, here are the three layers I'm currently maintaining locally:

  • ~/.claude/scripts/check-parallel-tmux.sh — SessionStart sentinel that warns about parallel tmux sessions in the same repo
  • ~/.claude/scripts/repo-session-lock.sh — process-level lock primitive (claim/check/release/list)
  • ~/.claude/scripts/block-main-writes.sh — PreToolUse hook that refuses main-branch mutators AND cross-repo HEAD movers

Happy to share the source if useful as a reference implementation.

Severity / frequency

P1 from a single-user perspective. The blast radius is bounded (it's per-machine, not network-side) but every collision costs 30-90 min of recovery, and the residual mental load between collisions is non-zero.

Acceptance criteria for closing this issue

  1. A stable CLAUDE_SESSION_ID env var available to hooks
  2. A documented mechanism for hooks to ask "which other Claude sessions are in this repo right now?"
  3. Reference documentation for the recommended cross-repo-via-worktree pattern in the official docs (not just user-layer rules)

I do NOT expect Anthropic to ship the full guard policy — most users will be fine without it. But the primitive (session id + cross-session visibility) is what enables every user to write their own guard without inventing the wheel.


Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Process-level "active session in this repo" tracking, with built-in cross-repo + multi-tmux collision guards [1 participants]