¿Qué es OpenSpec? El flujo de specs antes del código

OpenSpec convierte cada cambio en una propuesta escrita que apruebas antes de programar. Qué es, cómo funciona propose, apply y archive, y cuándo compensa.

¿Qué es OpenSpec? El flujo de specs antes del código

OpenSpec es una herramienta de spec-driven development que convierte cada cambio en una propuesta escrita dentro de tu repositorio y detiene al agente hasta que la apruebas. Si has visto el nombre en un repo y no te ha quedado claro qué añade sobre escribirle un prompt largo, la respuesta corta es que OpenSpec no es un formato de documento, es un ciclo de estados para tus cambios. Aquí explico cómo funciona ese ciclo por dentro, qué ficheros deja en tu proyecto y cuándo esa ceremonia compensa.

¿Cómo funciona el ciclo propose → apply → archive?

OpenSpec se usa casi todo desde el chat de tu agente, no desde la terminal. La terminal aparece dos veces, una para instalar y otra para inicializar:

# Requiere Node.js 20.19.0 o superior
npm install -g @fission-ai/openspec@latest
cd tu-proyecto
openspec init

A partir de ahí vives en comandos con barra dentro del asistente. El perfil por defecto, que la documentación llama core, trae seis: propose, explore, apply, update, sync y archive [1].

/opsx:explore es el paso opcional de delante. Le cuentas una idea todavía difusa, lee tu código, compara opciones y afila el plan sin comprometerte a nada. Cuando la conversación cuaja, te ofrece convertirla en un cambio.

/opsx:propose add-dark-mode es donde empieza lo formal. El agente crea la carpeta del cambio y escribe cuatro artefactos: el proposal.md con el porqué y el qué cambia, las specs con requisitos y escenarios, el design.md con el enfoque técnico y un tasks.md que es una lista de tareas con casillas. Y ahí se para. Ese punto de parada es el mecanismo entero de OpenSpec: tú lees el plan antes de que exista el código.

/opsx:apply implementa las tareas del tasks.md y va marcando casillas. /opsx:archive cierra el cambio: valida, fusiona las specs delta del cambio en las specs principales y mueve la carpeta a la de archivo con la fecha delante, algo como openspec/changes/archive/2025-01-23-add-dark-mode/ [4]. Existe además /opsx:sync, que hace esa fusión por separado, pero la documentación lo marca como opcional porque archive la ofrece cuando hace falta [1].

El nombre canónico es /opsx:propose, pero cada herramienta lo escribe según cómo carga el fichero que OpenSpec le deja: en Cursor es /opsx-propose, en Amazon Q se invoca con arroba y en Codex es $openspec-propose [3]. openspec init imprime la forma correcta para las herramientas que hayas elegido.

Qué escribe OpenSpec en tu repo

Todo lo que produce OpenSpec es Markdown dentro de una carpeta openspec/ en la raíz de tu proyecto, y por tanto todo entra en git como cualquier otro fichero [5]:

openspec/
├── specs/              # comportamiento actual del sistema
│   └── <dominio>/
│       └── spec.md
├── changes/            # cambios propuestos
│   └── <nombre-del-cambio>/
│       ├── proposal.md
│       ├── design.md
│       ├── tasks.md
│       └── specs/      # specs delta
│           └── <dominio>/
│               └── spec.md
└── config.yaml         # configuración del proyecto (opcional)

Esa separación entre specs/ y changes/<nombre>/specs/ es la parte que más cuesta al principio y la que más rendimiento da después. En specs/ vive lo que el sistema hace hoy. Dentro de un cambio vive solo el delta, o sea, qué requisitos se añaden, cuáles se modifican y cuáles desaparecen. Al archivar, el delta se funde con la spec principal y el histórico se queda en changes/archive/.

Las specs no tienen sintaxis propia que aprender, son Markdown con una convención de encabezados. Un requisito se escribe así [2]:

## ADDED Requirements

### Requirement: Theme selection
The app SHALL let users switch between light and dark themes,
defaulting to the system preference.

#### Scenario: User toggles dark mode
- **WHEN** the user clicks the theme toggle
- **THEN** the app switches to dark mode and persists the choice

Requisito en forma de SHALL, escenario en forma de cuándo y entonces. Nada más. Es lo bastante rígido para que una herramienta lo valide y lo bastante llano para que lo leas en una revisión de pull request sin abrir nada especial.

Además de las carpetas, openspec init configura tu asistente. Para Claude Code deja las instrucciones en .claude/skills/openspec-*/SKILL.md y los comandos en .claude/commands/opsx/<id>.md; cada herramienta tiene su ruta equivalente, y la tabla completa lista hoy cincuenta y una [3]. Si actualizas el paquete global, openspec update regenera esos ficheros dentro de cada proyecto.

En qué se diferencia de pedirle el cambio por el chat

La diferencia está en dónde vive el plan y cuándo se aprueba, no en lo que dice. Un prompt largo bien escrito puede describir el mismo cambio que un proposal.md, pero muere con la sesión, no se revisa, no se versiona y nadie puede compararlo con lo que el agente acabó haciendo.

Prompt largo en el chatCambio en OpenSpec
Dónde vive el acuerdoEn el historial de la conversaciónEn openspec/changes/<nombre>/, dentro del repo
Cuándo lo revisasMientras el agente ya está escribiendo códigoAntes, /opsx:propose se detiene y espera
Qué queda despuésNada, salvo el diffLas specs actualizadas más el cambio archivado con fecha
Quién más lo veTúCualquiera que abra el pull request, humano o agente
Comprobable por máquinaNoSí, con openspec validate

Esa última fila es la que convierte el ritual en algo más que disciplina personal. openspec validate comprueba que los cambios y las specs están bien formados, y además contrasta los requisitos marcados como MODIFIED contra las specs principales que van a reemplazar [4]. Tiene un detalle que delata que la herramienta se ha usado en proyectos de verdad: un cambio sin ninguna spec delta falla la validación, salvo que su .openspec.yaml declare skip_specs: true, pensado para refactors o trabajo de tooling que no cambian comportamiento.

Y hay un modo que vale para un hook de pre-commit: openspec validate --archived recorre los cambios de changes/archive/ y falla si alguno se archivó con casillas del tasks.md sin marcar [4].

Cuándo compensa y cuándo estorba

En el pipeline de contenido de este sitio cada fase de generación tiene un contrato escrito antes de ejecutarse, y de ahí sale mi criterio. La ceremonia compensa cuando el coste de que el agente construya lo que no era supera el coste de escribir el plan. Eso ocurre antes de lo que parece, en cuanto el cambio toca más de un fichero o más de una persona. Decidir dónde poner ese contrato y qué meter dentro es una de las cosas que se practican con ejercicios en el curso de patrones agénticos.

Compensa cuando el cambio cruza módulos y quieres que el acuerdo sobreviva a la sesión. Compensa mucho en brownfield, porque las specs de openspec/specs/ acaban siendo la descripción de lo que el sistema hace hoy, que es justo lo que a un agente le falta cuando aterriza en un repositorio viejo. Y compensa en equipo, donde la propuesta se discute en el pull request antes de que nadie haya quemado tokens implementando.

Estorba cuando el cambio es un arreglo de dos líneas o cuando el proyecto es un experimento que vas a tirar el viernes. Ahí la carpeta de artefactos es ruido. Para ese caso está /opsx:explore, que no crea nada hasta que se lo pides.

Hay un coste que la documentación no oculta y conviene tener presente: OpenSpec funciona mejor con modelos de razonamiento alto y con la ventana de contexto limpia, y el propio README recomienda vaciar el contexto antes de empezar la implementación [2]. Si tu agente llega a /opsx:apply con la conversación llena de la exploración previa, el plan escrito le sirve de poco.

Si lo que estás decidiendo es qué framework de specs adoptar y no si adoptar uno, la comparación está en cómo se compara OpenSpec con Spec Kit y BMAD. Y si el concepto de fondo todavía te suena a palabra de moda, empieza por qué es spec-driven development, que explica la idea sin atarla a ninguna herramienta.

Fuentes

  1. OpenSpec — Commands — nombres exactos de los comandos del perfil core y del perfil ampliado, y cómo se activa cada uno.
  2. OpenSpec — README — instalación, versión mínima de Node, ejemplo del ciclo completo, formato de las specs y nota sobre higiene de contexto.
  3. OpenSpec — Supported Tools — rutas que escribe para cada asistente y las distintas formas de invocar los comandos.
  4. OpenSpec — CLI — referencia de validate, archive, list, show, status y view con sus opciones.
  5. OpenSpec — Getting Started — estructura de directorios que crea openspec init y descripción del ciclo de vida de un cambio.
  6. openspec.dev — sitio oficial del proyecto y cómo se presenta.

Preguntas Frecuentes

¿Qué es OpenSpec en una frase?

OpenSpec es una herramienta de spec-driven development para asistentes de código que convierte cada cambio en una carpeta de Markdown dentro de tu repositorio, con la propuesta, los requisitos, el diseño y las tareas, y detiene al agente en ese punto para que apruebes el plan antes de que escriba código.

¿Qué es “openspec dev”?

Es el sitio oficial del proyecto, openspec.dev, que se presenta como un framework de specs ligero y configurable y dice ayudar a equipos y agentes de código a crear, refinar y mantener especificaciones vivas [6]. El código vive en GitHub bajo la organización Fission-AI, que lo describe como spec-driven development para asistentes de código [2], y se publica en npm como @fission-ai/openspec con licencia MIT.

¿Funciona con Claude Code?

Sí. openspec init le deja esto, y los comandos se invocan tal cual, /opsx:propose [3]:

.claude/skills/openspec-*/SKILL.md
.claude/commands/opsx/<id>.md

¿Necesito OpenSpec para hacer spec-driven development?

No. Puedes escribir la spec a mano en un fichero Markdown y pedirle al agente que la cumpla, y para un proyecto pequeño eso funciona. Lo que aporta OpenSpec es la parte aburrida: el sitio fijo donde ponerla, el delta separado del estado actual, el archivo con fecha y un validador que detecta que el cambio está mal formado o que lo archivaste con tareas sin marcar.

¿Es lo mismo que Spec Kit?

No. El propio README de OpenSpec se compara con Spec Kit y se sitúa como la opción más ligera de las dos [2]. La comparación en detalle, incluyendo BMAD, la tienes en el análisis de los tres frameworks.