AI Spec-Driven Development : coder depuis la spec

En résumé
- L'AI Spec-Driven Development place des spécifications versionnées avant la génération de code.
- La spec relie le besoin métier, le plan technique, les tâches et les critères de validation.
- La méthode réduit les écarts d'interprétation, sans remplacer les revues d'architecture, de sécurité et de code.
Les assistants de code ont changé de rythme. Une demande de quelques lignes peut produire une API, ses types TypeScript, les tests et la migration PostgreSQL en quelques minutes.
Le résultat compile parfois du premier coup. C’est précisément ce qui rend l’écart difficile à voir.
Sur un projet métier, le problème vient rarement de la vitesse d’écriture. Il vient des règles qui n’ont pas été dites : que faire d’un doublon, qui peut lancer l’opération, comment reprendre après un échec, quelles données journaliser, quelle volumétrie supporter. Un agent remplit les blancs. Il le fait avec assurance, mais pas avec la connaissance du terrain.
L’AI Spec-Driven Development, souvent abrégé en SDD, remet une étape durable entre le besoin et le code. Le besoin est transformé en spécification versionnée. Cette spécification alimente ensuite le plan technique, le découpage des tâches, l’implémentation et les tests.
La démarche n’est pas réservée aux nouveaux projets. Elle fonctionne aussi sur une application WinDev ancienne, une API Nuxt, un service TypeScript ou un traitement batch sous Linux. Le niveau d’automatisation change. Le principe reste le même : l’agent doit travailler depuis des décisions explicites, pas depuis une conversation devenue illisible au bout de quarante messages.
Définition de l’AI Spec-Driven Development
L’AI Spec-Driven Development est une méthode de développement assisté par IA où la spécification devient l’artefact central du travail.
Elle contient au minimum :
- le problème à résoudre ;
- le périmètre fonctionnel ;
- les cas non couverts ;
- les règles métier ;
- les critères d’acceptation ;
- les contraintes techniques et non fonctionnelles ;
- les décisions qui demandent encore un arbitrage.
Le code n’est lancé qu’après une phase de clarification et un plan d’implémentation relu.
Le workflow proposé par GitHub Spec Kit suit une chaîne simple : Spec → Plan → Tasks → Implement. Kiro structure ses feature specs autour des exigences, du design et des tâches. OpenSpec adopte une couche plus légère, pensée pour éviter que les exigences restent uniquement dans l’historique du chat.
Ces outils ne définissent pas une norme unique. Ils partagent une idée assez opérationnelle : une demande adressée à un agent doit laisser des fichiers relisibles dans le dépôt.
Pourquoi le prompt seul atteint vite ses limites
Prenons une demande courante dans un ERP :
Ajouter un import CSV des tarifs fournisseurs.
Le prompt paraît clair. Il ne l’est pas.
Le fichier utilise-t-il la virgule ou le point pour les décimales ? Un article inconnu doit-il bloquer tout le fichier ? Peut-on importer deux fois le même tarif ? La mise à jour doit-elle être transactionnelle ? Que devient une ligne valide si la suivante est erronée ? Qui a le droit de lancer l’import ? Faut-il conserver le fichier source ? Une reprise est-elle possible après coupure ?
Un développeur métier pose ces questions parce qu’il a déjà vu le sujet déborder. L’agent, lui, peut générer une interprétation complète sans signaler toutes ses hypothèses.
Une conversation améliore la première réponse. Elle reste un support fragile :
- les décisions sont dispersées ;
- une correction tardive contredit parfois un message plus ancien ;
- un autre développeur ne connaît pas le contexte ;
- un nouvel agent repart avec une partie seulement de l’historique ;
- la pull request montre le code, pas le raisonnement qui a fixé le comportement.
La spec rend ces éléments visibles. Une modification du comportement devient un diff Git. C’est nettement plus facile à discuter qu’un extrait de chat copié dans un ticket.
Les quatre artefacts utiles
Une mise en place raisonnable peut démarrer avec quatre fichiers. Inutile d’installer un framework complet dès le premier essai.
specs/
└── 017-import-tarifs-fournisseurs/
├── spec.md
├── plan.md
├── tasks.md
└── acceptance.md
spec.md : le comportement attendu
Ce fichier décrit le besoin et ses limites. Il reste lisible par un responsable métier.
# Import des tarifs fournisseurs
## Objectif
Permettre au service achats d'importer un fichier CSV contenant
les nouveaux tarifs d'un fournisseur.
## Périmètre
- Format CSV UTF-8 avec séparateur point-virgule.
- Colonnes obligatoires : reference, prix_achat, date_effet.
- Une référence inconnue invalide la ligne, pas le fichier complet.
- Les lignes valides sont appliquées dans une transaction unique.
- Seuls les utilisateurs du rôle ACHATS peuvent lancer l'import.
## Hors périmètre
- Création automatique des articles inconnus.
- Import de fichiers Excel.
- Modification des prix de vente.
## Contraintes
- 100 000 lignes maximum.
- Durée cible inférieure à 5 minutes sur l'environnement de production.
- Conservation du fichier source et du compte rendu pendant 12 mois.
Il faut accepter qu’une spec garde quelques questions ouvertes au début. Les masquer donne un document propre, mais une implémentation incertaine.
## Questions à arbitrer
- Un prix égal à zéro est-il autorisé ?
- Le même article peut-il apparaître plusieurs fois dans le fichier ?
- Quelle date retenir si deux lignes ont la même référence ?
Tant que ces points ne sont pas tranchés, l’agent ne devrait pas produire le traitement final.
plan.md : les choix techniques
Le plan traduit la spec dans l’architecture existante. Il ne doit pas réinventer le projet.
# Plan technique
## Composants touchés
- API Nuxt : POST /api/imports/tarifs-fournisseurs
- Worker TypeScript : traitement asynchrone du fichier
- PostgreSQL : table de staging import_tarif_ligne
- Stockage objet : conservation du fichier original
- Journal d'audit : utilisateur, date, fournisseur, résultat
## Stratégie de traitement
1. Valider le type, la taille et l'encodage du fichier.
2. Charger les lignes dans une table de staging.
3. Résoudre les références articles en une requête.
4. Produire le rapport d'erreurs.
5. Appliquer les lignes valides dans une transaction.
6. Publier le statut final de l'import.
## Décisions
- Pas de traitement synchrone dans la requête HTTP.
- Pas de boucle SQL ligne par ligne.
- Les prix existants ne sont jamais écrasés sans date d'effet.
Dans une application existante, ce fichier doit citer les composants réels. Un plan qui crée un nouveau service, une nouvelle file de messages et une nouvelle base pour un import mensuel de 2 000 lignes mérite une discussion avant la moindre génération.
tasks.md : un découpage exécutable
Les tâches doivent être assez petites pour être vérifiées séparément.
# Tâches
- [ ] T01 Ajouter les types d'entrée et les erreurs métier.
- [ ] T02 Créer la migration de la table de staging.
- [ ] T03 Implémenter le parseur CSV et ses tests.
- [ ] T04 Résoudre les références articles par lot.
- [ ] T05 Générer le rapport des lignes rejetées.
- [ ] T06 Appliquer les lignes valides dans une transaction.
- [ ] T07 Ajouter le contrôle du rôle ACHATS.
- [ ] T08 Exposer le suivi d'avancement de l'import.
- [ ] T09 Ajouter les métriques et le journal d'audit.
- [ ] T10 Exécuter les scénarios d'acceptation.
Une tâche comme " développer tout l’import " redonne à l’agent la liberté que la spec devait justement réduire.
acceptance.md : les preuves attendues
Les critères d’acceptation peuvent rester en Markdown, utiliser Gherkin ou être reliés directement à des tests.
Scénario: une ligne contient une référence inconnue
Étant donné un fichier avec 100 lignes
Et une ligne contenant une référence inconnue
Quand le service achats lance l'import
Alors 99 lignes sont appliquées
Et la ligne inconnue apparaît dans le rapport d'erreurs
Et le statut final indique "terminé avec rejets"
Le scénario est plus utile qu’une phrase comme " gérer les erreurs “. Il fixe le comportement observable.
Un workflow de travail qui tient en équipe
Le déroulement complet peut paraître lourd. Dans les faits, les étapes sont courtes quand le sujet est correctement dimensionné.
Partir du problème, pas de la solution demandée
Une demande métier arrive souvent déjà emballée dans une solution :
Il nous faut un bouton qui appelle une IA pour corriger les commandes.
La spec doit d’abord revenir au problème. Quelle anomalie faut-il détecter ? À quel moment ? Quel taux d’erreur est acceptable ? Qui valide la correction ? Les données peuvent-elles sortir du système d’information ?
Cette phase évite de générer proprement la mauvaise fonctionnalité.
Faire produire une première spec par l’agent
L’agent est utile pour transformer des notes, un ticket et quelques exemples en document structuré. Il sait aussi relever des incohérences.
Il faut lui demander de marquer les inconnues, pas de les inventer.
À partir du ticket et des fichiers du dépôt, rédige une spec fonctionnelle.
N'invente aucune règle manquante.
Place chaque ambiguïté dans une section "Questions à arbitrer".
Ne propose pas encore de code ni d'architecture.
Le résultat est relu par la personne qui connaît le processus métier. Sur un projet PME, ce n’est pas toujours le product owner. Cela peut être la responsable achats, le comptable ou la personne qui corrige les fichiers chaque lundi matin.
Produire le plan après validation du comportement
Le plan technique arrive ensuite. L’agent peut explorer le dépôt, identifier les conventions et proposer les fichiers touchés.
La revue porte sur des points très terre-à-terre :
- le composant proposé existe-t-il déjà ?
- la transaction couvre-t-elle vraiment toutes les écritures ?
- le volume annoncé est-il réaliste ?
- la sécurité est-elle traitée au bon niveau ?
- la migration peut-elle être annulée ?
- les logs contiennent-ils des données sensibles ?
Un plan approuvé évite de découvrir ces choix dans une pull request de trente fichiers.
Implémenter par lots courts
L’agent traite une ou quelques tâches. Chaque lot passe les tests, le lint et la revue avant de poursuivre.
C’est moins spectaculaire qu’une génération complète. Le diagnostic est aussi beaucoup plus simple quand la tâche T04 échoue sans avoir simultanément modifié l’API, le schéma SQL et l’interface.
Revenir à la spec après le code
La validation finale ne consiste pas uniquement à vérifier que la CI est verte.
Il faut reprendre les critères d’acceptation, les contraintes de volumétrie, les droits, la journalisation et les scénarios d’échec. Une suite de tests unitaires peut être parfaite tout en oubliant le cas métier principal.
Installer GitHub Spec Kit sous Linux
GitHub Spec Kit fournit un outillage pour initialiser un projet et guider les différentes phases. Le script ci-dessous prépare un poste Linux avec uv, puis installe une version épinglée de l’outil.
La version doit être validée et mise à jour par l’équipe. Évitez une installation permanente depuis une branche mouvante sur un environnement de production.
#!/usr/bin/env bash
set -euo pipefail
SPEC_KIT_VERSION="${SPEC_KIT_VERSION:-v0.12.11}"
sudo apt-get update
sudo apt-get install -y \
ca-certificates \
curl \
git
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="${HOME}/.local/bin:${PATH}"
uv tool install specify-cli \
--from "git+https://github.com/github/spec-kit.git@${SPEC_KIT_VERSION}"
specify check
echo "Spec Kit ${SPEC_KIT_VERSION} installé."
Pour initialiser un nouveau dépôt :
specify init mon-projet
cd mon-projet
Sur un dépôt existant, créez d’abord une branche et examinez les fichiers ajoutés. Les templates doivent être adaptés aux conventions du projet, pas l’inverse.
Ajouter une barrière simple dans la CI
Une spec n’a de valeur que si l’équipe la maintient. Un contrôle basique peut déjà empêcher les oublis les plus fréquents.
#!/usr/bin/env bash
set -euo pipefail
SPEC_DIR="${1:-}"
if [[ -z "${SPEC_DIR}" ]]; then
echo "Usage: $0 specs/NNN-nom-fonctionnalite" >&2
exit 64
fi
required_files=(
"spec.md"
"plan.md"
"tasks.md"
"acceptance.md"
)
for file in "${required_files[@]}"; do
if [[ ! -s "${SPEC_DIR}/${file}" ]]; then
echo "Fichier absent ou vide : ${SPEC_DIR}/${file}" >&2
exit 1
fi
done
if grep -RniE \
"NEEDS CLARIFICATION|QUESTION À ARBITRER|TODO_SPEC" \
"${SPEC_DIR}"; then
echo "La spec contient encore des arbitrages ouverts." >&2
exit 1
fi
if ! grep -qE '^- \[[ xX]\] T[0-9]+' "${SPEC_DIR}/tasks.md"; then
echo "Aucune tâche identifiée dans tasks.md." >&2
exit 1
fi
echo "Contrôle de spec terminé : ${SPEC_DIR}"
Un job GitHub Actions peut l’exécuter sur la spec concernée par la pull request.
name: spec-gate
on:
pull_request:
jobs:
validate-spec:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Vérifier la spec
run: |
chmod +x scripts/check-spec.sh
scripts/check-spec.sh specs/017-import-tarifs-fournisseurs
Ce contrôle ne juge pas la qualité du besoin. Il évite seulement qu’un agent démarre alors que le document contient encore des marqueurs explicites d’incertitude.
Transformer les critères en tests TypeScript
Le passage de la spec au code gagne en fiabilité quand les critères d’acceptation deviennent des tests lisibles.
import { describe, expect, it } from "vitest";
import { importSupplierPrices } from "../import-supplier-prices";
describe("importSupplierPrices", () => {
it("applique les lignes valides et reporte une référence inconnue", async () => {
const result = await importSupplierPrices({
supplierId: "FOU-0042",
initiatedBy: "user-achats-17",
rows: [
{ reference: "ART-001", purchasePrice: 12.4, effectiveDate: "2026-07-01" },
{ reference: "INCONNUE", purchasePrice: 8.2, effectiveDate: "2026-07-01" },
],
});
expect(result.appliedCount).toBe(1);
expect(result.rejectedCount).toBe(1);
expect(result.status).toBe("completed_with_rejections");
expect(result.errors[0]).toMatchObject({
reference: "INCONNUE",
code: "UNKNOWN_ARTICLE",
});
});
});
L’agent peut générer le squelette. Le développeur doit vérifier que le test prouve bien la règle métier, pas seulement l’implémentation choisie.
Un mauvais test peut figer une mauvaise interprétation avec beaucoup d’efficacité.
Utiliser la méthode dans un projet WinDev
L’AI Spec-Driven Development n’exige pas que l’IDE sache piloter un agent de bout en bout.
Dans un projet WinDev, les specs peuvent vivre dans le dépôt Git à côté des sources exportées, des requêtes, de la documentation d’analyse et des scripts d’intégration. L’agent produit alors des propositions de code WLangage, de requêtes HFSQL ou de contrats d’API à partir de fichiers structurés.
Le point de départ peut reprendre les conventions déjà utilisées pour améliorer la qualité du code WLangage généré par l’IA . Les instructions de nommage et les patterns de code restent utiles. La spec ajoute le comportement métier, les contraintes et les preuves attendues.
Un dossier peut ressembler à ceci :
specs/
└── 023-recalcul-marges/
├── spec.md
├── plan.md
├── tasks.md
├── acceptance.md
├── modele-donnees.md
└── conventions-wlangage.md
Pour une modification HFSQL, le plan doit préciser les fichiers de données, les index, les requêtes WDR, la stratégie de transaction et la reprise sur erreur. Sans cela, l’agent peut produire du code WLangage correct en apparence et médiocre sur plusieurs millions de lignes.
La compilation WinDev, les tests manuels et la revue restent dans la boucle. L’automatisation est moins intégrée que dans un projet TypeScript, mais le bénéfice documentaire est déjà réel.
Ce que la spec doit contenir pour être utile à une IA
Une spec efficace n’est pas forcément longue. Elle est précise là où l’agent risque d’interpréter.
Les exemples réels
Un fichier d’entrée, une facture anonymisée, une erreur de production ou une capture du comportement actuel vaut souvent plus qu’une page de vocabulaire générique.
Pour une règle de calcul, ajoutez deux ou trois cas chiffrés :
Cas A
Prix d'achat : 80,00 €
Prix de vente : 100,00 €
Remise : 10 %
Marge attendue : 10,00 €
Cas B
Prix d'achat : 80,00 €
Prix de vente : 100,00 €
Remise : 25 %
Marge attendue : -5,00 €
L’agent voit immédiatement si la remise intervient avant ou après le calcul de marge.
Les non-objectifs
Ils protègent le périmètre.
## Non-objectifs
- Reconcevoir l'écran de gestion des fournisseurs.
- Modifier les règles de valorisation du stock.
- Remplacer le moteur d'import historique pour les commandes clients.
Sans cette section, un agent orienté " amélioration " peut élargir le chantier pendant qu’il résout le ticket.
Les contraintes non fonctionnelles
Elles sont fréquemment absentes des tickets et pourtant décisives :
- temps de réponse ;
- volumétrie ;
- concurrence ;
- disponibilité ;
- audit ;
- confidentialité ;
- compatibilité ;
- observabilité ;
- stratégie de retour arrière.
Une API conforme fonctionnellement mais incapable de traiter le volume du lundi matin n’est pas terminée.
Les décisions irréversibles ou coûteuses
Le choix d’un format public, d’un schéma de base, d’un fournisseur IA ou d’une stratégie de migration doit apparaître clairement.
Une ligne dans plan.md peut éviter plusieurs semaines de dette :
Décision : la réponse publique conserve le champ `supplierReference`.
Le renommage interne vers `vendorReference` reste limité au domaine TypeScript.
Différences avec le TDD, le BDD et le cahier des charges
Le vocabulaire se mélange vite.
Le TDD part d’un test de développement et fait évoluer le code par petites boucles. Le BDD exprime le comportement attendu dans un langage partagé. L’AI Spec-Driven Development couvre un périmètre plus large : problème, exigences, architecture, tâches, implémentation et validation par un agent.
Ces pratiques se complètent bien.
Le cahier des charges classique est souvent produit avant le projet, puis consulté de moins en moins. Une spec utilisée par un agent reste proche du dépôt et change avec le code. C’est une différence importante. Si elle devient un document figé de cinquante pages, elle perd rapidement cette propriété.
Le SDD n’est pas non plus un retour automatique au cycle en V. Une équipe peut travailler par petites évolutions, chacune avec une spec courte, une revue et des tests.
Les limites rencontrées en pratique
La méthode réduit certaines erreurs. Elle n’améliore pas magiquement la qualité d’un besoin faux.
Une spec peut être précise et incorrecte
Si la règle métier est mal comprise, l’agent l’appliquera avec constance. La relecture par une personne du terrain reste nécessaire.
Le formalisme peut dépasser la valeur du changement
Rédiger quatre fichiers pour renommer un libellé est une perte de temps. Le niveau de spec doit suivre le risque, le nombre de composants touchés et l’ambiguïté.
L’agent peut ignorer une partie du contexte
Une fenêtre de contexte large ne garantit pas que chaque contrainte sera respectée. Les critères importants doivent être courts, visibles et testés.
La spec dérive du code
Le développeur corrige un détail directement, puis oublie le document. Après quelques mois, l’agent reçoit une vérité ancienne.
La pull request doit donc répondre à une question simple : le comportement a-t-il changé ? Si oui, la spec doit changer dans le même commit ou expliquer pourquoi elle ne change pas.
Les exigences de sécurité sont faciles à sous-estimer
Un agent de code peut ajouter un endpoint, une dépendance ou un log qui expose des données. Les contrôles d’autorisation, les secrets, les données personnelles et les sorties générées doivent être revus comme sur n’importe quel développement. Pour les usages IA intégrés à WinDev, les articles sur la validation des sorties LLM et la protection contre les prompt injections donnent un cadre complémentaire.
Choisir entre Spec Kit, Kiro, OpenSpec ou des fichiers maison
Le choix de l’outil arrive après la méthode.
| Option | Point fort | Point à vérifier |
|---|---|---|
| GitHub Spec Kit | Workflow complet et artefacts structurés | Adaptation des templates au dépôt existant |
| Kiro Specs | Intégration directe dans un IDE agentique | Compatibilité avec les règles de sécurité et l’environnement de l’équipe |
| OpenSpec | Couche légère et adaptée à plusieurs assistants | Discipline nécessaire pour garder les specs à jour |
| Fichiers Markdown maison | Contrôle total et adoption rapide | Moins d’automatisation et de commandes guidées |
Pour un premier pilote, les fichiers maison suffisent souvent. L’équipe découvre ce qu’elle veut réellement standardiser.
Un outil devient utile quand plusieurs développeurs répètent le même workflow, quand les specs doivent être retrouvées facilement ou quand les agents changent selon les projets.
Introduire le SDD sans bloquer l’équipe
Je commencerais sur une évolution réelle, assez importante pour révéler les ambiguïtés, mais pas critique au point de rendre l’essai dangereux.
Une période pilote peut suivre ce cadre :
- choisir une fonctionnalité touchant deux ou trois composants ;
- conserver les pratiques de revue et de test existantes ;
- écrire la spec avec le métier ;
- laisser l’agent proposer le plan et les tâches ;
- implémenter par lots courts ;
- noter les corrections demandées à l’agent ;
- comparer avec une évolution similaire réalisée auparavant.
Les mesures utiles restent simples :
- nombre d’allers-retours de clarification ;
- tâches rouvertes après revue ;
- défauts détectés en recette ;
- fichiers modifiés hors périmètre ;
- temps consacré à reprendre du code généré ;
- spec encore exacte après livraison.
Il ne faut pas chercher un pourcentage universel de gain. Le premier résultat intéressant est souvent ailleurs : l’équipe identifie plus tôt les décisions qu’elle prenait jusque-là pendant le développement.
Bonnes pratiques de gouvernance
Quelques règles évitent que le dépôt se remplisse de specs décoratives.
La spec appartient à l’équipe, pas à l’agent. Son approbation doit avoir un responsable identifié.
Les arbitrages doivent être datés et associés à une décision. Une réponse donnée dans une réunion ne doit pas rester uniquement dans les notes personnelles d’un développeur.
Le plan technique est relu par quelqu’un qui connaît l’architecture existante. Cette revue est particulièrement importante sur les applications anciennes, où une dépendance invisible peut se trouver dans un état, une procédure globale ou un traitement planifié.
Les tâches doivent garder une taille compatible avec une revue humaine. Une pull request générée en une fois avec plusieurs milliers de lignes déplace seulement le travail vers le reviewer.
Enfin, les sorties de l’agent ne sont pas des preuves. Les tests, la compilation, l’analyse de sécurité, la recette et l’observation en production le sont.
Conclusion
L’AI Spec-Driven Development apporte une structure qui manque souvent au développement assisté par IA.
Le bénéfice n’est pas de produire davantage de Markdown. Il vient du lien maintenu entre le besoin, les décisions techniques, les tâches et les tests. Quand l’agent s’écarte du périmètre, l’équipe dispose d’un point de comparaison clair. Quand le besoin change, le changement devient visible avant de toucher plusieurs composants.
Pour une entreprise comme EloNeva, la méthode est surtout utile sur les outils métier : règles nombreuses, historique long, documentation incomplète et peu de marge pour une régression silencieuse.
L’agent peut écrire vite. La spec aide à vérifier qu’il travaille sur le bon problème, avec les bonnes limites, dans l’architecture qui existe réellement.