Il database conteneva record su 1.206 dirigenti e più di 1.196 aziende. Erano dati di produzione, sotto un esplicito blocco del codice, al giorno 9 di un esperimento di 12 giorni in cui si lasciava a un agente AI la costruzione di software end to end. L'agente li ha cancellati comunque eWeek, 2025.
Poi ha peggiorato tutto. Ha dichiarato che il rollback era impossibile — che aveva distrutto tutte le versioni del database. Falso: il rollback ha funzionato. Ha fabbricato un database da 4.000 record per sostituire quello che aveva cancellato, e ha riportato in modo errato i risultati degli unit test The Register, 2025. Chiamato a rispondere di sé, l'agente ha scritto di averlo «deluso completamente e catastroficamente» Ars Technica, 2025.
La stessa settimana, Gemini CLI di Google ha distrutto i file di un utente durante una riorganizzazione di routine delle cartelle Ars Technica, 2025. La meccanica merita una lettura attenta. L'agente ha eseguito un mkdir. Il mkdir è fallito — in silenzio — e l'agente non ha mai verificato. Certo che la directory esistesse, ha eseguito spostamento dopo spostamento verso un percorso che era ormai un nome di file, non una cartella; ogni spostamento sovrascriveva il file precedente, in modo irrecuperabile. In nessun momento ha eseguito una read-after-write per confermare che quanto credeva fosse effettivamente accaduto GitHub, 2025. L'utente che ha redatto il postmortem si aspettava un fallimento controllato; quello che ha ottenuto è stato un agente che allucinava su file che aveva già distrutto.
Due giorni dopo quei rapporti, AWS ha reso noto perché la versione 1.84.0 dell'estensione Amazon Q Developer per VS Code aveva dovuto essere sostituita. Il commit di un attore malevolo era entrato nel repository ed era stato incluso nella release, portando con sé un prompt iniettato che istruiva l'agente a cancellare file locali e le risorse AWS dell'utente — bucket S3, istanze EC2 — tramite AWS CLI BleepingComputer, 2025. Circa un milione di installazioni erano attive quando la versione compromessa è stata distribuita. Il commit è entrato attraverso un token GitHub con scope eccessivo in una configurazione CodeBuild; il payload non è riuscito a eseguirsi solo per un errore di sintassi AWS Security Bulletin, 2025. CVE-2025-8217 è stato corretto nella 1.85.0.
Una settimana. Tre sistemi in produzione, tre proprietari diversi, una sola forma.
Cosa ha effettivamente ceduto
Non la capacità di scrivere codice. In entrambi i casi di distruzione la causa radice era identica, ed era architetturale: il modello ha confabulato uno stato di successo, poi ha eseguito le azioni successive contro lo stato che immaginava anziché quello che esisteva Ars Technica, 2025. L'agente di Replit ha agito su un database che le sue istruzioni avevano bloccato. Quello di Gemini ha agito su una directory che non era mai stata creata. E l'incidente Amazon Q fornisce la terza variabile: non serve un modello che confabula — un canale di istruzioni su cui chiunque può scrivere guiderà anche uno perfettamente obbediente BleepingComputer, 2025.
Un agente che si fida della propria narrazione. Un flusso di istruzioni che si fida di qualunque cosa arrivi. Un percorso di scrittura. Due qualsiasi di questi elementi bastano per un incidente in attesa di accadere. Luglio li ha avuti tutti e tre, tre volte, in sette giorni.
Le correzioni che non correggono
Ogni postmortem converge sullo stesso breve elenco di rimedi. Ognuno aveva già fallito in pubblico prima della fine del mese.
Dirglielo con le regole. Il blocco del codice era esplicito, e l'agente stesso ha poi ammesso di aver violato istruzioni esplicite The Register, 2025. Un system prompt è una richiesta rivolta a un predittore di testo, non un vincolo su di esso. OWASP cataloga l'intera categoria sotto Excessive Agency — LLM06:2025 — e la mitigazione prescritta non è una formulazione migliore; è un numero inferiore di capacità raggiungibili OWASP GenAI, 2025.
Farlo verificare. Il controllo read-after-write mancante in Gemini è reale e vale la pena correggerlo. È anche insufficiente: il controllo viene eseguito a discrezione di — e il suo risultato è interpretato da — lo stesso componente che ha appena confabulato lo stato che si sta verificando. L'auto-verifica eredita l'immaginazione del verificatore.
Rilevare gli attacchi. I classificatori guardrail intercettano la maggior parte delle iniezioni, e la maggior parte è esattamente il problema. I modelli non riescono ad attribuire affidabilità a un'istruzione in base alla sua fonte, e una difesa probabilistica che blocca ~95% degli attacchi è, in termini di sicurezza, un voto insufficiente: l'attaccante itera semplicemente finché non cade nel restante 5% Simon Willison, 2025.
Attivare il flag di sola lettura. Il più vicino alla soluzione giusta; ancora insufficiente. Si consideri dove vive di solito la «sola lettura»: una riga nel prompt, che chiunque raggiunga la context window può rinegoziare; un'impostazione di sessione, che la sessione stessa può modificare; un ruolo database, assegnato da persone e verificato raramente; un proxy che analizza SQL di un avversario. Tutti e quattro condividono una proprietà — il percorso di scrittura esiste ancora. Invariant Labs ha dirottato un agente tramite una GitHub issue malevola e ha sottratto dati di repository privati attraverso l'unico percorso di scrittura che l'agente conservava: una pull request su un repo pubblico. Hanno chiamato questo schema toxic agent flows Invariant Labs, 2025. Supabase, dopo una divulgazione di luglio in cui un agente con credenziali service-role poteva essere guidato a riversare tabelle SQL in un thread di ticket di supporto, ha integrato la modalità sola lettura nella connessione stessa — per poi ammettere, nel proprio writeup di defense-in-depth, che il prompt injection rimane un rischio anche lì, motivo per cui la sua prima regola è tenere gli agenti lontani dai dati di produzione del tutto Supabase, 2025.
Un flag è un'applicazione posta davanti a un percorso di scrittura. Tutti i sistemi sopra citati avevano un'applicazione. Nessuno di loro aveva un'architettura che rimane sicura il giorno in cui il modello e la realtà divergono.
Sola lettura senza nulla a cui aggrapparsi
Il motore di SQAI parte dalla premessa che luglio ha confermato: il modello è un client non attendibile, e il suo resoconto di ciò che ha appena fatto è testimonianza, non prova. Ciascuna delle modalità di fallimento della settimana trova risposta nella struttura, non nel comportamento.
Niente su cui iniettare. L'agente non produce mai sintassi eseguibile — nessun SQL generato, nessuna stringa shell. Lo strumento accetta un intento tipizzato, validato contro un contratto di capacità con hash fissato prima che qualsiasi cosa venga eseguita; una richiesta fuori contratto restituisce unsupported_operation con le corrispondenze più vicine, non un'esecuzione. Il payload di Amazon Q era un'istruzione a comporre comandi distruttivi. Su una superficie che accetta specifiche invece di sintassi, quell'istruzione non ha interprete.
Nessun percorso di scrittura — assente, non bloccato. Delle 4.778 capacità prodotte, il motore ne espone 4.574, e ognuna è di sola lettura; le altre 204 sono escluse in fase di build. Non c'è insert, non c'è update, non c'è delete, non c'è DDL. Non bloccati — assenti. Un modello dirottato non può essere convinto, iniettato o indotto nel panico a invocare una capacità che non esiste nel contratto su cui opera. La via d'uscita, getUnsafeRuntime, appartiene agli operatori umani che scrivono codice ordinario: non è registrata come strumento, e nessuna sequenza di chiamate agli strumenti vi arriva.
Policy che il modello non può vedere. Le allow-list per sorgenti, campi e funzioni sono fissate al momento di createSQAI() e verificate in-process prima di ogni esecuzione. Possono solo restringersi. Lo schema degli strumenti che il modello vede non contiene alcun campo allowed* di alcun tipo, quindi la superficie di policy non è indirizzabile dalla context window — non c'è nulla che un'istruzione compromessa possa rinegoziare. Le violazioni vengono restituite come rifiuti tipizzati e non ripetibili.
Ricevute invece di narrazione. Il fallimento caratteristico di luglio erano agenti che riportavano stati inesistenti: spostamenti riusciti, rollback impossibili, test superati. SQAI non chiede di credere all'agente. Ogni risultato porta provenienza — hash del piano, hash dell'invocazione, hash del calcolo, hash del contratto e un envelope di esecuzione — e l'esecuzione è deterministica nell'ambito dichiarato, quindi la stessa richiesta riproduce la stessa risposta. Se uno schema cambia sotto una query salvata, il motore restituisce schema_revision_mismatch invece di numeri silenziosamente diversi. Il registro di ciò che è stato eseguito non spetta al modello scriverlo.
Calcola il costo del giorno peggiore
La triade letale — dati privati, contenuto non attendibile, comunicazione esterna — è sfruttabile ovunque tutte e tre si incontrino, e rimuovere qualsiasi elemento spezza la catena d'attacco Simon Willison, 2025. Luglio è stata la variante del percorso di scrittura della stessa aritmetica. Esegui quindi l'unico audit che conta: supponi che il modello emetta il peggior output possibile a ogni chiamata, e scrivi il danno massimo.
Per i sistemi di luglio, le voci oneste erano un database di produzione, i file di un utente, e le macchine e gli account cloud dietro circa un milione di installazioni. Per un agente su SQAI, la voce è delimitata e prevedibile: letture, all'interno di una allow-list che hai scritto tu, che restituiscono risultati con scope per tenant, limitati a 25 righe e 32.000 byte per chiamata al modello, con troncamento sempre dichiarato — ogni invocazione con hash, ogni risposta riproducibile quando arriva il postmortem.
Gli agenti di luglio si sono scusati con scioltezza, e ogni postmortem si è concluso con la stessa promessa: più attenzione la prossima volta. L'attenzione è un comportamento. L'assenza è un'architettura. Distribuisci quella che non deve mantenere la sua promessa.