← Todos los artículos EN

Desarrollo dirigido por especificaciones con Claude Code en sistemas enterprise

He pasado los ultimos meses implementado Claude Code en infraestructura bancaria enterprise. El flujo de trabajo real — no la versión de demo. Especificaciones, gobernanza, límites y qué cambia genuinamente cuando la IA se convierte en parte de tu proceso de ingeniería.

Los equipos que más aprovechan las herramientas de código con IA no son los que escriben los mejores prompts. Son los que más han pensado antes de abrir la ventana de chat.

He pasado los últimos meses integrando Claude Code en mi flujo de trabajo de ingeniería sobre sistemas bancarios enterprise — código de producción, entorno regulado, requisitos reales de compliance. Esto no es un artículo de productividad. Es un relato operacional de lo que realmente ocurre cuando introduces herramientas de IA en un contexto de ingeniería serio.

La ilusión de productividad

Lo primero que nota la mayoría de los engineers cuando empieza a usar herramientas de código con IA es un aumento dramático en la velocidad de output. El boilerplate se escribe solo. Los endpoints CRUD aparecen. Los test fixtures se generan. Esto es real y tiene importancia. Pero crea un modelo mental engañoso sobre dónde se genera realmente el valor.

Las ganancias de velocidad son reales. La pregunta es qué estás construyendo más rápido.

En mi experiencia, el riesgo de las herramientas de código con IA en entornos enterprise no es que generen código incorrecto. Es que generan código técnicamente correcto que no pertenece a tu sistema — código que pasa el type checking, pasa los tests, y viola las restricciones arquitectónicas que no están codificadas en ningún lugar que una máquina pueda leer.

Una herramienta que escribe código más rápido sin cambiar lo que piensas tomará malas decisiones más rápido. El Desarrollo Dirigido por Especificaciones es la práctica que convierte la velocidad de la IA en apalancamiento de ingeniería compuesto en lugar de deuda técnica compuesta.

Qué significa realmente el desarrollo dirigido por especificaciones

Una spec no es un documento de requisitos. Los requisitos describen qué debe hacer un sistema desde la perspectiva del usuario. Una spec describe cómo debe verse una implementación desde la perspectiva de la ingeniería — las restricciones que preceden y limitan la implementación.

Una spec de producción contiene:

  • Modelos de datos con tipos e invariantes: no solo la forma, sino qué siempre es verdad sobre los datos
  • Contratos de API: inputs, outputs, todos los casos de error, no solo el happy path
  • Invariantes de comportamiento: propiedades que deben cumplirse en todos los estados, no solo en los iniciales
  • Declaraciones explícitas de fuera de alcance: qué no maneja deliberadamente este componente
  • Log de decisiones: las opciones que se consideraron y el razonamiento para la elegida

Los dos últimos son los más importantes y los más omitidos.

Las declaraciones de fuera de alcance previenen la expansión de alcance durante la implementación asistida por IA. Si no le dices a Claude Code de qué no es responsable un servicio, a menudo añadirá manejo para casos edge que deberían pertenecer a otro servicio — creando acoplamiento oculto que descubrirás seis meses después durante un refactor.

El log de decisiones es el mecanismo de gobernanza arquitectónica. Codifica el contexto que existe en el momento de diseño pero desaparece para el momento de implementación. “¿Por qué usamos aquí una unión discriminada en lugar de una jerarquía de clases?” es una pregunta que debería poder responderse desde la spec, no desde una búsqueda en Slack.

El modelo de orquestación de Claude Code

Claude Code opera con un modelo fundamentalmente diferente al de un asistente de chat. Tiene acceso a herramientas — lee archivos, ejecuta comandos, escribe código, corre tests. Las sesiones acumulan contexto dentro de una conversación pero no persisten automáticamente entre ellas. Esto crea un desafío operacional específico para codebases enterprise: la gestión de contexto es trabajo de ingeniería.

// FLUJO DE TRABAJO CLAUDE CODE — de la especificación a la implementación validada
graph TB SPEC["Especificación de Ingeniería\nModelos de datos · Contratos API\nInvariantes · Fuera de alcance · Log de decisiones"] CLAUDE_MD["CLAUDE.md\nContexto de arquitectura\nConvenciones · Restricciones\nLímites de paquetes · Requisitos de revisión"] SESSION["Sesión Claude Code\nLeer spec · Leer contexto del codebase\nHacer preguntas de clarificación\nGenerar plan de implementación"] IMPL["Implementación\nTipos · Lógica · Tests\nSigue restricciones de la spec"] REVIEW["Revisión Humana\nGates de arquitectura\nRevisión de compliance\nCheck de cobertura de tests"] MERGE["Merge\nChangeset · Actualización ADR\nDocumentación"]
SPEC --> SESSION
CLAUDE_MD --> SESSION
SESSION --> IMPL
IMPL --> REVIEW
REVIEW -->|"necesita revisión"| SESSION
REVIEW -->|"aprobado"| MERGE

El archivo CLAUDE.md es la feature más infrautilizada en el flujo de trabajo de Claude Code. Es un archivo de contexto persistente que Claude Code lee al inicio de cada sesión — contexto arquitectónico, convenciones, restricciones, límites de paquetes y patrones explícitamente prohibidos. Todo codebase enterprise que he trabajado tiene restricciones implícitas que los engineers experimentados entienden y que son invisibles para los nuevos. CLAUDE.md las hace explícitas y legibles por máquinas.

Nuestro CLAUDE.md para la plataforma OneBank incluye:

## Restricciones de arquitectura

- @onebank/forms no debe importar de @onebank/components ni de @onebank/primitives.
  La capa de forms es propietaria de la lógica de negocio, no de las preocupaciones visuales.
  
- resolverConfigFormulario debe permanecer como función pura.
  Sin hooks. Sin efectos secundarios. Sin imports de React. Testeable en Node.js.
  
- Los cambios en SolicitanteSchema requieren un label de revisión de compliance en el PR.
  Tagea al responsable de compliance (ver CODEOWNERS) antes de solicitar el merge.
  
- El schema de EventoFormulario es append-only. Se pueden añadir nuevos campos.
  Los campos existentes no pueden eliminarse ni tener sus tipos reducidos.
  
## Patrones prohibidos

- Sin llamadas directas a Core Banking API desde las apps de producto.
  Todo el acceso a Core Banking va a través del BFF.
  
- Sin nuevas tablas Postgres compartidas. Solo schemas específicos por producto.
  (Ver ADR-007 para el razonamiento detrás de esta restricción.)

Estas restricciones son cosas que los engineers experimentados del equipo conocen. No están en el sistema de tipos. No las hace cumplir el compilador. Sin CLAUDE.md, la implementación asistida por IA las violaría con regularidad — no porque la IA sea descuidada, sino porque no tiene acceso a la historia organizacional que las formó.

Anatomía de una spec de producción

Aquí hay una spec real de la plataforma OneBank — un servicio para manejar eventos de completado de pasos de formulario:

# StepCompletionService

## Responsabilidad
Registra la finalización de un paso del formulario de onboarding y actualiza el progreso de la sesión.
NO maneja el envío del formulario — eso es ApplicationSubmissionService.
NO maneja validación — la validación se gestiona antes de llamar a este servicio.

## Input
StepCompletionEvent: {
  sessionId: string (UUID, se requiere sesión activa)
  productCode: ProductCode (del enum PRODUCT_CODE)
  stepId: string (del enum FORM_STEPS para este producto)
  completedAt: Date (asignado por el servidor, no provisto por el cliente)
  formDataSnapshot: Partial<SolicitanteSchema> (slice validado)
}

## Invariantes
- Un paso no puede marcarse como completado si un paso posterior ya está completado.
  Los pasos deben completarse en orden. La completación fuera de orden es un estado de error.
  
- completedAt siempre es asignado por el servidor. Los timestamps del cliente se ignoran.

- formDataSnapshot se almacena con fines de auditoría. No debe modificarse
  después del almacenamiento. El snapshot representa el estado en el momento de la completación del paso.

## Output
StepCompletionResult: {
  sessionId: string
  stepId: string  
  nextStep: FormStep | null (null si este fue el paso final)
  sessionProgress: number (0-100)
}

## Casos de error
- SESSION_NOT_FOUND: el sessionId no existe o ha expirado
- STEP_ALREADY_COMPLETED: idempotente — devolver éxito con datos de completación existentes
- OUT_OF_ORDER_COMPLETION: lanzar, no manejar silenciosamente
- INVALID_STEP_FOR_PRODUCT: el stepId no es válido para el productCode dado

## Fuera de alcance
- Creación o expiración de sesión — eso es SessionManagementService
- Validación de formulario — la validación ocurre antes de este servicio
- Envío de notificaciones — manejado por consumers de eventos downstream
- Cálculo de pesos de progreso específicos por producto — todos los pasos cuentan igual

## Log de decisiones
- ¿Por qué almacenar formDataSnapshot? Requisito regulatorio. Necesitamos registros
  punto-en-el-tiempo de lo que el cliente envió en cada paso, no solo el estado final.
  
- ¿Por qué lanzar en OUT_OF_ORDER_COMPLETION en lugar de reordenar silenciosamente?
  Consideramos aceptar y reordenar silenciosamente. Rechazado: el manejo silencioso
  enmascara bugs del lado del cliente que indican corrupción del estado de sesión. Fallar alto.
  
- ¿Por qué completedAt asignado por el servidor? Los relojes del cliente son poco fiables y
  manipulables. Los requisitos de auditoría regulatoria necesitan timestamps del lado del servidor.

Esta spec tomó aproximadamente 45 minutos escribirla. Ahorró aproximadamente 3 horas de clarificaciones durante la implementación, un ciclo de revisión de compliance y un refactor post-implementación cuando descubrimos que una preocupación fuera de alcance había sido implementada dentro del servicio.

El pipeline de especificación

El flujo de trabajo corre en cinco etapas:

// PIPELINE DE ESPECIFICACIÓN — del requisito a la implementación mergeada
graph LR REQ["Requisito\nticket o RFC"] SPEC_WRITE["Escritura de Spec\nEngineer — 30-90 min\nModelos de datos · invariantes\nfuera de alcance · log de decisiones"] SPEC_REVIEW["Revisión de Spec\nPar + responsable de compliance\nSLA de 24-48 horas"] IMPL["Implementación asistida por IA\nSesión Claude Code\nContexto de spec + CLAUDE.md\n1-4 horas"] HUMAN_REVIEW["Revisión Humana\nGates de arquitectura\nTags de compliance\nCobertura de tests"] MERGE["Merge + ADR\nChangeset + docs\nADR si hay decisión arquitectónica"]
REQ --> SPEC_WRITE
SPEC_WRITE --> SPEC_REVIEW
SPEC_REVIEW -->|"aprobado"| IMPL
SPEC_REVIEW -->|"revisar"| SPEC_WRITE
IMPL --> HUMAN_REVIEW
HUMAN_REVIEW -->|"aprobado"| MERGE
HUMAN_REVIEW -->|"revisar spec"| SPEC_WRITE

La etapa de revisión de spec no es opcional. En un entorno regulado, una spec que no ha sido revisada por un responsable de compliance es una decisión de compliance sin revisar. La revisión crea un artefacto: una aprobación fechada de que una decisión de implementación relevante para compliance fue revisada antes de que comenzara la implementación. Esto es auditable. La alternativa — tomar decisiones de compliance en code review — crea un problema de auditoría, porque el code review no es un proceso de revisión de compliance.

El bucle de feedback “revisar spec” desde la revisión humana hacia la escritura de spec es donde se recupera la mayor parte del valor. Cuando una implementación no se siente correcta en code review, el problema está casi siempre en la spec, no en la implementación. Trabajar hacia atrás desde el código hasta la spec y el requisito expone la decisión real que estaba mal. Corregir la spec y reimplementar es más rápido que parchear el código.

Gobernanza arquitectónica: qué no puede decidir la IA

Hay decisiones que las herramientas de IA no deben tomar en sistemas enterprise, y principalmente no se trata de corrección. Se trata de autoridad y responsabilidad.

Decisiones de límites: Qué servicio posee qué preocupación es una decisión de gobernanza, no una decisión técnica. La IA generará código técnicamente funcional que cruza límites que no tiene autoridad para cruzar. Si resolverConfigFormulario necesita llamar a un servicio de compliance, Claude Code implementará la llamada. Esa implementación puede ser correcta. La decisión de hacer la llamada es una decisión arquitectónica que requiere autoridad humana.

Interpretación regulatoria: Cuando un requisito regulatorio es ambiguo, la IA hará una interpretación. Esa interpretación parecerá segura. Puede estar equivocada. Las interpretaciones regulatorias en banca requieren revisión legal — no porque la implementación técnica sea difícil, sino porque la interpretación tiene implicaciones de compliance que se extienden más allá del codebase.

Decisiones de deprecación y eliminación: La IA sugerirá eliminar código no utilizado. Eliminar código de un sistema regulado requiere entender si el código se usa para archivado de compliance, si su eliminación afecta a los audit trails, y si la eliminación crea una brecha en la cobertura regulatoria. Esto no es algo que la IA pueda determinar solo desde el codebase.

Decisiones de ADR: La IA puede generar la estructura de un ADR — contexto, opciones, consecuencias. No puede decidir qué opción elegir. El registro de decisiones documenta quién tomó una decisión técnica y por qué. Esa autoridad debe permanecer humana.

La implicación práctica: Claude Code funciona mejor como herramienta de implementación con una spec bien delimitada, no como herramienta de decisión arquitectónica. La spec es donde viven las decisiones arquitectónicas. La implementación es donde se ejecutan.

Escalando entre equipos

La pregunta natural una vez que el desarrollo dirigido por specs funciona para un engineer individual es si escala a un equipo. La respuesta es sí, pero el cuello de botella se desplaza.

La adopción individual es rápida. Un developer que entiende el ciclo spec → implementación → revisión puede operar de forma independiente con un alto apalancamiento. La adopción en equipo requiere plantillas de spec compartidas y convenciones de CLAUDE.md compartidas — lo que requiere que alguien sea propietario de esos artefactos.

// PATRÓN DE ADOPCIÓN EN EQUIPO — del apalancamiento individual al flujo organizacional
graph TB subgraph INDIVIDUAL["Adopción individual (semanas 1-4)"] I1["Engineer escribe spec\nantes de la implementación"] I2["Sesión Claude Code\ncon contexto de spec"] I3["Revisión humana\n+ bucle de feedback"] end subgraph TEAM["Adopción en equipo (meses 2-3)"] T1["Plantillas de spec compartidas\npor tipo de componente"] T2["CLAUDE.md compartido\ncontexto de arquitectura"] T3["Proceso de revisión de spec\nSLA de 24-48h"] T4["Responsable de compliance\nen el flujo de revisión"] end subgraph ORG["Flujo organizacional (mes 4+)"] O1["Spec-first\ndefinición de done"] O2["Generación de ADR\ndesde decisiones de spec"] O3["Quality gates\nen pipeline CI"] O4["Biblioteca de plantillas\npara patrones comunes"] end INDIVIDUAL --> TEAM --> ORG

La biblioteca de plantillas de spec es el artefacto de equipo de mayor apalancamiento. Cuando un equipo tiene plantillas para “servicio de dominio de eventos”, “handler de ruta BFF”, “schema de validación de formulario” y “schema de evento de auditoría”, el tiempo de escritura de spec baja de 45-90 minutos a 15-30 minutos, y la calidad de la spec se vuelve consistente. Las specs inconsistentes son un problema mayor a escala de equipo que a escala individual — crean implementaciones inconsistentes que requieren diferentes modelos mentales para razonar.

En la plataforma OneBank, mantenemos plantillas para:

  • Specs de servicio de dominio (lógica de negocio, sin dependencias de framework)
  • Specs de handler de ruta BFF (auth, rate limiting, orquestación)
  • Specs de schema de formulario (schemas Zod con contexto regulatorio)
  • Specs de evento de auditoría (extensiones de EventoFormulario)

Cada plantilla incluye las secciones que se requieren para una spec en esa categoría, con anotaciones que explican por qué existe cada sección. Los miembros nuevos del equipo aprenden el formato de spec leyendo las plantillas y las anotaciones — lo que también sirve como documentación de onboarding para la arquitectura misma.

Los límites que importan en contextos enterprise

La ventana de contexto como restricción: Claude Code tiene un límite de ventana de contexto. En codebases enterprise grandes, un único componente puede depender de patrones dispersos entre docenas de archivos. El archivo CLAUDE.md ayuda, pero no reemplaza leer la implementación real. Los refactors complejos que requieren entender el grafo completo de dependencias de un sistema grande alcanzan límites de contexto de formas que codebases más pequeños no experimentan.

La mitigación práctica: delimita las sesiones agresivamente. Una sesión debe tener un objetivo claramente delimitado — implementar este servicio concreto según esta spec — no “refactorizar la capa de forms”. El objetivo delimitado mantiene el contexto enfocado en los archivos que importan.

Brechas de conocimiento de dominio: La IA no tiene conocimiento de la historia de tu organización. No sabe sobre el incidente de compliance en el mes ocho que llevó al tipo sellado ContextoRegulatoria. No sabe sobre el refactor del BFF que movió el rate limiting del nivel de aplicación al nivel de gateway. Sugerirá implementaciones que habrían sido correctas antes de que esas decisiones se tomaran. CLAUDE.md es el mecanismo para codificar esta historia, pero requiere que alguien lo mantenga a medida que el codebase evoluciona.

Matiz regulatorio: La IA puede aplicar reglas regulatorias que están explícitamente en la spec. No puede identificar reglas regulatorias que faltan en la spec. Si una spec omite un campo que es legalmente requerido, la implementación omitirá el campo, el código pasará los tests, y la brecha aparecerá en una revisión de compliance — o en una auditoría regulatoria. La completitud de la spec en dominios regulados requiere experiencia en compliance, no solo experiencia técnica.

El problema de la certeza incorrecta: La generación de código con IA expresa confianza que no está calibrada según la corrección. Una API alucinada que no existe se generará con la misma confianza aparente que una correcta. En codebases enterprise con APIs internas, este es un riesgo específico — la documentación de la API interna puede no estar bien representada en los datos de entrenamiento. La mitigación es la implementación test-driven: corre los tests pronto, antes de asumir que la implementación es correcta.

Las salvaguardas operacionales que hemos implementado

Tras meses, estas son las salvaguardas que han prevenido incidentes en producción:

Detección de cambios de compliance en CI: Un script que detecta cambios en archivos del paquete forms (específicamente los archivos de schema y resolver) y requiere un label de revisión de compliance antes de la promoción a staging. Esto captura cambios relevantes para compliance que ocurren durante la iteración de implementación — cuando un developer extiende un schema para manejar un caso edge sin darse cuenta de que la extensión tiene implicaciones de compliance.

Requisito de ADR para decisiones arquitectónicas: Si un PR introduce un nuevo patrón no representado en el código existente, CI requiere un ADR vinculado. Esto se hace cumplir por un check de label — sin merge sin un link de ADR o un label explícito de “sin ADR requerido” de un arquitecto. Esto crea un rastro de papel para las decisiones tomadas durante el desarrollo asistido por IA.

Gate de cobertura de tests en lógica de negocio: 95% de cobertura de ramas requerida en resolverConfigFormulario y validadores de schema. Esto no es un requisito global de cobertura — está delimitado a la lógica que tiene implicaciones de compliance. Los requisitos globales de cobertura producen los incentivos incorrectos; los requisitos delimitados producen los correctos.

SLA de revisión de spec: Las specs deben ser revisadas en 48 horas por un par y el responsable de compliance. Esto previene que la spec se convierta en un cuello de botella mientras mantiene la propiedad de gobernanza. Si la revisión tarda más, el developer comienza la implementación con el riesgo implícito de que la spec puede cambiar — lo cual se le permite hacer, con el entendimiento de que los cambios de spec después de que comienza la implementación crean retrabajo.

Qué cambia esto para las organizaciones de ingeniería

La conclusión operacional tras meses no es que la IA hace a los engineers individuales dramáticamente más productivos — aunque lo hace. Es que la IA hace que la calidad de las decisiones de ingeniería sea dramáticamente más visible.

Cuando la implementación es rápida, la restricción se convierte en la calidad de las decisiones. Las organizaciones que antes tenían cuellos de botella en la velocidad de implementación ahora los tienen en la claridad arquitectónica. Cada ambigüedad en una spec se convierte en un riesgo latente en una implementación generada por IA. Cada límite poco claro se convierte en un lugar donde la implementación tomará una decisión que tú no tomaste.

Esta es información útil. Las organizaciones que tratan la calidad de la spec como la métrica de ingeniería principal — no story points, no velocidad, no frecuencia de despliegue — son las que obtienen valor compuesto de las herramientas de IA. Las organizaciones que tratan la IA como una forma más rápida de implementar trabajo especificado de forma vaga obtienen deuda técnica más rápida.

El Desarrollo Dirigido por Especificaciones no es una metodología para usar IA. Es una metodología para hacer explícitas las decisiones de ingeniería antes de implementarlas. Las herramientas de IA hacen más alto el payoff de esa explicitación — y hacen más inmediatamente visible el coste de omitirla.

La especificación no es overhead. Es el trabajo. Todo lo que viene después es ejecución.