Workflow CDAID — Practicas de Desarrollo Asistido por IA¶
SDD (Spec-Driven Development) — Metodologia principal¶
Desde el Sprint 23, el proyecto usa SDD como metodologia de desarrollo agentico:
- Spec escrito primero: Documento
XX_SDD_SPEC_*.mdcon criterios de aceptacion verificables, IDs unicos, lineas exactas del codigo a modificar - Implementacion por SPEC: Cada SPEC se implementa atomicamente con commit referenciado
- Cotejo post-implementacion: Auditoria campo por campo (spec vs codigo real)
- Certificacion: Resultado documentado en
XX_AUDITORIA_SDD_*.md
Estructura de un SPEC¶
### SPEC-S{sprint}-{fase}{N}: NombreDescriptivo
| Campo | Valor |
|-------|-------|
| **Servicio** | `src/sherlock_docs/application/services/xxx_service.py` |
| **Pagina GUI** | `src/sherlock_docs/interfaces/gui/pages/xxx.py` |
| **LOC duplicadas** | `xxx.py:100-150` = `xxx_service.py:50-100` (50 lineas) |
| **Estado** | `[x]` |
**Cambios requeridos**: (numerados)
**Criterios de aceptacion**: (checkboxes verificables)
**Verificado**: commit hash
Protocolo de auditoria SDD (8 puntos)¶
| Punto | Verifica |
|---|---|
| P1 | DTO en dtos.py — frozen, campos, JSON |
| P2 | Metodo *_result() — firma, Result, Success/Failure |
| P3 | Backward compat — metodo original intacto |
| P4 | ServiceContainer — property lazy, lock, init None |
| P5 | GUI delega — no repository directo para la operacion |
| P6 | Tests — Success, Failure, frozen, JSON, cantidad |
| P7 | Smells — Feature Envy, Duplicate Code, Dead Code eliminados |
| P8 | Patterns — Facade, DI, ROP |
Clasificacion de divergencias¶
| Tipo | Significado | Accion |
|---|---|---|
| CONFORME | Codigo = spec | Ninguna |
| DIVERGENCIA JUSTIFICADA | Difiere pero es mejor | Documentar razon |
| DIVERGENCIA MENOR | Difiere en nombre/tipo | Evaluar |
| DEFECTO | No cumple intencion | Corregir |
TDD Formal (test-first con agentes)¶
Para features nuevas, seguir este orden:
- Humano define criterios de aceptacion
- Agente escribe tests que deben FALLAR (
pytest -xconfirma fallo) - Commit tests por separado
- Agente implementa codigo hasta que tests pasen
- Commit codigo
- Gate: cobertura no puede bajar (
pytest --cov>= baseline)
Por que: Previene que el agente escriba tests que verifican comportamiento roto.
Checklist Pattern¶
Para sprints o tareas con >3 items, crear checklist operativo:
Actualizar en tiempo real durante la sesion. No es documentacion post-hoc sino herramienta de tracking activo.
Compactacion Deliberada¶
No depender de la auto-compactacion (83.5% de capacidad). Compactar manualmente:
/compactal terminar cada fix/feature/clearal cambiar de sprint/planning/tema/compact focus on [tema actual]al iniciar tarea compleja
Hooks como Quality Gates¶
Los hooks de .claude/settings.json ejecutan quality gates en cada operacion del agente:
- PostToolUse (Edit/Write):
ruff check --fix+ruff formaten archivos.py - Deteccion inmediata de errores de estilo/lint vs esperar al pre-commit
- Si un hook falla, investigar la causa — no desactivar el hook
Verificacion Pre-Commit¶
Antes de cada commit, verificar:
pytest -x # Tests pasan
ruff check src/ # Sin errores lint
ruff format --check src/ # Formato correcto
mypy src/ --strict --ignore-missing-imports # Type checking (0 errores)
Para verificacion completa usar el CI local:
bash scripts/ci_local.sh --quick # Lint + mypy + tests + coverage (~1 min)
bash scripts/ci_local.sh # Completo: + bandit + integration tests (~2 min)
CI/CD — Integracion y Despliegue Continuo¶
No usamos GitHub Actions. CI es local (
scripts/ci_local.sh) y CD es automatico via Easypanel + Webhooks.
Arquitectura del flujo¶
Desarrollo local GitHub VPS (Easypanel)
───────────────── ──────────── ──────────────────
editar codigo
│
ci_local.sh ──── gate local (5 checks)
│
git commit
│
git push main ──────► repo privado
│
├─ webhook HTTPS ────────► Easypanel (panel.sprintjudicial.com)
│ (POST push event) │
│ ├─ git clone via Deploy Key SSH
│ ├─ docker build (Dockerfile + BuildKit)
│ └─ swap contenedor (zero-downtime)
│
└─ 2 webhooks configurados:
1. sherlock-docs (GUI Streamlit)
2. sherlock-api (API FastAPI)
Procedimiento completo para hacer push a produccion¶
# Paso 1: Verificar que todo esta limpio
git status # Sin cambios sin commitear
# Paso 2: CI local COMPLETO (obligatorio antes de push)
bash scripts/ci_local.sh # ~2 min: lint + mypy + bandit + tests + integration
# Si falla: corregir ANTES de push
# Paso 3: Push
git push origin main # Dispara webhooks automaticamente
# Paso 4: Verificar deploy (esperar ~3-8 min para build Docker en VPS)
# Primer build: ~8-10 min (descarga dependencias)
# Builds subsecuentes: ~2-5 min (cache BuildKit)
curl -sf https://sherlock.sprintjudicial.com/_stcore/health && echo "GUI OK"
curl -sf https://api.sherlock.sprintjudicial.com/api/v1/health && echo "API OK"
CI Local (scripts/ci_local.sh)¶
Unica barrera de calidad — no hay CI remoto.
| Step | Que ejecuta | Gate |
|---|---|---|
| 1. Lint | ruff check src/ + ruff format --check src/ |
Bloquea si hay errores |
| 2. Types | mypy src/ --strict --ignore-missing-imports |
0 errores |
| 3. Security | bandit -r src/ -ll --skip B301,B608 |
Sin CRITICAL/HIGH |
| 4. Tests | pytest tests/unit/ --cov=src --cov-fail-under=83 |
Coverage >= 83% |
| 5. Integration | pytest tests/integration/ -m integration |
Todos pasan |
Modos de ejecucion:
bash scripts/ci_local.sh # Completo (5 steps) — OBLIGATORIO antes de push
bash scripts/ci_local.sh --quick # Steps 1-2-4 — solo durante desarrollo iterativo
CD Aplicacion (Easypanel)¶
Flujo automatico: Push a main -> Webhook GitHub -> Easypanel -> build -> deploy.
Infraestructura:
- PaaS: Easypanel autoalojado en VPS (Ubuntu 24.04, 2 vCPU, 7.8 GB RAM)
- Panel: https://panel.sprintjudicial.com (acceso administrador)
- Conexion al repo: Deploy Key SSH (repo privado GitHub)
- Build: Dockerfile en raiz del proyecto, BuildKit habilitado
- Cache Docker: --mount=type=cache,target=/root/.cache/pip (pip no redescarga 2GB cada vez)
Servicios desplegados:
| Servicio | Puerto | SHERLOCK_MODE | URL produccion | Webhook |
|---|---|---|---|---|
| GUI (Streamlit) | 8501 | gui |
https://sherlock.sprintjudicial.com | panel.sprintjudicial.com/api/deploy/... |
| API (FastAPI) | 8000 | api |
https://api.sherlock.sprintjudicial.com | panel.sprintjudicial.com/api/deploy/... |
Ambos servicios usan la misma imagen Docker (mismo Dockerfile), diferenciados por la variable SHERLOCK_MODE.
Variables de entorno configuradas en Easypanel (no en codigo):
- SHERLOCK_MODE: gui o api
- SHERLOCK_JWT_SECRET: secreto JWT para API
- SHERLOCK_AUTH_ENABLED: true en produccion
- SHERLOCK_PREWARM_MODELS: true (precarga SpaCy/PaddleOCR al inicio)
- SHERLOCK_CORS_ORIGINS: origenes permitidos
- AUTH_USERS: JSON con usuarios y hashes bcrypt
- TZ: America/Bogota
Configuracion de Webhooks (GitHub -> Easypanel)¶
Los webhooks se configuran en GitHub (repo Settings -> Webhooks) y deben apuntar al dominio HTTPS de Easypanel, no a la IP directa:
CORRECTO: https://panel.sprintjudicial.com/api/deploy/TOKEN
INCORRECTO: http://31.97.146.7:3000/api/deploy/TOKEN
La URL con IP:puerto falla porque el firewall del VPS (UFW) bloquea el puerto 3000 desde internet. Usar siempre el dominio con HTTPS (Traefik reverse proxy en Easypanel maneja el SSL y ruteo).
Verificar estado de webhooks:
# Ver webhooks configurados y su ultimo status
gh api repos/HammerDev99/sherlock-docs/hooks \
--jq '.[] | {id, url: .config.url, last_status: .last_response.code}'
# Ver entregas recientes (status_code 200 = exito, 0 = no pudo conectar)
gh api repos/HammerDev99/sherlock-docs/hooks/HOOK_ID/deliveries \
--jq '.[0:3] | .[] | {status_code, delivered_at}'
CD Sitio de Documentacion¶
El sitio MkDocs tiene su propio repo (sherlock-docs-site) y deploy independiente:
# 1. Regenerar contenido del sitio
python scripts/build_docs_site.py # Ensambla docs_site/ desde agent_docs/ + docs/
# 2. Sincronizar al directorio site/ (tiene su propio .git)
pwsh scripts/sync_docs.ps1 # Copia docs_site/ -> site/, preserva README y Dockerfile
# 3. Push del sitio (repo separado)
cd site && git add -A && git commit -m "docs: actualizar" && git push
# 4. Deploy automatico via webhook del repo sherlock-docs-site -> Easypanel -> Nginx
Importante: site/ tiene su propio .git (repo sherlock-docs-site). Los scripts preservan README.md y Dockerfile que Easypanel necesita para construir la imagen Nginx.
Deploy manual (fallback)¶
Si el webhook falla o se necesita deploy forzado:
# Opcion A: Boton "Deploy" en Easypanel
# panel.sprintjudicial.com -> servicio -> Deploy (boton manual)
# Opcion B: Script local con build en VPS
bash scripts/deploy_manual.sh --vps-build # Requiere SSH configurado (.env.deploy)
Verificacion post-deploy¶
# Health checks rapidos
curl -sf https://sherlock.sprintjudicial.com/_stcore/health && echo "GUI OK"
curl -sf https://api.sherlock.sprintjudicial.com/api/v1/health && echo "API OK"
# Health check detallado (API responde JSON con estado de componentes)
curl -s https://api.sherlock.sprintjudicial.com/api/v1/health | python -m json.tool
Troubleshooting deploy¶
| Problema | Causa probable | Solucion |
|---|---|---|
Webhook status_code: 0 |
URL usa http://IP:3000 |
Cambiar a https://panel.sprintjudicial.com/api/deploy/TOKEN |
Build falla: src does not exist |
Dockerfile copia src/ despues de pip install |
COPY src/ src/ debe ir ANTES de RUN pip install |
| Build falla: OOM | VPS sin RAM suficiente (~4 GB necesarios) | Detener servicio no esencial, reintentar |
| GUI no responde post-deploy | Container reiniciando (start-period 120s) | Esperar 2-3 min, verificar health |
| API responde 503 | SHERLOCK_PREWARM_MODELS=true cargando modelos |
Esperar 1-2 min (SpaCy + PaddleOCR) |
| Push no dispara deploy | Webhook inactivo o mal configurado | Verificar con gh api repos/.../hooks |
Multi-Claude (escritor + revisor)¶
Para features complejas, usar dos instancias de Claude Code:
- Instancia A (escritor): implementa feature en worktree aislado
- Instancia B (revisor): revisa codigo con
code-revieweragent, ejecuta tests - Humano: aprueba merge al branch principal
Agentes disponibles en .claude/agents/:
- security-scanner — audita seguridad (solo lectura)
- doc-auditor — verifica sincronizacion docs/codigo (solo lectura)
- test-generator — genera tests (solo escribe en tests/)
- code-reviewer — revisa codigo (solo lectura, modelo sonnet)
Trazas de Delegacion¶
Al documentar plannings/sprints, registrar decisiones de delegacion:
| Decision | Propuesta IA | Aprobacion Humano | Notas |
|----------|-------------|-------------------|-------|
| Refactorizar X | Si, 3 opciones | Opcion 2 aprobada | Opcion 1 sobre-ingenierada |
Scope Attenuation (permisos graduados)¶
Los sub-agentes tienen permisos restringidos segun su rol:
| Agente | Read | Grep | Write | Edit | Bash | Modelo |
|---|---|---|---|---|---|---|
| security-scanner | si | si | NO | NO | limitado | haiku |
| doc-auditor | si | si | NO | NO | NO | haiku |
| test-generator | si | si | tests/ | NO | si | haiku |
| code-reviewer | si | si | NO | NO | NO | sonnet |
Principio: cada agente recibe los permisos minimos necesarios para su tarea.
Skills de proyecto (.claude/skills/)¶
Skills disponibles para tareas especializadas:
| Skill | Cuando usar |
|---|---|
refactoring |
Code review, smell detection, refactoring |
design-patterns |
Seleccion e implementacion de patrones GoF |
systematic-debugging |
Bugs, errores, comportamiento inesperado |
streamlit |
Paginas GUI, dashboards, visualizaciones |
gobernanza-ia-judicial |
Cumplimiento PCSJA24-12243, GOBs |
senior-architect |
Decisiones arquitectonicas, diagramas |
Los skills se cargan bajo demanda con el tool Skill y proporcionan instrucciones detalladas, catalogos de referencia y ejemplos.