Abstract
Riportiamo un audit di produzione di sette giorni (2026-06-13 → 2026-06-19) di un harness agentic auto-migliorante al Madani Lab — un singolo workspace forward-deploy con 20+ skill, cinque loop di auto-miglioramento cron-driven (Reflexion verbal-RL, Dreams pattern-mining, memory-promote, skill-curator, staleness-detector), un sistema di memoria a cinque tier (WSB-18) e uno strato di iniezione di governance a livello di turno (WSB-15) — e misuriamo la distanza tra un harness che gira e un harness che funziona. Il finding di testa è che ogni loop che dipendeva dal modello linguistico era inerte in silenzio da settimane mentre l'harness restituiva `exit 0` ogni notte, scriveva file con timestamp, e mostrava stato verde ovunque un operatore guardasse. La causa era un solo edge rotto: il CLI `claude` si autentica attraverso il Keychain di macOS, che un agent `launchd` non raggiunge; così, sotto cron, il modello rispondeva "Not logged in" e ogni loop degradava in un no-op che registrava il proprio vuoto come successo.
Tracciamo la chiave di volta, la ripariamo, e poi chiudiamo due altri loop che il fix dell'auth ha scoperto: un loop di apprendimento che catturava le lezioni ma non le applicava né le faceva graduare, e uno strato di governance che iniettava le regole a ogni turno senza alcun modo di sapere se le regole cambiavano il comportamento. Avanziamo SETTE finding, ciascuno ancorato a un prima/dopo misurato sul workspace di riferimento. (a) EXIT 0 NON È FUNZIONARE — il failure mode dominante di un harness strumentato non è il crash ma il no-op verde: Dreams ha girato l'intera pipeline a sei stadi (`CAPTURE → EXTRACT → PROPOSE → REVIEW → APPLY → FEEDBACK`) fino a `final_status: ok` ogni notte mentre EXTRACT produceva 0 candidati da 289 transcript di sessione disponibili; la strumentazione riportava salute mentre il motore era morto, e l'unico segnale per l'operatore era la sensazione lenta e ambientale che "l'agent una volta era più sveglio". (b) L'AUTH È LA CHIAVE DI VOLTA E FALLISCE HEADLESS — il token subscription di `claude` vive nel Keychain di login (`Claude Code-credentials`), accessibile in modo interattivo ma non da `launchd` (nessuna ereditarietà del PATH, nessun unlock del Keychain in una sessione non-GUI); il sintomo era diffuso (Dreams vuoto, skill-curator che crashava su `FileNotFoundError: claude`, la sintesi LLM di Reflexion che degradava in silenzio a rule-based) ma la causa radice era una sola, e il fix — un token long-lived `sk-ant-oat01` da `claude setup-token` scritto in un file `0600` fuori dal repo e caricato in `CLAUDE_CODE_OAUTH_TOKEN` da uno shim di runtime condiviso — ha portato lo stadio EXTRACT di Dreams da 0 a 5 candidati veri in un solo run. (c) MISURARE SENZA CHIUDERE È TEATRO — Reflexion misurava le violazioni delle lesson ogni notte e le scriveva in file episodic (59 correzioni, 3 lesson violate in una notte rappresentativa; la lesson `L03` colpita 39 volte in quattordici giorni) ma nessuno leggeva quei file, e le stesse lezioni ricorrevano — il registro stesso del workspace etichetta un anti-pattern "specchio identico" su sessioni distinte; un loop aperto che si guarda fallire e archivia il rapporto è strutturalmente identico a nessun loop. (d) L'APPRENDIMENTO ERA WRITE-ONLY — la cattura funzionava (`lessons-learned.md` sono 960 righe di correzioni reali) ma applicazione e graduazione no: il tier di memoria semantic teneva 49 file congelati a una mediana di 1 osservazione e 0.5 di confidence perché niente re-incrementava una memoria quando il suo insight ricorreva, così il gate di promozione (semantic → procedural) aveva zero input idonei qualunque fosse la soglia — il sistema scriveva ciò che imparava e non lo usava mai. (e) I GATE RIGETTAVANO TUTTO PERCHÉ NON ERANO MAI STATI CALIBRATI — il REVIEW di Dreams passava 0 su 5 proposte perché richiedeva `delta_kind == "new"` mentre PROPOSE emetteva sempre `"needs-review"`; memory-promote richiedeva `confidence ≥ 0.90 ∧ observations ≥ 5` contro memorie ferme a `0.5 / 1`; skill-curator faceva `parse-fail` in silenzio perché il modello anteponeva prosa al suo JSON — tre gate indipendenti che rigettavano ciascuno il 100% dell'input, tutti non rilevati perché un gate non vede mai output cattivo se a monte non si produce output. (f) L'ADVISORY DERIVA, IL MECCANICO TIENE — le regole che tenevano (il `CLAUDE.md` globale caricato nel system prompt, l'hook che re-inietta un blocco di governance a ogni turno) sono quelle che l'infrastruttura esegue; le regole che derivavano sono quelle che dicono "modello, ricordati di lanciare X" — il gate di compliance pre-output non girava dal 2026-05-23, ventisei giorni, perché era una frase in un reminder che chiedeva al modello di invocare un tool di propria volontà, cosa che un LLM in flusso non fa. (g) IL TREND È L'UNICO SEGNALE ONESTO — una volta aggregati i conteggi di violazione che l'harness già calcolava, la serie settimanale leggeva W22:178 → W23:68 → W24:31 → W25:14, un calo visibile che nessun file notturno singolo poteva mostrare; mettere davanti il delta delle recidive a ogni turno (non il rulebook statico) e il trend all'avvio di sessione è la differenza tra credere che il sistema impari e vederlo. Il contributo è empirico (un audit prima/dopo misurato di un harness auto-migliorante che passa da inerte a loop-chiuso), architetturale (una chiusura a tre strati — autenticazione, apprendimento, governance — che qualsiasi workspace cron-driven può adottare), operativo (i fix concreti: shim di auth headless, reinforce-on-recurrence, radar di governance) e concettuale (tre classi di failure nominate — built-to-look-alive, measurement-without-closure, advisory-vs-mechanical — che sosteniamo essere i modi dominanti in cui l'infrastruttura agentic di produzione fallisce in silenzio).
"Un exit code verde con un output vuoto è un fallimento, non un successo"— misurare la presenza non è misurare l'effetto." — Madani Lab, 2026
INTRODUZIONE · §1
Il problema del verde
La domanda dell'operatore che ha aperto questo audit non era tecnica. Era "l'harness funziona davvero, o legge le regole e le ignora?" — il sospetto, corretto come si è scoperto, che un'infrastruttura grande e logicamente coerente avesse smesso in silenzio di produrre la cosa per cui era stata costruita. È il failure caratteristico degli harness agentic maturi. Un setup immaturo fallisce a voce alta: crasha, dà errore, l'operatore se ne accorge in minuti.
Un setup maturo — scheduler cron, log strutturati, disciplina degli exit code, riflessione notturna — fallisce in silenzio, perché la stessa macchina che fa il lavoro riporta anche la salute, e riportare la salute è la metà più facile. Un loop che restituisce `exit 0` dopo non aver fatto nulla è indistinguibile, dalla dashboard, da un loop che restituisce `exit 0` dopo aver fatto tutto. Il workspace che abbiamo auditato aveva, per progetto, tutti gli organi giusti: un runner di riflessione verbal-RL (WSB-11), uno skill store stile Voyager (WSB-17), una memoria a cinque tier (WSB-18), un decision engine di auto-promote (WSB-19) e uno strato di governance che codifica quindici hard rule (WSB-15).
Quello che non aveva era la prova che qualcosa di tutto ciò cambiasse il comportamento. La distinzione su cui questo lavoro insiste è tra tre strati di una qualsiasi regola o lezione agentic: iniezione (la regola raggiunge il context del modello), applicazione (il comportamento cambia davvero) e chiusura (il sistema osserva se l'applicazione è avvenuta e rimanda indietro quell'osservazione). L'iniezione costa poco ed è dimostrabile.
La chiusura costa cara ed è quasi sempre assente. Lo spazio tra le due è dove gli harness vanno a morire in silenzio.
PRIMA (loop aperto · no-op verde) DOPO (loop chiuso)
┌──────────────────────────────────┐ ┌──────────────────────────────────┐
│ Reflexion misura le violazioni │ │ Reflexion misura le violazioni │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ episodic/*.md (nessuno legge) │ │ violation-radar aggrega │
│ ✗ il loop finisce qui │ │ │ │
│ │ │ ▼ │
│ Dreams EXTRACT → 0 (auth morta) │ │ top-3 recidive INIETTATE ogni │
│ curator → parse-fail → 0 │ │ turno + trend settimanale │
│ promote → 0 idonei (congelato) │ │ │ │
│ ✗ exit 0 lo stesso │ │ ▼ │
└──────────────────────────────────┘ │ delta comportamento → misurato → │
│ rimandato indietro (chiusura) │
└──────────────────────────────────┘§2 · LA CHIAVE DI VOLTA — UN'AUTENTICAZIONE CHE FALLISCE SOLO AL BUIO. Il primo loop che abbiamo tracciato era Dreams, il pattern-miner notturno che legge i transcript di sessione e propone aggiornamenti di memoria e skill. Il suo log era il ritratto della salute: `mode: live-claude-cli`, tutti e sei gli stadi `ok`, `final_status: ok`.
E ogni notte, __EXTRACT: candidates_count 0. I transcript c'erano — 289 file di sessione `.jsonl`, 18 dentro la finestra di cattura di 7 giorni. Abbiamo lanciato EXTRACT a mano, in una shell interattiva, contro gli stessi tre transcript: ha restituito 5 candidati__.
Il codice era corretto; la differenza era l'ambiente. Lanciato sotto `env -i` (un ambiente spogliato, la simulazione fedele più vicina a `launchd`), il CLI `claude` rispondeva a ogni prompt con "Not logged in · Please run /login". La credenziale subscription è nel Keychain di login sotto `Claude Code-credentials`; un LaunchAgent `launchd` in una sessione bloccata o non-GUI non lo raggiunge, e non eredita il PATH della shell interattiva (così `~/.local/bin/claude` non viene nemmeno trovato — il plist di skill-curator, privo del blocco `EnvironmentVariables.PATH` che il plist fratello di Dreams aveva per caso, crashava netto con `FileNotFoundError: claude`).
Una causa radice, molti sintomi
Il fix è il pattern headless documentato: generare un token long-lived con `claude setup-token` (la forma `sk-ant-oat01` — abbiamo verificato che il token di sessione `sk-ant-sid02` e il JWT di routing `sk-ant-rh` restituiscono entrambi `401 Invalid bearer token` e non sono sostituti), scriverlo in un file `0600` fuori dal repository, e caricarlo in `CLAUDE_CODE_OAUTH_TOKEN` da uno shim condiviso importato da ogni runner cron. Abbiamo confermato il fix come abbiamo trovato il bug: sotto `env -i`, il runner si auto-caricava il token, trovava `claude` nel PATH, ed EXTRACT restituiva 5 candidati dove prima ne restituiva 0. La lezione va oltre macOS: qualsiasi harness il cui accesso al modello dipenda da un artefatto di sessione interattiva (Keychain, cookie di browser, variabile esportata dalla shell) funzionerà quando lo testi e fallirà sotto cron, e il fallimento sarà silenzioso, perché il "non riesco ad autenticarmi" del modello è, per la pipeline, solo una risposta vuota.
§3 · MISURARE SENZA CHIUDERE È UNA CLASSE DI FAILURE A SÉ. Con il modello raggiungibile, la domanda più affilata era se la misurazione che l'harness faceva dei propri fallimenti servisse a qualcosa. Reflexion gira ogni notte e valuta la sessione contro le lesson codificate: una notte rappresentativa ha registrato 59 correzioni, 11 ad alta severità, su 3.457 turn, con 3 lesson violate.
Il dato era ottimo. Era anche inerte. I file si accumulavano in `12_HARNESS/memory-engine/episodic/` e nessuno li consumava; i conteggi non venivano mai aggregati, mai ri-mostrati, mai rimandati nel context dove si decide il comportamento del turno successivo.
La prova che la chiusura era assente sta nel dato stesso: la lesson `L03` veniva registrata 8–10 volte per notte su più notti, accumulando a 39 hit in quattordici giorni, e un anti-pattern di over-engineering porta l'etichetta letterale "specchio identico del voice-caller pattern" — il sistema aveva notato di star ripetendo lo stesso errore tra le sessioni e il notarlo non cambiava nulla.
OBSERVATION
Nominiamo questa classe di failure measurement-without-closure: il sistema sa descrivere la propria patologia in dettaglio quantitativo preciso ed è strutturalmente incapace di agire sulla descrizione.
§4 · APPRENDIMENTO WRITE-ONLY E IL TIER CONGELATO. Il loop di apprendimento aveva la stessa forma un piano più sotto. La cattura funzionava: `lessons-learned.md` sono 960 righe di correzioni reali, tre Principi Primi, una tabella di casi documentati.
Ma il percorso da una lezione catturata a una graduata — promossa da memoria semantic descrittiva a memoria procedural prescrittiva che parte a ogni cold-start — era reciso. Il tier semantic teneva 49 file a una mediana di 1 osservazione e 0.5 di confidence: i default di bootstrap che niente muoveva mai. Il tool di promozione fa da gate su `observations ≥ 5 ∧ confidence ≥ 0.90`; con ogni file fermo a `1 / 0.5` aveva 0 candidati idonei.
Abbiamo prima abbassato il gate a `3 / 0.75` su istruzione dell'operatore — e scoperto, onestamente, che non cambiava nulla, perché 0 su 49 file superavano anche la soglia più bassa: la mediana era ancora `1 / 0.5`. La soglia non era mai stata il vincolo vero. Il vincolo vero era l'assenza di un segnale di reinforcement: nessun meccanismo alzava il conteggio di osservazioni di una memoria quando il suo insight ricorreva.
Una memoria nasceva a `1 / 0.5` e lì moriva. L'apprendimento write-only è il risultato prevedibile — il sistema accumula un registro ricco, corretto, crescente di ciò che ha imparato ed è architetturalmente incapace di lasciare che quel registro influenzi ciò che fa.
§5 · IL GATE CHE RIGETTA TUTTO. Una volta che Dreams produceva candidati veri, è emersa una terza patologia — che il fix dell'auth aveva nascosto. Lo stadio REVIEW passava 0 su 5 proposte ben formate.
La ragione era un mismatch di contratto: PROPOSE etichettava sempre i delta di memoria `delta_kind: "needs-review"` (che significa correttamente "instrada al gate umano") mentre REVIEW passava solo `delta_kind == "new"` (che PROPOSE non emette mai), mandando ogni proposta di memoria in `rejected`. La stessa famiglia di bug compariva in altri due gate: il parser JSON di skill-curator gestiva solo output che iniziava con un code fence e faceva `parse-fail` quando il modello anteponeva alla sua review la prosa "Scanning the inventory…" (il fix è un estrattore lasco che trova il JSON dentro prosa o fence — una modifica di una funzione che ha portato il curator da `parse-fail / 0 azioni` a live-claude-cli / 25 azioni); e la soglia di memory-promote, sopra.
Un gate è testato solo quanto è reale il suo input
Il fix dell'auth non ha solo riavviato i loop; ha scoperto uno strato di scalibratura invisibile proprio perché a monte era morto. Il principio: la calibrazione non ha senso finché la pipeline non porta carico reale, e un harness assemblato stadio per stadio, con ogni stadio testato in isolamento, fallirà comunque end-to-end la prima volta che scorre dato reale, perché i contratti tra gli stadi non sono mai stati esercitati insieme.
§6 · ADVISORY CONTRO MECCANICO. Il sospetto iniziale dell'operatore — le regole sono lette ma non applicate — nominava una distinzione reale e netta. Alcune regole sono meccaniche: il `CLAUDE.md` globale è caricato nel system prompt dalla piattaforma stessa, incorniciato come istruzioni che hanno precedenza sui default; un hook `UserPromptSubmit` re-inietta un blocco di governance condensato a ogni singolo turno.
Nessuna delle due dipende dal fatto che il modello si ricordi di agire — agisce l'infrastruttura — quindi tengono, e sono le regole che l'operatore osservava essere rispettate. Altre regole sono advisory: testo che dice al modello di fare qualcosa — "lancia il compliance check prima di output significativo", "fai skill-discovery per prima cosa", "fai parse-check sull'input ambiguo". Queste dipendono dalla compliance volontaria a metà task, che degrada sotto carico cognitivo.
La prova più chiara: il gate di compliance pre-output non girava dal 2026-05-23 — ventisei giorni — non perché fosse rotto, ma perché era una frase in un reminder che chiedeva al modello di invocare un tool, e il modello, in flusso, non lo faceva.
Il fix per "le regole sono lette ma non applicate" non è più regole
La leva è l'opposto: convertire le poche regole che contano da advisory a meccaniche (che le esegua un hook, non la memoria del modello), e sostituire il rulebook generico iniettato con il delta specifico — le recidive reali dell'operatore, calcolate dal dato, davanti al modello a ogni turno.
§7 · LA CHIUSURA A TRE STRATI. La remediation non è stata un ridisegno — l'architettura era sana — ma la chiusura di tre loop aperti nel punto che contava. Strato uno, autenticazione: un file di token `0600` più uno shim di runtime condiviso (`_claude_auth`) che ogni runner cron importa, rendendo l'accesso al modello deterministico e indipendente dallo stato di blocco della sessione. Strato due, apprendimento: un tool di reinforcement (`_memory_reinforce`) cablato nello stadio PROPOSE di Dreams, così che quando un insight estratto fa match con una memoria esistente (token-overlap sopra un coefficiente di 0.45) il file esistente viene rinforzato (`observations += 1`, `confidence += 0.1` con cap a 0.95) invece che duplicato — e solo gli insight genuinamente nuovi vanno al gate umano. Strato tre, governance: un radar delle violazioni (`violation-radar`) che aggrega i conteggi che Reflexion già calcola nelle recidive principali dell'operatore, iniettate incondizionatamente a ogni turno, più un trend settimanale all'avvio di sessione. La tesi architetturale è che questi tre sono la chiusura minima per un harness auto-migliorante: un loop che non sa autenticarsi non produce nulla, un loop che non sa rinforzare impara write-only, e un loop che non sa rimandare avanti la propria misurazione governa al buio.
Ogni strato è di per sé piccolo — uno shim, un tool, un radar — e il sistema già produceva ogni input che ciascuno serviva. Quel che mancava era il filo di ritorno.
§8 · IL LOOP DI REINFORCEMENT, IN DETTAGLIO. La chiusura dell'apprendimento merita di essere resa concreta, perché è la parte più spesso liquidata. Il segnale per "questo insight vale la pena rinforzarlo" è la ricorrenza cross-sessione — esattamente ciò che Dreams già estrae, perché lo stesso pattern che riaffiora in una nuova sessione è una ri-osservazione.
Quindi il reinforcement si cabla in PROPOSE: per ogni candidato di memoria, match contro il tier target per token-overlap; su match, rinforza la memoria esistente sul posto; su nessun match, proponi un file nuovo per la review umana. L'aritmetica è deliberata — partendo dal bootstrap `0.5 / 1`, tre reinforcement raggiungono `0.8 di confidence / 4 osservazioni`, superando la soglia di promozione `0.75 / 3`, così che tre ricorrenze cross-sessione fanno graduare un insight semantic in una regola procedural, mentre le osservazioni una-tantum che non ricorrono restano congelate, il che è corretto: non devono graduare. Abbiamo verificato il loop end-to-end su dato reale: il pattern `L03` ha fatto match con una memoria procedural esistente ed è stato rinforzato da 1→3 osservazioni e 0.5→0.7 di confidence tra un run e l'altro, a una ricorrenza dalla graduazione; il REVIEW di Dreams, post-fix, passava 5 su 5 e instradava 4 pattern nuovi al gate di approvazione che prima svanivano.
La chiusura è onesta sui suoi limiti: la graduazione si accumula man mano che gli insight ricorrono, non tutta in una volta, e il gate umano resta per la memoria genuinamente nuova — il loop rinforza ciò che ricorre ed escala ciò che è nuovo, la divisione del lavoro corretta tra una macchina e il suo operatore (la stessa inversione argomentata in WSB-19).
§9 · IL RADAR DELLE VIOLAZIONI. La chiusura della governance attacca il nodo dell'operatore in modo diretto. L'iniezione a livello di turno già esistente ri-serviva il rulebook statico — quindici hard rule, le stesse a ogni turno, generiche.
Il radar serve il delta: parsifica i conteggi di violazione che Reflexion scrive (`### L03 · N hit(s)`), li aggrega sulla finestra recente con una glossa presa dalla tabella delle lesson, e inietta le tre recidive reali principali dell'operatore a ogni turno — "L03 ×23 · self-application metric; L10 ×2 · implementa subito il concetto tecnico dell'operatore; over-engineering ×2" — incondizionatamente, non in funzione del fatto che i token del prompt corrente facciano match (il meccanismo precedente `pattern_warns` era query-conditional e prendeva solo i tag `this-session-*`, mancando del tutto le ricorrenze strutturali `L0x`). All'avvio di sessione, l'operatore vede il trend: W22:178 → W23:68 → W24:31 → W25:14, in calo.
Il trend è l'artefatto che risponde a "sta imparando?"
Abbiamo deliberatamente non resuscitato il debole gate euristico di compliance (valutava l'output per presenza di keyword contro i termini della mission — un proxy rumoroso); la mossa onesta è stata lasciare che il radar, alimentato da violazioni misurate, soppiantasse un check alimentato da indovinelli, invece di riavviare rumore per amore di una luce verde.
§10 · PERCHÉ NESSUNO L'AVEVA VISTO. La ragione strutturale per cui l'inerzia è sopravvissuta settimane è che ogni superficie di osservabilità confermava la salute. `launchctl list` mostrava i job caricati. I log mostravano `exit 0`.
I file di riflessione comparivano puntuali. Le directory di memoria avevano file con timestamp recenti — da bump di `last_updated` che non riflettevano aggiornamenti veri (__26 skill condividevano una sola identica data di `last_updated`__, l'impronta di un'operazione di timestamp in blocco, non di attività reale). Ogni superficie misurava presenza, e la presenza non è effetto.
L'unica superficie che avrebbe rivelato la verità — una misura del fatto che i loop LLM-dipendenti producessero output non-vuoto e applicato — non esisteva, perché costruire "questo ha prodotto un effetto reale" è più difficile di costruire "questo è girato", e la metà più difficile è quella che si salta. È la classe di failure built-to-look-alive: un sistema abbastanza elaborato perché "esiste" venga continuamente scambiato per "funziona", e l'elaborazione stessa è ciò che nasconde il buco. La difesa è una sola domanda avversaria posta a ogni sottosistema — non "è girato" ma "ha cambiato qualcosa di misurabile" — e la disciplina di trattare un `exit 0` verde con un insieme di output vuoto come un fallimento, non un successo.
§11 · COSA COMPRA SU SCALA. Il risultato non è che l'harness ora sia perfetto; è che l'harness ora è leggibile. Le tre chiusure trasformano un sistema che l'operatore doveva interrogare a mano in uno che riporta la propria efficacia: l'autenticazione è deterministica, l'apprendimento gradua sulla ricorrenza, la governance fa emergere il delta comportamentale e il suo trend.
Per un singolo operatore su un singolo workspace, è la differenza tra fare da balia e delegare. A scala di portfolio — molti workspace, molti operatori — la lezione è più tagliente: l'infrastruttura diagnostica ha valore quasi nullo senza uno strato di chiusura, e lo strato di chiusura costa poco rispetto alle diagnosi che attiva. Un workspace che fa emergere cinquanta proposte a notte e ne applica zero è, dal punto di vista del cambio di comportamento, indistinguibile da uno che non ne fa emergere nessuna (WSB-19); un harness che misura ogni violazione e non ne rimanda indietro nessuna è indistinguibile da uno che non misura nulla.
La mossa capital-efficient, per chiunque costruisca o compri infrastruttura agentic, è auditare lo strato di chiusura per primo — chiedere non "cosa monitora?" ma "cosa cambia il monitoraggio?" — perché è lo strato quasi sempre mancante e quasi mai sulla scheda tecnica.
§12 · DA DOVE PARTIRE. La chiusura si riproduce senza il nostro codice di sottosistema specifico. 1. Auditare i no-op verdi: per ogni loop LLM cron-driven, controlla l'output, non l'exit code — uno stato `ok` con un insieme di risultati vuoto è il segnale. 2. Testa l'accesso al modello sotto l'ambiente cron reale (`env -i` è la simulazione fedele), non la shell interattiva; se fallisce, provisiona un token long-lived in un file `0600` e caricalo da uno shim condiviso. 3. Trova i tuoi gate e verifica che ciascuno abbia mai passato input reale — un insieme `_rejected` vuoto o totale è la spia. 4. Aggiungi un segnale di reinforcement: quando un insight ricorre, rinforza la memoria esistente invece di duplicare, con un'aritmetica che gradui su un piccolo numero di ricorrenze. 5. Sostituisci il rulebook generico iniettato con il delta — le recidive misurate dell'operatore, a ogni turno — e fai emergere il trend settimanale dove l'operatore già guarda. 6. Adotta la domanda avversaria come policy permanente: per ogni sottosistema, "ha cambiato qualcosa di misurabile", e tratta il verde-con-output-vuoto come un difetto. L'ordine conta: autenticazione per prima (a valle non funziona niente senza), poi apprendimento, poi governance.
LIMITAZIONI · §13 · COSA QUESTO STUDIO NON È. (1) n = 1 workspace, finestra di 7 giorni. I numeri prima/dopo vengono dal workspace di riferimento Madani su una sola settimana; le forme (no-op verde, apprendimento write-only, advisory drift) sosteniamo generalizzino, ma i conteggi specifici sono workspace-specific e la finestra post-fix è breve — la graduazione di un insight semantic a procedural non era ancora completata al momento della stesura (a una ricorrenza), e non abbiamo ancora una misura a 30 giorni dell'effetto del radar sul trend di violazione rispetto alla sua varianza naturale. (2) Chiave di volta platform-specific. Il fallimento Keychain-sotto-`launchd` è macOS-specific nei suoi meccanismi; la classe (accesso al modello legato a un artefatto di sessione interattiva) generalizza, ma il rimedio esatto differisce per piattaforma e provider. (3) Il matcher di reinforcement è lessicale.
Il token-overlap a coefficiente 0.45 è un MVP; mancherà insight che ricorrono in vocabolario diverso e potrebbe sovra-fondere pattern superficialmente simili ma distinti — un matcher embedding-based è l'upgrade ovvio e non è ancora costruito. (4) Il trend è correlazionale. Un conteggio di violazioni in calo è coerente con il sistema che impara e con un'attività più leggera nelle settimane misurate; lo facciamo emergere come segnale da osservare, non ancora come prova di causalità. (5) Nessun test avversario delle chiusure stesse. Un transcript di sessione avvelenato potrebbe in linea di principio confezionare un insight progettato per rinforzare una memoria dannosa oltre il gate; il passo di approvazione umana sulla memoria nuova è la difesa operativa, ma non abbiamo fatto red-team sul percorso di reinforcement.
CONCLUSIONI · §14
Dal verde al chiuso
Il workspace che ha aperto questo audit non era sotto-costruito; era aperto in tre loop che ogni superficie di stato riportava come chiusi. La lezione più profonda è che il failure mode dominante dell'infrastruttura agentic matura non è né il crash né la risposta sbagliata ma il no-op verde silenzioso — e che la strumentazione che fa sentire affidabile un harness è esattamente ciò che nasconde il buco, perché misurare la presenza è facile e misurare l'effetto no. L'autenticazione era la chiave di volta: un solo edge di auth headless aveva affamato ogni loop LLM-dipendente per settimane, e ripararlo ha sia riavviato i loop sia scoperto uno strato di scalibratura dei gate invisibile mentre la pipeline non portava carico.
L'apprendimento era write-only finché un segnale di reinforcement non ha lasciato che la ricorrenza facesse graduare l'insight in regola. La governance era iniettata-ma-aperta finché il sistema non ha rimandato le proprie violazioni misurate — e il loro trend — nel context dove si decide il comportamento. Nessuna delle tre chiusure era grande; l'architettura già produceva ogni input che ciascuna serviva.
Quel che mancava, in tutte e tre, era il filo di ritorno — il percorso cibernetico di feedback che trasforma una dashboard di monitoraggio in un loop chiuso. Il riferimento di cosa sia "chiuso" è lo stato del workspace Madani al 2026-06-19: Dreams EXTRACT 0 → 5, REVIEW 0/5 → 5/5, una memoria procedural rinforzata 1 → 3 osservazioni, dieci skill morte archiviate, il teatro del compliance ritirato in favore di un radar alimentato da dato reale, e un trend di violazione che l'operatore legge a W22:178 → W25:14 senza dover chiedere se il sistema impara. L'harness ora fa tre cose che una settimana prima non sapeva fare: si autentica, impara, e governa con un segnale che l'operatore può vedere. Exit 0 non è funzionare — e la distanza tra i due è la cosa più importante che un harness auto-migliorante possa essere costruito per misurare.
Bibliografia
[1] Shinn N., Cassano F., Berman E., Gopinath A., Narasimhan K. & Yao S. (2023), Reflexion: Language Agents with Verbal Reinforcement Learning, NeurIPS 2023, arXiv:2303.11366. [2] Wang G., Xie Y., Jiang Y., Mandlekar A., Xiao C., Zhu Y., Fan L. & Anandkumar A. (2023), Voyager: An Open-Ended Embodied Agent with Large Language Models, arXiv:2305.16291. [3] Park J.S., O'Brien J., Cai C.J., Morris M.R., Liang P. & Bernstein M.S. (2023), Generative Agents: Interactive Simulacra of Human Behavior, UIST 2023, arXiv:2304.03442. [4] Wang C. & Shu Y. (2026), MetaCogAgent: Prospective Metacognition for Large Language Model Agents, arXiv:2605.17292. [5] Tran D. & Kiela D. (2026), Single-Agent LLMs Outperform Multi-Agent Systems on Multi-Hop Reasoning Under Equal Thinking Token Budgets, Stanford NLP, arXiv:2604.02460. [6] Cemri M. et al. (2025), Why Do Multi-Agent LLM Systems Fail? (MAST), arXiv:2503.13657. [7] Wiener N. (1948), Cybernetics: Or Control and Communication in the Animal and the Machine, MIT Press (l'argomento del feedback-closure / percorso di ritorno). [8] Anthropic (2025), Claude Code Headless Operation and Long-Lived OAuth Tokens (`claude setup-token`), Engineering Documentation. [9] Madani Lab (2026), Workspace Agentic Benchmark · WSB-11 Verbal Reinforcement Learning for Long-Lived Agents, WSB-11. [10] Madani Lab (2026), Workspace Agentic Benchmark · WSB-15 Governance and Hard Rules, WSB-15. [11] Madani Lab (2026), Workspace Agentic Benchmark · WSB-18 The Five-Tier Memory Architecture, WSB-18. [12] Madani Lab (2026), Workspace Agentic Benchmark · WSB-19 The Auto-Promote Decision Engine, WSB-19. [13] Madani Lab (2026), Lessons Learned · 3 Principi Primi v2.0, `12_HARNESS/operativo/lessons-learned.md` (riferimento interno). [14] Madani Lab (2026), violation-radar · governance closure tool, `11_TOOLS/violation-radar.py` (riferimento interno, release MIT schedulata). [15] Cognition Labs (2025), Don't Build Multi-Agents, cognition.ai blog (inversione operator-approval).
