C'era una volta un sistema chiamato Autonomous v1. Nato con le migliori intenzioni: dare a un agente AI la capacita di rispondere automaticamente agli eventi — siti down, email dei clienti, alert di monitoring. L'idea era semplice e seducente: Claude riceve un segnale, valuta cosa fare, lo fa. Meno lavoro manuale, piu reattivita.
Il problema e che "valuta cosa fare" e una frase che contiene un universo di complessita. Senza confini precisi, l'agente faceva quello che qualsiasi sistema autonomo mal progettato fa: bruciava token come un camino d'inverno, prendeva decisioni discutibili, e ogni tanto faceva cose che nessuno gli aveva chiesto. La carta bianca e il nemico dell'automazione.
Dopo due mesi di funzionamento irregolare, il signal_worker — il cuore pulsante del sistema — e stato spento. Non perche l'idea fosse sbagliata, ma perche l'implementazione violava un principio fondamentale: un sistema autonomo deve sapere esattamente cosa puo fare, e nient'altro.
Il nome viene dal greco antico. Il daimon di Socrate era una voce interiore che non gli diceva cosa fare — gli diceva quando fermarsi. Non un demone, non un angelo: uno spirito guida personale con un codice morale preciso. E esattamente quello che serve a un sistema di automazione.
Daimon v2 ribalta l'architettura della v1. Nella v1, Claude orchestrava tutto: riceveva l'evento, decideva cosa fare, lo faceva. In Daimon, Python orchestra e Claude esegue micro-task. La differenza e fondamentale. Python e deterministico, prevedibile, debuggabile. Claude e potente ma imprevedibile. Dare a Python il ruolo di decisore e a Claude quello di esecutore specializzato e come avere un capo progetto metodico che delega compiti specifici a un genio creativo — mai il contrario.
Ogni task che Daimon puo eseguire e whitelistato: breve (max 2-3 minuti), semplice (un solo obiettivo), verificabile (output binario ok/fail), sicuro (nessuna azione distruttiva). Se un evento non corrisponde a nessun task noto, Daimon fa l'unica cosa sensata: notifica e aspetta un umano.
La scelta di n8n come strato di orchestrazione non e casuale. n8n e gia in produzione, ha UI visuale per vedere i workflow, webhook nativi per ricevere alert, cron nativi per i check periodici, logging automatico di ogni esecuzione, retry e error handling built-in. Costruire tutto questo da zero in Python sarebbe stato un esercizio di masochismo.
Il flusso e lineare: un evento arriva (Kuma che segnala un sito down, GlitchTip con uno spike di errori, Beszel con un disco pieno), n8n lo riceve su un webhook unico, normalizza il payload, controlla il budget giornaliero, e chiama l'endpoint del brain. Il brain valuta l'evento con la skill Daimon, che calcola un punteggio di autonomia. Se il punteggio supera 90, n8n triggera l'esecuzione. Altrimenti, manda una notifica su Discord e aspetta.
La bellezza di questo modello e che la whitelist dei task coincide con l'insieme dei workflow attivi. Approvare un nuovo tipo di task autonomo significa creare un nuovo workflow n8n — un'azione esplicita, visibile, reversibile. Non c'e nessun file YAML nascosto, nessuna configurazione sepolta in un database. Se vuoi sapere cosa Daimon puo fare, apri n8n e guardi.
Durante la progettazione di Daimon e emersa una domanda: come fa il daimon a sapere cosa e successo prima? Se un sito va down e tre minuti prima c'e stato un deploy, la diagnosi cambia completamente. Senza contesto storico, il daimon e cieco.
La risposta e Pulse: una tabella PostgreSQL dove ogni evento del sistema viene registrato. Non e una dashboard (quelle si guardano tre giorni e poi si abbandonano), non e un'app standalone (overengineering per un solo utente). E una tabella con un INSERT e una SELECT. Kuma scrive quando un sito va giu, GlitchTip scrive quando c'e uno spike, il cron scrive quando un task finisce, Daimon scrive quando valuta o esegue qualcosa.
La cosa interessante e che Pulse non e nato da zero. Nel database esisteva gia ingest_log, una tabella usata come coda di lavoro per i transcript Read.ai. Dopo un breve dibattito interno (il devil's advocate ha smontato la proposta di tenerle separate in 30 secondi), le due tabelle sono state unificate. ingest_log e ora una view su pulse. Zero duplicazione, zero ambiguita su dove scrivere.
Pulse ha anche un campo processed per gli eventi che richiedono digestione (come i transcript vocali) e campi dedicati al Daimon (daimon_score, daimon_action) per tracciare le valutazioni automatiche. Tutto in una tabella, perche separare responsabilita che condividono lo stesso schema e lo stesso lifecycle e una forma sottile di overengineering.
La v1 e morta di token burn. Daimon ha un sistema di gate esplicito: massimo 50 esecuzioni al giorno, massimo 10 che coinvolgono un LLM, massimo 3 tool call per invocazione Claude, timeout di 90 secondi. Se tre esecuzioni consecutive falliscono, il circuit breaker scatta e tutto si ferma fino a intervento umano.
Questi numeri non sono arbitrari. 50 esecuzioni al giorno coprono ampiamente gli alert reali di un'infrastruttura di 100 monitor. 10 chiamate LLM significano che il 90% dei task deve funzionare senza intelligenza artificiale — restart di container, cleanup di disco, notifiche. Solo la diagnosi di problemi complessi giustifica un'invocazione Claude. E il timeout di 90 secondi impedisce quelle sessioni infinite che nella v1 bruciavano token per ore.
Ogni task parte in modalita dry run. Il daimon valuta l'evento, propone l'azione, calcola lo score, ma non esegue niente. Su Discord arriva un messaggio tipo: "Evento: site_down (pessano.it). Score: 92. Azione proposta: docker restart. Avrebbe eseguito: si." Cosi vedi cosa farebbe senza bruciare niente. Quando i dry run dimostrano che il task funziona come previsto, lo attivi in modalita live — uno alla volta, non tutti insieme.
Questo approccio incrementale e l'esatto opposto della v1, dove tutto era stato acceso in una volta con la speranza che funzionasse. La lezione e dolorosa ma semplice: l'autonomia si guadagna un task alla volta, non si concede in blocco.
La whitelist iniziale e volutamente conservativa. Sito down: diagnosi automatica (curl, log, docker status) e restart del container se il pattern e noto. Container unhealthy: restart. Disco oltre il 90 percento: cleanup dei log temporanei e notifica. Certificato SSL in scadenza: notifica (niente auto-renew, troppo rischioso). Git push fallito sul brain: diagnosi e notifica. Cron job fallito: retry una volta e notifica.
Notate il pattern: la maggior parte dei task finisce con "notifica". Daimon non e un sostituto dell'umano — e un primo soccorritore che stabilizza la situazione e chiama i rinforzi. I task che agiscono davvero (restart, cleanup) sono quelli con rischio zero e reversibilita totale.
L'elenco delle cose proibite e piu importante dell'elenco delle cose permesse. Mai inviare email o messaggi in autonomia. Mai fare deploy. Mai toccare DNS o configurazioni infrastrutturali. Mai operare con budget token illimitato. E soprattutto, mai "trovare qualcosa da fare" — Daimon risponde a eventi espliciti, non cerca lavoro. Un sistema autonomo che si inventa compiti e il modo piu veloce per generare caos.
Questi vincoli non sono temporanei. Non sono "per ora, finche non ci fidiamo". Sono strutturali. Un'automazione che puo mandare email a nome tuo e un'automazione che prima o poi mandera l'email sbagliata alla persona sbagliata. La questione non e se, ma quando.
La differenza tra Autonomous v1 e Daimon non e tecnica — e filosofica. La v1 partiva dalla domanda "cosa puo fare l'AI?". Daimon parte dalla domanda "cosa deve fare l'AI, e nient'altro?". La prima domanda porta all'espansione incontrollata. La seconda porta a sistemi che funzionano davvero.
Il daimon di Socrate non era una voce che diceva "fai questo". Era una voce che diceva "non fare quello". E forse e la metafora piu precisa per un buon sistema di automazione: il valore non sta in quello che fa, ma in quello che sa di non dover fare.