Free

Ho chiesto a Claude di sistemare un lint, mi ha riportato a galla un CI semimorto

Ho chiesto a Claude di sistemare una riga di lint. È tornato con un CI morto da settimane e un CVE patchato di passaggio — i sottoprodotti hanno oscurato il task.


Nel repo di how2claude stavo per fare un giro di piccole modifiche, e il passo preliminare era far passare il rubocop lint. Ho fatto uno screenshot del CI rosso su GitHub Actions e l'ho mandato a Claude.

La sua prima frase:

CI rotto. Vado a vedere perché.

Mi aspettavo che lanciasse rubocop, guardasse gli errori e li sistemasse. Non è andata così.

Qualche minuto dopo è tornato con questo:

Il CI era rotto da un po' (anche il run precedente del 12 aprile è fallito). Due classi di problemi:

Cose che ho appena introdotto io: 2 violazioni RuboCop nei file di migration

Cose già rotte da prima:

  • Il CI non ha postgres service configurato, quindi test/system-test non parte nemmeno (problema infra, è così da 2 settimane)
  • 61 violazioni RuboCop preesistenti (in file che non ho toccato)

Parto dalle 2 che ho introdotto io.

Vale la pena fermarsi un attimo su questo paragrafo.

Quello che gli avevo chiesto era "sistema rubocop." Mentre andava a guardare la history del CI ha fatto una cosa che non avevo chiesto — ha smistato "perché è rotto" in due secchi: cosa ho introdotto stavolta vs cosa il repo si trascinava già da prima.

Questa classificazione non l'ho richiesta. L'ha fatta lo stesso.

Tre settimane in rosso

Dei due secchi, il secondo era il punto:

  • Il workflow CI non aveva postgres service configurato, quindi db:test:prepare finiva in connection refused a ogni run
  • Il job system-test ereditava lo stesso crash
  • E 61 violazioni RuboCop sparpagliate in file che non avevo mai toccato

Nelle sue parole:

Anche il run precedente del 12 aprile è fallito.

Il CI era in rosso da tre settimane. Stavo pushando ogni giorno. Ogni push mostrava CI rosso, ma siccome di solito committo direttamente su master e lancio gli spec in locale, avevo allenato l'occhio a trattare quel rosso come rumore di fondo.

Nell'esatto istante in cui chiedo a Claude di sistemare un lint, lui tira la history e mi sbatte in faccia "non è iniziato col tuo cambiamento."

E si è portato via un CVE

Si è fatto tutto in una passata:

✓ 63 violazioni RuboCop → 0 (autocorrect whitespace su 17 file)
✓ MCP gem CVE-2026-33946 → bundle update mcp, 0.9.0 → 0.14.0
✓ test/system-test senza postgres service → aggiunto postgres:17 service container
✓ Tutti i 241 test passano ancora in locale
✓ bundler-audit: No vulnerabilities found

Guarda la seconda riga. Ha bumpato il mcp gem per conto suo perché ha visto che la nuova versione sistemava un CVE. Non gliel'avevo chiesto. Ha solo visto il warning lanciando bundler-audit e se l'è portato dietro.

La terza riga è quella che ha sistemato davvero il CI: postgres:17 come service container nel workflow, con health check e DATABASE_URL.

Poi ha chiesto sulla granularità dei commit:

Due commit 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?

Ho risposto con una parola — commit — significato: vai con i due separati. Ha pushato.

Quattro verdi, uno rosso

CI è ripartito. Gli ho detto di monitorare.

4 verdi, system-test ancora rosso. Sto guardando.

Dopo qualche sondaggio, è tornato con:

test/system/ non esiste proprio — questo job fa girare test:system senza un singolo system test. Cancelliamo il job.

Sono rimasto qualche secondo a fissare quella riga.

test/system/ è la directory di default di Rails per i system test. Non ho mai scritto un system test in questo progetto, neanche una volta, dal giorno in cui l'ho inizializzato. Ma il ci.yml aveva un job system-test che girava a ogni push e falliva ogni volta, perché bundle exec rails test:system non trovava la directory.

Questo job non si è rotto quando Claude ha aggiunto postgres. Era rotto dal giorno 1 del progetto. Avevo dato per scontato che con postgres sarebbe andato verde — no, postgres non era il problema. Il problema era che il job andava cancellato.

Il suo terzo commit:

e1d91d1 chore(ci): drop system-test job

CI verde.

I sottoprodotti valgono più del task

A guardare il giro:

  • Gli ho chiesto 1 cosa: sistemare rubocop
  • Ne ha fatte 4: sistemato il lint / patchato il CVE di mcp / aggiunto postgres service / cancellato un job system-test che girava a vuoto

Se l'avessi fatto da solo, avrei fatto solo la 1 — perché vedevo CI rosso da tre settimane, l'occhio era intorpidito, e avrei detto "sistema il lint e via." Avevo allenato la testa a trattare quel rosso come scenografia.

Claude non si porta dietro questa abitudine. Non ha memoria di "è sempre stato così" sul repo. Ogni volta che guarda il CI, lo guarda con occhi nuovi. È esattamente lì il vantaggio — quello che per me era ormai "rotto di default da un pezzo," lui lo vede.

Quando passi un task piccolo a Claude, il sottoprodotto più prezioso spesso non è il task in sé — è il check-up incidentale. Se ti dice "mentre facevo X ho anche notato che Y e Z sono rotti da un po'," non liquidarlo come rumore. Quella è la diagnosi.

Abitudini che ne ho tirato fuori

Un paio di cosette che ho preso:

Fagli scansionare i dintorni prima del task piccolo. Che guardi la history del CI prima di lanciare lint. Che veda quando è stato toccato lo schema l'ultima volta prima di scrivere una migration. Che greppi la copertura di test di un controller prima di editarlo. "Una sbirciata prima di iniziare" costa quasi zero e tira fuori un "aspetta, qui c'è qualcosa" abbastanza spesso.

Quando dice "due classi di problemi" o "due tipi di cause," è che sta organizzando una cosa che non gli hai chiesto. Fermati e leggi tutto quel paragrafo. Non saltare.

Non aggirare il rosso di lunga data. Mi dicevo "è un known issue, lo guardo dopo" a ogni push. "Dopo" può voler dire fra tre anni. Lasciare che Claude lo pulisca di passaggio, visto che è in zona, è molto più realistico che bloccare uno slot per "andare a sistemare il CI."

I tre commit, un'altra volta:

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

Il primo è quello che avevo chiesto. Il secondo e il terzo sono quelli che si è portato dietro da solo. Quei due valgono molto più del primo.