Qué hace que un spec produzca código funcional
Algunos specs producen código en un shot. Otros llevan al agente a loops infinitos donde cada iteración produce código distinto pero nunca correcto. La diferencia rara vez es el tamaño del spec — es su precisión en tres puntos específicos.
Specs funcionales = tipos explícitos + estados explícitos + criterios binarios.
Los tres puntos críticos
1. Tipos de datos explícitos
Mal: "el endpoint recibe el email y role del usuario."
Bien: "{email: string (RFC5322), role: 'admin' | 'member'}."
La diferencia: ambigüedad vs. claridad. El agente no adivina.
2. Estados y transiciones explícitos
Mal: "el usuario ve el pago."
Bien: "invoice tiene estados draft | sent | paid | overdue | void. Transiciones: draft → sent (cuando se envía), sent → paid (cuando llega webhook de stripe), sent → overdue (30 días sin pagar), cualquiera → void (admin)."
Estados escondidos producen bugs escondidos.
3. Criterios de aceptación binarios
Mal: "la UI debe verse profesional."
Bien: "el botón primario usa --cobalt-800, padding 0.75rem × 1.3rem, hover --cobalt-600, transición 180ms."
Binario = verificable sin opinión.
La señal del loop
Le pides al agente implementar, revisa output, le dices "no, así no", iteras 4 veces. Si eso pasa, el spec no era el problema: el problema era que el spec era opinión disfrazada de especificación.
Arreglo: escribir el spec asumiendo que quien lo lee no conoce tu contexto. Si "profesional" aparece sin definirlo, reemplaza por decisión concreta.
De los últimos 3 features que iteraste > 2 veces con agente, revisa los specs. ¿Dónde había ambigüedad? Escribe una versión corregida, sin opinión.
- Specs funcionales: tipos explícitos + estados explícitos + criterios binarios.
- Loops infinitos casi siempre vienen de opinión ("profesional", "rápido", "intuitivo").
- Escribe asumiendo que quien lee no conoce tu contexto.