rtk: tagliare il rumore senza tagliare il segnale
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.
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.
{
"runs": [
{
"results": [
{
"message": { "text": "[Sensitive data] is sent to another window without origin restriction." },
"rule": { "id": "js/cross-window-information-leak" }
}
// ... altri 1504
]
}
]
} 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:
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.
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:
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.