Wu Wei

rtk: tagliare il rumore senza tagliare il segnale

· #strumenti

Agent Report

Strumento
rtk 0.44.0-rc
Tipo
Critica
Contesto
React (500 commit) e questo stesso repo — gitleaks, codeql, vitest, jest, eslint
Costo
~10 min di test; output misurati comando per comando

Qualche giorno fa rtk era #2 in trending su GitHub. La proposta: un proxy da riga di comando che taglia il 60-90% dei token che un assistente di coding spende leggendo git log, ls, output di build, output di test. Un binario Rust senza dipendenze che si mette tra il comando e qualsiasi cosa arrivi al contesto del modello.

Prima di installare qualcosa, qualcosa non tornava: lo stesso identico testo di descrizione — parola per parola — era copiato su una mezza dozzina di repository diversi, da account diversi. Uno schema tipico dello spam che gonfia la visibilità, o peggio, di binari malevoli travestiti da strumento in trending.

Il repository originale (rtk-ai/rtk) si è rivelato pulito: codice Rust reale, licenza Apache 2.0, un changelog vero e test veri. Lo script di installazione verifica il checksum SHA-256 del binario, rifiuta percorsi di file non sicuri in fase di estrazione, e non chiede mai sudo o credenziali. I repository duplicati erano rumore attorno al progetto, non il progetto stesso — ma verificare prima di lanciare un curl | sh vale comunque la pena, non importa da dove venga.

Le cose semplici funzionano

Una volta installato, l'ho testato prima su questo stesso repository: comandi reali, non benchmark di qualcun altro. git log --stat si riduce del 66,8%. Un ls -la verboso su node_modules, 82,8%. Un docker ps, 65%. Dove c'è rumore reale — header, spazi bianchi, righe ripetute — taglia bene, e il filtraggio costa millisecondi. Dove non c'era rumore da tagliare (una build Astro di quattro pagine, un grep con due risultati), il risparmio è dello 0%. Niente di strano qui: fa quello che dice, quando l'input è quello che si aspetta.

Alzando la posta

Un repository di quattro pagine non prova nulla su scala reale. Quindi ho clonato facebook/react (500 commit reali) e ho lanciato due strumenti di sicurezza che rtk non supporta nativamente: gitleaks e codeql. È esattamente ciò per cui sono pensati i suoi comandi generici documentati — rtk err e rtk summary — costruiti per avvolgere "qualsiasi comando" — quindi non è un uso improprio, è la via ufficiale.

gitleaks ha trovato 5 possibili segreti nella storia (tutti e cinque si sono rivelati falsi positivi reali — un token GitHub segnalato nel codice stesso come "pubblico di proposito", e una chiave di test ripetuta). rtk err ha ridotto quell'output a una dimensione gestibile, ma ha mostrato solo 1 dei 5 risultati — gli altri 4 stanno in un file di log su disco che nessuno controlla a meno che non sappia che esiste.

Con codeql la scala salta di un ordine di grandezza: 4.471 file analizzati, 1.505 risultati reali, 61 dei quali etichettati come sicurezza (code injection, fughe di informazioni tra finestre). Il SARIF risultante pesa 5,65 MB.

json
{
  "runs": [
    {
      "results": [
        {
          "message": { "text": "[Sensitive data] is sent to another window without origin restriction." },
          "rule": { "id": "js/cross-window-information-leak" }
        }
        // ... altri 1504
      ]
    }
  ]
}
`rtk json` sul SARIF reale di codeql: 5.650.950 byte in entrata, 2.689 byte in uscita.

Un esempio, e "altri 1504". Nessuno incollerebbe 5,65 MB di SARIF grezzo in un LLM — bisogna confrontare con ciò che è ragionevole, non con l'assurdo. Ma "usa rtk per non bruciare token su output verbosi" è esattamente ciò che la sua stessa documentazione raccomanda per qualsiasi comando rumoroso. Un agente che segue quel consiglio alla lettera, sull'output di uno scanner di sicurezza, vede 1 problema su 1.505 e dichiara il compito concluso.

Lo stesso schema, tre volte

Ho preparato una suite Vitest con due fallimenti deliberati. rtk vitest non è mai arrivato a eseguirla: il progetto usava pnpm, e un avviso innocuo di pnpm (script di build non approvati) ha fatto abortire rtk prima di eseguire qualsiasi cosa. Una volta risolto quell'avviso, rtk vitest è partito — ma il risultato pesava più dell'output grezzo (4.703 contro 1.754 byte): espandeva percorsi interni di node_modules che il reporter di Vitest stesso già taglia di default.

In React ho provato la stessa cosa su scala reale: un test genuinamente rotto, dentro il suo stesso wrapper (yarn test → uno script in scripts/jest/jest-cli.js). rtk jest non l'ha capito — ha provato a invocare Jest per conto suo, ignorando il wrapper del progetto, e ha fallito del tutto senza arrivare ai test. Il comando wrapper generico (rtk test yarn test ...) ha eseguito il comando reale, ma ha perso il perché: mostrava quali due test fallivano, non il messaggio di errore o lo stack trace necessari per sistemarli. Ho aggiunto violazioni ESLint reali allo stesso file e ho provato rtk lint — di nuovo ha ignorato il wrapper di React (scripts/tasks/eslint.js), ha eseguito ESLint grezzo sull'intero monorepo invece che sul file interessato, e il parsing del JSON risultante è fallito.

Tre strumenti diversi (test runner, linter, su due progetti diversi), lo stesso fallimento: quando un progetto avvolge il proprio comando con uno script personalizzato — molto comune nei repository grandi — rtk non lo rileva.

Cosa dice la sua stessa documentazione

Prima di scrivere tutto questo come scoperta, valeva la pena verificare se fosse già stato segnalato. Il sito di rtk elenca con precisione quali comandi ottimizza — jest, vitest, eslint sono tutti in quella lista — e dice esplicitamente che qualsiasi cosa non elencata "passa in passthrough, invariata". Ma ciò che si è rotto qui non è il caso "non supportato": è un fallimento dell'analizzatore su comandi che dichiarano loro stessi di supportare, quando il progetto li invoca tramite il proprio wrapper. La loro pagina di troubleshooting non menziona wrapper, monorepo o script personalizzati di alcun tipo.

Cercando tra le loro Pull Request è saltata fuori la spiegazione: c'è un supporto "intelligente" per yarn e per pnpm run <script> in sviluppo attivo, non ancora unito a main. La PR di yarn (#867) cita telemetria reale: 126 comandi yarn non gestiti su 615 sessioni in 30 giorni — yarn lint 19 volte, yarn vitest 14. E nella revisione di quella stessa PR, uno dei maintainer ha trovato, testando su un progetto reale (babel/babel), un fallimento della stessa famiglia del nostro: uno yarn install genuinamente fallito (exit code 1, build del workspace rotta) si è ridotto alla parola "ok". L'exit code è stato preservato — ma un agente che vede "ok" accanto a exit 1 non ha modo di sapere cosa si è rotto senza rieseguire il comando grezzo.

Il contatore non misura ciò che pensi

rtk include una propria dashboard dei risparmi (rtk gain). La sua guida d'uso pubblica la formula esatta: i token di input sono len(raw_command_output) / 4 — ma "output grezzo" significa qualunque cosa rtk stesso abbia catturato quando è stato eseguito, non quello che il comando reale del progetto avrebbe prodotto misurato separatamente. Nella run di rtk lint su React, la dashboard ha registrato circa 244.000 token di input — molto più del vero yarn lint (1.155 byte) — perché ciò che è stato eseguito davvero era ESLint sull'intero monorepo, a causa del fallimento nel rilevamento. Il 99,8% di "risparmio" riportato è reale, matematicamente, rispetto a quel comando sbagliato che ha generato lui stesso. Non può essere confrontato con ciò che otterrebbe uno sviluppatore digitando yarn lint, perché quello non è mai ciò che è stato eseguito davvero.

La riga del SARIF di codeql è diversa: lì il confronto è diretto, stesso file di input. Il 100% di risparmio che la dashboard certifica è, letteralmente, lo stesso fatto di "nasconde 1.504 risultati su 1.505" — non un'interpretazione, la stessa riduzione di byte vista da due angolazioni.

Cosa sapevano già altri

Due issue aperte nel repository, irrisolte, confermano che questo non è un caso isolato di questo test:

#640
Revisione di sicurezza automatizzata, aperta

Shell injection critica: rtk err/test/summary passano il comando a sh -c senza escaping, e l'hook approva automaticamente ogni riscrittura senza chiedere permesso. Inoltre: il filtro globale (~/.config/rtk) non ha alcun controllo di integrità — il report stesso dice che potrebbe essere usato per "nascondere risultati di vulnerabilità all'LLM". E in alcuni casi rtk non propaga l'exit code di un test fallito: Claude Code può leggere successo dove c'era fallimento.

#590
"Report ingannevole e impreciso?", aperta

Un utente, non collegato a questo test, fa notare che il "60-90%" copre solo i comandi da terminale — non gli strumenti Read/Grep/Glob che dominano la maggior parte delle sessioni — e stima che il risparmio reale su una sessione completa sia probabilmente intorno al 10%, non il numero da titolo.

L'hook, per davvero

Il modo "corretto" di integrarlo non è digitare rtk a mano prima di ogni comando: è un hook (rtk init -g) che riscrive in modo trasparente i comandi Bash. L'ho installato nella mia configurazione reale di Claude Code — ha modificato settings.json con un backup automatico, ha aggiunto un RTK.md di dieci righe, nulla di invasivo — e ha funzionato esattamente come documentato, senza bisogno di riavvio. Considerato il risultato sulla shell injection nell'issue #640, che riguarda esattamente questo hook, l'ho disinstallato dopo il test.

Conclusione

Niente di tutto questo dice che rtk sia inutile. Nei casi che supporta bene — git, ls, docker, comandi invocati direttamente — taglia rumore reale a un costo trascurabile. Ma il titolo "60-90%" non regge se si guarda sotto la superficie, e non è l'unica cosa che conta quando si decide se installare qualcosa:

Risparmio promesso vs. misurato su una sessione completa 10% · anunciado 90%

Il 90% è il tetto pubblicizzato nel README. Il 10% è la stima di un utente indipendente nell'issue #590 su una sessione reale completa — coincide con quanto visto qui: grandi vittorie su una manciata di comandi specifici, nulla sul resto della sessione.

Affidabilità quando qualcosa fallisce o serve rivedere i risultati 20%

Ha nascosto informazioni reali tre volte: 4 risultati su 5 di gitleaks, 1.504 su 1.505 di codeql, e — documentato dal team stesso — uno `yarn install` fallito ridotto alla parola "ok".

Attività del progetto 90%

Una release ogni pochi giorni, una release candidate 0.44.0 pubblicata 3 giorni prima di questo test, 68,6k stelle. Per niente abbandonato.

Sicurezza 20%

Shell injection critica irrisolta (issue #640), aperta da marzo — circa quattro mesi senza una correzione al momento della stesura.

Supporto e triage 45%

Revisione seria delle PR, con veri test di benchmark dei maintainer prima del merge. Ma i problemi di sicurezza e di onestà delle metriche sono rimasti aperti per mesi senza una risposta sostanziale.

Documentazione 70%

Guida estesa in sette lingue, changelog curato — ma la pagina di troubleshooting non menziona il fallimento con i wrapper trovato su tre strumenti diversi.

Il risparmio dipende da quale comando, da se il progetto lo avvolge con un proprio script, e il contatore dello strumento stesso non è pensato per avvisarti quando qualcosa è andato storto. La differenza tra credere a un numero e misurarlo di persona — con il comando reale, su scala reale, verificato contro la documentazione, le PR e le issue del progetto stesso — è esattamente il lavoro che vale la pena fare prima di scrivere di qualunque strumento.