Skip to content

Escribir buenas especificaciones ​

Rara vez escribes una especificación desde una página en blanco. Describes un cambio en lenguaje sencillo, /opsx:propose redacta los requisitos y los escenarios, y luego los mejoras. Esta página trata sobre esa última parte: qué significa "bueno" y cómo guiar a la IA hacia ello.

Es el complemento de Revisar un cambio: revisar es detectar los puntos débiles de un borrador; escribir es saber de qué está hecho uno sólido.

Una especificación es comportamiento, no código ​

Una especificación dice lo que tu sistema hace, en términos que cualquiera pueda comprobar — no cómo está construido. Se compone de requisitos (declaraciones de comportamiento) y escenarios (ejemplos concretos que los demuestran).

markdown
### Requisito: Tiempo de espera de sesión
El sistema DEBE (SHALL) expirar una sesión después de 30 minutos de inactividad.

#### Escenario: Tiempo de espera por inactividad
- DADO una sesión autenticada
- CUANDO pasan 30 minutos sin actividad
- ENTONCES la sesión se invalida y el usuario debe autenticarse nuevamente

Mantén el cómo — la cola, la librería, el esquema de tabla — en design.md o en el código. Cuando el comportamiento y la implementación se mezclan en un mismo requisito, el requisito deja de ser comprobable y empieza a quedar obsoleto en cuanto el código cambia.

Qué hace bueno a un requisito ​

Un buen requisito es un único comportamiento, expresado con tanta claridad que podrías entregárselo a otra persona para que lo pruebe.

  • Una declaración, un SHALL/MUST. Si un requisito tiene tres cláusulas "y además", en realidad son tres requisitos. Divídelos.

  • Observable. Alguien fuera del código debería poder determinar si se cumple. "El sistema DEBE mostrar un banner de error cuando la carga supera los 10 MB" es observable. "El sistema DEBE manejar cargas grandes con elegancia" no lo es.

  • La fuerza adecuada. OpenSpec utiliza las palabras clave del RFC 2119, y significan cosas distintas:

    Palabra claveSignificado
    MUST / SHALLUn requisito estricto. Innegociable.
    SHOULDUna fuerte recomendación, con margen para una excepción justificada.
    MAYRealmente opcional.

    Usa MUST/SHALL por defecto. Utiliza SHOULD solo cuando realmente quieras decir "a menos que haya una buena razón para no hacerlo".

La prueba de un requisito: ¿podría un evaluador que nunca ha visto el código saber si se cumple? Si no, necesita ser afinado.

Qué hace bueno a un escenario ​

Los escenarios son donde un requisito demuestra su valor. Cada uno es un GIVEN / WHEN / THEN concreto que podría convertirse en una prueba automatizada.

  • Ejercita su requisito. Un escenario que solo reformula el requisito con otras palabras no prueba nada. Haz que sea una situación específica con un resultado específico.
  • Cubre los casos que importan, no solo el camino feliz. El inicio de sesión válido es fácil. La entrada vacía, el token caducado, el segundo clic, lo que sale mal — ahí es donde viven los errores, y donde un escenario vale más.
  • Nombra el caso en el título. "Escenario: Rechaza un token caducado" le dice a un revisor qué se cubre de un vistazo; "Escenario: Prueba 2" no lo hace.

Un hábito útil: antes de aprobar, pregúntate ¿cuál es el caso que me molestaría ver fallar? — y asegúrate de que un escenario lo nombre.

Elige el tipo correcto de delta ​

Un cambio describe sus ediciones a las especificaciones con tres tipos de sección. Usar el correcto mantiene tus especificaciones archivadas honestas:

  • ## ADDED Requirements — comportamiento completamente nuevo que no existía antes.
  • ## MODIFIED Requirements — comportamiento que ya existía y está cambiando. Incluye la versión completa nueva; una breve nota sobre qué cambió ayuda al revisor.
  • ## REMOVED Requirements — comportamiento que desaparece, con una línea sobre el porqué.

Al archivar, ADDED se anexa a la especificación principal, MODIFIED reemplaza la versión anterior y REMOVED se elimina de ella. Si eliminas el último requisito de una capacidad, la retiras: en lugar de dejar una especificación sin contenido, el archivo elimina openspec/specs/<capacidad>/spec.md. Dado que es el único paso de archivado que elimina un archivo, debe solicitarse explícitamente: añade retire_capabilities: true al .openspec.yaml del cambio, junto con el schema: que ese archivo ya necesita. Sin ello, el archivado se aborta y te lo indica. La retirada elimina todo el archivo, por lo que también se rechaza mientras la especificación contenga algo fuera de su título, ## Purpose y sus bloques de requisitos — una sección ## Notes, un comentario bajo un requisito. El aborto nombra esas líneas; muévelas a ## Purpose o a un requisito, o elimina la especificación manualmente. Para una especificación en el checkout del llamador, la salida del archivado también indica el git checkout que restaura un archivo confirmado; las tiendas seleccionadas reciben orientación de recuperación específica del checkout. Si marcas un cambio real como ADDED, terminas con dos requisitos en competencia; si describes un comportamiento nuevo como MODIFIED, no hay nada que reemplazar. En caso de duda, abre la especificación actual y comprueba si el requisito ya está ahí.

Vale la pena conocer otra sección más. Cuando tu delta crea una capacidad que aún no existe, ábrela con ## Purpose — una o dos frases sobre para qué sirve la capacidad. El archivado lo usa como Propósito de la especificación principal que crea; si lo omites, obtienes un marcador TBD para rellenar a mano. Una especificación existente ya tiene un Propósito, por lo que el de un delta se ignora en ese caso — edita openspec/specs/<ruta-de-capacidad>/spec.md directamente para cambiarlo. Aquí, <ruta-de-capacidad> es el directorio relativo a specs/, como user-auth en un proyecto plano o identity/user-auth en un proyecto organizado por dominio.

Ajusta el tamaño del cambio ​

El error de autoría más común no es un requisito mal redactado — es un cambio que intenta ser tres cambios a la vez.

Un buen cambio tiene una única intención que puedes expresar en una frase. "Añadir un interruptor de modo oscuro." "Limitar la tasa del endpoint de inicio de sesión." "Migrar las sesiones fuera de las cookies." Si describir el cambio requiere muchos "y además", esa es la señal para dividirlo.

Señales de que un cambio es demasiado grande:

  • El alcance de la propuesta parece una lista de características no relacionadas.
  • Revisarlo tomaría toda una tarde, por lo que nadie lo hará.
  • Dos personas no podrían trabajar en él sin chocar.
  • La mitad de las tareas podrían publicarse por sí solas.

Los cambios más pequeños son más fáciles de revisar, más fáciles de construir en una sesión enfocada y más fáciles de razonar seis meses después cuando solo queda el archivo. Siempre puedes ejecutar varios cambios en paralelo — consulta Editar e iterar y Flujos de trabajo.

También ocurre lo contrario: una corrección de una línea de un error tipográfico no necesita tres requisitos y un documento de diseño. Adapta la ceremonia a lo que está en juego.

Cómo guiar a la IA hacia un buen borrador ​

Dado que /opsx:propose hace el primer borrador, la calidad de lo que recibes sigue la calidad de lo que le das. No tienes que escribir requisitos a mano — tienes que apuntar bien a la IA:

  • Indica la intención y el límite. "Añade un interruptor de modo oscuro que siga la configuración del sistema en la primera carga — no toques la API de temas existente." La mitad fuera de alcance importa tanto como la mitad dentro de alcance.
  • Nombra los casos que te importan. "Asegúrate de que haya un escenario para un usuario que ya eligió un tema manualmente." La IA cubre lo que señalas.
  • Luego edita. Es Markdown sencillo. Ajusta un SHALL vago, elimina un escenario que no prueba nada, añade el caso que omitió — o pídele a la IA: "el requisito de tiempo de espera es vago, fíjalo a 30 minutos."

Borraja, afina, repite. Unas cuantas rondas de eso producen una especificación en la que confías, que es el objetivo principal.

Una lista de verificación rápida ​

A dónde ir después ​