DEV Community

Cover image for Stop Re-Teaching Claude Every Session
Yaohua Chen
Yaohua Chen

Posted on

Stop Re-Teaching Claude Every Session

The .claude/ Playbook: Hooks, Agents, Permissions, and Everything Your Team Should Be Sharing

Transitioning from Ephemeral Prompts to Workspace-Level Execution

You open a new Claude Code session. You retype your style preferences, your folder conventions, your testing protocols. Then you do it again tomorrow.

Most developers approach AI coding assistants through the narrow lens of prompt engineering—sending isolated, one-off instructions in a chat interface. While useful for simple tasks, this ephemeral approach falls apart in complex, multi-file codebases. It relies on probabilistic recall, suffers from conversational noise, and forces you to repeatedly re-teach the model your style guides, folder patterns, and testing protocols.

To unlock the true power of an agentic workflow, you must transition from prompting an AI to configuring a collaborative workspace.

By treating your project root as a deterministic runtime environment, you can guide agent behaviors programmatically. This blog post explores how to leverage the .claude/ directory structure to establish a production-grade workspace design system. We will dissect the technical anatomy of custom agent environments, transition from probabilistic instructions to deterministic automation, and establish concrete patterns to keep your development cycles efficient, reproducible, and context-aware.

Mapping Our Exploration of the Agent Runtime

To help you build a structured workspace, this guide breaks down the core architecture of the .claude/ environment:

  • Deconstructing the Workspace Anatomy (.claude/): A deep dive into the purpose and hierarchy of CLAUDE.md, scoping user-specific vs. team-wide configs, and utilizing .gitignore to protect sensitive local rules.
  • Orchestrating Integrations (MCPs): How to integrate Model Context Protocol (MCP) servers, resolve routing ambiguities through rich tool schemas, and handle failures gracefully with structured error metadata.
  • Enforcing Deterministic Workflow Rules (Hooks): Moving beyond fragile "best-effort" prompts by intercepting tool calls and normalizing data via lifecycle scripts (e.g., PostToolUse).
  • Packaging Custom On-Demand Workflows (Commands & Skills): Creating shareable slash commands and scoping verbose agent behaviors using isolated, fork-based sub-agent contexts (context: fork).
  • Spawning Collaborative Contexts (Subagents): Decomposing complex customer requests or architectural changes into parallel tasks managed by specialized agent roles.
  • Managing Context Budgets (Rules & Performance): Keeping token consumption lean by lazy-loading topic-specific rules using path-matching glob patterns (.claude/rules/).
  • Combating Contextual Decay: Why reviewing your code in an independent, fresh session prevents self-correction blind spots and logical bias.

Anatomy of .claude/

A typical project layout — what each file/folder is for:

your-project/
├── CLAUDE.md                # Project rules; keep under ~200 lines
├── CLAUDE.local.md          # Personal local config (gitignored)
├── .gitignore               # Files Claude should NOT read
├── .mcp.json                # MCP config — lives at the repo root by convention
└── .claude/                 # Highest-priority project-context directory
    ├── hooks/               # Lifecycle scripts (fire deterministically)
    │   ├── PostToolUse.sh       # runs after a tool call
    │   ├── SessionStart.sh      # loads context at session start
    │   └── PreCompact.sh        # saves state before context compaction
    ├── commands/            # Slash commands — shared via version control
    │   └── ship.md              # invoked as /ship
    ├── skills/              # On-demand skills — lazy-loaded via INDEX
    │   ├── INDEX.md             # one-line trigger per skill; drives routing
    │   ├── skill-loader.md      # tells Claude how to pick and load a skill
    │   ├── harvest-session.md   # session knowledge distillation
    │   └── web-fetch-fallback.md # Gemini CLI fallback for blocked sites
    ├── agents/              # Subagents, each with its own context window
    │   ├── code-reviewer.md     # summarizes diffs
    │   ├── researcher.md        # gathers and stitches web info
    │   └── log-analyzer.md      # parses error logs
    ├── output-styles/       # Response-style presets (e.g. terse.md)
    ├── plugins/             # Bundles of commands + agents + MCP servers
    ├── rules/               # Scoped rules, lazy-loaded by path match
    ├── statusline.sh        # Bottom-of-CLI status bar
    ├── settings.json        # Permissions, model, hook registration
    └── settings.local.json  # Local personal preferences (gitignored)
Enter fullscreen mode Exit fullscreen mode

CLAUDE.md and CLAUDE.local.md

Most people prompt Claude. Power users configure it.

The highest-leverage thing you can do with Claude Code is write a CLAUDE.md — a plain markdown file that gets loaded into context every time you start a session. It's how you stop re-typing your preferences into every prompt and start treating Claude like a colleague who remembers how you work.

Claude Code supports four levels of CLAUDE.md, from highest to lowest priority:

Level Location Use Case
Organization /Library/Application Support/ClaudeCode/CLAUDE.md (macOS) IT admin unified policy for the whole org
Project ./CLAUDE.md or ./.claude/CLAUDE.md Project standards, committed to git
Local ./CLAUDE.local.md Personal project overrides, gitignored
User global ~/.claude/CLAUDE.md Personal preferences, applies to all projects

Subdirectory CLAUDE.md files (e.g., ./src/CLAUDE.md) are also supported and load on demand when Claude enters that directory — they extend the project level rather than forming a separate tier.

Local and user-level files stay on your machine — they are not shared via version control.

What to put in a project CLAUDE.md:

## Build and Test Commands
- Install: npm install
- Test: npm test -- --grep "test name"

## Coding Standards
- Python uses ruff, line width 88
- Tests use pytest, one file per service
- Commit format: type(scope): description

## Architecture Decisions
- Tailwind over CSS Modules — team standardized on it
- Permission checks live in middleware, not in individual routes
- Redis cache keys use unified prefix `app:v1:`

## Common Pitfalls
- DB connection pool limit is 20 — don't open connections in loops
- Don't mock the database; last time mock tests passed but prod migration failed
Enter fullscreen mode Exit fullscreen mode

A project CLAUDE.md has two complementary layers: project context (above) and behavioral rules — operating principles for how Claude approaches every task in the codebase. Here's a reusable 12-rule template to drop in below your project context:

# Behavioral Rules
These rules apply to every task unless explicitly overridden.
Bias: caution over speed on non-trivial work.

Rule 1 — Think Before Coding
State assumptions explicitly. If uncertain, ask rather than guess. Push back when a simpler approach exists.

Rule 2 — Simplicity First
Minimum code that solves the problem. No features beyond what was asked. No single-use abstractions.

Rule 3 — Surgical Changes
Touch only what you must. Don't "improve" adjacent code or formatting. Match existing style.

Rule 4 — Goal-Driven Execution
Define success criteria. Loop until verified. Strong success criteria let you loop independently.

Rule 5 — Use the model only for judgment calls
Use for: classification, drafting, summarization, extraction.
Do NOT use for: routing, retries, deterministic transforms.
If code can answer, code answers.

Rule 6 — Token budgets are not advisory
Set explicit per-task and per-session token ceilings in this file.
If approaching either limit, summarize and start fresh. Surface the breach. Do not silently overrun.

Rule 7 — Surface conflicts, don't average them
If two patterns contradict, pick one (more recent / more tested). Explain why. Flag the other for cleanup.

Rule 8 — Read before you write
Before adding code, read exports, immediate callers, shared utilities.

Rule 9 — Tests verify intent, not just behavior
Tests must encode WHY behavior matters, not just WHAT it does.

Rule 10 — Checkpoint after every significant step
Summarize what was done, what's verified, what's left. Don't continue from a state you can't describe back.

Rule 11 — Match the codebase's conventions, even if you disagree
Conformance > taste. If a convention is harmful, surface it. Don't fork silently.

Rule 12 — Fail loud
"Completed" is wrong if anything was skipped silently. Surface uncertainty, don't hide it.

# Project-specific rules go here — keep total file under 200 lines
Enter fullscreen mode Exit fullscreen mode

Rule 5 carries the most architectural weight: it draws an explicit boundary between what belongs in the model and what belongs in code or hooks. Routing logic, retry loops, and deterministic data transforms should never be delegated to probabilistic model responses — if code can answer, code answers. This directly motivates why hooks exist: to handle the deterministic work that CLAUDE.md should tell Claude not to attempt itself.

Three principles for what goes in:

Write what Claude can't read from the code. The "why" matters more than the "what." Claude already knows how React works; it doesn't know you chose Tailwind because the team standardized on it, or that you avoid mocking the database because of a past incident.

Don't put frequently changing content. API documentation, file-by-file descriptions, and dependency lists go stale fast. Link to them instead of embedding them.

Keep it under ~200 lines. An overly long CLAUDE.md causes Claude to start ignoring rules. Use headers and lists for scannability, and run a monthly pass to prune stale entries.

Your personal global ~/.claude/CLAUDE.md follows the same rules but calibrates Claude to you as a developer:

- I'm a full-stack engineer — no need to over-explain basic concepts
- Keep responses concise, skip pleasantries
- After code changes, don't summarize what you did — I'll read the diff
- Prefer simple solutions, don't over-engineer
Enter fullscreen mode Exit fullscreen mode

Four lines like these can save hundreds of repetitive corrections across every project you touch.

A useful routing test for deciding where project content belongs:

Would a teammate doing the same task tomorrow need this?

  • Yes → goes into CLAUDE.md (shared team memory)
  • No → stays in CLAUDE.local.md (personal notes)

MCPs

MCP servers extend Claude Code with external tools — databases, APIs, documentation indexes, or anything your agent needs to interact with outside the codebase. Team-shared servers go in .mcp.json at the repo root; personal or experimental servers go in ~/.claude.json.

Tool description quality is the single biggest lever for reliable tool selection. When two tools have vague or overlapping descriptions — say, analyze_content vs. analyze_document with near-identical summaries — Claude will misroute calls. Effective descriptions name the input format, provide an example query, explain edge cases, and clarify what distinguishes this tool from adjacent ones. Enhancing these descriptions also prevents Claude from defaulting to built-in tools (like Grep) when a more capable MCP tool exists.

Error responses matter just as much. A generic "Operation failed" message prevents Claude from making recovery decisions. Return structured metadata instead: an errorCategory field (transient, validation, permission, or business), an isRetryable boolean, and a human-readable explanation. For business rule violations — a refund above a threshold, a policy block — include a customer-friendly explanation so Claude can communicate appropriately rather than retrying a call that will never succeed.

// .mcp.json  project-scoped, committed to version control
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Use ${ENV_VAR} expansion to keep credentials out of the repo. When you need to guarantee that Claude calls a tool rather than responding conversationally, set tool_choice: "any". For workflows where a specific tool must run first (e.g., extract_metadata before any enrichment step), use forced tool selection in that turn, then process subsequent steps in follow-up turns.

MCP resources are a lower-overhead alternative to exploratory tool calls: expose content catalogs (issue summaries, documentation hierarchies, database schemas) as resources so Claude can browse available data without burning tool-call budget.

Hooks

hooks/ are deterministic — unlike instructions in CLAUDE.md, they
will run at the wired-up lifecycle moment, so they're the right tool
when "the model usually remembers to…" isn't good enough.

The most common pattern is PostToolUse: intercept tool results before Claude processes them, normalize inconsistent formats (Unix timestamps, ISO 8601, numeric status codes from different MCP upstream sources), and return clean, uniform data. This eliminates the need to ask Claude to "handle whichever date format comes back."

PreToolUse hooks run before the tool call executes — the right place to enforce compliance rules. A hook can inspect an outgoing process_refund call, check the amount against a policy threshold, and block it before Claude proceeds. The redirect (to a human escalation queue, for example) happens in the hook script, not in a prompt.

# .claude/hooks/PostToolUse.sh
# Normalizes timestamps from MCP tools to ISO 8601
INPUT=$(cat)
echo "$INPUT" | jq '.timestamp |= (if type == "number" then todate else . end)'
Enter fullscreen mode Exit fullscreen mode

Use hooks when "the model usually remembers to…" isn't reliable enough. If a business rule requires guaranteed compliance, wire it into a hook — not a CLAUDE.md instruction.

Claude Code exposes around 29 lifecycle events — including SubagentStart, SubagentStop, TaskCreated, TaskCompleted, UserPromptSubmit, and PostCompact — giving you fine-grained control well beyond the four shown in the anatomy tree.

Commands and Skills

In current Claude Code, commands and skills have been unified — a file at .claude/commands/ship.md and a skill at .claude/skills/ship/SKILL.md both create /ship and work the same way. The .claude/commands/ path is the legacy location and still works; new slash commands are best created as skills in .claude/skills/. A command is a plain markdown file; they're best for multi-step workflows you run repeatedly: release checklists, scaffolding routines, structured debugging flows.

Skills in .claude/skills/ go further by supporting frontmatter configuration:

---
context: fork
allowed-tools: [Write, Edit]
argument-hint: "component name"
---
Enter fullscreen mode Exit fullscreen mode

context: fork is the critical option: it runs the skill in an isolated sub-agent context, so verbose exploratory output — a full codebase analysis, a brainstorm session — never pollutes your main conversation's context window. Use allowed-tools to restrict what the skill can do; a documentation-generation skill has no business deleting files. Use argument-hint to prompt for required parameters when the skill is invoked without arguments.

For personal customization without affecting teammates, create variants in ~/.claude/skills/ under a different name.

As your skill library grows, add an INDEX.md to .claude/skills/ — a one-line-per-skill table of trigger phrases — and a skill-loader.md that tells Claude to consult the index first, then deep-load only the one matching skill. This prevents context bloat from loading all skills upfront, and applies the same lazy-loading principle used by rules/.

File Purpose Trigger
harvest-session Session knowledge distillation "harvest", "I'm done"
code-review PR rating and confidence check "review this PR"
scaffold-component Generate component boilerplate "scaffold a component"

Before promoting a skill from personal to shared, run it against five checks:

  • Used successfully in at least 2 different contexts
  • No reliance on personal private knowledge (e.g., "ask Jane for access")
  • Verified against at least 1 real task end-to-end
  • Frontmatter has a clear, unambiguous trigger phrase
  • Not a duplicate of an existing skill

If it doesn't pass → keep it in ~/.claude/skills/, not the team repo.

Using Gemini CLI as a fallback for blocked sites: Claude Code's WebFetch tool can't access certain websites — Reddit is a common example. A skill can bridge this gap by instructing Claude to shell out to Gemini CLI when WebFetch is unavailable. Gemini can retrieve content from sites Claude can't reach directly, and Claude processes the result in its normal context.

---
name: web-fetch-fallback
description: Fetch content from sites WebFetch cannot access (e.g. Reddit). Use when WebFetch returns a blocked or error response.
allowed-tools: [Bash]
---

When WebFetch is blocked or unavailable, use Bash to call:
gemini -p "fetch and summarize the content at <URL>"

Return the retrieved content to the main conversation for further processing.
Enter fullscreen mode Exit fullscreen mode

Keep the skill narrow — allowed-tools: [Bash] restricts it to shell calls only, and its only job is retrieval, not analysis.

Decision rule: use commands for team-wide, repeatable procedures you invoke explicitly; use skills when you need context isolation, tool restrictions, or lazy-loaded execution.

Agents

Every grep, find, and ls call stays permanently in your main context window. After 30 minutes of active development, 80k tokens of intermediate search output are sitting in your conversation — noise you'll never scroll back to read. Claude Code's auto-compact squashes it into a summary, but buries key details that can't be retrieved later.

Subagents solve this by working in their own room and only sending the answer back. All intermediate tool calls happen inside the subagent's context window; the main agent never sees them. Only the final summary returns.

Subagents are separate Claude instances with their own context windows and tool access. The coordinator spawns them using the Agent tool (renamed from Task in v2.1.63; Task still works as an alias) — which means Agent must appear in the coordinator's allowedTools. By default, subagents start with a blank slate — only their system prompt, no knowledge of the current conversation — so everything they need must be passed explicitly in their prompt.

Define each agent type in its own file under .claude/agents/:

.claude/agents/
├── code-reviewer.md    # receives a diff, returns a structured review
├── researcher.md       # gathers and synthesizes information
└── log-analyzer.md     # parses error logs, surfaces root causes
Enter fullscreen mode Exit fullscreen mode

Each agent is a markdown file with frontmatter that Claude Code reads to recognize and auto-dispatch it:

---
name: code-reviewer
description: Reviews code for quality, security, and maintainability. Use after writing or modifying code.
tools: Read, Grep, Glob, Bash
model: sonnet
---

You are a senior code reviewer. When invoked:
1. Run git diff to see recent changes
2. Focus on modified files
3. Start the review immediately
Enter fullscreen mode Exit fullscreen mode
Field Purpose
name Short slug used to identify the agent
description What it does and when — Claude Code uses this for auto-dispatch
tools Only what it needs — fewer is better
model Match to task complexity: haiku for search, sonnet for review, opus for planning

The description field drives auto-dispatch. The better it describes when the agent should be invoked, the more reliably Claude Code routes tasks to it without you specifying manually every time. Write it as a trigger condition, not a job title.

Restricting tool access by role is important: a researcher agent shouldn't be able to write files; a code-reviewer shouldn't be able to trigger deployments.

Agent files can live in two locations with different scope:

.claude/agents/ ~/.claude/agents/
Scope Current project only All projects on your machine
Sharing Committed to git — teammates get it on clone Local only, never shared
Best for Team-agreed reviewers, project workflows Personal explore/refactor helpers
Priority Wins on name collision Overridden by project version

When the same agent name exists in both directories, the project-level version wins — teams can enforce a shared code-reviewer definition over any individual's personal variant.

Three built-in agents ship with Claude Code:

  • Explore — runs grep, find, and glob internally, returns only findings. Use it when you need to locate a function, pattern, or file. All search noise stays out of your main conversation.
  • Plan — reads multiple files and returns a complete implementation plan. Use it before starting a complex task to think through steps, dependencies, and code volume.
  • General-purpose — full tool access for complex multi-step tasks that don't fit a specialist role.

Start with Explore and Plan before building custom agents — they handle the two highest-noise operations with zero setup.

Passing context between agents: include the full output of prior agents directly in the next agent's prompt — don't rely on the coordinator to summarize. When handing off between agents, use structured formats with metadata (source URLs, document names, page numbers) so attribution is preserved in the final synthesis.

Parallel execution: emit multiple Agent calls in a single coordinator response. Each fires as a separate subagent, running concurrently. Write coordinator prompts that specify goals and quality criteria rather than procedural steps — this lets subagents adapt when a particular approach fails.

Ordered workflows: when step B requires verified output from step A, use a programmatic prerequisite gate rather than a prompt instruction. A hook or tool wrapper that blocks process_refund until get_customer returns a verified customer ID is more reliable than telling Claude to "always verify first."

Background execution: use /background (or /bg) to detach the current session and run it as a background agent while you open a new session. Best for long-running operations — full test suites, large-scale searches, non-urgent code reviews — where you don't need to block on the result.

Blank vs. fork context: the default blank slate is right for independent tasks. When a subagent's work is closely tied to the ongoing conversation and needs inherited background — for example, a refactor agent that needs to understand the architectural decisions made earlier in the session — use fork. Set CLAUDE_CODE_FORK_SUBAGENT=1 to make all subagents fork by default; with that env var active, /fork spawns a forked subagent (without it, /fork is just an alias for /branch). Fork copies the full parent conversation into the subagent's context and shares the parent's prompt cache prefix, making input tokens approximately 10x cheaper after the first token. The tradeoff: fork costs more tokens upfront, so reserve it for subagents where context inheritance genuinely matters.

Output Styles

.claude/output-styles/ holds response-style presets — markdown files that configure how Claude formats its output for a given context. A terse.md style skips preamble and returns only code with inline comments. A verbose.md style includes rationale for every decision.

Invoke a style via a slash command or reference it in a skill's frontmatter. This keeps CLAUDE.md clean of conditional formatting instructions that only apply in specific workflows.

Plugins

Plugins bundle related commands, agents, and MCP server configs into a single distributable unit under .claude/plugins/. A "design-system" plugin might package a scaffolding command, a component-review agent, and a Figma MCP server config — one install wires up the entire workflow.

For most teams, plugins are overkill until you're managing enough shared tooling that versioned, distributable packages make sense. Start with standalone commands and skills; extract a plugin when a set of them are always deployed together across multiple repos.

Recommended starting point: Superpowers

Superpowers is the most widely adopted Claude Code plugin and the best ready-made starting point for teams. It was accepted into the official Anthropic plugin marketplace in January 2026 and installs 14 structured skills covering TDD, systematic debugging, brainstorming, subagent-driven development with built-in code review, and skill authoring (you can create new skills from inside a session).

What makes it worth installing: it enforces a 5-phase discipline on every task — clarify → design → plan → code → verify — preventing the "just start coding" failure mode where Claude jumps to implementation before understanding the requirements. Install it with one command inside an active Claude Code session:

/plugin install superpowers@claude-plugins-official
Enter fullscreen mode Exit fullscreen mode

Rules

.claude/rules/ organizes topic-specific rule files (e.g., testing.md, api-conventions.md, deployment.md) as an alternative to one monolithic CLAUDE.md. Rules files use YAML frontmatter to declare which paths trigger them:

---
paths:
  - "**/*.test.tsx"
  - "**/*.spec.ts"
---
# Testing conventions
Always mock external HTTP calls. Never use real database connections in unit tests.
Enter fullscreen mode Exit fullscreen mode

Rules load lazily — only when Claude is editing a file that matches the glob pattern. This keeps the always-on context budget small while still giving you per-area guidance when it's relevant.

The key advantage over directory-level CLAUDE.md files: glob patterns can target files by type across the entire repo. A testing.md rule that matches **/*.test.tsx applies to all test files regardless of where they live, without duplicating the rule in every subdirectory.

Settings and Permissions

.claude/settings.json controls what Claude Code is allowed to do — which tools it can call, which file patterns it can edit, and which shell commands it can run without asking. Commit it to git to share those rules with the team; .claude/settings.local.json (gitignored) handles personal overrides.

Six permission modes — three cycle via Shift+Tab (default → acceptEdits → plan); the rest are set via startup flags:

Mode Behavior
default Asks on first use of each tool type
acceptEdits Auto-accepts file edits; still asks for shell commands
plan Read-only — no modifications allowed
auto Autonomous mode — approves based on context
dontAsk Approves everything not explicitly denied
bypassPermissions Skips all prompts — use with caution

Allow and deny rules give fine-grained control within any mode:

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)",
      "Edit(src/**/*.ts)",
      "Read(*.md)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Edit(.env)"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Priority order: deny → ask → allow. Deny always wins — so you can broadly allow common commands while protecting sensitive files. .env should appear in the deny list unconditionally.

Settings file hierarchy, highest to lowest priority:

Organization policy   (/Library/Application Support/ClaudeCode/settings.json)
  ↓ CLI parameters
  ↓ .claude/settings.local.json   (local, gitignored)
  ↓ .claude/settings.json         (project-level, team-shared)
  ↓ ~/.claude/settings.json       (global personal)
  ↓ Defaults
Enter fullscreen mode Exit fullscreen mode

Practical split: team rules go in .claude/settings.json, personal preferences go in ~/.claude/settings.json, and sensitive configurations go in .claude/settings.local.json.

Other Best Practices

Reviewing Code in a New Session

When Claude generates code and then is asked to review it in the same session, it is often blinded by its own initial logic, cognitive biases, and the accumulated "noise" (failed attempts) within the conversation history.

An independent review instance—a new chat session—breaks this cycle by offering a fresh "context," free from the previous faulty reasoning path.

Why same-session review fails:

  • Self-correction blind spot — LLMs frequently fail to recognize errors in their own outputs, even though they can easily identify those same errors when presented as new information. The model reinforces its initial incorrect, but plausible-sounding, logic.
  • Contextual noise — As a session grows, it accumulates dead-end attempts, partial fixes, and conflicting instructions, making it harder to distinguish good code from bad.
  • Lost-in-the-middle effect — Claude prioritizes information at the very beginning and very end of the context window. If the original design flaw appeared in the middle of a long conversation, it may be forgotten during review.
  • Premature compaction — Long sessions trigger auto-compact, which may compress away the critical details of the original requirements.

Example — the subtle state management bug:

You ask Claude to build a React component that fetches data on button click. Claude writes the component but fails to clear previous data before fetching new data, causing a flickering display.

  • Same-session review: You say "It's flickering." Claude reads its own code and suggests adding useEffect — wrong. It needs to clear state in the onClick handler. Claude is stuck in its initial incorrect mental model.
  • Independent review: Open a new chat, paste the same code, say "Review this for data fetching bugs." The fresh instance immediately spots the missing state reset and gives the correct fix.

Capturing Value Before You Close the Session

The flip side of contextual decay is knowledge loss: every decision, workaround, and insight from a session disappears when you close it. A session harvest skill addresses this directly.

At the end of a session, trigger the skill (e.g., /harvest) and Claude routes whatever is worth keeping to one of four destinations:

Destination What goes there Where
Team memory Cross-developer reusable context CLAUDE.md
Project memory Context specific to this project project-level CLAUDE.md or a memory.md
Output artifacts Specs, decision logs, documents project output/ directory
Personal draft pad Early drafts, sensitive info, personal notes CLAUDE.local.md

Use the same routing test from the CLAUDE.md section: would a different developer need this tomorrow? If yes, it goes to team memory. If no, it stays personal.

One hard rule: never silent harvest. Claude must confirm with you before writing to any shared file. Auto-writing to CLAUDE.md contaminates team memory with session-specific noise that misleads every future session.

Managing Context During a Session

Claude Code's context window is large but finite — and what fills it directly affects output quality. Three commands help you manage it actively:

/clear — clears the entire conversation while preserving CLAUDE.md. Use it between distinct tasks rather than carrying unrelated history from one problem into the next.

/compact [focus on X] — manually compresses the conversation. The focus hint tells Claude what to prioritize:

/compact focus on API changes and test results
Enter fullscreen mode Exit fullscreen mode

Without a focus hint, compression treats everything equally and may bury the details that matter most.

/context — shows current token usage broken down by file, tool definition, and conversation history. Run it when a session feels sluggish — unused MCP servers are a frequent culprit.

Beyond reactive monitoring, enforce hard token limits in CLAUDE.md so Claude self-reports when approaching them rather than waiting to be told:

## Token Budgets
Define your per-task and per-session token ceilings here.
If approaching either limit, summarize progress and flag it explicitly.
Do not silently overrun — surface the breach.
Enter fullscreen mode Exit fullscreen mode

This shifts enforcement from reactive (you notice sluggishness, run /context) to proactive (Claude surfaces the breach before it compounds).

You can also write compression instructions directly into CLAUDE.md so they apply automatically during auto-compact:

## Compression Instructions
When compressing context, always preserve:
- The complete list of modified files
- Test commands and their results
- Key architecture decisions made this session
Enter fullscreen mode Exit fullscreen mode

The general habit: one task per session when possible. /clear is free — the cost of carrying stale context is not.

Plan Mode: Think Before You Act

Plan Mode restricts Claude Code to read-only — it can explore and analyze but cannot modify anything. Use it when a task has multiple implementation paths and you want to align on approach before touching code.

Three ways to enter it:

claude --permission-mode plan   # launch directly in Plan Mode
# or press Shift+Tab twice during a session
# or say "don't change code yet, just make me a plan"
Enter fullscreen mode Exit fullscreen mode

Ctrl+G opens the generated plan in your editor — the key step. Delete the parts you disagree with, add your own constraints, then switch back to normal mode and let Claude execute the modified plan. Editing a plan takes seconds; correcting code built from a misunderstood plan takes much longer.

The recommended flow for complex tasks:

  1. Enter Plan Mode
  2. Have Claude read relevant code: "Read src/auth/ and understand session handling"
  3. Request a plan: "Create an OAuth2 migration plan"
  4. Ctrl+G — review and edit the plan
  5. Switch back to normal mode
  6. "Execute the plan and write tests"
  7. Have Claude self-verify against the original requirements

Checkpoint after every significant step. For multi-phase plans, enforce this with a behavioral rule in CLAUDE.md:

Rule 10 — Checkpoint after every significant step
Summarize what was done, what's verified, what's left.
Don't continue from a state you can't describe back.
If you lose track, stop and restate.
Enter fullscreen mode Exit fullscreen mode

The Ctrl+G edit step is where you define the checkpoints; Rule 10 ensures Claude doesn't barrel past them silently.

When not to bother: renaming a variable, fixing a typo, adding a log line. The rule — if there's only one reasonable way to implement the task, just do it. If there are multiple choices, plan first.


Conclusion

A well-structured .claude/ directory transforms Claude Code from a chat tool into a programmable development environment — one that your whole team can share, extend, and version-control.

Key takeaways:

  • CLAUDE.md for always-on context: style guides, project conventions, and non-negotiable rules
  • Hooks when you need deterministic enforcement — not probabilistic, prompt-based compliance
  • Commands and skills for repeatable team workflows and isolated, context-safe sub-tasks
  • Agents for decomposing complex work across parallel, specialized contexts
  • Rules for keeping context lean — load only what's relevant to the file being edited
  • Review in a fresh session to break the self-correction blind spot

Start small: a CLAUDE.md and one hook. Add commands as you notice yourself repeating instructions. Add agents when a task is complex enough to benefit from parallelism or specialist focus. The configuration is code — version it, review it, and let it evolve with your team.

Top comments (0)