🎯 OBJECTIF
Comprendre OpenSpec à travers un fil rouge — l'ajout d'une authentification à deux facteurs (2FA) sur les comptes admin :
propose → review → apply → archive (qui fait quoi) ;opsx (profil cœur vs étendu) et à quoi sert chacune ;config.yaml, schéma custom) ;📌 Version
OpenSpec 1.13.2 (23 sept. 2026). Les mentions (1.x) dans la note indiquent la version d'arrivée d'une fonctionnalité.
🧠 MODÈLE MENTAL
Un agent de code est puissant mais non-déterministe : si les exigences ne vivent que dans l'historique de chat, elles se perdent, se déforment, et deviennent impossibles à reviewer. OpenSpec déplace la source de vérité du chat vers un artefact écrit, versionné dans le repo, sur lequel humain et IA s'accordent avant d'écrire la moindre ligne. L'intuition n'est pas "ajouter du process" mais "figer l'intention" : on transforme un prompt flou en une spec relisable, qu'on peut diffuser, critiquer en PR, et qui survit à la fin de la session. C'est le levier « spec versionnée » évoqué dans outiller-developpement-ia-skills-agents-instructions, poussé jusqu'à un workflow complet.
openspec/changes/<change-id>/.proposal.md, le delta de specs/, design.md, tasks.md.ADDED / MODIFIED / REMOVED / RENAMED), par opposition à la spec courante complète.skip_specs — drapeau d'un change qui déclare ne modifier aucune spec (refactor pur, doc). Le change passe validate et archive sans delta (1.7).auth), à laquelle est rattachée une spec.spec-driven est le schéma intégré par défaut.MUST / SHALL / SHOULD / MAY) exprimant la force d'une exigence.Sans spec, l'agent génère du code à partir d'un prompt vague : exigences manquantes, fonctionnalités non demandées, résultat incohérent. Pire pour la review : le relecteur n'a aucun référentiel écrit auquel comparer le code produit. Et au-delà d'un certain remplissage du contexte, l'agent oublie ou altère les détails d'exigence vus plus tôt dans la conversation.
OpenSpec répond par un principe simple : structure avant code. On décrit le changement, on raffine le comportement attendu, on planifie les tâches, puis on implémente contre une spec validée.
🔑 Conclusion clé
OpenSpec ne rend pas l'agent plus intelligent — il rend l'intention auditable et persistante. Le gain vient du référentiel écrit, pas d'une couche magique.
Cas concret : on veut ajouter une 2FA sur les comptes admin. Voilà le déroulé. On lance d'abord la proposition — l'IA scaffolde le change et génère les artefacts :
You: /opsx:propose add-two-factor-auth
AI: Created openspec/changes/add-two-factor-auth/
✓ proposal.md — pourquoi & quoi
✓ specs/ — requirements & scenarios (le delta)
✓ design.md — approche technique
✓ tasks.md — checklist d'implémentation
Prêt pour la review.Depuis la 1.12, propose et ff inspectent le code, les tests et la doc concernés avant de drafter les artefacts. explore fait de même : il vérifie le dépôt avant de te poser une question dont la réponse est déjà dans le code. Ce n'est pas du reverse-engineering de la legacy, mais l'agent ne propose plus à l'aveugle.
Le workflow global tient en quatre temps, et le point qui bloque souvent c'est qui agit à chaque étape :
flowchart LR
P["1 · PROPOSE<br/>TOI : l'intention<br/>IA : drafte les 4 artefacts"]
REV{"2 · REVIEW<br/>TOI : valides & corriges"}
AP["3 · APPLY<br/>IA : implémente tasks.md"]
AR["4 · ARCHIVE<br/>merge delta → specs/<br/>+ historise"]
P --> REV --> AP --> AR
REV -.->|"/opsx:update : révise le plan"| Pmermaidadd-two-factor-auth + 1-2 phrases) ; l'IA génère les 4 artefacts./opsx:update révise le plan en place et réconcilie les artefacts liés, sans déborder sur l'implémentation.tasks.md ; tu supervises. Depuis la 1.9, la consigne d'apply demande à l'agent de signaler le travail hors périmètre plutôt que de le reporter en silence.openspec/specs/ (la vérité courante) et le change part, daté, dans archive/. (Entre apply et archive, /opsx:sync peut propager le delta dans specs/ sans archiver — optionnel, utile pour un change long ou des changes en parallèle.)Réviser un plan sans repartir de zéro
Avant la 1.6.0, un plan devenu faux laissait deux options moches : éditer les .md à la main en resynchronisant mentalement tasks.md avec les specs (dérive garantie), ou repartir sur un nouveau change. /opsx:update couvre ce trou :
You: /opsx:update add-two-factor-auth
Le TOTP seul ne passe pas : les admins terrain n'ont pas de
smartphone pro. Ajouter des codes de secours à usage unique,
et répercuter sur la spec, le design et les tâches.
AI: Updated openspec/changes/add-two-factor-auth/
✓ proposal.md, specs/, design.md, tasks.md réconciliés
Aucune implémentation lancée.Le point important : l'agent ne touche pas au code au passage, même si le changement décrit a des conséquences évidentes côté implémentation. La frontière planification / implémentation reste tenue, et c'est /opsx:apply qui code.
Ce que TU écris vs ce que l'IA génère
| Étape | Toi | L'IA |
|---|---|---|
| Propose | l'intention (1-2 phrases) | lit le code concerné, drafte les 4 artefacts |
| Review | valides / corriges (surtout Out of Scope + delta) |
— |
| Update | dis ce qui change dans le plan | révise et réconcilie les artefacts |
| Apply | supervises | implémente tasks.md |
| Archive | déclenches | merge dans specs/, archive |
Tu n'écris quasi jamais les .md à la main : l'IA les drafte. Ton vrai travail = la review. Le seul artefact durable que tu possèdes vraiment = la spec dans specs/.
⚠️ Ne pas sauter l'archive
Tant que le delta n'est pas fusionné dans openspec/specs/, la vérité courante ment : elle ne reflète plus le code livré. archive (ou sync) n'est pas du ménage — c'est ce qui maintient specs/ aligné avec le réel.
Depuis la 1.6.0, une archive bloquée en mode humain sort en code non-zéro. C'est le bon comportement (une validation en échec n'est plus lue comme un succès), mais tout enchaînement du type openspec archive … && <suite> qui passait « par accident » en CI va maintenant couper.
Le pendant côté CI (1.9) : openspec validate --archived vérifie que chaque change de changes/archive/ a toutes ses cases de tasks.md cochées, et sort non-zéro sinon. Un hook pre-commit ou un job CI avec ce flag attrape le travail archivé inachevé.
Par défaut, OpenSpec active le profil core. /opsx:propose y fait tout d'un coup (scaffold + tous les artefacts). Le profil étendu (à activer via openspec config profile puis openspec update) découpe cette étape pour itérer plus finement — créer un artefact à la fois, tester chaque template indépendamment.
| Commande | Profil | Rôle |
|---|---|---|
/opsx:explore |
cœur | Défricher une idée, investiguer, clarifier le besoin — partenaire de réflexion, sans structure, avant de proposer. Lit le dépôt avant de poser des questions (1.12) |
/opsx:propose |
cœur | Crée le change et génère tous les artefacts de planif d'un coup (chemin rapide) |
/opsx:update |
cœur | (1.6.0) Révise le plan d'un change existant et réconcilie les artefacts liés, sans franchir la frontière de l'implémentation |
/opsx:apply |
cœur | Implémente les tâches, met à jour les artefacts au besoin |
/opsx:sync |
cœur | (optionnel) Propage le delta de specs vers specs/ sans archiver |
/opsx:archive |
cœur | Clôt le change : merge le delta dans specs/ + déplace dans archive/ |
/opsx:new |
étendu | Scaffold du change seul (dossier, sans artefacts) |
/opsx:continue |
étendu | Crée le prochain artefact possible, un à la fois (selon les dépendances) |
/opsx:ff |
étendu | Fast-forward : génère tous les artefacts de planif d'un coup |
/opsx:verify |
étendu | Valide l'implémentation contre les artefacts. Depuis la 1.13.2, ne compte plus un contrôle sauté comme réussi, et ne redemande plus d'implémenter un requirement REMOVED |
/opsx:bulk-archive |
étendu | Archive plusieurs changes terminés d'un coup |
/opsx:onboard |
étendu | Walkthrough guidé d'un change de bout en bout |
Cœur ou étendu ?
/opsx:propose (cœur) = /opsx:new + /opsx:ff en une seule commande. Passe à l'étendu seulement si tu veux construire le change incrémentalement (/opsx:continue artefact par artefact) ou vérifier finement (/opsx:verify). Sinon, le cœur suffit.
La CLI derrière les slash commands
Les slash commands appellent la CLI openspec. Quelques commandes CLI utiles en direct, arrivées après la 1.6 :
| Commande | Version | À quoi ça sert |
|---|---|---|
openspec show <change> --diff |
1.11 | Affiche seulement les lignes qui changent vraiment dans le delta, requirement par requirement. Texte complet pour ADDED, Reason + Migration pour REMOVED, FROM/TO pour RENAMED. --json --diff pour la CI |
openspec status --all |
1.11 | Tous les changes actifs en une commande. Depuis la 1.13.1, status termine par une ligne Next: qui nomme la commande suivante |
openspec validate --archived |
1.9 | Vérifie que les changes archivés ont toutes leurs tâches cochées |
openspec validate --report findings |
1.12 | N'affiche que les erreurs, warnings et infos, en gardant les totaux et le code de sortie |
openspec update |
1.7 | Régénère les skills et vérifie sur npm s'il existe une version plus récente, avec proposition d'upgrade |
Pourquoi --diff compte pour la review : un MODIFIED doit restituer tous les scénarios qu'il conserve, donc le delta brut est surtout du texte identique à la spec courante. --diff isole ce qui change réellement.
Toute la mécanique tient dans une séparation état courant / diff en cours :
openspec/specs/ — la spec vivante, source de vérité de ce que le système fait aujourd'hui. Organisée par domaine (auth/, payments/…).openspec/changes/<change-id>/ — un dossier par changement, qui regroupe proposal, delta de specs, design et tasks. Ce regroupement par feature rend le suivi lisible.openspec/changes/archive/ — l'historique daté des changements appliqués.flowchart LR
subgraph C["openspec/changes/add-two-factor-auth/"]
P["proposal.md"]
S["specs/ — delta"]
D["design.md"]
T["tasks.md"]
end
SP["openspec/specs/auth/ — verite courante"]
AR["openspec/changes/archive/ — historique date"]
C -->|"apply : implémente le delta"| SP
C -->|"sync / archive : fusionne le delta"| SP
C -->|"archive : déplacement daté"| ARmermaidPourquoi ce découpage gagne en brownfield
Séparer état et diff permet de toucher une feature existante sans réécrire toute sa spec : on ne décrit que le delta. C'est l'inverse d'un outil greenfield qui suppose que tout part de zéro. Bonus : deux changes peuvent modifier des requirements différents du même domaine sans conflit.
Un change sans delta : skip_specs
Un refactor pur ou un travail de doc ne change aucun comportement, donc aucune spec. Depuis la 1.7, le change peut le déclarer avec skip_specs: true et passer validate puis archive sans delta.
Sans ce drapeau, un change sans specs/ est rejeté par validate. Depuis la 1.13, openspec instructions apply le signale aussi en warning, et nomme les deux sorties : écrire les specs, ou déclarer skip_specs: true. Avant, un tasks.md écrit avant les specs pouvait faire passer le change pour prêt à implémenter.
Ces quatre fichiers sont produits par l'IA sur /opsx:propose. Ton rôle n'est pas de les écrire mais de les relire. Voici à quoi chacun ressemble pour notre change add-two-factor-auth, et le point d'attention en review (annotations ←).
proposal.md — le pourquoi / quoi / impact.
# Proposal: Add Two-Factor Authentication
## Why
Les comptes admin sont la cible n°1 de credential stuffing.
## What Changes
- Challenge OTP (TOTP) après validation du mot de passe.
## Out of Scope ← EN REVIEW : vérifie que l'IA n'élargit pas le périmètre
- SMS comme second facteur (TOTP uniquement).
## Impact
- Specs : `auth`. Breaking : `POST /login` → `202 otp_required`.
En review : le
Out of Scopeet l'Impact(breaking changes) sont les deux blocs où l'IA dérape le plus. C'est là que tu cadres.
specs/auth/spec.md — le delta (le cœur). Une spec est un contrat de comportement : requirements + scenarios en Given/When/Then, mots-clés RFC 2119. Pas de noms de classes ni de librairie (ça, c'est design.md). On décrit le diff via quatre opérations :
# Delta for Auth
## ADDED Requirements ← nouvelle exigence
### Requirement: Two-Factor Authentication
The system SHALL require a second factor (TOTP) for admin login.
#### Scenario: OTP required ← ≥1 scénario, sinon validation KO
- GIVEN a user with 2FA enabled
- WHEN the user submits valid credentials
- THEN an OTP challenge is presented
## MODIFIED Requirements ← requirement RÉÉCRIT en entier
### Requirement: Session Timeout
The system SHALL expire sessions after 15 minutes of inactivity.
#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 15 minutes pass without activity
- THEN the session is invalidated
## REMOVED Requirements ← + Reason / Migration
### Requirement: Remember Me
**Reason**: Deprecated in favor of 2FA.
**Migration**: Tokens révoqués ; ré-auth à chaque session.
## RENAMED Requirements ← FROM / TO, le contenu ne bouge pas
- FROM: `### Requirement: Password Login`
- TO: `### Requirement: Primary Factor Login`
À l'archive : ADDED s'ajoute, MODIFIED remplace, REMOVED supprime, RENAMED renomme sur place. Depuis la 1.11, un requirement renommé garde sa position dans la spec au lieu d'être déplacé à la fin, ce qui garde le diff d'archive petit.
Pour relire le delta sans te noyer dans le texte répété des MODIFIED, openspec show <change> --diff (1.11) n'affiche que les lignes qui changent.
⚠️ En review, les pièges de format à traquer
openspec validate échoue.### Requirement: / #### Scenario: exactement (format codé en dur dans le parser).validate, en nommant les scénarios à recopier. Avant, l'archive les supprimait en silence. Depuis la 1.13.2, le message dit aussi ce que le bloc ajoute.validate. Warning par défaut, échec sous --strict.design.md — l'approche technique (optionnel, changements non triviaux). C'est ici que vivent les décisions d'archi et les alternatives écartées — pas dans la spec.
# Design: Two-Factor Authentication
## Décision : TOTP vs SMS
TOTP (RFC 6238). SMS écarté : coût, SIM-swap, dépendance opérateur.
## Alternatives écartées
WebAuthn/passkeys : meilleure sécu, mais hors scope de cette itération.
En review : les décisions tiennent-elles ? Les alternatives sont-elles justifiées ? C'est souvent ici qu'on découvre « cette approche ne marchera pas » — avant de coder. Quand le verdict tombe ici, c'est le cas d'usage type de
/opsx:update: on corrige le plan, on ne repart pas de zéro.
tasks.md — la checklist exécutable. Découpée en phases, cochée au fil de l'eau par l'IA pendant apply. Depuis la 1.10, chaque tâche générée doit dire comment on saura qu'elle est finie : un test, une commande, un résultat observable ou un artefact livré. Et depuis la 1.13.2, chaque groupe de tâches embarque ses propres tests et mises à jour de doc, au lieu de tout reporter dans un groupe final.
# Tasks: Add Two-Factor Authentication
## Phase 1 — MVP
- [ ] 1.1 Migration : table `user_2fa_secrets`
Done : migration appliquée, `\d user_2fa_secrets` montre les colonnes
- [ ] 1.2 Service `TotpService` (RFC 6238)
Done : `TotpServiceTest` vert (génération + vérification + fenêtre de dérive)
- [ ] 1.3 `POST /login` → `202 otp_required` si 2FA active
Done : test d'intégration du endpoint vert, doc OpenAPI mise à jour
## Phase 2 — Durcissement
- [ ] 2.1 Rate-limit après 5 échecs OTP
Done : test vert sur le 6e échec → 429
- [ ] 2.2 Lint + build + suite complète au vert ← vérif = une tâche à part entière
Conventions de nommage
user-auth, payment-capture), un seul objectif ; si la description a besoin d'un « AND », splitter.add-, update-, remove-, refactor-), unique (-2, -3 si pris). Un préfixe numérique (0001-add-auth) est accepté depuis la 1.7.file.ts:42 ; une spec se cite specs/auth/spec.md.Point clé : le schéma spec-driven est intégré à OpenSpec. Tu ne l'écris jamais. La config ne sert qu'à le customiser, et elle est facultative. Trois niveaux.
openspec init # et c'est toutbashTu es sur le schéma spec-driven, qui génère proposal → specs → design → tasks avec les conventions vues plus haut. Aucune config nécessaire. Pour le contexte projet (stack, archi), tu remplis simplement project.md.
config.yaml (optionnel) : contexte + règlesPour imposer du contexte ou des règles maison à chaque change :
# openspec/config.yaml — UNIQUEMENT si tu veux customiser
schema: spec-driven # schéma par défaut → évite de passer --schema
context: | # injecté dans TOUS les artefacts (limite 50 KB)
Stack : TypeScript, React, Node, Postgres.
Rétro-compat obligatoire sur les API publiques.
rules: # règles PAR artefact (clé = id d'artefact)
proposal: # → injectées en générant le proposal seulement
- Inclure un plan de rollback
specs: # → injectées en générant les specs seulement
- Au moins un scénario d'erreur en plus du happy-pathyamlInjection : context et rules sont insérés dans le prompt sous forme de blocs <context> / <rules> (puis le <template> du schéma). Le contexte va partout ; une règle seulement sur l'artefact qu'elle cible. Ordre de résolution du schéma : --schema CLI → .openspec.yaml du change → config.yaml → défaut spec-driven.
Depuis la 1.13.1, une valeur de config.yaml ne peut plus injecter de directives dans les instructions agent. Le contexte est traité comme de la donnée, pas comme une consigne. Utile quand on clone un dépôt qu'on n'a pas encore relu.
Un schéma, c'est la recette d'un change : la liste des artefacts qu'il doit contenir, leur ordre de dépendance, et les instructions que l'IA suit pour générer chacun. Le défaut spec-driven impose toujours proposal → specs → design → tasks.
La différence avec le Mode 2 est là :
config.yaml) — tu gardes la recette par défaut et tu la décores (contexte + règles). La liste des fichiers ne change pas.Trois cas typiques : workflow plus léger (sauter specs/design), plus lourd (ajouter un research avant le proposal), ou changer les prompts (ex. imposer un diagramme de séquence dans chaque design.md — effet immédiat, plus besoin d'attendre une release).
On ne part jamais de zéro : on forke le défaut, puis on édite. Exemple — un workflow rapid réduit à proposal + tasks :
openspec schema fork spec-driven rapid # copie spec-driven dans openspec/schemas/rapid/bash# openspec/schemas/rapid/schema.yaml — édité : on a retiré specs et design
name: rapid
version: 1
description: Workflow léger — pas de specs ni de design
artifacts:
- id: proposal
generates: proposal.md
template: proposal.md
requires: [] # rien requis → créable en premier
- id: tasks
generates: tasks.md
template: tasks.md
requires: [proposal] # tasks juste après proposal (plus de specs/design entre)
apply:
requires: [tasks] # on n'implémente qu'une fois tasks créé
tracks: tasks.md # apply coche cette checklistyamlopenspec schema validate rapid # vérifie syntaxe, templates, pas de cycle
openspec new change quick-fix --schema rapid # ou `schema: rapid` dans config.yaml pour en faire le défautbashChamps du schema.yaml, relus sur cet exemple : id (nom de l'artefact, = clé des rules), generates (fichier produit, globs OK), template (squelette dans templates/ que l'IA remplit), instruction (consigne IA), requires (artefacts prérequis), apply.requires / apply.tracks (ce qui doit exister avant d'implémenter + la checklist suivie). Les templates/*.md sont des squelettes avec des commentaires HTML qui guident l'IA.
Deux ajouts depuis : openspec schema fork conserve les commentaires, le style des blocs et l'ordre des clés du YAML (1.9). Et openspec schema init --default écrit bien la clé schema que le loader lit, donc un nouveau schéma prend effet tout de suite (1.11).
Dépendances = enablers, pas des gates
requires: [proposal] veut dire « proposal doit exister avant de pouvoir créer design » — c'est un prérequis d'ordre, pas une obligation d'enchaîner. Rien ne te force à créer design : les dépendances montrent ce qui devient possible, pas ce que tu dois faire ensuite. C'est tout l'esprit OPSX : des actions, pas des phases.
⚠️ Le Mode 3 est rarement nécessaire
La plupart des équipes ne touchent jamais au schéma custom : le défaut (Mode 1) couvre l'essentiel, config.yaml (Mode 2) la quasi-totalité du reste. Le Mode 3 sert seulement quand la forme même du workflow par défaut ne convient pas. Et attention : le fichier de config doit s'appeler config.yaml (pas config.yml), sinon il est ignoré sans erreur ; le YAML natif n'est pas templaté ({{…}}) ; un id d'artefact inconnu dans rules ne lève qu'un warning.
Prérequis : Node.js ≥ 20.19.0. Package npm @fission-ai/openspec (MIT, open-source).
npm install -g @fission-ai/openspec@latest # aussi : pnpm, yarn, bun, nix
cd your-project
openspec init # openspec/ + config interactive + skills
openspec init --language fr # (1.10) artefacts générés en français, en-têtes et SHALL/MUST restent en anglais
openspec update # régénère instructions agent + slash commands, vérifie npm (1.7)bashopenspec init génère aussi des skills dans .claude/skills/ (ou équivalent) que les agents auto-détectent. Selon l'outil : Claude Code / Cursor → slash commands /opsx:* ; GitHub Copilot CLI → prompts sous .github/prompts/ ; Windsurf → workflows sous .windsurf/ ; le reste → AGENTS.md générique. Plus de 30 outils supportés (compte 1.7+). Depuis la 1.6.0, les skills et commandes générés peuvent pré-approuver la CLI OpenSpec : plus de confirmation à chaque appel, les autres outils restant sous contrôle normal.
Sur --language (1.10) : la langue ne s'applique qu'au contenu généré. Les en-têtes ### Requirement: / #### Scenario: et les mots-clés RFC 2119 restent en anglais, sinon la validation casse.
Durcissement 1.13.1 : cloner un repo inconnu
Trois protections pour un dépôt qu'on vient de cloner et qu'on n'a pas relu : une valeur de config.yaml ne peut plus injecter de directives dans les instructions agent, des fichiers forgés ne peuvent plus bloquer openspec update ou openspec archive, et le .npmrc du repo ne peut plus rediriger le check de mise à jour.
⚠️ Qualité bornée par le modèle ET l'hygiène de contexte
OpenSpec recommande des modèles à fort raisonnement (Codex 5.5, Opus 4.7) et un contexte propre : vider le contexte avant apply. Sur un petit modèle ou un contexte pollué, le bénéfice se dégrade — l'outil discipline le workflow, il ne compense pas un mauvais raisonnement. Télémétrie anonyme par défaut (noms de commandes + version, pas de PII), désactivable via OPENSPEC_TELEMETRY=0 ou DO_NOT_TRACK=1.
| Critère | OpenSpec | Spec Kit (GitHub) | Kiro (AWS) |
|---|---|---|---|
| Poids du process | Léger, itératif, actions ré-éditables | Lourd, phase gates rigides | Structuré, intégré à l'IDE |
| Setup | npm/node, openspec init |
Setup Python | IDE dédié |
| Brownfield (1→n) | Conçu pour | Plus orienté greenfield | Variable |
| Greenfield (0→1) | Fonctionne, pas son différenciateur | Point fort | Oui |
| Lock-in | Aucun — 30+ outils | Aucun mais cérémonie | IDE AWS + modèles Claude only |
| Modèle de specs | Deux dossiers (état / delta) | Multi-fichiers Markdown | Specs éparpillées |
Quand choisir OpenSpec
⚡ TL;DR — chaque concept en une ligne
Spec-driven development (SDD) ✓ La spec écrite et versionnée devient la source de vérité, validée avant tout code. ⚠ Ne remplace pas la réflexion : une spec vague produit du code vague.
Workflow propose → review → apply → archive
✓ propose lit le code concerné puis drafte les artefacts (TOI : l'intention), tu valides en review, apply implémente, archive merge le delta dans specs/ + historise.
⚠ Ton vrai travail = la review ; sauter l'archive fait diverger specs/ du code réel.
Commandes opsx
✓ Cœur : explore / propose / update / apply / sync / archive. Étendu : new / continue / ff / verify / bulk-archive / onboard.
⚠ propose = new + ff ; update révise le plan sans écrire une ligne de code ; l'étendu ne sert que pour itérer artefact par artefact.
Format des specs (delta)
✓ Requirements + scenarios (Given/When/Then), RFC 2119, opérations ADDED / MODIFIED / REMOVED / RENAMED ; openspec show --diff pour relire seulement ce qui change.
⚠ MODIFIED = requirement réécrit en entier ; un scénario perdu ou un requirement sans scénario casse la validation.
Change sans spec
✓ skip_specs: true laisse passer un refactor ou de la doc sans delta.
⚠ Sans ce drapeau, un change sans specs/ est rejeté ; apply te le dit désormais en warning.
Customisation (3 niveaux)
✓ spec-driven intégré (init suffit) ; config.yaml décore (context/rules) ; schema.yaml change la recette (les artefacts eux-mêmes).
⚠ Le Mode 3 est rarement utile ; config.yaml (pas .yml) et le YAML natif n'est pas templaté.
🎓 À retenir
propose ; ton vrai travail est la review, et le seul artefact durable que tu possèdes = la spec dans specs/./opsx:update (1.6.0) réconcilie les artefacts d'un change existant sans franchir la frontière de l'implémentation ; c'est ce qui manquait pour qu'une hypothèse invalidée tardivement ne coûte pas un nouveau change.propose et explore lisent quand même le code concerné avant de drafter : l'agent propose moins à l'aveugle, mais il ne reconstruit pas la spec de l'existant à ta place.archive réécrit specs/ — ADDED s'ajoute, MODIFIED remplace, REMOVED supprime, RENAMED renomme sur place, puis historise ; sync fait le merge sans archiver, en option.show --diff existe : le delta brut est illisible sur un gros MODIFIED.validate ou remontent en warning dans apply.config.yaml décore la recette par défaut, un schéma custom change la recette ; la plupart des équipes restent en Mode 1/2./opsx:update, support Oh My Pi et TRAE, pré-approbation CLI, exit code de l'archive bloquée.skip_specs: true, openspec update qui vérifie npm, 30+ outils, change-id à préfixe numérique.validate détecte la perte de scénario dans un MODIFIED, archive plus parlante sans terminal.validate --archived, résolution de racine stricte, schema fork qui conserve le YAML, consigne d'apply sur le hors-périmètre.init --language, critère de done obligatoire dans les tâches.show --diff, status --all, Purpose placeholder, ordre conservé sur RENAMED, schema init --default.validate --report findings.Next: dans status./opsx:verify fiabilisé, tests et doc par groupe de tâches, messages de perte de scénario.config.yaml, injection, schema.yaml + templates, schema fork/init/validate.