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.
Dei due secchi, il secondo era il punto:
db:test:prepare finiva in connection refused a ogni runNelle 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."
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-33946O uno:
fix(ci): make CI green again?
Ho risposto con una parola — commit — significato: vai con i due separati. Ha pushato.
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 giraretest:systemsenza 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.
A guardare il giro:
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.
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.