PTENES
MODULE 2.1

📘 CLAUDE.md and the .claude/ folder

The heart of a project's Claude Code configuration—instructions, settings, hooks, slash commands, permissions.

7
Topics
35
Minutes
Inter.
Level
Practical
Type

🎯What you get here

Know EXACTLY where to put each piece of Claude Code configuration. Move from “I threw everything into CLAUDE.md” to putting settings, hooks, slash commands, and permissions in the right places — where they work.

Detailed content

1

📜 CLAUDE.md — hierarchy and scope

CLAUDE.md exists at three levels, all concatenated into the system prompt in order. Getting the hierarchy wrong can make project instructions override global ones without you noticing, or worse — global instructions can drown out project-specific preferences.

The 3 levels (from most general to most specific)

~/.claude/CLAUDE.md         ← Global (você, todos os projetos)
   ↓ concatena
./CLAUDE.md                 ← Projeto (raiz)
   ↓ concatena
./src/api/CLAUDE.md         ← Subdir (escopo desta pasta)

When Claude opens a file in src/api/, see all 3 files. When you open one in src/ui/, you see only the first 2 (global + project).

✓ Good CLAUDE.md

  • • LITERAL build/test/lint commands at the top
  • • Non-obvious conventions (don't repeat what the linter already enforces)
  • • Links to deep ADRs/runbooks
  • • Preferred tone of voice in responses
  • • < 2KB (fits without scrolling)

✗ Bloated CLAUDE.md

  • • Repeats the entire style guide (which is already in .editorconfig)
  • • Project history (irrelevant to the agent)
  • • HR policy (not a code instruction)
  • • 50+ KB of generic "best practices"
  • • Internal library documentation

💡Golden rule

If the content can be read on demand (reference), put it in references/ of a skill or in docs/ from the project. If it’s always necessary (build commands, core conventions), put them in CLAUDE.md. Default: everything goes in references/, unless proven otherwise.

Key concepts

3 levels
Global, project, subdir
Concatenation
Everything goes into the prompt
Precedence
Specific wins
2KB rule
Fit without scrolling
2

📂 Complete .claude/ folder structure

The convention is strict: the right name, the right folder, or Claude won't see it. Here's the map you can print and tape next to your monitor:

.claude/                          ─ raiz do projeto (também ~/.claude/ global)
├── CLAUDE.md                      ─ instruções (pode estar na raiz do projeto)
├── settings.json                  ─ permissões, modelo, env, hooks
├── settings.local.json            ─ override local (.gitignore)
│
├── agents/                       ─ SUB-AGENTS em Markdown
│   ├── code-reviewer.md
│   └── doc-writer.md
│
├── skills/                       ─ SKILLS (pastas com SKILL.md)
│   └── my-skill/
│       ├── SKILL.md             ─ frontmatter + body
│       ├── scripts/             ─ scripts auxiliares
│       ├── references/          ─ docs lazy-load
│       └── assets/              ─ imagens/binários
│
├── commands/                     ─ SLASH COMMANDS
│   ├── review.md                ─ /review
│   ├── ship.md                  ─ /ship
│   └── plugin/sub.md            ─ /plugin:sub (namespaced)
│
├── hooks/                        ─ scripts disparados em eventos
│   ├── pre-commit.sh
│   └── on-stop.sh
│
└── output-styles/                ─ estilos de resposta
    └── concise.md

Global vs. project — same structure

All of this exists the same way in ~/.claude/ (your preferences, apply to every project) and in ./.claude/ (specific to that project, committed to git). Project skills/agents take precedence over global ones when the names match.

⚠️Common path errors

  • • Put the skill in .claude/skill/ (singular) → Claude doesn't see
  • • Lowercase SKILL.md → not recognized
  • • Sub-agent in .claude/sub-agents/ → has to be agents/
  • • Slash command without .md → ignored

Key concepts

Convention
Right Name, Right Folder
Mirror layout
Global = project
Precedence
Project > global
Partial gitignore
.local.json outside
3

⚙️ settings.json — what you control

JSON file with behavioral configuration. This is where you reduce permission friction, switch models, and inject hooks. Cascading override: user (~/.claude/) → project (.claude/) → local (.claude/settings.local.json).

commented settings.json (real example)

{
  "model": "claude-opus-4-6",         // modelo padrão da sessão
  "includeCoAuthoredBy": true,         // Co-Authored-By em commits

  "permissions": {
    "allow": [
      "Bash(ls:*)", "Bash(cat:*)",           // libera leitura
      "Bash(git status:*)", "Bash(git log:*)", // git read-only
      "Read", "Grep", "Glob"                   // tools básicas
    ],
    "deny": [
      "Bash(rm -rf:*)",                       // nunca
      "Bash(curl:* | sh)"                     // pipe pra shell = não
    ],
    "ask": [
      "Bash(git push:*)",                     // sempre confirma
      "Write", "Edit"                          // escrita = confirma
    ]
  },

  "env": {
    "CLAUDE_PROJECT_DIR": "${cwd}",
    "NODE_ENV": "development"
  },

  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "./scripts/log-bash.sh"
      }]
    }]
  }
}

user

~/.claude/settings.json

Your preferences across all projects. Model, theme, tone of voice.

project

.claude/settings.json

It goes into git. Permissions and hooks the whole team inherits.

local

.claude/settings.local.json

Local override (.gitignore). Credentials, dev env.

Key concepts

User → project → local cascade
Each one overrides
allow/deny/ask
3 permission verbs
Env interpolation
${cwd}, ${env}
Matchers
Glob per tool
4

🪝 Hooks — the only way to guarantee behavior

Hooks are shell commands triggered by the harness in agent events. They RUN; they don’t depend on Claude remembering to do it. It’s the only way to guarantee determinism ("always lint before commit").

⏮

PreToolUse — before each tool

Runs before for Claude to run a tool. It can block (exit ≠ 0) or just log.

Classic use case: block dangerous commands, log every Bash command, redirect Read to indexed MCP.

⏭

PostToolUse — after each tool

Runs then. Receives the tool output and can annotate context for future rounds.

Classic use case: run a formatter after Edit, validate JSON after Write, index the changed file.

⏹

Stop — when the agent decides to stop

Runs when Claude finishes the turn. Allows a final check.

Classic use case: run tests, validate the diff before handing back control, require a completed checklist.

🟢

SessionStart and UserPromptSubmit

SessionStart: runs when you open a session. UserPromptSubmit: with each message you send.

Classic use case: SessionStart populates MCP, UserPromptSubmit injects additional context (claude-mem, etc.).

💡Memory does NOT replace a hook

When you ask it to "always do X," Claude may forget (it's not deterministic). A hook RUNS. Asked it to run lint before committing? Hook. Asked it to log commands? Hook. Skill memory helps, but for a guarantee, use a hook.

Key concepts

Deterministic
Always run
Exit code
0 ok, ≠0 blocks
Fail-open vs. fail-closed
Error policy
Matchers
Filter by tool
5

⚡ Custom slash commands

Markdown files in .claude/commands/ that automatically become slash commands. A task you repeat? It becomes /comando and disappears.

Example — .claude/commands/review.md

---
description: Revisa o diff atual procurando bugs de correção
allowed-tools: Bash(git diff:*), Read, Grep
---

Revise o diff atual da branch.

Procure:
- Bugs de correção (não estilo)
- Casos não tratados (null, vazio, edge)
- Vulnerabilidades comuns (SQLi, XSS, path traversal)

Use \`$ARGUMENTS\` se passado para focar em arquivo específico.

Retorne uma lista numerada de findings + severity.

Usage: /review or /review src/api/auth.ts

✓ Good slash command use cases

  • • /review — reviews the current diff
  • • /ship — pre-merge checklist
  • • /test — generates tests for the open file
  • • /explain — explains the selected passage
  • • /changelog — generates a CHANGELOG entry

✗ Poor slash command use

  • • Huge content that should be a skill
  • • A command that only makes sense for you (use user-level, not project-level)
  • • No allowed-tools (anything goes)
  • • No description (you only find out by reading the file)

Key concepts

$ARGUMENTS
Command arguments
allowed-tools
Restrict surface
Namespace
/plugin:sub
User vs. project
Slash scope
6

🔐 Permission system — friction vs. security

Three verbs: allow (unlocks), deny (blocks), ask (asks). Poorly calibrated configuration creates friction (asking about everything) or risk (allowing too much).

Category
Recommended
Example
Read/analyze
allow
Read, Grep, Glob, Bash(ls:*)
Read-only Git
allow
Bash(git status:*), Bash(git log:*)
Editing
ask
Edit, Write
Push/merge
ask
Bash(git push:*), Bash(gh pr merge:*)
Destructive
deny
Bash(rm -rf:*), Bash(git push --force:*)
Curl with a pipe
deny
Bash(curl:* | sh)

Session modes

Independent of the permissions of settings.json, you can switch MODES live:

  • default: use the exact settings
  • acceptEdits: accepts Edit/Write without asking (useful in refactoring)
  • plan: only plans, never edits (useful in architecture)
  • bypassPermissions: ignores everything (dangerous — only for a sandbox environment)

Key concepts

3 verbs
allow/deny/ask
Glob patterns
Bash(cmd:*)
Modes
plan, acceptEdits
MCP allowlist
mcp__server__
7

🧪 Plan mode and output styles

Two mechanisms for switching behavior live without editing settings. Plan mode freezes editing (Claude plans, doesn’t act). Output styles change the response tone (concise, verbose, explanatory, etc.).

📋 Plan mode

Activated by /plan or flag --plan. Claude reads, thinks, proposes—but doesn’t write or run anything destructive until you exit the mode.

When to use: major refactor, architectural choice, bug hypothesis. You want alignment before taking action.

🎨 Output styles

Activated by /output-style concise. Live in .claude/output-styles/<nome>.md. They change the tone without touching the system prompt.

Built-in: concise (goal-oriented), verbose (detailed), explanatory (teaching-focused). Customize by creating your own.

💡Practical combo

Starting a new architecture task? Go to /plan + /output-style verbose. Claude designs everything, you review it, then you exit plan mode and it executes.

Key concepts

Session mode
You don't need to edit settings
/plan
Reads only, doesn't write
/output-style
Response tone
Customization
.md in output-styles/

🎯Module summary

✓
CLAUDE.md has 3 levels — global, project, subdirectory; all concatenated.
✓
.claude/ has a strict convention — agents/, skills/, commands/, hooks/, output-styles/.
✓
cascading settings.json — user → project → local.json (gitignore).
✓
Hooks are deterministic — the only way to GUARANTEE behavior.
✓
Slash commands = a recurring task turned into a command — .md in .claude/commands/.
✓
allow reading, ask for writing, deny destructive actions — default calibration.
✓
Plan mode + output styles adjust live — without editing settings.

Next module:

2.2 — Skills, sub-agents, and MCP in Claude Code