Saltar al contenido
Nm NoumorDevs

Fundamentos · 01

Spec-Driven Development: diseñar antes de escribir

Spec-Driven Development (SDD) es una forma de construir software donde la unidad de trabajo no es la tarea ni el ticket, sino la especificación: un artefacto versionado, verificable y ejecutable que describe qué debe cumplir una pieza de software y cómo se comprueba que lo cumple.

Definición

Qué es exactamente

En SDD, la especificación es el contrato entre el problema y la solución. No es un documento muerto: vive en el repositorio, se revisa como código, se valida con pruebas y sirve como fuente única para humanos y agentes.

El trabajo fluye así: se escribe una spec, se revisa, se descompone en diseño y tareas, se implementa (por personas, por agentes o mixto), y se valida contra la propia spec. Toda la trazabilidad vive junto al código.

Comparativa

SDD frente al desarrollo tradicional

Diferencias entre desarrollo tradicional y Spec-Driven Development
DimensiónTradicionalSpec-Driven
Unidad de trabajoTicket / tareaSpec versionada
Fuente de verdadEl código ya escritoLa spec y sus pruebas
Rol de la IAAutocompletar líneasPlanificar, implementar y validar contra spec
RevisiónPR sobre el códigoPR sobre la spec + PR sobre el código
TrazabilidadTickets de JiraSpec ↔ tests ↔ commits
QACasos definidos tardeCriterios en la spec desde el día 0
Riesgo típicoDrift entre doc y códigoSpecs demasiado detalladas

Ciclo de vida

Las cinco fases del ciclo SDD

  1. 01

    Descubrir

    Entender el problema real y acotarlo con el negocio.

  2. 02

    Especificar

    Redactar la spec con contratos y criterios verificables.

  3. 03

    Diseñar

    Modelar módulos, interfaces y riesgos antes de implementar.

  4. 04

    Ejecutar

    Implementar con humanos y/o agentes guiados por la spec.

  5. 05

    Validar

    Comprobar que el sistema cumple la spec y cerrar el ciclo.

Artefactos

Qué contiene una spec bien hecha

  • 01.Contexto y objetivo. Por qué existe y qué cambia si se resuelve.
  • 02.Alcance y no-alcance. Límite explícito del problema.
  • 03.Casos de uso. Entradas, salidas y actores.
  • 04.Contratos. APIs, eventos, esquemas.
  • 05.Criterios de aceptación. Verificables, no subjetivos.
  • 06.Riesgos y supuestos. Dependencias y decisiones pendientes.
  • 07.Plan de validación. Cómo se comprueba que cumple.
spec/orders/create-order.spec.mdmarkdown
# Crear pedido

## Objetivo
Permitir que un cliente autenticado cree un pedido a partir de su carrito.

## Alcance
- Validar stock y precio.
- Registrar el pedido en estado PENDIENTE_PAGO.
- Emitir evento `order.created`.

## No alcance
- Procesamiento del pago (lo hace otro servicio).
- Gestión de devoluciones.

## Contrato
POST /orders
  body: { cartId: string, shippingId: string }
  200:  { orderId: string, total: number, currency: 'EUR' }
  409:  { code: 'STOCK_INSUFFICIENT', items: string[] }

## Criterios de aceptación
- [ ] Dado carrito válido, devuelve 200 con orderId.
- [ ] Si falta stock de un item, devuelve 409 con el detalle.
- [ ] Se emite un único evento `order.created` por pedido.
- [ ] Es idempotente respecto al cartId durante 15 minutos.

Integración con IA

Specs, agentes, prompts y ejecución

Una spec bien escrita es el mejor prompt posible. Describe el problema con precisión, deja explícitos los criterios de aceptación y sirve a un agente como brújula durante todo el ciclo de ejecución.

En un workflow agéntico, la spec alimenta al planner, guía al coder, da rúbrica al reviewer y define el oráculo del QA. Si la spec está mal, el agente entregará rápido algo mal hecho — que es el peor de los mundos.

Por eso en SDD la regla es simple: no hay código sin spec, no hay spec sin criterio de aceptación, no hay criterio sin validación automatizable.

Contrato de herramienta expuesto a un agente desde la spectypescript
// spec/agents/tools/create-order.tool.ts
export const createOrderTool = {
  name: 'create_order',
  description: 'Crea un pedido a partir de un carrito validado.',
  input: z.object({
    cartId: z.string().uuid(),
    shippingId: z.string().uuid(),
  }),
  output: z.object({
    orderId: z.string().uuid(),
    total: z.number().nonnegative(),
    currency: z.literal('EUR'),
  }),
  execute: async (i) => ordersService.create(i),
} satisfies AgentTool;

Antipatrones

Señales de que no estás haciendo SDD

Spec = PDF

Si la spec vive fuera del repo, no es spec: es documentación.

Criterios "que funcione"

Sin rúbrica no hay validación; hay opinión.

Spec escrita después

Si la spec se escribe cuando ya hay código, es un acta, no una guía.

Agente sin spec

Un agente sin rúbrica deriva; generará muchísimo código irrelevante.