Stores : Planifier dans son propre dépôt
Bêta. Les stores, références, contexte de travail et worksets sont nouveaux. Les noms de commandes, les drapeaux, les formats de fichiers et la sortie JSON peuvent encore changer de forme entre les versions. Chaque démonstration ci-dessous a été exécutée sur la version actuelle, mais relisez ce guide après une mise à jour.
Le problème que cela résout
OpenSpec vit normalement à l'intérieur d'un dépôt de code : un dossier openspec/ à côté de votre code, contenant les spécifications et les modifications pour ce dépôt.
Cela ne convient plus dès que votre planification dépasse un seul dépôt :
- Votre travail s'étend sur plusieurs dépôts — une fonctionnalité touche le serveur API, l'application web et une bibliothèque partagée. Dans quel dossier
openspec/le plan doit-il vivre ? - Votre équipe planifie avant que le code n'existe, ou planifie des choses qui ne deviendront jamais du code dans ce dépôt.
- Les exigences sont possédées par une équipe et consommées par d'autres. La version wiki dérive, et votre agent de codage ne peut de toute façon pas la lire.
Un store est la réponse : un dépôt autonome dont l'unique rôle est la planification. Il possède la même structure openspec/ que vous connaissez déjà — spécifications et modifications — plus un petit fichier d'identité. Vous l'enregistrez sur votre machine une fois, par son nom, et ensuite chaque commande OpenSpec normale peut y travailler depuis n'importe où.
La structure
team-plans (un magasin : planification dans son propre dépôt)
├── .openspec-store/store.yaml identité : "I am team-plans"
└── openspec/
├── specs/ ce qui est vrai
└── changes/ ce qui est en cours
▲
│ enregistré sur chaque machine par nom ;
│ partagé par poussée/clonage comme n'importe quel dépôt
┌─────────────┼─────────────┐
│ │ │
web-app api-server mobile-app
(dépôt de code) (dépôt de code) (dépôt de code)Deux règles maintiennent cette simplicité :
- Un magasin n'est qu'un dépôt git. Vous le commitez, le poussez, le tirez et le révisez vous-même. OpenSpec ne clone, ne synchronise ni ne pousse jamais quoi que ce soit de lui-même.
- Des déclarations, pas de la machinerie. Les dépôts peuvent déclarer comment ils se rapportent aux magasins (voir ci-dessous). Les déclarations changent ce qu'OpenSpec peut vous dire — jamais l'endroit où vos commandes agissent.
Cinq minutes pour votre premier magasin
Deux commandes vous mènent de rien à un changement fonctionnel, limité à un magasin :
openspec store setup team-plans --path ~/openspec/team-plansStore ready: team-plans
Location: /Users/you/openspec/team-plans
OpenSpec root: ready
Registry: registered
Next: run normal OpenSpec commands against this store, for example:
openspec new change <change-id> --store team-plans
Share this store by committing and pushing it like any Git repo.openspec new change add-login --store team-plansUsing OpenSpec root: team-plans (/Users/you/openspec/team-plans)
Created change 'add-login' at /Users/you/openspec/team-plans/openspec/changes/add-login/
Schema: spec-driven
Next: openspec status --change add-login --store team-plansVoilà tout le modèle. À partir d'ici, le cycle de vie est exactement ce que vous connaissez — status, instructions, validate, archive — avec --store team-plans sur chaque commande, et chaque indice affiché porte le drapeau pour vous. La ligne Using OpenSpec root: vous indique toujours où une commande agit.
Histoire : une équipe, un dépôt de planification
Une équipe conserve ses spécifications et ses changements dans team-plans plutôt que de les disperser à travers les dépôts de code.
Jour un (celui qui le configure) :
openspec store setup team-plans --path ~/openspec/team-plans \
--remote git@github.com:acme/team-plans.git
git -C ~/openspec/team-plans push -u origin mainPasser --remote enregistre l'URL de clonage dans le fichier d'identité du magasin lui-même (.openspec-store/store.yaml), dans le commit initial. Chaque clonage futur naît en sachant d'où il vient, de sorte que les vérifications de santé et les messages d'erreur peuvent afficher un correctif complet et collable pour les coéquipiers qui ne l'ont pas encore.
Chaque coéquipier (une fois par machine) :
git clone git@github.com:acme/team-plans.git ~/openspec/team-plans
openspec store register ~/openspec/team-plansÀ partir de là, tout le monde travaille dans le même dépôt de planification par nom :
openspec status --store team-plans --change add-login
openspec show add-login --store team-plansLe partage du travail est du git, volontairement. Un changement que vous créez n'existe que dans votre checkout jusqu'à ce que vous le commitez et le poussiez — comme pour le code. Les plans obtiennent gratuitement des branches, des demandes de tirage et des révisions, car un magasin est un dépôt ordinaire.
Connecter les dépôts de code de l'équipe. Un dépôt de code dont la planification est entièrement externalisée a besoin d'une seule ligne, dans openspec/config.yaml :
# web-app/openspec/config.yaml
store: team-plansMaintenant, chaque commande OpenSpec exécutée dans web-app agit sur team-plans sans aucun drapeau :
cd ~/src/web-app
openspec status --change add-loginUsing OpenSpec root: team-plans (/Users/you/openspec/team-plans)
...Le pointeur est un repli, jamais une surcharge : un --store explicite gagne toujours, et si le dépôt développe ses propres dossiers de planification, ceux-ci gagnent (avec un avertissement pour retirer le pointeur obsolète).
Un défaut pour tous les dépôts de votre machine. Si vous travaillez sur plusieurs dépôts de code qui planifient tous dans le même magasin, définissez-le une fois, globalement, plutôt que d'ajouter la ligne store: à chaque dépôt :
openspec config set defaultStore team-plansMaintenant, toute commande exécutée en dehors d'une racine de planification — et sans --store ni pointeur de projet — se résout vers team-plans. Elle se situe au bas de la liste de priorité, de sorte que --store, une racine locale et un pointeur store: de projet gagnent toujours. La bannière de racine et le bloc JSON root rapportent source: "global_default" avec l'identifiant du magasin, de sorte que vous pouvez toujours distinguer un défaut machine d'un pointeur propre à un dépôt. Effacez-le avec openspec config unset defaultStore. Si l'identifiant n'est pas enregistré, les commandes signalent une erreur et vous indiquent de l'enregistrer ou d'effacer le défaut obsolète.
Exemple : une fonctionnalité, deux dépôts de composants
Supposons que add-checkout-promo modifie à la fois checkout-api et checkout-web. L'équipe veut un contrat produit partagé, tandis que chaque dépôt de code a encore besoin de ses propres tâches d'implémentation, de sa branche et de sa révision.
Utilisez deux couches :
- Conservez le comportement partagé dans
team-plans. - Conservez les plans d'implémentation dans chaque dépôt de composant et référencez le magasin comme contexte en amont en lecture seule.
D'abord, planifiez le contrat partagé dans le magasin :
openspec new change add-checkout-promo --store team-plans
openspec status --change add-checkout-promo --store team-plansLa proposition et les spécifications doivent décrire le comportement à la frontière entre les composants — par exemple, les champs de promotion renvoyés par le service et la façon dont le frontend gère un checkout non éligible. Révisez ce changement dans le dépôt du magasin comme n'importe quelle autre branche et demande de tirage.
Quel contexte la planification voit-elle ?
Sélectionner un magasin change la racine OpenSpec ; cela ne découvre ni ne lit tous les dépôts de code qui utilisent ce magasin. Les instructions du magasin voient les artefacts et le contexte configuré dans le magasin. Elles voient le code des composants uniquement lorsque ces dossiers sont également disponibles pour l'agent ou l'éditeur et que l'agent les lit.
Un workset est un moyen pratique d'ouvrir le magasin de planification et les deux dépôts de code ensemble :
openspec workset create checkout-promo \
--member ~/openspec/team-plans \
--member ~/src/checkout-api \
--member ~/src/checkout-web \
--tool code
openspec workset open checkout-promoCela rend les dossiers visibles dans un espace de travail IDE unique. Cela ne copie pas le contexte source dans le magasin, ne sélectionne pas les dépôts affectés et ne donne pas à un agent la permission de les modifier. Placez les faits durables inter-composants dans les spécifications partagées ; ne vous fiez pas à un planificateur qui se souvient du code source qu'il a eu la chance d'inspecter.
Comment l'implémentation commence-t-elle dans chaque dépôt ?
Lorsqu'aucun --store explicite ni racine openspec/ plus proche ne s'applique, un pointeur store: team-plans redirige les commandes vers ce magasin. Il ne divise pas une liste de tâches d'un magasin par le dossier depuis lequel apply a été invoqué. OpenSpec ne redirige actuellement pas les tâches vers les dépôts.
Lorsque chaque composant a besoin d'un cycle apply/révision indépendamment limité, donnez-lui une racine OpenSpec locale et référencez le magasin central plutôt que de pointer vers lui :
# checkout-api/openspec/config.yaml (et de même dans checkout-web)
schema: spec-driven
references:
- team-plansAprès que le contrat partagé est approuvé et disponible dans les spécifications principales du magasin, créez un petit changement local pour la partie du composant :
cd ~/src/checkout-api
openspec new change implement-checkout-promo-api
cd ~/src/checkout-web
openspec new change implement-checkout-promo-uiL'index de références dans les instructions de chaque dépôt fournit le résumé de la spécification du magasin et la commande de récupération exacte (openspec show ... --store team-plans). Chaque proposition locale cite ce contrat partagé, et ses tâches décrivent uniquement le travail dans ce composant. Puis exécutez /opsx:apply dans chaque dépôt séparément ; la résolution de la racine maintient les artefacts et les modifications d'implémentation limités à ce dépôt. Les modifications du service et du frontend peuvent maintenant être testées, révisées, fusionnées et archivées indépendamment.
Si l'implémentation doit commencer pendant que le changement du magasin partagé est encore actif, récupérez-le explicitement avec openspec show add-checkout-promo --store team-plans ; les index de références listent les spécifications canoniques du magasin, pas les changements actifs du magasin. Maintenez la branche du magasin et les branches des composants liées dans les descriptions de leurs demandes de tirage afin que les réviseurs puissent voir quelle version du contrat chaque implémentation suit.
Histoire : des exigences qui traversent les lignes d'équipe
Une équipe plateforme possède les exigences. Les équipes produit construisent sur leur base, dans leurs propres dépôts, avec leurs propres conceptions. Une référence décrit cette relation sans déplacer le travail de personne.
platform-reqs (magasin) api-server (dépôt de code)
possédé par l'équipe plateforme possédé par une équipe produit
┌──────────────────────────┐ ┌──────────────────────────┐
│ openspec/specs/ │ ◀────────│ openspec/config.yaml │
│ payments/spec.md │ lit │ references: │
│ auth/spec.md │ │ - platform-reqs │
│ │ │ openspec/specs/ │
│ openspec/changes/ │ │ (leurs propres │
│ travail plateforme │ │ conceptions) │
│ │ │ openspec/changes/ │
│ │ │ (leur propre travail) │
│ │ └──────────────────────────┘
└──────────────────────────┘L'équipe produit déclare ce sur quoi elle s'appuie dans le openspec/config.yaml de son dépôt :
references:
- platform-reqsLes références sont un contexte en lecture seule. Le dépôt conserve sa propre racine openspec/ ; le travail reste là. Ce qui change : openspec instructions dans ce dépôt inclut maintenant un index des spécifications du magasin référencé — chacune avec un résumé d'une ligne et la commande de récupération exacte (openspec show <spec-id> --type spec --store platform-reqs). Un agent travaillant dans api-server peut trouver les exigences de paiement en amont, les citer et écrire sa conception de bas niveau dans la racine propre au dépôt — sans que personne ne colle de contexte autour.
Une référence peut porter sa source de clonage, de sorte que les coéquipiers qui n'ont pas encore le magasin obtiennent un correctif complet plutôt qu'une impasse :
references:
- { id: platform-reqs, remote: "git@github.com:acme/platform-reqs.git" }Quand vous voulez ouvrir le plan et le code ensemble, créez un workset. C'est personnel et explicite : chaque personne choisit les dossiers avec lesquels elle travaille réellement sur sa machine. Rien sur ces chemins de checkout locaux n'est commité dans le dépôt de planification partagé.
openspec workset create platform \
--member ~/openspec/platform-reqs \
--member ~/src/api-server \
--member ~/src/web-appDeux questions que vous pouvez toujours poser
« Mon installation est-elle saine ? » — openspec doctor vérifie la racine actuelle et ses magasins référencés, en lecture seule, avec un correctif collable par constat :
Doctor
Root
Location: /Users/you/src/api-server
OpenSpec root: ok
References
- platform-reqs: ok (/Users/you/openspec/platform-reqs)
- design-system: Referenced store 'design-system' is not registered on this machine.
Fix: git clone -- git@github.com:acme/design-system.git '/Users/you/openspec/design-system' && openspec store register '/Users/you/openspec/design-system' --id design-system« Avec quoi travaille-je ? » — openspec context assemble le jeu de travail à partir des déclarations OpenSpec : la racine et les magasins qu'elle référence.
Working context for api-server (/Users/you/src/api-server)
OpenSpec root
api-server /Users/you/src/api-server
Referenced stores
platform-reqs /Users/you/openspec/platform-reqs
Fetch: openspec show <spec-id> --type spec --store platform-reqsLes deux prennent en charge --json pour les agents. openspec context --code-workspace <path> écrit en outre un fichier d'espace de travail VS Code contenant l'ensemble complet — la seule écriture que cette commande effectue.
Worksets : rouvrez les dossiers sur lesquels vous travaillez ensemble
En plus de tout ce qui précède : la plupart des gens ouvrent les mêmes quelques dossiers ensemble à chaque session — le dépôt de planification plus deux ou trois dépôts de code. Un workset est une vue personnelle et nommée de cela, rouverte avec une commande dans l'outil de votre choix.
workset "platform" openspec workset open platform
├── team-plans ~/openspec/team-plans │
├── api-server ~/src/api-server ▼
└── web-app ~/src/web-app all three open in your toolopenspec workset create platform \
--member ~/openspec/team-plans --member ~/src/api-server \
--tool code
openspec workset listplatform (opens in VS Code)
team-plans /Users/you/openspec/team-plans
api-server /Users/you/src/api-serveropenspec workset open platform lance ensuite l'outil enregistré : les éditeurs (VS Code, Cursor) ouvrent une fenêtre avec chaque membre et reviennent. Le premier membre est le principal. Vous pouvez remplacer l'outil à tout moment avec --tool <id>.
Les worksets ne sont délibérément pas un état partagé. Ils vivent sur votre machine, ne sont jamais commités et ne font aucune prétention sur le travail — ils enregistrent simplement ce que vous aimez ouvrir ensemble. En supprimer un ne touche jamais aux dossiers membres. Les nouveaux outils sont de la configuration, pas du code : tout ce qui est lancé via un fichier d'espace de travail ou des indicateurs d'attachement par dossier peut être ajouté sous la clé openers dans la configuration globale (openspec config edit).
Comment les commandes décident où agir
Chaque commande normale résout sa racine de la même manière, dans cet ordre :
1. --store <id> you said so explicitly → that store
2. nearest openspec/ a real planning root here → this repo
(walking up from cwd)
3. store: pointer config.yaml declares a store → that store
4. defaultStore global config sets a machine → that store
default
5. none of the above stores registered on this → error with a
machine? selection hint
no stores registered? → the current
directory
(classic behavior)La ligne Using OpenSpec root: (et le bloc root dans la sortie --json) vous indique dans quel cas vous êtes.
Limitations connues
- Forme bêta. Tout sur cette page peut changer entre les versions — noms, indicateurs, formats de fichiers, clés JSON.
- Une copie de travail par identifiant de store et par machine. L'enregistrement d'une deuxième copie de travail sous le même identifiant échoue avec une suggestion de faire
store unregisterd'abord. - Aucune synchronisation, jamais — par conception. OpenSpec ne clone, ne tire (pull) ni ne pousse (push) jamais. Une copie de travail obsolète affiche des spécifications obsolètes jusqu'à ce que vous tiriez ; les références sont indexées en direct à partir de ce qui se trouve sur le disque.
- Les dossiers de planification vides peuvent être absents. Un nouveau store peut ne pas encore avoir
openspec/changes/,openspec/specs/ouopenspec/changes/archive/dans Git. Cela est accepté pendant la bêta ; ces dossiers apparaissent une fois que les commandes normales créent des fichiers pour eux. - Les dépôts pointeurs restent des pointeurs. Un dépôt de configuration seule dont
openspec/config.yamldéclarestore: <id>est traité comme une planification externalisée, pas comme une copie de travail de store à enregistrer. Retirez d'abord la lignestore:si vous voulez intentionnellement convertir ce dépôt en racine de store local. - Certaines commandes restent là où elles sont.
templateset les formes nominales dépréciées (openspec change show, ...) agissent uniquement sur le répertoire actuel — sans--store.schemassuit la précédence canonique de sélection de racine et accepte--store <id>tout en conservant sa forme de tableau JSON réussie inchangée. - L'état par machine est par machine. Le registre de stores et les worksets sont des paramètres locaux. Rien concernant la disposition de votre machine n'est jamais committé à la planification partagée.
- Deux styles de lancement pour les worksets. Un outil qui ne peut pas être lancé avec un fichier d'espace de travail ou des indicateurs d'attachement par dossier ne peut pas être ajouté comme ouvreur.
- Le JSON d'agent a une scission de casse connue (les clés de la famille des stores sont en snake_case, celles de la famille des workflows en camelCase). Documenté dans le contrat d'agent ; son unification est reportée à une version avec version.
Où vivent les choses
| Quoi | Où | Partagé ? |
|---|---|---|
| La planification d'un store | <store>/openspec/ (spécifications, modifications) | Oui — commitez-le et poussez-le |
| L'identité d'un store | <store>/.openspec-store/store.yaml | Oui — committé avec le store |
| Le registre des stores | <data dir>/openspec/stores/registry.yaml | Non — cette machine uniquement |
| Worksets | <data dir>/openspec/worksets/ | Non — cette machine uniquement |
<data dir> est ~/.local/share/openspec sur macOS et Linux (ou $XDG_DATA_HOME/openspec si défini), et %LOCALAPPDATA%\openspec sur Windows.
Référence
Indicateurs exacts et formes JSON pour chaque commande sur cette page : Référence CLI (Stores, Doctor, Contexte de travail, Worksets personnels) et le contrat d'agent.