Mi sistema de specs para Claude Code: cómo pasé de vibe coding a desarrollo predecible

El vibe coding funciona para prototipar. Para producción, a escala, con múltiples agentes trabajando en paralelo, no funciona.

Llevo meses desarrollando Archivo Final — una plataforma Django + Vertex AI para evaluación de manuscritos, seleccionada por Lanzadera en 2025 — con un sistema de 11 agentes especializados, 17 worktrees activos y más de 16 comandos personalizados. En el workflow real con Claude Code: 9 agentes, worktrees y 10 MCPs ya documenté la arquitectura base. Este artículo va un paso más allá: explica el sistema que introduje para que los agentes dejen de improvisar.

El cambio concreto fue añadir dos capas al ciclo de implementación: una spec técnica que define el contrato antes de escribir código, y un review de implementación que detecta desviaciones antes de llegar al QA. El resultado en el Issue #113 del sistema de créditos: spec de 230 líneas, 6 fases de implementación, 36 tests en verde, cero ciclos de QA adicionales necesarios.

Esto es lo que aprendí.


El problema con el vibe coding en proyectos reales

El vibe coding —desarrollar a golpe de prompt conversacional sin especificación previa— tiene una ventaja enorme: velocidad inicial. Le dices al agente lo que quieres, él improvisa una solución, tú la revisas, iteras. Para un prototipo de fin de semana, es perfectamente válido.

El problema aparece cuando el proyecto tiene estado: base de datos real, usuarios reales, tests que cubren comportamientos específicos, y agentes que trabajan en ramas paralelas sin coordinación explícita.

Qué ocurre cuando un agente IA no tiene contrato de implementación

Sin spec, el agente trabaja con la información disponible en el prompt de turno. Eso implica varios problemas que he visto repetidamente en Archivo Final:

  • Scope creep silencioso. El agente implementa features que no pediste porque “parecen útiles”. En el Issue #104, el agente cambió la lógica de autorización de la vista sin que estuviera en el plan. La implementación era razonable — y al final la aceptamos — pero no era parte del contrato.
  • Decisiones de implementación inconsistentes. Sin una arquitectura documentada, dos agentes trabajando en paralelo pueden tomar decisiones que colisionan al mergear.
  • QA en bucle. Si el agente no tiene criterios de éxito explícitos, el ciclo de revisión se alarga. Cada iteración añade contexto acumulado que degrada la calidad de las respuestas siguientes.

Por qué el Plan Mode de Claude Code no es suficiente

Claude Code tiene un modo de planificación integrado: antes de escribir código, el agente puede explorar el repositorio y proponer un plan. Es útil para sesiones únicas. El problema es que ese plan vive en la conversación. Cuando el agente abre un worktree nuevo, cuando el contexto se reinicia, cuando un segundo agente necesita hacer el review, el plan desaparece.

Lo que necesitaba era un plan que persistiera en disco, que el agente leyera al arrancar, y que sirviera también como referencia de auditoría post-implementación. Eso es exactamente lo que hace una spec técnica.


Qué es una spec técnica para agentes IA (y qué no es)

Una spec técnica (en mi sistema, issue_spec) es un documento Markdown persistente que define el contrato de implementación para un issue concreto. El agente la lee al inicio del worktree y la usa como referencia durante todo el ciclo. A diferencia del Plan Mode de Claude Code, la spec no vive en la sesión — vive en el repositorio, en .claude/sessions/issue_spec_NNN.md.

La spec no es un prompt. No es una descripción de usuario. No es un backlog de tareas.

Una spec es: qué hay que construir exactamente, en qué orden, con qué criterios de éxito verificables, y qué queda explícitamente fuera del scope.

La metodología SDD y por qué nació como respuesta al vibe coding ya lo expliqué en detalle en este artículo sobre desarrollo dirigido por especificaciones con IA. Aquí me centro en la implementación práctica.

Anatomía de un issue_spec: las secciones que no pueden faltar

Una spec completa en Archivo Final tiene esta estructura:

  1. Executive Summary — el cambio en una frase
  2. Problem Statement — qué está roto o falta, con referencias a archivos y líneas concretas del código actual
  3. Proposed Solution — arquitectura del cambio: qué capas afecta, qué componentes toca
  4. Core Capabilities (MoSCoW) — tabla con Must / Should / Could / Won’t
  5. Technical Design — secciones por agente especializado (@backend-developer, @django-config-migrations, etc.) con el diseño técnico detallado, incluyendo el código exacto que se espera
  6. Implementation Phases — el orden concreto de las fases
  7. Acceptance Criteria — criterios verificables que el agente puede comprobar por sí solo
  8. Tests requeridos — qué tests hay que escribir, con nombres de métodos

Las secciones 4, 7 y 8 son las más importantes para la calidad del resultado.

MoSCoW aplicado a agentes: cómo priorizar lo que el agente debe y no debe hacer

MoSCoW (Must / Should / Could / Won’t) es una técnica de priorización estándar en gestión de producto. Aplicada a specs para agentes tiene un uso específico: define el límite de lo que el agente puede implementar sin consultar.

Los Must son el contrato. Si no están implementados, la spec no está completa.
Los Should son deseables pero no bloqueantes.
Los Could son opcionales si el tiempo lo permite.
Los Won’t son tan importantes como los Must — documentan explícitamente qué queda fuera, para que el agente no lo implemente aunque “parezca lógico”.

En la spec del Issue #113 (sistema de créditos), el Won’t más importante era la integración con Stripe. Sin ese Won’t explícito, un agente orientado a completar la feature podría haber empezado a plantear la arquitectura de pagos.

Acceptance criteria: el criterio de éxito que el agente verifica por sí solo

Los acceptance criteria (AC) son afirmaciones verificables sobre el comportamiento esperado. El formato que uso es directo:

AC-01: Cuando un usuario sube un manuscrito, report_credits se decrementa en 1 antes de que el procesamiento comience.
AC-02: Cuando un manuscrito falla durante el procesamiento, report_credits se incrementa en 1 automáticamente.
AC-03: Los superusers no consumen créditos en ninguna operación.

Un buen AC puede convertirse directamente en un test. Si el agente puede leer el AC y escribir el test sin preguntar nada, la spec está bien escrita.


Cómo creo un issue_spec en Archivo Final (con ejemplo real)

El flujo empieza con el comando create-new-gh-issue. Le paso una descripción de la feature y el agente analiza el código actual, identifica los ficheros afectados, comprueba dependencias con otros issues en curso, y genera un issue estructurado en GitHub.

Lo que hace diferente a este flujo del issue estándar es que el cuerpo del issue en GitHub ya incluye el Problem Statement con referencias a archivos y líneas de código reales, la tabla MoSCoW, y el Technical Design con el código esperado. Cuando el issue está publicado en GitHub, genero la spec local (issue_spec_NNN.md) que amplía ese contenido con el diseño por agente especializado y los pasos de implementación.

El agente que implementará la feature arranca con el comando start-working-on-issue-new, que hace tres cosas: lee la spec completa, crea el worktree aislado (git worktree add .trees/feature-issue-NNN), y arranca en esa rama con el contexto completo del contrato de implementación.

Ejemplo completo: issue_spec_113.md — el sistema de créditos

El Issue #113 era una migración del sistema de créditos de Archivo Final: reemplazar report_count (contador incremental con límite fijo de 3) por report_credits (saldo decreciente). Un cambio aparentemente simple que afectaba a 10 ficheros, requería 3 migraciones secuenciales de base de datos, y tocaba la lógica de autorización en un punto crítico.

La spec resultó en 230+ líneas de documento técnico estructurado en 6 fases de implementación:

  1. Model Layer — añadir report_credits, preparar métodos
  2. Service Layer — nuevos métodos deduct_credit() y add_credits() con F expressions para seguridad en concurrencia
  3. Manuscript Service — deducción de crédito al crear el manuscrito, antes del procesamiento asíncrono
  4. Signals — refund automático en manuscritos fallidos o eliminados con @transaction.atomic
  5. Admin Actions — acciones bulk (+1/+5/+10/+20 créditos) con queryset.update()
  6. Templates y Cleanup — actualización de contexto en vistas, eliminación de FREEMIUM_REPORT_LIMIT

La spec incluía el código exacto de los métodos nuevos, incluyendo las justificaciones técnicas de cada decisión. Por ejemplo, el uso de F expressions en deduct_credit() para evitar race conditions cuando múltiples requests llegan simultáneamente:

updated = CustomUser.objects.filter(
    id=user.id,
    report_credits__gt=0
).update(report_credits=F('report_credits') - 1)

if updated == 0:
    raise ValueError(f"User {user.id} has no credits available")

El agente no necesita decidir cómo implementar esto — está en la spec. Lee el plan, escribe los tests, y marca los AC como completados.

Qué hace que una spec genere 0 ciclos de QA

El resultado del Issue #113 fue 36 tests en verde y ningún ciclo de QA adicional. No fue suerte — fue consecuencia directa de tres factores:

  1. Los AC eran directamente convertibles en tests. El agente podía leer “AC-01: cuando un usuario sube un manuscrito, report_credits se decrementa” y escribir el test correspondiente sin ambigüedad.
  2. Los Won’t eliminaron el scope creep. El agente no tocó la integración con Stripe porque la spec lo excluía explícitamente.
  3. El Technical Design incluía el código esperado. Para las secciones más delicadas (migración de datos, F expressions, signals con transacciones), la spec mostraba exactamente qué escribir y por qué.

El review de implementación: detectar desviaciones antes del QA

Una spec bien escrita no garantiza que el agente la siga al pie de la letra. Los agentes toman decisiones durante la implementación — a veces mejores que las planificadas, a veces problemáticas. El review de implementación es el mecanismo para auditar esas decisiones antes de llegar al QA.

El documento review_spec_NNN.md es generado por un segundo agente que no implementó el issue. Su trabajo es comparar el PR con la spec original y clasificar cada desviación.

Si buscas una comparativa con otros frameworks como BMAD, tienes el análisis en el artículo sobre BMAD Method vs. workflow de agentes IA.

Qué es un review_spec y por qué va antes del QA

El review_spec va después de que el PR está abierto y antes de que empiece el QA manual o automatizado. Su función es detectar dos tipos de problemas:

  • Problemas que hacen que el QA falle por razones incorrectas. Si el agente implementó algo diferente a lo especificado, el QA puede fallar no porque el código esté mal sino porque el tester espera un comportamiento diferente.
  • Decisiones de diseño que necesitan aprobación del producto antes de continuar. Un cambio de autorización no planificado puede ser técnicamente correcto pero estratégicamente incorrecto.

El review no es un bloqueo. Es un checkpoint para tomar decisiones informadas antes de gastar tiempo en QA.

Tipos de desviaciones: Approach Change, Missing, Gold Plating

El sistema de clasificación de desviaciones tiene cuatro categorías:

  • Approach Change — el agente implementó lo que se pedía pero con un enfoque técnico diferente al planificado. La funcionalidad existe, el resultado es equivalente.
  • Missing — algo especificado no fue implementado. Puede ser un Must (bloqueante) o un Should (no bloqueante).
  • Gold Plating — el agente implementó features no pedidas. Normalmente inofensivo, pero puede introducir complejidad no deseada.
  • Scope Creep — una variante del Gold Plating con impacto en la arquitectura o en la lógica de negocio. Requiere decisión explícita del producto.

Caso real: review_spec_104.md — 5 approach changes detectados en el Tab Lectores

El Issue #104 era la implementación del Tab “Lectores Expertos” en el informe de Archivo Final. La spec tenía 8 fases de implementación. El review detectó:

  • 5 Approach Changes en CSS, templates y JavaScript. Todos aceptados — el agente usó enfoques técnicamente equivalentes o mejores (por ejemplo, cambiar targetNav.click() por manipulación directa de classList, que es más explícito).
  • 1 Missing — los atributos aria-label y rel="noopener noreferrer" en el link de descarga. Era un Should en el MoSCoW, no un Must, así que no bloqueaba el QA.
  • 1 Scope Creep — un cambio no planificado en la lógica de autorización que permitía a industry_members ver cualquier informe. El review lo identificó, el producto lo evaluó y lo aceptó.

El veredicto final: Apto para QA con notas. El QA recibió el review con las desviaciones documentadas y pudo ajustar sus casos de prueba en consecuencia — por ejemplo, buscar “Áreas de mejora” en lugar de “Debilidades” porque el agente había cambiado esa etiqueta con criterio editorial.

Sin el review, el QA habría encontrado estas diferencias durante la validación manual y no habría sabido si eran bugs o decisiones intencionales. Con el review, cada desviación tenía ya una decisión tomada.


El QA loop automático: 3 ciclos con auto-fix

Después del review viene el QA. En Archivo Final el QA automatizado usa el MCP de concurrent browser (hasta 20 instancias en paralelo) para validar el comportamiento de la aplicación en múltiples escenarios simultáneamente. Cuando un test falla, el ciclo update-feedback activa un fix automático del agente.

El límite está en 3 ciclos. No más.

Cómo funciona el update-feedback con ciclos automáticos

El ciclo es simple: el QA identifica fallos, genera feedback estructurado, el agente lee el feedback y propone fixes, los fixes se aplican, el QA vuelve a ejecutar. Si después de 3 ciclos el QA sigue fallando, el proceso se detiene.

El número 3 no es arbitrario. Es una decisión de diseño basada en la observación del comportamiento de los LLMs con contexto acumulado.

Por qué 3 ciclos y no más (el principio de contexto acumulado)

Cuando un agente lleva varios ciclos de feedback acumulado en su contexto, la calidad de sus respuestas empieza a degradarse. El agente tiene demasiadas instrucciones contradictorias, demasiados estados intermedios en su ventana de contexto. Los fixes que propone en el ciclo 4 o 5 tienden a ser parches sobre parches, no soluciones reales.

Si el QA no pasa en 3 ciclos, el problema suele estar en uno de dos sitios: la spec era ambigua (el agente implementó algo diferente a lo esperado porque el contrato no era claro), o el scope del issue era demasiado grande para una sola implementación (hay que descomponerlo).

La respuesta correcta en ese caso no es añadir más ciclos. Es volver a la spec.


El ciclo completo: spec → worktree → implementación → review → QA

El sistema completo funciona así:

Paso 1 — Crear el issue como spec. El comando create-new-gh-issue genera un issue estructurado en GitHub con Problem Statement, MoSCoW, Technical Design y Acceptance Criteria. El agente analiza el código real antes de redactar la spec.

Paso 2 — Generar la spec local. A partir del issue de GitHub, se genera el archivo issue_spec_NNN.md en .claude/sessions/. Este documento amplía el issue con el diseño técnico por agente especializado y los pasos de implementación secuenciales.

Paso 3 — Arrancar en worktree. El comando start-working-on-issue-new crea la rama y el worktree aislado (git worktree add .trees/feature-issue-NNN) y carga la spec como contexto inicial del agente implementador.

Paso 4 — Implementar siguiendo la spec. El agente lee la spec al completo, implementa fase a fase, escribe los tests antes o junto con el código, y verifica los acceptance criteria antes de abrir el PR.

Paso 5 — Review de implementación. Un segundo agente genera el review_spec_NNN.md comparando el PR con la spec original. Clasifica todas las desviaciones. El producto toma decisiones sobre Scope Creep antes de pasar al QA.

Paso 6 — QA loop automático. El QA automatizado ejecuta hasta 3 ciclos de update-feedback. Si pasa: PR listo para merge. Si no pasa en 3 ciclos: se vuelve al Paso 2 con una spec revisada.

Cuándo saltarse la spec. Para bugs triviales (un typo, un cambio de configuración, una corrección de CSS menor) la spec es overhead innecesario. La regla que uso: si el cambio toca más de 2 ficheros o requiere decisiones de diseño no triviales, necesita spec.


Resultados: qué cambia cuando usas specs en tu workflow con IA

Los números del Issue #113 son el mejor argumento: spec de 230+ líneas, 6 fases de implementación que tocaron 10 ficheros y 3 migraciones de base de datos, 36 tests en verde, cero ciclos de QA adicionales. El tiempo invertido en escribir la spec se recuperó en el primer ciclo de implementación.

Más allá de los números, lo que cambió fue la naturaleza del trabajo. Con specs, mi tiempo como desarrollador lo dedico a tomar decisiones de diseño y a revisar que esas decisiones se implementaron correctamente — no a corregir alucinaciones ni a reconstruir el razonamiento del agente cuando una implementación no encaja con el sistema existente.

Los agentes no improvisan porque no tienen que hacerlo. Tienen un contrato. Lo ejecutan.


FAQ


Conclusión

El sistema de specs no es una solución mágica para los problemas de los agentes IA. Es un método para trasladar las decisiones de diseño al momento correcto — antes de implementar — y para tener un registro verificable de esas decisiones cuando el agente termina su trabajo.

Lo que ganas con las specs es predecibilidad. No velocidad inicial — esa la pierde el vibe coding cuando las cosas se complican. Sino la capacidad de estimar cuándo algo estará listo, confiar en que el agente no se saldrá del scope, y dedicar tu tiempo como desarrollador a lo que requiere juicio humano.

Si trabajas con Claude Code en proyectos reales y quieres implementar este sistema en tu equipo o proyecto, puedo ayudarte. Escríbeme y lo vemos.

Scroll al inicio