Kevin Aubrée

Blog / · 6 min de lecture

J'ai laissé un agent bosser 8h pendant que je dormais. Le rapport au réveil.

Retour d'expérience brut : un agent Claude Code lancé à minuit en mode autonome sur une migration. Ce qui a été shippé, ce qui a été cassé, la dette de review au réveil.

J'ai laissé un agent bosser 8h pendant que je dormais. Le rapport au réveil.

La nuit du 3 au 4 avril, j’ai lancé un agent Claude Code à 23h30 sur une migration Doctrine un peu pénible. Je lui ai donné un todo détaillé, l’accès au repo, permission d’écrire, et je suis allé me coucher.

Au réveil à 7h45, il y avait 23 commits sur la branche, la CI verte, et un résumé Markdown propre. Mon premier réflexe a été de me dire “OK, c’est fini, j’ai dormi pendant que ça bossait”. Mon deuxième réflexe, après avoir ouvert le diff, a été “ah merde”.

Voilà ce que j’ai appris de cette expérience.

Le setup

La tâche : migrer 34 entités Doctrine d’un mapping YAML vers des attributes PHP 8, plus refactor de quelques relations pour passer en lazy loading. Le genre de chose mécanique mais volumineuse. Parfait pour un agent, en théorie.

Mon setup :

  • Claude Code en mode --dangerously-skip-permissions (oui, sur une branche dédiée, dans un container)
  • Un CLAUDE.md précis avec conventions de nommage, mapping rules, et exemples
  • Un fichier TODO avec les 34 entités listées
  • Une CI qui tourne à chaque commit (PHPStan niveau 8 + PHPUnit)
  • Instructions : “après chaque entité migrée, commit avec message conventional, lance la CI, si rouge fix et recommit”

Le rapport au réveil

Les chiffres bruts :

  • 23 entités migrées sur 34 (68% du scope)
  • Temps d’exécution : 7h48
  • Commits : 23
  • CI : verte sur HEAD
  • Coût API : 11,80 €

Ça ressemble à une réussite. Le résumé Markdown que l’agent avait rédigé à la fin était impeccable : il expliquait quelles entités avaient été migrées, lesquelles restaient, et pourquoi il s’était arrêté (une entité Invoice avec une relation polymorphique qu’il n’osait pas toucher sans validation humaine — bon réflexe).

Ce qui a été cassé

Quand j’ai commencé la review sérieuse, j’ai trouvé :

1. Une relation OneToMany retournée en Collection là où le legacy retournait un array. Techniquement meilleur. Mais 14 endroits du code appelaient count($this->getItems()) en s’attendant à un array PHP natif. L’agent a “corrigé” les call sites… en changeant le type de retour de 6 getters dans d’autres entités. Effet de bord silencieux. La CI était verte parce que les tests ne couvraient pas ces chemins.

2. Une cascade remove ajoutée “pour être cohérent”. L’agent a vu que 80% des relations avaient cascade={"remove"} et a harmonisé les 20% restantes. Sauf que ces 20%, c’était des relations vers des entités partagées (Categories, Tags). En prod, supprimer un produit aurait effacé ses catégories. Catastrophe évitée parce que je review.

3. Des imports “nettoyés” dans des fichiers hors scope. L’agent, zélé, a fait un pass de cleanup sur des fichiers qu’il a ouverts “en passant”. Une vingtaine de fichiers touchés, la plupart sans casse, mais impossible à isoler dans le diff final.

4. Un commit entier annulé et refait sans le dire. Dans les logs, je vois qu’il a tenté une approche sur Product, s’est heurté à un échec CI, a git reset et repris autrement. Aucune trace dans l’historique Git, pas de mention dans le rapport. Si je n’avais pas lu les logs, je n’aurais jamais su.

Le temps de review

Pour 7h48 de travail agent, j’ai passé 4h30 de review. Concrètement :

  • 1h30 à lire les 23 commits un par un
  • 1h à identifier les effets de bord (point 1 et 3 ci-dessus)
  • 45 min à re-runner les tests d’intégration manquants
  • 1h15 à réverter les décisions que je ne voulais pas (point 2, point 3 partiel)

Donc net, j’ai “gagné” 7h48 - 4h30 = 3h18 de productivité. Tout en m’étant réveillé plus fatigué à cause de l’anxiété latente du “est-ce que ça a marché”.

Ce que j’en tire

L’agent autonome marche pour des tâches mécaniques. La migration YAML → attributes, c’est mécanique. Il l’a fait correctement à 90%.

Il craque sur les décisions d’architecture déguisées en tâches mécaniques. Une migration, ce n’est pas que du remplacement de texte. Il y a des micro-décisions (cascade, type de retour, conventions de nommage quand elles divergent) qui ressemblent à de la cosmétique mais ont des conséquences système. L’agent prend ces décisions seul, rationnellement, et se trompe.

La CI verte n’est pas un signal de qualité. C’est un signal d’absence de régression sur ce qui est testé. Sur une codebase moyenne, ça couvre 40% du comportement. Le reste, l’agent peut le casser en toute impunité.

Le “je dors pendant que ça code” est un mensonge. On déplace le travail, on ne l’élimine pas. Coder = écrire + penser + décider. L’agent fait “écrire” très bien, “penser” correctement, et “décider” mal. Le coût de review d’un agent autonome non-supervisé est au moins 50% du temps agent pour une tâche de migration.

Comment je vais m’en servir désormais

J’ai changé mon process après cette nuit :

  1. Plus de mode autonome long (>2h) sur une branche sans checkpoints humains. Je préfère découper en 4 sessions de 2h où je review entre chaque.
  2. Instructions explicites sur ce que l’agent n’a PAS le droit de faire (“ne touche pas aux imports des autres fichiers”, “ne change pas les types de retour”, “si tu hésites sur une cascade, stoppe et rapporte”).
  3. Force-log des git reset et commits annulés dans le rapport final. J’ai ajouté une ligne dans mon CLAUDE.md : “documente toute tentative échouée, même si tu as reset”.
  4. Review avant merge, pas après. Pas de push sur main automatique même si la CI est verte.

À retenir

Les agents autonomes de 2026 ne sont pas magiques. Ils déplacent le goulot d’étranglement du développement vers la review, sans le supprimer. Pour un dev senior qui sait ce qu’il cherche, c’est un gain net. Pour un junior qui ne sait pas ce qu’il regarde, c’est un gouffre à dette technique invisible.

Je continue à les utiliser. Mais je ne dormirai plus “pendant qu’ils bossent”. Je les fais tourner quand je suis à côté, sur 1-2h focalisées, avec review continue. C’est moins sexy comme tweet, mais c’est là que la valeur sort.

Kevin Aubrée

Continuer la lecture

Retour au blog