Claude Code — hooks pre-commit, sécurité et workflow de code review
Maîtriser les hooks Claude Code : pre-commit, post-tool, sécurité des scripts et bonnes pratiques de workflow.
Temps estimé : 60 min
Résultat final : Inventaire complet des hooks ECC actifs documenté, deux nouveaux hooks de sécurité opérationnels (circuit breaker + scan secrets truffleHog), et les 7 techniques ZDNet mappées sur le stack existant avec les règles manquantes ajoutées dans CLAUDE.md.
Prérequis :
- TUTO-09 complété — Claude Code opérationnel, ECC installé, RTK et backup-on-stop actifs
jqv1.6+ (jq --version)- Python 3 disponible (
python3 --version)
Objectif
TUTO-09 documente l’installation et les deux hooks fondamentaux (RTK, backup-on-stop). Ce tuto couvre :
- L’inventaire des hooks ECC déjà actifs — comprendre ce qui tourne en arrière-plan
- Deux nouveaux hooks de sécurité issus des bonnes pratiques Korben : circuit breaker et scan secrets pré-commit
- Le mapping des 7 techniques ZDNet sur le stack existant — identifier ce qui est déjà en place et ce qui manque
Étape 1 : Inventaire des hooks ECC actifs
ECC installe une vingtaine de hooks via le plugin superpowers. Ils s’exécutent silencieusement — il est important de savoir ce qui tourne.
# Voir tous les hooks configurés
cat ~/.claude/hooks/hooks.json | jq '[.hooks | to_entries[] | {event: .key, count: (.value | length), descriptions: [.value[].description]}]'
# Compter par type d'événement
cat ~/.claude/hooks/hooks.json | jq '.hooks | to_entries[] | "\(.key): \(.value | length) hook(s)"' -r
Ce qui devrait être actif :
| Événement | Hook | Rôle |
|---|---|---|
| PreToolUse/Bash | block-no-verify | Bloque git --no-verify et git --no-gpg-sign |
| PreToolUse/Bash | auto-tmux-dev | Auto-démarre serveurs dev dans tmux (détection par répertoire) |
| PreToolUse/Bash | pre-bash-tmux-reminder | Rappel d’utiliser tmux pour commandes longues |
| PreToolUse/Bash | pre-bash-git-push-reminder | Alerte relecture avant git push |
| PreToolUse/Write | doc-file-warning | Avertit sur les fichiers doc non standards |
| PreToolUse/Edit|Write | suggest-compact | Suggère une compaction contexte aux moments clés |
| PreToolUse/* | observe.sh | Capture les usages d’outils pour apprentissage continu |
| PreToolUse/Write|Edit | config-protection | Bloque toute modification des configs linter/formatter |
| PostToolUse/Edit | post-edit-format | Auto-formate JS/TS (Biome ou Prettier selon projet) |
| PostToolUse/Edit | post-edit-typecheck | Lance tsc après chaque édition .ts/.tsx |
| PostToolUse/Edit | post-edit-console-warn | Avertit si console.log détecté dans les fichiers édités |
| PostToolUse/Edit|Write | quality-gate | Vérifie la qualité après édition (async) |
| PostToolUse/Bash | post-bash-pr-created | Logue l’URL de PR créée et propose la commande de revue |
| Stop | check-console-log | Vérifie console.log dans tous les fichiers modifiés |
| Stop | session-end | Persiste l’état de session |
| Stop | evaluate-session | Extrait les patterns appris de la session (async) |
| Stop | cost-tracker | Calcule et logue tokens/coût par session (async) |
| PreCompact | pre-compact | Sauvegarde l’état avant compaction du contexte |
| SessionStart | session-start | Charge le contexte précédent au démarrage |
| SessionEnd | session-end-marker | Marqueur de fin de session (non-bloquant) |
# Vérifier les hooks optionnels (désactivés par défaut, activables via env)
grep -E "ECC_ENABLE|ECC_GOVERNANCE" ~/.claude/hooks/hooks.json | head -5
# insaits-security-wrapper → activé par ECC_ENABLE_INSAITS=1
# governance-capture → activé par ECC_GOVERNANCE_CAPTURE=1
# Vérifier que settings.json + hooks.json sont cohérents
# (settings.json override/complète hooks.json)
cat ~/.claude/settings.json | jq '.hooks | to_entries[] | "\(.key): \(.value | length) hook(s)"' -r
Checklist étape 1 :
-
hooks.jsonlisible et contient > 10 hooks - Les hooks
block-no-verify,cost-tracker,config-protectionsont présents -
settings.jsoncontient au minimum PreToolUse/Bash (RTK) et Stop (backup-on-stop)
Étape 2 : Vérifier les hooks de protection code
2a — block-no-verify
Ce hook bloque git commit --no-verify, git push --no-verify, et git commit --no-gpg-sign. Sans lui, Claude Code peut contourner les pre-commit hooks.
# Test : simuler une commande bloquée (le hook doit rejeter)
echo '{"tool_name":"Bash","tool_input":{"command":"git commit --no-verify -m test"}}' \
| node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags.js" \
"pre:block-no-verify" \
"scripts/hooks/block-no-verify.js" \
"standard,strict" 2>&1 | head -5
# Attendu : exit non nul ou message de blocage
sans ce hook, Claude Code peut passer --no-verify pour contourner les pre-commit hooks de sécurité (scan secrets, linting). C’est exactement le vecteur qu’un agent mal configuré exploiterait pour committer du code sans validation.
2b — config-protection
Bloque toute modification des fichiers .eslintrc, .prettierrc, tsconfig.json, biome.json et équivalents. Empêche Claude Code d’affaiblir les configs de qualité pour “faire passer les tests”.
# Lister les fichiers protégés
cat "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/config-protection.js" 2>/dev/null | grep -A 5 "PROTECTED" | head -10
un agent qui modifie .eslintrc pour désactiver une règle gênante résout le symptôme en supprimant le garde-fou. Ce hook force la correction du code plutôt que de la config.
Checklist étape 2 :
-
git commit --no-verifybloqué par le hook (ou CLAUDE_PLUGIN_ROOT pointé correctement) -
CLAUDE_PLUGIN_ROOTdéfini dans l’environnement :echo $CLAUDE_PLUGIN_ROOT
Étape 3 : Hooks qualité post-édition
Vérifier l’auto-format et le typecheck
Ces hooks s’exécutent après chaque opération Edit. Ils détectent automatiquement Biome ou Prettier selon les fichiers présents dans le projet.
# Vérifier que Biome ou Prettier est disponible dans un projet JS/TS type
ls package.json 2>/dev/null && (cat package.json | jq '.devDependencies | keys[] | select(startswith("@biomejs") or . == "prettier")' -r) || echo "Pas de package.json ici"
# Vérifier que tsc est disponible pour le typecheck
which tsc 2>/dev/null || npx --yes tsc --version
Cost-tracker : vérifier le suivi des coûts
# Voir les données de coût accumulées (fichier créé après la première session)
ls ~/.claude/session-data/ 2>/dev/null | head -5
# Si vide : lancer une session Claude Code et terminer → le fichier sera créé
# Exemple de lecture d'un fichier de coût
ls ~/.claude/session-data/*.json 2>/dev/null | tail -1 | xargs cat 2>/dev/null | jq '{tokens: .tokens, cost_usd: .cost_usd, duration_s: .duration_s}' 2>/dev/null || echo "Aucun fichier de session disponible"
Checklist étape 3 :
-
CLAUDE_PLUGIN_ROOTpointe vers le répertoire ECC (ls $CLAUDE_PLUGIN_ROOT/scripts/hooks/) -
~/.claude/session-data/existe (créé après première session) - Cost-tracker produit un fichier de métriques après chaque session
Étape 4 : Circuit breaker — bloquer les boucles d’échecs (pattern Korben)
Problème : quand Claude Code enchaîne des commandes Bash qui échouent, il peut entrer dans une boucle de tentatives qui consomme des tokens inutilement. Après 3 échecs consécutifs, il faut couper le circuit et forcer une réévaluation.
Ce hook implémente le pattern circuit breaker décrit dans l’article Korben “6 trucs à piquer pour vos hooks”.
mkdir -p ~/.claude/hooks
# Hook de comptage des échecs (PostToolUseFailure)
cat > ~/.claude/hooks/circuit-breaker-failure.sh << 'EOF'
#!/usr/bin/env bash
# circuit-breaker-failure.sh — PostToolUseFailure/Bash
# Incrémente le compteur d'échecs consécutifs
set -euo pipefail
INPUT=$(cat)
STATE_FILE="${HOME}/.claude/hooks/circuit-breaker-state.json"
THRESHOLD=3
# Initialiser si absent
if ! -f "$STATE_FILE"; then
echo '{"failures": 0, "last_failure": ""}' > "$STATE_FILE"
fi
# Incrémenter
CURRENT=$(jq -r '.failures // 0' "$STATE_FILE")
NEW=$((CURRENT + 1))
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
echo "{\"failures\": ${NEW}, \"last_failure\": \"${TS}\"}" > "$STATE_FILE"
if "$NEW" -ge "$THRESHOLD"; then
echo "[circuit-breaker] ⚡ Circuit ouvert : ${NEW} échecs consécutifs. Prochain appel Bash sera bloqué." >&2
fi
echo "$INPUT"
EOF
chmod +x ~/.claude/hooks/circuit-breaker-failure.sh
# Hook de vérification avant exécution (PreToolUse)
cat > ~/.claude/hooks/circuit-breaker-check.sh << 'EOF'
#!/usr/bin/env bash
# circuit-breaker-check.sh — PreToolUse/Bash
# Bloque l'exécution si le circuit est ouvert (>= THRESHOLD échecs)
set -euo pipefail
INPUT=$(cat)
STATE_FILE="${HOME}/.claude/hooks/circuit-breaker-state.json"
THRESHOLD=3
if ! -f "$STATE_FILE"; then
echo "$INPUT"
exit 0
fi
FAILURES=$(jq -r '.failures // 0' "$STATE_FILE")
if "$FAILURES" -ge "$THRESHOLD"; then
LAST=$(jq -r '.last_failure // "inconnu"' "$STATE_FILE")
cat >&2 << MSG
[circuit-breaker] ⚡ CIRCUIT OUVERT — ${FAILURES} échecs consécutifs depuis ${LAST}.
L'exécution Bash est bloquée. Actions possibles :
1. Diagnostiquer la cause racine avant de continuer
2. Réinitialiser manuellement : echo '{"failures":0,"last_failure":""}' > ${STATE_FILE}
3. Adopter une approche différente (éviter la même commande)
MSG
exit 2
fi
echo "$INPUT"
EOF
chmod +x ~/.claude/hooks/circuit-breaker-check.sh
# Hook de réinitialisation sur succès (PostToolUse)
cat > ~/.claude/hooks/circuit-breaker-reset.sh << 'EOF'
#!/usr/bin/env bash
# circuit-breaker-reset.sh — PostToolUse/Bash
# Remet le compteur à 0 après une exécution réussie
set -euo pipefail
INPUT=$(cat)
STATE_FILE="${HOME}/.claude/hooks/circuit-breaker-state.json"
if -f "$STATE_FILE"; then
CURRENT=$(jq -r '.failures // 0' "$STATE_FILE")
if "$CURRENT" -gt 0; then
echo '{"failures": 0, "last_failure": ""}' > "$STATE_FILE"
echo "[circuit-breaker] ✅ Circuit fermé (réinitialisé après succès)" >&2
fi
fi
echo "$INPUT"
EOF
chmod +x ~/.claude/hooks/circuit-breaker-reset.sh
# Initialiser le fichier d'état
echo '{"failures": 0, "last_failure": ""}' > ~/.claude/hooks/circuit-breaker-state.json
le fichier circuit-breaker-state.json est modifié par des hooks shell. S’assurer que ses permissions empêchent une écriture externe : chmod 600 ~/.claude/hooks/circuit-breaker-state.json.
# Enregistrer les 3 hooks dans settings.json
python3 - << 'PYEOF'
import json, os
settings_path = os.path.expanduser("~/.claude/settings.json")
with open(settings_path) as f:
cfg = json.load(f)
hooks = cfg.setdefault("hooks", {})
# PreToolUse — vérification circuit
pre = hooks.setdefault("PreToolUse", [])
pre.append({
"matcher": "Bash",
"hooks": [{"type": "command", "command": "bash ~/.claude/hooks/circuit-breaker-check.sh"}],
"description": "Circuit breaker : bloque Bash après 3 échecs consécutifs"
})
# PostToolUse — réinitialisation sur succès
post = hooks.setdefault("PostToolUse", [])
post.append({
"matcher": "Bash",
"hooks": [{"type": "command", "command": "bash ~/.claude/hooks/circuit-breaker-reset.sh"}],
"description": "Circuit breaker : reset compteur sur succès Bash"
})
# PostToolUseFailure — incrémentation
failure = hooks.setdefault("PostToolUseFailure", [])
failure.append({
"matcher": "Bash",
"hooks": [{"type": "command", "command": "bash ~/.claude/hooks/circuit-breaker-failure.sh"}],
"description": "Circuit breaker : incrémente compteur d'échecs Bash"
})
with open(settings_path, "w") as f:
json.dump(cfg, f, indent=2)
print("settings.json mis à jour")
PYEOF
# Vérifier la configuration
cat ~/.claude/settings.json | jq '.hooks | keys'
# Attendu : ["PostToolUse", "PostToolUseFailure", "PreToolUse", "Stop"]
# Test : simuler 3 échecs et vérifier le blocage
for i in 1 2 3; do
echo "{\"failures\": $i, \"last_failure\": \"2026-04-04T00:00:0${i}Z\"}" > ~/.claude/hooks/circuit-breaker-state.json
echo "--- Test avec failures=$i ---"
echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | bash ~/.claude/hooks/circuit-breaker-check.sh > /dev/null 2>&1 \
&& echo "Passage autorisé" || echo "BLOQUÉ (exit $?)"
done
# Réinitialiser après test
echo '{"failures": 0, "last_failure": ""}' > ~/.claude/hooks/circuit-breaker-state.json
Checklist étape 4 :
- Les 3 scripts créés et exécutables (
ls -la ~/.claude/hooks/circuit-breaker-*.sh) -
circuit-breaker-state.jsonprésent avecfailures: 0 -
settings.jsoncontient les 3 nouveaux hooks (PreToolUse, PostToolUse, PostToolUseFailure) - Test avec
failures=3→ exit 2 (bloqué) confirmé
Étape 5 : Scan secrets pré-commit via truffleHog (pattern Korben)
Problème : Claude Code peut committer accidentellement des secrets (tokens, clés API) dans un repo. Ce hook intercepte chaque commande git commit et scan les fichiers stagés avant d’autoriser le commit.
5a — Installer truffleHog
# Option 1 : via pip (recommandé WSL2)
pip3 install trufflehog 2>/dev/null && trufflehog --version && echo "truffleHog OK via pip"
# Option 2 : via binaire GitHub (si pip échoue)
TRUFFLEHOG_VERSION=$(curl -s https://api.github.com/repos/trufflesecurity/trufflehog/releases/latest | jq -r '.tag_name' | tr -d 'v')
curl -sSfL "https://github.com/trufflesecurity/trufflehog/releases/download/v${TRUFFLEHOG_VERSION}/trufflehog_${TRUFFLEHOG_VERSION}_linux_amd64.tar.gz" \
| sudo tar -xz -C /usr/local/bin trufflehog
trufflehog --version
# Fallback : detect-secrets (si truffleHog indisponible)
pip3 install detect-secrets 2>/dev/null && detect-secrets --version && echo "detect-secrets OK"
truffleHog envoie les patterns de détection via réseau au premier lancement pour les mettre à jour. Si la souveraineté réseau est critique, utiliser trufflehog --no-update ou detect-secrets (100% local).
5b — Créer le hook
cat > ~/.claude/hooks/pre-commit-secrets.sh << 'EOF'
#!/usr/bin/env bash
# pre-commit-secrets.sh — PreToolUse/Bash
# Intercepte git commit et scanne les fichiers stagés pour secrets
set -euo pipefail
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# Passer si ce n'est pas un git commit
if ! echo "$CMD" | grep -qE '(^|&&|\|)\s*git\s+commit'; then
echo "$INPUT"
exit 0
fi
# Récupérer les fichiers stagés
STAGED=$(git diff --name-only --cached 2>/dev/null)
if -z "$STAGED"; then
echo "$INPUT"
exit 0
fi
echo "[pre-commit-secrets] Scan des fichiers stagés..." >&2
# --- Tentative 1 : truffleHog ---
if command -v trufflehog &>/dev/null; then
RESULT=$(trufflehog git \
file://. \
--since-commit HEAD \
--only-verified \
--json \
--no-update \
2>/dev/null | head -50)
if -n "$RESULT"; then
echo "" >&2
echo "[pre-commit-secrets] 🚨 SECRETS DÉTECTÉS — commit bloqué" >&2
echo "$RESULT" | jq -r '
" Fichier : \(.SourceMetadata.Data.Git.file // "inconnu")\n" +
" Ligne : \(.SourceMetadata.Data.Git.line // "?")\n" +
" Type : \(.DetectorName // "inconnu")"
' 2>/dev/null >&2 || echo "$RESULT" | head -5 >&2
echo "" >&2
echo " → Supprimer le secret du fichier, puis recommiter." >&2
echo " → Si c'est un faux positif : git commit avec le flag --allowed-secret (hors Claude Code)" >&2
exit 2
fi
echo "[pre-commit-secrets] ✅ truffleHog : aucun secret détecté" >&2
# --- Tentative 2 : detect-secrets ---
elif command -v detect-secrets &>/dev/null; then
BASELINE=".secrets.baseline"
# Initialiser la baseline si absente
if ! -f "$BASELINE"; then
detect-secrets scan > "$BASELINE" 2>/dev/null
fi
VIOLATIONS=$(detect-secrets scan \
--baseline "$BASELINE" \
--json \
2>/dev/null | jq '.results | length' 2>/dev/null || echo 0)
if "$VIOLATIONS" -gt 0; then
echo "[pre-commit-secrets] 🚨 detect-secrets : ${VIOLATIONS} secret(s) potentiel(s) — commit bloqué" >&2
echo " → Lancer : detect-secrets audit .secrets.baseline" >&2
exit 2
fi
echo "[pre-commit-secrets] ✅ detect-secrets : aucun secret détecté" >&2
# --- Aucun outil disponible ---
else
echo "[pre-commit-secrets] ⚠️ Ni truffleHog ni detect-secrets disponibles — scan ignoré" >&2
echo " → Installer : pip3 install trufflehog" >&2
fi
echo "$INPUT"
EOF
chmod +x ~/.claude/hooks/pre-commit-secrets.sh
ce hook scanne les fichiers stagés au moment du commit — pas les fichiers non stagés ni l’historique. Un secret ajouté à un fichier non committé mais laissé en clair sur disque reste exposé. Pour un audit complet de l’historique : trufflehog git file://. --since-commit $(git rev-list --max-parents=0 HEAD).
# Enregistrer le hook dans settings.json
python3 - << 'PYEOF'
import json, os
settings_path = os.path.expanduser("~/.claude/settings.json")
with open(settings_path) as f:
cfg = json.load(f)
pre = cfg.setdefault("hooks", {}).setdefault("PreToolUse", [])
pre.append({
"matcher": "Bash",
"hooks": [{"type": "command", "command": "bash ~/.claude/hooks/pre-commit-secrets.sh"}],
"description": "Scan secrets pré-commit : truffleHog/detect-secrets avant git commit"
})
with open(settings_path, "w") as f:
json.dump(cfg, f, indent=2)
print("settings.json mis à jour")
PYEOF
# Test du hook : créer un faux secret et vérifier le blocage
TMPDIR=$(mktemp -d)
cd "$TMPDIR"
git init -q
echo "ANTHROPIC_API_KEY=sk-ant-FakeKey123456789" > secret-test.txt
git add secret-test.txt
echo '{"tool_name":"Bash","tool_input":{"command":"git commit -m test"}}' \
| bash ~/.claude/hooks/pre-commit-secrets.sh > /dev/null 2>&1 \
&& echo "PROBLÈME : commit non bloqué" \
|| echo "✅ Commit bloqué correctement (exit $?)"
cd - > /dev/null
rm -rf "$TMPDIR"
Checklist étape 5 :
-
trufflehog --versionoudetect-secrets --version→ au moins un disponible -
~/.claude/hooks/pre-commit-secrets.shprésent et exécutable -
settings.jsoncontient le hookpre-commit-secrets - Test avec faux secret → exit 2 (commit bloqué)
- Test avec fichier propre → exit 0 (commit autorisé)
Étape 6 : Les 7 techniques ZDNet — mapping sur le stack existant
L’article ZDNet de David Gewirtz décrit 7 bonnes pratiques pour le développement avec IA. Voici leur état dans la configuration actuelle et les compléments à ajouter.
Technique 1 — Visibilité séquentielle plutôt que vitesse parallèle
Principe ZDNet : ne pas lancer plusieurs agents en parallèle, traiter les fichiers un par un, informer l’utilisateur à chaque étape.
État actuel : ❌ Non documenté dans CLAUDE.md du projet.
Action : ajouter cette règle dans le CLAUDE.md de chaque projet devbot :
## Règles d'exécution
- Ne PAS lancer d'agents ou de tâches en arrière-plan sans confirmation explicite
- Traiter les fichiers UN PAR UN, de manière séquentielle
- Informer l'utilisateur après chaque étape significative
- En cas de doute sur une action destructive : demander avant d'exécuter
Cette règle est particulièrement critique pour devbot (TUTO-08) qui opère de manière autonome sur des repos GitHub. Un agent parallèle bloqué peut laisser un repo dans un état intermédiaire.
Technique 2 — Suivi de la migration comme artefact
Principe ZDNet : journaliser dans un fichier structuré les changements qui doivent être répliqués sur d’autres plateformes.
État actuel : ➡️ Hors scope direct (stack iOS/macOS dans l’article). Adaptable pour le cas multi-agents : quand devbot modifie une config partagée par ha-agent et telegram-agent, journaliser la migration dans MIGRATION_LOG.md.
# Si pertinent : créer le fichier de suivi dans les repos devbot
echo "# Migration Log
Format : date | fichier modifié | agents concernés | changement | statut
" > ~/projects/ton-repo-devbot/MIGRATION_LOG.md
Technique 3 — Mémoire persistante avec organisation sémantique
Principe ZDNet : MEMORY.md organisé par thème (pas chronologique), mis à jour et dédupliqué.
État actuel : ✅ Déjà en place. ECC gère MEMORY.md via le système de mémoire automatique (hooks session-end + evaluate-session). Le fichier est organisé sémantiquement par type (user, feedback, project, reference).
# Vérifier le contenu de la mémoire du projet
cat ~/.claude/projects/$(pwd | tr '/' '-' | sed 's/^-//')/memory/MEMORY.md 2>/dev/null | head -30 || echo "Pas encore de mémoire pour ce projet"
Technique 4 — Journalisation des prompts comme piste d’audit
Principe ZDNet : PROMPT_LOG.md horodaté, chaque instruction consignée.
État actuel : ✅ Partiellement. ECC session-data/ contient les transcripts complets. Mais pas de PROMPT_LOG.md dédié par projet.
# Voir les sessions disponibles
ls ~/.claude/session-data/ 2>/dev/null | tail -5
Pour un projet spécifique nécessitant un audit trail (devbot notamment), ajouter cette instruction dans son CLAUDE.md :
## Journalisation
À chaque session, après avoir lu ces instructions, consigner chaque instruction reçue
dans `PROMPT_LOG.md` avec la date et l'heure (format ISO 8601).
Ne pas consigner les réponses — uniquement les instructions utilisateur.
Technique 5 — Profil utilisateur comme contrainte de conception
Principe ZDNet : décrire l’utilisateur cible dans CLAUDE.md pour que l’IA comprenne pour qui elle construit.
État actuel : ✅ Déjà en place via SOUL.md (TUTO-02d et TUTO-08). Le SOUL.md définit les contraintes de chaque agent — ce qui inclut implicitement le profil d’usage.
# Vérifier que SOUL.md de chaque agent contient un contexte d'usage
grep -l "SOUL.md" ~/projects/*/SOUL.md 2>/dev/null | head -5
Technique 6 — Système de conception codifié dans le fichier de config
Principe ZDNet : intégrer les tokens de design (couleurs RVB, tailles de police, styles de composants) directement dans CLAUDE.md.
État actuel : ✅ Partiellement. TUTO-09 documente CLAUDE.md comme vecteur de règles. Pour des projets frontend, ajouter les tokens de design dans le CLAUDE.md du projet.
## Design System (exemple — adapter à votre projet)
### Typographie
- Titres : 24pt Bold
- Corps : 15pt Regular
- Sous-texte : 12pt Medium
### Palette
- Primaire : rgb(37, 99, 235)
- Danger : rgb(220, 38, 38)
- Succès : rgb(22, 163, 74)
### Composants de référence
- Cards : border-radius 8px, shadow sm
- Boutons : height 40px, padding 0 16px
Technique 7 — Leçons durement acquises codées comme règles permanentes
Principe ZDNet : chaque bug corrigé devient une règle permanente dans CLAUDE.md. Ne pas réapprendre la même erreur.
État actuel : ✅ Déjà en place. ECC continuous-learning-v2 (hooks observe.sh + evaluate-session) extrait automatiquement les patterns de chaque session et les stocke dans le système de mémoire. Le hook Stop/evaluate-session analyse la session et propose des apprentissages.
# Voir les instincts appris (règles extraites automatiquement)
ls ~/.claude/projects/$(pwd | tr '/' '-' | sed 's/^-//')/memory/*.md 2>/dev/null
Pour renforcer ce mécanisme : à la fin de chaque session de debug longue, demander explicitement à Claude Code :
Encode les leçons apprises de cette session comme règles permanentes dans CLAUDE.md.
Format : "Ne jamais [action] car [raison apprise]."
Bonus ZDNet — Revue de code avec regard neuf
Principe : ouvrir une nouvelle session sans contexte accumulé pour auditer le projet avec un œil frais.
# Lancer une session d'audit isolée
# Option 1 : nouvelle session Claude Code vierge
claude --no-resume --print "Analyse ce projet et signale les problèmes et anomalies sans connaître l'historique." 2>&1
# Option 2 : via git worktree (TUTO-09 — ségrégation mémoire)
ECC_MEMORY_DIR="$(mktemp -d)" claude --print "Audit de sécurité du projet : cherche les problèmes sans contexte préalable."
Récapitulatif — état de la configuration
# Vue d'ensemble des hooks actifs
cat ~/.claude/settings.json | jq '[.hooks | to_entries[] | {event: .key, hooks: [.value[].hooks[].description? // .value[].description?]}]' 2>/dev/null
# Vérifier que les 2 nouveaux hooks sont en place
grep -c "circuit-breaker\|pre-commit-secrets" ~/.claude/settings.json
# Attendu : 4 (circuit-breaker apparaît 3 fois, pre-commit-secrets 1 fois)
# Vérifier les outils de scan disponibles
command -v trufflehog && trufflehog --version || echo "truffleHog absent"
command -v detect-secrets && detect-secrets --version || echo "detect-secrets absent"
# Au moins un doit répondre
Checklist finale :
- Inventaire hooks ECC fait et compris
-
block-no-verifyactif (testé) -
config-protectionactif - Circuit breaker : 3 scripts créés + settings.json mis à jour
- pre-commit-secrets : script créé + au moins un scanner disponible
- Règle séquentielle ZDNet #1 ajoutée dans CLAUDE.md du projet devbot
- PROMPT_LOG.md configuré dans le CLAUDE.md des agents nécessitant un audit trail
Dépannage
Circuit breaker — le circuit ne se ferme pas après un succès
# Vérifier l'état courant
cat ~/.claude/hooks/circuit-breaker-state.json
# Si failures >= 3 : réinitialiser manuellement
echo '{"failures": 0, "last_failure": ""}' > ~/.claude/hooks/circuit-breaker-state.json
pre-commit-secrets — hook non déclenché sur git commit
# Vérifier que la commande git commit déclenche bien le hook PreToolUse
# Le hook doit être en position dans PreToolUse AVANT rtk-rewrite
cat ~/.claude/settings.json | jq '.hooks.PreToolUse | map(select(.matcher == "Bash")) | .[].hooks[].command'
# Attendu : rtk-rewrite, circuit-breaker-check, pre-commit-secrets dans cet ordre
truffleHog — erreur “no git history” sur repo vide
# truffleHog nécessite au moins un commit dans l'historique
git log --oneline 2>/dev/null | head -3
# Si vide : faire un premier commit avant d'utiliser le hook
git commit --allow-empty -m "chore: initial commit"
CLAUDE_PLUGIN_ROOT — variable non définie
# Trouver le chemin du plugin ECC
find ~/.claude/plugins ~/.claude/cache -name "run-with-flags.js" 2>/dev/null | head -3
# Définir la variable (remplacer par le chemin trouvé)
export CLAUDE_PLUGIN_ROOT="$(dirname $(find ~/.claude -name 'run-with-flags.js' 2>/dev/null | head -1))"
# Ajouter dans ~/.bashrc pour persistance
echo "export CLAUDE_PLUGIN_ROOT=\"${CLAUDE_PLUGIN_ROOT}\"" >> ~/.bashrc
Références
- TUTO-09 — Installation Claude Code, ECC, RTK, backup-on-stop, MCP, mémoire, PAT
- TUTO-02d — Sécurité agents avancée (SOUL.md, profil utilisateur)
- TUTO-08 — devbot : maintenance code autonome
- Article Korben : “Fuite Claude Code - 6 trucs à piquer pour vos hooks” (2026-04-01)
- Article ZDNet : “7 techniques de programmation IA” — David Gewirtz (2026-04-04)
~/.claude/hooks/hooks.json— hooks ECC complets~/.claude/settings.json— hooks personnalisés (override/complément ECC)
Phase accomplie : les hooks de protection (circuit breaker, scan secrets) sont opérationnels. Les 7 techniques ZDNet sont mappées sur le stack existant — 4 sont déjà en place via ECC, 3 nécessitent des ajouts dans CLAUDE.md des projets agents.