CLAUDE.md Productivity Stack: Skills, Git Worktrees, and Hooks for Parallel Development

The single most important file in any Claude Code project is CLAUDE.md - a persistent instruction set that loads every session and shapes how the agent reads, writes, and verifies code. But CLAUDE.md alone is not what separates productive setups from fragile ones. The real productivity stack in 2026 combines CLAUDE.md conventions with on-demand skills, deterministic hooks, and git worktree isolation for running 10-15 parallel sessions against a single repository. Each session is scoped to one task, operating in its own branch, turning a solo developer into a small engineering team.
What follows covers each layer of that stack - what goes in CLAUDE.md, how skills extend it without bloating context, why hooks beat advisory rules for non-negotiable behaviors, and how worktrees make parallel sessions practical.
CLAUDE.md Anatomy - What Goes In, What Stays Out
Most teams either leave CLAUDE.md empty or bloat it into a novel. Both approaches fail for the same reason: the instruction budget is real. Frontier LLMs follow roughly 150-200 individual instructions with reasonable consistency. Claude Code’s own system prompt consumes about 50 of those. That leaves you with approximately 100-150 instructions before compliance starts dropping off. Boris Cherny, Claude Code’s creator at Anthropic, keeps his own CLAUDE.md at around 100 lines and roughly 2,500 tokens . Some teams like HumanLayer keep theirs under 60.
Run /init to generate a starter CLAUDE.md from your project’s detected build systems, test frameworks, and code patterns. Treat it as a starting point to edit, not a finished product.
What belongs in CLAUDE.md:
- Bash commands Claude cannot guess (
npm run test:integration --watch,cargo test -- --nocapture) - Code style rules that deviate from language defaults (“Use ES modules, not CommonJS”)
- Testing instructions and preferred runners
- Repo etiquette: branch naming, PR conventions, commit message format
- Architectural decisions specific to the project
- Environment quirks: required env vars, local cert paths
- Common gotchas or non-obvious behaviors
What to leave out:
- Anything Claude can figure out by reading code
- Standard language conventions it already knows
- Detailed API docs (link to them instead)
- Information that changes frequently
- File-by-file codebase descriptions
- Self-evident instructions like “write clean code”
For every line, ask: “Would removing this cause Claude to make a mistake?” If the answer is no, cut it.
Here is a realistic CLAUDE.md for a TypeScript API project:
# Code style
- Use ES modules (import/export), not CommonJS (require)
- Destructure imports when possible
- Prefer named exports over default exports
# Testing
- Run single tests: `npx vitest run src/path/to/test.ts`
- Full suite: `npm run test`
- Always include integration tests for new endpoints
# Workflow
- Typecheck after making code changes: `npx tsc --noEmit`
- Branch naming: feature/<ticket-id>-<short-desc>
- Prefer running single tests, not the whole suite
- IMPORTANT: Never modify files in src/db/migrations/ without explicit approval
# Architecture
- API routes in src/routes/, business logic in src/services/
- Database queries go through src/db/queries/, not inline SQL
- Auth middleware at src/middleware/auth.ts - do not duplicate auth logic
# Environment
- Requires POSTGRES_URL and REDIS_URL in .env
- Local dev uses port 3001; tests use port 3099File placement matters. CLAUDE.md files can live in several locations, loaded in this hierarchy: ~/.claude/CLAUDE.md (global, all sessions), ./CLAUDE.md (project root, checked into git for team use), ./CLAUDE.local.md (personal overrides, add to .gitignore), parent directories (useful for monorepos), and child directories (loaded on demand when Claude works in those directories). CLAUDE.md also supports @path/to/import references to pull in content from other files without bloating the root file.
Emphasis tuning works. Adding “IMPORTANT” or “YOU MUST” to critical rules genuinely improves adherence. Use it sparingly - if everything is important, nothing is.
The self-improvement loop is worth building into your routine. Cherny’s team rule: “Anytime we see Claude do something incorrectly, we add it to CLAUDE.md so it doesn’t repeat next time.” The prompt “Update your CLAUDE.md so you don’t make that mistake again” works well in practice - Claude is reportedly good at writing rules for itself. The file gets checked into git and updated multiple times per week.
Skills - On-Demand Knowledge Without Context Bloat
CLAUDE.md loads every session . Skills load only when relevant. That distinction is what keeps your context window lean while still giving Claude access to detailed workflows and domain knowledge.
Skills follow the open Agent Skills
standard, which as of early 2026 has been adopted by over 30 agent products - including OpenAI Codex, Google Gemini CLI, Microsoft Copilot, Cursor, and JetBrains Junie. A skill is a SKILL.md file with YAML frontmatter and markdown instructions. The name field becomes the /slash-command, and the description helps Claude decide when to load the skill automatically.
Skills live in: ~/.claude/skills/<name>/SKILL.md (personal, all projects), .claude/skills/<name>/SKILL.md (project-level, committed to git), enterprise managed settings (org-wide), and plugin directories. Higher-priority locations win when names collide.
Here is a complete skill for fixing GitHub issues:
---
name: fix-issue
description: Fix a GitHub issue by reading it, finding relevant code, implementing the fix, writing tests, and creating a commit
disable-model-invocation: true
---
Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read the issue with `gh issue view $ARGUMENTS`
2. Search the codebase for relevant files
3. Implement the fix
4. Write and run tests
5. Create a commit referencing the issue and pushInvoke it with /fix-issue 1234 and $ARGUMENTS gets replaced with 1234. You can also use positional arguments: $1, $2, and so on.

Key frontmatter fields that control behavior:
| Field | Purpose | Example |
|---|---|---|
name | Becomes the /slash-command | fix-issue |
description | Helps Claude auto-trigger (truncated at 250 chars) | Fix a GitHub issue... |
disable-model-invocation | Prevents auto-triggering, manual only | true |
user-invocable | Hides from menu (background knowledge) | false |
allowed-tools | Restricts available tools during skill | ["Bash", "Read"] |
context | Runs in isolated subagent context | fork |
model | Override session model | claude-sonnet-4-6 |
Dynamic context injection makes skills much more useful than static templates. The !`command` syntax runs a shell command before the skill content reaches Claude, replacing the placeholder with the output. A PR review skill can include !`gh pr diff` to inject the actual diff at runtime - no manual copying needed.
A more involved deployment skill with dynamic context injection:
---
name: deploy
description: Deploy the current branch to staging or production
disable-model-invocation: true
---
Deploy to $1 environment.
Current branch status:
!`git status --short`
Recent commits being deployed:
!`git log --oneline -5`
Steps:
1. Run the full test suite
2. Build the project
3. Deploy using `./scripts/deploy.sh $1`
4. Verify the deployment health check
5. Report the deployment URL and statusClaude Code ships with several built-in skills in 2026: /batch (orchestrates large-scale parallel changes across worktrees), /claude-api (loads API reference for your language), /debug (enables debug logging), /loop (runs a prompt on a recurring interval), and /simplify (spawns 3 parallel review agents to check changed files for quality).
Git Worktrees - Running 10+ Parallel Sessions
Context is Claude Code’s fundamental constraint. A single session can only do one thing well at a time. As context fills up, performance degrades and unrelated changes collide. Running multiple sessions in the same directory causes git conflicts.
Git worktrees
solve this by creating separate working directories attached to a single repository. Each directory has its own checked-out branch, but they all share the same .git folder and commit history. No cloning, no syncing.
Claude Code’s --worktree (-w) flag creates an isolated worktree and starts a session in it:
claude --worktree feature-auth
# Creates .claude/worktrees/feature-auth/
# Branches from origin/HEAD as worktree-feature-authOmit the name for an auto-generated one: claude --worktree.
The parallel development workflow: open multiple terminals, run claude -w task-name in each, and let each session work independently. Cherny reports running 10-15 parallel sessions simultaneously at Anthropic. Some teams using this pattern have reported up to 18% throughput improvement
over sequential single-session work, with the real gain being that while Claude works in one worktree, you review what finished in another - you are directing, not waiting.

The /batch skill uses worktrees at scale. It decomposes a large task into 5-30 independent units, spawns one background agent per unit in an isolated worktree, and each agent implements its unit, runs tests, and opens a PR. Example: /batch migrate src/ from Solid to React.
The Writer/Reviewer pattern produces better code quality than solo sessions. Session A implements a feature. Session B reviews it with fresh context - Claude is not biased toward code it just wrote. Session A applies the feedback. You can also split test writing and implementation: one session writes tests, another writes code to pass them.
Subagent worktrees work the same way. Ask Claude to “use worktrees for your agents” or set isolation: worktree in a custom subagent’s frontmatter. Each subagent gets its own worktree, automatically cleaned up when it finishes without changes.
Practical worktree tips:
- Add
.claude/worktrees/to your.gitignore - Create a
.worktreeincludefile in your project root (uses.gitignoresyntax) to auto-copy gitignored files like.envor.env.localinto new worktrees:
# .worktreeinclude
.env
.env.local
config/master.key- Re-sync
origin/HEADif the remote’s default branch changes:git remote set-head origin -a - Orphaned subagent worktrees are cleaned up automatically at startup based on the
cleanupPeriodDayssetting, provided they have no tracked modifications or unpushed commits
Hooks and Permissions - Deterministic Rules, Not Suggestions
CLAUDE.md instructions are advisory. Claude follows them about 80% of the time - by design, since CLAUDE.md content is delivered as a user message, not a system-level forced configuration. Claude judges whether each rule is relevant to the current task, and may skip it when context is full.
Hooks are deterministic scripts that fire automatically at specific points in Claude’s workflow with zero exceptions. They execute as code, so there is no question of compliance.
Hook configuration lives in .claude/settings.json (project-level, committed to git) or ~/.claude/settings.json (user-level, all projects). Claude can write hooks for you: “Write a hook that runs eslint after every file edit.”
Key hook events:
| Event | Behavior | Use Case |
|---|---|---|
PreToolUse | Can block actions (exit code 2) | Security gates, file protection |
PostToolUse | Reacts after actions | Formatting, logging, running tests |
SessionStart | Injects context at session start | Environment checks, status updates |
Notification | Fires when Claude needs input | Desktop notifications, Slack alerts |
Here is a complete .claude/settings.json with hooks working together:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm -rf|DROP TABLE|truncate' && exit 2 || exit 0"
}
]
},
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "echo \"$CLAUDE_TOOL_INPUT_FILE_PATH\" | grep -q 'src/db/migrations' && echo 'Cannot modify migration files' >&2 && exit 2 || exit 0"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\" 2>/dev/null; exit 0"
}
]
}
],
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' \"$CLAUDE_NOTIFICATION\" 2>/dev/null; exit 0"
}
]
}
]
}
}Exit codes matter: 0 means allow/ok, 2 means block (PreToolUse only - the message sent to stderr is forwarded to Claude), and any other non-zero is a non-blocking error shown to the user.
The hook-vs-CLAUDE.md decision rule: if something must happen every single time with zero exceptions (formatting, linting, file protection), make it a hook. If it is guidance that benefits from flexibility (coding patterns, architectural preferences), put it in CLAUDE.md. If Claude keeps violating a CLAUDE.md rule, convert it to a hook.
Notification hooks are essential for parallel worktree workflows. Configure a Notification hook with notify-send (Linux) or osascript (macOS) to get pinged when Claude is blocked or finished in any session. You kick off tasks across terminals and get alerted only when attention is needed.
Permission modes reduce interruptions without sacrificing safety: Auto mode (a classifier model reviews commands and blocks risky ones), permission allowlists (permit specific safe tools like npm run lint), and sandboxing (OS-level filesystem and network isolation).
CLAUDE.md vs Skills vs Hooks - When to Use Each
Deciding where to put a rule is the most common question when building a Claude Code stack. Here is a quick reference:
| Factor | CLAUDE.md | Skills | Hooks |
|---|---|---|---|
| Loads | Every session | On demand | Every matching event |
| Nature | Advisory | Advisory | Deterministic |
| Compliance | ~80% | ~80% | 100% |
| Good for | Project context, style rules | Workflows, domain knowledge | Formatting, security, linting |
| Context cost | Always consumed | Only when invoked | Zero (runs externally) |
| Can block actions | No | No | Yes (PreToolUse) |
The hierarchy in practice: CLAUDE.md provides persistent project context. Skills extend it with on-demand workflows and knowledge. Hooks enforce non-negotiable behaviors. Worktrees enable parallel isolation. Subagents handle delegated investigation with separate context windows.
Putting the Stack Together in Daily Practice
A typical day with the full stack looks like this. Start by reviewing open issues in a planning session using Plan Mode. For each task, spin up claude -w task-name in a separate terminal. Each session has CLAUDE.md loaded automatically, skills available on demand, hooks enforcing formatting and linting. Use subagents within each session for codebase research (“use a subagent to investigate how auth handles token refresh”) so exploration does not consume the implementation context. When implementation is done, a fresh session reviews the worktree’s diff. Commit and PR through a /commit skill with a PostToolUse hook that runs the full test suite.
Context management discipline is what makes the stack work:
- Start fresh sessions per task (
/clearbetween unrelated work) - Compact proactively at 70% context usage
- Delegate research to subagents
- Scope each prompt narrowly
The single biggest mistake is letting one session accumulate context from multiple unrelated tasks. Each worktree session should do one thing.
Each layer feeds the next over time. When Claude makes a mistake, run “Update your CLAUDE.md so you don’t make that mistake again.” When a CLAUDE.md rule gets violated repeatedly, convert it to a hook. When a hook triggers too often for the same pattern, create a skill that teaches Claude the correct approach. A week of this and your setup is noticeably tighter than when you started.
Scaling from solo to team works because every layer is version-controlled. CLAUDE.md and .claude/skills/ are checked into git. Hooks in .claude/settings.json are committed too. When a new team member clones the repo, they inherit the full stack - every convention, every workflow, every guard rail. The team’s collective Claude experience is encoded in configuration that persists across sessions and people.
Metrics worth tracking:
- Context window usage per session (stay under 70%)
- Number of corrections per task (more than 2 means
/clearand restart with a better prompt) - Hook failure rate (signals misalignment between CLAUDE.md guidance and actual behavior)
- Worktree cleanup ratio (orphaned worktrees suggest incomplete tasks)
Never put secrets or API keys in CLAUDE.md - the file is checked into git. Use .env files and reference them through .worktreeinclude so they propagate to worktrees without hitting version control. Sensitive project context that cannot go in a shared file belongs in CLAUDE.local.md, which should be in your .gitignore.