Stores: Planificar en su propio repositorio
Beta. Stores, references, working context y worksets son novedades. Los nombres de comandos, las banderas, los formatos de archivo y la salida JSON aún pueden cambiar entre versiones. Cada recorrido descrito a continuación se ejecutó contra la compilación actual, pero vuelva a leer esta guía después de actualizar.
El problema que resuelve esto
OpenSpec normalmente vive dentro de un solo repositorio de código: una carpeta openspec/ junto a su código, que contiene las especificaciones y los cambios para ese repositorio.
Eso deja de funcionar en el momento en que su planificación es más grande que un solo repositorio:
- Su trabajo abarca varios repositorios: una sola funcionalidad afecta al servidor de API, a la aplicación web y a una biblioteca compartida. ¿En la carpeta
openspec/de quién vive el plan? - Su equipo planifica antes de que exista código, o planifica cosas que nunca se convierten en código en este repositorio.
- Los requisitos son propiedad de un equipo y son consumidos por otros. La versión del wiki se desactualiza, y su agente de código no puede leerla de todos modos.
Un store es la respuesta: un repositorio independiente cuyo único propósito es la planificación. Tiene la misma estructura openspec/ que ya conoce — especificaciones y cambios — más un pequeño archivo de identidad. Lo registra en su máquina una sola vez, por nombre, y luego cada comando normal de OpenSpec puede trabajar en él desde cualquier lugar.
La forma
team-plans (un almacén: planificación en su propio repositorio)
├── .openspec-store/store.yaml identity: "Yo soy team-plans"
└── openspec/
├── specs/ lo que es verdadero
└── changes/ lo que está en proceso
▲
│ registrado en cada máquina por nombre;
│ compartido mediante push/clone como cualquier repositorio
┌─────────────┼─────────────┐
│ │ │
web-app api-server mobile-app
(repo de código) (repo de código) (repo de código)Dos reglas mantienen esto simple:
- Un almacén es simplemente un repositorio git. Tú haces commit, push, pull y lo revisas por ti mismo. OpenSpec nunca clona, sincroniza ni hace push por sí solo.
- Declaraciones, no maquinaria. Los repositorios pueden declarar cómo se relacionan con los almacenes (mostrado abajo). Las declaraciones cambian lo que OpenSpec puede decirte — nunca dónde actúan tus comandos.
Cinco minutos para tu primer almacén
Dos comandos te llevan de la nada a un cambio funcional, limitado al almacén:
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-plansEse es todo el modelo. A partir de aquí, el ciclo de vida es exactamente lo que conoces — status, instructions, validate, archive — con --store team-plans en cada comando, y cada pista impresa lleva la bandera por ti. La línea Using OpenSpec root: siempre te indica dónde está actuando un comando.
Historia: un equipo, un repositorio de planificación
Un equipo mantiene sus especificaciones y cambios en team-plans en lugar de esparcirlos a través de los repositorios de código.
Día uno (quien lo 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 mainPasar --remote registra la URL de clonación dentro del archivo de identidad propio del almacén (.openspec-store/store.yaml), en el commit inicial. Cada clon futuro nace sabiendo de dónde vino, por lo que las comprobaciones de salud y los mensajes de error pueden imprimir una solución completa y copiable para los compañeros de equipo que aún no la tienen.
Cada compañero de equipo (una vez por máquina):
git clone git@github.com:acme/team-plans.git ~/openspec/team-plans
openspec store register ~/openspec/team-plansA partir de entonces, todos trabajan en el mismo repositorio de planificación por nombre:
openspec status --store team-plans --change add-login
openspec show add-login --store team-plansCompartir el trabajo es git, a propósito. Un cambio que creas existe solo en tu checkout hasta que lo commiteas y haces push — igual que el código. Los planes obtienen ramas, pull requests y revisión de forma gratuita, porque un almacén es un repositorio ordinario.
Conectando los repositorios de código del equipo. Un repositorio de código cuya planificación está completamente externalizada necesita exactamente una línea, en openspec/config.yaml:
# web-app/openspec/config.yaml
store: team-plansAhora cada comando de OpenSpec ejecutado dentro de web-app actúa sobre team-plans sin ninguna bandera:
cd ~/src/web-app
openspec status --change add-loginUsing OpenSpec root: team-plans (/Users/you/openspec/team-plans)
...El puntero es un fallback, nunca una anulación: una bandera explícita --store siempre gana, y si el repositorio desarrolla sus propias carpetas de planificación reales, esas ganan (con una advertencia para eliminar el puntero obsoleto).
Un valor predeterminado para cada repositorio en tu máquina. Si trabajas en muchos repositorios de código que todos planifican en el mismo almacén, configúralo una vez, globalmente, en lugar de añadir la línea store: a cada repositorio:
openspec config set defaultStore team-plansAhora cualquier comando ejecutado fuera de una raíz de planificación — y sin --store ni puntero del proyecto — se resuelve a team-plans. Se encuentra al final de la lista de precedencia, por lo que --store, una raíz local y un puntero store: del proyecto siguen ganando. El banner de raíz y el bloque JSON root reportan source: "global_default" con el id del almacén, para que siempre puedas distinguir un valor predeterminado de toda la máquina de un puntero propio del repositorio. Límpialo con openspec config unset defaultStore. Si el id no está registrado, los comandos dan error y te indican que lo registres o limpies el valor predeterminado obsoleto.
Ejemplo: una funcionalidad, dos repositorios de componentes
Supongamos que add-checkout-promo cambia tanto checkout-api como checkout-web. El equipo quiere un contrato de producto compartido, mientras que cada repositorio de código aún necesita sus propias tareas de implementación, rama y revisión.
Usa dos capas:
- Mantén el comportamiento compartido en
team-plans. - Mantén los planes de implementación en cada repositorio de componentes y referencia el almacén como contexto ascendente de solo lectura.
Primero, planifica el contrato compartido en el almacén:
openspec new change add-checkout-promo --store team-plans
openspec status --change add-checkout-promo --store team-plansLa propuesta y las especificaciones deben describir el comportamiento en el límite entre los componentes — por ejemplo, los campos de promoción devueltos por el servicio y cómo el frontend maneja un checkout no elegible. Revisa este cambio en el repositorio del almacén como cualquier otra rama y pull request.
¿Qué contexto ve la planificación?
Seleccionar un almacén cambia la raíz de OpenSpec; no descubre ni lee cada repositorio de código que usa ese almacén. Las instrucciones del almacén ven los artefactos y el contexto configurado en el almacén. Ven el código del componente solo cuando esas carpetas también están disponibles para el agente o editor y el agente las lee.
Un conjunto de trabajo es una forma conveniente de abrir el almacén de planificación y ambos repositorios de código juntos:
openspec workset create checkout-promo \
--member ~/openspec/team-plans \
--member ~/src/checkout-api \
--member ~/src/checkout-web \
--tool code
openspec workset open checkout-promoEsto hace que las carpetas sean visibles en un espacio de trabajo del IDE. No copia el contexto fuente en el almacén, selecciona repositorios afectados ni otorga permiso a un agente para editarlos. Pon hechos duraderos entre componentes en las especificaciones compartidas; no confíes en que un planificador recuerde el código fuente que inspeccionó por casualidad.
¿Cómo comienza la implementación en cada repositorio?
Cuando no se aplica un --store explícito o una raíz openspec/ más cercana, un puntero store: team-plans enruta los comandos a ese almacén. No divide una lista de tareas del almacén por el directorio desde el cual se invocó apply. Actualmente, OpenSpec no enruta tareas a repositorios.
Cuando cada componente necesita un ciclo apply/review con alcance independiente, dale una raíz local de OpenSpec y referencia el almacén central en lugar de apuntar a él:
# checkout-api/openspec/config.yaml (y de manera similar en checkout-web)
schema: spec-driven
references:
- team-plansDespués de que el contrato compartido sea aprobado y esté disponible en las especificaciones principales del almacén, crea un pequeño cambio local para la parte del componente:
cd ~/src/checkout-api
openspec new change implement-checkout-promo-api
cd ~/src/checkout-web
openspec new change implement-checkout-promo-uiEl índice de referencia en las instrucciones de cada repositorio proporciona el resumen de la especificación del almacén y el comando de búsqueda exacto openspec show ... --store team-plans. Cada propuesta local cita ese contrato compartido, y sus tareas describen solo el trabajo en ese componente. Luego ejecuta /opsx:apply en cada repositorio por separado; la resolución de la raíz mantiene los artefactos y las ediciones de implementación con ámbito en ese repositorio. Los cambios del servicio y del frontend ahora pueden ser probados, revisados, fusionados y archivados de forma independiente.
Si la implementación debe comenzar mientras el cambio compartido del almacén aún está activo, recupéralo explícitamente con openspec show add-checkout-promo --store team-plans; los índices de referencia listan las especificaciones canónicas del almacén, no los cambios activos. Mantén la rama del almacén y las ramas de los componentes vinculadas en las descripciones de sus pull requests para que los revisores puedan ver qué versión del contrato sigue cada implementación.
Historia: requisitos que cruzan líneas de equipo
Un equipo de plataforma posee los requisitos. Los equipos de producto construyen contra ellos, en sus propios repositorios, con sus propios diseños. Una referencia describe esa relación sin mover el trabajo de nadie.
platform-reqs (almacén) api-server (repo de código)
propiedad del equipo de plataforma propiedad de un equipo de producto
┌──────────────────────────┐ ┌──────────────────────────┐
│ openspec/specs/ │ ◀────────────│ openspec/config.yaml │
│ payments/spec.md │ lee │ references: │
│ auth/spec.md │ │ - platform-reqs │
│ │ │ openspec/specs/ │
│ openspec/changes/ │ │ (sus propios diseños) │
│ trabajo de plataforma │ │ openspec/changes/ │
│ │ │ (su propio trabajo) │
│ │ └──────────────────────────┘
└──────────────────────────┘El equipo de producto declara de qué se nutre en el openspec/config.yaml de su repositorio:
references:
- platform-reqsLas referencias son contexto de solo lectura. El repositorio mantiene su propia raíz openspec/; el trabajo permanece allí. Lo que cambia: openspec instructions en ese repositorio ahora incluye un índice de las especificaciones del almacén referenciado — cada una con un resumen de una línea y el comando de búsqueda exacto (openspec show <spec-id> --type spec --store platform-reqs). Un agente que trabaje en api-server puede encontrar los requisitos de pago ascendentes, citarlos y escribir su diseño de bajo nivel en la propia raíz del repositorio — sin que nadie pegue contexto alrededor.
Una referencia puede llevar su fuente de clonación, para que los compañeros que aún no tienen el almacén obtengan una solución completa en lugar de un callejón sin salida:
references:
- { id: platform-reqs, remote: "git@github.com:acme/platform-reqs.git" }Cuando quieras el plan y el código abiertos juntos, crea un conjunto de trabajo. Esto es personal y explícito: cada persona elige las carpetas con las que realmente trabaja en su máquina. Nada sobre esas rutas locales de checkout se commitea al repositorio de planificación compartido.
openspec workset create platform \
--member ~/openspec/platform-reqs \
--member ~/src/api-server \
--member ~/src/web-appDos preguntas que siempre puedes hacer
"¿Está sano mi entorno?" — openspec doctor verifica la raíz actual y sus almacenes referenciados, de solo lectura, con una solución copiable por hallazgo:
Doctor
Raíz
Ubicación: /Users/you/src/api-server
Raíz OpenSpec: ok
Referencias
- platform-reqs: ok (/Users/you/openspec/platform-reqs)
- design-system: El almacén referenciado 'design-system' no está registrado en esta máquina.
Solución: 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"¿Con qué estoy trabajando?" — openspec context ensambla el conjunto de trabajo a partir de las declaraciones de OpenSpec: la raíz y los almacenes que referencia.
Contexto de trabajo para api-server (/Users/you/src/api-server)
Raíz OpenSpec
api-server /Users/you/src/api-server
Almacenes referenciados
platform-reqs /Users/you/openspec/platform-reqs
Obtener: openspec show <spec-id> --type spec --store platform-reqsAmbos soportan --json para agentes. openspec context --code-workspace <ruta> escribe adicionalmente un archivo de espacio de trabajo de VS Code que contiene todo el conjunto — la única escritura que realiza este comando.
Worksets: reabre las carpetas con las que trabajas juntos
Separado de todo lo anterior: la mayoría de las personas abre las mismas pocas carpetas juntas en cada sesión — el repositorio de planificación más dos o tres repositorios de código. Un workset es una vista personal y nombrada de exactamente eso, reabierta con un solo comando en tu herramienta de elección.
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 luego lanza la herramienta guardada: los editores (VS Code, Cursor) abren una ventana con cada miembro y regresan. El primer miembro es el primario. Puedes sobrescribir la herramienta en cualquier momento con --tool <id>.
Los worksets deliberadamente no son estado compartido. Viven en tu máquina, nunca se commitean y no hacen afirmaciones sobre el trabajo — solo registran lo que te gusta tener abierto junto. Eliminar uno nunca toca las carpetas miembro. Las nuevas herramientas son configuración, no código: cualquier cosa lanzada mediante un archivo de workspace o flags de adjuntar por carpeta puede agregarse bajo la clave openers en la configuración global (openspec config edit).
Cómo los comandos deciden dónde actuar
Cada comando normal resuelve su raíz de la misma manera, en este orden:
1. --store <id> lo dijiste explícitamente → ese store
2. nearest openspec/ una raíz de planificación real aquí → este repo
(walking up from cwd)
3. store: pointer config.yaml declara un store → ese store
4. defaultStore la configuración global establece un → ese store
default
5. none of the above ¿stores registrados en esta → error con una
máquina? pista de selección
¿sin stores registrados? → el directorio
actual
(comportamiento clásico)La línea Using OpenSpec root: (y el bloque root en la salida --json) te indica en qué caso estás.
Limitaciones conocidas
- Forma beta. Todo en esta página puede cambiar entre versiones — nombres, flags, formatos de archivo, claves JSON.
- Un checkout por store id por máquina. Registrar un segundo checkout bajo el mismo id falla con una pista para usar
store unregisterprimero. - Sin sincronización, nunca — por diseño. OpenSpec nunca clona, tira ni empuja. Un checkout desactualizado muestra specs desactualizadas hasta que tú tires; las referencias se indexan en vivo desde lo que hay en disco.
- Las carpetas de planificación vacías pueden estar ausentes. Un store nuevo puede no tener
openspec/changes/,openspec/specs/, oopenspec/changes/archive/en Git todavía. Esto se acepta durante la beta; esas carpetas aparecen una vez que los comandos normales crean archivos para ellas. - Los repos de puntero siguen siendo punteros. Un repo solo de configuración cuyo
openspec/config.yamldeclarastore: <id>se trata como planificación externalizada, no como un checkout de store para registrar. Elimina la líneastore:primero si intencionalmente quieres convertir ese repo en una raíz de store local. - Algunos comandos se quedan donde están.
templatesy las formas de sustantivo deprecadas (openspec change show, ...) actúan solo sobre el directorio actual — sin--store.schemassigue la precedencia canónica de selección de raíz y acepta--store <id>mientras mantiene su forma de arreglo JSON exitoso sin cambios. - El estado por máquina es por máquina. El registro de stores y los worksets son configuraciones locales. Nada sobre el layout de tu máquina se commitea nunca a la planificación compartida.
- Dos estilos de lanzamiento para worksets. Una herramienta que no puede lanzarse con un archivo de workspace o flags de adjuntar por carpeta no puede agregarse como opener.
- El JSON del agente tiene una división de mayúsculas conocida (las claves de la familia store son snake_case, las de la familia workflow camelCase). Documentado en el contrato del agente; unificarlo se difiere a una versión estable.
Dónde viven las cosas
| Qué | Dónde | ¿Compartido? |
|---|---|---|
| La planificación de un store | <store>/openspec/ (specs, changes) | Sí — commitea y empuja |
| La identidad de un store | <store>/.openspec-store/store.yaml | Sí — se commitea con el store |
| El registro de stores | <data dir>/openspec/stores/registry.yaml | No — solo esta máquina |
| Worksets | <data dir>/openspec/worksets/ | No — solo esta máquina |
<data dir> es ~/.local/share/openspec en macOS y Linux (o $XDG_DATA_HOME/openspec cuando está configurado), y %LOCALAPPDATA%\openspec en Windows.
Referencia
Flags exactos y formas JSON para cada comando en esta página: referencia CLI (Stores, Doctor, Working context, Personal worksets) y el contrato del agente.