Rules files loaded twice when using built-in worktree isolation (.claude/worktrees/)

Resolved 💬 4 comments Opened Apr 14, 2026 by shamliau Closed May 26, 2026

Description

When using Claude Code's built-in worktree isolation (e.g., isolation: "worktree" in Agent tool, or EnterWorktree), the same .claude/rules/*.md files are loaded twice into context — once from the worktree's own .claude/rules/ and once from the parent repo's .claude/rules/ (reachable via directory traversal).

Reproduction

  1. Have a repo with .claude/rules/*.md files (e.g., 5-15 rules files)
  2. Start a Claude Code session that uses worktree isolation (plan mode, or Agent with isolation: "worktree")
  3. Observe the "Loaded" messages — each rules file appears twice:
L  Loaded ../../rules/services-infrastructure.md
L  Loaded ../../rules/testing.md
L  Loaded ../../rules/performance.md
L  Loaded ../../rules/clean-architecture.md
L  Loaded ../../rules/api-contracts.md
L  Loaded .claude/rules/services-infrastructure.md
L  Loaded .claude/rules/testing.md
L  Loaded .claude/rules/performance.md
L  Loaded .claude/rules/clean-architecture.md
L  Loaded .claude/rules/api-contracts.md

Root Cause

Worktrees are created inside .claude/worktrees/<name>/:

repo-root/
  .claude/
    rules/                         ← parent repo's rules (path 1)
    worktrees/
      radiant-conjuring-squirrel/  ← worktree root
        .claude/
          rules/                   ← worktree's own copy (path 2)

Claude Code's rules loader walks up from the working directory looking for .claude/rules/. From the worktree root, it finds:

  1. <worktree>/.claude/rules/*.md — the worktree's checked-out copy
  2. <worktree>/../../rules/*.md — resolves to the parent repo's .claude/rules/ because the worktree lives inside .claude/worktrees/

Both directories contain identical files (same git content), but the loader treats them as separate because the paths differ.

Impact

  • Doubled context window usage for rules. In our case, 5 rules files × ~5-10KB each = ~50-100KB of wasted context per session.
  • For repos with many rules files, this significantly reduces available context for actual work.

Expected Behavior

Each rules file should be loaded exactly once, regardless of worktree placement. Options:

  1. Deduplicate by content hash — skip loading a file if its content matches an already-loaded rules file
  2. Deduplicate by canonical path — resolve symlinks and .. before loading, skip if the canonical path was already loaded
  3. Stop traversal at worktree boundary — don't walk above the worktree root when looking for .claude/ directories

Environment

  • Claude Code CLI (latest)
  • macOS Darwin 24.5.0
  • Git worktrees created by built-in isolation: "worktree" agent parameter

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗