--- tipo: entità --- # Consumo token istanze secondarie → conversione a servizi meccanici **04/09/2026** — Mauro segnala consumo credito alto (`/usage`: 86% uso a >150k contesto, 59% da sessioni attive 8+ ore, 43% da sessioni subagent-heavy, 18% con 4+ sessioni in parallelo — settimana all'86%, sessione corrente al 100%). Fermate tutte e 6 le istanze secondarie (`sentinella-madre`, `sentinella-gmail-personale`, `expert-domotica`, `sentinella-gate-ufficio`, `sentinella-inbox-documenti`, `expert-flussi`) con `claude stop ` per isolare la diagnosi. ## Diagnosi Analisi diretta dei `.jsonl` di sessione (`~/.claude/projects/`) di tutte e 6 le istanze — dimensione del file come proxy grossolano in prima battuta: | Istanza | File sessione | Note | |---|---|---| | `inbox-documenti` | **62 MB** | outlier enorme | | `sentinella-madre` | 3,5 MB | | | `expert-data` | 1,2 MB | | | `gate-ufficio` | 1,18 MB | | | `expert-flussi` | 706 KB | | | `expert-domotica` | 690 KB | | | `sentinella-gmail-personale` | 717 KB | | Causa strutturale comune a tutte: **nessuna sentinella ruota mai la propria sessione**. `slave_sentinel_ensure.sh` tiene lo stesso `session_id` per sempre — la rilancia solo se il processo risulta morto, altrimenti la considera "viva" all'infinito. Ogni istanza porta avanti la stessa conversazione ininterrottamente da giorni, non una sessione fresca ogni giorno. Ma l'impatto varia moltissimo in base al *contenuto*: `inbox-documenti` valeva da sola più di 10 volte tutte le altre messe insieme — le righe più pesanti (12 MB, 6,4 MB, 6,1 MB) erano tutte risultati del tool `Read` su PDF scansionati interi (contratti, bollette, atti). Il protocollo della sentinella dice esplicitamente "Leggi il file (Read tool — funziona anche su PDF)" per ogni documento — quel contenuto pesante non usciva mai più dal contesto perché la sessione non ruotava mai: effetto moltiplicativo, contenuto pesante + sessione che non si resetta. Le altre cinque non avevano questo problema di contenuto — crescita lenta e lineare, solo effetto "sessione lunga". ## Riformulazione architetturale: quale parte serve davvero un LLM? Domanda successiva di Mauro: "Tutte le istanze ci servono? Potrebbero diventare servizi senza LLM, possiamo cambiare i meccanismi di innesco?" — ha portato a separare, per ciascuna sentinella, "accorgersi dell'evento" (spesso puro parsing/polling meccanico) da "reagire con giudizio" (a volte davvero necessario, a volte no): - **`inbox-documenti`**: giudizio LLM necessario (classificare/archiviare un documento), ma il trigger (poll ogni 30s) no. - **`gate-ufficio`**: quasi tutto parsing già fatto da `monitor_executions.py` — LLM serve solo per spiegare un fallimento in prosa. - **`sentinella-madre`**: qui il blocco non era di giudizio ma tecnico — `SendMessage` esiste solo dentro una sessione Claude Code, quindi "mandare un ping" richiede comunque un LLM anche se il contenuto è banale. Ma nessuno dei tre compiti originali richiedeva una sessione *persistente*. - **`expert-domotica`/`expert-data`/`expert-flussi`**: non pollano, non hanno il problema — la loro crescita viene solo da query di dominio reali + il keep-alive che `sentinella-madre` gli mandava ogni 45 min. - **`sentinella-gmail-personale`**: giudizio reale a ogni tick (filtro, calibrazione in corso) — nessun cambio architetturale proposto, il costo è legittimo. ## Le tre conversioni (tutte 04/09/2026, stesso pattern: trigger meccanico esterno + reazione LLM one-shot) ### 1. `inbox-documenti` → `servizio-inbox-watch` `scripts/servizio-inbox-watch/watch.py` (systemd, nessun LLM, poll 30s sulla cartella) rileva un file nuovo e lancia una `slave` one-shot (`avvia_slave.sh`) che applica `scripts/servizio-inbox-watch/PROTOCOLLO.md` (il vecchio protocollo di archiviazione, spacchettato dalla parte "arma un Monitor" ormai obsoleta) a quel solo file, poi muore. Riporto esito: `SendMessage` standard (deciso da Mauro — non mailbox, nonostante siano spesso documenti finanziari/legali dove la durabilità conterebbe di più: la preferenza per la coerenza col resto del sistema ha vinto). Testato end-to-end con un file finto: rilevato → slave lanciata → completata, nessun errore. La slave ha anche mostrato buon giudizio su un caso non previsto dal protocollo (un file di test con contenuto "da eliminare" — l'ha cancellato invece di archiviarlo o trattarlo come anomalia). ### 2. `gate-ufficio` → `servizio-gate-watch` `scripts/servizio-gate-watch/watch.py` fa girare `PYTHON/gate-ufficio/nave/monitor_executions.py` **invariato** (riusato come sottoprocesso, non reimplementato) e reagisce alle righe che stampa: un successo va **direttamente in mailbox** (nessun LLM coinvolto — qui la mailbox non è un ripiego, è l'unico canale disponibile per un demone Python puro dato che `SendMessage` esiste solo dentro una sessione Claude Code); un fallimento lancia una `slave` one-shot che legge il log e spiega la causa via `SendMessage` standard (`scripts/servizio-gate-watch/PROTOCOLLO.md`). Testato end-to-end con un log di fallimento sintetico: rilevato → slave lanciata → `SendMessage` `FALLIMENTO TEST_servizio_gate_watch: exit_code=1, connessione al database fallita: timeout dopo 5s` ricevuto correttamente → completata. ### 3. `sentinella-madre` → `servizio-madre-watch` Qui la conversione non è stata 1:1 sui tre compiti originali (relay mailbox, keep-alive esperti+gemello-ufficio, supervisione/rilancio sentinelle) — due sono stati **eliminati**, deciso con Mauro ("non serve reattività immediata"): - **relay mailbox**: eliminato — le entry arrivano comunque al prossimo avvio sessione via l'hook `session-start-reminder.sh` (verificato che lo fa davvero, legge `mailbox.log`/`mailbox.offset`). - **keep-alive esperti**: eliminato deliberatamente — `expert-domotica`/`expert-data`/ `expert-flussi` si lasciano scadere e si rilanciano a freddo on-demand quando servono davvero, invece di tenerli caldi per sempre. Cambio di comportamento reale (latenza a freddo accettata), non solo di infrastruttura. - **check `gemello-ufficio`** (scheduler.pid Ufficio): **mantenuto** — unico pezzo con vero bisogno di LLM, nessun ping meccanico raggiunge un demone Windows su Ufficio. Fatto con una `slave` one-shot per tick (`scripts/servizio-madre-watch/PROTOCOLLO.md`) invece di una sessione persistente. - **supervisione/rilancio sentinelle**: tornata meccanica, ma con scope ridotto — `slave_sentinel_ensure.sh` ha ora un argomento opzionale `` (retrocompatibile: senza argomenti fa lo sweep completo come prima) usato per un tick orario mirato solo su `sentinella-gmail-personale` (l'unica istanza che deve girare in continuo, non on-demand). **Effetto collaterale corretto in corsa**: testando lo scope ridotto di `slave_sentinel_ensure.sh` è stata rilanciata per errore `sentinella-gmail-personale` (violando temporaneamente la deroga "non rilanciare finché non lo dice Mauro" ancora attiva in quel momento) — fermata subito, segnalato a Mauro, poi riautorizzata esplicitamente da lui ("fai ripartire") pochi minuti dopo. Testato al primo tick reale: rilancio corretto di `sentinella-gmail-personale` + slave di check `gemello-ufficio` completata senza errori (nessun `gemello-ufficio` raggiungibile a quell'ora — PC ufficio verosimilmente spento, comportamento atteso). **Coerenza successiva**: il passo 7 di `avvio-sessione` eseguiva ancora lo sweep completo di `slave_sentinel_ensure.sh` (senza scope) — avrebbe rilanciato anche gli esperti a ogni avvio sessione, reintroducendo lo stesso pattern di keep-alive appena eliminato per un'altra via. Corretto lo stesso giorno: ora chiama `slave_sentinel_ensure.sh sentinella-gmail-personale`. ## Monitoraggio permanente (stesso giorno, dopo le tre conversioni) Mauro ha chiesto un monitoraggio permanente del consumo per istanza. `scripts/monitor-consumo- istanze/report.py` (cron giornaliero 05:58) legge il campo `usage` reale di ogni turno assistant nei transcript `.jsonl` — non più una stima dalla dimensione del file, il dato vero (`cache_creation_input_tokens`, `cache_read_input_tokens`, `output_tokens`). Calibrazione fatta testando sui dati reali: la prima versione usava il totale grezzo come soglia di allarme, generando solo falsi positivi sulle normali sessioni interattive lunghe (dominate da `cache_read`, economico, non un segnale di spreco). Corretto usando `cache_creation + output` ("costo reale") come metrica di soglia, e escludendo esplicitamente le sessioni interattive Adrian/slave one-shot dalla lista di allarmi (lavoro umano deliberato, non automazione che può derapare da sola) — il monitoraggio ha senso solo sulle istanze secondarie. Seconda soglia: sessione persistente attiva oltre 72h senza restart — il segnale strutturale della diagnosi di oggi, non solo il contenuto. Auto-pulente: solo attività negli ultimi 3 giorni, così un'istanza smantellata esce da sola dal radar invece di restare segnalata per sempre. Integrato nell'hook `session-start-reminder.sh` come `logbook`/`job_health`. Testato sui dati reali del giorno stesso: ha classificato correttamente le tre istanze appena convertite come le più problematiche, confermando la diagnosi fatta a mano. ## Stato a fine giornata - `scripts/slave-sentinels/` contiene solo `expert-data`, `expert-domotica`, `expert-flussi` (dormienti, on-demand) e `sentinella-gmail-personale` (unica sentinella LLM persistente vera, riattivata). - Tre `servizio-*` systemd in produzione, nessun LLM persistente. - `CLAUDE.md` a v1.98 con l'architettura aggiornata. ## Non fatto, per la prossima sessione `archivio/Adrian/riferimento/claude-cli-headless.md` non è stato aggiornato — descrive ancora il vecchio comportamento di keep-alive/`sentinella-madre` in alcuni punti. Rimandato esplicitamente da Mauro a "prossima sessione". ## Validazione su cicli reali (thread aperto in `MEMORY.md`) Mauro ha segnalato esplicitamente, il giorno stesso della conversione, "dovremo vedere se regge" — il cambio da sentinelle persistenti a `servizio` meccanico + slave one-shot non è considerato chiuso finché non si vedono abbastanza cicli reali. Punti concreti da osservare: - **Prossimo documento vero in `inbox-documenti/`** — la slave one-shot segue bene `PROTOCOLLO.md`? **(05/09) Primo ciclo positivo**: libretto uso/manutenzione Opel Mokka di Nadia processato correttamente (rinominato, archiviato in `_documenti/`, sidecar in `famiglia-nadia.md`, commit `dff217f`, inbox tornata vuota). - **Prossimo fallimento reale di un job `gate-ufficio`** — la slave lanciata da `servizio-gate-watch` spiega bene la causa? **(07/09) Due casi reali capitati, nessuno dei due passato per il canale previsto**: il crash di `omdb_batch_enrich` (04/09, `database is locked`) non risulta mai segnalato in mailbox da `servizio-gate-watch` (verificato, `mailbox.log` non lo menziona) — trovato per altra via, non per il meccanismo che doveva validare questo punto. Lo stop dell'intero scheduler Ufficio per il weekend (05→07/09) è un caso diverso e più a monte: se lo scheduler non gira, nessun job "fallisce" in senso stretto, quindi `monitor_executions.py`/`servizio-gate-watch` probabilmente non lo intercetta nemmeno come categoria di evento — non verificato, ma coerente con l'assenza di qualunque segnalazione in mailbox per quei giorni. **(07/09, poche ore dopo) Validato**: `backup` ha chiuso con `exit_code=3` (due file di lock temporanei Office `~$...` su `I:\Budget`/`X:\MonitorOsservatorio`, warning benigno di restic, backup comunque completo) — una slave (`adrian-28`) è partita da sola, ha letto il log, ha mandato una diagnosi corretta via `SendMessage` senza bisogno di sollecito. Primo caso in cui il canale previsto ha funzionato esattamente come pensato. **Ricapitato poco dopo** (`adrian-e5`, altro file di lock Excel) — stesso schema, confermato non un caso isolato. Il caso ancora non coperto resta lo scheduler fermo/silenzioso (nessun job che "fallisce" in senso stretto) — punto diverso, non chiuso da questo. - **Tenuta del riavvio preventivo 24h di `sentinella-gmail-personale`** nei giorni successivi alla conversione. Non ancora verificato su più cicli. Non richiudere questo thread (né qui né in `MEMORY.md`) finché tutti e tre i punti non hanno avuto almeno un riscontro reale. ## Idea aperta (10/09) — allineare `inbox-documenti` a Gmail, con un expert dedicato Nata riflettendo sul parallelo con `servizio-gmail-check`: lì il rilevamento è puramente meccanico (mailbox, nessuna slave lanciata in autonomia), il giudizio lo applica Adrian dentro una sessione già viva. Mauro propone di valutare lo stesso per `servizio-inbox-watch`, con un distinguo importante rispetto a Gmail: - **Differenza dal caso Gmail**: il giudizio su un'email è leggero (mittente+oggetto+snippet, criteri già scritti) — inserirlo in una sessione viva costa poco. Il giudizio su un documento è pesante (leggere un intero PDF, spesso scansionato) — portarlo inline rischierebbe di mescolare contenuto pesante nel contesto di qualunque altra cosa la sessione stesse facendo, lo stesso tipo di contenuto che aveva già causato il problema dei 62MB. Via di mezzo proposta da Adrian: rilevamento meccanico + mailbox come Gmail, ma quando Adrian legge la mailbox in una sessione viva, lancia lui una slave dedicata per il documento pesante invece di leggerlo inline — isola comunque il contenuto pesante, elimina la sessione persistente sprecata. - **Precisazione di Mauro, stesso giorno**: il pattern che ha in mente è — sensore meccanico rileva l'evento → scrive in mailbox (come Gmail) → **Adrian, dentro una sessione viva, decide se attivare l'expert per processare**. Non "Adrian applica lui il giudizio" (come per Gmail, dove il giudizio è leggero) e non "il servizio lancia da solo una slave anonima con un protocollo statico" (come oggi) — un terzo passo intermedio: Adrian smista, l'expert (con la propria base di conoscenza di classificazione, che crescerebbe nel tempo come la whitelist/blacklist di Gmail) fa il lavoro di merito. **Domanda aperta non ancora chiarita**: questo richiederebbe che l'expert **esegua** il processing (legga il PDF, classifichi, archivi/sposti il file) — un'azione di scrittura vera, diversa dal ruolo puramente consultivo/sola-lettura che gli esperti hanno oggi (`expert-data`/ `expert-flussi`/`expert-domotica` non scrivono mai, solo rispondono e segnalano). Due letture possibili, da chiarire insieme: - L'expert stesso esegue il compito con scrittura — estensione reale del ruolo "esperto" oltre la sola consultazione, da conciliare con "Scrittura diretta... criterio deciso ma non ancora attivato" (`claude-cli-headless.md`, sezione Terza classe). - L'expert resta consultivo (fornisce solo la conoscenza di classificazione aggiornata), ma l'esecuzione/scrittura vera la fa comunque una slave dedicata che lo interroga prima di agire — più coerente con la disciplina attuale, ma un passaggio in più rispetto a "attivare l'expert per processare" preso alla lettera. Non scoped, solo registrato — nessuna decisione, da riprendere insieme. ## Idea collegata — `gemello-nave` (10/09, canvas proprio) Dalla stessa discussione è emersa un'idea più grande, che ha superato lo scope di questo file: una sessione persistente su Nave con le stesse capacità di Adrian, dedicata a gestire i `servizio-*` in autonomia (mailbox, esperti, slave), fino a una visione a regime dove gestirebbe tutta l'operatività di Nave mentre Adrian+Mauro restano sulla progettazione/visione strategica. Canvas dedicato, con riscontri tecnici già verificati (capacità, CLI vs VSCode, gerarchia): [[project_gemello_nave]]. ## Fallimento `backup.bat` per lettere di rete non montate (08/09, chiuso) Il thread "backup.bat usa lettere di rete mappate invece di UNC" (segnalato 07/09) ha avuto il primo caso reale l'08/09 mattina (exit_code=1, `I:`/`W:`/`X:` tutte "does not exist" all'avvio del task, 10:00:21). Diagnosi approfondita con `gemello-ufficio`: - **Topologia**: `I:`, `W:`, `X:` sono tutte sullo stesso namespace DFS domain-based `\\mediaset.it\`. `I:` mappa esattamente su `\\mediaset.it\share\Indirizzo_Controllo_Risorse` — lo stesso path già documentato in `PYTHON/MyICR_Suite/CLAUDE.md` come DFS con repliche fuori sync dal 17/03/2026 ("mai UNC nel codice"). **UNC quindi escluso come fix**, almeno per `I:` — introdurrebbe il rischio opposto (dati stale da replica sbagliata, in silenzio). `W:`/`X:` su link DFS diversi (`\mediaset.it\cologno\...`), stato repliche non verificabile (niente `dfsutil`/RSAT sulla macchina ufficio). - **Causa radice reale (non solo "lettere non ancora rimontate")**: Mauro conferma che la policy Mediaset fa **logoff vero per inattività**, non solo blocco schermo — quindi non è un problema di Session-0-isolation banale da scheduled task "run whether or not logged on", è che la sessione utente stessa (con le sue lettere mappate) viene chiusa se il PC resta inattivo troppo a lungo. - **Nessun fix al codice**: Mauro attiva **Caffeine** (keep-awake) ogni mattina quando apre `gemello-ufficio` — tiene viva la sessione interattiva, evita il logoff per inattività a monte, quindi le lettere restano montate per tutto il giorno lavorativo. Rischio accettato consapevolmente se un giorno dimentica di attivarlo (stessa categoria di rischio già accettata per l'apertura manuale di `gemello-ufficio` stesso — disciplina personale, non automazione). **Thread chiuso**, non riaprire senza un nuovo fallimento reale con Caffeine attivo. ## Gap: un riavvio macchina Ufficio uccide scheduler+Monitor insieme (10/09→11/09/2026) Diverso dal "PC spento la notte" già accettato: qui la macchina si è riavviata durante quella che doveva essere una sessione `gemello-ufficio` viva (probabile logout per inattività) — la disciplina "tieni la sessione aperta" non basta contro un riavvio vero. Il 10/09 ha fatto saltare `check_doppi_gemma` + 7 backup di una giornata intera, scoperto solo dall'alert ripetuto di `check_job_health`. Proposta di `gemello-ufficio`, non ancora valutata: autostart almeno per lo scheduler (non l'intera sessione). **Due manifestazioni trovate l'11/09 leggendo i log reali (non solo l'alert)**: il backup delle 08:00 dell'11/09 è fallito in 2s perché `I:`/`W:`/`X:` non erano ancora montate — probabile finestra tra il riavvio dello scheduler (morto per causa ignota, riavviato da `gemello-ufficio` alle 06:39) e il rimontaggio delle unità di rete (il run delle 10:00 è andato bene normalmente). Diverso e più preoccupante: il run di backup delle 18:00 del 10/09 è morto a metà ("signal terminated received... Fatal: unable to save snapshot: context canceled", nessuna riga `=== ESITO ===`) — non è il pattern noto lock Excel (`exit_code=3`, quello va lasciato stare), qui il processo restic è stato interrotto per motivo ancora ignoto, causa dell'alert "senza esito leggibile" ripetuto per ore. Stesso giorno, `archivio_raw_conversazioni` e `check_doppi_gemma` non sono partiti il 10/09 all'orario previsto (11:00/11:30) — causa non ancora nota, da chiedere a `gemello-ufficio` cosa stava succedendo sulla macchina in quella finestra. Non urgente, da riprendere con calma.