Llevo meses integrando agentes CLI en pipelines de producción y he topado contra el mismo muro decenas de veces. Diseñar una especificación técnica monolítica antes de escribir código funciona bien sobre el papel. Sin embargo, cuando sueltas a un agente autónomo sobre un repositorio complejo, las specs estáticas se desmoronan al primer imprevisto arquitectónico.
El error recurrente es asumir que el agente debe limitarse a obedecer un documento inmutable de tres mil palabras. Cuando aparecen dependencias no compatibles, APIs cambiantes o fallos en el runtime, el modelo intenta forzar la implementación para cumplir la especificación a ciegas. Termina rompiendo interfaces adyacentes o degradando el diseño original.
Para solucionar este desajuste he refinado una metodología que denomino Dynamic Workflows con sdd claude code. En lugar de congelar los requisitos en un archivo estático, la especificación se convierte en un árbol vivo. Claude Code genera subespecificaciones acotadas durante la ejecución, evalúa los contratos contra suites de testing automatizadas y reajusta la spec antes de validar cada pull request. Te voy a mostrar la arquitectura técnica y los comandos que utilizo para poner este sistema a funcionar.
El colapso de las especificaciones estáticas en terminal
Cuando publiqué mi enfoque sobre Spec-Driven Development con Claude Code, defendí que ningún agente debía generar código sin un contrato previo de diseño y testing. Sigo manteniendo esa premisa. No obstante, en proyectos de gran escala, redactar todos los casos límite de antemano es inviable para el desarrollador humano.
Las specs fijas sufren una desconexión inevitable con el estado real del repositorio. Si la spec dicta utilizar una librería de parsing específica que falla en el runtime de destino, el agente se queda atrapado en un bucle intentando parches inútiles. La aproximación tradicional de sdd claude code delega demasiada carga predictiva en el prompt inicial.
Spec Monolítica Estática ──> Claude Code ──> Falla Runtime ──> Alucinación/Parche roto
│
└──> Bucle ciego sin actualizar contrato
El flujo dinámico altera esta dinámica por completo. La especificación principal (Master Spec) define únicamente invariantes arquitectónicos, objetivos de negocio y restricciones de seguridad. Las implementaciones intermedias se descomponen en micro-especificaciones de corto alcance que el propio motor de sdd claude actualiza tras recibir feedback de los linters y compiladores. Si un supuesto técnico resulta erróneo, el agente modifica la subespecificación antes de insistir con el código fuente.
Al contrastar este modelo dinámico con estructuras rígidas, se aprecia una gran diferencia operativa respecto al enfoque orquestado de BMAD Method vs Workflow de Agentes IA. Aquí no gestionamos un ejército de agentes dispersos con prompts inconexos. Utilizamos una única instancia de Claude Code guiada por contratos técnicos mutables que se validan a sí mismos en la terminal.
Arquitectura de un flujo adaptativo con sdd claude code
Para implementar este sistema necesitamos dividir el espacio de trabajo en cuatro capas acopladas mediante scripts deterministas:
┌────────────────────────────────────────────────────────┐
│ Master Spec (Invariantes, contratos globales) │
└──────────────────────────┬─────────────────────────────┘
▼
┌────────────────────────────────────────────────────────┐
│ Spec Engine (Generador de Sub-specs dinámicas) │
└──────────────────────────┬─────────────────────────────┘
▼
┌────────────────────────────────────────────────────────┐
│ Worker (Claude Code: Código + Tests unitarios) │
└──────────────────────────┬─────────────────────────────┘
▼
┌────────────────────────────────────────────────────────┐
│ QA Loop Autónomo (Vitest, TSC, Linters, Cobertura) │
└────────────────────────────────────────────────────────┘
El ciclo se apoya en tres conceptos esenciales que diferencian este flujo de una sesión estándar de codificación asistida:
- Master Spec Inmutable: Contiene exclusivamente las firmas públicas de la API, presupuestos de rendimiento, tipados globales y dependencias autorizadas. Claude Code tiene permisos de solo lectura sobre este documento.
- Sub-specs Adaptativas: Archivos Markdown temporales generados en una carpeta interna
.specs/active/. Cada sub-spec resuelve un único ticket técnico y define sus propios criterios de aceptación antes de generar código fuente. - QA Gates Predictivos: Scripts ejecutados vía hooks locales que analizan no solo si los tests pasan, sino si el diff introducido respeta la sub-spec activa.
Al utilizar sdd claude code bajo esta arquitectura evitamos que el agente tome decisiones arquitectónicas globales por su cuenta. Si durante la ejecución se descubre una inconsistencia en la base de datos o en un adaptador de red, el modelo detiene la escritura de código. Luego genera un borrador de cambio en la sub-spec y solicita aprobación o ejecuta una batería de pruebas de aislamiento para validar la nueva dirección técnica.
Configuración del entorno y hooks para Claude Code
Para trasladar este planteamiento a la práctica, configuro el archivo CLAUDE.md en la raíz del proyecto. Este archivo actúa como el sistema operativo mental del agente. Le prohíbo terminantemente editar archivos en src/ si no existe una sub-spec aprobada en .specs/active/.
Este es el extracto exacto de configuración que utilizo para activar el flujo adaptativo:
## Protocolo de Desarrollo SDD Adaptativo
Eres un desarrollador senior operando bajo la metodología SDD Dinámica.
Tu objetivo es implementar tareas respetando rigurosamente los contratos definidos.
## Reglas Inviolables
1. NUNCA toques archivos dentro de `src/` sin haber creado o actualizado la sub-spec en `.specs/active/<ticket>.md`.
2. Lee siempre `specs/master-contract.md` antes de tomar cualquier decisión de diseño.
3. Si un test falla debido a una incompatibilidad de arquitectura externa:
a. Documenta la causa raíz en la sub-spec.
b. Actualiza la propuesta técnica dentro de `.specs/active/<ticket>.md`.
c. Ejecuta `npm run test:verify-spec -- --ticket=<ticket>` antes de volver a escribir código.
4. Cada cambio en código debe ir precedido por su correspondiente test en rojo (TDD estricto).
Acompaño esta configuración con una herramienta CLI local escrita en Node.js que orquesta el bucle de validación. Esta herramienta compara el AST del código generado frente a los contratos de tipo estipulados en la sub-spec. Si el modelo altera una firma pública sin haber registrado el cambio en la sub-spec, el pipeline aborta la ejecución antes de compilar. El flujo de sdd claude code se vuelve completamente trazable.
// scripts/verify-spec-sync.ts
import { readFileSync } from 'fs';
import { Project } from 'ts-morph';
const ticketId = process.argv[2];
if (!ticketId) {
console.error("Falta el identificador del ticket");
process.exit(1);
}
const specContent = readFileSync(`.specs/active/${ticketId}.md`, 'utf-8');
const project = new Project({ tsConfigFilePath: './tsconfig.json' });
// Comprobación de firmas declaradas en la sub-spec frente a src/
console.log(`Verificando sincronización de contratos para ${ticketId}...`);
const sourceFiles = project.getSourceFiles(`src/**/*.ts`);
// Lógica de validación sintáctica
let contractsPassed = true;
// Si la sub-spec define interfaces obligatorias, validamos su existencia en el AST
const declaredInterfaces = Array.from(specContent.matchAll(/### Interface: `(\w+)`/g)).map(m => m[1]);
for (const iface of declaredInterfaces) {
const match = sourceFiles.some(f => f.getInterface(iface) !== undefined);
if (!match) {
console.error(`Error: La interfaz ${iface} definida en la spec no existe en el código.`);
contractsPassed = false;
}
}
if (!contractsPassed) {
process.exit(1);
}
console.log("Contratos de interfaz validados correctamente.");
Este script actúa como salvaguarda determinista. Impide que la flexibilidad adaptativa se convierta en una excusa para que Claude Code relaje los estándares de tipado o mute interfaces arbitrariamente.
Implementación paso a paso: De la Master Spec a la Sub-spec adaptativa
Imaginemos un caso concreto en el que debemos implementar un motor de almacenamiento en caché con soporte para edge workers. Nuestra Master Spec prohíbe el uso de librerías nativas de Node.js como crypto o fs para garantizar compatibilidad con Cloudflare Workers.
El programador humano inicia el ciclo ejecutando Claude Code con una instrucción directa:
claude "Implementa el módulo de invalidación de caché por tags según specs/master-contract.md. Ticket: CACHE-104"
El modelo lee la Master Spec y genera la sub-spec correspondiente en el directorio temporal. Analicemos cómo luce esa primera versión generada por el agente bajo las pautas de sdd claude code:
## Sub-Spec: CACHE-104 (Invalidación por Tags)
Estado: BORRADOR_INICIAL
Runtime: Edge Compatible
### Interface: `TagCacheStore`
```typescript
export interface TagCacheStore {
set(key: string, value: unknown, tags: string[]): Promise<void>;
invalidateTags(tags: string[]): Promise<number>;
get(key: string): Promise<unknown | null>;
}
Casos de Prueba
- Almacenar clave con dos tags y verificar persistencia.
- Invalidar un tag y confirmar que las claves vinculadas retornan null.
- Verificar que no se invocan APIs exclusivas de Node.js runtime.
Claude Code escribe los tests unitarios en `test/cache-tags.spec.ts` y acto seguido redacta la implementación en `src/cache-tags.ts`. Supongamos que, durante la implementación, el modelo decide utilizar una función hash rápida y escribe por descuido:
```typescript
import { createHash } from 'node:crypto'; // Incompatible con el runtime especificado
En un flujo convencional, la suite de tests unitarios que corre en Node pasaría sin problemas. Sin embargo, nuestro validador dinámico ejecuta las pruebas dentro de un entorno aislado de Miniflare o Vitest con entorno edge. El test falla de inmediato:
FAIL test/cache-tags.spec.ts > TagCacheStore > Runtime Isolation
ReferenceError: node:crypto is not supported in edge workers target.
Aquí es donde el paradigma tradicional falla y brilla sdd claude code. En vez de permitir que el modelo intente soluciones sucias en el código, el protocolo de sdd claude fuerza la reescritura de la sub-spec. Claude Code analiza el error, detecta la colisión con la Master Spec y muta la sub-spec temporal.
Actualiza el documento .specs/active/CACHE-104.md añadiendo una sección de adaptación técnica:
### Adaptación Runtime (Iteración 2)
- Problema detectado: Fallo de resolución de módulo `node:crypto`.
- Corrección de diseño: Sustituir `node:crypto` por `crypto.subtle` nativo de Web Standards.
- Criterio de QA: Validar que el digest SHA-256 se resuelva asíncronamente.
El agente reescribe la implementación utilizando la Web Crypto API nativa, actualiza los tests para manejar promesas en el cálculo del hash y vuelve a correr la suite de verificación. Todo el proceso ocurre de manera autónoma, pero dejando un rastro auditable en la sub-spec sin modificar jamás la Master Spec global.
El bucle de QA autónomo: Verificación semántica y pruebas sintéticas
El verdadero rendimiento de los Dynamic Workflows se consolida en la fase de control de calidad. La mayoría de los desarrolladores limitan su pipeline a ejecutar npm test. En sistemas orientados a agentes esto resulta insuficiente. Un modelo puede hacer que un test pase simplemente modificando las aserciones del propio test para que siempre devuelvan verdadero.
Para cerrar esa brecha he integrado tres niveles de validación en mi flujo de sdd claude code:
- Mutation Testing Ligero: Usamos un runner que muta operadores lógicos en el código recién escrito. Si los tests siguen pasando tras invertir una condición booleana, Claude Code rechaza su propia solución y reescribe la suite de pruebas.
- Type Coverage Estricto: Cero tolerancia a
anyo casts implícitos medianteas unknown as T. - Diff Guard: Un script valida que el diff del pull request no modifique archivos fuera del alcance declarado en la sub-spec.
El bucle de ejecución se articula mediante este script bash que Claude Code ejecuta de manera autónoma tras cada iteración:
#!/usr/bin/env bash
set -eo pipefail
TICKET_ID=$1
echo "==> Validando sub-spec frente a Master Spec"
npx tsx scripts/verify-spec-sync.ts "$TICKET_ID"
echo "==> Comprobación de tipos estricta"
npx tsc --noEmit --strict
echo "==> Ejecución de tests en entorno aislado"
npx vitest run --coverage
echo "==> Inspección de cobertura de mutación"
npx stryker run --reporters clear-text
echo "QA completado con éxito para $TICKET_ID"
Cuando integro este bucle dentro de la sesión de sdd claude code, el agente toma control total de la consola. Si Stryker reporta mutantes supervivientes en la lógica de invalidación de tags, Claude Code inspecciona el informe de cobertura, identifica las ramas lógicas desprotegidas, añade los tests ausentes y vuelve a ejecutar el ciclo de QA.
La ventaja fundamental de este método reside en la retroalimentación estructurada. El modelo no recibe un vago “algo no funciona”. Recibe trazas precisas de compilación, análisis estático y métricas de mutación. Con esa información, el motor de sdd claude code ajusta la implementación con una precisión que supera ampliamente al desarrollo asistido por chat manual.
Métricas de rendimiento y lecciones en repositorios reales
He medido la eficacia de este enfoque en dos proyectos reales durante tres meses: una API bancaria basada en microservicios y una plataforma SaaS multitenant. Los datos muestran un contraste contundente frente a los métodos convencionales.
El tiempo medio de resolución de tareas complejas aumentó un 18% en la fase de diseño inicial debido a la creación obligatoria de sub-specs. Sin embargo, la tasa de regresión en producción se redujo de un 14.2% a un 1.8%. El número de interacciones manuales necesarias para corregir fallos arquitectónicos cayó de 6.4 intervenciones por ticket a solo 1.1.
| Métrica de Proyecto | Spec Estática Tradicional | Dynamic SDD con Claude Code |
|---|---|---|
| Tiempo medio hasta primer commit verde | 22 minutos | 34 minutos |
| Bugs de contrato detectados en CI/CD | 18% de las ramas | Menos del 2% |
| Tasa de supervivencia de mutantes | 31% | 6% |
| Intervención humana requerida por ticket | Alta (corrección continua) | Baja (revisión de Sub-Spec) |
Mi experiencia directa con este sistema me ha enseñado varias verdades incómodas que debes considerar antes de lanzarte a implementarlo:
Primero, el consumo de tokens aumenta sensiblemente. Como Claude Code debe inspeccionar la sub-spec, mutarla, generar tests y evaluar linters cíclicamente, el coste por funcionalidad se incrementa aproximadamente en un 40% respecto al uso básico del CLI. No obstante, el ahorro en horas de depuración manual compensa este gasto con creces en proyectos comerciales.
Segundo, la putrefacción de contexto (context rot) es una amenaza constante. Si permites que la sesión de Claude Code acumule cientos de mensajes con trazas de errores de compilación, el modelo pierde nitidez y empieza a alucinar soluciones. Para prevenir esto, programo una limpieza periódica del buffer de contexto del CLI una vez que la sub-spec alcanza el estado aprobado, forzando al agente a releer únicamente la sub-spec y el archivo que está modificando.
Tercero, la Master Spec debe ser concisa. Si redactas una Master Spec de cuarenta páginas con detalles de implementación minuciosos, anulas la capacidad adaptativa de sdd claude code. La Master Spec debe actuar como una constitución: define derechos, prohibiciones y límites inviolables. Las leyes operativas concretas deben dejarse a las sub-specs dinámicas generadas en cada ciclo.
Implementar este flujo requiere disciplina y una inversión inicial en scripts de validación local. Pese a ello, una vez configurado el andamiaje, la sensación de ver a Claude Code diseñar contratos, refactorizar su propia arquitectura y someterse a pruebas de QA implacables sin requerir supervisión constante transforma por completo el flujo de trabajo en la terminal.


