DEV Community

Cover image for Claude Code in Practice (Part 2): Memory, Rules, Permissions & Shortcuts
WonderLab
WonderLab

Posted on

Claude Code in Practice (Part 2): Memory, Rules, Permissions & Shortcuts

Introduction

Part 1 covered CC's launch modes, CLAUDE.md configuration, and multi-task concurrency — all at the "how to use it" level.

This part goes one layer deeper: how to make CC fit your working style:

  • Memory: teach CC your preferences so you don't have to repeat yourself
  • Rules: set boundaries for CC so your team's coding standards actually get followed
  • Configuration scope: know which settings are global and which are project-level
  • Permissions: find the right balance between safety and efficiency
  • Shortcuts: a set of commands that meaningfully improve daily interaction

Memory: Teaching CC Your Preferences

The Scenario

Say you're developing a Python project. Every time CC runs code, it defaults to the system Python — but you want it to use a conda virtual environment for proper isolation.

You can just tell CC: "Remember, this project always uses Python from the conda environment."

CC will save that preference into the project's MEMORY file. From that point on, CC reads this file at the start of every conversation and treats it as part of its context — it genuinely "remembers."

How Memory Works

You tell CC a preference
         │
         ▼
CC writes it to the MEMORY file (project-level or global)
         │
         ▼
On the next conversation start, CC automatically reads the MEMORY file
         │
         ▼
The stored memory becomes part of the context, shaping CC's behavior
Enter fullscreen mode Exit fullscreen mode

What's Worth Saving to Memory

  • Environment preferences (which Python environment, which Node version)
  • Naming conventions (variable naming style, file naming patterns)
  • Personal workflow habits (commit message format preferences)
  • Toolchain choices (yarn vs npm, pytest vs unittest)


Memory is personal- or project-level. Don't store sensitive information (API keys, passwords) in memory files.


Rules: Setting Boundaries for CC

CLAUDE.md vs Rules: Two Different Documents

As covered in Part 1, CLAUDE.md is the project's owner's manual — it tells CC what the project is. Rules are a different document: the team standards handbook — it tells CC how things should be done in this project.

The analogy:

  • CLAUDE.md = project handover doc (structure, tech stack, build commands)
  • Rules = team code standards (coding rules, test requirements, commit conventions)

File Organization

your-repo/
├─ CLAUDE.md              # Project facts (tech stack, commands, constraints)
└─ .claude/
   └─ rules/              # Hard rules (split into small files by responsibility)
      ├─ security.md      # Security baselines
      ├─ testing.md       # Testing baselines
      └─ coding-style.md  # Code style baselines
Enter fullscreen mode Exit fullscreen mode

Splitting into small files keeps responsibilities clear, makes maintenance easier, and lets different people own different areas.

Sample Rules File

# Testing Standards

## Unit Tests
- Coverage: > 80%
- Framework: Jest + Testing Library
- Every public function must have tests
- Test case naming: `should ... when ...`

## Integration Tests
- Tool: Cypress / Playwright
- Coverage: critical user flows
- When to run: before merging a PR

## TDD Workflow
- RED: write a failing test first
- GREEN: implement the minimum code to make it pass
- REFACTOR: clean up and optimize
Enter fullscreen mode Exit fullscreen mode

Rules Are a Shared Team Asset


Rules files should be committed to the repository. If you notice CC doing something that conflicts with team standards, you are responsible for adding the corresponding constraint to rules and sharing it with the team.

The payoff: everyone who picks up the project will get consistent CC behavior, regardless of personal habits.


Configuration Scope: Knowing Where Your Settings Take Effect

All of CC's configuration — CLAUDE.md, Rules, Settings — has a scope, and different scopes have different precedence.

Scope Hierarchy

Global config (~/.claude/)          ← Lowest priority, affects all projects
        │
        ▼
Project config (project/.claude/)   ← Medium priority, affects current project
        │
        ▼
Session-level config (in-conversation) ← Highest priority, current session only
Enter fullscreen mode Exit fullscreen mode

Practical Guidance

Config Type Where to Put It Why
Personal toolchain preferences (conda, nvm, etc.) Global ~/.claude/ Common across all projects
Coding standards, test standards Project .claude/rules/ Team-shared, committed to repo
One-off task-specific constraints Specify in the conversation No need to persist
Project-specific permission settings Project settings.json Isolated per project

Once you understand scope, you won't be confused by a global rule accidentally affecting all your projects, or find yourself duplicating project-specific config across every repo.


Permission Management: Balancing Safety and Efficiency

Both Extremes Are Bad

  • Launch with --dangerously-skip-permissions: full authorization, CC can do anything — fast but risky
  • Configure nothing: CC asks you before every file read — safe but infuriating

The right answer is granular permission configuration.

Configuring Permissions Inside CC

Type /permissions in a CC session to configure tools across three categories:

  • Allow: executes immediately, no prompting
  • Ask: prompts you each time before executing
  • Deny: never allowed to execute

Bash command format: Bash(command:args), where * means all arguments.

Editing settings.json Directly

{
  "permissions": {
    "allow": [
      "Bash(cat:*)",
      "Bash(ls:*)",
      "Bash(grep:*)",
      "Bash(git:status)",
      "Bash(git:log:*)",
      "Bash(git:diff:*)",
      "Bash(npm:test)",
      "Bash(npm:run:lint)"
    ],
    "deny": [
      "Bash(rm:-rf:*)",
      "Bash(sudo:*)",
      "Bash(mkfs:*)",
      "Bash(dd:*)",
      "Bash(curl:*:|:bash)",
      "Bash(wget:*:|:sh)",
      "Bash(reboot)",
      "Bash(shutdown:*)"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode
{
  "permissions": {
    "allow": [
      "Bash(npm:*)",
      "Bash(yarn:*)",
      "Bash(git:*)",
      "Bash(docker:ps)",
      "Bash(docker:logs:*)"
    ],
    "deny": [
      "Bash(docker:rm:*)",
      "Bash(docker:rmi:*)"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode


Apply scope thinking to permissions too: general operations like file reads and running tests belong in global config; project-specific build commands and container operations go in the project config.


Shortcut Reference

Reference material — keep it handy.

! — Run a Bash Command Without Leaving CC

002

! ls -la
! git status
! cat package.json
Enter fullscreen mode Exit fullscreen mode

No need to open a separate terminal. Run local commands directly inside CC and see the results immediately.

@ — Point CC at a Specific File

003

@src/components/Button.tsx add a loading state to this component
@docs/api.md generate TypeScript type definitions based on this API spec
Enter fullscreen mode Exit fullscreen mode

Points CC precisely at the file you mean. Supports path matching. More reliable than just stating a filename — especially useful when filenames aren't unique or paths are deeply nested.

/model — Switch Models On Demand

004

/model
Enter fullscreen mode Exit fullscreen mode

Opens the model selection menu where you can switch models and configure the thinking effort level.

Three effort levels:

Level Best For
low Simple Q&A, code completion, copy edits
medium General feature work, everyday debugging
high Complex architecture design, hard-to-reproduce bugs, multi-module changes

Opus 4.6 introduces Adaptive Thinking — CC automatically decides whether and how much deep reasoning to apply based on task complexity. You control depth via effort level; you no longer need to write think hard or ultrathink in your prompts.

Three ways to configure it:

# Option 1: use ← → arrow keys to adjust the slider in the /model menu
/model

# Option 2: environment variable
export CLAUDE_CODE_EFFORT_LEVEL=low    # low | medium | high

# Option 3: settings.json
# { "effortLevel": "high" }
Enter fullscreen mode Exit fullscreen mode

/cost — See What the Current Task Cost

/cost
Enter fullscreen mode Exit fullscreen mode

Shows the token count, models used, and total spend for the current session.

Real example: analyzing a 150 MB black-screen log with Opus cost $1.90. Switching to Sonnet for the same task would save roughly 40%, bringing it down to about $1.18.


For cost-sensitive tasks like long log analysis, try Sonnet first. Quality is usually sufficient, and the savings are significant.

/context — See Where Your Tokens Are Going

005

/context
Enter fullscreen mode Exit fullscreen mode

Shows a detailed breakdown of token usage across each part of the current context. Particularly useful during skill or agent development and debugging — helps you pinpoint what's consuming your context budget.

Ctrl + S — Stash Your Current Input

Scenario: you're halfway through typing a long message and realize you need to switch models first — but you don't want to lose what you've written.

Ctrl + S saves the current input. After finishing whatever you needed to do, press Ctrl + S again to restore it.

/btw — Ask a Side Question Without Affecting the Main Conversation

/btw what does the -P flag do in the grep command you just used?
Enter fullscreen mode Exit fullscreen mode

This question is handled in a "sidecar" — it does not affect the main conversation's context or memory. After reading the answer, press Space, Enter, or ESC to return to the main conversation.

Ideal for quickly looking up a command's usage or clarifying a concept without polluting the main thread.

/export — Export the Conversation to a File

/export
Enter fullscreen mode Exit fullscreen mode

Saves the current conversation to a file. Useful for: preserving a valuable debugging session, exporting generated docs or code snippets, archiving the analysis of a complex problem.

Ctrl + R — Search Prompt History

Press Ctrl + R, then type a keyword to search through previous prompts and quickly retrieve one you used before.

Use case: recovering a complex prompt to reuse or fine-tune, without having to write it from scratch.


Configuration Overview

All configuration items and where they live:

~/.claude/
├─ settings.json          # Global settings (notification hooks, global permissions, model preferences)
├─ CLAUDE.md              # Global preferences (cross-project context)
└─ rules/                 # Global rules (cross-project standards, used sparingly)

your-repo/
├─ CLAUDE.md              # Project owner's manual (tech stack, commands, constraints)
└─ .claude/
   ├─ settings.json       # Project-level permission config
   └─ rules/              # Project standards (committed to repo, shared with team)
      ├─ security.md
      ├─ testing.md
      └─ coding-style.md
Enter fullscreen mode Exit fullscreen mode

Summary

Part 2 filled in the other half of CC's configuration system:

  1. Memory: tell CC your preferences once — it remembers and applies them every session
  2. Rules: encode team standards into Rules, giving CC consistent baselines that travel with the repo
  3. Configuration scope: three layers — global, project, session — put things in the right place
  4. Permission management: granular allow/deny beats both "full trust" and "ask everything"
  5. Shortcuts: !, @, /model, /cost, /context, Ctrl+S, /btw, /export, Ctrl+R — each one saves real time in the right situation

Together, Parts 1 and 2 cover most of what falls into the "I know this exists but haven't actually used it well" category for CC. Tools only have value when you use them — pick one or two things to try today.

Questions or better approaches? Leave a comment — always happy to discuss.

Top comments (0)