DIGITAL TOOLS · DEV #2 · JUL 2026
SESIÓN 2 · DEV #2
Claude Code
manos al teclado

Sesión 2 del track Dev: práctica guiada, instalamos la base común, dominamos Spec-Driven Development sobre el ticket real ONEDEV-218 y dejamos la revisión de PRs automatizada.

AI Mate · David Ramos Sesión 2 · Dev #2
EL PROGRAMA COMPLETO
PROGRAMA DE SESIONES

Tres sesiones, un equipo dev autónomo

01
Dev #1 · Fundamentos + SDD  ·  Jun 2026 ✓
Starter kit, Claude Code, primer ciclo SDD sobre ONEDEV-63.
02
Dev #2 · Herramientas avanzadas  ·  HOY
Ciclo SDD completo con el lean kit, TDD estricto, AI code review, generación de PR.
03
Dev #3 · Estándares + primer agente
Estándar del equipo en el repo y tu primer agente personal.

Hoy hacemos el ciclo completo propose → archive sobre un ticket real. Con tests, con review y con PR generado por IA.

SESIÓN 2 · DEV #2 · 4 H
PROGRAMA DE HOY

Seis bloques, manos al teclado

15'
Bloque 0 — Rescate + setup del kit (--preset onehub)
25'
Bloque 1 — Recap activo + reglas de la Liga SDD
40'
Bloque 2Misión 1: Propose → Spec (/enrich-us + /opsx:propose)
15'
☕ Pausa 1 — Checkpoint leaderboard #1
35'
Bloque 3Misión 2: Design → Tasks (revisar design.md + tasks.md de /opsx:propose)
45'
Bloque 4Misión 3: Apply con TDD estricto (/opsx:apply)
15'
☕ Pausa 2 — Checkpoint leaderboard #2
35'
Bloque 5Misión 4: Verify + AI code review (/opsx:verify + /adversarial-review)
35'
Bloque 6Misión 5: PR + Archive (/commit + /opsx:archive)
LA LIGA SDD
GAMIFICACIÓN · SESIÓN 2

¡Bienvenidos a la Liga SDD!

Cada misión es una fase del ciclo. XP por completar, badges por destacar, leaderboard en cada pausa.

LIGA SDD · REGLAS
CÓMO FUNCIONA

XP, badges y podio al cierre

MISIONES + XP
M1
Propose → Spec
+150 XP · badge Spec Smith
M2
Design → Tasks
+100 XP · badge Architect
M3
Apply TDD
+200 XP · badge Green Bar 🟢
M4
Verify + Review
+150 XP · badge Judge's Verdict ⚖️
M5
PR + Archive
+100 XP · badge Shipper 🚀
BONUS XP
  • +50 XP — primer test en rojo sin ayuda
  • +50 XP — adversarial review con 0 issues
  • +30 XP — PR merged sin cambios manuales
  • +20 XP — commit message impecable
FORMATO
  • En parejas (opcional) — la XP se reparte
  • Leaderboard en cada pausa
  • Podio final con badges
BLOQUE 0 DE 6
BLOQUE 0 · INICIO

Rescate + Setup

15 minutos para salvar el entorno de quien llegue a la sesión sin él.

00
BLOQUE 0 · SETUP
INSTALAR EL KIT · 15'

El kit listo, con el preset de OHE

# 1. Clonar el SDD kit (repo privado — los asistentes tienen acceso)
git clone https://github.com/One-Hub-Energy/aimate-sdd-kit.git

# 2. Clonar el repo del proyecto y cambiar a la rama de la feature
git clone https://github.com/One-Hub-Energy/onedev-grid-service.git
cd onedev-grid-service
git checkout ONEDEV-63-automated-capacity-data

# 3. Instalar el scaffold del SDD kit (también activa /opsx:verify automáticamente)
node ../aimate-sdd-kit/packages/sdd-kit/bin/init.js . --preset onehub

# 4. Inicializar OpenSpec (genera los comandos /opsx:*, incluido /opsx:verify)
openspec init --tools claude .
EL PRESET INSTALA
  • Standards Python/FastAPI en docs/
  • Data model (CNMC/REE/DSOs) en docs/data-model.md
  • Agente backend-developer configurado
  • Ejemplo ONEDEV-218 en examples/
SIN FRONTEND
  • El preset es API-only — frontend-standards.md no se instala
  • Los symlinks de agente solo tienen backend-developer
  • El config.yml ya apunta a Python 3.12 + structlog
BLOQUE 1 DE 6
BLOQUE 1 · EL NÚCLEO

Recap activo + Por qué SDD

Lo que aprendimos en la Sesión 1 y por qué el ciclo SDD es el eje de la sesión de hoy.

01
BLOQUE 1 · EL KIT
AIMATE SDD KIT

Estándares de proyecto portables y versionados

QUÉ INCLUYE
  • docs/ — backend-standards, api-spec, data-model, dev guide
  • ai-specs/agents/ — backend-developer, product-analyst
  • ai-specs/skills/ — enrich-us, adversarial-review, commit, code-auditing
  • Preset --preset onehub → stack Python/FastAPI + dominio OHE ya configurado

El kit no ejecuta código. Es el contexto que Claude necesita para razonar sobre tu proyecto específico.

# Instalar en tu proyecto (desde el repo clonado del kit)
node ../aimate-sdd-kit/packages/sdd-kit/bin/init.js . --preset onehub

# Repositorio privado — el equipo tiene acceso
github.com/One-Hub-Energy/aimate-sdd-kit

# Requiere también OpenSpec (el motor SDD)
npm install -g @fission-ai/openspec@latest
openspec init
BLOQUE 1 · EL KIT
EL WORKFLOW DEL KIT

Siete pasos, un ciclo

📝
/enrich-us
kit skill
💡
/opsx:propose
OpenSpec
⚙️
/opsx:apply
OpenSpec
🔍
/opsx:verify
OpenSpec
⚖️
/adversarial-review
kit skill
📦
/opsx:archive
OpenSpec
🚀
/commit
kit skill

/opsx:propose es el comando nuevo de OpenSpec que combina /new + /ff. Genera todos los artifacts en un paso: proposal.md, spec.md, design.md y tasks.md.

# Flujo actual (recomendado)
/enrich-us/opsx:propose/opsx:apply/opsx:verify/adversarial-review/opsx:archive/commit
BLOQUE 1 · EL CICLO
SPEC-DRIVEN DEVELOPMENT · RECAP

Un comando genera todo, el contrato ejecutable

📝
/enrich-us
Enriquecer
💡
/opsx:propose
Proposal+Spec+Design+Tasks
⚙️
/opsx:apply
Apply
🔍
/opsx:verify
Verify
⚖️
/adversarial-review
Review
📦
/opsx:archive
Archive
🚀
/commit
Commit+PR

La especificación ES el contrato: el código viene después. Si cambias de idea, actualizas la spec primero.

# Hoy hacemos el ciclo completo sobre ONEDEV-218 (dedup)
/enrich-us/opsx:propose/opsx:apply/opsx:verify/adversarial-review/opsx:archive/commit
LIGA SDD · MAPA DE JUEGO
DÓNDE ESTAMOS

El ciclo completo, bloque por bloque

🔧
Setup
📝
Recap
💡
Propose
Spec

Pausa 1
🏗️
Design
Tasks
⚙️
Apply
TDD

Pausa 2
🔍
Verify
Review
🚀
PR
Archive
🏆
Podio
700XP Total
5Misiones
5Badges
2Pausas
BLOQUE 2 DE 6
MISIÓN 1 · +150 XP · BADGE SPEC SMITH

Propose → Spec

Convertir ONEDEV-218 en una spec ejecutable que el equipo y la IA puedan seguir.

02
BLOQUE 2 · PROPOSE
PASO 1 DE 2 · /ENRICH-US · 15'

Enriquecer la US antes de planificar

# 1. Abre examples/onedev-63/enriched-us.md
#    Úsalo como referencia o pégalo en Claude

/enrich-us

# Claude hace preguntas sobre:
#  · Reglas de negocio del dedup
#  · Edge cases (fuerza, race condition)
#  · Criterios de aceptación precisos
QUÉ PRODUCE
  • Historia enriquecida con ACs precisos
  • Casos borde documentados (force, IntegrityError)
  • Contexto técnico para el siguiente paso
  • Todo listo para /opsx:propose

Tip: el archivo examples/onedev-63/enriched-us.md ya tiene el ejemplo completo de ONEDEV-218. Úsalo si el tiempo aprieta.

BLOQUE 2 · PROPOSE
QUÉ ES UNA US ENRIQUECIDA

Cuatro secciones, cero ambigüedad

01
Historia + contexto
Como operador de ingesta, quiero que el sistema salte archivos ya procesados para evitar duplicar readings.
02
Criterios de aceptación (ACs)
AC-1: duplicado detectado antes de ingestar. AC-2: archivo nuevo sigue normal. AC-3: race condition manejado. AC-4: flag force.
03
Notas técnicas
Hash = SHA-256 del contenido del archivo. Campo sha256_hash en raw_files con índice UNIQUE.
04
Kata TDD
compute_sha256(content: bytes) → str es pura. test_compute_sha256_returns_64_char_hex() es el primer test.
BLOQUE 2 · PROPOSE
PASO 2 DE 3 · /OPSX:PROPOSE · 15'

Generar el Proposal: el QUÉ y el POR QUÉ

# Con la US enriquecida activa en el contexto
/opsx:propose

# Claude genera TODOS los artifacts en un paso:
#  · proposal.md — objetivo, alcance, riesgos
#  · spec.md     — ACs formales + escenarios
#  · design.md   — decisiones técnicas
#  · tasks.md    — lista de tareas ordenadas
EL PROPOSAL INCLUYE
  • Objetivo de negocio (por qué importa el dedup)
  • Alcance: qué sí / qué no (ONEDEV-218 only)
  • Riesgos y decisiones abiertas
VERSIÓN ANTERIOR (EQUIVALENTE)
  • /new — inicia el change en OpenSpec
  • /ff — genera los artifacts (fast-forward)
  • /new + /ff = /opsx:propose
BLOQUE 2 · SPEC
ARTIFACTS GENERADOS · REVISAR Y VALIDAR

Cuatro archivos en openspec/changes/dedup-218/

La spec no es documentación. Es el contrato que la IA va a ejecutar en /opsx:apply y que /opsx:verify va a comprobar. Si la spec es ambigua, el código también lo será.

# Estructura esperada en openspec/changes/dedup-218/
proposal.md    ← PRD con objetivo, alcance, riesgos
spec.md        ← ACs formales + escenarios
design.md      ← (siguiente bloque)
tasks.md       ← (siguiente bloque)
apply-progress.md  ← (bloque 4)
verify-report.md   ← (bloque 5)
✅ MISIÓN 1 COMPLETADA cuando
  • proposal.md y spec.md existen en openspec/changes/
  • Los 4 ACs están capturados con criterios claros
  • El scope no incluye scrapers, S3 ni Lambda
LIGA SDD · CHECKPOINT
ANTES DE LA PAUSA

Misión 1: ¿quién lo tiene?

150XP · Misión 1
⚒️Badge Spec Smith
2archivos en openspec/
CRITERIO DE "HECHO" — MISIÓN 1
  • proposal.md generado y revisado
  • spec.md con los 4 ACs de ONEDEV-218
  • ✅ El scope excluye scrapers, S3 y Lambda explícitamente
  • ✅ Commit realizado: feat: add spec for ONEDEV-218 dedup

Si no llegas al commit, guarda el trabajo igualmente — en la pausa lo sincronizamos.

☕ PAUSA 1
CHECKPOINT LEADERBOARD #1

15 minutos y primer podio

🥇1er lugar
🥈2do lugar
🥉3er lugar
XP
Misión 1 completada → 150 XP + badge Spec Smith ⚒️
📋
proposal.md + spec.md en openspec/changes/dedup-218/
Volvemos en 15 minutos — Bloque 3: Design + Tasks
BLOQUE 3 DE 6
MISIÓN 2 · +100 XP · BADGE ARCHITECT

Design → Tasks

Del spec al plan de ejecución: arquitectura técnica y lista de tareas ordenada.

03
BLOQUE 3 · DESIGN + TASKS
DESIGN + TASKS · GENERADOS POR /OPSX:PROPOSE · 35'

Revisar y ajustar lo que generó /opsx:propose

# /opsx:propose ya generó design.md y tasks.md — revisar en openspec/changes/dedup-218/

# design.md: verificar decisiones clave
#  · Diagrama de flujo: compute_sha256 → is_duplicate → IntegrityError
#  · Decisión: UNIQUE index como safety net (no solo app-level check)
#  · Estructura: services/dedup.py + models/raw_file.py

# tasks.md: verificar orden y estimaciones
#  · T1: compute_sha256 + unit test (0.5 SP)
#  · T2: is_duplicate + integration test (1 SP)
#  · T3: integración en flujo + flag force (1 SP)
#  · T4: race condition IntegrityError (0.5 SP)
BLOQUE 3 · TASKS
QUÉ ESPERAR DEL TASK BREAKDOWN

Cuatro tareas, orden de dependencias

T1
compute_sha256 + unit test · 0.5 SP
tests/unit/test_dedup.py: test_compute_sha256_returns_64_char_hex(). Mínima implementación: hashlib.sha256(content).hexdigest().
T2
is_duplicate + integration test · 1 SP
tests/integration/test_ingest_api.py: fixture de RawFile ya ingested. Query a BD con sha256_hash + status='ingested'.
T3
Integración en flujo + flag force · 1 SP
Modificar el pipeline de ingesta. POST /ingest/trigger acepta force: bool. Status 'duplicate' vs 'skipped'.
T4
Race condition IntegrityError · 0.5 SP
try/except IntegrityError en register_raw_file. db.rollback(). Log WARNING 'ingest.dedup.race_condition'.
LIGA SDD · MISIÓN 2
COMPLETADA

Design + Tasks: +100 XP · badge Architect 🏗️

250XP Acumulado
🏗️Badge Architect
4Archivos en openspec/
CRITERIO DE "HECHO" — MISIÓN 2
  • design.md con la decisión de UNIQUE index documentada
  • tasks.md con las 4 tareas ordenadas y estimadas
  • ✅ Las dependencias entre tareas son explícitas (T1 antes de T2)
  • ✅ El test approach de cada tarea está especificado
BLOQUE 4 DE 6
MISIÓN 3 · +200 XP · BADGE GREEN BAR

Apply con TDD estricto

RED → GREEN → REFACTOR. El test primero, siempre, sin excepción.

04
BLOQUE 4 · APPLY · TDD
PASO 1: RED · EL TEST ANTES

Primero el test, aunque duela

# tests/unit/test_dedup.py
# Escribir ANTES de abrir services/dedup.py

from src.grid_service.services.dedup import compute_sha256

def test_compute_sha256_returns_64_char_hex() -> None:
    result = compute_sha256(b"hello world")
    assert len(result) == 64
    assert all(c in "0123456789abcdef" for c in result)

def test_sha256_is_deterministic() -> None:
    content = b"grid capacity"
    assert compute_sha256(content) == compute_sha256(content)

# Ejecutar → FALLA (ImportError o AssertionError)
pytest tests/unit/test_dedup.py -v
# Expected: FAILED ← esto es correcto

Si el test no falla antes de escribir el código, el test no vale nada.

BLOQUE 4 · APPLY · TDD
PASO 2: GREEN · MÍNIMA IMPLEMENTACIÓN

Solo lo justo para pasar el test

# src/grid_service/services/dedup.py
import hashlib
from sqlalchemy.orm import Session
from ..models.raw_file import RawFile

def compute_sha256(content: bytes) -> str:
    """Return hex SHA-256 digest of content."""
    return hashlib.sha256(content).hexdigest()

# Ejecutar → VERDE
pytest tests/unit/test_dedup.py -v
# Expected: PASSED ✅

No agregar nada más. Mínima implementación. El refactor viene después.

BLOQUE 4 · APPLY · TDD
PASO 3: REFACTOR + AÑADIR T2-T4

Sin romper nada, añadir is_duplicate

# /opsx:apply continúa con las tareas T2–T4
/opsx:apply

# Claude implementa:
#  T2: is_duplicate(db, sha256_hash) + integration test
#  T3: integración en flujo de ingesta + flag force
#  T4: try/except IntegrityError + log WARNING

# Mantiene todos los tests en verde
pytest --cov=src tests/
# Expected: PASSED · coverage report

# Verificar estilo
black . && ruff check .
EL APPLY HACE TDD AUTOMÁTICO CON STRICT TDD MODE
  • Detecta que tienes pytest configurado → activa Strict TDD Mode
  • Escribe test fallido primero para cada tarea
  • Solo después implementa la lógica
BLOQUE 4 · APPLY
QUÉ ESPERAR AL FINAL DEL /OPSX:APPLY

Cuatro tareas, todos los tests verdes

ARCHIVOS CREADOS/MODIFICADOS
src/grid_service/services/dedup.py
src/grid_service/models/raw_file.py
src/grid_service/api/ingest.py  ← modif
tests/unit/test_dedup.py
tests/integration/test_ingest_api.py
tests/conftest.py  ← fixtures DB
SALIDA ESPERADA
pytest --cov=src tests/

====== test session starts ======
tests/unit/test_dedup.py ....  PASSED
tests/integration/test_ingest.py ..  PASSED

6 passed in 1.23s
Coverage: src/grid_service/services/dedup.py: 94%
LIGA SDD · MISIÓN 3
COMPLETADA

Apply TDD: +200 XP · badge Green Bar 🟢

450XP Acumulado
🟢Badge Green Bar
100%Tests verdes
CRITERIO DE "HECHO" — MISIÓN 3
  • pytest --cov=src tests/ pasa sin errores
  • black . y ruff check . sin issues
  • compute_sha256 e is_duplicate en services/dedup.py
  • ✅ Race condition manejado con IntegrityError
  • ✅ Flag force implementado en POST /ingest/trigger
☕ PAUSA 2
CHECKPOINT LEADERBOARD #2

15 minutos y segundo podio

🥇1er lugar
🥈2do lugar
🥉3er lugar
M3
Apply TDD completado → +200 XP · badge Green Bar 🟢
📊
Acumulado: 450 XP para los que tienen las 3 misiones
Volvemos en 15 min — Bloque 5: Verify + Adversarial Review
BLOQUE 5 DE 6
MISIÓN 4 · +150 XP · BADGE JUDGE'S VERDICT

Verify + Adversarial Review

Primero la IA verifica contra la spec. Luego dos jueces ciegos se intentan refutar mutuamente.

05
BLOQUE 5 · VERIFY
/OPSX:VERIFY — VALIDACIÓN CONTRA LA SPEC · 15'

La IA revisa su propio trabajo

/opsx:verify

# Claude compara la implementación contra spec.md + tasks.md
# Produce verify-report.md con:
#  CRITICAL — falla de un AC (bloqueante)
#  WARNING  — no sigue el diseño (revisar)
#  SUGGESTION — mejora opcional

# Si hay un CRITICAL, /opsx:apply de nuevo antes de continuar
QUÉ ESPERAR
  • Los 4 ACs verificados: ✅ PASSED o ❌ FAILED
  • Cobertura de tests comprobada
  • Ningún CRITICAL si el apply fue correcto
  • Posible WARNING sobre mypy (upgrade no activo aún)
BLOQUE 5 · ADVERSARIAL REVIEW
EL BOSS FIGHT · /ADVERSARIAL-REVIEW · 20'

¿Tu código sobrevive a dos jueces?

/adversarial-review

# Dos jueces ciegos, en paralelo, con una misión:
# REFUTAR el código. Buscar bugs, edge cases, problemas.

# Juez A — correctness + security
# Juez B — resilience + performance

# El voto: si ≥2 de 3 jueces confirman → el bug es real
# Si refutan → el código sobrevive
POSIBLES FINDINGS
  • ¿Qué pasa si content es un archivo vacío?
  • ¿El rollback en IntegrityError es completo?
  • ¿Se loguea el hash completo o solo el prefix?
LO QUE LOS JUECES NO PUEDEN TOCAR
  • El código pasa los tests → no pueden negar eso
  • El AC-3 (race condition) está cubierto
  • El índice UNIQUE es el safety net
BLOQUE 5 · ADVERSARIAL REVIEW
QUÉ HACE EL EQUIPO CON LOS FINDINGS

Discernir, decidir, actuar

CONFIRMED

Ambos jueces lo encontraron. Es un bug real. /opsx:apply de nuevo para corregirlo antes de continuar.

PLAUSIBLE

Solo un juez lo encontró. Revisar en equipo: ¿es un edge case real o hipotético? Decidir si bloquea o va al backlog.

REFUTED

Los jueces no pudieron encontrar el bug. El código sobrevive al boss fight. Continuar.

El adversarial review no es para criticar. Es para que el equipo aprenda a leer código con ojos críticos.

LIGA SDD · MISIÓN 4
COMPLETADA

Verify + Review: +150 XP · badge Judge's Verdict ⚖️

600XP Acumulado
⚖️Badge Judge's Verdict
0CRITICAL issues
CRITERIO DE "HECHO" — MISIÓN 4
  • verify-report.md generado sin CRITICAL
  • ✅ Todos los ACs verificados como PASSED
  • ✅ Adversarial review completado (0 CONFIRMED o corregidos)
  • ✅ Cualquier PLAUSIBLE anotado en el backlog o cerrado
BLOQUE 6 DE 6
MISIÓN 5 · +100 XP · BADGE SHIPPER

PR + Archive

Commit convencional, Pull Request con review automática, cierre del ciclo SDD.

06
BLOQUE 6 · PR
/COMMIT + PR · 15'

Conventional commit y PR generado por IA

/commit

# Claude propone el commit message
# feat: add SHA-256 file-level deduplication for raw ingestion files
# test: add unit + integration tests for dedup service
# fix: handle IntegrityError race condition in concurrent ingest

# Luego genera el PR description
## Summary
- Implements file-level dedup via SHA-256 hash in raw_files
- Handles concurrent ingest race condition via IntegrityError catch
- force flag allows re-ingestion when needed

## Test plan
- [ ] pytest tests/unit/test_dedup.py
- [ ] pytest tests/integration/test_ingest_api.py
BLOQUE 6 · PR
CI EN MARCHA

GitHub Actions: pre-commit + tests automáticos

pre-commit.yml
on: [push, pull_request]
jobs:
  pre-commit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pre-commit/action@v3
        # black + ruff + file hygiene
tests.yml
services:
  postgres:
    image: postgres:15
steps:
  - name: Test
    run: pytest --cov=src tests/
    # Requiere BD activa para integration

El CI de OHE ya tiene estos dos workflows. El PR se va a revisar automáticamente cuando hagas push.

BLOQUE 6 · ARCHIVE
/OPSX:ARCHIVE — CERRAR EL CICLO SDD · 10'

El cambio queda sellado

/opsx:archive

# Claude genera archive-report.md con:
#  · Resumen del cambio implementado
#  · ACs verificados y su estado final
#  · Lessons learned del adversarial review
#  · Referencia al PR mergeado

# Mueve los artifacts a openspec/archive/dedup-218/
EL CICLO COMPLETO
enrich-us
propose
spec
design
tasks
apply
TDD
verify
review
PR
merge
archive
LIGA SDD · PODIO FINAL
LEADERBOARD

Los ganadores de la sesión

🥇1er lugar
🥈2do lugar
🥉3er lugar
BADGES DEL DÍA
  • ⚒️ Spec Smith
  • 🏗️ Architect
  • 🟢 Green Bar
  • ⚖️ Judge's Verdict
  • 🚀 Shipper
PRÓXIMOS PASOS
  • Scrapers en paralelo: 1 dev/scraper (ONEDEV-212-216)
  • Cada scraper: mismo ciclo SDD con el kit
  • PR review automática cuando hagáis push
  • Sesión 3: estándar del equipo + primer agente personal
LO QUE HICIMOS HOY
  • Ciclo SDD completo en 4 horas reales
  • TDD estricto con pytest en Python
  • Adversarial review con doble juez
  • PR generado con IA + CI automático
×
PRÓXIMOS PASOS
Lo que sale
de esta sesión

Cada dev sale con el SDD kit instalado, un ciclo SDD completo sobre ONEDEV-218 (TDD estricto, verify + AI code review y PR generado) y el flujo /opsx dominado. Lo que quede, en deberes para la Sesión 3.

1 · SDD kit instalado 2 · Ciclo SDD completo sobre ONEDEV-218 3 · Verify + AI review + PR Digital Tools · One Hub Energy