# D7 · Claude Code

Composants principaux, hiérarchie CLAUDE.md et imports, scopes et permissions de settings.json, gestion de session, slash commands, modes headless et streaming, modes de permission, hooks, config MCP et plan mode.

import { Accordions, AccordionItem, Tabs, TabItem } from '@prosefly/astro-components';

Ce domaine représente environ **2 items sur 53**. Il vérifie que vous savez comment Claude Code est configuré et exploité : la hiérarchie `CLAUDE.md`, les scopes et permissions de `settings.json`, la gestion de session, les slash commands, le mode headless, les hooks, la config MCP et le plan mode. Le thème : **le comportement vient des fichiers de configuration, et les permissions/hooks – pas la prose – imposent le contrôle.**

## Objectifs d’apprentissage
À la fin de cette page, vous devriez être capable de :

1. Identifier les **composants principaux** de Claude Code : Rules/`CLAUDE.md`, Skills, Commands, Agents/subagents, Agent Memory.
2. Expliquer la **hiérarchie `CLAUDE.md`** et les **imports** `@path`.
3. Configurer les scopes de **`settings.json`** et les **permissions** (allow/deny/ask).
4. Gérer les sessions (`/compact`, `/clear`, resume) et utiliser les **slash commands**.
5. Utiliser les modes **headless** (`-p`, `--output-format`) et **streaming** et les **modes de permission**.
6. Configurer les **hooks**, **MCP**, et le **plan mode**.

---

## 7.1 Core components

| Component | Where | Purpose |
| --- | --- | --- |
| **Rules / `CLAUDE.md`** | Hiérarchie de fichiers | Instructions persistantes projet/utilisateur |
| **Skills** | `.claude/skills/<name>/SKILL.md` | Capacités progressives, à la demande (frontmatter name + description) |
| **Commands** | `.claude/commands/*.md` | Slash commands personnalisées avec `$ARGUMENTS` |
| **Agents / subagents** | `.claude/agents/*.md` | Propre prompt système, liste blanche d’outils, modèle ; contexte isolé |
| **Agent Memory** | `/memory` | Notes durables entre sessions |

---

## 7.2 CLAUDE.md hierarchy and imports

Les fichiers `CLAUDE.md` sont de la mémoire : des instructions persistantes que Claude charge au démarrage de la session. Ils se **composent** du plus large au plus étroit, les fichiers plus spécifiques se superposant aux (sans remplacer les) plus larges. La politique managée est au sommet et ne peut pas être outrepassée.

```text
                 ┌─────────────────────────────────────────┐
  highest ►      │  enterprise / managed policy             │  admin-controlled, NOT overridable
  precedence     └─────────────────────────────────────────┘
                                  ↓ composes down
                 ┌─────────────────────────────────────────┐
                 │  user       ~/.claude/CLAUDE.md          │  personal, spans all your projects
                 └─────────────────────────────────────────┘
                                  ↓
                 ┌─────────────────────────────────────────┐
                 │  project    ./CLAUDE.md                  │  checked in; the team standard
                 └─────────────────────────────────────────┘
                                  ↓
                 ┌─────────────────────────────────────────┐
                 │  subdirectory  ./services/api/CLAUDE.md  │  module-specific, loaded when working there
                 └─────────────────────────────────────────┘

  CLAUDE.local.md = git-ignored personal override that lives beside a project file
  @path imports   = pull shared files into any CLAUDE.md, e.g. @docs/standards.md
```

### What belongs where

| Content | File | Reason |
| --- | --- | --- |
| Règles de sécurité à l’échelle de l’org, outils interdits | managed policy | Ne doit pas être outrepassable par un développeur |
| Préférences personnelles (style d’éditeur, notes d’alias) | `~/.claude/CLAUDE.md` | S’applique à vous sur tous les projets |
| Standards de code d’équipe, architecture, commandes build/test | `./CLAUDE.md` | Committé ; source unique de vérité de l’équipe |
| Conventions spécifiques à un module (p. ex. règles de la couche API) | `./services/api/CLAUDE.md` | Chargé seulement en travaillant dans ce sous-arbre |
| Vos notes de travail locales, instructions expérimentales | `CLAUDE.local.md` | Git-ignored ; jamais partagé |
| Standards partagés référencés depuis plusieurs endroits | fichier séparé via import `@path` | Écrire une fois, importer dans le `CLAUDE.md` du projet |
| Secrets, tokens, clés d’API | **aucun de ce qui précède** | Sous gestion de versions ; utilisez `env` / un gestionnaire de secrets |

### Example project CLAUDE.md

```markdown
# Payments Service — Claude memory

## Stack
- Python 3.12, FastAPI, PostgreSQL, pytest.

## Commands
- Install: `uv sync`
- Test: `uv run pytest -q`
- Lint: `uv run ruff check .`

## Conventions
- Money is always integer cents; never floats.
- All external calls go through `app/clients/` with retries and timeouts.
- New endpoints require a test and an entry in `CHANGELOG.md`.

## Imports
@docs/api-style.md
@docs/security-checklist.md

## Guardrails
- Do not run destructive DB commands.
- Do not edit files under `infra/` without an explicit request.
```

:::caution[Les secrets ne vont jamais dans CLAUDE.md]
`CLAUDE.md` est sous gestion de versions et partagé. Mettez les secrets dans des variables d’environnement ou un gestionnaire de secrets et référencez-les par nom. Une clé fuitée dans `CLAUDE.md` est un incident d’exfiltration.
:::

---

## 7.3 settings.json scopes and permissions

`settings.json` contrôle le **comportement** (modèle, permissions, hooks, environnement). Comme la mémoire, il se compose à travers les scopes, et la politique managée ne peut pas être outrepassée.

```text
managed policy  →  user ~/.claude/settings.json  →  project .claude/settings.json  →  .claude/settings.local.json
(not overridable)   (personal, all projects)        (checked in, team baseline)        (git-ignored, personal)
```

Un `settings.json` de projet committé avec `permissions`, `hooks`, et `env` :

```json
{
  "model": "claude-sonnet-5",
  "permissions": {
    "allow": ["Read", "Grep", "Glob", "Edit"],
    "deny": ["Bash(rm -rf:*)", "Bash(git push --force:*)", "Read(./.env)"],
    "ask": ["Bash", "WebFetch"]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": ".claude/hooks/guard-bash.sh" }
        ]
      }
    ]
  },
  "env": {
    "ANTHROPIC_MODEL": "claude-sonnet-5",
    "DEPLOY_ENV": "development"
  }
}
```

- `permissions.allow` exécute l’outil sans demander ; `ask` demande confirmation ; `deny` bloque catégoriquement.
- **`deny` l’emporte sur `allow`.** Un outil correspondant aux deux est refusé.
- Les règles sont des **patterns**, p. ex. `Bash(rm -rf:*)` refuse cette famille de commandes tout en autorisant les autres Bash.
- Préférez le refus par défaut pour les commandes destructrices ; gardez `allow` aux outils dont une tâche a réellement besoin.

:::tip[Signal d’examen]
« Imposer une règle / bloquer une commande / personne ne peut outrepasser » → **permissions + managed policy**, pas une phrase dans `CLAUDE.md`. La prose est une consigne ; les permissions et hooks sont de l’application.
:::

---

## 7.4 Hooks

Les hooks sont des handlers déterministes shell ou HTTP qui se déclenchent sur des événements du cycle de vie. Contrairement aux instructions en prose, ils s’exécutent **toujours** et peuvent bloquer une action — le mécanisme pour imposer les règles métier critiques (l’anti-pattern nº 3 consiste à imposer les règles en prose à la place).

| Event | Fires when | Typical use |
| --- | --- | --- |
| `PreToolUse` | Avant l’exécution d’un outil | Valider/bloquer une commande ; `exit 2` la refuse |
| `PostToolUse` | Après l’exécution d’un outil | Auto-format, lint, exécuter les tests sur les fichiers édités |
| `UserPromptSubmit` | L’utilisateur soumet un prompt | Injecter du contexte ; scanner les secrets |
| `Stop` | L’agent principal a fini de répondre | Imposer des contrôles d’achèvement |
| `SubagentStop` | Un subagent termine | Valider la sortie du subagent |
| `SessionStart` | La session commence | Charger des infos d’environnement, afficher des rappels |
| `Notification` | Claude envoie une notification | Router vers Slack/paging |
| `PreCompact` | Avant la compaction du contexte | Persister l’état qui doit survivre à la compaction |

**Le code de sortie 2 d’un hook bloque l’action** (stderr est montré à Claude) ; les autres codes non nuls sont des erreurs non bloquantes.

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "if grep -qE 'rm -rf|drop table' <<< \"$CLAUDE_TOOL_INPUT\"; then echo 'blocked: destructive command' >&2; exit 2; fi"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          { "type": "command", "command": "uv run ruff format $CLAUDE_FILE_PATHS" }
        ]
      }
    ]
  }
}
```

---

## 7.5 Skills vs slash commands vs subagents

Trois façons d’empaqueter un comportement réutilisable. L’examen teste laquelle convient à un scénario.

| Dimension | Skill | Slash command | Subagent |
| --- | --- | --- | --- |
| Fichier | `.claude/skills/<name>/SKILL.md` | `.claude/commands/<name>.md` | `.claude/agents/<name>.md` |
| Déclencheur | Le modèle le charge **à la demande** quand pertinent | L’utilisateur tape `/<name>` explicitement | Une tâche lui est déléguée (auto ou explicite) |
| Contexte | Progressif ; chargé seulement quand nécessaire | Injecté dans le contexte courant | **Isolé** dans sa propre fenêtre de contexte |
| Propre prompt système / modèle | Non | Non | **Oui** (propre prompt, liste blanche d’outils, modèle) |
| Idéal pour | Une capacité vers laquelle Claude devrait aller automatiquement | Un prompt répétable que vous invoquez à la main | Un worker spécialisé nécessitant de l’isolation |

Skill (`.claude/skills/api-docs/SKILL.md`) :

```markdown
---
name: api-docs
description: Write and format REST API reference docs in the house style. Use when documenting endpoints.
---

# API documentation style

- One H2 per endpoint: `## METHOD /path`.
- Document auth, params (table), request body, responses by status.
- Include a curl example and a JSON response example.
```

Slash command avec `$ARGUMENTS` (`.claude/commands/fix-issue.md`) :

```markdown
---
description: Investigate and fix a GitHub issue by number.
---

Investigate issue #$ARGUMENTS. Read the linked code, reproduce the bug,
propose a fix in plan mode, then implement it with a regression test.
```

Invoquez avec `/fix-issue 482` — `$ARGUMENTS` devient `482`.

Subagent (`.claude/agents/reviewer.md`) :

```markdown
---
name: reviewer
description: Reviews diffs for security and style. Use proactively before commits.
tools: Read, Grep, Glob
model: claude-opus-5
---

You are a senior code reviewer. Review only the staged diff.
Report findings by severity. Do not modify files.
```

:::tip[Signal d’examen]
« Se charge automatiquement quand pertinent / divulgation progressive » → **Skill**. « Une commande que le développeur exécute avec un argument » → **slash command** avec `$ARGUMENTS`. « A besoin de son propre contexte / d’outils restreints / d’un modèle différent / d’isolation » → **subagent**.
:::

---

## 7.6 Plan mode

Le plan mode (entrez avec **Shift+Tab**, ou `--permission-mode plan` en headless) fait explorer Claude en **lecture seule** et produire un plan avant qu’il n’édite quoi que ce soit. C’est la première étape sûre pour les changements importants ou risqués : une migration, un refactoring transversal, ou du code non familier. Vous relisez le plan, puis approuvez l’exécution.

L’examen associe le plan mode aux **grandes migrations automatisées** et à la **réduction des risques** : explorer → planifier → approuver → appliquer avec des tests.

---

## 7.7 Headless mode, streaming and permission modes

<Tabs>
  <TabItem label="Headless">
```bash
# One-shot, sortie exploitable par machine pour la CI
claude -p "Summarise the failing tests" --output-format json

# Événements JSON en streaming (parser incrémentalement)
claude -p "Refactor utils" --output-format stream-json --allowedTools "Read,Edit"

# Revue en lecture seule avec un ensemble d'outils restreint
claude -p "Review the staged diff for security issues; output JSON." \
  --output-format json \
  --allowedTools "Read,Grep" \
  --permission-mode plan
```
`-p` s’exécute de manière non interactive ; `--output-format` vaut `json` ou `stream-json` ; `--allowedTools` restreint l’ensemble d’outils ; `--permission-mode` fixe le comportement de contrôle.
  </TabItem>
  <TabItem label="Permission modes">
`--permission-mode` (ou `permissionMode` dans le SDK) :

| Mode | Behaviour |
| --- | --- |
| `default` | Demander avant les outils non listés en allow |
| `acceptEdits` | Auto-accepter les éditions de fichiers, protéger les autres outils |
| `plan` | Lecture seule ; explorer et planifier, aucun changement |
| `bypassPermissions` | Sauter toutes les invites — dangereux ; uniquement dans une CI de confiance, sandboxée |
  </TabItem>
  <TabItem label="Plan mode">
**Shift+Tab** en interactif entre en plan mode : exploration en lecture seule, puis un plan proposé que vous approuvez avant tout changement. L’équivalent headless est `--permission-mode plan`.
  </TabItem>
</Tabs>

:::tip[Signal d’examen]
« Exécuter Claude Code en CI / de manière non interactive / sortie exploitable par machine » → headless `-p` avec `--output-format json|stream-json` et un `--allowedTools` restreint. « Explorer en toute sécurité avant de changer quoi que ce soit » → plan mode. Jamais `bypassPermissions` en dehors d’un sandbox de confiance.
:::

---

## 7.8 Session commands and MCP configuration

Slash commands pendant une session interactive :

| Command | Effect |
| --- | --- |
| `/compact` | Résumer la conversation côté serveur pour libérer du contexte (garde le fil narratif) |
| `/clear` | Réinitialiser entièrement la conversation (contexte neuf) |
| `/init` | Amorcer un `CLAUDE.md` pour le projet courant |
| `/memory` | Voir/éditer la mémoire de l’agent (fichiers `CLAUDE.md`) |
| `/agents` | Gérer les subagents |
| `/hooks` | Gérer les hooks |
| `/mcp` | Gérer/inspecter les serveurs MCP et l’auth |
| `/cost` | Afficher l’usage en tokens et le coût pour la session |

`/compact` résume pour préserver le fil narratif ; `/clear` jette le contexte — ne les confondez pas.

### MCP config scopes

Ajoutez des serveurs avec `claude mcp add <name> --scope <scope> -- <command>` ou en éditant `.mcp.json` :

| Scope | Stored in | Shared? |
| --- | --- | --- |
| `local` | Votre machine, projet courant uniquement | Non (personnel, ce projet) |
| `project` | `.mcp.json` dans le dépôt | **Oui** — committé, catalogue validé à l’échelle de l’équipe |
| `user` | Votre config utilisateur | Non — s’étend à vos projets, personnel |

```json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
    }
  }
}
```

Utilisez le scope **project** pour un catalogue partagé et validé ; inspectez et authentifiez avec `/mcp`.

---

## 7.9 The permission model in depth: allow / ask / deny and precedence

Le contrôle d’outils de Claude Code est une surface de décision petite mais fortement testée. Les règles sont des **patterns**, elles se composent à travers les scopes, et **`deny` l’emporte sur `allow`** ; la politique managée surplombe tout.

| Decision | Meaning | Use for |
| --- | --- | --- |
| `allow` | Exécuter sans demander | Outils sûrs et fréquemment utilisés (Read, Grep, Glob) |
| `ask` | Demander confirmation | Outils à risque moyen (Bash, WebFetch) |
| `deny` | Bloquer catégoriquement (l’emporte sur `allow`) | Familles de commandes destructrices, lecture de `.env` |

```text
managed policy  →  user settings  →  project settings (.claude/settings.json)  →  settings.local.json
(non-overridable)   (personal)        (checked in, team baseline)                  (git-ignored, personal)

resolution: deny > ask > allow, with more-specific scopes layering over broader ones,
            and managed policy overriding all of them.
```

| Scenario | Correct configuration |
| --- | --- |
| Bloquer `rm -rf` pour tout le monde, de manière non outrepassable | `Bash(rm -rf:*)` dans `deny`, défini via **managed policy** |
| Auto-exécuter les outils de lecture, confirmer le shell | `allow: [Read, Grep, Glob]`, `ask: [Bash]` |
| Ne jamais lire le fichier de secrets | `deny: [Read(./.env)]` |
| Expérience personnelle uniquement | `settings.local.json` (git-ignored) |

:::tip[Signal d’examen]
« Personne ne peut outrepasser ce blocage » → **managed policy** `deny`. « Un outil est à la fois dans allow et deny » → **refusé** (`deny` l’emporte sur `allow`). « Imposer une règle » → permissions/hooks, jamais une phrase de `CLAUDE.md`.
:::

---

## 7.10 Composing memory and settings across scopes

`CLAUDE.md` (mémoire) et `settings.json` (comportement) se composent tous deux du large au étroit, et sont tous deux surplombés par une politique managée non outrepassable. Savoir *ce qui va où* est un item fréquent.

| Layer | `CLAUDE.md` (memory) | `settings.json` (behaviour) |
| --- | --- | --- |
| Managé / entreprise | Règles de sécurité de l’org, outils interdits (non outrepassable) | Permissions/hooks managés (non outrepassable) |
| Utilisateur (`~/.claude/`) | Préférences personnelles sur tous les projets | Défauts personnels de modèle/permission |
| Projet (`./`, `.claude/`) | Standards d’équipe, commandes build/test (committé) | Permissions de base d’équipe, hooks, env (committé) |
| Sous-répertoire / local | Règles de module ; `CLAUDE.local.md` (git-ignored) | `settings.local.json` (git-ignored) |

- Les secrets n’appartiennent à aucun des deux — utilisez des variables d’env / un gestionnaire de secrets.
- Les imports `@path` tirent des fichiers partagés dans n’importe quel `CLAUDE.md`.
- Un fichier de sous-répertoire **se superpose aux** (ne remplace pas les) fichiers plus larges en travaillant dans ce sous-arbre.

:::caution[Les fichiers locaux sont personnels, pas de la politique d’équipe]
`CLAUDE.local.md` et `settings.local.json` sont git-ignored et personnels. Mettre une règle que vous voulez que toute l’équipe suive dans un fichier local signifie que personne d’autre ne l’obtient — utilisez des fichiers de projet committés ou une politique managée.
:::

---

## 7.11 Common misconceptions

| Misconception | Reality | Why it matters on the exam |
| --- | --- | --- |
| Une phrase de `CLAUDE.md` impose une règle | La prose est une consigne ; l’application est permissions/hooks | Anti-pattern nº 3 sous forme Claude Code |
| Les settings de projet peuvent outrepasser la politique managée | La politique managée/entreprise est non outrepassable | Questions de précédence |
| `allow` l’emporte si un outil est aussi refusé | `deny` l’emporte sur `allow` | Piège de résolution de permissions |
| `bypassPermissions` convient par commodité | Uniquement dans une CI de confiance, sandboxée ; il supprime les garde-fous | Piège de sécurité |
| `/compact` et `/clear` sont interchangeables | Compact résume (garde le fil) ; clear réinitialise | Piège de gestion de session |
| Les secrets peuvent vivre dans `CLAUDE.md` comme documentation | Il est sous gestion de versions ; utilisez env/gestionnaire de secrets | Piège d’hygiène des secrets |
| Une slash command se charge automatiquement | Les slash commands sont invoquées par l’utilisateur ; les Skills se chargent à la demande | Skill vs command vs subagent |
| `CLAUDE.local.md` est un bon endroit pour les règles d’équipe | Il est git-ignored et personnel | Piège de scope |

---

## 7.12 Scenario walkthrough: hardening a shared Claude Code setup for CI

**Scénario.** Une équipe utilise Claude Code à la fois en interactif et en CI. La sécurité exige que `rm -rf`, `git push --force`, et la lecture de `.env` soient bloqués pour *tout le monde* et ne puissent pas être outrepassés par un développeur. La CI doit s’exécuter de manière non interactive, produire une sortie exploitable par machine, et ne lire que le code (aucune édition). Les développeurs demandent sans cesse `bypassPermissions` en CI « pour accélérer », et l’un a ajouté « never force-push » à `./CLAUDE.md` en s’attendant à ce que ce soit imposé. Concevez la configuration.

**Trace de raisonnement d’expert.**

1. **Imposez les blocages de commandes destructrices de manière non outrepassable.** Placez les patterns `deny` (`Bash(rm -rf:*)`, `Bash(git push --force:*)`, `Read(./.env)`) dans la **managed policy** pour qu’aucun fichier user/project/local ne puisse les outrepasser ; `deny` l’emporte sur `allow`. La phrase de `./CLAUDE.md` est de la prose, pas de l’application (anti-pattern nº 3) — elle doit être retirée comme un faux sentiment de sécurité et remplacée par la règle de permission.
2. **Configurez correctement la CI.** Headless `claude -p "..." --output-format json` avec un `--allowedTools "Read,Grep,Glob"` explicite et `--permission-mode plan` (lecture seule). C’est exploitable par machine, non interactif et sans édition.
3. **Rejetez `bypassPermissions`.** Il supprime précisément les garde-fous requis et laisserait une étape compromise ou injectée exécuter des commandes destructrices ; ne l’autorisez qu’à l’intérieur d’une automatisation entièrement de confiance et sandboxée — pas la CI générale ici.
4. **Placez les règles d’équipe dans le bon scope.** Les standards de code et les commandes build/test vont dans un `./CLAUDE.md` committé ; les blocages de sécurité vont dans la managed policy ; les expériences personnelles vont dans un `CLAUDE.local.md`/`settings.local.json` git-ignored.
5. **Rejetez les alternatives tentantes.** « Faire confiance à la règle de `CLAUDE.md` » — la prose n’est pas de l’application. « Utiliser `bypassPermissions` pour la vitesse » — supprime les garde-fous. « Ajouter le blocage seulement aux settings de projet » — un développeur pourrait l’outrepasser localement, donc ce doit être de la managed policy.

**Décision correcte.** Patterns `deny` en managed policy pour les commandes destructrices et `.env` ; CI headless avec `--output-format json`, une liste blanche `--allowedTools` en lecture seule, et `--permission-mode plan` ; pas de `bypassPermissions` en dehors d’un sandbox de confiance ; standards d’équipe dans un `CLAUDE.md` committé, éléments personnels dans des fichiers locaux git-ignored.

---

## Pièges de l’examen dans ce domaine
| Piège | Pourquoi c’est faux |
| --- | --- |
| Mettre des secrets dans `CLAUDE.md` | Il est sous gestion de versions ; utilisez env/gestionnaire de secrets |
| Supposer que le `CLAUDE.md` de projet outrepasse la politique managée | La politique managée/entreprise l’emporte et n’est pas outrepassable |
| Utiliser `bypassPermissions` à la légère | Supprime les garde-fous ; uniquement en automatisation de confiance, sandboxée |
| Imposer les règles dans la prose de `CLAUDE.md` au lieu des permissions/hooks | La prose est une consigne, pas de l’application (anti-pattern nº 3) |
| Attendre des invites interactives en CI | Utilisez headless `-p` + `--output-format` + `--allowedTools` |
| Confondre `/compact` avec `/clear` | Compact résume et garde le fil ; clear réinitialise |
| Charger un énorme ensemble d’outils au lieu de subagents | Surcharge la sélection ; utilisez subagents + tool search |
| Oublier que `deny` l’emporte sur `allow` | Un outil dans les deux listes est refusé |
| Utiliser une slash command là où un Skill est nécessaire | Les Skills se chargent à la demande ; les commandes sont invoquées par l’utilisateur |
| Donner à un subagent des outils larges « au cas où » | Viole le moindre privilège ; cadrez la liste blanche |
| Mettre une règle dans `CLAUDE.local.md` pour toute l’équipe | Il est git-ignored et personnel ; utilisez committé/managé |
| Confondre les scopes MCP `local` et `project` | Seul `project` (`.mcp.json`) est partagé/committé |
| Mettre un blocage non outrepassable seulement dans les settings de projet | Un développeur peut l’outrepasser localement ; utilisez la managed policy |
| Supposer que `allow` l’emporte sur `deny` | `deny` l’emporte sur `allow` ; la résolution est deny > ask > allow |
| Imposer une règle de sécurité via une phrase de `./CLAUDE.md` | La prose est une consigne ; utilisez une permission `deny` ou un hook (anti-pattern nº 3) |
| Utiliser `bypassPermissions` en CI générale pour la vitesse | Supprime les garde-fous ; uniquement dans un sandbox entièrement de confiance |
| Stocker les standards d’équipe dans `settings.local.json` | Il est git-ignored et personnel ; utilisez les settings de projet committés |

---

## Questions d’entraînement
<Accordions>
  <AccordionItem title="Q1 · Une équipe exécute Claude Code dans un pipeline CI et a besoin de résultats exploitables par machine sans invites interactives. Quelle invocation convient ? (Sélectionnez une réponse)">
    A. `claude` interactif avec plan mode.
    B. `claude -p "..." --output-format json` avec une liste blanche `--allowedTools` explicite.
    C. `claude` avec `bypassPermissions` et sans format de sortie.
    D. Ouvrir Claude Desktop.

    **Réponse : B.** Headless `-p` avec `--output-format json` et une liste blanche d’outils est le pattern CI. Le plan mode interactif (A) et Desktop (D) ne sont pas headless et ne peuvent pas s’exécuter sans surveillance ; `bypassPermissions` (C) supprime les garde-fous et donne une sortie non structurée que la CI ne peut pas parser.
  </AccordionItem>

  <AccordionItem title="Q2 · Une politique d’entreprise managée interdit l’outil Bash, mais un `CLAUDE.md` de projet dit de l’utiliser et `settings.local.json` l’autorise. Que se passe-t-il ? (Sélectionnez une réponse)">
    A. Le setting de projet l’emporte.
    B. Le setting local l’emporte.
    C. La politique managée l’emporte et Bash reste refusé.
    D. C’est indéfini.

    **Réponse : C.** La politique managée/entreprise est au sommet de la précédence et ne peut pas être outrepassée par la config user, project ou local. La prose dans `CLAUDE.md` (A) n’est pas de l’application, et un fichier local (B) ne peut pas outrepasser un deny managé ; le comportement est bien défini, pas indéfini (D).
  </AccordionItem>

  <AccordionItem title="Q3 · Un sous-répertoire `./services/api/CLAUDE.md` fixe une règle qui entre en conflit avec le `./CLAUDE.md` racine pendant que vous travaillez dans ce sous-arbre. Lequel s’applique, et pourquoi ? (Sélectionnez une réponse)">
    A. Le fichier racine l’emporte toujours car il est committé en premier.
    B. Le fichier de sous-répertoire plus spécifique se superpose pour le travail dans ce sous-arbre, tandis que le fichier racine contribue toujours ; la politique managée outrepasse encore les deux.
    C. Ni l’un ni l’autre ne s’applique ; vous devez les fusionner manuellement.
    D. Seul `CLAUDE.local.md` s’applique dans les sous-répertoires.

    **Réponse : B.** La mémoire se compose du large à l’étroit : le fichier de sous-répertoire ajoute un contexte spécifique au module par-dessus le standard racine, et la politique managée reste non outrepassable au-dessus des deux. La racine ne l’emporte pas simplement (A) ; les fichiers se composent automatiquement plutôt que d’exiger une fusion manuelle (C) ; `CLAUDE.local.md` est un override personnel git-ignored, pas le mécanisme général (D).
  </AccordionItem>

  <AccordionItem title="Q4 · Une équipe veut qu’une famille de commandes destructrices comme `rm -rf` soit bloquée de manière déterministe pour tout le monde, et veut aussi que le blocage soit imposé même si un développeur tente de l’autoriser. Quelles DEUX étapes réalisent cela ? (Sélectionnez deux réponses)">
    A. Ajouter `Bash(rm -rf:*)` à `permissions.deny` dans le `.claude/settings.json` committé.
    B. Écrire « never run rm -rf » dans `./CLAUDE.md`.
    C. Imposer le deny via la managed policy pour qu’il ne puisse pas être outrepassé.
    D. Ajouter un hook `PostToolUse` pour s’excuser après l’exécution de la commande.
    E. Demander aux développeurs d’être prudents.

    **Réponse : A et C.** Un pattern `deny` bloque la famille de commandes de manière déterministe (`deny` l’emporte sur `allow`), et le mettre en managed policy le rend non outrepassable. La prose dans `CLAUDE.md` (B) est une consigne, pas de l’application ; un hook `PostToolUse` (D) se déclenche après les dégâts ; demander aux développeurs (E) n’est pas un contrôle.
  </AccordionItem>

  <AccordionItem title="Q5 · Vous voulez que Claude aille automatiquement chercher un style maison documenté chaque fois qu’il écrit de la documentation de référence d’API, sans que le développeur ait à invoquer quoi que ce soit. Quel composant convient ? (Sélectionnez une réponse)">
    A. Une slash command dans `.claude/commands/`.
    B. Un Skill (`.claude/skills/api-docs/SKILL.md`) avec un name et une description, chargé à la demande.
    C. Un subagent avec son propre modèle.
    D. Une ligne dans `settings.local.json`.

    **Réponse : B.** Les Skills se chargent progressivement et automatiquement quand leur description correspond à la tâche — exactement « y aller quand c’est pertinent ». Une slash command (A) doit être tapée par l’utilisateur ; un subagent (C) sert au travail délégué isolé avec son propre contexte ; un fichier de settings (D) ne porte pas de contenu de capacité rédigé.
  </AccordionItem>

  <AccordionItem title="Q6 · Un développeur veut que `/fix-issue 482` investigue et corrige l’issue GitHub 482. Comment le numéro d’issue est-il passé dans la définition de la commande ? (Sélectionnez une réponse)">
    A. Il est lu automatiquement depuis une variable d’environnement.
    B. Via `$ARGUMENTS` dans le fichier `.claude/commands/fix-issue.md`.
    C. Par la liste blanche d’outils du subagent.
    D. Il ne peut pas prendre d’arguments ; les commandes sont statiques.

    **Réponse : B.** Les slash commands personnalisées substituent le texte après le nom de la commande dans `$ARGUMENTS`. Ce n’est pas une variable d’env (A) ; la liste blanche d’outils (C) régit les permissions du subagent, pas les arguments de commande ; les commandes acceptent bien des arguments (D).
  </AccordionItem>

  <AccordionItem title="Q7 · Un subagent reviewer devrait lire et analyser du code mais ne doit jamais modifier de fichiers, et devrait utiliser un modèle plus puissant pour le jugement. Quelle configuration est correcte ? (Sélectionnez une réponse)">
    A. `tools: Read, Grep, Glob` et `model: claude-opus-5` dans `.claude/agents/reviewer.md`.
    B. Lui donner tous les outils et se fier à un prompt disant « do not edit ».
    C. Le mettre dans `.claude/commands/` avec `$ARGUMENTS`.
    D. Régler `bypassPermissions` pour qu’il s’exécute sans friction.

    **Réponse : A.** Un subagent prend une liste blanche d’outils explicite et son propre modèle ; le restreindre aux outils de lecture impose la règle no-edit, et Opus 5 fournit un jugement plus solide. Une règle par prompt seul (B) n’est pas de l’application ; une slash command (C) n’est pas un agent isolé ; `bypassPermissions` (D) supprime précisément les garde-fous voulus.
  </AccordionItem>

  <AccordionItem title="Q8 · Pendant une longue session, le contexte est presque plein mais le développeur veut garder le fil de travail et continuer. Quelle commande est appropriée, et en quoi diffère-t-elle de l’alternative ? (Sélectionnez une réponse)">
    A. `/clear`, car elle libère le plus d’espace.
    B. `/compact`, qui résume côté serveur en préservant le fil narratif ; `/clear` jetterait entièrement la conversation.
    C. `/init`, pour reconstruire le contexte.
    D. `/memory`, pour effacer les anciens tours.

    **Réponse : B.** `/compact` résume pour libérer du contexte tout en gardant la continuité ; `/clear` réinitialise tout et perd le fil narratif. `/init` (C) amorce un `CLAUDE.md` ; `/memory` (D) édite les fichiers de mémoire, pas la transcription en direct.
  </AccordionItem>

  <AccordionItem title="Q9 · Une équipe veut un ensemble validé de serveurs MCP partagé à travers le dépôt et committé sous gestion de versions. Quel scope devrait-elle utiliser ? (Sélectionnez une réponse)">
    A. Le scope `local`.
    B. Le scope `user`.
    C. Le scope `project` via `.mcp.json`, committé dans le dépôt.
    D. Il n’y a aucun moyen de partager des serveurs MCP.

    **Réponse : C.** Le scope projet stocke les serveurs dans `.mcp.json` dans le dépôt, rendant un catalogue partagé et validé disponible à l’échelle de l’équipe. `local` (A) est personnel à une machine/un projet ; `user` (B) ne s’étend qu’à vos propres projets ; le partage est clairement possible (D).
  </AccordionItem>

  <AccordionItem title="Q10 · Avant une grande migration automatisée sur de nombreux fichiers, quelle est la première étape la plus sûre dans Claude Code ? (Sélectionnez une réponse)">
    A. Appliquer toutes les éditions immédiatement, puis relire le diff.
    B. Utiliser le plan mode (Shift+Tab ou `--permission-mode plan`) pour explorer en lecture seule et produire un plan, puis approuver et appliquer avec des tests.
    C. Régler `bypassPermissions` pour aller vite.
    D. Supprimer les tests pour éviter le bruit.

    **Réponse : B.** Le plan mode explore sans éditer et fournit un plan relisible, réduisant le rayon d’impact sur les grands changements. Appliquer à l’aveugle (A), contourner les permissions (C), et retirer les tests (D) augmentent tous le risque.
  </AccordionItem>

  <AccordionItem title="Q11 · Quelles DEUX pratiques imposent correctement une règle critique et gèrent l’accès aux outils dans Claude Code ? (Sélectionnez deux réponses)">
    A. Un hook `PreToolUse` qui sort avec le code 2 pour bloquer une commande interdite.
    B. Un pattern `permissions.deny` pour la commande interdite.
    C. Un paragraphe dans `CLAUDE.md` décrivant la règle.
    D. `tool_choice` défini dans le texte du prompt.
    E. Faire confiance au modèle pour se souvenir de l’instruction.

    **Réponse : A et B.** Un hook `PreToolUse` renvoyant le code de sortie 2 bloque l’action de manière déterministe, et un pattern `deny` refuse l’outil catégoriquement — les deux sont de l’application. La prose dans `CLAUDE.md` (C) et le recours à la mémoire (E) sont des consignes, pas du contrôle ; `tool_choice` (D) est un paramètre d’API, pas un mécanisme de permission de Claude Code.
  </AccordionItem>

  <AccordionItem title="Q12 · Un développeur veut des instructions expérimentales personnelles qui ne doivent jamais être committées ni partagées avec les collègues. Où appartiennent-elles ? (Sélectionnez une réponse)">
    A. `./CLAUDE.md`.
    B. Managed policy.
    C. `CLAUDE.local.md` (git-ignored) ou `settings.local.json`.
    D. `.mcp.json`.

    **Réponse : C.** `CLAUDE.local.md` et `settings.local.json` sont des overrides personnels git-ignored — le bon foyer pour les expériences non partagées. `./CLAUDE.md` (A) est committé et partagé ; la managed policy (B) est à l’échelle de l’org et non outrepassable ; `.mcp.json` (D) configure les serveurs MCP, pas les instructions.
  </AccordionItem>

  <AccordionItem title="Q13 · Un outil correspond à la fois à un pattern `allow` et à un pattern `deny` dans les settings résolus. Que se passe-t-il ? (Sélectionnez une réponse)">
    A. `allow` l’emporte car il est listé en premier.
    B. `deny` l’emporte ; la résolution est deny > ask > allow.
    C. L’outil demande à l’utilisateur à chaque fois.
    D. Le comportement est indéfini.

    **Réponse : B.** `deny` l’emporte sur `allow` dans la résolution des permissions. L’ordre ne décide pas (A) ; il est refusé, pas une invite `ask` (C) ; et le comportement est bien défini (D).
  </AccordionItem>

  <AccordionItem title="Q14 · La sécurité a besoin que `rm -rf` soit bloqué pour tout le monde sans qu’aucun développeur puisse l’outrepasser. Où la règle `deny` doit-elle vivre ? (Sélectionnez une réponse)">
    A. Dans le `settings.local.json` de chaque développeur.
    B. Dans la politique managée/entreprise, qui est non outrepassable et l’emporte sur `allow`.
    C. Dans `./CLAUDE.md` comme une phrase.
    D. Dans un hook `PostToolUse`.

    **Réponse : B.** Seule la managed policy est non outrepassable par la config user/project/local. Les fichiers locaux (A) peuvent être modifiés par le développeur ; une phrase de `CLAUDE.md` (C) est de la prose, pas de l’application ; un hook `PostToolUse` (D) se déclenche après l’exécution de la commande.
  </AccordionItem>

  <AccordionItem title="Q15 · Un job CI doit s’exécuter de manière non interactive, produire des résultats exploitables par machine, et ne jamais éditer de fichiers. Quelle invocation convient le MIEUX ? (Sélectionnez une réponse)">
    A. `claude` interactif avec plan mode.
    B. `claude -p "..." --output-format json --allowedTools "Read,Grep,Glob" --permission-mode plan`.
    C. `claude -p "..." --permission-mode bypassPermissions`.
    D. Claude Desktop avec MCP.

    **Réponse : B.** Headless `-p` avec sortie JSON, une liste blanche en lecture seule, et plan mode est non interactif, exploitable par machine et sans édition. Le plan mode interactif (A) et Desktop (D) ne sont pas headless ; `bypassPermissions` (C) supprime les garde-fous et ne garantit pas la lecture seule.
  </AccordionItem>

  <AccordionItem title="Q16 · Un développeur ajoute « never force-push » à `./CLAUDE.md` et s’attend à ce que ce soit imposé. Pourquoi est-ce insuffisant, et que devrait-il faire ? (Sélectionnez une réponse)">
    A. C’est suffisant ; les règles de `CLAUDE.md` sont imposées.
    B. `CLAUDE.md` est une consigne, pas de l’application ; ajoutez `Bash(git push --force:*)` à `permissions.deny` (idéalement via la managed policy) ou un hook PreToolUse.
    C. Déplacer la phrase dans `settings.local.json`.
    D. Augmenter le niveau d’effort du modèle.

    **Réponse : B.** La prose dans `CLAUDE.md` est une suggestion (anti-pattern nº 3 sous forme Claude Code) ; un pattern `deny` ou un hook PreToolUse l’impose de manière déterministe. Ce n’est pas suffisant (A) ; un fichier local (C) est personnel et n’est pas de l’application ; l’effort (D) est sans rapport.
  </AccordionItem>

  <AccordionItem title="Q17 · Pendant une longue session, le contexte est presque plein mais le développeur doit garder le fil de travail. Quelle commande convient, et en quoi diffère-t-elle de l’alternative ? (Sélectionnez une réponse)">
    A. `/clear`, car elle libère le plus d’espace.
    B. `/compact`, qui résume côté serveur en préservant le fil narratif ; `/clear` jetterait entièrement la conversation.
    C. `/init`, pour reconstruire le contexte.
    D. `/memory`, pour effacer les anciens tours.

    **Réponse : B.** `/compact` résume pour libérer du contexte tout en gardant la continuité ; `/clear` réinitialise tout. `/init` (C) amorce un `CLAUDE.md` ; `/memory` (D) édite les fichiers de mémoire, pas la transcription en direct.
  </AccordionItem>

  <AccordionItem title="Q18 · Une équipe veut des standards de code partagés avec tout le monde, mais un développeur a besoin d’une instruction expérimentale personnelle qui ne doit jamais être committée. Où appartient chacun ? (Sélectionnez une réponse)">
    A. Les deux dans `./CLAUDE.md`.
    B. Les standards dans un `./CLAUDE.md` committé ; l’expérience personnelle dans un `CLAUDE.local.md` git-ignored.
    C. Les deux dans `settings.local.json`.
    D. Les deux dans la managed policy.

    **Réponse : B.** Les standards d’équipe vont dans le fichier de projet committé ; les instructions personnelles non partagées vont dans le fichier local git-ignored. Mettre l’élément personnel dans `./CLAUDE.md` (A) le partage ; les fichiers locaux (C) cacheraient les standards d’équipe aux autres ; la managed policy (D) est pour les règles d’org non outrepassables, pas les expériences personnelles.
  </AccordionItem>
</Accordions>

## À retenir
- Composants principaux : Rules/`CLAUDE.md`, Skills, Commands, Agents/subagents, Agent Memory.
- La précédence de `CLAUDE.md` se compose du large à l’étroit : managed → user → project → subdirectory ; `CLAUDE.local.md` est git-ignored ; les imports `@path` tirent des fichiers partagés ; les secrets n’appartiennent jamais ici.
- `settings.json` se compose à travers les mêmes scopes ; `permissions` (`allow`/`ask`/`deny`) imposent les outils de manière déterministe ; **`deny` l’emporte sur `allow`** et la politique managée est non outrepassable.
- Les hooks (PreToolUse, PostToolUse, UserPromptSubmit, Stop, SubagentStop, SessionStart, Notification, PreCompact) sont déterministes ; **le code de sortie 2 bloque** l’action — la façon d’imposer les règles critiques plutôt que la prose.
- Skill = capacité auto/progressive ; slash command = prompt invoqué par l’utilisateur avec `$ARGUMENTS` ; subagent = contexte isolé avec son propre prompt, sa liste blanche d’outils et son modèle.
- Le plan mode explore en lecture seule et propose un plan avant les éditions — la première étape sûre pour les changements importants/risqués.
- Headless `-p` + `--output-format json|stream-json` + `--allowedTools` + `--permission-mode` pour la CI ; `bypassPermissions` uniquement dans un sandbox de confiance.
- Commandes de session : `/compact` (résumer, garder le fil) vs `/clear` (réinitialiser) ; `/init`, `/memory`, `/agents`, `/hooks`, `/mcp`, `/cost`. Scopes MCP : `local` (personnel), `project` (`.mcp.json`, partagé/committé), `user` (vos projets).
- La résolution des permissions est **deny > ask > allow**, se composant du large à l’étroit, avec la politique managée non outrepassable — un blocage non outrepassable doit vivre en managed policy, pas dans les settings de projet ou locaux.
- `CLAUDE.md` et `settings.json` se composent tous deux à travers les mêmes scopes ; les standards d’équipe vont dans des fichiers de projet committés, les éléments personnels dans des fichiers locaux git-ignored, et les secrets dans aucun.
- Une règle que vous voulez imposée est un pattern `deny` ou un hook, jamais une phrase de `CLAUDE.md` (anti-pattern nº 3 sous forme Claude Code).
