AIDive

Pack vidéo

Les habitudes Claude Code en commandes : hook, /goal, relecteur et checklist

5 min de lecture

TL;DR et verdict

Une règle écrite dans CLAUDE.md est un conseil que Claude pèse. Une règle transformée en commande s'exécute que Claude la lise ou non. Nous avons pris une API de facturation (Node 20, TypeScript, vitest) sur notre propre machine, avec Claude Code 2.1.294, et lancé cinq habitudes sous forme de cinq commandes.

  • Terminé : avec /goal, la réponse a affiché toute la sortie de vitest, "Tests 44 passed (44)", et l'objectif a été marqué atteint après 1 tour. Sans lui, Claude a seulement dit "pnpm test passes (37/37)" et la sortie est restée repliée dans un appel d'outil.
  • Une règle qui doit tenir : un hook PreToolUse a bloqué 2 modifications du fichier de migrations protégé, et Claude a modifié le reste.
  • Une tâche par contexte : /clear a fait passer la conversation de 26.4k tokens à 130 tokens.
  • Charger ce que vous utilisez : /skill-doctor a trouvé 52 skills chargés mais jamais invoqués (13 + 14 + 25).
  • Relecture neuve : un relecteur en lecture seule a trouvé le même bug d'ordre en cas d'égalité que la session auteur, plus un test manquant, et a affirmé une vérification des types propre qu'il ne pouvait pas avoir exécutée.

Verdict : mettez le hook en place en premier, sur la règle déjà enfreinte dans votre repo. /clear et /skill-doctor ne coûtent rien. Gardez /goal pour les longues exécutions et le relecteur pour le merge. Le pack vous donne les fichiers.

Synthèse sourcée

Une ligne de CLAUDE.md n'est pas appliquée de force. Les bonnes pratiques d'Anthropic disent qu'une ligne comme Always typecheck before you finish fonctionne la plupart du temps, pas à chaque fois s1. La documentation sur la mémoire ajoute une cible de moins de 200 lignes par CLAUDE.md, car des fichiers plus longs consomment plus de contexte et réduisent le respect des règles s6. Notre fichier de test avait quatre règles, dont une en majuscules : "NEVER edit src/store/migrations.ts".

/goal juge ce qui est à l'écran. L'évaluateur n'exécute pas de commandes et ne lit pas de fichiers, donc la condition doit être quelque chose que la sortie de Claude peut démontrer s2. C'est pourquoi notre condition demande que la sortie complète des tests soit affichée dans la conversation. Un retour d'expérience d'une équipe avec environ 600 PRs a constaté que son pire bug passait tsc, le lint et les propres tests de l'agent s8. Un contrôle de fin qui ne peut jamais être satisfait boucle jusqu'à un plafond de blocages s9.

Un hook qui sort avec 2 bloque l'appel. Dans le guide des hooks, la sortie 2 signifie bloquer l'action s3. Lors de notre essai, avec la règle retirée de CLAUDE.md, Claude s'est dirigé deux fois vers le fichier de migrations et les deux modifications ont été bloquées avec notre message. Avec la ligne en majuscules, Claude a refusé de lui-même, et lors de 2 essais ultérieurs il a lu le script du hook d'abord et n'a jamais essayé le fichier. Un fil sur Hacker News formule la critique la plus nette : un blocage est déterministe, ce que le modèle fait ensuite ne l'est pas s10.

/clear est gratuit, et il vide la bonne chose. Les bonnes pratiques disent que /clear entre deux tâches sans rapport ne coûte rien s1. Après notre fonctionnalité, /context affichait 57.5k sur 1m de tokens, avec 26.4k pour les messages. Après /clear, il affichait 31.1k, avec 130 tokens pour les messages. Les instructions, les outils et les skills sont restés.

/skill-doctor nomme ce que vous n'utilisez jamais. Il signale les skills de la liste qui n'ont jamais été invoqués et indique où les désactiver s7. Sur notre machine, il a rapporté 13 skills chargés mais jamais invoqués, 14 synchronisés depuis claude.ai et 25 skills de plugins : 52 au total, plus 4 plugins non utilisés récemment. La place de la liste est limitée : un article a constaté que 267 caractères en trop dans une description ont réduit 7 autres skills à de simples noms s12. Le gain, c'est du bruit en moins, pas un contexte divisé par deux.

Un relecteur neuf aide parce qu'il n'a pas vu votre raisonnement. Les bonnes pratiques le disent directement, et ajoutent que confier la même tâche à un subagent n'améliore pas la réponse s1. Chaque subagent démarre avec une fenêtre de contexte neuve et isolée s5. Cela a un coût : un utilisateur a mesuré environ 51k tokens par subagent au démarrage s14, donc appelez-le une fois par fonctionnalité. Notre relecteur a tourné 28 s en arrière-plan.

Code

  • goal-conditions.md

# /goal conditions

The /goal judge reads only the conversation. It does not run commands or read files, so write the condition as something Claude's own output can demonstrate. Name one end state and the proof you want printed on screen.

## 1. The one we used (overdue invoices endpoint)

```
/goal GET /invoices/overdue returns the overdue invoices with page and pageSize query params, new tests cover it, and the full pnpm test output showing every test passing is printed in this conversation
```

Result on our run: the reply printed the full vitest output, then the goal was marked achieved.

## 2. Template: a bug fix

```
/goal <the failing behaviour> no longer happens, a new test reproduces it and passes, and the full <your test command> output showing every test passing is printed in this conversation
```

## 3. Template: a refactor

```
/goal <the old name or pattern> no longer appears in the code, the output of <your search command> showing no matches is printed in this conversation, and the full <your test command> output showing every test passing is printed too
```

## Rules for all three

- One end state, not a list of wishes.
- The proof is output Claude prints (test results, a search result), never "it works".
- Do not write a condition Claude cannot meet; an unsatisfiable goal loops.
- Check it with `/goal` alone; remove it with `/goal clear`.

goal-conditions.md on GitHub

: la condition `/goal` exacte que nous avons utilisée, plus 2 modèles construits sur la même règle. Collez-en un après `/goal` avant de demander une fonctionnalité. -

protect-migrations.sh

#!/bin/sh
# Block edits to the append-only migrations file
path=$(jq -r '.tool_input.file_path // empty')
case "$path" in
  *src/store/migrations.ts)
    echo "migrations.ts is append-only: add a new migration file instead" >&2
    exit 2 ;;
esac
exit 0

protect-migrations.sh on GitHub

: le script du hook. Il lit le chemin du fichier et sort avec 2 et une raison quand le chemin se termine par `src/store/migrations.ts`. Enregistrez-le sous `.claude/hooks/protect-migrations.sh` et lancez `chmod +x` dessus. Il a besoin de `jq`. Changez le chemin pour le fichier que vous protégez. -

settings.json

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Edit|Write",
        "hooks": [ { "type": "command", "command": ".claude/hooks/protect-migrations.sh" } ] }
    ]
  }
}

settings.json on GitHub

: enregistre le script comme hook PreToolUse sur `Edit|Write`. Fusionnez-le dans `.claude/settings.json`. -

reviewer.md

---
name: reviewer
description: Read-only code reviewer. Use it to review the current git diff before a merge, against the conventions in README.md.
tools: Read, Grep, Glob, Bash(git diff:*), Bash(git status:*)
---

You review a diff you did not write. You never edit files.

1. Run `git diff` and read every changed file in full.
2. Read README.md and check the diff against each of its conventions.
3. Look for bugs: wrong edge cases, missing validation, untested branches, behaviour that breaks existing routes.

Report each finding with the file, the line, what is wrong and why it matters. Say plainly when you find nothing real. No style nits.

reviewer.md on GitHub

: le subagent relecteur en lecture seule, avec les outils Read, Grep, Glob, `Bash(git diff:*)` et `Bash(git status:*)`. Enregistrez-le sous `.claude/agents/reviewer.md`. -

checklist.md

# Clear and skill-doctor checklist

After every finished task
1. Run `/context` and read what the session carries.
2. Run `/clear` before the next unrelated task.
3. Run `/context` again; the conversation should be near empty while instructions, tools and skills stay.
4. In the middle of a task, do not clear: use `/compact` with a focus instead.

Once a month
1. Run `/skill-doctor` (needs a recent Claude Code release).
2. Skills loaded but never invoked: turn them off in `/skills` (space bar cycles).
3. Skills synced from claude.ai: switch them off on the web side, deleting them locally brings them back.
4. Plugin skills: disable the plugin in the Installed tab.
5. Keep what you use rarely but still need.

checklist.md on GitHub

: la routine `/context`, `/clear` et `/skill-doctor` sur une page.

À faire lundi

  • Ouvrez votre CLAUDE.md et marquez chaque ligne qui doit tenir à chaque fois, pas seulement la plupart du temps.
  • Copiez protect-migrations.sh et settings.json dans .claude/, pointez le chemin vers votre fichier protégé, puis demandez à Claude de le modifier et regardez le blocage.
  • Avant votre prochaine fonctionnalité, tapez /goal avec une condition qui demande d'afficher la sortie complète des tests.
  • Quand cette tâche est terminée, lancez /context, puis /clear, puis /context à nouveau.
  • Lancez /skill-doctor et désactivez ce que vous n'avez jamais invoqué. Pour les skills synchronisés, faites-le côté web.
  • Copiez reviewer.md dans .claude/agents/ et demandez une relecture du diff avant votre prochain merge.
  • Lancez vous-même la vérification des types après la relecture. Notre relecteur en a affirmé une qu'il ne pouvait pas exécuter.

Pour aller plus loin

Nous avons laissé ces sujets de côté.

  • Audit de prompt. /doctor prompt-audit et l'argument "règle plus forte, fichier plus long". Vérifiez la version minimale dans la référence des commandes s4.
  • Skills qui ne se déclenchent jamais. Cela concerne les descriptions, pas ce qui est chargé. L'article de primeline est le bon point de départ s12.
  • Élagage des MCP. Un article a mesuré 12 serveurs MCP à 5.8k tokens avec la recherche d'outils et 63k sans, donc c'est moins important qu'avant s13.
  • CLAUDE.md plus gros. Un billet est passé de 455,530 à 88,584 caractères sur neuf fichiers, et note que les imports @path se chargent immédiatement tandis que les liens simples se chargent à la demande s11.
  • /batch. Pour les gros refactorings, la référence des commandes indique de 5 à 30 unités, un worktree chacune s4. Nous ne l'avons pas testé.
  • Seuils manuels de /compact. Nous n'avons trouvé aucune source pour un pourcentage fixe, donc nous n'en donnons pas.

FAQ

/goal remplace-t-il le fait de lancer les tests moi-même ? Non. Le juge ne lit que la conversation. Il vérifie que la sortie a été affichée, pas qu'elle est vraie.

Le hook empêche-t-il Claude d'essayer la modification ? Non. Il bloque la modification une fois que Claude l'essaie. Lors de notre essai, Claude s'est dirigé deux fois vers le fichier sans règle dans CLAUDE.md, et les deux modifications ont été bloquées.

Dois-je supprimer mes règles de CLAUDE.md une fois que j'ai un hook ? Non. Avec la ligne en majuscules, Claude a refusé la modification de lui-même, ce qui évite un appel bloqué. Gardez-le pour ce que Claude ne peut pas déduire de votre code.

Pourquoi ne pas utiliser le relecteur à chaque modification ? Chaque subagent démarre avec son propre contexte complet, donc il coûte de vrais tokens. Utilisez-le une fois par fonctionnalité, avant le merge.

/skill-doctor fonctionnera-t-il sur ma version ? Il dépend d'un feature flag et d'une version récente, d'après la référence des commandes s4. Sur la 2.1.294, il a fonctionné sur notre machine, mais mettez Claude Code à jour d'abord si ce n'est pas le cas chez vous.

Fichiers