AI 9 min

El Pipeline SDD en la Práctica: De la Sintaxis EARS a las Tareas Atómicas

Descubre cómo aplicar el Spec-Driven Development en un ciclo real con Spec Kit, transformando ideas vagas en tareas atómicas y gobernadas.

Escrito por Samir El Azem Crovetto • Senior Backend Engineer & DevSecOps

Seguro que después de hablar tanto sobre constitutions y arquitecturas de gobernanza tienes ganas de ver cómo se traduce todo esto en comandos reales de terminal. Al fin y al cabo, a los desarrolladores lo que nos gusta es abrir la consola, ver archivos y ejecutar cosas.

Hoy vamos a bajar del cielo conceptual a la tierra de la terminal. Vamos a hacer un walkthrough completo de un ciclo de desarrollo real usando Spec Kit (esa navaja suiza de código abierto de GitHub de la que hablamos en el post anterior). Vamos a simular que tenemos que añadir una funcionalidad típica en un proyecto: un sistema de reserva de mesas para una aplicación de restaurante.

Verás cómo una simple idea vaga se transforma en un checklist atómico de tareas totalmente gobernado y estructurado, sin margen para que la IA improvise o alucine por el camino.


1. Desplegando el andamiaje: specify init

Lo primero es lo primero. Para que Spec Kit empiece a funcionar en el proyecto, necesitas instalar su CLI e inicializar el repositorio. En producción, la forma más limpia de hacerlo es utilizando uv (el gestor de paquetes ultra rápido de Python) para no pelearnos con las dependencias globales.

Solo hay que ejecutar este comando en la raíz de tu proyecto:

uv tool install specify-cli
specify init mi-proyecto-restaurante --integration copilot

(Nota: El flag --integration le dice a Spec Kit con qué agente de IA trabajas en el día a día, ya sea Copilot, Claude Code, o cualquier otro editor agéntico compatible).

Este comando de inicialización creará una estructura oculta en tu repositorio dentro de la carpeta .specify/. Ahí es donde Spec Kit guarda sus plantillas de comandos, scripts de validación y la memoria interna del pipeline.

Una vez hecho esto, tu agente de IA preferido tendrá acceso automático a una serie de comandos de barra diagonal (/speckit.*) directamente en la consola de chat del editor. A partir de aquí, el humano deja de dar rodeos interactivos y empieza a guiar el flujo.


2. Paso 1: Especificar sin alucinaciones (La magia de EARS)

La mayoría de los desastres en el código generado por IA ocurren porque le pedimos cosas como: «Créame un sistema de reservas de mesas». Para un humano, eso tiene sentido. Para un LLM, es una invitación abierta a inventar. La IA decidirá por su cuenta si el usuario puede reservar para cien personas, qué pasa si seleccionas una fecha en el pasado o en qué formato se guarda el email.

En SDD no dejamos que la IA asuma nada. Para ello, usamos el comando de especificación:

/speckit.specify Añadir funcionalidad de reserva de mesas al asistente del restaurante. Los clientes deben poder reservar mesa dando su nombre, número de personas, fecha y hora. También deben poder consultar sus reservas. El sistema tiene que confirmar antes de guardar y manejar peticiones especiales como "mesa al lado de la ventana" o "celebración de cumpleaños".

Al lanzar este comando, Spec Kit crea automáticamente una rama de Git específica para esta funcionalidad (por ejemplo, 012-mesa-reservas) y genera un archivo de especificación limpia en specs/012-mesa-reservas/spec.md.

Pero lo verdaderamente importante no es el archivo, sino la sintaxis que utiliza para definir las reglas de negocio. Spec Kit viene preparado para obligar a la IA a escribir las reglas usando la notación EARS (Easy Approach to Requirements Syntax).

EARS es básicamente una forma de estructurar frases lógicas con plantillas rígidas para eliminar cualquier rastro de ambigüedad. En lugar de escribir prosa libre, las reglas de aceptación en spec.md se redactan siguiendo estos patrones:

  • Ubiquitous (Siempre activo):
  • Sintaxis: El [sistema] deberá [hacer algo].
  • Ejemplo: El sistema deberá mostrar siempre las horas de reserva en formato de 24 horas.
  • Event-Driven (Cuando ocurre algo):
  • Sintaxis: CUANDO [ocurra el evento], el [sistema] deberá [hacer algo].
  • Ejemplo: CUANDO el cliente confirme los detalles en pantalla, el sistema deberá procesar la reserva.
  • Unwanted Behavior (Si pasa algo malo, control de errores):
  • Sintaxis: SI [ocurre una condición no deseada], ENTONCES el [sistema] deberá [hacer algo].
  • Ejemplo: SI el número de comensales supera el aforo máximo de la mesa, ENTONCES el sistema deberá denegar la reserva con un mensaje de error explicativo.
  • State-Driven (Mientras estemos en un estado específico):
  • Sintaxis: MIENTRAS [estemos en este estado], el [sistema] deberá [hacer algo].
  • Ejemplo: MIENTRAS la pasarela de pago esté fuera de servicio, el sistema deberá marcar las reservas en estado "Pendiente de confirmación".

Al obligar a la IA (y a nosotros mismos) a escribir los requerimientos con este nivel de rigor matemático, la ambigüedad desaparece. El comportamiento del sistema bajo casos límite queda perfectamente definido antes de escribir una sola línea de código.


3. Paso 2: /speckit.clarify (La entrevista incómoda)

Escribir una especificación perfecta al primer intento es casi imposible. Siempre nos dejamos algún cabo suelto. En el flujo tradicional, estos cabos sueltos los descubre el programador a mitad del desarrollo y decide improvisar según su criterio.

En SDD, antes de pasar a la fase técnica, ejecutamos el comando de clarificación:

/speckit.clarify

Este comando es como pasarle un test estático de lógica a nuestra especificación en inglés o español. Spec Kit escanea el archivo spec.md buscando contradicciones, asunciones silenciosas o datos que faltan. Al terminar, la IA no se pone a programar: se pone en modo entrevistadora y te hace preguntas de opción múltiple.

En nuestro ejemplo de las reservas, la interacción en la consola se vería así:

IA: He analizado la especificación de reservas. Tengo 3 dudas críticas que resolver antes de continuar:

1. Cancelaciones: No has especificado si el usuario puede cancelar una reserva ya confirmada. ¿Cómo procedemos?

* [A] Permitir cancelación en cualquier momento.

* [B] Permitir cancelación solo con un mínimo de 2 horas de antelación.

* [C] No permitir cancelaciones por chat (requiere llamar al restaurante).

2. Límite de comensales por mesa: ¿Cuál es el aforo máximo permitido para una sola reserva online?

* [A] Máximo 8 personas (reservas mayores requieren contacto directo).

* [B] Sin límite técnico (se asume que hay mesas gigantes).

3. Fechas pasadas: ¿Qué ocurre si un usuario intenta reservar para una fecha que ya ha pasado?

* [A] Denegar con error 400.

* [B] Redirigir automáticamente a la fecha disponible más cercana.

Por favor, responde con la opción elegida para cada punto (ej. 1B, 2A, 3A).

Tú respondes en el chat de forma rápida ("1B, 2A, 3A"), y la IA se encarga de reescribir e inyectar esas decisiones directamente dentro del archivo spec.md, usando la sintaxis EARS correspondiente. El contrato de negocio está ahora sellado y sin fisuras.


4. Paso 3: /speckit.plan (Diseño técnico bajo la lupa de la Constitución)

Una vez que sabemos exactamente qué queremos construir, toca definir cómo lo vamos a hacer a nivel de arquitectura. Para eso lanzamos el comando de planificación:

/speckit.plan El backend usará Node.js con Express, guardando los datos en una base de datos SQLite local para simplificar el despliegue.

Aquí ocurre magia por debajo. El comando /speckit.plan lee nuestra especificación pulida, pero también carga de forma obligatoria la Constitución del repositorio (constitution.md) de la que tanto hablamos en el post anterior.

La IA analiza tu propuesta técnica y la cruza con las leyes inmutables de tu arquitectura. Si en tu Constitución pusiste que "Está prohibido añadir dependencias externas sin validación" o que "Toda base de datos debe migrarse mediante archivos SQL reversibles", el plan técnico se adaptará estrictamente a esas restricciones.

Como resultado de este paso, Spec Kit generará tres archivos fundamentales dentro de la carpeta de la funcionalidad:

  • plan.md: El mapa de ruta técnico. Qué archivos se van a crear, qué servicios existentes se van a modificar y cómo se estructurará la lógica.
  • data-model.md: El diseño de base de datos. En nuestro caso, la definición de la tabla reservations con sus tipos (UUID para el id, VARCHAR para el nombre, INTEGER para la cantidad, etc.) y sus restricciones de integridad.
  • research.md: Notas de investigación. Si la IA ha tenido que buscar la compatibilidad de una librería de fechas o analizar el rendimiento de SQLite bajo concurrencia, lo deja documentado aquí con su justificación técnica.

5. Paso 4: /speckit.tasks (El checklist de ejecución real)

Con el diseño técnico aprobado, lo último que queremos es que un desarrollador (o una IA) intente implementar todo el sistema de reservas de una sola sentada. Los cambios gigantescos en un solo prompt saturan la ventana de contexto de los modelos, provocando código incompleto o parches rotos.

Para evitarlo, descomponemos el plan en tareas ultra granulares utilizando el comando:

/speckit.tasks

Spec Kit lee el plan, el modelo de datos y las APIs diseñadas, y escupe un archivo llamado tasks.md en la carpeta de la funcionalidad. Este archivo es un checklist con un formato súper estricto y secuencial:

# Checklist de Tareas: Funcionalidad Reserva de Mesas

## Fase 1: Base de Datos e Integración
- [ ] [T001] [P] Crear script de migración SQL para la tabla `reservations` en `db/migrations/003_reservations.sql`.
- [ ] [T002] [P] Añadir datos de prueba iniciales (seed) en `db/seeds/reservations_seed.sql`.

## Fase 2: Lógica de Contratos y API (TDD)
- [ ] [T003] [P] Escribir tests de integración para el endpoint `POST /api/reservations` verificando rechazo de fechas pasadas y aforos superiores a 8 personas.
- [ ] [T004] [P] Escribir tests de integración para `GET /api/reservations` verificando listado por usuario.

## Fase 3: Implementación de Controladores
- [ ] [T005] Crear controlador de Express `controllers/reservations.js` con las validaciones de entrada.
- [ ] [T006] Crear servicio de base de datos `services/reservations.js` para persistir reservas.

## Fase 4: Pulido y Verificación
- [ ] [T007] Ejecutar linter y suite completa de pruebas para garantizar regresión cero.

La gestión de estados en las tareas

Fíjate en los detalles de este checklist, porque no son meros adornos:

  • El tag [P] (Parallel): Le indica al motor de ejecución que esas tareas son independientes y se pueden realizar en paralelo por diferentes subagentes (por ejemplo, crear la tabla de la base de datos y preparar los datos de prueba).
  • Los IDs de tarea ([T001], [T002]): Sirven para que el agente de implementación sepa exactamente qué está haciendo y pueda actualizar el estado de forma atómica.

Durante la fase de codificación real (/speckit.implement), el agente irá marcando el estado de cada tarea usando una sintaxis que soporta pausas e interrupciones:

  • [ ] - Tarea pendiente.
  • [>] - Tarea en ejecución (el agente está trabajando en ella ahora mismo).
  • [x] - Tarea completada con éxito.
  • [!] - Tarea fallida o bloqueada (si el test falla o hay un error de compilación).

6. Paso 5: /speckit.analyze (El último guardián)

Antes de permitir que el agente de implementación empiece a escribir código, tenemos un último paso de seguridad opcional pero súper recomendable:

/speckit.analyze

El comando de análisis realiza una auditoría cruzada de consistencia entre todos los archivos que acabamos de generar. Compara spec.md (lo que pide el negocio), plan.md (la solución técnica diseñada), tasks.md (los pasos de ejecución) y la Constitución del repositorio.

Si la IA detecta que en la especificación se pedía que «el sistema debe permitir notas especiales como mesa al lado de la ventana», pero en el data-model.md no has definido ninguna columna de texto para guardar comentarios en la tabla de reservas, el analizador detendrá el flujo en seco y generará una alerta de discrepancia crítica. Te tocará ajustar el plan de base de datos antes de programar.


Resumen del flujo: Tu rol en este pipeline

Fíjate en cómo ha cambiado tu forma de trabajar con este walkthrough. En lugar de estar dos horas peleándote con la sintaxis de Express o depurando por qué un objeto SQL devuelve un undefined en la consola, has dedicado quince minutos a:

  1. Definir las reglas de juego lógicas usando una sintaxis robusta (EARS).
  2. Resolver dudas de negocio reales antes de que se conviertan en bugs de código.
  3. Auditar que el diseño técnico respeta las leyes de tu repositorio.

El código resultante que generará la IA en el siguiente paso (/speckit.implement) será limpio, seguro, estará probado de entrada y encajará perfectamente en tu arquitectura. Has dejado de picar código para empezar a diseñar contratos lógicos.

En el siguiente artículo, La Entrevista de Requisitos y el Bucle "SpecOps": Cómo usar la IA de Sparring y rehacer código sin dolor daremos un paso más allá en la automatización extrema. Veremos cómo herramientas como Google Antigravity y el Protocolo de Contexto de Modelos (MCP) llevan este flujo a un entorno blindado, ejecutando las pruebas en sandboxes aislados y dejando que la IA interactúe con navegadores reales en local para autocorregir sus propios fallos de interfaz antes de abrir la Pull Request. ¡Nos vemos en el próximo artículo!


📚 Serie Spec-Driven Development (SDD)

  1. Spec-Driven Development (SDD): Gobernanza de Agentes IA y el Fin del 'Vibe Coding'
  2. El Chasis de la Gobernanza: Constitución vs. AGENTS.md (Y cómo no ahogarte en deuda de sincronización)
  3. El Pipeline SDD en la Práctica: De la Sintaxis EARS a las Tareas Atómicas
  4. La Entrevista de Requisitos y el Bucle "SpecOps": Cómo usar la IA de Sparring y rehacer código sin dolor
  5. El Reto del Código Existente (Brownfield) y la Gestión de Múltiples Specs con Jira/Git
  6. Google Antigravity y MCP: Sandboxing, Autocorrección y la Nube