Chi cerca "claude code hooks" di solito usa già Claude Code e ha notato una cosa precisa: prima che un tool call parta, o subito dopo, c'è un momento in cui uno script può intervenire. È il punto dove si aggancia gran parte degli strumenti costruiti oggi attorno a Claude Code, permessi, linting, notifiche. Ed è anche, meno deliberatamente, il punto più vicino che l'agente ha a un posto dove scrivere una registrazione di cosa ha fatto.
Cosa intercettano davvero gli hook di Claude Code
Un hook è un comando che Claude Code esegue in un punto preciso del suo ciclo di vita: prima che un tool call parta, dopo che è riuscito o fallito, quando una sessione inizia o finisce, quando l'agente sta per smettere di rispondere, prima che il contesto venga compattato, e in oltre una dozzina di altri punti documentati nella guida ufficiale agli hook di Claude Code. L'hook riceve un payload JSON su stdin, tipicamente il nome del tool e il suo input per un hook a livello di tool, e risponde tramite il proprio exit code e, opzionalmente, un JSON strutturato su stdout: l'exit code 2 blocca l'azione senza appello, un permissionDecision JSON con valore allow, deny o block da' un controllo più fine, e l'output semplice può tornare nel contesto dell'agente. La configurazione sta in settings.json, a livello di progetto o di utente, come un semplice elenco di matcher e comandi, senza un servizio separato da far girare.
È un meccanismo genuinamente utile, ed è per questo che gli hook sono diventati la risposta di default a "come impedisco a Claude Code di fare X" o "come vengo avvisato quando fa Y". Un hook PreToolUse può bloccare un comando che corrisponde a rm -rf. Un hook PostToolUse può far girare un linter su ogni file appena modificato dall'agente. Un hook SessionStart può caricare automaticamente il contesto specifico del progetto. Niente di tutto questo richiede di fidarsi che il modello si autoregoli, ed è esattamente questo il punto di forza: il controllo gira fuori dal ragionamento dell'agente, in modo deterministico, ogni volta che l'evento corrispondente scatta.
I tutorial che esistono già, e cosa lasciano fuori
Cercando tutorial sugli hook oggi, quasi tutto quello che si trova è una guida al meccanismo in sé: quali eventi esistono, come funzionano i matcher, come scrivere uno script PreToolUse che blocca un comando pericoloso, come incanalare l'output di PostToolUse in un file di log con jq e un timestamp. Quella copertura è accurata e utile fin dove arriva, e un thread Reddit molto seguito ha costruito la sua reputazione proprio catalogando ogni evento hook con un esempio funzionante per ciascuno. Quello che non fa, perché non è quello il suo obiettivo, è chiedersi a cosa serva davvero quel file di log una volta che esiste.
Uno script shell che aggiunge una riga per ogni tool call a ~/.claude/audit.log produce qualcosa che assomiglia a una traccia verificabile. Registra un nome di tool, un input, magari un timestamp. Resta comunque un file di testo locale che chiunque abbia accesso al filesystem può modificare, cancellare, o che potrebbe non essere mai stato scritto correttamente fin dall'inizio se lo script aveva un bug che nessuno ha notato. Chiamarlo audit trail è generoso con la parola.
Da un log da hook a una traccia di prova: cosa manca
Un log di eventi e una prova rispondono a domande diverse. Un log risponde a "cosa è successo". Una prova deve rispondere anche a "posso fidarmi che sia davvero successo così, e posso verificare chi lo ha autorizzato". Un log costruito solo su hook, di per sé, non è firmato, sta dove lo sviluppatore o il runner CI ha deciso di scriverlo, e non ha nessun legame crittografico con il task o con la persona che ha effettivamente richiesto il lavoro. Chi ha accesso in scrittura a quel file di log può riscrivere la storia dopo il fatto, e niente nel meccanismo in sé se ne accorgerebbe.
Non è un limite specifico degli hook. È lo stesso limite che la maggior parte delle rassegne sugli agenti di coding salta quando giudica uno strumento solo su cosa produce dentro una sessione: non si chiedono cosa resta dopo, da mostrare a qualcuno che non c'era. Gli hook sono in realtà un passo più vicini a una risposta di quanto lo sia gran parte della categoria, perché intercettano gli eventi grezzi mentre accadono invece di ricostruirli a posteriori da una trascrizione di chat. Un passo più vicini non è arrivarci. Intercettare non è attestare, e una riga JSON in un file di log non è una firma.
Dove uno script hook artigianale si rompe alla scala di un team
Un singolo sviluppatore con un hook PostToolUse che scrive su un file locale funziona bene per quello sviluppatore, su quella macchina, finché nessuno ha bisogno di controllare quel log più avanti. Smette di funzionare nel momento in cui una seconda persona fa una domanda a cui quel log non è mai stato pensato per rispondere: quale delle dodici sessioni che hanno toccato questo file questa settimana è quella che ha introdotto la regressione, chi l'ha revisionata, e posso vedere quella revisione collegata al commit specifico. Un file di testo locale per sviluppatore non regge a quella domanda. Non regge nemmeno un log condiviso senza controllo degli accessi, senza rilevamento delle manomissioni, e senza uno schema che un secondo strumento possa leggere in modo affidabile sei mesi dopo, quando chi ha scritto lo script jq originale è passato a un altro team.
La stessa domanda sui permessi che pone l'auto mode di Claude Code si ripresenta qui in una forma diversa: un classifier che blocca un comando pericoloso a metà sessione e un hook che scrive una riga su un file di log risolvono due problemi diversi, e nessuno dei due è "chi ha firmato cosa è stato rilasciato". Il classifier dell'auto mode blocca un incidente prima che accada. Un log da hook registra che qualcosa è successo. Nessuno dei due produce l'oggetto di cui un revisore, sei mesi dopo, ha davvero bisogno.
Cosa serve a un log da hook prima di poter contare come prova
Gli hook sono il punto giusto da cui partire, non perché siano perfetti, ma perché sono l'unico meccanismo in Claude Code che vede l'evento grezzo nel momento in cui accade, prima che ci si sovrapponga la narrazione dell'agente stesso. Quello che trasforma quella cattura grezza in qualcosa più vicino a una prova è tutto ciò che il meccanismo non fornisce da solo: un record append-only o concatenato crittograficamente invece di un semplice file che chiunque può riscrivere, un legame tra ogni azione loggata e il task e la persona che l'ha autorizzata, e un punto in cui una persona firma davvero prima che qualcosa venga rilasciato, non solo uno script che conferma che la sessione è avvenuta.
È il livello sopra l'agente, non dentro l'agente: il sistema prepara il record, hook compresi, e una persona firma prima che conti come consegnato. Uno script hook che logga fedelmente è un buon mattone. Da solo, resta un log di cui il team si fida, non una prova che il team può consegnare a qualcun altro.
