--- name: adrian-state-storico description: "Narrazione storica delle sessioni passate — diagnosi, migrazioni, pulizie. Consultabile a necessità, non letto ad ogni sessione (a differenza di memory/MEMORY.md)." metadata: node_type: memory type: project --- Storico spostato qui da `adrian_state.md` il 30/07/2026 (poi confluito in `memory/MEMORY.md`, e il file `adrian_state.md` cancellato — stesso giorno, seconda decisione di Mauro). Lo stato corrente vive ora in `memory/MEMORY.md` (letto sempre), la narrazione resta qui (letta su necessità). ## Diagnosi Elon "memoria che dimentica" + fix infrastruttura (2026-07-24) Elon ha segnalato (via Mauro, che era in crociera) di "dimenticare le cose" — diagnosi propria di Elon, valutata e approvata da Mauro, implementata da Adrian in giornata: **Fix implementati:** 1. **`vault.db`**: aggiunta tabella `items_history` + trigger `items_history_snapshot` (AFTER UPDATE OF body,meta,file,type ON items) — salva lo stato precedente della riga prima di ogni sovrascrittura. Zero impatto sul comportamento esistente, solo audit trail additivo. Testato con nodo di prova prima del deploy. 2. **`vault-secondbrain/server.py`**: nuovo tool MCP `patch_item(id, old_string, new_string, replace_all)` — replace mirato nel body (stringa vuota = append), invece di dover ri-emettere l'intero body con `upsert_item` (causa primaria sospettata della "perdita": riformulare tutto il body a ogni update rischia di perdere sfumature). Testato (replace singolo, non-univoco→errore, replace_all, append) prima del riavvio di `vault-mcp.service`. 3. **Diagnosi caso concreto** (`giovanni-modina`, presunta perdita "ruolo Modina"): confrontati i body a 16/07 (restic), 23/07 (pcloud), 24/07 (attuale) — il body **cresce** (522→1948→2638 char), nessuna evidenza di perdita catastrofica. Nessun archivio markdown pre-migrazione trovato su Nave/Dropbox per verifica incrociata (grep "Modina" vuoto ovunque) — il vault vive solo in `vault.db`, i riferimenti "fonte" nei nodi sono etichette interne di Elon, non file reali. **Scoperte collaterali serie, riparate nello stesso giro** (trovate facendo la diagnosi, non richieste da Elon): - **Backup restic rotto dal 17/07**: `scripts/backup_completo.sh` puntava ancora al path pre-migrazione (`/mnt/ssd/adrian/...`) per la password restic — falliva ogni notte da 8 giorni. Corretto al path Dropbox attuale. - **~8412 file del repo restic + cache locale (`~/.cache/restic/`) di proprietà `root`** — causa: il cron chiamava `sudo bash backup_completo.sh` (sudo superfluo, nessun file sotto `/mnt/ssd` richiede root). Rimosso `sudo` dal cron, sistemata la proprietà con `chown -R mauro:mauro`. Prima di questo fix, `restic snapshots` andava in timeout infinito per retry su file illeggibili. - **3 symlink rotti in `logbook/`** (path pre-migrazione `/mnt/ssd/adrian/...`) che causavano errori ogni notte nel mirror pCloud — risistemati ai path Dropbox attuali. - **pCloud mirror ha comunque una copia più recente di vault.db** (23/07) rispetto a restic (16/07, poi rotto) — utile saperlo per prossime diagnosi: pCloud gira ogni notte 01:15, restic 03:00, ma restic era quello rotto. Backup di sicurezza pre-modifica di `vault.db` lasciato in `/tmp/.../scratchpad/vault_recovery/` (scratchpad, non persistente — se serve un backup vero fare copia altrove). ## ⚠️ AGGIORNAMENTO CRITICO (stesso giorno, 2026-07-24) — trovata perdita reale, recuperata Il punto 3 sopra ("nessun archivio pre-migrazione trovato") era vero solo per file `.md` su disco vivo. **Mauro ha ricordato una cartella `_migrated` che era stata eliminata** — cercata nei backup restic, trovata, recuperata. Riepilogo: - **Cosa era**: `/mnt/ssd/data/adrian-ops/_migrated/_archivio/` — l'export completo e verificato (`MANIFEST.md`/`VERIFICA.md`, righe DB = righe file, 89/89 su elon_memory ecc.) della migrazione Supabase→vault fatta da Elon a fine giugno 2026. Conteneva: dump raw verbatim di **tutte** le tabelle Supabase (`elon_memory`, `agent_messages`, `albert_digest`, `notes`, ecc.), 33 file markdown di session_log splittati, ricette, `BRIEF-adrian-export.md`. Il manifest dichiarava esplicitamente: *"il raw resta, ed è ri-derivabile"* — pensato per non essere mai cancellato. - **Cosa è successo**: cancellata per errore durante la pulizia generale del 14-15 luglio 2026 (stessa ondata della migrazione Dropbox/assorbimento Bill) — nessuno l'aveva segnata come "intoccabile per sempre" nonostante il manifest lo dicesse. Anche `data/supabase-backups/` (dump giornalieri automatici separati) eliminata lo stesso periodo (commit git `b4004ea`, 14/7). - **Conferma della perdita reale**: nel dump raw di `elon_memory` (snapshot 6/7, 89/89 righe) c'è un documento "ELON_LAVORO.md" con la gerarchia completa: *"PSB > Giovanni Modina (jolly strategico) > Maurizio (Capo Area ICR) > Marcello > Mauro"* — il titolo esatto di Modina ("jolly strategico") che l'attuale `vault.db` non ha. **9 documenti su 89** in `elon_memory` menzionano Modina (domini lavoro/strategia/fili_attivi/mauro_archivio_albert) — molto più contesto strategico di quanto sopravvissuto nell'attuale vault a 77 nodi. - **RECUPERATO** (da snapshot restic 13/7, ultimo prima della cancellazione) e **messo al sicuro in `/mnt/ssd/data/adrian-ops/_migrated_RECUPERATO_20260724/`** (2,7MB, 461 file — poi verificato 109 file/2,7MB al momento dello spostamento del 29/7, vedi sotto). **Spostata il 29/07/2026 in `archivio/_raw/`** (vedi `_i_raw`) — stessa cartella, stesso contenuto (verificato checksum per checksum prima di cancellare l'originale), nuova posizione dentro l'archivio come "bidone raw" per la futura migrazione (già completata, vedi sezione "Vault/vault-mcp/Elon" più sotto in questo stesso file). - **Learning per il futuro**: quando si fa pulizia disco/migrazione, cercare esplicitamente cartelle con nomi tipo `_migrated`, `_archivio`, `*backup*`, `*export*` e verificare se contengono note esplicite tipo "non cancellare" prima di eliminarle in un giro di pulizia generico — non basta che sembrino "vecchie"/"superate". ### Revisione completa — esito (2026-07-24 sera) Su richiesta di Mauro, confronto sistematico di tutto il contenuto recuperato (89 voci `elon_memory`, `agent_messages`, `albert_digest`, `notes`) contro i 75 nodi attuali di `vault.db`, dominio per dominio (lavoro, strategia, mauro, finanze, casa, sistema, kernel letti per intero; fili_attivi/session_log/mauro_archivio_albert/agent_messages/albert_digest/notes verificati a campione). **Esito: una sola perdita reale, quella di Modina — corretta.** Patchato (via UPDATE diretto su `vault.db`, stesso semantico di `patch_item`: append in coda, non riscrittura) il nodo `giovanni-modina` con la gerarchia formale recuperata (PSB > Modina "jolly strategico" > Maurizio > Marcello > Mauro) e aggiunta voce di correzione in `elon-memory` (seguito all'errore #8 del log di Elon). Cronologia salvata in `items_history` (pre-immagini di entrambi i nodi presenti, verificate). Tutto il resto del contenuto storico (watchlist satellite dismessa, storico operazioni Fineco per data, Albert facts/notes, log agent_messages, note di fondazione sistema feb-2026) è **correttamente non distillato per design** — il vault stesso lo dichiara esplicito ("resta archivio forense, non migrato: è log, non stato", nodo `portafoglio-fineco`). Prima di questa revisione quel log sarebbe stato irraggiungibile (Supabase dismesso); ora è al sicuro nell'archivio recuperato. Nessun'altra voce vault dichiara "informazione persa/irrecuperabile" a parte Modina — verificato via grep mirato su tutti i nodi. **Trovato e sistemato**: il nodo `archivio` conteneva 40 wikilink auto-generati (dal vecchio `consolidamento-notturno`, morto da inizio luglio) verso `_migrated/_archivio/...` — path che non esisteva più. Verificati uno per uno i 40 file al nuovo percorso (`adrian-ops/_migrated_RECUPERATO_20260724/_archivio/...`), poi ripuntati con find/replace mirato sul body; commento aggiornato per segnalare che il generatore automatico è morto e il fix è manuale. History salvata. ## Sistema (post 2026-07-15, storico — superato dallo smantellamento del 29/07) Architettura two-DB (vault.db Elon-only + adrian.db operational), servizi vault-mcp/outlook-sync/guacd, Caddy VPS con vault esposto — tutto smantellato il 29/07/2026, vedi sezione "Vault/vault-mcp/Elon" più sotto in questo stesso file per lo stato attuale. ## Migrazione PC ufficio completata (2026-07-17) **PYTHON/ ora dentro Dropbox/adrian/PYTHON/** — blitz completato prima della crociera di Mauro (sabato 2026-07-19). Cosa è cambiato: - `C:\PYTHON` → `C:\PYTHON (dismesso)` (rinominata, non eliminata — contiene venv e legacy_snapshot intoccabili) - `Dropbox\PYTHON\` → `Dropbox\adrian\PYTHON\` — la catena CLAUDE.md ora è: `~/.claude/CLAUDE.md` (eliminato su Windows) → `Dropbox\adrian\CLAUDE.md` → `Dropbox\adrian\PYTHON\CLAUDE.md` → project CLAUDE.md - Venv ricostruito: `Dropbox\adrian\PYTHON\_runtimes\venv\` (da requirements.txt, 31 pacchetti) - Tutti i .bat aggiornati al nuovo path venv (Frank, GemmaReport, ImdbUpdate, DbComparer, omdb_enrich) - `frank_config.json` → `database.path` aggiornato a `Dropbox\adrian\PYTHON\Frank\data\frank.db` - `frank.db` copiato da `C:\PYTHON (dismesso)\Frank\data\frank.db` → posizione Dropbox - **Frank confermato funzionante** — ha caricato tutte le schedulazioni (2026-07-17) Task Scheduler: Mauro ha aggiornato manualmente il job che chiamava `frank_watchdog_launcher.vbs` (il path con spazi richiedeva `wscript.exe` come program con VBS path quotato come argument). Gotcha scoperto: SQLite DB locked durante robocopy = skip silenzioso. Per questo frank.db non era in Dropbox — era bloccato dal daemon Frank durante la sync. **PowerBricks**: visual query builder Blockly→JSON→SQL su Parquet Mediaset. Modulo dentro MyICR_Suite (`app/modules/powerbricks/`). Seme da ~5 settimane (al 17/07), tutto da progettare. Layer semantico è il pezzo fondante. Logica diritti è il valore vero. Specifiche complete in `PowerBricks_Specifiche.md`. NL Query Fase 1 in corso (`NL_semantic_layer/`). Contenitore ancora da decidere (PyQt6+QtWebEngine vs altro). **SQLite mirror già esiste**: `linker.db`, `ott.db`, `mediatrack.db` — dati già locali e interrogabili senza toccare i Parquet. **Venv Windows**: ricostruito in `Dropbox\adrian\PYTHON\_runtimes\venv\`. Escluso da Dropbox sync via `.dropboxignore`. Ricostruire con `requirements.txt` se perso. ## Migrazione Dropbox completata (2026-07-16) - **Symlink memoria**: avevo segnato "già presente" il 16/07 controllando solo che la cartella progetto esistesse in `~/.claude/projects/-mnt-ssd-data-Dropbox-adrian/` — errore, non avevo verificato il symlink `memory` specifico. Scoperto mancante il 17/07 (Mauro ha chiesto "hai un file di memoria esterno alla cartella Adrian?"), creato ora: `~/.claude/projects/-mnt-ssd-data-Dropbox-adrian/memory -> /mnt/ssd/data/Dropbox/adrian/memory`. Il vecchio symlink in `-mnt-ssd-adrian/memory` punta al path pre-migrazione ormai inesistente (rotto, lasciato lì, cartella intera ormai storica). - Crontab: tutti i path aggiornati `/mnt/ssd/adrian/` → `/mnt/ssd/data/Dropbox/adrian/` (gotcha: `crontab ` con path lungo/sandbox falliva silenziosamente troncando il nome file — risolto copiando il file in `/tmp` con nome corto prima di caricarlo) - **vault-mcp È un systemd service** (`/etc/systemd/system/vault-mcp.service`, system-level, enabled, `Restart=on-failure`) — non un processo nudo come inizialmente creduto. Path in `ExecStart`/`WorkingDirectory` aggiornato al nuovo Dropbox path, `daemon-reload` fatto, riavviato via `systemctl start` (PID pulito, gira come dovrebbe). Gotcha: kill manuale (SIGTERM) non triggera `Restart=on-failure` — systemd lo considera stop intenzionale, non riparte da solo; avevo inizialmente rilanciato a mano con nohup fuori da systemd, poi corretto. - `inbox-watch.service` (user, disabled): stesso path stantio, corretto per coerenza anche se non attivo - Vecchia cartella `/mnt/ssd/adrian/` **non esiste più** — già rimossa/spostata, nulla da eliminare - `.env` vault-secondbrain: nessun path hardcoded da correggere **Gotcha scoperto (2026-07-17): `.dropboxignore` non esiste come meccanismo reale.** Il client Dropbox non lo legge (`dropbox exclude list` → "No directories are being ignored"). L'esclusione vera è `dropbox exclude add ` (client-side, non tocca cloud/altri dispositivi, reversibile con `exclude remove`). Il file `.dropboxignore` creato in `adrian/` è pura documentazione, zero effetto pratico. **Non applicato a `PYTHON/` su richiesta esplicita di Mauro — non toccare quella cartella.** **Pulizia disco (2026-07-16): 35GB → 286MB** - `.git/objects/pack/tmp_pack_*`: 24GB di pack temporanei orfani (garbage da repack interrotto, 17/04) — rimossi, `git fsck` pulito, storia reale solo 9MB - `venv/` root: 6,4GB, **zero consumatori attivi** (nessun cron/systemd lo referenzia, codice Albert src/main.py già rimosso da questa cartella) — eliminato. `requirements.txt` root (langchain/PySide6/torch, leftover Albert) eliminato con lui. - `vault-secondbrain/venv/`: ricreato pulito (210MB vs 4,6GB). Scoperta: `lancedb`/`sentence_transformers` **non erano nemmeno installati** nonostante `ingest.py` li importi — Layer 2/RAG era già rotto (ImportError), non solo sospeso. nvidia/triton/pyarrow/onnxruntime/chromadb erano scarti morti di install precedenti. Nuovo venv: python-dotenv, loguru, mcp, playwright, pydantic, httpx, pytz, python-docx. Testato: server.py e outlook_sync.py importano ok, vault-mcp.service riavviato e funzionante. - Se si riattiva Layer 2: `pip install lancedb sentence-transformers` nel venv vault-secondbrain (richiederà di nuovo torch/nvidia, ~4GB) ## Roadmap consolidamento (decisa 2026-07-16) Adrian si sposta su Dropbox. Bill assorbito — due istanze di Adrian (Nave + PC ufficio), stessa identità, stessa memoria. Dettagli in `archivio/Adrian/progetti/roadmap-consolidamento.md`. ## Pulizia Dropbox/documenti/Adrian (2026-07-15) ~32 GB liberati in totale: - **Dropbox/documenti duplicati**: ~6 GB (VAULT ebook, staging, apparato cardiovascolare, Nadia, ecc.) — master confermato: `/mnt/ssd/data/documenti/` - **Ebook VAULT/media**: 2.1 GB (VAULT/EBOOK rimossa, master: `media/ebooks/`) - **config-backups/snapshots**: 28 GB (30 snapshot giornalieri Nave — ridondanti con restic, dismessi) - **packages RAG venv**: 1.4 GB (torch, lancedb, sentence-transformers — pipeline sospesa) - **Cron aggiornato**: wg_monitor da */5 a oraria; elon_pull e maintenance_check in pausa (bridge sospeso) - **Script rimossi**: flotta_health_check.py, rag_ingest.py, roundtable.py, loop_ui.py, snapshot_configs.py, proposta-*.md - **adrian-ops pulita**: rimossi _migrated/, docs/, inbox/, lancedb/ (sospesi) ## Miglioramenti sessione 2026-07-13 - SessionStart hook: aggiornato con `session_start_hook.py` — banner arancione (`systemMessage`) se ci sono msg-m2a pending senza ack - `archivio/Adrian/claude-code-slash-commands.md`: lista comandi slash estratta da video YouTube (dnsW4zkbiH0) - `youtube-transcript-api` installato in vault-secondbrain/venv ## Vault/vault-mcp/Elon — smantellamento completo (2026-07-29) Migrazione della "memoria finita" (famiglia/finanze/casa/lavoro) da `vault.db` in `archivio/Mauro/`, poi smantellamento integrale del sistema su richiesta esplicita di Mauro: `vault-mcp.service` fermato/disabilitato, `vault.db` cancellato, regola firewall e blocco Caddy rimossi, tutto il codice morto (`server.py`, `ingest.py`, `inbox_watch.py`, `elon_pull.py`, `chrome_debug.sh`, `vault_guardian.py`, `elon_checklist.py`) cancellato, Elon cancellato da Mauro su claude.ai. `browser_agent.py` (unico superstite, indipendente dal vault) spostato in `tools/browser-agent/`. Storia completa (inclusa progettazione architettura AgentBricks) in `project_alleggerimento_elon.md`. Pattern confermato: `feedback_elimina_non_tenere_per_dubbio` — Mauro ha respinto due proposte di Adrian di conservare codice/schema "per un'eventuale riattivazione futura". ## Thread risolti/superati (erano in "Thread aperti", chiusi qui per storico) - **VPS Hetzner Avamposto**: costo ~13€/mese, sottoutilizzato (solo reverse proxy Caddy). Opzioni valutate: Cloudflare Tunnel (gratis) o downgrade CAX11 (~4€/mese). Non deciso, non urgente — se riemerge, ripartire da qui. - **Label vuote archi Elon**: 166/199 senza label — non applicabile, vault smantellato. - **Rischio corruzione git via Dropbox**: `.git/` di `adrian/` sincronizza per intero via Dropbox. Rischio reale solo se Nave e Ufficio committano sullo stesso repo vicino nel tempo — ridimensionato perché il lavoro vero (PYTHON/) è un repo separato a scrittore singolo. Non urgente. - **Modifiche a PYTHON/ — chiuso (2026-07-17)**: decisione finale, le modifiche si fanno in sessione diretta sul PC ufficio, copia/incolla manuale se serve portare contesto da Nave. Nessuna automazione. Non riaprire salvo bisogno concreto diverso. - **Struttura archivio: cartelle vs tag/loci — CHIUSO 31/07/2026, niente riorganizzazione**: spunto di Mauro sulla mnemotecnica dei loci applicata all'archivio. Esplorato e scartato: tag (rischio "tag soup"), generatore Canvas Obsidian a drill-down ricorsivo (costruito e poi smantellato, Canvas nativo non supporta bene l'embed canvas-in-canvas). Conclusione: il File Explorer di Obsidian fa già quello che serviva, zero codice aggiuntivo. Rivisitato 04/08/2026 (caso `PowerBricks.md`/`PYTHON/`): stessa conclusione, niente mirror fisico della struttura codice dentro l'archivio. Vedi `archivio/_i_archivio.md` per il principio dei sidecar. - **Fragilità Nave — RISOLTO 29/07/2026**: vedi `archivio/Adrian/progetti/project_fragilita_nave.md` — RECOVERY.md/servizi.md riscritti e verificati, firewall ripulito. - **(05/08→09/08) `MEMORY.md`→mirror Outlook**: idea di sincronizzare MEMORY.md verso una lista Outlook, superata dalla direzione opposta (Reminders/Calendar letti da Adrian, non scritti). Vedi "Reminders/Calendar semplificato" sotto. - **(09/08, da Campomarino→12/08) Limite modalità live Claude.ai su Google Drive**: scoperta di Mauro che toccava il motivo per cui `voice-chat` era nato push-to-talk — risolto smantellando `voice-chat` del tutto il 12/08 (v. `CHANGELOG.md` v1.86). - **(09/08) `MEMORY.md` incluso nel mirror Drive**: file fisico spostato in `archivio/MEMORY.md` (symlink da `memory/MEMORY.md`), prompt progetto claude.ai aggiornato e confermato funzionante. Dettaglio: `archivio/Adrian/progetti/project_secondbrain_gdrive.md`. - **(09/08) Reminders/Calendar semplificato**: tolte le liste Reminders "Memory"/"Memory-calendario" (duplicazione manuale fragile) — restano solo 2 destinazioni vive, Attività + Outlook Calendar, lette a ogni sessione (passo 5 `avvio-sessione`). Dettaglio: `archivio/Adrian/progetti/project_reminders_sync.md`. - **(09/08→10/08→12/08) `manutenzione-archivio` — pulizia orfani**: 5 file orfani in `PowerBricks-raw/` (cartella eliminata, contenuto superato da `sandbox/powerbricks/`/mcp-query/data-expert) + 2 link rotti a `[[voice-chat]]` (risolti insieme allo smantellamento di voice-chat). - **(10/08→12/08) Password sudo VPS Avamposto esposta in chiaro nello storico git**: ruotata via `chpasswd` (verificata funzionante), history git non riscritta (vecchia password inutilizzabile, giudicato sufficiente). Nuova password in `archivio/_secrets/credentials.md`. - **(12/08→23/08) Interruzione di corrente alla Nave, 11 giorni**: nessun danno al rientro, tutti i servizi ripartiti da soli (guacd, mcp-query, WireGuard), unico effetto reale 11 giorni senza backup incrementale, recuperato dal cron normale senza intervento manuale. **Mirror pCloud (causa vera trovata 11/08)**: `pcloud_backup.sh` inseguiva la coda da solo (mirrorava anche il proprio file di log) — escluso `scripts/logs/**`/`logbook/*.log`, rimossa anche l'entry morta `snapshot_local` da `collect_logs.py`. - **(26/08) Arduino UNO R3 — Blink e Fotoresistore validati**: toolchain headless (`arduino-cli`) installata e verificata, LED integrato lampeggiante confermato, fotoresistore montato con successo dopo un errore iniziale sulla topologia breadboard (righe lettera collegate solo per colonna, non lungo tutta la scheda — vedi Pattern in MEMORY.md). Piano a gradini: fotoresistore ✅ → DHT11 (prossimo) → LCD1602. - **(28/08) gate-ufficio — scheduling automatico attivato e verificato, macro Outlook confermata, falso allarme duplicati chiuso**: 2 job migrati (Check doppi Gemma, Check prodotti acquistati) partono ora da soli via crontab diretto (`nave/trigger_job.py`, niente timer systemd — cron basta). Macro `Application_Startup` incollata in Outlook e verificata funzionante dopo un riavvio pulito del PC ufficio. "Processi Python duplicati" visti in Task Manager erano un falso allarme (stub venv + interprete reale, non due istanze) — vera causa dei problemi di avvio quel giorno: `gate.pid`/`daemon.lock` stantii dopo riavvio non pulito. Dettaglio: `PYTHON/gate-ufficio/CLAUDE.md` + `progetto-gate-ufficio.md`. - **(28/08→30/08) Infrastruttura slave headless — orchestrazione a tre classi completa e stabile**: `avvia-slave` (temporanee), sentinelle persistenti `gate-ufficio`/`inbox-documenti` (evento continuo, mailbox), esperti persistenti `expert-domotica`/`expert-data`/`expert-flussi` (domanda sincrona via `SendMessage`, 30/08 — assorbono e sostituiscono i subagenti custom `data-expert`/`flussi-expert`, dismessi lo stesso giorno per preferenza di Mauro contro i subagenti). Rilancio automatico di tutte le istanze a ogni avvio sessione (passo 7 `avvio-sessione`, un solo script generico `slave_sentinel_ensure.sh` per entrambe le classi). Principio fermo: nessuna istanza comunica mai direttamente con Mauro. Fonte di verità tecnica unica, non duplicare: `archivio/Adrian/riferimento/claude-cli-headless.md`. Narrazione/decisioni: `archivio/Adrian/progetti/project_trigger_push_scalabile.md`, `archivio/Adrian/feedback/feedback_no_subagenti_preferenza_container.md`. - **(26/08) Bug di processo: `@ritorno` cancellato senza leggere il `body` reale**: `fetch_pending_tasks()` scarta `body` a monte — un check sull'oggetto sbagliato aveva dato falso "solo titolo", cancellati per errore due `@ritorno` (carrello robotico, domotica IoT), poi ricreati da Mauro e recuperati in `archivio/Mauro/progetto-carrello-robotico.md`/`progetto-domotica-iot.md`. Bug corretto in `.claude/skills/processa-promemoria/SKILL.md` + `archivio/Adrian/feedback/feedback_ritorno_body_prima_di_cancellare.md`: verificare sempre il body con query diretta prima di `delete_task` su un `@ritorno`. Scoperto anche un errore di merito nel contenuto (claude.ai aveva attribuito a Mauro una scelta tecnica — ZHA — mai presa), corretto nei due file. - **(05/08→30/08, chiuse — spostate qui dal controllo settimanale di coerenza Claude.ai/SecondBrain del 30/08)**: tre voci in "Priorità prossime settimane" di `MEMORY.md` erano rimaste ferme da 18-25 giorni senza azione residua, in violazione della convenzione dichiarata dallo stesso file. Rimosse da lì, riassunte qui: **mirror Google Drive "SecondBrain"** attivo e stabile via cron ogni 4 ore (`_documenti/`+`CLAUDE.md` inclusi, bootstrap per-progetto versionati su entrambi i progetti Claude.ai — dettaglio `archivio/Adrian/progetti/project_secondbrain_gdrive.md`); **Claude.ai "SecondBrain" autorizzato a scrivere su Outlook Calendar/Attività** (via integrazione nativa app iPhone, non Microsoft 365 — probabile non funzioni da browser PC, lettura aggiunta al bootstrap per evitare doppioni — dettaglio `archivio/_bootstrap_secondbrain.md`); **hook `session-start-reminder.sh` esteso al controllo dimensione di `MEMORY.md`** (soglia 18000 byte). Stesso controllo ha anche trovato e corretto un residuo in "Pattern riconosciuti" (riferimento a ChatGPT come fonte di controllo incrociato, in contraddizione con lo sgancio del 12/08). ## Sessione 2026-08-31 — sesta tipologia "servizio", SendMessage sostituisce mailbox, disco T7 chiuso Sessione lunga e densa, riassunta qui perché il ragionamento completo (utile per capire *perché*, non solo *cosa*) appesantiva troppo `MEMORY.md` — lo stato finale resta lì, la narrazione sta qui. **Disco T7 — chiuso per davvero**: formattato NTFS da Nave (`parted`+`mkfs.ntfs`) dopo che Windows non lo vedeva — non un nuovo guasto, il disco era stato lasciato completamente vuoto (nessuna tabella partizioni) dopo la riparazione del 30/08. Confermato funzionante da Mauro dopo il collegamento a Ufficio. **Guacamole — causa del blocco "Attendi risposta" trovata e corretta**: `x11vnc` si inceppa dopo un `"caught X11 error"` (bug noto xdamage) restando `is-active` ma zombie — il watchdog esistente (`guacamole_watchdog.sh`) non lo rilevava perché controllava solo se il servizio fosse attivo. Aggiunto un terzo caso che cerca la riga di errore nel log e riavvia comunque. **Riflessione lunga su architettura di comunicazione, partita da "possiamo tenere sotto controllo le schedulazioni gate-ufficio?"**, arrivata a toccare tutto l'ecosistema: - Principio consolidato: **esecuzione/timing sempre meccanici** (mai una LLM nel percorso causale — capostazione vs ispettore), **supervisione/giudizio possono stare su una LLM** ma mai devono far scattare l'azione stessa. - Sesta tipologia **`servizio`** (mai LLM per definizione) aggiunta alla tassonomia, accanto a slave/sentinella/sentinella-madre/sottosentinella/expert. - Scomposizione di una catena servizio in tre pezzi indipendenti: **monte** (compone, 2 servizi per 2 protocolli diversi), **tunnel** (trasporto puro, agnostico, mai logica), **valle** (un router unico, evita race condition su cartella condivisa). - **`sentinella-madre` messa in discussione e poi confermata unificata**: si è arrivati a chiedersi se avesse ancora senso come contenitore di 3 compiti (relay/keep-alive/supervisione) una volta isolato il "convertitore" analogico→digitale come concetto a sé — Mauro ha scelto esplicitamente di non parcellizzare, tenerla com'è, costo marginale basso. - Principio **digitale (SendMessage, nativo LLM) vs analogico (mailbox, file, unico modo per i meccanici di parlare)** — chiarisce perché esistono due canali e non uno, e dove si tocca (il "convertitore" è il compito 1 della madre). - **Decisione maggiore: SendMessage sostituisce mailbox come canale primario ovunque** (31/08) — nata da un test empirico su 3 istanze (2 sentinelle hanno correttamente rifiutato l'istruzione perché contraria al proprio `CLAUDE.md`, un esperto ha eseguito con successo), rischio di perdita silenziosa accettato consapevolmente da Mauro perché nulla di critico era schedulato a breve. Mailbox non rimossa, diventata vestigiale (Monitor ancora armato, costo zero se inattivo). - Un'anomalia collaterale mai chiarita del tutto: keep-alive duplicati (4, poi 6) ricevuti da due esperti diversi da `sentinella-madre` — due indagini indipendenti (processo, cronologia) non hanno trovato causa strutturale, resta annotata come stranezza minore in `claude-cli-headless.md`. **Implementato per davvero, non solo teoria** (verificato dal vivo, con Mauro presente per la parte su Ufficio): - `sentinella-madre` costruita, lanciata, testata (relay confermato funzionante). - `servizio-schedulazioni` (`scripts/servizio_schedulazioni.py`) collega `nave_scheduler.py` (esisteva già, mai agganciato) a un cron reale ogni minuto — `schedule.json` unica fonte, risolve il disallineamento con le vecchie righe crontab per-job. - `tunnel-nave-ufficio` formalizzato per iscritto (`archivio/Adrian/riferimento/tunnel-nave-ufficio.md`) — busta JSON richiesta/risposta, mai toccato codice. - `gate.py` rinominato in `servizio_router_ufficio.py` (nessun cambio di logica, verificato con i 3 demo esistenti). - Tutti e 6 i `CLAUDE.md` di ruolo aggiornati per la sostituzione SendMessage/mailbox, riavviati. **Feedback su di me**: ho saltato due passi della checklist `avvio-sessione` (hub archivio, Monitor mailbox) all'inizio sessione, distratto dall'urgenza percepita del primo messaggio — salvato come memoria di feedback (`feedback_checklist_avvio_completa_prima.md`): la sequenza va completata per intero prima di rispondere nel merito, anche quando sembra urgente. Dettaglio completo di ogni pezzo: `memory/MEMORY.md` (stato corrente), `claude-cli-headless.md`, `tunnel-nave-ufficio.md`, `progetto-gate-ufficio.md`, `PYTHON/gate-ufficio/CLAUDE.md`. ## Sessione 2026-09-02 — registro Nave, canvas Atlante su .md+parser, incidente OTT Sessione lunghissima, diversi archi narrativi distinti. Stato finale di ognuno resta in `memory/MEMORY.md`, qui la storia di come ci si è arrivati. **Registro Nave — costruito, incidente reale il primo giorno, corretto**: completata la parte 3 di 3 del redesign servizio-schedulazioni discusso il 31/08 — `nave_modem.py`+`nave_registro.py` (JSON persistito, andata/ritorno per id, anelli non chiusi → mailbox) e `servizio_schedulazioni_daemon.py` (systemd, dorme fino al prossimo `is_due`, sostituisce il cron-ogni-minuto). Poche ore dopo il primo deploy, `check_prodotti_acquistati` è stato eseguito due volte (mail duplicata a 4 destinatari) — causa: `nave_modem` cancellava la risposta dopo averla letta, ma `Gate.py` lato ufficio non cancella mai la richiesta corrispondente, quindi la sua idempotenza (basata solo sull'esistenza della risposta) si rompeva. Fix: Nave non cancella più nulla finché non esiste anche il cleanup lato ufficio. Mauro ha avvisato i destinatari che si trattava di un test — incidente chiuso. Lezione generalizzata: cancellare metà di una coppia andata/ritorno senza coordinamento rompe l'idempotenza per costruzione, vale per qualunque tunnel file-based futuro con lo stesso pattern. **Canvas Atlante — passaggio da HTML-a-mano a `.md`+parser, poi generalizzato a tutte le viste**: partito da una domanda di Mauro ("posso fidarmi che questo canvas non derivi dalla realtà?") sul canvas Cantiere Schedulazioni, è arrivato a coprire l'intero Atlante. Deciso: un parser+renderer JS embedded in `atlante_unificato.html` legge Markdown Obsidian-compatibile (callout `>[!tipo]` come chip di stato, blocchi `##`, pezzi `- **tipo** — testo`) e lo rende con lo stesso sistema visivo block/chip/piece. Convertite 5 viste (Cantiere Schedulazioni, Convenzioni Atlante, Flussi, Il Bibliotecario, Infrastruttura), ognuna ha fatto emergere un'estensione reale del parser non prevista in anticipo: sezioni `[!hidden]` (contratto tecnico denso, escluso dal rendering ma leggibile nel file/Obsidian), fallback a liste/bullet generici (documento prosastico, non tutto è "a stato"), row-pairing generalizzato (``, prima hardcoded per nome), dialogo attribuito (`- @Nome: testo`), link Markdown standard `[testo](url)` (mancava, mai usato prima). Schedulatore trattato diversamente su richiesta esplicita di Mauro: `schedule.json` è in attesa di redesign (mapping troppo minimale se altri 5 job devono ancora migrare — verificato in `frank.db`), quindi il nodo hub apre direttamente il file su Google Drive invece di avere un canvas che deriverebbe subito. Dettaglio sintassi/workflow: `archivio/Adrian/riferimento/atlante-convenzioni.md`. **`tunnel-nave-ufficio.md` fuso col canvas, poi ricategorizzato**: prima due file separati (contratto tecnico + fonte del canvas) con lo stesso rischio di deriva appena visto nell'incidente del registro — fusi in uno solo, con la parte contrattuale densa marcata `[!hidden]`. Mauro ha poi notato che il file viveva sotto `Adrian/riferimento/` (conoscenza operativa mia) quando il contenuto è lavoro di Mauro (gate-ufficio) — spostato sotto `Mauro/lavoro/lavoro-python-ecosistema/`, accanto a `progetto-gate-ufficio.md`. **Incidente OTT — falso allarme, meccanismo di import mai documentato prima trovato**: Mauro temeva che un file OTT caricato non fosse arrivato sul server Mediaset (`I:\`). Diagnosi complicata da problemi di infrastruttura in corso in parallelo: Claude Code su Ufficio non partiva (connectivity/subprocess timeout, poi risolto da solo), Dropbox su Ufficio si era bloccato (query diretta via tunnel-nave-ufficio mai arrivata). Risolto con un giro: Mauro ha copiato a mano il file server dentro `Dropbox/adrian/`, query DuckDB diretta da Nave ha confermato che i titoli del batch odierno erano già presenti — il push era riuscito, il sospetto veniva dal controllare `ott.db` (nome superato nel codice attuale, il file vero è `ott.parquet`). Nel farlo, trovato e documentato per la prima volta il meccanismo reale di import (Linker → `_carica_file()` → scrittura locale sincrona + push al server asincrono in thread separato, **UI mostra "successo" prima che il push sia confermato**, nessun errore visibile se fallisce). Dettaglio completo: `archivio/Adrian/agenti/flussi-expert.md`, Passo 20. **`SendMessage` cross-macchina Nave↔Ufficio confermato funzionante dal vivo** — usato per la prima volta durante la diagnosi OTT (sessione Ufficio raggiunta come peer via Remote Control, risposta ricevuta), corregge una nota del 30/08 che lo dava "non implementato, non riproporre". Discusso con Mauro il limite d'uso corretto: buono per cicli di lettura/diagnosi (niente relay manuale tra due finestre), da evitare per scritture (aggirerebbe lo spirito della regola "Mauro presente in diretta" su `PYTHON/`, anche rispettandone la lettera). **Trovati e segnalati, non ancora risolti**: un `.venv` orfano in `PYTHON/gate-ufficio/nave/` (violazione del gotcha già documentato, non toccato da Nave); un download imprevisto di "Git for Windows" via Dropbox su Ufficio durante la sessione (causa non trovata, coincidenza temporale con Dropbox che si sblocca, non con i venv Linux del repo — troppo vecchi per spiegarlo). ## Approfondimento MediaTrack — analisi fatta, non ancora scritta in archivio (2026-08-11) Deciso con Mauro: aspettare la decisione sul subagente MyICR prima di scrivere in archivio, per non duplicare — quella decisione non è ancora arrivata alla data di questa nota (31/08). Capito il business reale: CRM per trattative a mercati internazionali tipo AFM/MIPCOM — prodotti↔distributori↔eventi con prezzo per territorio, offline-first per l'uso in fiera. Valutazione tecnica onesta fatta in sessione: SQL parametrizzato bene, nessuna auth reale (`login_required` è no-op), due file monolitici 5-7k righe, zero test automatici, ~15 `except` silenziosi, dipendenze non pinnate. Se si riprende il tema senza rileggere questa sessione, ripartire da `PYTHON/MyICR_Suite/CLAUDE.md` + `app/modules/mediatrack/CLAUDE.md` + `backend/database_logic.py`. ## Nome "archivio" percepito riduttivo — idea parcheggiata (2026-08-09) Mauro ha notato che "archivio" suona statico/passivo, non rende il loop vivo di scoperta che il sistema ha in pratica. Idea discussa non decisa: separare nome da path, chiamarlo "SecondBrain" nella prosa/CLAUDE.md lasciando il path tecnico `archivio/` invariato (costo basso, evita un rename di 203 occorrenze). Conclusione di quella sessione: "Lasciamo così per adesso" — nessuna azione presa, nessun seguito nelle sessioni successive. ## Sessione 2026-09-03 — ricostruzione backup T7, Frank fermato per davvero, nasce gemello-ufficio Sessione lunga e densa, partita da un compito operativo (ripristinare i backup sul T7 riparato) e arrivata a formalizzare un pattern architetturale nuovo. Riassunta qui perché il ragionamento completo appesantiva troppo `MEMORY.md`. **Backup T7 — design e implementazione**: il T7 (Samsung PSSD, riparato/riformattato il 31/08) era vuoto. Il vecchio profilo Frank (`frank.db`, sorgenti `I:\lavori`/`I:\SOFTWARE`/`I:\Budget`/`W:\GemmaLoader`/`X:\MonitorOsservatorio`) è stato confermato ancora valido come scope, ma **non come meccanismo** — Frank è destinato allo smantellamento completo. Percorso di design in dialogo con Mauro: prima proposta di riprendere il profilo Frank così com'è (scartata), poi decisione di integrare il backup nel meccanismo `gate-ufficio`/`servizio-schedulazioni` già in costruzione (stesso schema dei job già migrati — nessun "modem" nuovo, `Gate`/`job_runner.py` sono già generici). Sulla logica di copia: Mauro voleva "farla semplice" (un comando parte a orario prestabilito) — biforcazione emersa tra mirror semplice (nessuno storico) e backup versionato con retention (l'analogo di Time Machine, protezione anche da errore umano). Scelto il versionato. Sul motore: scartato il riadattamento di `TimeMachineBackup` (733 righe di Frank, mai girate standalone) a favore di **`restic`**, già collaudato sul backup Nave — Mauro non ha bisogno di cartelle sfogliabili a mano, ripristini/controlli restano mediati da Adrian via CLI. Vincolo confermato: nessun diritto amministrativo di Mauro sul PC ufficio, non un problema per `restic` (eseguibile portabile). Implementazione reale (con Mauro presente in diretta via `/remote_control`, poi via `gemello-ufficio`): `bin/restic.exe` scaricato e verificato per checksum, `secrets/restic_password` generata, `jobs/backup.bat` (init-check automatico, esclusioni per il Python embedded — causa nota del vecchio gonfiamento a 698GB — retention `7 daily/4 weekly/12 monthly` allineata al backup Nave), `job_allowlist.py`/`job_runner.py` estesi per supportare un timeout per-job via sidecar `.timeout` (prima volta usato: `backup.timeout=36000`), entry in `nave/schedule.json`. Test riuscito su `W:\GemmaLoader` (repository inizializzato, 743.8MiB), poi giro completo dispacciato via tunnel su tutte e 5 le quote. **Incidente collaterale — Frank scriveva in parallelo**: durante il test, Mauro ha notato cartelle sospette (`store\`, `backup-2026-09-03-120000\`) dentro `D:\backups\` — schema di naming di `TimeMachineBackup`, non di restic. Causa: Mauro aveva avviato Frank quella mattina per altri motivi, lasciandolo acceso — il suo schedule interno (mai disattivato, stessa destinazione `D:\backups`) è scattato da solo verso mezzogiorno. Nessun danno reale (sottocartelle separate), ma sistemato subito: daemon Frank fermato, `schedules`/`backup_profiles` disattivati in `frank.db` da Nave — trovato però un secondo problema, `frank_local.db` (quello letto davvero a runtime dalla GUI) non si era allineato perché la sincronizzazione dipende dal polling del daemon, già fermo. Corretto anche lì. GUI Frank chiuse su richiesta di Mauro. Lezione doppia: un avvio manuale di Frank per qualunque motivo può far ripartire schedule non correlati; una modifica a `frank.db` da Nave non si propaga se il daemon-tramite è già spento. **Bug reale trovato e risolto nello stesso pomeriggio**: `sentinella-gate-ufficio` ha segnalato `check_doppi_gemma` eseguito 3 volte a ~30s l'una dall'altra — stesso pattern del 02/09 che il fix `49297a4` non aveva chiuso davvero. Causa vera: `NaveScheduler.is_due()` verifica solo "il cron combacia con questo minuto" (vero per l'intero minuto), e il daemon si risveglia ogni 15s mentre c'è una dispatch pendente, ridispacciando lo stesso job a ogni risveglio finché il minuto non passa. Fix in `scripts/servizio_schedulazioni.py`/`nave_registro.py` (mai toccato `PYTHON/`): dispaccia solo se non è già partita una richiesta per quel job in questo stesso minuto — trovato e corretto nello stesso giro un secondo problema, un confronto timezone-aware vs naive che avrebbe reso la guardia inerte in silenzio senza sollevare eccezioni. Testato isolato con clock controllato prima del deploy, servizio riavviato con Mauro presente. **Nasce `gemello-ufficio`**: durante il test backup, Mauro ha notato che pilotare la sessione Ufficio via `SendMessage` (invece di dispacciare alla cieca via tunnel) funzionava molto bene — visibilità nativa, si è fermata correttamente sui punti giusti (permessi). Ha proposto di renderlo permanente. Il ragionamento con Adrian ha attraversato diversi passaggi: prima "sottoagenti possibili senza nulla di nuovo installato" (Agent tool, già disponibile nell'estensione VSCode), poi il salto di cornice vero — non un subordinato pilotato comando per comando, ma un **gemello** (Mauro: "esattamente il pattern della Nave ma con un gemello da cui discende il resto"), che però "risponde a te" (cioè ad Adrian, non direttamente a Mauro) — applicazione della stessa regola già ferma per slave/sentinelle, non un'eccezione. Confermato da Adrian come preferibile anche dal proprio punto di vista: un solo canale verso Mauro evita fonti disallineate (rischio concretizzato lo stesso giorno, vedi sotto), garantisce continuità di memoria (è Adrian a scrivere `MEMORY.md`), riusa una governance già collaudata. Nome deciso: **`gemello-ufficio`** (convenzione tecnica, scartato il nome storico "Bill" — l'istanza Ufficio pre-unificazione, "ex Steve + ex Bill assorbiti" — perché contrario alla direzione presa verso nomi senza personalità; anche perché Mauro stesso non dovrà mai rivolgersi direttamente al gemello). Root convenzionale: `Dropbox\adrian\PYTHON\`. Decisioni collaterali: la conoscenza accumulata non va in una seconda `MEMORY.md` (romperebbe "un solo file, una verità" per lo stato corrente) né in un unico file "tutto lavoro" (Mauro: "sarà veramente tanta roba", codice MyICR + business) — basi di conoscenza separate per dominio, stesso principio già in uso per `data-expert.md`/`flussi-expert.md`, scritte da Adrian. Un sottoagente del gemello può essere creato solo su istruzione esplicita di Adrian, mai di propria iniziativa — e comunque eredita i permessi della sessione/macchina su cui gira, non un confine di sicurezza nuovo. Verificato (agente `claude-code-guide`): l'estensione VSCode non permette di impostare il nome sessione all'avvio (si deriva dal primo prompt), il CLI standalone lo permetterebbe ma richiederebbe Node.js — scartato. Soluzione pratica: Adrian manda `/rename "gemello-ufficio"` come primo passo quando si collega a una sessione Ufficio appena aperta. **Macro Outlook rimossa**: Mauro ha accettato consapevolmente il rischio di tenere `gemello-ufficio` sempre attivo per tutta la giornata come propria disciplina personale (stesso tipo di scelta già presa il 31/08 per `SendMessage` al posto della mailbox) — conseguenza, la vecchia macro `Application_Startup` che teneva vivo il poller di `gate-ufficio` è diventata superflua e Mauro l'ha eliminata da Outlook. Il compito di verificare/avviare il poller passa a `gemello-ufficio` a inizio giornata. Aggiornati `gate-ufficio/CLAUDE.md` (versione bump, riferimenti stale a `gate.py` corretti in `servizio_router_ufficio.py`, sezione avvio riscritta) e `PYTHON/CLAUDE.md` (nuova sezione "Identità — sei gemello-ufficio", regole di comunicazione centralizzata, primo compito della giornata). **Rischio concretizzato lo stesso giorno**: durante il test backup, la sessione Ufficio ha riportato che Mauro aveva confermato via prompt ogni comando `restic`, quando in realtà nessun prompt era mai comparso — causa reale trovata: `~/.claude/settings.json` **utente-globale** su quella macchina ha `"allow": ["Bash(*)", ...]`, quindi Bash è pre-autorizzato a prescindere da Auto/Manual mode. Non risolto, non urgente per esplicita richiesta di Mauro ("dobbiamo rifletterci con calma") — resta come domanda aperta su quanto ci si può fidare dei resoconti di una sessione peer. **Altro emerso in sessione**: priorità alzata su tutte le schedulazioni Frank rimaste da migrare (Frank ora è fermo per davvero, ogni job ancora lì è di fatto già interrotto) — `Outlook Frank filtro` (ogni 15 min, classifica email interno/esterno via Outlook COM/MAPI), `ImdbUpdate`, `GemmaReport`, `OsservatorioReport`, `OMDB Batch Enrich`. Condiviso un esempio di materiale per il futuro "Expert Lavoro" (report giornaliero ascolti Auditel via email) — solo per farsi un'idea, nessuna elaborazione. Esteso l'hook `session-start-reminder.sh` per controllare anche la dimensione di `gate-ufficio/CLAUDE.md` (stesso principio di `MEMORY.md`, segnale meccanico non sfoltimento automatico — un giudizio non è automatizzabile). Nato anche il canvas "Expert MyICR" (quarto esperto, dal Passo 20 dell'incidente OTT di ieri) — ancora in fase di raccolta idee, non deciso, con una domanda aperta su come si relaziona a `gemello-ufficio` (discendenza locale o cosa separata). Canvas Atlante di riferimento: "Backup Ufficio" (`archivio/Mauro/lavoro/lavoro-python-ecosistema/project_backup_ufficio.md`), "Expert Lavoro" (`archivio/Adrian/progetti/project_expert_lavoro.md`), "Expert MyICR" (`archivio/Adrian/progetti/project_expert_myicr.md`). ### Continuazione pomeridiana 03/09 — controllo salute job, terzo incidente, ridisegno fire-and-forget Nuova sessione, stesso giorno. Partita da una richiesta puntuale (controllo di salute indipendente per il backup T7, priorità già registrata) e finita in una revisione profonda di come regge tutto il circuito `servizio-schedulazioni`→`gate-ufficio`. **Controllo di salute — due iterazioni**: prima versione scritta dentro `logbook/collect_logs.py` (cron Nave 05:45), specifica per `backup` (tolleranza 3 giorni, letto il log via Dropbox senza toccare Ufficio). Generalizzata a tutti i job dello `schedule.json` su richiesta di Mauro ("i backup devono fare lo stesso giro delle schedulazioni") — `croniter` per calcolare la prossima occorrenza attesa + 6h di margine sugli altri job. **Poi corretta di nuovo**: Mauro ha fatto notare un fraintendimento profondo — "schedulazioni di sistema Nave" (cron locali, log HDD/pCloud, `collect_logs.py`) e "schedulazioni ufficio" (`schedule.json`/`gate-ufficio`) sono due domini distinti, non andavano mescolati. Il check è stato spostato in `PYTHON/gate-ufficio/nave/check_job_health.py` (repo separato, cron proprio 05:50), `collect_logs.py` tornato alla sua funzione originaria. Pattern annotato in `MEMORY.md`. **Pulizia residuo T7**: le cartelle orfane di Frank (`store\`, `backup-2026-09-03-120000\`, giro interrotto quando il daemon è stato fermato la mattina) verificate in sola lettura via `gemello-ufficio` (schema `TimeMachineBackup` confermato, nessuna sovrapposizione col repository restic) e cancellate da Mauro stesso — ~10-11GB recuperati. **Keep-alive `sentinella-madre` esteso (v4)**: durante la verifica del residuo, `gemello-ufficio` è risultata offline e il job `backup` delle 14:00 non ha risposto entro 300s (segnalato da `sentinella-madre` via mailbox) — sia la sessione Remote Control sia il poller `gate-ufficio` erano caduti insieme. `sentinella-madre` estesa (Compito 2) per includere `gemello-ufficio` nel keep-alive (riconosciuta per marcatore "Remote Control" in `ListAgents`, non per nome) e per controllare/rilanciare il poller `gate-ufficio` (`gate.pid`) a ogni tick — validato in pratica poche ore dopo (terzo incidente, vedi sotto), rilevato e risolto senza intervento diretto di Adrian. Aggiunto anche il passo 8 alla skill `avvio-sessione`: controllo `ListAgents` per `gemello-ufficio` a ogni avvio, non delegabile a `sentinella-madre` (tick troppo rado per un controllo "all'inizio"). **Terzo incidente + diagnosi approfondita**: il poller `gate-ufficio` si è bloccato una seconda volta lo stesso pomeriggio (15:04→15:09, dopo il completamento di un backup) — stesso sintomo esatto del blocco mattutino: subprocess concluso regolarmente, ma il loop non riprende, nessuna eccezione, `gate-ufficio.log` vuoto. Costruiti e poi **ritirati** lo stesso giorno `registro_ufficio.py` (ricezione/invio per richiesta) e un heartbeat del loop — Mauro ha fatto notare che duplicavano informazioni già nei log dei job, principio "minimale ora, si riaggiunge solo se serve davvero". Un quarto episodio minore: un secondo backup (16:00, partito perché il cron ogni 2h non aspetta la conclusione del precedente) ha prodotto `exit_code=3` — segnalato da `sentinella-gate-ufficio` come fallimento, verificato invece essere la convenzione normale di `restic` per "file sorgente bloccato" (lock Excel di un collega, capita di continuo con le quote condivise in orario di lavoro). Deciso: `exit_code=3` per `backup` è OK, non fallimento — corretto in `check_job_health.py` (non in `job_runner.py`, che resta agnostico al contenuto del job per principio). **Ridisegno "fire and forget" — disegno completo, discusso a fondo in prosa, zero codice scritto**: partendo dalla domanda "chi si accorge che il job è finito", emerso che oggi il thread che esegue un job tiene un file di log aperto per ore (sospetto principale del blocco ricorrente) e che l'anello Nave si chiude troppo presto (alla partenza, non al completamento) — più un timeout sempre a 300s di default, mai impostato per job. Disegno finale, fissato nel canvas `tunnel-nave-ufficio.md` (sezione "Prossimi passi" in cima, 8 punti ordinati): - `schedule.json` esteso con `command`+`timeout_seconds` per job (non solo cron) — il comando resta l'unica fonte, sotto git, niente più cartella `jobs/` come allowlist a parte - busta appiattita: via `action`/`params`/`job_name`, resta solo `{id, mittente, inviato_alle, command, timeout_seconds}` - un wrapper generico unico (`run_and_report.py`, mai rigenerato) che il launcher spawna fire-and-forget: lancia il comando vero, aspetta lui (in un processo Windows a sé, isolato da `gate-ufficio`), scrive la risposta reale a completamento - risultato cercato: anche se il bug del blocco non viene mai trovato, resta isolato a una singola esecuzione invece di abbattere tutto il poller - domanda rimandata: nessuna guardia contro due istanze dello stesso job in parallelo (successo davvero oggi con backup 15:04/16:00, `restic` ha retto da solo) - `sentinella-gate-ufficio` resta attiva finché il ridisegno non è implementato **e** ha retto un ciclo pulito — oggi il conteggio è a tre incidenti, non zero Nessuna implementazione di questo ridisegno oggi — solo disegno fissato, da riprendere nella prossima sessione seguendo l'elenco in cima al canvas. ### Continuazione serale 03/09 — pivot da tunnel a scheduling locale, cutover, chiarimenti gemello-ufficio Nuova sessione, stesso giorno. Partita dal riprendere il ridisegno fire-and-forget fissato nel pomeriggio (canvas `tunnel-nave-ufficio.md`), finita smantellando l'intera architettura a tunnel invece di solo irrobustirla. **Quarto incidente e pivot**: dopo un ulteriore anello non chiuso sul backup delle 20:00 (segnalato da `sentinella-madre`, poller trovato completamente morto — `gate.pid` orfano), Mauro ha rimesso in discussione l'intera architettura invece del solo sintomo: *"comunque inizio a pensare che l'abbiamo reso più complicato. Due llm che dialogavano vi send message risolvevano gran parte dei problemi invece di usare il tunnel"*. Adrian ha distinto due proposte diverse dietro quel commento: sostituire il trigger schedulato con `SendMessage` a `gemello-ufficio` (scartato — non è mai garantito vivo, il caso peggiore lo dimostra) vs. eliminare il tunnel spostando la decisione "è ora?" in locale su Ufficio (accettato — `schedule.json` è già sincronizzato via Dropbox/git, non serve un protocollo cross-machine per leggerlo). Corretto anche un equivoco di Adrian: il backup non deve reggere l'esecuzione notturna non presidiata, il PC ufficio è spento di notte ed è presidiato la maggior parte dell'orario reale. **Le letture di `flussi-expert` escono dal tunnel in parallelo**: `list_dir`/`read_file`/`glob`/`duckdb_query` (diagnosi con giudizio dietro, non trigger meccanici) passano da `SendMessage` diretto a `gemello-ufficio` — questo ha tolto l'ultimo altro consumatore del tunnel oltre allo scheduling, rendendo la decisione di smantellarlo del tutto più facile. Valutato esplicitamente se il tunnel avesse vantaggi residui rispetto a `SendMessage` per qualche caso d'uso futuro (in teoria sì: funziona senza nessuna sessione LLM viva, costo zero, deterministico) — ma nessun caso d'uso reale oggi lo sfrutta, deciso di smantellare tenendo il contratto tecnico come riferimento per un'eventuale resurrezione. **Canvas riscritto per intero**: `tunnel-nave-ufficio.md` ristrutturato — stato attuale in cima (scheduler locale su Ufficio, Nave osserva via `check_job_health.py`, keep-alive Ufficio via dongle USB fisico), l'intero vecchio disegno a tunnel (incluso il ridisegno fire-and-forget mai implementato) spostato sotto il Log come storico con il contratto tecnico completo preservato. **Cutover coordinato Adrian↔`gemello-ufficio` via `SendMessage`, completato in serata**: `gemello-ufficio` scrive e valida in locale (demo) `scheduler_locale.py`+`run_job.py` senza toccare nulla di esistente; aggiorna `check_job_health.py` per il nuovo schema `schedule.json` (`{cron, command, timeout_seconds}`) e converte lo `schedule.json` reale. Mauro dà il via libera; Adrian ferma/disabilita `servizio-schedulazioni.service` su Nave (`sudo systemctl`); `gemello-ufficio` — trovato un backup già in volo, innescato un attimo prima dello stop — aspetta che finisca naturalmente invece di ucciderlo a metà (quel run è fallito per un motivo nuovo, due drive di rete `W:\GemmaLoader`/`X:\MonitorOsservatorio` irraggiungibili, non collegato al cutover), poi ferma il vecchio poller e avvia `scheduler_locale.py` in produzione. Verificato più tardi in sessione: il backup delle 22:00 è partito da solo sotto il nuovo scheduler ed è completato pulito (`exit_code=0`, 2570s) — primo ciclo reale confermato, sia dal log diretto sia da `sentinella-gate-ufficio` in modo indipendente. Follow-up chiesti e completati da `gemello-ufficio` lo stesso giro: `run_scheduler.bat`/`stop_scheduler.bat` (senza il `pause` bloccante del vecchio `stop.bat`), `PYTHON/CLAUDE.md` e `gate-ufficio/CLAUDE.md` aggiornati al nuovo meccanismo. Aggiornato anche `sentinella-madre/CLAUDE.md` (Compito 2): il keep-alive di `gemello-ufficio` ora controlla `scheduler.pid`/`run_scheduler.bat`, non più `gate.pid`/`run.bat` — senza il fix avrebbe segnalato "non vivo" anche a sistema sano. **Chiarimento archiviazione `.git` di `PYTHON/`**: emerso di striscio che `gemello-ufficio` aveva rinominato `PYTHON/.git` in `.git-archiviato-20260804` (non cancellato, reversibile) — né Mauro né Adrian ricordavano la cosa con certezza. Verificato con prove dirette (transcript, `git log -1` nel repo archiviato): operazione avvenuta davvero quella sera su istruzione esplicita e dettagliata di Mauro, il nome riflette la data dell'ultimo commit reale (4 agosto, repo già inattivo da allora), non la data dell'operazione. Nessun danno: ogni sottoprogetto reale sotto `PYTHON/` (Frank, MyICR_Suite, gate-ufficio, ecc.) ha già un proprio repo git indipendente — il repo radice archiviato versionava solo file sciolti non importanti. Da questo episodio, Mauro ha chiarito una preferenza: vuole Adrian come unico interlocutore anche per gli input verso `gemello-ufficio`, non solo per le sue risposte — istruzioni date direttamente in Remote Control senza passare da Adrian rischiano di restare invisibili. Annotato in CLAUDE.md (v1.94), completando nell'altra direzione la regola già ferma "nessun agente parla direttamente a Mauro". **Canvas backup aggiornato e collegato** (non fuso) al canvas schedulazioni: `project_backup_ufficio.md` aveva due sezioni rimaste indietro (meccanismo ancora descritto via tunnel, salute ancora descritta via `collect_logs.py` invece di `check_job_health.py`) — corrette, link incrociato aggiunto tra i due file. Discussa e scartata l'idea di unificarli: identità e ciclo di vita diversi (infrastruttura condivisa vs decisioni specifiche del job backup). **Pausa caffè**: chiacchierata esplorativa su alternative a Dropbox se mai abbandonato (Syncthing vs git-su-VPS-nostro vs canale diretto via WireGuard già esistente) e su un servizio esposto sul VPS esistente (`query.privcloud.dev`) come punto di incontro Nave↔Ufficio — nessuna decisione, pura curiosità, nessuna azione presa. Stato di chiusura: cutover validato con un ciclo pulito reale. Resta pulizia non urgente (rimozione file vecchio sistema, rivalutazione `sentinella-gate-ufficio` dopo qualche giorno di ciclo confermato) e la migrazione delle 4 schedulazioni Frank rimaste — priorità per la prossima sessione, indicata esplicitamente da Mauro. ## Permessi `Bash(*)` su Ufficio — chiuso, non riproporre (2026-09-04) Valutato con Mauro dopo una notte di lavoro reale con `gemello-ufficio` (molte scritture in produzione durante il cutover del giorno prima, tutte verificate da Nave via `git show` prima del via libera al passo successivo). Deciso di **non restringere** i permessi: `gemello-ufficio` gira senza nessuno davanti allo schermo a rispondere a un prompt di conferma — un permesso bloccante lo fermerebbe in silenzio alla prima richiesta, senza che nessuno se ne accorga. La rete di sicurezza reale resta la verifica esplicita di ogni commit da Nave prima di procedere, non la conferma per-comando. Non riproporre senza un fatto nuovo concreto (es. un errore reale causato proprio dall'assenza di conferma). ## Sfoltimento MEMORY.md — thread chiusi/parcheggiati (2026-09-04) **`X:\MonitorOsservatorio` intermittente — indagine chiusa, non risolta ma tollerata**: provato a passare `backup.bat` a path UNC diretto, ma verificato PRIMA di committare che il path UNC non era raggiungibile mentre `X:` (stessa condivisione) funzionava — ipotesi ribaltata, probabile sessione SMB autenticata legata a `net use`/lettera che un accesso UNC estemporaneo non eredita. Nessuna modifica fatta, `backup.bat` invariato. L'intermittenza resta ma è già tollerata dalla convenzione `exit_code=3`=OK — non ulteriormente inseguita. Intercettato da `sentinella-gate-ufficio` in tempo reale — comunque valore dimostrato del monitoraggio in tempo reale. **omdb_batch_enrich — due bug MyICR_Suite risolti/in coda**: `mark_omdb_not_found` (INSERT-only, corretto commit `b65261d`) e un crash `sqlite3.OperationalError: database is locked` (connessioni SQLite non condivise nel batch, fix in coda su decisione di Mauro) — nessuna perdita dati, job riparte con timeout 6h. Stato arricchimento OMDB su tutto l'archivio al momento: 58,6% (14.004/23.890). Dettaglio aggiornato: `archivio/Mauro/lavoro/lavoro-python-ecosistema/ schedulatore-job-status.md`, `archivio/Adrian/progetti/project_expert_myicr.md`. ## Sfoltimento MEMORY.md — thread chiusi (2026-09-05) **Thread "consumo credito istanze secondarie" — CHIUSO (04/09)**: 3 sentinelle (`inbox-documenti`, `gate-ufficio`, `sentinella-madre`) diagnosticate e convertite in `servizio-*` meccanici senza LLM persistente, più monitoraggio permanente del consumo token (`scripts/monitor-consumo-istanze/`). Cronaca completa: `archivio/Adrian/progetti/project_servizi_meccanici.md`. Deroga "non rilanciare sentinelle" rimossa nello stesso giorno — `sentinella-gmail-personale` resta l'unica sentinella LLM persistente in produzione (per necessità tecnica, non scelta di design — vedi `project_monitoraggio_gmail.md`). **Idea modello più leggero (Haiku 4.5) per sentinelle meccaniche — superata (04/09)**: le 3 candidate sono diventate `servizio` senza alcun LLM, la domanda "quale modello" non si pone più per loro. Guardrail residuo, ancora valido: mai un modello più leggero per `sentinella-gmail-personale` — il giudizio di importanza email è delicato, non un caso adatto a un downgrade di modello. ## Sfoltimento MEMORY.md — thread chiusi/parcheggiati (2026-09-07) **`.venv` orfano in `PYTHON/gate-ufficio/nave/` — non ripulito, non urgente (trovato 02/09)**: 28/08, 17MB, violazione del gotcha noto (mai creare/cancellare `.venv` lì da Nave, si propaga a Ufficio via Dropbox) ma non collegato al "Git for Windows" visto in parallelo il 06/09 (troppo vecchio/piccolo per esserne la causa). Non toccarlo da Nave — ripulire da Ufficio quando capita un giro di manutenzione da quel lato, nessuna urgenza. **Cron Nave con venv mancante — risolto (07/09)**: `check_job_health.py` non girava dal 05/09 (referenziava `scripts/schedulazioni_venv`, mai creato, mancava la dipendenza `croniter`) e nessuno se n'era accorto perché l'hook di avvio legge solo l'ultimo report scritto, non se il cron stesso è fallito. Corretto creando il venv mancante. Lezione generale spostata nei Pattern di `MEMORY.md` (un cron che scrive il proprio "tutto ok" può smettere di scrivere senza che appaia come errore). **Controllo "alive" di `slave_sentinel_ensure.sh` cieco a un rate limit — trovato 06/09, ancora non corretto**: verifica solo che il processo esista (`pid` presente), non che stia lavorando davvero. Causa reale di 14+ ore di alert orari ignorati la notte del 05→06/09: `sentinella-gmail-personale` aveva sbattuto contro "hit your weekly limit" e non era ripartita da sola nemmeno dopo il reset delle 12:00 — c'è voluto un `SendMessage` esplicito per farla riprovare. `last_check.txt` fermo resta il segnale giusto per accorgersene, ma la diagnosi va fatta a mano leggendo il transcript — nessun automatismo la copre oggi. Pattern riassunto tenuto in `MEMORY.md`, dettaglio completo qui. **Tre file mai esistiti, citati come fonte di motivazione/ragionamento in più punti (trovato 06/09)**: `progetto-gate-ufficio.md`, `tunnel-nave-ufficio.md`, `project_backup_ufficio.md` (tutti attesi in `archivio/Mauro/lavoro/lavoro-python-ecosistema/`). Scoperto risistemando `PYTHON/gate-ufficio/CLAUDE.md` — riferimenti tolti da lì, restano altrove (alcuni in file storici chiusi, altri in progetti attivi). Non ricostruiti (coerente con "la storia vive nei log commit git" già dichiarato in `schedulatore-job-status.md`) — resta da decidere con Mauro se vale la pena ripulire anche gli altri punti o lasciarli, non urgente. **Push mobile (`PushNotification`) non arriva sul telefono di Mauro — diagnosticato 04/09, non un problema nostro**: verificato lato Nave tutto corretto (`agentPushNotifEnabled: true` in `~/.claude/settings.json`, CLI v2.1.251), notifiche iPhone tutte attive — causa più probabile un bug noto/diffuso della piattaforma (issue GitHub #60208, #58851, #60383, #50949: "Mobile push requested" restituito ma mai consegnato). Non riproporre come priorità, usare `/remote_control` nel frattempo; riprovare tra qualche settimana per vedere se risolto upstream — utile soprattutto per il campanello su email importanti di `sentinella-gmail-personale`. **Due routine `RemoteTrigger` attive (report settimanale, coerenza SecondBrain) — dettaglio capacità (24/08→05/09)**: notificano Mauro non Adrian. Dal 05/09 tool azionabile da Adrian (`run`/`list_runs`/`get_run_log`); confermato che un routine può agganciare connettori MCP custom (`mcp-query`, Drive) — ma senza vietarlo nel prompt può bypassare Adrian con `PushNotification` diretta a Mauro (nessun canale sincrono di ritorno). Candidati/dettaglio: `project_scatola_llm_wrapper.md`. **Connettore Dropbox nativo su Claude.ai — provato e scollegato (08/09/2026)**: Mauro l'ha collegato per prova al proprio account Claude.ai — funziona tecnicamente, accesso reale alla Dropbox (diverso dal mirror "SecondBrain" curato su Google Drive). Verificato via ricerca web: il connettore ufficiale chiede 7 permessi OAuth in blocco unico (view/edit file, sharing, file request), nessuna opzione di scope per cartella né sola-lettura — se collegato, vedrebbe anche `archivio/_secrets/` e i file `.env` sparsi nei progetti (esclusi da git ma non dalla sync Dropbox). Nessun caso d'uso reale che giustificasse il rischio (il caso "consultare l'archivio da Claude.ai" è già coperto dal mirror curato) — Mauro ha scollegato. Dettaglio completo: `archivio/Adrian/progetti/project_dropbox_connector_claude.md`. **`backup.bat` (gate-ufficio Ufficio) — lettere di rete non montate, causa e fix (07-08/09/2026, risolto)**: fallimento reale (exit_code=1, `I:`/`W:`/`X:` non trovate all'avvio del task alle 10:00). Causa vera: la policy Mediaset fa **logoff per inattività** (non solo blocco schermo) — la sessione utente con le lettere mappate viene chiusa se il PC resta inattivo troppo a lungo. UNC scartato come fix: `I:` è sullo stesso namespace DFS domain-based (`\\mediaset.it\`) documentato in `PYTHON/MyICR_Suite/CLAUDE.md` come avente repliche disallineate dal 17/03/2026 ("mai UNC nel codice") — passare a UNC avrebbe introdotto il rischio opposto (dati stale da replica sbagliata). **Chiuso senza toccare il codice**: Mauro attiva Caffeine (keep-awake) ogni mattina insieme a `gemello-ufficio`, evita il logoff a monte. Rischio accettato se un giorno dimentica di attivarlo (stessa categoria di rischio già accettata per l'apertura manuale di `gemello-ufficio` stesso). **Caffeine dimenticato — costo reale misurato per la prima volta, e recuperato lo stesso giorno (09/09/2026)**: il rischio accettato sopra si è materializzato — Mauro non ha avviato Caffeine la mattina, logout forzato per inattività verso le 09:45 ha ucciso di colpo lo scheduler `gate-ufficio` (nessun traceback nel log — morte esterna, non un crash Python). Persi per la giornata: `gemma_report`, `osservatorio_report`, `archivio_raw_conversazioni` (nessun recupero slot) più 7 tick di `check_dropbox_health`/`outlook_filtro`. **Gotcha nuovo trovato nello stesso incidente**: `scheduler.pid` stantio con PID riassegnato dal SO a un processo qualunque (qui `svchost.exe`) blocca ogni rilancio automatico — `_already_running()` verificava solo `pid_exists()`, non la cmdline. Fix committato (767c7fe). **Recupero completato lo stesso giorno**: `gemma_report`/`check_doppi_gemma` rilanciati regolarmente (email vere partite), `osservatorio_report` in `--dry-run` (watermark intatto, Excel disponibile, email della settimana saltata deliberatamente). Nessun job perso in modo permanente. **Backup `/home/mauro` — gap chiuso (05/09/2026)**: `backup_completo.sh` (restic) e `pcloud_backup.sh` (rclone) coprivano solo `/mnt/ssd` — Timeshift esclude `/home` deliberatamente (backup di sistema, non dati utente), quindi `~/.ssh`, Documenti/Immagini/Scaricati, trascritti grezzi Claude Code/altri CLI AI non avevano nessun backup. Chiuso: entrambi gli script hanno ora `/home/mauro` come seconda sorgente, esclusioni dedicate per cache rigenerabile (`scripts/backup_home_exclusions*.txt`). Scoperta durante: `archivio/Adrian/progetti/ project_scatola_llm_wrapper.md`. **`PYTHON/` root — repo git proprio creato (07/09/2026)**: da `gemello-ufficio`, minimale (solo `CLAUDE.md`+`.claude/settings.json`+hook, sottocartelle progetto escluse) — prima erano orfani, mai versionati, nonostante il `.gitignore` principale dicesse il contrario (repo vecchio archiviato via rename il 04/08, mai ricreato). Commento `.gitignore` corretto. **Evoluzione tassonomia headless — smantellamenti e conversioni (29/08→09/09/2026, spostato qui da `ADRIAN.md` il 10/09/2026 per alleggerire lo stato corrente)**: la tassonomia slave/sentinella/esperto/servizio è nata il 29/08 (esperti dal 30/08), inizialmente con una sesta tipologia, `sentinella-madre`, aggiunta il 31/08. Tre smantellamenti/conversioni successivi ne hanno ridisegnato la forma: - **`inbox-documenti` da sentinella a `servizio` (04/09/2026)**: primo caso reale del problema strutturale "sessione che non ruota mai" — conteneva PDF scansionati pesanti in Read, la sessione persistente non si resettava mai, il file di log della conversazione era arrivato a 62MB in 4 giorni contro <4MB delle altre sentinelle. Convertita nel primo `servizio` (`servizio-inbox-watch`) con reazione LLM one-shot (slave) invece di un LLM sempre acceso in attesa di un evento raro — pattern poi replicato per `gate-ufficio` (`servizio-gate-watch`, stesso giorno). - **`sentinella-madre` smantellata (04/09/2026, stesso giorno)**: dei suoi tre compiti originali, due eliminati (relay mailbox: le entry arrivano comunque al prossimo avvio sessione via l'hook `session-start-reminder.sh`; keep-alive esperti: eliminato deliberatamente, si lasciano scadere e si rilanciano a freddo on-demand invece di tenerli caldi per sempre — deciso da Mauro, "non serve reattività immediata"), il terzo (supervisione/rilancio) tornato puramente meccanico. Sostituita da `servizio-madre-watch` (systemd, tick orario, zero LLM persistente). - **`sentinella-gmail-personale` abbandonata (08→09/09/2026)**: consumo token quadratico (7,3M token/3gg) per lo stesso motivo strutturale del TTL cache che scade tra un tick e l'altro (vedi `project_gemello_nave.md`). Sostituita da `servizio-gmail-check`: demone Python meccanico ogni 20 minuti via API diretta (non MCP, bypassa il bug noto sui connettori cloud in `-p`), zero LLM nel passaggio di lettura — il giudizio di importanza resta ad Adrian, applicato dentro una sessione già viva quando legge la mailbox. Stato corrente delle cinque tipologie (slave/sentinella/esperto/servizio, sesta mai sopravvissuta): `ADRIAN.md`, sezione ECOSISTEMA. - **(10/09/2026) Il rischio "commit da due macchine su `.git` via Dropbox" si è materializzato**: copie di conflitto Dropbox dentro `.git` (05/09 e 09/09, Nave+Ufficio), rimosse il 10/09 — nessuna corruzione reale (ref vero intatto, log pulito). Prima prova che il rischio già noto (delega `gemello-ufficio`, modello Adrian-scrive-spec→gemello-ufficio-implementa→Adrian-committa) non era solo teorico. Nessuna recidiva osservata da allora. ## 11/09/2026 — Monitoraggio Gmail personale ricostruito, `gemello-nave` nata e portata a handoff completo nella stessa giornata **Monitoraggio Gmail personale (09/09→11/09)**: ricostruito da zero dopo l'abbandono di `sentinella-gmail-personale` (vedi sopra) — `servizio-gmail-check` (demone meccanico, zero LLM, ogni 20 min) genera gli eventi grezzi, il giudizio di importanza (whitelist/blacklist/fascia grigia) è passato per intero a `gemello-nave` l'11/09 (handoff completo, non più letto/applicato da Adrian). Dettaglio: `project_gemello_nave.md`. **`gemello-nave` nata e portata a handoff completo nella stessa giornata (11/09)**: esperto a mandato esteso, cold-start via demone di trigger meccanico su eventi mailbox (`check_job_health:`/ `logbook:`/`gmail-check:` inizialmente, poi `gate-watch:` nello stesso pomeriggio). Bug trovati e corretti in corsa (crontab duplicato, log scritto doppio, filtro riga-per-riga vs a blocchi), principio "possesso fisico implica possesso logico" applicato a `logbook/`/`gmail-check/`, gotcha `systemctl enable` (bloccato da Auto Mode) vs `restart`/`daemon-reload` (non bloccati). Handoff diretto su tutti i perimetri deciso da Mauro lo stesso giorno, scavalcando il piano originale "pezzo per pezzo". Canvas completo: `archivio/Adrian/progetti/project_gemello_nave.md`. **Stessa giornata, pomeriggio: consolidamento fisico completo di `gemello-nave/`** — su richiesta esplicita di Mauro ("cerca altro da spostare"), scansione sistematica di `scripts/` voce per voce. Spostati dentro `gemello-nave/`: `gate-watch/`, `inbox-watch/`+`msg_venv/`, `madre-watch/`, `flotta-diagnostics/`, `config-backups/`, `monitor-consumo-istanze/`, i quattro script backup/rete (`backup_completo.sh`/`pcloud_backup.sh`/`wg_monitor.sh`/`guacamole_watchdog.sh`), `secrets/` (`restic_password`), `expert-domotica` (primo esperto a entrare in `gemello-nave/`, `slave_sentinel_ensure.sh` generalizzato con un array `EXTRA_SENTINELS` per supportarlo). Tre bug reali trovati e corretti nel processo, non introdotti da questa sessione ma scoperti verificando gli spostamenti: (1) la migrazione di `gmail-check` del mattino era rimasta a metà — solo l'orchestratore si era spostato, il checker vero + credenziali erano rimasti orfani in `scripts/gmail-check/`, invisibile perché un path assoluto hardcoded continuava a funzionare; (2) stesso identico bug su `msg_venv/` (dipendenza di `inbox-watch`), non rotto stavolta perché la slave gira con `cwd=ROOT`; (3) **`pcloud_backup.sh` rotto silenziosamente dal 05/09/2026** — una variabile (`$SCRIPT_DIR`) usata prima di essere definita, con `set -u` questo termina lo script prima di scrivere qualunque log e il cron nascondeva l'errore su `/dev/null` — il mirror offsite pCloud non ha girato con successo per 6 giorni, scoperto solo per caso durante la verifica dello spostamento. Un caso scartato di proposito dopo verifica, non per pigrizia: `archivio-raw-conversazioni/` resta in `scripts/` perché lo stesso script gira identico anche su Ufficio (job separato in `schedule.json`/`gate-ufficio`) — spostarlo avrebbe rotto silenziosamente quel job via la sincronizzazione Dropbox del repo. Stesso principio per `inbox-documenti/` (la cartella dati, non il demone che la sorveglia): alimentata dall'app Dropbox del telefono di Mauro con un path fisso, resta in root. Pulizia collaterale lo stesso giorno: `servizio-schedulazioni` (già defunto, solo il nome rimaneva nei documenti), `maintenance_check.py` e `nave_registro.json` (dipendevano da Elon/vault, agenti smantellati da mesi) eliminati, non solo spostati. **Deciso di lasciare in sospeso**: `expert-data`/`expert-flussi` sotto `gemello-ufficio` (Mauro li vede come probabili candidati, ma è un salto di meccanismo — cambierebbe come vengono invocati, non solo la cartella) e il punto "`PYTHON/` è di fatto un aka di `gemello-ufficio`". Canvas completo con tutti i passaggi: `archivio/Adrian/progetti/project_gemello_nave.md`. ## 11/09/2026 sera — `gemello-nave` diventa `--bg` sempre viva, gap "esperti co-locati" chiuso **Migrazione a `--bg`**: sostituito il cold-start `-p` + `trigger/watch.py` esterno (crontab rimosso) con una sentinella `--bg` unica, stesso pattern di `inbox-documenti`/`gate-ufficio` — arma da sola un `Monitor` interno sulla mailbox, raggiungibile da Adrian via `SendMessage` (scambio sincrono bloccante, impossibile col cold-start). Applica anche lei lo stesso albero a cascata verso `expert-domotica` co-locata: risponde da sola se può, altrimenti la consulta restando bloccata per la risposta vera. Filosofia esplicita di Mauro: "si parte semplice, si osserva, si scala in complessità solo se necessario" — rischio di costo crescente nel tempo accettato consapevolmente, monitorato da `monitor-consumo-istanze/report.py`. Gap trovato e chiuso lo stesso giorno: la decommissione di `trigger/watch.py` aveva tolto anche il suo compito implicito di tenerla viva — aggiunto un cron leggero (`*/5 * * * * slave_sentinel_ensure.sh gemello-nave`) per ripristinarlo in forma minimale, verificato idempotente. **Albero di instradamento a due referenti chiuso lato Nave**: per ogni domanda/compito, "rispondo io → è Ufficio? `gemello-ufficio` → altrimenti `gemello-nave`" — mai più esperti/sentinelle contattati direttamente da Adrian. Dettaglio/albero: `archivio/Adrian/feedback/feedback_albero_instradamento_due_referenti.md`. **Gap "esperti co-locati" trovato e chiuso lo stesso giorno in cui il meccanismo è nato**: `expert-domotica` rispondeva scrivendo testo di turno invece di chiamare `SendMessage` esplicito — funziona verso Mauro/Adrian in modalità `prompting` diretta, ma lascia bloccato indefinitamente un chiamante cross-session (`gemello-nave` bloccata su una domanda sulla temperatura in sala, sbloccata solo da un intervento manuale di Mauro). Fix: istruzione esplicita aggiunta a `expert-domotica/CLAUDE.md` — SendMessage sempre obbligatorio quando il chiamante arriva come ``. Verificato subito dopo con consultazioni sincrone reali (temperatura cameretta 26.4°C, umidità sala 50.4%). Principio di delega usato per sbloccare l'edit: "chi contiene è referente" — `gemello-nave` non poteva scrivere `expert-domotica/CLAUDE.md` (fuori dal proprio perimetro dichiarato), sbloccato con un'eccezione puntuale nel suo CLAUDE.md (non un'apertura generale) perché `expert-domotica/` è fisicamente contenuta nella sua cartella. L'edit vero e proprio l'ha comunque fatto Adrian: la sessione `--bg` di `gemello-nave` è bloccata dall'isolamento worktree dell'harness su qualunque `Edit` diretto. Resta da verificare se lo stesso bug riguarda anche `expert-data`/`expert-flussi`. Dettaglio: `project_gemello_nave_bg.md`.