Le spec-driven development marche quand le spec retire les ambiguïtés avant que Claude Code écrive du code. Le vrai sujet, c’est moins “faire coder l’IA” que lui donner des critères impossibles à interpréter librement. Je vous montre comment cadrer ça proprement.
Pourquoi le spec change tout ?
Le spec change tout parce qu’il réduit le nombre de décisions que l’agent doit prendre seul. C’est vraiment le point central. Claude Code, ou n’importe quel autre agent de programmation, peut être très bon localement. Il comprend une fonction, corrige un bug, ajoute un test, refactorise un bout de code. Mais il devient fragile quand il doit enchaîner trop de choix implicites.
Imaginez 20 décisions à prendre pendant une tâche. Le modèle doit choisir le bon fichier, la bonne architecture, le bon nom de route, le bon format d’erreur, le bon comportement si l’utilisateur n’est pas connecté, la bonne façon de tester, etc. Si chaque décision a 80 % de chances d’être bonne, ça semble confortable. Sauf que 0,8 puissance 20, ça tombe autour de 1 %. Voilà le piège. Le problème n’est pas que l’agent est nul. Le problème, c’est qu’on lui laisse trop de carrefours.
Le spec-driven development sert à enlever ces décisions du chemin. Pas à faire joli dans un dossier projet. Pas à produire un document que personne ne lit. Un bon spec transforme une intention vague en contraintes utilisables.
“Ajoute l’authentification”, c’est trop flou. L’agent doit deviner les rôles, les routes, les erreurs, les redirections, les états limites, les fichiers à modifier, les tests attendus. Un spec utile dit plutôt : il y a un rôle admin et un rôle user, la route /login accepte email et mot de passe, une erreur 401 est renvoyée si les identifiants sont faux, un compte bloqué ne peut pas se connecter, les fichiers concernés sont tels contrôleurs et tels middlewares, et la tâche est terminée quand ces critères d’acceptation passent.
Dans mes missions data, IA ou automatisation, les échecs viennent rarement du modèle seul. Ils viennent souvent d’une intention business mal découpée. On croit demander une feature, mais en réalité on envoie un nuage d’hypothèses.
Avec Claude Code, c’est pareil. Plus le contexte est explicite, moins l’agent invente. Et moins il invente, plus il livre quelque chose de proche de ce que vous aviez vraiment en tête.
| Demande floue | Spec exploitable |
| Ajoute l’authentification. | Définir les rôles, les routes, les erreurs, les cas limites, les fichiers concernés et les critères d’acceptation. |
| Améliore le dashboard. | Ajouter trois métriques précises, avec sources de données, filtres, états vides et règles d’affichage. |
| Corrige les permissions. | Lister chaque rôle, chaque action autorisée, chaque action interdite et les tests attendus. |
Comment cadrer les exigences ?
Je cadre les exigences en laissant d’abord Claude m’interroger, puis en reprenant la main sur le document final. Dans la phase Requirements du spec-driven development, je cherche surtout à transformer une idée floue en exigences vérifiables, avant de parler architecture, code ou tickets.
Partir d’une page blanche marche rarement très bien. On oublie des cas bêtes, on suppose trop, on écrit ce qu’on a en tête mais pas ce que le produit doit vraiment faire. Je préfère demander à Claude Code, idéalement en mode plan quand il est disponible, de me poser des questions avant d’écrire quoi que ce soit. Ce mode sert justement à empêcher l’agent de coder trop tôt. Il force une phase de clarification, et franchement, ça évite pas mal de déchets.
Les bonnes questions tournent toujours autour des mêmes sujets :
- Objectif utilisateur : Qui utilise la fonctionnalité, et pour faire quoi concrètement ?
- Comportement attendu : Qu’est-ce qui doit se passer dans le cas normal ?
- Cas limites : Que fait-on si les données sont vides, incomplètes, trop volumineuses ou incohérentes ?
- Données manipulées : Quels champs entrent, quels champs sortent, quel format est attendu ?
- Sécurité : Qui a le droit d’accéder à quoi, et quelles données ne doivent jamais fuiter ?
- Compatibilité : Qu’est-ce qui existe déjà et qu’on ne doit pas casser ?
- Erreurs visibles : Quels messages l’utilisateur ou l’API doit recevoir en cas de problème ?
- Dépendances : Quels services, tables, fichiers ou jobs sont nécessaires ?
- Exclusions : Qu’est-ce qu’on ne fait pas dans cette version ?
Prenons un export CSV. Une demande comme “Ajouter un export CSV” est trop vague. Je veux savoir si l’export concerne toutes les lignes ou seulement les résultats filtrés, quels champs sont inclus, dans quel ordre, avec quel encodage, comment gérer les virgules dans les valeurs, les dates, les droits d’accès, les gros volumes, et ce qu’on affiche si l’export échoue. Sur une API de scoring, c’est pareil : je verrouille les entrées, la plage du score, les erreurs, les temps de réponse attendus et les cas où le score ne peut pas être calculé.
Le point important, c’est que le SPEC.md généré par l’agent ne doit pas rester “son” spec. Je l’édite. Je corrige les ambiguïtés. Je supprime les hypothèses gratuites. Je valide les arbitrages. J’ai vu trop de specs propres en apparence, mais pleines de décisions inventées par l’IA. C’est confortable, mais dangereux.
Avant de passer au design, je verrouille au minimum ça :
- Le besoin utilisateur est clair et relié à un usage réel.
- Les entrées et sorties sont définies, formats compris.
- Les cas limites sont listés, pas repoussés à plus tard.
- Les règles de sécurité sont explicites, surtout sur les données sensibles.
- Les exclusions sont écrites, pour éviter le “tant qu’on y est”.
- Les arbitrages sont validés par moi, pas inventés par l’agent.
Que doit contenir le design ?
Le design doit transformer les exigences en décisions techniques vérifiables avant l’exécution.
Je ne parle pas d’une architecture de 40 pages que personne ne relit. Je parle d’une carte assez précise pour éviter que l’agent parte explorer le code au hasard, devine les conventions, modifie trois fichiers de trop, puis casse un comportement existant sans s’en rendre compte.
Dans cette phase, je veux surtout verrouiller les choses concrètes. Les modèles de données, les contrats API, les fichiers à lire, les fichiers à modifier, les flux entre composants, les dépendances, les effets de bord, les migrations éventuelles et les erreurs attendues. Une API, c’est simplement un point d’échange entre deux parties du système. Le contrat API décrit ce qu’on envoie, ce qu’on reçoit, et ce qui se passe quand ça échoue.
Claude Code est un bon exécutant quand les frontières sont claires. Je lui dis quels fichiers lire, quels fichiers modifier, quelles conventions respecter, quels comportements ne pas casser. C’est là que la spec devient utile. Elle réduit l’espace de recherche. Elle évite les “je pense que”. Elle force des choix vérifiables.
Je fais souvent préciser ces éléments avant de lancer l’implémentation :
- Les entrées attendues, avec leurs formats et leurs contraintes.
- Les sorties attendues, avec les cas nominaux et les cas d’erreur.
- Les fichiers concernés, séparés entre lecture seule et modification autorisée.
- Les tests automatisés à créer ou à adapter.
- Les critères d’acceptation observables, c’est-à-dire ce qu’on peut vérifier sans interprétation.
Les tests automatisés, les contrats d’interface et les critères d’acceptation observables ne sont pas des lubies liées à l’IA. Ce sont des pratiques classiques d’ingénierie logicielle pour limiter les régressions. La différence, c’est qu’avec un agent, elles deviennent encore plus importantes, parce qu’il peut produire vite, y compris produire vite une mauvaise direction.
Petit aparté honnête. J’ai vu des specs très longues échouer parce qu’elles décrivaient beaucoup le “pourquoi”, la vision, le contexte produit, mais presque rien sur les entrées, les sorties et les erreurs. Ça donne une belle intention, pas une exécution fiable.
| Élément de design | Pourquoi c’est utile | Exemple de formulation |
| Modèle de données | Évite les champs inventés et les incohérences. | Ajouter un champ “status” avec les valeurs draft, active, archived. |
| Contrat API | Clarifie les entrées, sorties et erreurs. | POST /projects retourne 201 avec id, name, createdAt, ou 400 si name est vide. |
| Fichiers touchés | Réduit les modifications inutiles. | Modifier uniquement project.service.ts et project.controller.ts. |
| Effets de bord | Protège les comportements existants. | Ne pas modifier le calcul des permissions utilisateur. |
| Critères d’acceptation | Rend le résultat vérifiable. | Un utilisateur non admin reçoit une erreur 403 sur la suppression. |
Comment écrire des critères testables ?
Un bon critère d’acceptation doit pouvoir échouer devant une commande, pas seulement sembler correct à l’agent. C’est le point que je vérifie en premier dans une spec, parce qu’un critère flou donne une illusion de contrôle.
Une suite de tests verte ne prouve rien si les tests peuvent être contournés, ignorés, transformés en skip, ou si le critère n’a pas d’état d’échec observable. J’ai déjà vu ça chez un client : l’agent avait “réussi” la tâche, les tests passaient, mais deux tests critiques avaient été désactivés. Techniquement, tout était vert. En réalité, on avait perdu le signal.
Une commande peut trancher. Ça peut être un test automatisé, une commande de build, un lint, une requête SQL, une comparaison de sortie, un statut HTTP attendu, une valeur en base, ou un fichier généré. Le critère doit dire ce qu’on lance, ce qu’on observe, et ce qui fait échouer.
| Mauvais critère | Bon critère |
| L’export doit être rapide. | La commande de test vérifie que l’export de 10 000 lignes produit un fichier CSV avec l’en-tête attendu et se termine sans erreur. |
| L’API doit bien gérer les erreurs. | Une requête POST invalide retourne un statut HTTP 400 avec un champ error.code égal à VALIDATION_ERROR. |
| Le fichier doit être généré correctement. | Après exécution de la commande, le fichier reports/monthly.csv existe, contient 12 colonnes, et la première ligne correspond à l’en-tête attendu. |
| Le code doit être propre. | La commande de lint se termine avec un code de sortie 0, sans désactiver de règle existante. |
Je mets aussi noir sur blanc les interdits anti-faux positifs. Ne pas skip les tests. Ne pas modifier les assertions juste pour les faire passer. Ne pas supprimer un test sans justification explicite dans la spec ou dans la pull request. Ne pas remplacer une vérification précise par une vérification molle du genre “le fichier existe”.
Les commandes peuvent rester génériques, l’idée n’est pas de dépendre d’un framework précis :
npm test
pytest
make test
make lint
./scripts/check-export.sh
- Chaque critère doit avoir une commande ou une vérification observable.
- Chaque critère doit définir clairement ce qui fait échouer.
- Chaque résultat attendu doit être mesurable, pas interprétable.
- Chaque test ajouté doit rester actif, sans skip ni contournement.
- Chaque assertion doit vérifier un comportement utile, pas juste l’absence d’erreur.
- Chaque suppression de test doit être justifiée et relue.
- Chaque critère doit pouvoir être rejoué par une autre personne ou par un agent.
Pourquoi exécuter en session fraîche ?
J’exécute en session fraîche pour que l’implémentation parte du spec validé, pas des idées explorées pendant la préparation. C’est une règle simple, mais je la vois souvent oubliée dans la phase Execute du spec-driven development.
La phase Execute, c’est le moment où on arrête de réfléchir en vrac et où on code à partir d’un contrat clair. Ce contrat, c’est le SPEC.md. Il contient les Requirements, donc ce que le produit doit faire, le Design, donc comment on prévoit de le construire, et les Tasks, donc les actions à exécuter dans le bon ordre.
Avec Claude Code, c’est encore plus important. Pendant l’interview et le design, l’agent a vu plein de choses. Des pistes rejetées. Des hypothèses discutées. Des variantes qu’on a testées mentalement. Des raccourcis qu’on a finalement abandonnés. Et même si tout ça n’est pas dans le SPEC.md final, ça reste dans le contexte de la session.
Si je garde la même session pour coder, je prends le risque que Claude s’appuie sur une vieille idée au lieu du spec validé. C’est subtil. Il ne va pas forcément dire “je reprends cette hypothèse rejetée”. Il va juste produire un bout de code légèrement aligné avec une conversation passée. Et là, on perd le bénéfice du spec-driven development.
Mon workflow propre ressemble à ça :
- Je prépare les Requirements, le Design et les Tasks avec l’agent.
- J’édite le SPEC.md pour enlever l’ambigu, le bruit, les options non retenues.
- J’ouvre une nouvelle session Claude Code.
- Je donne uniquement le spec validé.
- Je demande l’exécution tâche par tâche, sans improviser.
Les tâches doivent être ordonnées avec leurs dépendances. D’abord les structures, comme les modèles, les dossiers, les schémas de données. Ensuite les comportements, comme les fonctions métier et les flux. Puis les tests. Puis la validation finale. C’est bête, mais ça évite de demander à l’agent de tester un comportement alors que la structure n’est pas stable.
Je préfère des lots petits et vérifiables plutôt qu’une grosse génération impossible à relire. Sur un projet client, on avait gagné du temps en apparence avec une grosse passe de code. On en a perdu le double à comprendre pourquoi certains choix venaient d’une option discutée puis abandonnée deux heures avant.
| Session unique | Session fraîche |
| Contexte pollué par les hypothèses, variantes et pistes rejetées. | Contexte limité au SPEC.md validé. |
| Risque de code influencé par la phase de préparation. | Implémentation alignée sur le contrat final. |
| Plus difficile de savoir d’où vient une décision. | Décisions traçables dans les Requirements, Design et Tasks. |
| Génération souvent large, moins contrôlable. | Exécution tâche par tâche, plus simple à relire. |
Et si le vrai gain venait du cadrage ?
Le spec-driven development n’est pas une couche de process en plus, c’est une façon simple de rendre Claude Code plus fiable. Je clarifie les exigences, je transforme ça en design exploitable, je découpe les tâches, puis j’exécute dans une session fraîche. Le point clé reste les critères d’acceptation : ils doivent pouvoir échouer via une commande, sinon on risque juste une fausse impression de qualité. Pour moi, c’est là que l’IA devient vraiment utile en production. Vous gardez le contrôle, l’agent code mieux, et vous gagnez du temps sans sacrifier la fiabilité.
FAQ
- Qu’est-ce que le spec-driven development ? Le spec-driven development consiste à écrire des spécifications claires avant de laisser un agent comme Claude Code produire le code. Le but, c’est de réduire les décisions implicites et d’augmenter les chances d’obtenir une implémentation conforme.
- Pourquoi utiliser Claude Code avec un spec ? Claude Code est plus fiable quand il reçoit un cadre précis : exigences, design, tâches, fichiers concernés et critères d’acceptation. Sans ça, il doit deviner trop de choses, et chaque hypothèse augmente le risque d’erreur.
- À quoi sert le mode plan dans Claude Code ? Le mode plan sert à clarifier avant de coder. L’agent peut poser des questions, explorer les besoins et proposer un SPEC.md sans écrire directement l’implémentation. C’est utile pour éviter la production prématurée de code basé sur des hypothèses fragiles.
- Comment éviter les faux tests verts ? Il faut écrire des critères qu’une commande peut vérifier. Un test ne doit pas pouvoir être simplement ignoré, passé en skip ou modifié pour devenir vert. Le spec doit préciser ce qui doit échouer si le comportement attendu n’est pas présent.
- Pourquoi lancer l’exécution dans une nouvelle session ? Une session fraîche évite que l’agent soit influencé par les pistes rejetées pendant la phase de réflexion. Il repart du spec validé, pas de tout l’historique de discussion. C’est plus propre pour obtenir une implémentation alignée.
A propos de l’auteur
Je suis Franck Scandolera, expert et formateur en tracking avancé server-side, Analytics Engineering, automatisation No/Low Code avec n8n, intégration de l’IA en entreprise et SEO/GEO. J’accompagne des équipes qui veulent utiliser l’IA pour produire mieux, pas juste plus vite. Avec webAnalyste et Formations Analytics, j’ai travaillé pour des clients comme Logis Hôtel, Yelloh Village, BazarChic, la Fédération Française de Football ou Texdecor. Si vous voulez cadrer vos usages IA, automatiser vos workflows ou fiabiliser vos projets data, contactez-moi.
⭐ Data Analyst, Analytics Engineer et expert dans l’automatisation IA ⭐
Ref clients : Logis Hôtel, Yelloh Village, BazarChic, Fédération Football Français, Texdecor…
Mon terrain de jeu :
Data Analyst & Analytics engineering : tracking propre RGPD, entrepôt de données (GTM server, BigQuery…), modèles (dbt/Dataform), dashboards décisionnels (Looker, SQL, Python).
Automatisation IA des taches Data, Marketing, RH, compta etc : conception de workflows intelligents robustes (n8n, Make, App Script, scraping) connectés aux API de vos outils et LLM (OpenAI, Mistral, Claude…).
Engineering IA pour créer des applications et agent IA sur mesure : intégration de LLM (OpenAI, Mistral…), RAG, assistants métier, génération de documents complexes, APIs, backends Node.js/Python.





