CreaRack-SL

CI rojo 24h por ruff format sin gemelo local

Incidenteactiveverificado 2026-04-21#incident#ci#ruff#harness

CI rojo 24h por ruff format sin gemelo local

Cuándo

20 de abril de 2026, entre 18:00-18:13 CEST. Cuatro commits consecutivos en CreaRack-Pro: ffd9cdc, caa6ad2, db273e9, f839eac. Todos tocaban Python (correcciones UI en static/js/base.js, scripts/, changelog). CI de GitHub Actions empezó a fallar tras el primer push. Bloqueo pasó desapercibido ~24h hasta la mañana del 21-04.

Síntomas

  • Pipeline CI (GitHub Actions) rojo persistente en main.
  • Job ruff fallaba con ruff format --check sobre scripts/bib_ast.py, scripts/harness/bib_report_check.py, scripts/harness/pre_commit_check.py.
  • Dokploy seguía desplegando (no tiene gate en CI), aplicación funcionaba normal, nadie recibió alerta de regresión funcional.
  • Commits del 20-04 pasaron el pre-commit hook local sin errores ni advertencias.

Causa raíz

Asimetría entre hook local y workflow CI. scripts/harness/pre_commit_check.py solo ejecutaba 3 chequeos: LOC, SQL crudo en f-strings, filtro |safe. No incluía ruff format --check.

CI, en cambio, ejecutaba ruff format --check sobre el árbol completo como parte del job lint (introducido con pin ruff==0.9.6 en 70e4e57 de la Auditoría Abril). Resultado: cuatro commits con Python sin formatear pasaron el pre-commit sin obstáculos y rompieron CI al llegar al remoto. Sin gate de despliegue en CI, incidente silencioso 24h.

Fix aplicado

81af8ca — style: ruff format sobre 3 scripts — desbloquea CI. Se ejecutó ruff format sobre los 3 archivos y se commiteó, devolviendo CI a verde.

0b429bf — chore(harness): sync pre_commit_check.py con claude-method@5f2d494. Añadida función check_ruff_format(py_files) al pre-commit hook local. Ejecuta python -m ruff format --check sobre .py staged y bloquea commit si alguno necesita reformateo. Si ruff no está instalado, check se omite silenciosamente. Propagado al repo claude-method para que todos los proyectos que usen el método lo hereden via claude-method-sync.

Lecciones (feedback_pre_commit_mirrors_ci)

Documentado en onboarding/shared-memory/feedback_pre_commit_mirrors_ci.md: todo check que corre en CI debe tener su gemelo en el pre-commit hook local. Gap entre fijación de ruff en CI (Auditoría Abril) y ausencia del check equivalente en hook permitió que commits mal formateados pasaran sin fricción local. Check en CI existe para garantizar consistencia; sin gemelo local, su única función es bloquear a posteriori cuando el daño ya está hecho.

Preventivos futuros

  • Al añadir/modificar job en .github/workflows/ci.yml, abrir scripts/harness/pre_commit_check.py en la misma PR y añadir función check_<tool>() que replique el chequeo localmente.
  • Si el check es universal (ruff, black, biome, prettier, mypy), propagarlo a claude-method para que todos los proyectos derivados lo hereden.
  • No meter en pre-commit checks que requieran suite completa (tests integración, migration checks largos): dejarlos solo en CI.
  • Validar cada nuevo check con caso negativo intencionado (romper la regla a propósito) antes de considerar el preventivo activo.
  • Evaluar si Dokploy puede tener gate opcional sobre estado de CI para visibilidad de deploys con CI roja.

Véase también

  • [[crearack-tech—method—harness-guide]] — guía maestra del Harness (sustituye a feature--harness--engineering archivada)
  • [[decision—20260417—ruff-pin]]