Back

Desarrollo Dirigido por Especificaciones: Cómo Dejar el Vibe Coding y Enviar Código Generado por IA Listo para Producción

Ya viste las demos. Un ingeniero escribe "construime un dashboard SaaS" en un agente de IA, y en tres minutos aparece una app React completa con auth, base de datos y flujo de pagos. Aplausos. El tweet se vuelve viral.

Después lo intentás en tu proyecto real, el que tiene 200 archivos, una capa de auth custom, tres integraciones con APIs externas y una estructura monorepo, y el agente reescribe tu esquema de base de datos con total confianza, borra un middleware crítico e introduce cuatro vulnerabilidades de seguridad antes de que puedas tocar Ctrl+C.

Esta es la brecha del vibe coding. La distancia entre "funciona en una demo" y "funciona en producción" no es un problema de herramientas. Es un problema de metodología. Y la metodología que cierra esta brecha tiene nombre: Desarrollo Dirigido por Especificaciones (SDD).

SDD no es escribir más documentación. Se trata de darle a los agentes IA exactamente las restricciones que necesitan para operar de manera confiable: archivos de spec, loops test-first y un flujo de 4 fases que reemplaza "generar y rezar" con "especificar, diseñar, dividir, implementar." Los equipos que adoptan SDD reportan consistentemente 60-80% menos regresiones generadas por IA y dramáticamente menos tiempo debugueando código que no escribieron.

Esta guía cubre la metodología completa: por qué el vibe coding falla a escala, el loop SDD de 4 fases, cómo estructurar archivos de spec (CLAUDE.md, cursor rules, AGENTS.md), integración de TDD con agentes IA y patrones de producción para orquestar agentes en codebases reales.


Por Qué el Vibe Coding Se Rompe

Seamos precisos sobre qué falla y por qué. El vibe coding, la práctica de prompt en lenguaje natural al agente y desplegar la salida inmediatamente, funciona sorprendentemente bien para prototipos greenfield. Pero falla sistemáticamente en codebases de producción por cuatro razones específicas:

1. El Problema del Colapso de Contexto

Los agentes IA son stateless. Cada nueva sesión empieza de cero. Tu proyecto de 200 archivos tiene conocimiento implícito embebido por todos lados: convenciones de naming, patrones de manejo de errores, el hecho de que userId en tu capa de auth es un UUID pero user_id en tu API legacy es un entero secuencial. Nada de esto existe en el contexto del agente a menos que se lo des explícitamente.

El vibe coding no provee mecanismo para esto. Escribís un prompt, el agente genera código basado en sus datos de entrenamiento, y el output sigue los patrones por defecto del agente, no los tuyos. El resultado es código que "funciona" aislado pero crea inconsistencias sutiles que se acumulan en drift arquitectural.

Colapso de Contexto en la Práctica:

  Tu proyecto:             Lo que genera el agente:
  ─────────────            ──────────────────────────
  camelCase en todo        snake_case en archivos nuevos
  Zod para validación      if-checks manuales
  Clases de error custom   Generic throw new Error()
  Patrón Repository        Llamadas directas a la DB
  Claves primarias UUID    Auto-increment integers

2. El Sesgo del Happy Path

Los LLMs están entrenados predominantemente con código de tutoriales, ejemplos de documentación y respuestas de Stack Overflow. Estos datos de entrenamiento demuestran abrumadoramente el "happy path": cuando todo sale bien. El resultado es código AI que maneja el flujo principal elegantemente pero se desmorona en los bordes:

  • ¿Timeouts de red? No manejados.
  • ¿Requests concurrentes al mismo recurso? Race conditions.
  • ¿Agotamiento del pool de conexiones a la DB? Crash.
  • ¿Input malformado del usuario? Sin validar.
  • ¿Rate limits de APIs externas? Ignorados.

Un estudio de Endor Labs de 2025 encontró que el 62% del código generado por IA contenía debilidades de seguridad o defectos de diseño, con 44-49% de las dependencias sugeridas por IA portando vulnerabilidades conocidas. El reporte Verizon DBIR 2025 encontró que la participación de terceros en brechas se duplicó al 30%, subrayando el riesgo creciente de código generado por IA sin verificar entrando en las cadenas de suministro de software.

3. El Vacío de Ownership

El vibe coding produce código que su supuesto dueño no entiende. El developer lo desplegó, pero no puede explicar el control flow, la estrategia de manejo de errores, o por qué se eligió una librería particular. Cuando aparecen bugs en producción a las 2 AM, se enfrentan a código escrito por una inteligencia alien con suposiciones diferentes sobre cómo se propagan los estados de error.

Esto no es una preocupación teórica: es la queja más común de los engineering managers sobre el desarrollo asistido por IA en 2026. El código funciona hasta que no funciona, y cuando no funciona, nadie puede arreglarlo rápido porque nadie lo entiende profundamente.

4. La Deuda Técnica Compuesta

Cada sesión de vibe coding agrega código que sigue los patrones implícitos del agente en lugar de los establecidos por el proyecto. Después de diez sesiones, no tenés un codebase: tenés una acumulación de diez estilos de codificación ligeramente diferentes, enfoques de manejo de errores y suposiciones arquitecturales. Esta deuda técnica se acumula exponencialmente porque cada nueva sesión de IA hereda la confusión de las anteriores.


El Loop SDD de 4 Fases

El Desarrollo Dirigido por Especificaciones reemplaza el paso único "prompt → código" con un loop de 4 fases que construye contexto antes de generar código. Cada fase produce un artefacto documental que el agente puede referenciar en fases posteriores.

El Loop SDD:

  Fase 1: REQUERIMIENTOS    ──→  requirements.md
       ↓                           "¿Qué estamos construyendo?"
  Fase 2: DISEÑO            ──→  design.md
       ↓                           "¿Cómo lo vamos a construir?"
  Fase 3: TAREAS            ──→  tasks.md
       ↓                           "¿Qué pasos exactos en qué orden?"
  Fase 4: IMPLEMENTACIÓN    ──→  código + tests
       ↓                           "Construir, testear, verificar."
       └──── FEEDBACK ──────→  Actualizar specs, repetir.

Fase 1: Requerimientos

Empezá cada feature haciendo que la IA te ayude a clarificar qué estás construyendo. No pidas código: pedí un análisis de requerimientos.

Prompt a tu agente IA: "Necesito agregar un sistema de invitación de equipos a nuestra app SaaS. Antes de escribir código, creá un requirements.md que cubra: - User stories para el flujo de invitación - Edge cases (invitaciones expiradas, emails duplicados, conflictos de roles) - Requerimientos de seguridad (rate limiting, validación de tokens) - Puntos de integración con nuestro sistema de auth existente - Lo que NO estamos construyendo en esta fase"

La restricción "lo que NO estamos construyendo" es crítica. Sin límites de scope explícitos, los agentes IA tienden a sobre-construir: agregan features que nadie pidió, introducen abstracciones prematuras y expanden el scope hasta que el cambio toca la mitad del codebase.

Fase 2: Diseño

Con los requerimientos fijados, traducilos en decisiones técnicas. De nuevo, todavía nada de código: solo arquitectura.

Prompt a tu agente IA: "Leé requirements.md. Ahora creá un design.md que cubra: - Cambios de esquema de DB (tablas/columnas, con estrategia de migración) - Endpoints de API (método, path, shapes de request/response) - Arquitectura de service layer (funciones, dependencias) - Estrategia de manejo de errores (errores, códigos HTTP, mensajes) - Máquina de estados del ciclo de vida de invitación Referenciá nuestros patrones existentes en src/services/ y src/api/. NO escribas código de implementación."

Esta fase atrapa errores arquitecturales antes de que exista código. Arreglar un documento de diseño es infinitamente más barato que debuguear una feature medio implementada.

Fase 3: Tareas

Descomponé el diseño en pasos de implementación discretos, ordenados por dependencia. Cada tarea debe ser lo suficientemente chica para que el agente la complete en una sola sesión enfocada.

tasks.md ejemplo: ## Sistema de Invitación de Equipos — Tareas de Implementación ### Capa de Base de Datos - [x] Task 1 (S): Crear migración `team_invitations` - Columnas: id, team_id, email, role, token, status, expires_at - Tests: migración up/down, validación de constraints ### Capa de Servicios - [ ] Task 2 (M): Implementar `InvitationService.create()` - Depende de: Task 1 - Valida: formato de email, chequeo de duplicados, límite de miembros - Tests: happy path, rechazo de duplicados, enforcement de límite - [ ] Task 3 (M): Implementar `InvitationService.accept()` - Depende de: Task 2 - Valida: token existe, no expirado, no ya aceptado - Tests: aceptación válida, token expirado, token ya usado ### Capa de API - [ ] Task 4 (M): POST /api/teams/:id/invitations - Depende de: Task 2 - Auth: requiere rol de team admin - Tests: 201 success, 403 no-admin, 409 duplicado, 429 rate limit - [ ] Task 5 (M): POST /api/invitations/:token/accept - Depende de: Task 3 - Auth: debe estar logueado, email debe coincidir con invitación - Tests: 200 success, 404 token inválido, 410 expirado

Fase 4: Implementación

Ahora, y recién ahora, la IA escribe código. Pero en vez de un prompt masivo único, le das una tarea a la vez, con contexto completo:

Prompt a tu agente IA: "Leé requirements.md, design.md y tasks.md. Implementá Task 2: InvitationService.create() Requerimientos: - Seguí nuestro patrón de servicio existente en src/services/TeamService.ts - Usá Zod para validación de input - Usá nuestra clase custom AppError para manejo de errores - Escribí tests primero (archivo de test, después implementación) - Ejecutá tests después de implementar para verificar NO modifiques ningún archivo existente excepto para agregar imports. NO implementes las tasks 3-5 todavía."

Las restricciones en este prompt hacen el trabajo pesado. "Seguí nuestro patrón existente" previene el colapso de contexto. "Escribí tests primero" fuerza TDD. "NO modifiques archivos existentes" previene el refactoring "amable" del agente. "NO implementes tasks 3-5" previene el scope creep.


Estructurando tus Archivos de Spec

El loop SDD depende de contexto persistente: archivos que sobreviven entre sesiones y le dicen a cada agente cómo comportarse en tu proyecto.

CLAUDE.md / Cursor Rules / AGENTS.md

Estos archivos sirven el mismo propósito en diferentes herramientas: son el "documento de briefing" del proyecto que la IA lee al inicio de cada sesión.

# CLAUDE.md (o .cursor/rules, o AGENTS.md) ## Visión General del Proyecto Plataforma SaaS de e-commerce construida con Next.js 16, TypeScript, Drizzle ORM, PostgreSQL. Monorepo gestionado con Turborepo. ## Stack Tecnológico - Framework: Next.js 16 (App Router, Server Components) - Lenguaje: TypeScript 6.0 (strict mode) - Base de datos: PostgreSQL 17 + Drizzle ORM - Validación: Zod v3 - Estilos: Tailwind CSS v4 - Testing: Vitest + Playwright - Auth: JWT custom + rotación de refresh tokens ## Reglas de Arquitectura 1. Todo acceso a DB va a través de clases repository en src/repositories/ 2. La lógica de negocio vive en clases de servicio en src/services/ 3. Las rutas de API son controladores delgados que llaman a servicios 4. Todos los inputs se validan con esquemas Zod en src/schemas/ 5. Los errores usan la clase custom AppError (ver src/lib/errors.ts) 6. Todos los IDs son UUIDs generados con crypto.randomUUID() ## Convenciones de Código - Usá named exports, no default exports - Tipos de retorno explícitos en todas las funciones públicas - Patrón de mensajes de error: "[Entidad].[acción] failed: [razón]" - Nombres de archivos: kebab-case. Clases: PascalCase - Imports: agrupar por externos → internos → tipos ## Warnings Críticos - NUNCA usés tipo `any`. Usá `unknown` con type narrowing. - NUNCA usés default exports. Solo named exports. - NUNCA modifiques archivos de migración. Creá nuevos para cambios. - NUNCA comitees archivos .env. Usá .env.example para documentación.

Principio Clave: Ruteá, No Volcás

Mantené tu archivo root de spec debajo de 200-300 líneas. Debe decirle al agente qué hacer y dónde encontrar más info, no contener cada regla del proyecto.

## Documentos de Referencia - Decisiones de arquitectura: /docs/architecture.md - Convenciones de API: /docs/api-conventions.md - Esquema de base de datos: /docs/schema.md - Specs de features: /docs/specs/[nombre-feature].md

El agente lee el archivo root, después lee los documentos referenciados on-demand cuando trabaja en áreas relevantes. Es revelación progresiva: el mismo principio de UX que hace buen software, aplicado a la gestión de contexto de IA.

Reglas Por Directorio

Muchas herramientas de IA soportan reglas con scope por directorio. Usalas para restricciones específicas del dominio:

# src/services/.rules (o src/services/.cursorrules) ## Reglas del Service Layer - Todos los métodos de servicio deben ser async - Los servicios reciben dependencias por inyección en el constructor - Los servicios no deben importar desde src/api/ (sin deps circulares) - Cada método público debe tener un test correspondiente - Usá transacciones para operaciones multi-tabla - Logueá entrada y salida de operaciones críticas con logger.info()

TDD con Agentes IA: El Loop Red-Green-Refactor

El TDD no solo es compatible con agentes IA: es el flujo de trabajo ideal para ellos. Los tests proveen lo único que los agentes necesitan desesperadamente: una definición objetiva y verificable de "correcto."

Por Qué TDD Funciona Mejor Con IA Que Sin Ella

Sin tests, le pedís a la IA que genere código y después lo revisás manualmente buscando errores. Esto es cognitivamente agotador y propenso a errores.

Con TDD, definís la corrección primero, después dejás que la IA genere código hasta que los tests pasen. No estás revisando detalles de implementación: estás revisando resultados. La suite de tests es tu verificador automático.

Flujo Tradicional (frágil):
  Prompt → Código → Revisión Manual → "¿Se ve bien?" → Deploy → Bug

Flujo TDD (confiable):
  Spec → Test (falla) → Prompt IA → Código → Correr Tests → ¿Pasa? → Deploy
                                                    ↓
                                                 Falla → IA itera automáticamente

El Patrón Spec → Test → Implementación

Paso 1: Escribí el spec del test (humano guía)

// __tests__/services/invitation-service.test.ts import { describe, it, expect, beforeEach } from 'vitest'; import { InvitationService } from '@/services/invitation-service'; describe('InvitationService.create', () => { it('debería crear una invitación con email y rol válidos', async () => { const result = await service.create({ teamId: 'team-uuid-1', email: '[email protected]', role: 'member', invitedBy: 'admin-uuid-1', }); expect(result.id).toBeDefined(); expect(result.status).toBe('pending'); expect(result.token).toHaveLength(64); expect(result.expiresAt).toBeInstanceOf(Date); }); it('debería rechazar invitaciones duplicadas para el mismo email', async () => { await service.create({ teamId: 'team-uuid-1', email: '[email protected]', role: 'member', invitedBy: 'admin-uuid-1' }); await expect( service.create({ teamId: 'team-uuid-1', email: '[email protected]', role: 'member', invitedBy: 'admin-uuid-1' }) ).rejects.toThrow('Invitation.create failed: duplicate invitation'); }); it('debería imponer el límite de miembros del equipo', async () => { await expect( service.create({ teamId: 'full-team', email: '[email protected]', role: 'member', invitedBy: 'admin-uuid-1' }) ).rejects.toThrow('Invitation.create failed: team member limit reached'); }); });

Paso 2: Dejá que la IA implemente (agente guía)

El agente genera código, corre los tests, ve fallos e itera automáticamente. Es el loop Red-Green, pero la IA es la que cicla. Vos definiste el "qué" (tests), y la IA resuelve el "cómo" (implementación).

Paso 3: Revisión humana (enfocada en resultados)

Una vez que pasan los tests, revisá la implementación para: ¿sigue los patrones del proyecto? ¿Hay concerns de performance? ¿Hay concerns de seguridad? Estás revisando con propósito, no escaneando línea por línea código desconocido esperando encontrar un bug.


Patrones de Fallo y Cómo SDD los Previene

Patrón de FalloCausa RaízPrevención SDD
Colapso de contextoEl agente no conoce las convencionesCLAUDE.md con reglas de arquitectura y convenciones
Sesgo del happy pathNo genera manejo de erroresTests definen explícitamente escenarios de error
Scope creepSobre-construye o toca código no relacionadoDesglose de tareas con restricciones "NO" explícitas
Drift arquitecturalUsa sus patrones, no los tuyosDocumento de diseño + reglas por directorio
RegresiónCódigo nuevo rompe funcionalidad existenteFlujo test-first atrapa regresiones inmediatamente
Agujeros de seguridadNo considera el modelo de amenazasRequerimientos de seguridad + test cases de seguridad
Vacío de ownershipSe despliega código sin entenderloRevisión de diseño fuerza comprensión antes de implementar
Deuda técnicaPatrones inconsistentes entre sesionesCLAUDE.md asegura consistencia en cada sesión

Flujo de Producción: Poniéndolo Todo Junto

Acá va el flujo SDD completo del mundo real, desde el pedido de feature hasta el merge:

1. Brief del Feature

## Feature: Gestión de Roles de Equipo Los usuarios necesitan poder cambiar roles de miembros del equipo (admin → miembro, miembro → admin) y eliminar miembros. Solo los admins del equipo deberían poder realizar estas acciones.

2. Requerimientos Asistidos por IA

Prompt: "Leé el brief del feature arriba y nuestro sistema de auth existente en src/services/auth-service.ts. Generá requirements.md cubriendo user stories, edge cases, requerimientos de seguridad y lo que NO estamos construyendo. Considerá: ¿qué pasa cuando el último admin intenta cambiar su propio rol?"

3. Diseño Asistido por IA

Prompt: "Leé requirements.md. Creá design.md con cambios de schema de DB, endpoints de API, métodos de servicio y un diagrama de estados para transiciones de roles. Seguí los patrones de nuestro codebase existente. Marcá cualquier decisión de diseño que necesite revisión humana."

4. Checkpoint de Revisión Humana

Este es el momento crítico de human-in-the-loop. Revisá el documento de diseño:

  • ¿Tiene sentido el schema de la base de datos?
  • ¿Los endpoints de API son RESTful y consistentes con nuestra API existente?
  • ¿La IA capturó el edge case del "último admin"?
  • ¿Hay implicaciones de seguridad que la IA no vio?

Se hacen correcciones al documento de diseño antes de escribir una sola línea de código.

5. Desglose de Tareas Asistido por IA

Prompt: "Leé requirements.md y design.md. Creá tasks.md con pasos de implementación ordenados y con dependencias. Cada tarea debe incluir sus requerimientos de cobertura de tests."

6. Implementación Iterativa

Prompt: "Implementá Task 1 de tasks.md. Escribí tests primero, después la implementación. Corré tests para verificar. Marcá la tarea como completa en tasks.md cuando termines. NO avances a Task 2."

Repetir para cada tarea. Cada tarea se puede revisar independientemente, haciendo el code review manejable en vez de enfrentar un solo PR masivo.

7. Verificación de Integración

Prompt: "Todas las tareas en tasks.md están completas. Corré la suite de tests completa con `pnpm test`. Si hay fallos, arreglalos. Después corré `pnpm lint` y arreglá cualquier issue."

Escalando SDD: Patrones de Equipo

Repositorio Compartido de Specs

Para equipos, mantené los archivos de spec en control de versiones junto al código:

project/
├── .claude/
│   └── rules/
│       ├── general.md
│       ├── api-conventions.md
│       └── testing.md
├── docs/
│   └── specs/
│       ├── team-invitations/
│       │   ├── requirements.md
│       │   ├── design.md
│       │   └── tasks.md
│       └── role-management/
├── CLAUDE.md
├── AGENTS.md
└── src/

Template de PR para Trabajo AI-Asistido

Exigí que los PRs con código generado por IA referencien su spec:

## Checklist de PR (AI-Asistido) - [ ] Spec de feature existe en /docs/specs/[nombre-feature]/ - [ ] requirements.md revisado y aprobado por tech lead - [ ] design.md revisado y aprobado por tech lead - [ ] Todas las tareas en tasks.md completadas y chequeadas - [ ] Cobertura de tests: todos los paths de requirements testeados - [ ] Sin modificaciones a archivos fuera del scope del feature - [ ] `pnpm test` pasa - [ ] `pnpm lint` pasa

Métricas que Importan

MétricaAntes de SDDDespués de SDDPor Qué Importa
Regresiones IA por sprint8-151-3Medida directa de calidad de código
Tiempo de debug de código IA2-4 horas/bug15-30 min/bugReducción del vacío de ownership
Tiempo de review de PR45-60 min15-20 minEficiencia de revisión
Tiempo total de deliveryIgual (coding rápido, debug lento)30-40% más rápido netoGanancia real de productividad
Issues de seguridad detectados20-30% tasa de captura80-90% (tests + spec)Mejora de seguridad

Objeciones Comunes (y Respuestas)

"SDD es solo más overhead de documentación"

No. Los documentos SDD son generados por la IA, revisados por vos, y consumidos por la IA. El esfuerzo total de documentación humana es 10-15 minutos por feature (tiempo de revisión). La alternativa es 2-4 horas por bug debugueando código que no entendés.

"Mi proyecto es muy chico para esto"

Si tu proyecto es lo suficientemente chico como para tener todo el codebase en tu cabeza, el vibe coding puede funcionar. SDD se vuelve esencial cuando el codebase excede tu memoria de trabajo: aproximadamente 10-20 archivos con lógica interconectada.

"Los tests enlentecen el desarrollo"

Los tests enlentecen la primera hora. Aceleran todas las horas siguientes. Con agentes IA, este trade-off es aún más favorable: el agente escribe la implementación para matchear tus tests, generalmente acertando en el primer o segundo intento. Escribir tests lleva 5-10 minutos para humanos; la implementación le lleva a la IA 30-60 segundos.

"Solo necesito escribir mejores prompts"

La calidad del prompt importa, pero los prompts son efímeros. Desaparecen cuando la sesión termina. Los archivos de spec de SDD persisten, mejoran con el tiempo y funcionan entre diferentes herramientas de IA. Tu CLAUDE.md no solo ayuda a la sesión de hoy: ayuda a cada sesión, cada miembro del equipo y cada herramienta de IA.


El Modelo de Madurez

Los equipos que adoptan SDD típicamente progresan por tres etapas:

Etapa 1: Reactiva (La mayoría de los equipos hoy)

  • Usan IA para generación de código con prompts ad-hoc
  • Debuguean frecuentemente, reviews dolorosos
  • Sin archivos de contexto persistente
  • Cada sesión empieza de cero

Etapa 2: Estructurada (Adopción de SDD)

  • CLAUDE.md / AGENTS.md establecidos
  • Loop de 4 fases para features complejos
  • TDD integrado con workflows de IA
  • Reglas por directorio para restricciones de dominio
  • Revisión de diseño antes de implementación

Etapa 3: Sistemática (Madurez SDD completa)

  • Repositorio de specs mantenido junto al código
  • Agentes IA actualizan documentos de spec mientras trabajan
  • Métricas trackeadas y optimizadas
  • Onboarding de nuevos miembros via docs de spec
  • Consistencia entre herramientas (Cursor, Claude Code, Copilot siguen las mismas specs)

La mayoría de los equipos puede llegar a la Etapa 2 en un solo sprint. La Etapa 3 se desarrolla naturalmente en 2-3 meses a medida que los archivos de spec se acumulan y los patrones se estabilizan.


La Realidad de Ingeniería

Los agentes de IA son las herramientas más poderosas que hemos tenido para producir código rápido. También son las más poderosas para producir bugs rápido. La diferencia entre ambos resultados no es el modelo, el prompt ni la herramienta: es la metodología.

El vibe coding trata a la IA como reemplazo de la disciplina de ingeniería. SDD trata a la IA como amplificador de la disciplina de ingeniería. El loop de 4 fases no es burocracia. Es el mismo proceso que los senior devs siempre siguieron, ahora hecho explícito para que los agentes también lo sigan.

Tu agente IA es el junior más productivo que jamás contrataste. SDD es cómo lo onboardeás correctamente: con requerimientos claros, patrones documentados, tareas definidas y criterios de aceptación verificables. Salteate el onboarding y obtenés el caos del que todos se quejan. Invertí en el onboarding y obtenés el multiplicador de productividad con el que todos sueñan.

La elección no es si usar agentes de IA. La elección es si usarlos con disciplina de ingeniería o sin ella. SDD hace esa elección obvia.

AIDeveloper ProductivitySoftware EngineeringCoding AgentsTDDBest Practices

Explora herramientas relacionadas

Prueba estas herramientas gratuitas de Pockit