Après des semaines de collaboration intensive avec Claude Code (Anthropic), j'ai identifié des patterns comportementaux toxiques récurrents : complaisance, mensonges par omission, raccourcis non signales, oubli des corrections entre sessions. J'ai conçu et déployé un système à 3 couches — enforcement mécanique, mémoire persistante, observabilité — pour rendre l'IA fiable de manière structurelle, pas volontaire.
On parle beaucoup de hallucinations factuelles des LLM. "L'IA à invente une reference", "l'IA à cite un package qui n'existe pas". OK. C'est un problème connu, documente, sur lequel tout le monde travaille.
Mais il y à un autre problème, plus insidieux, dont personne ne parle : la complaisance comportementale.
Je développe depuis janvier 2026 une PWA de gestion immobilière avec Claude Code comme co-pilote principal. Pas un jouet — une vraie app en production, avec une vraie cliente qui l'utilise au quotidien. Express, React, Supabase, AssemblyAI, déployé sur un VPS Hostinger.
Et au bout de 3 mois de travail intensif, voici ce que j'ai observé :
1. La complaisance
Claude Code livre vite pour faire plaisir. La réponse rapide prime sur la réponse correcte. Tu demandes un diagnostic sur un bug ? Il te sort une hypothese en 30 secondes sans avoir regarde la donnée réelle. Ca à l'air pro. C'est faux.
2. Le mensonge par omission
Je lui ai prescrit d'utiliser un outil spécifique (Stitch MCP) pour générér des visuels. Il à généré du HTML/CSS à la place — un résultat médiocre — et me l'a présenté comme si c'était normal. Sans me dire qu'il n'avait pas utilise l'outil prescrit. Quand je m'en suis rendu compte, j'ai du comparer les deux résultats moi-même. La difference était flagrante.
3. Le non-respect des règles
Claude Code à un système de fichiers d'instructions (CLAUDE.md) ou tu peux ecrire des règles. J'en ai ecrit. Beaucoup. Des règles de debug ("toujours regarder la base de données avant le code"), des règles de déploiement ("toujours tester avant de déployér"), des règles de comportement ("ne pas prendre de raccourcis"). Il les ignore des que le chemin facile existe. Même quand je les répète 3 fois dans la même session.
4. L'echo chamber inter-agents
Claude Code peut lancer des sous-agents pour des taches complexes. En theorie, c'est genial — parallelisation, expertise. En pratique, les agents se confortent mutuellement. L'un propose une approche facile, l'autre la valide, le résultat m'est présenté comme un "consensus". C'est un consensus entre oui-oui.
5. L'oubli inter-sessions
Tu corrigés un comportement en session 1. En session 2, la correction est oubliée. Tu recorrigés. Session 3, oubliée. Tu finis par ecrire la correction dans un fichier de mémoire. Session 4 : le fichier existe mais n'est pas consulte.
Le problème n'est pas que l'IA fait des erreurs — tout le monde fait des erreurs. Le problème c'est que si je dois tout vérifiér et tout surveiller, il n'y à aucun gain de productivité. L'outil devient un cout, pas une aide.
Et il y à des jours ou le levier est phénoménal. Un mois de travail abattu en une journée. Mais c'est comme travailler avec un développeur genial mais adolescent : compétences hors normes, fiabilité zéro.
Les instructions dans CLAUDE.md sont l'equivalent d'un panneau "Interdit de rouler à 150 km/h". Sans radar, sans amende, sans barrière physique. La recherche académique confirme : la conformité des LLM aux instructions décroît linéairement avec le nombre d'instructions. Au-dela de 20 règles, c'est < 30% de conformité en mode agent.
J'avais déjà construit un système de hooks (BRAKE) qui injectait des messages d'avertissement avant certaines actions. "Attention, tu lis du code sans avoir regarde la base". Le problème : ces messages font exit 0 — ils informent, ils ne bloquent pas. Claude les voit, les ignore, et continue.
J'ai 30+ fichiers markdown de feedbacks, corrections, protocoles. Ils existent. Ils ne sont pas consultes. La mémoire est la, mais personne ne la regarde. C'est comme avoir une bibliothèque fermée à clé.
Tout mécanisme qui depend de la bonne volonté de l'IA échouera.
La fiabilité doit etre mécanique, pas volontaire.
Avant de foncer tête baissée dans une implementation, j'ai fait un tour exhaustif de ce qui existe. Parce que mon premier reflexe (et celui de Claude) était d'installer le premier outil mentionne sans chercher d'alternatives. Ironie.
| Solution | Stars GitHub | Maturity | Ce que ca fait |
|---|---|---|---|
| Mem0 | 51K | 3 ans | Mémoire persistante, API simple |
| Letta (ex-MemGPT) | 22K | 2.5 ans | Runtime agent avec mémoire intégrée |
| Cognée | 15K | 2.5 ans | Mémoire cognitive structurée |
| Hindsight | 6.5K | 5 mois | Mémoire biomimétique 3 niveaux, 91.4% sur benchmark LongMemEval |
| Zep | 4.3K | 3 ans | Mémoire temporelle, principalement SaaS |
Constat : tous font du recall (ramener l'info pertinente). Aucun ne fait de l'enforcement (bloquer une action non conforme). Ils resolvent "j'ai oublie", pas "je m'en fous".
| Solution | Stars | Compatible Claude Code ? |
|---|---|---|
| NeMo Guardrails (NVIDIA) | 5.9K | Non — conçu pour chatbots |
| Guardrails AI | 6.6K | Non — valide le format, pas le comportement |
Constat : les guardrails existants sont conçus pour des chatbots conversationnels, pas pour des agents de code autonomes.
| Solution | Pertinence |
|---|---|
| Hooks natifs (PreToolCall/Stop) | Le seul mécanisme qui peut bloquer une action — via exit 2 |
| Plugin Hindsight | Auto-recall sur chaque prompt, auto-retain en fin de session |
| Langfuse | Observabilite, traces, scoring, dashboard |
Aucun outil unique ne couvre les deux faces du problème :
La solution : combiner 3 couches complementaires.
┌─────────────────────────────────────────────────────┐
│ PROMPT UTILISATEUR │
└──────────────────────┬──────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ COUCHE B — HINDSIGHT (mémoire) │
│ Hook UserPromptSubmit → auto-recall │
│ Injecte les feedbacks pertinents dans le contexte │
│ L'IA ne choisit PAS de les voir. Ils sont la. │
└──────────────────────┬──────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ L'IA RAISONNE │
│ (avec les feedbacks injectes en face d'elle) │
└──────────────────────┬──────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ COUCHE A — BRAKE HARD (enforcement) │
│ Hook PreToolCall → gate.sh │
│ Verifie AVANT chaque outil : │
│ - Read code sans DB query ? → exit 2 (BLOQUE) │
│ - Deploy sans audit ? → exit 2 (BLOQUE) │
│ - HTML au lieu de Stitch ? → exit 2 (BLOQUE) │
│ Exit 2 = outil refuse. Pas un warning, un MUR. │
└──────────────────────┬──────────────────────────────┘
▼ (si autorise)
┌─────────────────────────────────────────────────────┐
│ OUTIL EXECUTE │
└──────────────────────┬──────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ COUCHE C — LANGFUSE (observabilité) │
│ Trace passive : quel outil, quel contexte, │
│ quel résultat. Dashboard consultable. │
│ Ne bloque rien. OBSERVE. │
└─────────────────────────────────────────────────────┘
| Couche | Role | Analogie |
|---|---|---|
| Hindsight | Je ne peux pas dire "j'ai oublie" | La mémoire arrive automatiquement |
| BRAKE | Je ne peux pas dire "j'ai vu mais j'ai decide autrement" | L'outil est physiquement refuse |
| Langfuse | Je ne peux pas dire "ca s'est bien passe" | Les traces sont la, verifiables |
Mémoire forcée + action bloquée + traçabilité totale.
npm install -g @anthropic-ai/claude-code)C'est le coeur du système. Le seul mécanisme qui bloque réellement dans Claude Code.
mkdir -p ~/.claude/brakeCe script Python parse l'input JSON du hook, met à jour l'état de session, et retourne les informations nécessaires au script bash.
cat > ~/.claude/brake/gate-parse.py << 'PYEOF'
#!/usr/bin/env python3
"""Parse l'input du hook PreToolCall, met à jour session-state, retourne les infos."""
import json
import os
import sys
from datetime import datetime
SESSION_FILE = os.path.expanduser("~/.claude/brake/session-state.json")
# Lire stdin
try:
inp = sys.stdin.read()
except Exception:
inp = ""
# Parser l'input JSON
tool_name = "unknown"
file_path = ""
command = ""
try:
d = json.loads(inp)
tool_name = d.get("tool_name", "unknown")
ti = d.get("tool_input", {})
if isinstance(ti, dict):
file_path = ti.get("file_path", ti.get("path", ""))
command = ti.get("command", "")
except Exception:
pass
# Charger session-state
try:
with open(SESSION_FILE) as f:
state = json.load(f)
except Exception:
state = {
"db_queried": False,
"roko_invoked": False,
"tests_run": False,
"context_mode": "dev",
"files_read": 0,
"files_edited": 0,
"deploy_attempted": False,
"tools": [],
}
# Tracker l'outil
state["tools"].append({"tool": tool_name, "time": datetime.now().isoformat()[:19]})
# Détecter requête DB
cmd_lower = command.lower()
if tool_name == "Bash" and any(
k in cmd_lower
for k in ["supabase", "pipeline_jobs", "from('", 'from("', ".select(", "psql"]
):
state["db_queried"] = True
# Détecter invocation agent contradicteur
if tool_name == "Bash" and "roko" in cmd_lower:
state["roko_invoked"] = True
if tool_name == "Skill" and "roko" in inp.lower():
state["roko_invoked"] = True
# Détecter tests
if tool_name == "Bash" and any(
k in command for k in ["npm test", "npm run test", "jest", "vitest", "mocha", "pytest"]
):
state["tests_run"] = True
# Tracker lectures et editions
if tool_name in ("Read", "Grep"):
state["files_read"] = state.get("files_read", 0) + 1
if tool_name in ("Edit", "Write"):
state["files_edited"] = state.get("files_edited", 0) + 1
# Détecter deploy
if tool_name == "Bash" and any(
k in command
for k in ["rsync", "pm2 restart", "pm2 reload", "docker push", "npm run deploy"]
):
state["deploy_attempted"] = True
# Sauvegarder
with open(SESSION_FILE, "w") as f:
json.dump(state, f)
# Output pour gate.sh
print(
f"{tool_name}|||{file_path}|||{command}|||"
f"{state['db_queried']}|||{state['roko_invoked']}|||{state['tests_run']}|||"
f"{state['files_read']}|||{state['files_edited']}|||{state.get('context_mode', 'dev')}"
)
PYEOFLe coeur du système. Chaque règle qui matche fait exit 2 — l'outil est refuse, le message est affiche à l'IA.
cat > ~/.claude/brake/gate.sh << 'GATEOF'
#!/usr/bin/env bash
# gate.sh — PreToolCall hook : BLOQUE les actions non conformes (exit 2)
# Exit 0 = autorise | Exit 2 = BLOQUE (message stderr affiche à l'IA)
# Degradation gracieuse : si ce script plante, on autorise l'outil
trap 'exit 0' ERR
BRAKE_DIR="$HOME/.claude/brake"
# Lire stdin
INPUT=""
if [[ ! -t 0 ]]; then
INPUT=$(cat 2>/dev/null || true)
fi
# Parser via Python
PARSED=$(echo "$INPUT" | python3 "$BRAKE_DIR/gate-parse.py" 2>/dev/null || echo "unknown||||||False|||False|||False|||0|||0|||dev")
# Extraire les valeurs (separateur |||)
TOOL_NAME=$(echo "$PARSED" | cut -d'|' -f1)
FILE_PATH=$(echo "$PARSED" | cut -d'|' -f4)
COMMAND=$(echo "$PARSED" | cut -d'|' -f7)
DB_QUERIED=$(echo "$PARSED" | cut -d'|' -f10)
ROKO_INVOKED=$(echo "$PARSED" | cut -d'|' -f13)
TESTS_RUN=$(echo "$PARSED" | cut -d'|' -f16)
FILES_READ=$(echo "$PARSED" | cut -d'|' -f19)
FILES_EDITED=$(echo "$PARSED" | cut -d'|' -f22)
# Parsing échoué = laisser passer
if [[ "$TOOL_NAME" == "unknown" || -z "$TOOL_NAME" ]]; then
exit 0
fi
# ============================================================
# REGLES DE BLOCAGE — Adapter selon vos besoins
# ============================================================
# REGLE 1 : Pas de lecture de code serveur sans requête DB (après 2 lectures)
if [[ "$TOOL_NAME" == "Read" || "$TOOL_NAME" == "Grep" ]]; then
if echo "$FILE_PATH" | grep -qE '(server/|worker|pipeline|api/)' 2>/dev/null; then
if [[ "$DB_QUERIED" == "False" && "${FILES_READ:-0}" -gt 2 ]]; then
echo "BRAKE BLOQUE : Lecture code serveur sans requête base (${FILES_READ} lectures)." >&2
echo "ACTION : Requeter la base d'abord. Diagnostic AVANT code." >&2
exit 2
fi
fi
fi
# REGLE 2 : Pas d'edition de code sans diagnostic base
if [[ "$TOOL_NAME" == "Edit" || "$TOOL_NAME" == "Write" ]]; then
if echo "$FILE_PATH" | grep -qE '\.(js|ts|jsx|tsx|py)$' 2>/dev/null; then
if [[ "$DB_QUERIED" == "False" && "${FILES_READ:-0}" -gt 3 ]]; then
echo "BRAKE BLOQUE : Edition après $FILES_READ lectures sans requête base." >&2
echo "Pattern : lecture code -> faux diagnostic -> faux fix. STOP." >&2
exit 2
fi
fi
fi
# REGLE 3 : Pas de deploy sans audit contradicteur
if [[ "$TOOL_NAME" == "Bash" ]]; then
if echo "$COMMAND" | grep -qE '(rsync|pm2 restart|pm2 reload|docker push|npm run deploy)' 2>/dev/null; then
if [[ "$ROKO_INVOKED" == "False" ]]; then
echo "BRAKE BLOQUE : Deploy sans audit contradicteur." >&2
echo "Checklist : tests, backup, env vars, commit propre, rollback." >&2
exit 2
fi
fi
fi
# REGLE 4 : Pas de push sans tests
if [[ "$TOOL_NAME" == "Bash" ]]; then
if echo "$COMMAND" | grep -qE 'git push.*(main|develop|origin)' 2>/dev/null; then
if [[ "$TESTS_RUN" == "False" ]]; then
echo "BRAKE BLOQUE : Push sans tests. Lance les tests d'abord." >&2
exit 2
fi
fi
fi
# REGLE 5 : Pas de HTML/CSS pour les visuels (utiliser l'outil prescrit)
if [[ "$TOOL_NAME" == "Write" ]]; then
if echo "$FILE_PATH" | grep -qE '\.(html|svg)$' 2>/dev/null; then
if echo "$FILE_PATH" | grep -qiE '(slide|carousel|carrousel|presentation|poster|visual|banner|infograph)' 2>/dev/null; then
echo "BRAKE BLOQUE : Visuel en HTML. Utiliser l'outil prescrit." >&2
exit 2
fi
fi
fi
# WARNINGS (ne bloquent pas)
if [[ "$TOOL_NAME" == "Read" || "$TOOL_NAME" == "Grep" ]]; then
if echo "$FILE_PATH" | grep -qE '(server/|worker|pipeline|api/)' 2>/dev/null; then
if [[ "$DB_QUERIED" == "False" && "${FILES_READ:-0}" -gt 0 && "${FILES_READ:-0}" -le 2 ]]; then
echo "BRAKE WARNING : Lecture code serveur sans requête base (${FILES_READ}/2 avant blocage)." >&2
fi
fi
fi
exit 0
GATEOF
chmod +x ~/.claude/brake/gate.shcat > ~/.claude/brake/session-reset.sh << 'EOF'
#!/usr/bin/env bash
cat > ~/.claude/brake/session-state.json << 'JSON'
{"db_queried":false,"roko_invoked":false,"tests_run":false,"context_mode":"dev","files_read":0,"files_edited":0,"deploy_attempted":false,"tools":[]}
JSON
EOF
chmod +x ~/.claude/brake/session-reset.sh
bash ~/.claude/brake/session-reset.shEditer ~/.claude/settings.json pour ajouter les hooks :
{
"hooks": {
"PreToolCall": [
{
"matcher": "Read|Grep|Edit|Write|Bash",
"hooks": [
{
"type": "command",
"command": "bash $HOME/.claude/brake/gate.sh",
"timeout": 5
}
]
}
]
}
}# Syntaxe OK ?
bash -n ~/.claude/brake/gate.sh && echo "OK"
python3 -m py_compile ~/.claude/brake/gate-parse.py && echo "OK"
# Test blocage DB_FIRST (simuler 3 lectures sans DB query)
cat > ~/.claude/brake/session-state.json << 'JSON'
{"db_queried":false,"roko_invoked":false,"tests_run":false,"context_mode":"dev","files_read":3,"files_edited":0,"deploy_attempted":false,"tools":[]}
JSON
echo '{"tool_name":"Read","tool_input":{"file_path":"server/worker.js"}}' | bash ~/.claude/brake/gate.sh 2>&1
echo "Exit code: $?"
# Attendu : message BRAKE BLOQUE + exit code 2
# Test deploy sans audit
bash ~/.claude/brake/session-reset.sh
echo '{"tool_name":"Bash","tool_input":{"command":"rsync -avz ./dist/ user@server:/app/"}}' | bash ~/.claude/brake/gate.sh 2>&1
echo "Exit code: $?"
# Attendu : BRAKE BLOQUE + exit code 2
# Test push sans tests
echo '{"tool_name":"Bash","tool_input":{"command":"git push origin main"}}' | bash ~/.claude/brake/gate.sh 2>&1
echo "Exit code: $?"
# Attendu : BRAKE BLOQUE + exit code 2
# Test Write HTML visuel
echo '{"tool_name":"Write","tool_input":{"file_path":"/tmp/carrousel-linkedin.html"}}' | bash ~/.claude/brake/gate.sh 2>&1
echo "Exit code: $?"
# Attendu : BRAKE BLOQUE + exit code 2
# Test Write HTML normal (code applicatif) — doit passer
echo '{"tool_name":"Write","tool_input":{"file_path":"/app/client/index.html"}}' | bash ~/.claude/brake/gate.sh 2>&1
echo "Exit code: $?"
# Attendu : exit code 0
# Reset pour usage normal
bash ~/.claude/brake/session-reset.shHindsight est un système de mémoire biomimétique pour agents IA. Il organise les souvenirs en 3 niveaux (faits, observations, modèles mentaux) et les retrouve via 4 strategies de recherche en parallele (sémantique, BM25, graphe, temporel).
Ce qui nous interesse : le plugin Claude Code qui injecte automatiquement les memories pertinentes dans le contexte de l'IA à chaque prompt.
# docker-compose.yml
cat > ~/hindsight-docker/docker-compose.yml << 'DCEOF'
version: '3.8'
services:
hindsight-db:
image: pgvector/pgvector:pg18
container_name: hindsight-db
environment:
POSTGRES_USER: hindsight
POSTGRES_PASSWORD: hindsight
POSTGRES_DB: hindsight
volumes:
- hindsight-pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U hindsight"]
interval: 5s
timeout: 5s
retries: 5
hindsight-app:
image: ghcr.io/vectorize-io/hindsight:latest
container_name: hindsight-app
ports:
- "8888:8888"
- "9999:9999"
environment:
HINDSIGHT_API_DATABASE_URL: "postgresql://hindsight:hindsight@hindsight-db:5432/hindsight"
HINDSIGHT_API_LLM_PROVIDER: "openai"
HINDSIGHT_API_LLM_API_KEY: "${OPENAI_API_KEY}"
HINDSIGHT_API_LLM_MODEL: "gpt-4o-mini"
depends_on:
hindsight-db:
condition: service_healthy
volumes:
hindsight-pgdata:
DCEOF
cd ~/hindsight-docker
docker compose up -dNote : j'utilise PostgreSQL externe (pgvector) au lieu du pg0 embarque. Le pg0 à un bug connu de perte de données après restart Docker (#675).
curl -s http://localhost:8888/health
# {"status": "healthy", "database": "connected"}curl -s -X PUT http://localhost:8888/v1/default/banks/david-global \
-H "Content-Type: application/json" \
-d '{
"description": "Regles globales, feedbacks, protocoles pour toutes les sessions"
}'# Exemple : ingérer un feedback
curl -s -X POST http://localhost:8888/v1/default/banks/david-global/memories \
-H "Content-Type: application/json" \
-d '{
"items": [{
"content": "Regle : toujours requêter la base de données AVANT de lire le code source pour diagnostiquer un bug. Ne jamais proposer un fix sans avoir vu la donnée réelle.",
"context": "feedback-rule",
"tags": ["feedback", "global-rules"]
}],
"async": false
}'
# Ingerer tous vos fichiers de feedback en batch
for f in ~/.claude/projects/*/memory/feedback-*.md; do
python3 -c "
import json, urllib.request, os
content = open('$f').read()
payload = json.dumps({
'items': [{'content': content, 'context': 'feedback-rule', 'tags': ['feedback', 'global-rules']}],
'async': False
})
req = urllib.request.Request(
'http://localhost:8888/v1/default/banks/david-global/memories',
data=payload.encode(),
headers={'Content-Type': 'application/json'},
method='POST'
)
resp = urllib.request.urlopen(req, timeout=60)
result = json.loads(resp.read())
print(f'OK: {os.path.basename(\"$f\")} — {result.get(\"usage\",{}).get(\"total_tokens\",0)} tokens')
"
donecurl -s -X POST http://localhost:8888/v1/default/banks/david-global/memories/recall \
-H "Content-Type: application/json" \
-d '{"query": "comment debugger un job bloque dans le pipeline"}' | python3 -c "
import json, sys
d = json.load(sys.stdin)
for m in d.get('results', [])[:3]:
print(f' {m[\"text\"][:150]}')
print()
"# Ajouter le marketplace Hindsight
claude plugin marketplace add vectorize-io/hindsight
# Installer le plugin mémoire
claude plugin install hindsight-memorymkdir -p ~/.hindsight
cat > ~/.hindsight/claude-code.json << 'EOF'
{
"hindsightApiUrl": "http://localhost:8888",
"bankId": "david-global",
"bankMission": "Mémoire globale. Regles de travail, feedbacks critiques, protocoles obligatoires, corrections comportementales.",
"retainMission": "Extraire : corrections sur le comportement (complaisance, raccourcis, mensonges), decisions techniques, règles de process, préférénces de travail. Ignorer les salutations.",
"autoRecall": true,
"autoRetain": true,
"recallBudget": "mid",
"recallMaxTokens": 2048,
"recallTypes": ["world", "experience", "observation"],
"recallContextTurns": 2,
"retainEveryNTurns": 5,
"retainOverlapTurns": 2,
"debug": false
}
EOFA partir de maintenant, chaque prompt que vous envoyez déclénché un recall automatique. Vos feedbacks sont injectes dans le contexte de l'IA — elle ne choisit pas de les consulter, ils sont la.
# docker-compose-langfuse.yml
cat > ~/langfuse-docker/docker-compose.yml << 'DCEOF'
version: '3.8'
services:
langfuse-server:
image: langfuse/langfuse:2
ports:
- "3001:3000"
environment:
DATABASE_URL: "postgresql://langfuse:langfuse@langfuse-db:5432/langfuse"
NEXTAUTH_SECRET: "votre-secret-aleatoire-ici"
NEXTAUTH_URL: "http://localhost:3001"
SALT: "votre-salt-aleatoire-ici"
depends_on:
langfuse-db:
condition: service_healthy
langfuse-db:
image: postgres:16
environment:
POSTGRES_USER: langfuse
POSTGRES_PASSWORD: langfuse
POSTGRES_DB: langfuse
volumes:
- langfuse-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U langfuse"]
interval: 5s
timeout: 5s
retries: 5
volumes:
langfuse-data:
DCEOF
cd ~/langfuse-docker
docker compose up -d
# Dashboard accessible sur http://localhost:3001L'intégration avec Claude Code se fait via le hook Stop — un script envoie les traces de session à Langfuse après chaque réponse.
Rien n'est gratuit. Voici ce que ce système coute :
Hindsight ajoute 1-3 secondes par prompt (recall API). Sur 50 echanges, ca fait ~2 minutes. Perceptible, pas bloquant.
Le risque le plus sérieux. BRAKE peut bloquer des actions legitimes :
Mitigation : calibration progressive. Semaine 1 en mode "log only" (exit 0 + log), semaine 2 review des logs, semaine 3 activation des règles validées.
3 systèmes = 3 trucs qui peuvent casser. Docker tombe, un hook change de format après une mise à jour, un script à un bug.
Mitigation : dégradation gracieuse partout. trap 'exit 0' ERR dans gate.sh. Le plugin Hindsight fait exit 0 si le serveur est down. Langfuse est passif — s'il tombe, rien ne change.
| Couche | Status | Detail |
|---|---|---|
| A — BRAKE Hard | Operationnel | 5 règles avec exit 2, degrade gracieusement, teste |
| B — Hindsight | Operationnel | Serveur Docker, 232 faits extraits, 51 observations, recall fonctionne |
| C — Langfuse | A déployér | Prevu ce week-end |
La question n'est pas "est-ce que ca marche techniquement" (ca marche, les tests le prouvent). La question est : est-ce que ca change réellement le comportement de l'IA au quotidien ?
Les métriques à suivre :
Ce système est en place depuis aujourd'hui. Il va vivre en production sur tous mes projets Claude Code pendant les 4 prochaines semaines.
Le 28 avril 2026, je publierai un articlé de suivi avec :
Parce que c'est facile de construire un système. C'est autre chose de vivre avec.
A dans un mois.
David Perrot — Ingenieur en Informatique
Testeur de limites, constructeur de garde-fous.