Escribir specs
Una spec describe qué hace el sistema, no cómo está construido. OpenSpec distingue entre las specs principales (openspec/specs/), que reflejan el comportamiento vigente, y las delta specs de cada change, que describen solo lo que ese change añade, modifica o elimina.
Reglas del formato
Sección titulada «Reglas del formato»- Cada requisito empieza con
### Requirement: <nombre>y usa una palabra normativa en inglés: SHALL o MUST. - Cada requisito tiene al menos un
#### Scenario: <nombre>(cuatro almohadillas; con tres, el validador no lo reconoce). - Los escenarios se escriben con GIVEN / WHEN / THEN / AND en negrita y en lista.
- Una capacidad por carpeta:
openspec/specs/<capacidad>/spec.md. - El nombre del requisito es su identificador: las deltas lo localizan por nombre exacto.
Ejemplo de spec principal
Sección titulada «Ejemplo de spec principal»# Reservas
## PurposeGestión de reservas de salas por parte de los usuarios registrados.
## Requirements
### Requirement: Crear reservaEl sistema SHALL permitir reservar una sala libre para una franja horaria.
#### Scenario: Reserva de una sala libre- **GIVEN** la sala "Norte" está libre de 10:00 a 11:00- **WHEN** un usuario la reserva para esa franja- **THEN** la reserva queda en estado "confirmada"
#### Scenario: Reserva duplicada- **GIVEN** la sala "Norte" ya está reservada de 10:00 a 11:00- **WHEN** otro usuario intenta reservarla para esa franja- **THEN** el sistema rechaza la petición con el código `RESERVA_DUPLICADA`Delta specs
Sección titulada «Delta specs»Dentro de un change, la delta spec vive en openspec/changes/<change>/specs/<capacidad>/spec.md y agrupa los requisitos por operación. Al archivar, OpenSpec aplica cada operación sobre la spec principal.
ADDED: requisito nuevo
Sección titulada «ADDED: requisito nuevo»## ADDED Requirements
### Requirement: Cancelar reservaEl sistema SHALL permitir cancelar una reserva confirmada hasta 2 horas antes de su inicio.
#### Scenario: Cancelación dentro de plazo- **GIVEN** una reserva confirmada que empieza dentro de 5 horas- **WHEN** su titular la cancela- **THEN** la reserva pasa a estado "cancelada" y la sala queda libreMODIFIED: cambiar un requisito existente
Sección titulada «MODIFIED: cambiar un requisito existente»MODIFIED reescribe el requisito completo: copia el bloque entero de la spec principal y edítalo. Lo que no incluyas se pierde al archivar. En el ejemplo, la línea eliminada es la versión anterior y las insertadas son lo nuevo.
## MODIFIED Requirements
### Requirement: Crear reservaEl sistema SHALL permitir reservar una sala libre para una franja horaria.El sistema SHALL permitir reservar una sala libre para una franja horaria de 4 horas como máximo.
#### Scenario: Reserva de una sala libre- **GIVEN** la sala "Norte" está libre de 10:00 a 11:00- **WHEN** un usuario la reserva para esa franja- **THEN** la reserva queda en estado "confirmada"
#### Scenario: Franja demasiado larga- **WHEN** un usuario intenta reservar una sala durante 5 horas- **THEN** el sistema rechaza la petición con el código `FRANJA_EXCEDIDA`En el fichero real no dejas la línea antigua: los marcadores solo muestran qué cambia respecto a la spec principal.
REMOVED: retirar un requisito
Sección titulada «REMOVED: retirar un requisito»## REMOVED Requirements
### Requirement: Lista de espera**Reason**: la lista de espera apenas se usaba y complicaba la liberación de salas.**Migration**: se avisa a los usuarios cuando una sala se libera; las entradas en lista de espera se eliminan.REMOVED siempre lleva Reason (por qué se retira) y Migration (qué ocurre con quien dependía de ese comportamiento).
Buenas prácticas
Sección titulada «Buenas prácticas»- Escribe comportamiento observable, no detalles de implementación (nada de tablas, clases o endpoints concretos salvo que sean el contrato).
- Un requisito, una regla. Si un requisito necesita «y además», probablemente son dos.
- Cubre el caso feliz y al menos un caso de error con su código (
RESERVA_DUPLICADA). Usa códigos de error estables, no mensajes literales: el frontend y los tests dependen de ellos. - Usa datos de ejemplo concretos y neutros: salas, franjas, estados. Nunca datos personales.
- Cada escenario debe poder convertirse en un test cuyo nombre contenga
Scenario: <nombre>. - No rellenes specs de todo el sistema de golpe (backfilling): las specs crecen change a change, solo sobre lo que tocas.
Checklist de revisión
Sección titulada «Checklist de revisión»- ¿Cada requisito usa SHALL o MUST?
- ¿Cada requisito tiene al menos un escenario con
####? - ¿Los escenarios cubren el caso feliz y los errores relevantes?
- ¿Los
MODIFIEDincluyen el requisito completo, con todos sus escenarios? - ¿Los
REMOVEDexplican Reason y Migration? - ¿Pasa
openspec validate --strict?