Skip to content

spec-driven ​

Les artefacts du workflow par défaut : leur ordre, leurs formats et le dossier de changement qu'ils produisent.

spec-driven est le schéma par défaut intégré d'OpenSpec. schema.yaml définit les champs qu'il configure.

Artefacts ​

Le workflow rédige quatre artefacts :

ArtefactFichierObjectif
proposalproposal.mdPourquoi le changement est nécessaire
specsspecs/<capability-path>/spec.md, un par capacitéQuel comportement change
designdesign.mdComment le construire
taskstasks.mdLa liste de contrôle de mise en œuvre

Ordre de rédaction ​

text
             ┌─ specs ──┐
proposal ────┤          ├── tasks ── apply
             └─ design ─┘

La proposition vient en premier. Les specs et le design suivent dans l'un ou l'autre ordre, et les tasks ont besoin des deux. L'implémentation (apply) commence une fois que tasks.md est en place.

Deux artefacts peuvent être ignorés :

  • design : lorsque aucune de ses conditions ne s'applique, l'agent l'omet et rédige quand même tasks.
  • specs : définir skip_specs: true dans le .openspec.yaml du changement.

Exemple de dossier de changement ​

Un changement nommé add-user-auth, avec tous les artefacts rédigés :

text
openspec/changes/add-user-auth/
├── .openspec.yaml      métadonnées du changement, écrites lors de la création du changement
├── proposal.md
├── specs/
│   └── user-auth/
│       └── spec.md     une spec delta par capacité
├── design.md
└── tasks.md

proposal.md ​

Établit pourquoi le changement est nécessaire.

Structure ​

Le modèle que l'agent reçoit comme format de sortie (templates/proposal.md) :

md
# Proposal

## Why

<!-- Expliquer la motivation de ce changement. Quel problème cela résout-il ? Pourquoi maintenant ? -->

## What Changes

<!-- Décrire ce qui va changer. Soyez précis sur les nouvelles capacités, les modifications ou les suppressions. -->

## Capabilities

### New Capabilities
<!-- Capacités introduites. Nommez chaque capacité pour un comportement système
     cohérent qui peut posséder des exigences connexes à mesure que le système évolue. Ne nommez pas
     les tâches d'implémentation ou les sections de la proposition. Évitez les noms trop larges. Utilisez
     kebab-case pour les segments de chemin que vous introduisez (par ex., user-auth ou identity/user-auth)
     qui suivent l'organisation existante des specs du projet. Chacune crée
     specs/<capability-path>/spec.md. -->
- `<capability-path>` : <brève description de ce que couvre cette capacité>

### Modified Capabilities
<!-- Capacités existantes dont les EXIGENCES changent (pas seulement l'implémentation).
     Ne lister ici que si le comportement au niveau spec change. Chacune nécessite un fichier de spec delta.
     Utilisez le chemin existant exact sous openspec/specs/. Laisser vide si aucune exigence
     ne change. Un changement sans aucune capacité (refactorisation pure, outillage, docs)
     doit définir `skip_specs: true` dans son .openspec.yaml - openspec validate rejette
     un changement sans delta sans ce marqueur. N'inventez pas une exigence juste pour
     satisfaire la validation. -->
- `<existing-capability-path>` : <quelle exigence change>

## Impact

<!-- Code, API, dépendances, systèmes affectés -->

Instructions ​

L'instruction envoyée à l'agent lorsqu'il rédige cet artefact (depuis schema.yaml) :

md
Créer le document de proposition qui établit POURQUOI ce changement est nécessaire.

Sections :
- **Why** : 1-2 phrases sur le problème ou l'opportunité. Quel problème cela résout-il ? Pourquoi maintenant ?
- **What Changes** : Liste à puces des changements. Soyez précis sur les nouvelles capacités, les modifications ou les suppressions. Marquez les changements breaking avec **BREAKING**.
- **Capabilities** : Identifier quelles specs seront créées ou modifiées :
  - **New Capabilities** : Lister les capacités introduites. Chacune devient un nouveau `specs/<capability-path>/spec.md`. Nommez chaque capacité pour un comportement système durable (par exemple, `user-auth`), et non le travail de ce changement (par exemple, `add-login-endpoint`). Choisissez une frontière cohérente qui peut posséder des exigences connexes à mesure que le système évolue ; évitez les capacités trop larges. Utilisez kebab-case pour les segments de chemin que vous introduisez (par ex., `user-auth` ou `identity/user-auth`) et suivez l'organisation existante des specs du projet.
  - **Modified Capabilities** : Lister les capacités existantes dont les EXIGENCES changent. N'inclure que si le comportement au niveau spec change (pas seulement des détails d'implémentation). Chacune nécessite un fichier de spec delta. Utilisez le chemin existant exact sous `openspec/specs/`. Laisser vide si aucune exigence ne change.
- **Impact** : Code, API, dépendances ou systèmes affectés.

IMPORTANT : La section Capabilities est critique. Elle crée le contrat entre
les phases de proposition et de specs. Recherchez les specs existantes avant de la remplir :
exécutez `openspec list --specs` pour l'inventaire des capacités du projet, puis
`openspec show "<spec-id>" --type spec --json --no-scenarios` pour celles qui
semblent liées - cela renvoie le but et les textes d'exigences d'une capacité
sans charger des fichiers spec entiers dans le contexte. Ajoutez `--store "<id>"` aux
deux commandes uniquement pour un registre autonome enregistré, et gardez `--type
spec` : un changement et une spec partageant un nom est sinon une erreur d'élément ambigu.
`openspec list` sans `--specs` liste les changements en cours, pas les
specs - cela ne montre jamais ce que le projet couvre déjà. Réutilisez le chemin exact
d'une capacité existante au lieu d'introduire un nom quasi-doublon.
La lecture filtrée n'est qu'un aperçu. Avant de décider ce qui est déjà
couvert ou ce qui doit changer, lisez chaque spec pertinente en entier, y compris
les scénarios, avec `openspec show "<spec-id>" --type spec` (même règle `--store`).
Chaque capacité listée ici nécessitera un fichier spec correspondant.

Chaque changement doit soit déclarer au moins une capacité (nouvelle ou
modifiée) soit explicitement renoncer aux specs : `openspec validate` rejette un
changement sans delta à moins que le `.openspec.yaml` du changement ne définisse
`skip_specs: true`. N'utilisez `skip_specs: true` que lorsqu'aucun comportement
au niveau spec ne change (refactorisation pure, outillage, docs) - les specs décrivent
le comportement, donc si le comportement ne change pas, aucune spec ne devrait changer non plus.
N'inventez pas une exigence juste pour satisfaire la validation.

Gardez-le concis (1-2 pages). Concentrez-vous sur le « pourquoi » et non sur le « comment » -
les détails d'implémentation appartiennent à design.md.

C'est la fondation - les specs, le design et les tasks s'appuient tous sur ceci.

Specs delta (spec.md) ​

Définit quels comportements changent, avec une spec delta par capacité listée dans la proposition.

Chaque spec delta est le spec.md à l'intérieur du dossier de sa capacité. openspec validate et openspec archive rejettent les sections delta écrites dans tout autre fichier sous specs/, comme specs/user-auth.md, car l'archivage ne les fusionne jamais.

Structure ​

Le modèle que l'agent reçoit comme format de sortie (templates/spec.md) :

md
# Spec Delta

## Purpose
<!-- Nouvelles capacités uniquement : une ou deux phrases (50+ caractères) sur ce que cette capacité sert à faire. Supprimez cette section pour une capacité existante. -->

## ADDED Requirements

### Requirement: <!-- nom de l'exigence -->
<!-- texte de l'exigence -->

#### Scenario: <!-- nom du scénario -->
- **WHEN** <!-- condition -->
- **THEN** <!-- résultat attendu -->

Instructions ​

L'instruction envoyée à l'agent lorsqu'il rédige cet artefact (depuis schema.yaml) :

md
Créer des fichiers de spécification qui définissent CE QUE le système doit faire.

Une spec est un contrat de comportement, pas un plan d'implémentation.

Bon contenu de spec :
- Comportement observable sur lequel les utilisateurs ou les systèmes en aval s'appuient
- Entrées, sorties et conditions d'erreur
- Contraintes externes (sécurité, confidentialité, fiabilité, compatibilité)
- Scénarios qui peuvent être testés ou explicitement validés

Éviter dans les specs :
- Noms de classes/fonctions internes
- Choix de bibliothèques ou frameworks
- Détails d'implémentation étape par étape
- Plans d'exécution détaillés (ils appartiennent à design.md ou tasks.md)

Test rapide : si l'implémentation peut changer sans changer le comportement
visible de l'extérieur, cela n'appartient probablement pas à la spec.

Créez un fichier spec par capacité listée dans la section Capabilities de la proposition.
`<capability-path>` est le répertoire spec par rapport à `specs/` (par exemple,
`user-auth` ou `identity/user-auth`). Conservez le chemin complet :
- Nouvelles capacités : utilisez le chemin exact de la proposition dans `specs/<capability-path>/spec.md`. Tout segment de chemin nouvellement introduit dans la proposition doit être en kebab-case. Suivez l'organisation existante du projet ; n'ajoutez pas un nouveau niveau de domaine lorsque le projet utilise une mise en page plate.
- Capacités modifiées : utilisez le chemin existant exact de `openspec/specs/<capability-path>/` lors de la création du delta dans `specs/<capability-path>/spec.md`. Exécutez `openspec list --specs` pour confirmer ce chemin avant d'écrire le delta, en ajoutant `--store "<id>"` uniquement pour un registre autonome enregistré - un chemin mal orthographié ou inventé cible une capacité inexistante au lieu de celle que vous vouliez. Ne déplacez pas et ne renommez pas la capacité.

Écrivez les fichiers spec un par un, pour que l'utilisateur voie la progression et qu'une
exécution interrompue conserve les fichiers déjà écrits :
- Avant d'écrire quoi que ce soit, comparez les capacités que la proposition liste
  avec les fichiers `specs/<capability-path>/spec.md` qui existent déjà,
  et commencez par la première capacité qui n'a pas de fichier. Ne réécrivez
  pas un fichier existant à moins que l'utilisateur ne vous le demande.
- Avant chaque fichier, indiquez en une ligne quelle capacité vous écrivez.
- Écrivez chaque fichier dès que vous l'avez rédigé. Ne planifiez pas tous les fichiers
  avant d'écrire le premier.
- Arrêtez-vous lorsque chaque capacité que la proposition liste a son fichier.

Il doit y avoir au moins un fichier spec à moins que le `.openspec.yaml` du changement
ne définisse `skip_specs: true` (aucun changement de comportement au niveau spec) - `openspec validate`
rejette un changement sans delta sans ce marqueur. Si la proposition ne liste aucune
capacité et que `skip_specs` n'est pas défini, revoyez d'abord la proposition.

Opérations delta (utiliser des en-têtes ##) :
- **ADDED Requirements** : Nouvelles capacités
- **MODIFIED Requirements** : Comportement modifié - DOIT inclure le contenu mis à jour complet
- **REMOVED Requirements** : Fonctionnalités dépréciées - DOIT inclure **Reason** et **Migration**
- **RENAMED Requirements** : Changements de nom uniquement - utiliser le format FROM:/TO:

Exigences de format :
- Chaque exigence : `### Requirement: <name>` suivi d'une description
- Utiliser SHALL/MUST pour les exigences normatives (éviter should/may)
- Chaque scénario : `#### Scenario: <name>` au format WHEN/THEN
- **CRITIQUE** : Les scénarios DOIVENT utiliser exactement 4 dièses (`####`). L'utilisation de 3 dièses ou de puces échouera silencieusement.
- Chaque exigence DOIT avoir au moins un scénario.
- Chaque scénario DOIT avoir une étape WHEN/GIVEN (son déclencheur) et une étape THEN (son résultat). Un scénario avec uniquement des lignes AND ou de la prose simple compte toujours comme un scénario, mais `openspec validate` le signale comme un avertissement : la validation normale passe toujours, mais `openspec validate --strict` échoue dessus.
- Gardez la description de chaque exigence (le texte entre `### Requirement:` et son premier scénario) à 500 caractères ou moins. `openspec validate` signale les descriptions plus longues dans les exigences ADDED et dans la spec principale. C'est un avertissement : la validation normale passe toujours, mais `openspec validate --strict` échoue dessus. Lors de l'écriture d'une nouvelle exigence, énoncez un comportement par exigence : déplacez les exemples et les cas limites dans des scénarios, et divisez une exigence couvrant plusieurs comportements en blocs `### Requirement:` distincts, chacun avec ses propres scénarios. Sous MODIFIED, gardez le bloc d'exigence existant entier ; ne divisez jamais, ne tronquez pas et ne réécrivez pas le texte existant juste pour respecter la longueur. Ne divisez une exigence longue existante que lorsque l'utilisateur le demande, dans un changement effectué à cette fin : sous MODIFIED, gardez son en-tête et tous ses scénarios et réduisez sa description à un comportement sans changer son sens, puis ajoutez chaque comportement supprimé comme sa propre exigence ADDED avec ses propres scénarios.

Nouvelles capacités uniquement : la première section de la spec delta est `## Purpose` -
une ou deux phrases (50+ caractères, ou `openspec validate --strict`
le signale comme trop bref) décrivant ce que sert la capacité. L'archivage
le copie dans la spec principale qu'il crée ; sans cela, la nouvelle spec principale
se retrouve avec un espace réservé `TBD ... Update Purpose after archive` à remplir
à la main. N'ajoutez PAS `## Purpose` à un delta pour une capacité existante -
cette spec en a déjà un et celui du delta est ignoré. Pour modifier le
Purpose d'une capacité existante - y compris un espace réservé `TBD` restant -
modifiez directement `<planningHome.root>/openspec/specs/<capability-path>/spec.md`.
`planningHome.root` provient de la réponse `openspec instructions ...
--json`. Utilisez-le toujours plutôt qu'un chemin relatif au dépôt : il
se résout vers le registre lorsque le changement y vit - que cela
vienne de `--store`, d'un pointeur `store:` de projet ou d'un registre
par défaut global - et vers le dépôt actuel sinon. N'essayez pas de déterminer
quel cas s'applique ; le champ le sait déjà.

Workflow des exigences MODIFIED :
1. Localisez l'exigence existante dans `<planningHome.root>/openspec/specs/<capability-path>/spec.md` (la même racine tenant compte du registre que ci-dessus)
2. Copiez l'INTÉGRALITÉ du bloc d'exigence (de `### Requirement:` à travers tous les scénarios)
3. Collez sous `## MODIFIED Requirements` et modifiez pour refléter le nouveau comportement
4. Assurez-vous que le texte de l'en-tête correspond exactement (espaces insensibles)

Piège courant : utiliser MODIFIED avec un contenu partiel entraîne une perte de détails au moment de l'archivage.
Si vous ajoutez de nouvelles préoccupations sans changer le comportement existant, utilisez ADDED à la place.

Exemple (une nouvelle capacité, donc sa première section est `## Purpose`) :
```
# Spec Delta

Objectif ​

Permettre aux utilisateurs d'exporter leurs données du produit dans un format portable.

Exigences AJOUTÉES ​

Exigence : L'utilisateur peut exporter ses données ​

Le système DOIT permettre aux utilisateurs d'exporter leurs données au format CSV.

Scénario : Export réussi ​

  • LORSQUE l'utilisateur clique sur le bouton « Exporter »
  • ALORS le système télécharge un fichier CSV contenant toutes les données utilisateur

Exigences SUPPRIMÉES ​

Exigence : Export hérité ​

Raison : Remplacé par le nouveau système d'export Migration : Utiliser le nouveau point de terminaison d'export à /api/v2/export


Les spécifications doivent être testables - chaque scénario est un cas de test potentiel.

design.md ​

Explique comment implémenter le changement. Rédigé uniquement lorsque le changement le nécessite.

Structure ​

Le modèle que l'agent reçoit comme format de sortie (templates/design.md) :

md
# Design

## Contexte

<!-- État actuel et contraintes qui façonnent l'approche. Voir proposal.md pour la motivation - ne pas la répéter -->

## Objectifs / Non-objectifs

**Objectifs :**
<!-- Ce que ce design vise à accomplir -->

**Non-objectifs :**
<!-- Ce qui est explicitement hors périmètre -->

## Décisions

<!-- Décisions de conception clés avec justification et alternatives envisagées -->

## Risques / Compromis

<!-- Risques et compromis connus -->

Instructions ​

L'instruction envoyée à l'agent lorsqu'il rédige cet artefact (depuis schema.yaml) :

md
Créez le document de design qui explique COMMENT implémenter le changement.

Quand inclure design.md (créer uniquement si l'un des cas suivants s'applique) :
- Changement transversal (plusieurs services/modules) ou nouveau modèle d'architecture
- Nouvelle dépendance externe ou changements significatifs du modèle de données
- Complexité en matière de sécurité, performance ou migration
- Ambiguïté qui bénéficie de décisions techniques avant le codage

Sections :
- **Contexte** : Uniquement l'état actuel et les contraintes nécessaires pour expliquer l'approche. Référez-vous à la proposition pour la motivation au lieu de la répéter (ex. « Voir proposal.md - Pourquoi »).
- **Objectifs / Non-objectifs** : Ce que ce design accomplit et exclut explicitement. Ne répétez pas le périmètre de la proposition - ajoutez uniquement des limites au niveau du design.
- **Décisions** : Choix techniques clés avec justification (pourquoi X plutôt que Y ?). Incluez les alternatives envisagées pour chaque décision.
- **Risques / Compromis** : Limitations connues, éléments susceptibles de mal fonctionner. Format : [Risque] → Atténuation
- **Plan de migration** : Étapes de déploiement, stratégie de retour en arrière (si applicable)
- **Questions ouvertes** : Inconnues qui peuvent être reportées sans modifier
  les specs, l'approche ou la répartition des tâches. Omettre si aucune.

Les questions ouvertes concernent des inconnues véritablement reportables, pas des
décisions que vous avez évitées. Si une question modifierait les specs, l'approche
choisie ou la répartition des tâches, résolvez-la maintenant - demandez à
l'utilisateur au lieu de deviner.

Concentrez-vous sur l'architecture et l'approche, pas sur l'implémentation ligne par ligne.
La proposition couvre le pourquoi et le quoi ; le design couvre le comment. Référez-vous à la
proposition pour la motivation et, une fois rédigées, aux specs pour les exigences -
si une section ne ferait que les répéter, pointez vers elles.

Les bons documents de design expliquent le « pourquoi » derrière les décisions techniques.

tasks.md ​

Ventile l'implémentation en tâches vérifiables. apply suit la progression ici.

Structure ​

Le modèle que l'agent reçoit comme format de sortie (templates/tasks.md) :

md
# Tâches

## 1. <!-- Nom du groupe de tâches -->

- [ ] 1.1 <!-- Description de la tâche -->
- [ ] 1.2 <!-- Description de la tâche -->

## 2. <!-- Nom du groupe de tâches -->

- [ ] 2.1 <!-- Description de la tâche -->
- [ ] 2.2 <!-- Description de la tâche -->

Instructions ​

L'instruction envoyée à l'agent lorsqu'il rédige cet artefact (depuis schema.yaml) :

md
Créez la liste de tâches qui ventile le travail d'implémentation.

Avant de rédiger les tâches, consultez design.md pour les questions ouvertes. Si l'une d'elles
modifierait ce qui doit être construit, résolvez-la d'abord avec l'utilisateur - ne
faîtes pas d'hypothèse non vérifiée dans la liste de tâches.

**IMPORTANT : Suivez le modèle ci-dessous pour les tâches suivies.** La phase apply analyse le
format des cases à cocher pour suivre la progression. Une case contenant uniquement `x` compte comme terminée,
majuscule ou minuscule et avec n'importe quel espacement, donc `- [ x]` est également terminé. Tout
autre marqueur, y compris `- [~]`, `- [-]` et un `- []` vide, est considéré comme
non terminé. Une ligne sans case à cocher n'est pas suivie du tout.

Directives :
- Regroupez les tâches suivies liées sous des titres numérotés ##
- Chaque tâche suivie DOIT être une case à cocher : `- [ ] X.Y Description de la tâche`
- Les tâches doivent être suffisamment petites pour être complétées en une session
- Ordonnez les tâches par dépendance (ce qui doit être fait en premier ?)
- Suivez le travail d'implémentation et de vérification qui peut être complété avant
  l'archivage. Si le workflow demandé inclut l'archivage ou un travail qui nécessite
  que ce changement soit archivé, conservez ces étapes sous forme de puces simples dans une
  section `## Suivi du workflow` optionnelle à la fin de tasks.md. Ces
  puces sont des informations de référence en dehors de la progression des tâches suivies.
- Chaque tâche DOIT indiquer comment vérifier son achèvement (un test, une commande,
  un comportement observable ou un artefact livré). Indiquez la vérification dans
  la description de la case à cocher de cette tâche. Utilisez une tâche de vérification distincte
  uniquement lorsqu'elle contrôle une intégration plus large ou un comportement système qui s'étend
  sur plusieurs tâches d'implémentation.
- Chaque groupe de tâches DOIT livrer les tests et la documentation que son propre travail
  exige. Ne collectez PAS les tests ou la documentation dans un groupe final -
  lorsqu'un groupe ultérieur teste pour la première fois le travail d'un groupe antérieur, les échecs
  se propagent en cascade à travers chaque groupe intermédiaire et imposent une reprise. Un groupe
  dont le travail n'exige ni l'un ni l'autre, comme le scaffolding ou la configuration de dépendances,
  n'en porte aucun. Un groupe final sert uniquement aux vérifications d'intégration, pas aux
  tests et documents qu'un groupe antérieur devait fournir.

Exemple :
```
# Tâches

## 1. Configuration

- [ ] 1.1 Créer la nouvelle structure de module et vérifier que les fichiers attendus sont présents
- [ ] 1.2 Ajouter les dépendances à package.json et vérifier que l'installation du paquet réussit

## 2. Implémentation principale

- [ ] 2.1 Implémenter la fonction d'export des données et vérifier que le test d'export passe
- [ ] 2.2 Ajouter les utilitaires de formatage CSV et vérifier que les tests unitaires couvrent les guillemets et les délimiteurs
- [ ] 2.3 Documenter l'API d'export dans docs/export.md et vérifier que la commande documentée s'exécute comme écrite
```

Le cas échéant, ajoutez le suivi du workflow sous forme de puces simples, par exemple :
```
## Suivi du workflow

- Archiver le changement une fois les exigences de revue du projet satisfaites.
- Vérifier le résultat archivé.
```

Référez-vous aux specs pour ce qui doit être construit, au design pour comment le construire.

Apply ​

Le passage de la planification à l'implémentation. Apply est la phase qui traite tasks.md, pas un artefact.

  • Démarre : une fois que tasks.md existe et liste au moins une tâche.
  • Suit : les cases à cocher dans tasks.md. Les cocher constitue le registre de progression.
  • Se termine : lorsque chaque case est cochée. OpenSpec suggère alors d'archiver le changement.

Paramètres ​

Les paramètres d'apply (depuis schema.yaml) :

yaml
apply:
  requires: [tasks]
  tracks: tasks.md
  # instruction: affichée ci-dessous

Instructions ​

L'instruction envoyée à l'agent lorsque l'implémentation démarre (depuis schema.yaml) :

md
Lisez les fichiers de contexte, traitez les tâches en attente, marquez-les comme terminées au fur et à mesure.
Faites une pause si vous rencontrez des blocages ou avez besoin de clarifications.

schema.yaml ​

Le schema.yaml complet, avec les corps d'instruction omis. Chacun est présenté en intégralité dans sa section ci-dessus.

yaml
name: spec-driven
version: 1
description: Default OpenSpec workflow - proposal → specs → design → tasks
artifacts:
  - id: proposal
    generates: proposal.md
    description: Initial proposal document outlining the change
    template: proposal.md
    # instruction: shown in full under proposal.md above
    requires: []

  - id: specs
    generates: "specs/**/*.md"
    description: Detailed specifications for the change
    template: spec.md
    # instruction: shown in full under Delta specs above
    requires:
      - proposal

  - id: design
    generates: design.md
    description: Technical design document with implementation details
    template: design.md
    # instruction: shown in full under design.md above
    requires:
      - proposal

  - id: tasks
    generates: tasks.md
    description: Implementation checklist with trackable tasks
    template: tasks.md
    # instruction: shown in full under tasks.md above
    requires:
      - specs
      - design

apply:
  requires: [tasks]
  tracks: tasks.md
  # instruction: shown in full under Apply above