Rédiger de bons spécifications
Vous écrivez rarement une spécification à partir d'une page blanche. Vous décrivez un changement en langage naturel, /opsx:propose rédige les exigences et les scénarios, puis vous les améliorez. Cette page porte sur cette dernière étape — ce qu'est un résultat « bon » et comment orienter l'IA vers ce résultat.
C'est le complément à Revue d'un changement : la revue consiste à repérer les points faibles d'une ébauche, tandis que la rédaction consiste à savoir de quoi est faite une bonne spécification.
Une spécification décrit un comportement, pas du code
Une spécification indique ce que votre système fait, en des termes vérifiables par n'importe qui — et non comment il est construit. Elle est composée d'exigences (énoncés de comportement) et de scénarios (exemples concrets qui les prouvent).
### Exigence : Délai d'inactivité de session
Le système DOIT expirer une session après 30 minutes d'inactivité.
#### Scénario : Délai d'inactivité
- ÉTANT DONNÉ une session authentifiée
- LORSQUE 30 minutes s'écoulent sans activité
- ALORS la session est invalidée et l'utilisateur doit se ré-authentifierConservez le comment — la file d'attente, la bibliothèque, le schéma de table — dans design.md ou dans le code. Lorsque le comportement et l'implémentation sont mélangés au sein d'une seule exigence, celle-ci cesse d'être testable et devient obsolète dès le premier changement de code.
Ce qui fait une bonne exigence
Une bonne exigence décrit un seul comportement, formulé si simplement que vous pourriez la confier à quelqu'un d'autre pour qu'il la teste.
Une phrase, un
DOIT/DEVEIT. Si une exigence contient trois clauses « et aussi », il s'agit en réalité de trois exigences. Séparez-les.Observable. Quelqu'un en dehors du code devrait pouvoir déterminer si elle est respectée. « Le système DOIT afficher une bannière d'erreur lorsque le téléchargement dépasse 10 Mo » est observable. « Le système DOIT gérer les gros téléchargements avec élégance » ne l'est pas.
La force appropriée. OpenSpec utilise les mots-clés RFC 2119, qui ont des significations différentes :
Mot-clé Signification MUST/SHALLUne exigence stricte. Non négociable. SHOULDUne recommandation forte, laissant place à une exception justifiée. MAYVraiment optionnel. Privilégiez par défaut
MUST/SHALL. N'utilisezSHOULDque lorsque vous voulez vraiment dire « sauf s'il y a une bonne raison de ne pas le faire ».
Le test d'une exigence : un testeur qui n'a jamais vu le code pourrait-il dire si elle a été validée ? Si non, elle doit être affinée.
Ce qui fait un bon scénario
Les scénarios sont l'endroit où une exigence prouve sa valeur. Chacun est un GIVEN / WHEN / THEN concret qui pourrait devenir un test automatisé.
- Il met en œuvre son exigence. Un scénario qui ne fait que reformuler l'exigence avec d'autres mots ne teste rien. Créez une situation spécifique avec un résultat spécifique.
- Couvrez les cas importants, pas seulement le chemin heureux. La connexion valide est facile. Les entrées vides, le jeton expiré, le deuxième clic, les erreurs — c'est là que résident les bugs, et c'est là qu'un scénario a le plus de valeur.
- Nommez le cas dans le titre. « Scénario : Rejette un jeton expiré » indique au réviseur ce qui est couvert en un coup d'œil ; « Scénario : Test 2 » ne l'indique pas.
Une habitude utile : avant d'approuver, demandez-vous quel est le cas unique dont je serais mécontent de voir la rupture ? — et assurez-vous qu'un scénario le nomme explicitement.
Choisissez le bon type de delta
Un changement décrit ses modifications aux spécifications via trois types de sections. Utiliser le bon type maintient l'honnêteté de vos spécifications archivées :
## ADDED Requirements— nouveaux comportements qui n'existaient pas auparavant.## MODIFIED Requirements— comportements existants qui changent. Incluez la nouvelle version complète ; une courte note expliquant ce qui a changé aide le réviseur.## REMOVED Requirements— comportements supprimés, accompagnés d'une ligne expliquant pourquoi.
Lors de l'archivage, ADDED est ajouté à la spécification principale, MODIFIED remplace l'ancienne version, et REMOVED est supprimé. Supprimez la dernière exigence d'une capacité et vous la retirez : plutôt que de laisser une spécification vide, l'archive supprime openspec/specs/<capability>/spec.md. Comme c'est la seule étape d'archive qui supprime un fichier, elle doit être explicitement demandée — ajoutez retire_capabilities: true au .openspec.yaml du changement, à côté du schema: que ce fichier nécessite déjà. Sans cela, l'archive échoue et vous l'indique. La suppression supprime le fichier entier, elle est donc également refusée tant que la spécification contient autre chose que son titre, ## Purpose, et ses blocs d'exigences — une section ## Notes, un commentaire sous une exigence. L'échec liste ces lignes ; déplacez-les dans ## Purpose ou une exigence, ou supprimez la spécification manuellement. Pour une spécification dans le répertoire de travail du caller, la sortie de l'archive indique également la commande git checkout permettant de restaurer un fichier engagé ; les magasins sélectionnés reçoivent des instructions de récupération spécifiques au contexte de checkout. Si vous marquez un vrai changement comme ADDED, vous vous retrouvez avec deux exigences concurrentes ; si vous décrivez un nouveau comportement comme MODIFIED, il n'y a rien à remplacer. En cas de doute, ouvrez la spécification actuelle et vérifiez si l'exigence y figure déjà.
Une autre section vaut la peine d'être connue. Lorsque votre delta crée une capacité qui n'existe pas encore, ouvrez-la avec ## Purpose — une ou deux phrases expliquant l'utilité de la capacité. L'archive l'utilise comme Objectif de la spécification principale qu'elle crée ; omettez-le et vous obtiendrez un espace réservé TBD à remplir manuellement. Une spécification existante possède déjà un Objectif, donc celui d'un delta est ignoré dans ce cas — modifiez directement openspec/specs/<capability-path>/spec.md pour changer l'un d'eux. Ici, <capability-path> est le répertoire relatif à specs/, tel que user-auth dans un projet plat ou identity/user-auth dans un projet organisé par domaine.
Dimensionnez correctement le changement
L'erreur de rédaction la plus courante n'est pas une exigence mal formulée — c'est un changement qui tente d'être trois changements.
Un bon changement a une intention unique que vous pouvez exprimer en une phrase. « Ajouter un bouton basculant pour le mode sombre. » « Limiter le taux de l'endpoint de connexion. » « Migrer les sessions hors des cookies. » Si la description du changement nécessite beaucoup de « et aussi », c'est le signal de le diviser.
Signes qu'un changement est trop volumineux :
- La portée de la proposition ressemble à une liste de fonctionnalités sans rapport.
- Sa révision prendrait un après-midi, donc personne ne le fera.
- Deux personnes ne pourraient pas travailler dessus sans entrer en collision.
- La moitié des tâches pourraient être livrées indépendamment.
Les changements plus petits sont plus faciles à réviser, plus faciles à développer en une session focalisée, et plus faciles à appréhender six mois plus tard lorsque l'archive sera la seule trace restante. Vous pouvez toujours exécuter plusieurs changements en parallèle — voir Édition et itération et Flux de travail.
L'inverse arrive aussi : une correction de typo d'une ligne ne nécessite pas trois exigences et un document de conception. Adaptez la cérémonie aux enjeux.
Comment orienter l'IA vers une bonne ébauche
Parce que /opsx:propose réalise la première ébauche, la qualité de ce que vous recevez dépend de la qualité de ce que vous lui donnez. Vous n'avez pas besoin d'écrire les exigences à la main — vous devez bien guider l'IA :
- Énoncez l'intention et la limite. « Ajoutez un bouton basculant pour le mode sombre qui suit le paramètre du système d'exploitation au premier chargement — ne touchez pas l'API de thème existante. » La partie hors périmètre est aussi importante que la partie dans le périmètre.
- Nommez les cas qui vous intéressent. « Assurez-vous qu'il y ait un scénario pour un utilisateur ayant déjà choisi un thème manuellement. » L'IA couvre ce que vous lui pointez du doigt.
- Puis éditez. C'est du Markdown brut. Affinez un
DOITvague, supprimez un scénario qui ne teste rien, ajoutez le cas qu'il a manqué — ou demandez à l'IA de le faire : « l'exigence de délai d'inactivité est vague, fixez-la à 30 minutes. »
Ébauchez, affinez, répétez. Quelques tours de cela produisent une spécification digne de confiance, ce qui est tout l'intérêt.
Une rapide checklist
Où aller ensuite
- Revue d'un changement — le passage rapide de deux minutes qui repère ce qui a été oublié.
- Concepts — le modèle profond derrière les spécifications, les changements et les deltas.
- Exemples & Recettes — des changements réels, du début à la fin.