Ir al contenido

Spec-First Enforcement

Version: 1.0 | Fase principal: F05-F06 | Track minimo: Solo (warn) Referencia: project-template/.claude/skills/spec_workflow/SKILL.md


Spec-first no es documentacion post-facto. Es la validacion de la logica de negocio ANTES de escribir codigo.

Sin spec-first, el ciclo tipico es:

Usuario describe feature → Agente interpreta → Agente codea → Codigo refleja interpretacion incorrecta → Reescritura

Esto genera:

  • Desperdicio de tokens y tiempo: codigo que se descarta porque la logica estaba mal
  • Deuda tecnica invisible: endpoints sin contrato que nadie puede validar
  • Regresiones silenciosas: cambios de API sin spec que rompen integraciones
Usuario describe feature → Validar logica de negocio → Generar spec → Validar spec → Codear con certeza

Beneficios:

  • La logica de negocio se valida con el usuario ANTES de invertir en codigo
  • El contrato OpenAPI es la fuente de verdad — no el codigo
  • Cualquier agente puede implementar el mismo endpoint sin ambiguedad
  • Los tests de contrato se derivan automaticamente del spec
  • Los cambios de API son detectables y versionables
AspectoDocumentacion post-factoSpec-first
MomentoDespues del codigoAntes del codigo
PropositoDescribir lo que existeDefinir lo que debe existir
ValidacionManual, opcionalAutomatizada, obligatoria
Fuente de verdadEl codigoEl contrato
Costo de errorAlto (reescritura)Bajo (editar spec)

El flujo spec-first tiene 5 pasos, de los cuales los primeros 4 ocurren ANTES de escribir codigo:

┌─────────────────────────────────────────────────────────────────┐
│ 1. Lenguaje natural: usuario describe que necesita │
│ 2. Validar logica de negocio: confirmar entendimiento │
│ 3. Generar SPEC: crear contrato OpenAPI en .openspec/ │
│ 4. Validar SPEC: lint, schema check, review │
│ 5. Codigo: implementar desde el contrato validado │
└─────────────────────────────────────────────────────────────────┘

El usuario describe la feature en sus propios terminos. No se requiere formato especifico.

El agente debe:

  • Identificar entidades y relaciones del dominio
  • Documentar reglas de negocio (invariantes, validaciones, flujos)
  • Confirmar con el usuario: “Entendi que X debe hacer Y cuando Z. Correcto?”
  • NO proceder sin confirmacion

Crear el contrato OpenAPI 3.1 en project/F05_contracts/.openspec/:

  • Request schema, response schema, error schema
  • Usar $ref para reutilizar schemas
  • Registrar entidades en data_dictionary.yaml
  • Lint del YAML (sintaxis, indentacion)
  • Validacion contra JSON Schema de OpenAPI
  • Review de consistencia con specs existentes

Solo despues de los pasos 1-4:

  • Implementar endpoint segun contrato
  • Tests de contrato derivados del spec
  • Verificar compliance con spec-first-check.py

El enforcement spec-first opera en 4 capas complementarias, de la mas temprana a la mas tardia:

El archivo project-template/.claude/agents/builder.md tiene un SPEC-FIRST GATE como paso 0:

Before ANY code generation:
0. SPEC-FIRST GATE: Verify .openspec/ contains a contract for what you are about to build.
- If NO spec exists: STOP IMMEDIATELY. Do NOT write any code.
- Instead: invoke /spec_workflow to create the spec first.

Este es el primer punto de enforcement. Si el agente sigue sus instrucciones, nunca genera codigo sin spec.

El hook pre-commit detecta commits que agregan codigo en project/F06_build/ sin archivos correspondientes en project/F05_contracts/.openspec/:

  • Si el commit incluye archivos de codigo nuevos sin spec → bloqueo
  • El desarrollador debe crear el spec antes de commitear
  • Configurable via .claude/settings.json

Nivel 3: Compliance Linter (validacion continua)

Sección titulada «Nivel 3: Compliance Linter (validacion continua)»

El compliance-linter.py incluye checks especificos para spec-first:

CheckCodigoDescripcion
Spec coverageSF-01Todo endpoint en F06 debe tener spec en .openspec/
Data dictionarySF-02Todo modelo de datos debe tener entrada en data_dictionary.yaml

Severidad por track:

  • Solo: WARNING (permite avanzar, reporta gap)
  • Lean: FAIL (bloquea gate si no hay spec)
  • Full: FAIL (bloquea gate si no hay spec)

El workflow gates.yml verifica spec coverage antes de permitir merge:

  • PRs que agregan codigo sin spec correspondiente → PR bloqueado
  • El check se ejecuta como parte del gate de F06
  • Solo se puede bypasear con flag --skip-spec-check (requiere justificacion)
Nivel 1 (Agent) → Previene que el agente genere codigo sin spec
↓ (si falla)
Nivel 2 (Pre-commit) → Bloquea el commit local
↓ (si falla)
Nivel 3 (Linter) → Reporta violacion en validacion
↓ (si falla)
Nivel 4 (CI) → Bloquea el PR en GitHub

Si un archivo en project/F06_build/ define un endpoint HTTP (route, controller, handler) y no existe un contrato correspondiente en project/F05_contracts/.openspec/:

  • Nivel 1: Agente se detiene, invoca /spec_workflow
  • Nivel 2: Pre-commit rechaza el commit
  • Nivel 3: Linter reporta SF-01 como FAIL
  • Nivel 4: CI bloquea el PR

Si se crea un modelo de datos (schema, entity, migration) sin entrada correspondiente en data_dictionary.yaml:

  • Nivel 1: Agente verifica data_dictionary antes de crear modelo
  • Nivel 3: Linter reporta SF-02 como FAIL

Si el proyecto tiene archivos en F06_build/ pero el directorio project/F05_contracts/.openspec/ no existe o esta vacio:

  • Nivel 3: Linter reporta SF-01 como CRITICAL
  • Nivel 4: CI bloquea cualquier PR con codigo

5. Como Generar Specs desde Lenguaje Natural

Sección titulada «5. Como Generar Specs desde Lenguaje Natural»

El skill /spec_workflow es la herramienta principal para generar specs. Su flujo completo es:

Fase 0: Validacion de Logica de Negocio (OBLIGATORIA)

Sección titulada «Fase 0: Validacion de Logica de Negocio (OBLIGATORIA)»

Antes de generar cualquier spec:

  1. Entender el requerimiento en lenguaje natural
  2. Identificar entidades y relaciones del dominio
  3. Documentar reglas de negocio (invariantes, validaciones, flujos)
  4. Confirmar con el usuario
  5. Solo despues de confirmacion: proceder a /specify

Fase 1: /specify — Especificar QUE y POR QUE

Sección titulada «Fase 1: /specify — Especificar QUE y POR QUE»

Crear spec centrada en el usuario con: feature, problema, usuario_objetivo, user_stories, criterios_aceptacion, no_goals.

Definir stack, arquitectura, data_model, api_contracts, dependencias, riesgos.

Lista de tareas atomicas con orden: contratos → tests → implementacion → docs.

Implementar tarea por tarea, verificando contra criterios de aceptacion.

Para detalle completo del flujo, invocar /spec_workflow.


El enforcement spec-first respeta el track del proyecto:

TrackSeveridad SF-01/SF-02Comportamiento
SoloWARNINGReporta gap, permite avanzar
LeanFAILBloquea gate, requiere spec
FullFAILBloquea gate, requiere spec

Para proyectos Solo que quieran enforcement completo:

Ventana de terminal
python3 baseline/scripts/spec-first-check.py --project-dir . --track solo --strict

Con --strict, todos los tracks tratan SF-01/SF-02 como FAIL.

Para proyectos brownfield que adoptan spec-first:

  1. Ejecutar spec-first-check.py en modo inventario (sin --strict)
  2. Generar specs para endpoints existentes usando /spec_workflow
  3. Una vez cubiertos todos los endpoints, activar --strict

El script spec-first-check.py verifica compliance spec-first:

Ventana de terminal
# Verificacion basica (respeta severidad por track)
python3 baseline/scripts/spec-first-check.py --project-dir . --track lean
# Verificacion estricta (FAIL para todos los tracks)
python3 baseline/scripts/spec-first-check.py --project-dir . --track solo --strict
# Solo inventario (lista gaps sin fallar)
python3 baseline/scripts/spec-first-check.py --project-dir . --track solo --inventory
CheckCodigoDescripcion
Spec coverageSF-01Endpoint en F06 tiene spec en .openspec/
Data dictionarySF-02Modelo tiene entrada en data_dictionary.yaml
Spec driftSF-03Endpoint en codigo puede haber divergido del spec (method/path)
Dead specSF-04Spec define endpoint que codigo ya no implementa
=== Spec-First Compliance Check ===
Track: lean | Mode: enforce
[PASS] SF-01: 12/12 endpoints have specs
[PASS] SF-02: 8/8 models in data_dictionary
[PASS] SF-03: All specs are valid OpenAPI 3.1
[WARN] SF-04: 2 specs older than their implementations
Score: 95/100
Status: PASS (2 warnings)

A partir de v1.1, spec-first-check.py incluye deteccion de drift entre codigo y specs. No solo verifica que exista un spec, sino que el spec este sincronizado con el codigo.

SF-03: SPEC_DRIFT — Endpoint puede haber divergido del spec

Sección titulada «SF-03: SPEC_DRIFT — Endpoint puede haber divergido del spec»

Se reporta cuando:

  • Un endpoint en codigo tiene un method que el spec no define para ese path (ej: codigo tiene POST /api/users pero spec solo define GET /api/users)
  • Un endpoint en codigo tiene un path similar pero no identico al spec (ej: codigo tiene /api/v2/users pero spec define /api/v1/users)

Severidad: medium (warning, no bloquea)

[MEDIUM] SPEC_DRIFT: Endpoint POST /api/users en src/routes.ts:42 —
spec define GET para este path pero no POST
Fix: Actualizar spec en .openspec/ para incluir POST /api/users, o alinear codigo con spec

SF-04: DEAD_SPEC — Spec sin implementacion en codigo

Sección titulada «SF-04: DEAD_SPEC — Spec sin implementacion en codigo»

Se reporta cuando:

  • Un spec define un endpoint (method + path) que no tiene implementacion en el codigo escaneado
  • Solo se reporta si el proyecto tiene al menos un endpoint de codigo (para evitar falsos positivos en proyectos sin codigo)

Severidad: medium (warning, no bloquea)

[MEDIUM] DEAD_SPEC: Spec define DELETE /api/users/{id} en project/F05_contracts/.openspec/api.yaml
pero no se encontro implementacion en codigo
Fix: Implementar DELETE /api/users/{id} segun el contrato, o eliminar del spec si ya no aplica
SituacionAccion recomendada
SPEC_DRIFT por methodAgregar el method al spec o corregir el codigo
SPEC_DRIFT por pathVerificar cual es el path correcto (spec o codigo)
DEAD_SPEC intencionalEndpoint planeado pero no implementado aun — ignorar
DEAD_SPEC accidentalEndpoint eliminado del codigo — limpiar el spec

Para proyectos que necesitan eximir ciertos archivos o directorios del enforcement spec-first, se puede crear un archivo .specignore en la raiz del proyecto.

El archivo sigue el mismo formato que .gitignore:

  • Un patron por linea
  • Lineas en blanco se ignoran
  • Comentarios con #
  • Patrones de directorio terminan en /
  • Patrones de archivo usan wildcards (*, ?)
# Directorios de experimentacion
spike/
sandbox/
# Utilidades internas sin API publica
src/utils/
src/helpers/
# Scripts de migracion
scripts/*.py
# Archivos generados
*.generated.ts

El script siempre aplica los siguientes patrones, incluso sin archivo .specignore:

PatronProposito
test/, tests/, __tests__/Directorios de tests
*.test.*, *.spec.*Archivos de test
spike/, spikes/Spikes de exploracion
experimental/, sandbox/, prototype/Codigo experimental

Cuando specignore esta activo, el reporte incluye:

Specignore: 12 patterns loaded, 5 files excluded

El framework reconoce que la exploracion es parte natural del desarrollo. No toda linea de codigo necesita un spec formal — los spikes y prototipos son herramientas validas de aprendizaje.

Cuando un commit incluye el tag [spike] en su mensaje, indica que el codigo es exploratorio y no requiere spec:

Ventana de terminal
git commit -m "[spike] Explorar integracion con API de pagos"

El pre-commit hook reconoce este tag y no aplica la validacion spec-first.

Para excluir automaticamente los directorios de exploracion:

Ventana de terminal
python3 baseline/scripts/spec-first-check.py --project-dir . --skip-spike-dirs

Esto excluye automaticamente:

  • spike/ y spikes/
  • experimental/
  • sandbox/
  • prototype/
ReglaDetalle
Duracion maxima2-4 horas (1 sprint max)
Output esperadoDescubrimiento documentado en DISCOVERIES.md
NO llevar a produccionEl spike se descarta; el codigo final se hace con spec
UbicacionSiempre en directorios designados (spike/, experimental/, etc.)
1. Crear directorio spike/nombre-exploracion/
2. Experimentar libremente (sin spec)
3. Documentar hallazgos en DISCOVERIES.md
4. Descartar el spike
5. Si el spike valida la idea: crear spec → implementar con spec-first

  • Skill: project-template/.claude/skills/spec_workflow/SKILL.md
  • Agente: project-template/.claude/agents/builder.md (SPEC-FIRST GATE)
  • Regla: project-template/.claude/rules/contracts.md (Spec-First Enforcement)
  • Regla: project-template/.claude/rules/code_quality.md (Spec primero)
  • Linter: scripts/compliance-linter.py (checks SF-01, SF-02)
  • Acelerador: framework/accelerators/playbooks/ACC_PLAYBOOK_Spec_Kit_Acelerador_Operativo.md