Free

Le pedí a Claude que arreglara un lint y me devolvió un CI medio muerto

Le pedí a Claude una corrección de lint. Me trajo de vuelta un CI muerto desde hacía semanas y un CVE parcheado de propina — los subproductos eclipsaron la tarea.


En el repo de how2claude estaba a punto de hacer una tanda de pequeñas ediciones, y el paso previo era pasar el rubocop lint. Hice una captura del CI rojo en GitHub Actions y se la pasé a Claude.

Su primera frase:

CI está caído. Voy a ver por qué.

Asumí que iba a correr rubocop, mirar los errores y arreglarlos. No fue así.

Unos minutos después me devolvió esto:

CI llevaba un rato caído (la run anterior del 12 de abril también falló). Dos clases de problema:

Cosas que acabo de meter yo: 2 RuboCop violations en archivos de migración

Cosas que ya estaban rotas:

  • El CI no tiene postgres service configurado, así que test/system-test ni siquiera arrancan (problema de infra, lleva 2 semanas así)
  • 61 RuboCop violations preexistentes (en archivos que no toqué)

Empiezo arreglando las 2 que metí yo.

Vale la pena pararse un segundo en este párrafo.

Lo que le pedí fue "arregla rubocop". Mientras revisaba el historial del CI hizo algo que no le pedí — clasificó "por qué está roto" en dos cubos: lo que metí yo esta vez vs lo que el repo ya arrastraba.

Esa clasificación no la pedí. La hizo igual.

Tres semanas en rojo

De los dos cubos, el segundo era el meollo:

  • El workflow de CI no tenía postgres service configurado, así que db:test:prepare se quedaba en connection refused cada vez
  • El job system-test heredaba el mismo fallo
  • Y 61 RuboCop violations dispersas por archivos que jamás había tocado

En sus palabras:

La run anterior del 12 de abril también falló.

CI llevaba tres semanas en rojo. Yo había estado pusheando todos los días. Cada push mostraba un CI rojo, pero como suelo commitear directo a master y correr specs en local, había entrenado el ojo a tratar ese rojo como ruido de fondo.

En el momento en que le pedí a Claude que arreglara un lint, se trajo el historial y me empujó "esto no empezó con tu cambio" a la cara.

Y de paso liquidó un CVE

Se mandó todo de una pasada:

✓ 63 RuboCop violations → 0 (autocorrect de whitespace en 17 archivos)
✓ MCP gem CVE-2026-33946 → bundle update mcp, 0.9.0 → 0.14.0
✓ test/system-test sin postgres service → añadido postgres:17 service container
✓ Los 241 tests siguen pasando en local
✓ bundler-audit: No vulnerabilities found

Mira la segunda línea. Subió la versión del mcp gem por su cuenta porque vio que la nueva arreglaba un CVE. No se lo pedí. Simplemente vio el aviso al correr bundler-audit y se lo trajo de propina.

La tercera línea es la que de verdad arregló el CI: postgres:17 como service container en el workflow, con health check y DATABASE_URL.

Después preguntó por la granularidad de los commits:

¿Dos commits o uno?

  • chore(lint): rubocop autocorrect (whitespace only)
  • fix(ci): add postgres service + bump mcp gem for CVE-2026-33946

¿O uno: fix(ci): make CI green again?

Respondí con una palabra — commit — significando que vaya con la división en dos. Pusheó.

Cuatro verdes, uno rojo

CI volvió a correr. Le dije que monitoreara.

4 verdes, system-test sigue rojo. Mirando.

Tras un par de pinchazos vino esto:

test/system/ ni siquiera existe — este job corre test:system sin un solo system test. Borremos el job.

Me quedé varios segundos mirando esa línea.

test/system/ es el directorio por defecto de Rails para system tests. Nunca había escrito un system test en este proyecto, ni una vez, desde que lo init-é. Pero ci.yml tenía un job system-test que corría en cada push y fallaba siempre porque bundle exec rails test:system no encontraba el directorio.

Este job no se rompió cuando Claude añadió postgres. Llevaba roto desde el día uno del proyecto. Yo había asumido que con postgres se pondría verde — resultó que postgres no era el problema. El problema era que el job tenía que desaparecer.

Su tercer commit:

e1d91d1 chore(ci): drop system-test job

CI verde.

Los subproductos valen más que la tarea

Mirando atrás:

  • Le pedí 1 cosa: arreglar rubocop
  • Hizo 4: arreglar lint / parchear CVE de mcp / añadir postgres service / borrar un system-test job que llevaba años en vacío

Si lo hubiera hecho yo solo, habría hecho solo la 1 — porque llevaba tres semanas viendo el CI rojo, tenía el ojo entumecido, y habría dicho "arreglo el lint y a otra cosa". Había entrenado al cerebro a tratar ese rojo como decorado.

Claude no carga ese hábito. No tiene memoria de "esto siempre fue así" sobre el repo. Cada vez que mira el CI lo mira con ojos nuevos. Eso es justo la ventaja — lo que para mí ya era "roto por defecto desde hace tiempo," él lo ve.

Cuando le pasas a Claude una tarea pequeña, el subproducto más valioso suele no ser la tarea hecha — es el chequeo de salud incidental. Si te dice "mientras hacía X también vi que Y y Z llevan rotos un rato," no lo descartes como ruido. Es el diagnóstico.

Hábitos que saqué de aquí

Algunas cosas pequeñas que adopté:

Hazle escanear el entorno antes de la tarea pequeña. Que mire el historial del CI antes de correr lint. Que vea cuándo se tocó el schema antes de escribir una migración. Que haga un grep de la cobertura de tests del controller antes de editarlo. "Una mirada antes de empezar" cuesta casi nada y suelta un "espera, hay algo aquí" con bastante frecuencia.

Cuando dice "dos clases de problemas" o "dos tipos de causas," eso es organización que no le pediste. Para y léete ese párrafo entero. No lo saltes.

No esquives lo que lleva mucho en rojo. Llevaba diciéndome "es un known issue, lo veo más adelante" cada vez que pusheaba. "Más adelante" puede ser tres años. Dejar que Claude lo limpie de paso, ya que está cerca, es mucho más realista que reservar un día específico para "ir a arreglar el CI."

Los tres commits, una vez más:

74a3ebf  chore(lint): rubocop autocorrect — Layout cops only
76264ee  fix(ci): add postgres service + bump mcp gem for CVE-2026-33946
e1d91d1  chore(ci): drop system-test job

El primero es el que pedí. El segundo y el tercero son los que se trajo solo. Esos dos valen mucho más que el primero.