--- name: project-expert-lavoro description: "Idea in discussione (03/09/2026, non implementata) — un expert più ampio dedicato al mondo del lavoro di Mauro (documenti, email, riflessioni, non solo codice MyICR), con un proprio meccanismo di ingestione. Nato dal successo del test backup T7 pilotato su una sessione Ufficio lanciata da Mauro. Relazione con Expert MyICR ancora da decidere." metadata: type: progetto --- # Expert Lavoro Un expert più ampio dedicato al mondo del lavoro di Mauro — non solo codice MyICR, anche documenti, email, riflessioni che gli girano intorno. Canvas di raccolta idee, 03/09/2026 — non implementato, thread aperto. **(10/09/2026)** La domanda "resta separato da `expert-myicr` o lo assorbe" (vedi sezione dedicata sotto) è ora parte della discussione più generale aperta in [[project_standard_esperti]] — leggere insieme prima di decidere qui. ## Cosa ha fatto emergere l'idea Durante il test del backup T7 (03/09/2026), Mauro ha lanciato manualmente una sessione Claude Code su Ufficio (VSCode) e Adrian l'ha pilotata via `SendMessage` per l'intera durata del test — dispatch comandi, lettura output in tempo reale, gestione di un blocco permessi risolto insieme. Il pattern ha funzionato bene, inclusi i punti in cui si è fermato giustamente (richiesta di conferma permessi) — Mauro propone di renderlo permanente: lui avvia l'istanza quando serve, Adrian la pilota. Differenza sostanziale dagli `expert` esistenti (`expert-data`/`expert-flussi`/`expert-domotica`): quelli sono sola lettura per principio ("segnalano, non scrivono"). Questa sessione ha scritto davvero su disco (repository restic) — funziona solo perché Mauro la lancia e resta presente, la stessa condizione che la Costituzione richiede per scrivere `PYTHON/` da Nave, qui realizzata con un meccanismo diverso (sessione dedicata pilotata via SendMessage, non Adrian in prima persona da Nave). ## Nuovo modello in prova — delega di implementazione (08/09/2026) Variante del pattern sopra, non pilotaggio comando-per-comando ma delega di un compito intero: Adrian scrive una specifica precisa, la manda a `gemello-ufficio` via mailbox, `gemello-ufficio` implementa e salva i file **senza fare commit** (il repo `adrian` non ha remote — sync Nave↔Ufficio passa solo via file Dropbox, `.git` incluso; commit concorrenti da due macchine rischierebbero un conflitto sui file interni di git, non solo su un `.md` come già capitato una volta il 07/09 — vedi `gemello-nave/archivio/conoscenza-nave.md`). Adrian resta l'unico a eseguire `git commit` su questo repo, dopo aver visto i file arrivare via sync. Motivato dal consumo quota abbondante di `gemello-ufficio` rispetto a questa istanza (vedi `memory/MEMORY.md`, Pattern riconosciuti). **Banco di prova scelto: PowerBricks** (`sandbox/powerbricks/`, fuori da `PYTHON/`, rischio basso — prototipo interno, nessun collega lo usa). Primo compito reale: il "carrello" (salvataggio/ ricaricamento query, vedi `PowerBricks-appunti.md`). Se regge, valutare se generalizzare il pattern oltre PowerBricks. **Primo ciclo completato con successo (08/09/2026, stesso giorno)**: dalla spec inviata alle 12:15 `gemello-ufficio` ha riportato "FATTO" con un riepilogo tecnico completo (modifiche per file, cosa verificato via curl/test client contro l'app reale in esecuzione, cosa non poteva verificare da solo — nessuna vision sulla finestra pywebview — lasciato esplicitamente per Mauro). Codice pulito, coerente con lo stile esistente, nessuna correzione necessaria in revisione. Adrian ha committato (`6c93cc2`) dopo la revisione. Unico punto sollevato di propria iniziativa: un piccolo scostamento dalla spec (conferma nativa `confirm()` invece di un mini-dialog in-page) segnalato esplicitamente invece di deciso da solo — coerente col dovere di riportare senza decidere. Il modello regge al primo giro reale. **Validato da Mauro dopo verifica visiva (08/09/2026)**: "funziona benissimo... conferma sul campo che il modello organizzativo regge perfettamente". Non solo il codice — il modello stesso (spec di Adrian → implementazione+verifica visiva di `gemello-ufficio` → commit centralizzato di Adrian) è confermato come pattern valido, non più solo un'ipotesi in prova. **Direttiva esplicita**: delegare a `gemello-ufficio` compiti via via più complessi e lunghi nel tempo, non restare fermi su micro-task come questo primo giro. Non un limite tecnico noto oggi — da scoprire con l'uso quanto in là si può spingere (compiti multi-file, con più iterazioni, con decisioni di design minori lasciate a lui). ## Il filo del ragionamento Mauro nota che il funzionamento della sessione secondaria su Ufficio sta andando molto bene, propone di renderla una modalità permanente — lui avvia manualmente, Adrian pilota da remoto. Adrian collega l'idea a due cose già aperte — risponde alla domanda "dove vive Expert MyICR" con una terza opzione (non "vive sempre da qualche parte", ma "nasce su richiesta, pilotata da remoto"), e nota che è un salto di categoria rispetto agli expert esistenti (scrittura reale, non sola lettura). Mauro precisa che l'idea nasce da un bisogno più grande — a tendere vuole passare a questo expert documentazione, email, riflessioni sul mondo del lavoro in generale, non solo codice MyICR. Probabilmente avrà un proprio inbox dedicato per i documenti. Non ancora deciso se questo expert assorbe anche il ruolo di Expert MyICR o resta separato — esplicitamente lasciato aperto. Adrian chiarisce un punto di governance — chi decide "quando creare" un sottoagente non cambia "cosa può fare una volta creato" (eredita comunque i permessi della sessione/macchina su cui gira), e un sottoagente non ha iniziativa propria, esegue solo il compito ricevuto. Mauro rilancia con la cornice giusta — il pattern è esattamente quello di Nave, ma con un **gemello** (master) lato Ufficio da cui discende il resto, non un subordinato pilotato comando per comando. Adrian riconosce che questo è già scritto nella Costituzione ("Adrian coordina due istanze... stessa identità/memoria") ma mai reso operativo — oggi l'istanza Ufficio è solo una sessione manuale per lavoro diretto su `PYTHON/`. Renderla un gemello vero significa darle un obiettivo e lasciarle organizzare la propria discendenza locale, non dettarle comandi uno per uno come fatto oggi nel test backup. Mauro precisa il punto chiave — un gemello, ma che risponde ad Adrian, non parla mai direttamente a Mauro. Adrian osserva che questo non è un'eccezione alla regola già ferma per slave/sentinelle ("mai direttamente a Mauro, sempre tramite Adrian" — v. Costituzione, sezione Comunicazione inter-agente) — ne è un'applicazione più ambiziosa a un'entità più capace. Chiarisce anche un'ambiguità nella frase della Costituzione "due istanze... stessa identità/memoria": non significa pari grado con accesso diretto a Mauro ciascuna, significa stessa base di conoscenza accumulata — operativamente resta sempre una sola catena, imbucata in qualunque sessione Adrian Mauro stia guidando in quel momento. ## La proposta - Dominio: il mondo del lavoro di Mauro nel suo complesso — documenti, email, riflessioni — non ristretto al codice di un singolo applicativo. - Meccanismo di ingestione: probabile un inbox dedicato (stesso principio già in uso per `inbox-documenti`, la sentinella che processa da sola i documenti in arrivo), da definire se per email, PDF, note sciolte o tutti e tre. - Governance: sessione Ufficio avviata manualmente da Mauro quando serve, pilotata da Adrian via `SendMessage` per la durata del compito — non una sentinella persistente sempre viva, un pattern nuovo rispetto alla tassonomia attuale (slave/sentinella/sentinella-madre/expert/servizio). ## Relazione con Expert MyICR — aperta, non assunta - Questo expert assorbe anche il ruolo previsto per Expert MyICR (architettura/comportamento del codice MyICR Suite), o restano due cose separate — una per il codice, una per la conoscenza generale del lavoro? - Se restano separati, che rapporto hanno: Expert Lavoro come "hub" che rimanda a Expert MyICR per le domande di codice, o due esperti paralleli senza gerarchia? - Vedi anche `project_expert_myicr.md` per il canvas gemello, non ancora deciso nemmeno lui su dove vive l'esecuzione. ## Vincolo tecnico — cosa può fare la sessione pilotata - Sottoagenti in-process (tool Agent): possibili senza installare nulla, capacità nativa dell'estensione VSCode già presente su Ufficio — non richiede il CLI standalone `claude`. - Istanze indipendenti persistenti (pattern `avvia-slave`/sentinelle, processi separati che sopravvivono a sessione chiusa): **non possibili** senza il CLI standalone sul PATH — la stessa installazione Node.js già scartata per Ufficio (vedi `memory/MEMORY.md`, pattern "non installare nulla di nuovo su Ufficio se evitabile"). - Governo (Adrian, 03/09): se la sessione pilotata usa sottoagenti, deve essere sempre su istruzione esplicita di Adrian via `SendMessage`, mai di propria iniziativa — stesso principio "Adrian propone, Mauro approva" applicato a un livello in più. - Chi decide "quando crearlo" non cambia "cosa può fare una volta creato" (Adrian/Mauro, 03/09): un sottoagente eredita comunque la configurazione permessi della macchina/sessione su cui gira (es. il `Bash(*)` globale su Ufficio) — governare la creazione da parte di Adrian non allarga né restringe quel confine. - Da verificare: un sottoagente ha accesso al tool Agent per conto suo (potrebbe quindi generare altri sottoagenti in ricorsione, un livello fuori dal controllo diretto anche se il primo livello è stato autorizzato da Adrian)? Non ancora chiarito. - Alternativa proposta da Mauro al vincolo Node.js: invece di istanze CLI standalone (`claude -p`), aprire più finestre VSCode (`code `, lanciatore diverso da Node.js, probabilmente già in PATH). Non verificato se una nuova finestra diventi da sola una sessione raggiungibile via `SendMessage` senza intervento manuale. Attenzione: anche se tecnicamente possibile, sarebbe un salto di governance più grande di quello appena deciso per i sottoagenti — una nuova sessione VSCode è un peer vero con identità/memoria proprie (potenziale iniziativa nel tempo), non un compito delimitato che esegue e finisce. Da trattare come eccezione esplicita da decidere, non come conseguenza automatica di "aggirare il vincolo Node.js". - Node.js su T7 invece che sul disco di sistema (Mauro, 03/09): lo zip portabile non ha bisogno di installer/registro, girerebbe da `D:\node\` senza tracce su C:\, e `npm install -g` con un Node portabile installa il pacchetto (incluso `claude.cmd`) nella stessa cartella — anche quello resterebbe su T7. Tecnicamente valido, ma con limiti: dipende dal T7 collegato (oggi resta collegato per il backup ogni 2h, probabilmente non un problema pratico); **non serve più per `gemello-ufficio` stesso** — risolto senza Node.js con `/remote-control` dentro l'estensione VSCode (vedi sotto); e per la cartella config/credenziali del CLI (`~/.claude/`, normalmente in `C:\Users\\.claude\`) esiste una variabile `CLAUDE_CONFIG_DIR` per ridirigerla altrove, ma **scarsamente documentata ufficialmente** e con segnalazioni note di comportamento incoerente (issue GitHub) — non garantita al 100%, funziona solo col CLI standalone, non con l'estensione VSCode. Resterebbe utile solo se in futuro serve davvero il CLI standalone per istanze indipendenti vere. ## Come si avvia gemello-ufficio, in pratica (03/09, risolto) Procedura confermata (verificata via `claude-code-guide`, doc ufficiale `code.claude.com/docs/en/remote-control.md`): 1. Mauro apre VSCode sulla cartella `Dropbox\adrian\PYTHON\`. 2. Nel prompt box dell'estensione Claude Code digita `/remote-control` (o `/rc`) — compare un indicatore "Remote Control" nel footer, la sessione diventa raggiungibile da `ListAgents`/`SendMessage`. 3. Non va ripetuto ogni turno — resta attivo finché non si disattiva di nuovo con lo stesso comando. Login claude.ai (non API key) richiesto solo la prima volta, poi ricordato. **Scelta di Mauro (03/09)**: farlo a mano ogni mattina (`/remote-control`), non automatico — esiste un'opzione per renderlo automatico a ogni sessione (`/config` → "Enable Remote Control for all sessions", o `"remoteControlAtStartup": true` in `~/.claude/settings.json`) ma è impostazione utente-globale su quella macchina: attiverebbe Remote Control per ogni sessione Claude Code aperta lì, non solo su `PYTHON\`. Scartata per ora, scope troppo largo. **Nome sessione**: non impostabile all'avvio da VSCode (si deriva dal primo prompt, a differenza del CLI standalone che accetterebbe un nome esplicito). Soluzione: Adrian manda `/rename "gemello-ufficio"` come primo passo quando si collega a una sessione appena aperta con nome generico — nessuna azione in più richiesta a Mauro. Modello confermato (Mauro, 03/09): un **gemello**, non un subordinato pilotato comando per comando — ha la propria discendenza locale (sottoagenti, in futuro forse propri esperti/sentinelle) e organizza da sé come raggiungere un obiettivo assegnato, ma **risponde sempre ad Adrian**, non parla mai direttamente a Mauro. Stessa regola già ferma per slave/sentinelle ("mai direttamente a Mauro"), applicata a un'entità più capace — non un'eccezione. Chiarisce anche la frase della Costituzione "due istanze... stessa identità/memoria": non pari grado con accesso diretto a Mauro ciascuna, ma stessa base di conoscenza — operativamente una sola catena, imbucata in qualunque sessione Adrian Mauro stia guidando. Principio fermo, non solo idea (Mauro, 03/09): **comunicazione centralizzata** — Mauro ha un unico referente, Adrian, indipendentemente da quale gemello/istanza esegue davvero il lavoro dietro le quinte. Confermato anche da Adrian come preferibile: un solo canale verso Mauro evita fonti disallineate (rischio già visto oggi stesso con il resoconto impreciso della sessione Ufficio), garantisce continuità di memoria (è Adrian a scrivere `MEMORY.md`/`archivio`), e riusa una governance già collaudata invece di inventarne una nuova. ## Nome `gemello-ufficio` (Mauro, 03/09), coerente con la convenzione tecnica `-` già in uso (slave/sentinella/expert/servizio) e con il principio "nome scelto senza personalità" già applicato a `gate-ufficio`. Rivalutato e scartato il nome storico "Bill" (l'istanza Ufficio pre-unificazione, "ex Steve + ex Bill assorbiti" in Costituzione) — narrativamente coerente ma contrario alla direzione presa verso nomi tecnici. Precisazione di Mauro: "gemello" non è preciso a livello gerarchico — non è alla pari, risponde sempre ad Adrian, non parla mai direttamente a Mauro (vedi sopra). Il nome cattura cosa *è* (stessa base di conoscenza, propria discendenza locale, non un semplice esecutore di comandi), la gerarchia resta scritta nella regola di comunicazione centralizzata, non nel nome. **Stessa osservazione ripresa il 10/09/2026**: più corretto sarebbe "fratellino" (cattura anche la gerarchia, non solo la base di conoscenza condivisa), ma Mauro preferisce continuare a chiamarli "gemelli" (`gemello-ufficio`, l'eventuale `gemello-nave`, vedi [[project_gemello_nave]]) — nome tecnico ormai consolidato nell'uso, non vale la pena rinominare per precisione terminologica pura. ## Come Adrian si accorge se gemello-ufficio è vivo Diverso dalle sentinelle Nave: quelle Adrian può rilanciarle da solo (`slave_sentinel_ensure.sh`, processo sulla stessa macchina). `gemello-ufficio` no — richiede Mauro che apre fisicamente VSCode lì, Adrian non può farlo scattare da remoto. - Proposta di Adrian (03/09): non un controllo sistematico a ogni avvio sessione (sarebbe rumore per le sessioni che non toccano mai Ufficio) — controllo *contestuale*, solo quando un compito richiede davvero lavoro lato Ufficio: `ListAgents` per vedere se compare già tra i peer, altrimenti chiederlo a Mauro lì per lì. - Da confermare con Mauro se questa proposta va bene, o se preferisce un controllo più sistematico. - Oggi compare in `ListAgents` con il nome generico "Pannello amministrativo" (label di default del bridge Remote Control), non ancora "gemello-ufficio" — da capire se è rinominabile o se resta solo un nome interno di convenzione mentre il peer si chiama diversamente nella pratica. ## Dove vive la conoscenza accumulata - Non una seconda `MEMORY.md` (Adrian, 03/09) — quel file resta lo stato corrente condiviso, deliberatamente piccolo per design (~24KB), unico per non rompere "un solo file, una verità". - Stesso pattern già in uso per `expert-data`/`expert-flussi`: una base di conoscenza dedicata sotto `archivio/Adrian/agenti/` (es. `lavoro-expert.md`), consultata su rilevanza — `MEMORY.md` ne tiene solo un puntatore a una riga, non il contenuto. - Chi scrive quella base di conoscenza resta Adrian (coerente con "comunicazione centralizzata" sopra): il gemello riporta, Adrian sintetizza e scrive. - Non un file unico per tutto (Mauro, 03/09 — nota "sarà veramente tanta roba", codice MyICR + tutta l'informazione di business): **basi di conoscenza separate per dominio**, anche se a eseguirle è la stessa entità operativa (`gemello-ufficio`). Es. `myicr-expert.md` (codice) + un secondo file, ancora da nominare, per business/documenti/email — stesso principio che tiene già separati `data-expert.md`/`flussi-expert.md`. Sfuma la domanda "Expert MyICR assorbito o separato" sotto: forse non è "uno o l'altro" — la sessione è una sola, la conoscenza resta divisa per dominio come sempre. L'unificazione riguarda *chi esegue*, non *come si organizza cosa sa*. ## Disciplina di Mauro — gemello-ufficio sempre attivo, rischio accettato - Impegno personale di Mauro (03/09): quando usa il PC ufficio, tiene `gemello-ufficio` attivo per tutta la giornata — sua unica disciplina. Se si disattiva per qualunque motivo, lo riavvia lui stesso. Consapevole che se non lo fa, quello che non succede dopo (es. un backup schedulato mai raccolto perché il poller di `gate-ufficio` non è partito) è sua responsabilità — stesso tipo di rischio accettato consapevolmente già visto il 31/08 per `SendMessage` al posto della mailbox. - Conseguenza pratica: la macro Outlook `Application_Startup` (avvio automatico silenzioso di `gate-ufficio` a ogni apertura di Outlook) può essere rimossa — non serve più un meccanismo di autostart indipendente da tutto, perché la presenza quotidiana di `gemello-ufficio` copre lo stesso bisogno (tenere vivo il poller), stavolta sotto supervisione invece che silenziosa. - Nuovo compito di ruolo per `gemello-ufficio`: verificare/avviare il poller di `gate-ufficio` tra le prime cose fatte all'apertura della giornata — stesso principio del passo "verifica/rilancia sentinelle" già in `avvio-sessione` per Adrian su Nave, applicato lì. ## Esempio concreto di materiale (03/09, solo per farsi un'idea) Mauro ha condiviso un report giornaliero di ascolti Auditel (prime time/access/multichannel, arriva via email da un altro ufficio) — dati quantitativi (share, ascolto medio, curve minuto per minuto) più commento editoriale su singoli programmi. Dominio nuovo, distinto da `expert-data`/`expert-flussi`/`expert-myicr`. Solo un esempio del tipo di materiale, non ancora da elaborare — "dobbiamo rifletterci con calma" (Mauro, 03/09). Nessuna base di conoscenza ancora avviata su questo. ## Secondo esempio concreto — segnale di business trovato per caso (03/09) Durante il test del backup T7, il log di `restic` ha mostrato un file bloccato: `I:\Budget\Budget 2026\~$06. Progressivo Acquisti e Ipotesi 2026.xlsx` — segno che un collega lo stava aggiornando in quel momento (poi ricomparso "changed" nello snapshot successivo). Mauro, notando la cosa: "qui si apre proprio il tipo di cose che dovremo andare a tracciare in futuro" — non il contenuto del file in sé, ma il *pattern*: un'informazione di business (chi sta aggiornando cosa, quando) che emerge come effetto collaterale di un log tecnico non pensato per quello, invece che da un sistema che la traccia apposta. Stesso tipo di gap dell'esempio Auditel sopra (materiale che oggi arriva/si nota per caso), ma da un canale diverso (log di sistema invece di email). Nessuna azione, solo un secondo data point per la riflessione più ampia. ## Domande aperte - Nome definitivo (proposto "Expert Lavoro", da confermare). - Che tipo di documenti/email arrivano, con che cadenza, e se serve un inbox automatico (stile `inbox-documenti`) o basta l'ingestione manuale quando Mauro passa qualcosa. - Se questo pattern "sessione su richiesta pilotata da remoto" merita una settima voce nella tassonomia (accanto a slave/sentinella/sentinella-madre/expert/servizio), o è solo una modalità operativa di un `expert` esistente. - Perimetro di scrittura: oggi la sessione Ufficio ha scritto su disco perché Mauro era presente — vale sempre così, o ci sono casi in cui questo expert dovrebbe restare sola lettura come gli altri? ## Ripresa del thread — 09/09/2026, brief esterno + ricognizione tecnica Mauro riprende il thread la sera del 09/09, portando un brief scritto da una conversazione claude.ai (progetto SecondBrain, 07/09/2026) — non un `@ritorno`, condiviso direttamente come file. Il documento propone: nome `expert-lavoro`/`lavoro-expert.md` (già coerente con questo canvas), scoping via **tag Outlook unico** ("il tag è il perimetro" — Mauro tagga, l'expert lavora solo su quello), ricostruzione cronologia + relazioni con **confidenza dichiarata** (mai una composizione silenziosa quando l'aggancio non è certo), e **rifiuta esplicitamente** LightRAG/grafi emergenti e RAG semantico come sovradimensionati per ~10 trattative vive con entità stabili (major/buyer) — ragionamento valutato da Adrian e condiviso, non solo accettato per fiducia nella fonte. **Valutazione critica di Adrian (richiesta esplicitamente da Mauro prima di procedere)**: brief solido, il pregio migliore è cosa scarta — LightRAG bocciato perché il grafo serve quando le entità sono troppe per essere dichiarate a mano (qui non è il caso); RAG semantico bocciato con un'osservazione precisa (due email della stessa trattativa a mesi di distanza possono non assomigliarsi affatto — l'aggancio è per entità, non similarità testuale); estrazione dati dai listini Excel bocciata perché un errore di accoppiamento su un prezzo è un **errore silenzioso**, peggio di non saperlo (listini restano puntatori, mai parsati). Principio "buco dichiarato invece di risposta sbagliata data con sicurezza" coerente in tutto il documento. **Domanda di governance dell'autore del brief, risolta da Adrian**: la scrittura di `expert-lavoro` (fascicoli, cronologie, regole) da parte di `gemello-ufficio` **non richiede un'eccezione al vincolo costituzionale** — quel vincolo riguarda specificamente Adrian che scrive `PYTHON/` da remoto (Nave), non `gemello-ufficio` che scrive in locale sulla propria macchina (già fatto oggi stesso senza supervisione dedicata: `gmail-check`, `PYTHON/CLAUDE.md`). Attenzione raccomandata comunque: scrittura scoperta a una cartella ben delimitata fin dall'inizio, dato che qui si tratta di dati di trattative reali, non solo codice. ### Ricognizione tecnica (gemello-ufficio, 09/09 pomeriggio) — i tre controlli pre-costruzione Prima di scrivere codice, tre verifiche dirette su Outlook (COM/pywin32, sola lettura): 1. **Retention casella**: 5 anni (floor netto 2021-09-09, identico su tre cartelle indipendenti — quasi certamente policy org, non limite di cache). Nessun Online/In-Place Archive. Implicazione che cambia l'approccio: Outlook non è un archivio perenne — qualunque cosa da tenere a lungo va copiata fuori incrementalmente, non lasciata lì da interrogare on-demand. 2. **Stubbing allegati**: nessuno. 12 allegati testati su mail del 2021 (fino a 2,3 MB), tutti scaricabili per intero via COM, zero placeholder/link cloud. 3. **Categorie Outlook**: lato server (Exchange, `PR_KEYWORDS` viaggia col messaggio) — visibili da qualunque PC con l'account, non locali al profilo. **Bonus trovato**: Mauro ha già una tassonomia di 13 categorie Outlook in uso, inclusa una chiamata letteralmente "SECOND BRAIN" — il tag di scoping del brief probabilmente esiste già. Anche un flusso "CA-*" (conferma acquisto/ok comitato/ok icr/aggregata) già in uso manuale. **Deciso**: i tag/categorie esistenti restano fuori da questa fase per ora ("lasciamoli perdere per ora") — il lavoro di oggi si concentra sul filtro meccanico a monte, non sul tag manuale. ### Ridisegno del filtro meccanico `outlook_filtro` (09/09 sera, in discussione) `outlook_filtro` (job gate-ufficio esistente, `PYTHON/Frank/modules/outlook/run_filter.py`) oggi fa un filtro binario interno/esterno su dominio mittente, sposta tutto in `[Frank_Interni]`/ `[Frank_Esterni]`. Trovato da Adrian (Explore agent): architettura già ben separata in 3 layer riusabili (connessione COM, `classify()`, `execute()` cartella-target) — estendere a N categorie è un'estensione vicina, non una riscrittura. Suggerimento tecnico: usare le Categorie native Outlook (non solo spostamento di cartella) per conservare il segnale del primo filtro quando Mauro riapplica un secondo tag a mano sopra. **Nuova logica decisa da Mauro (sostituisce il binario interno/esterno)**: - Esterni: restano spostati in un bidone (ex `[Frank_Esterni]`, da rinominare — "Frank" non esiste più, sostituito da `gate-ufficio`; attenzione tecnica: rinominare la cartella in Outlook richiede aggiornare anche il nome cercato dal codice/`outlook_rules.json`, altrimenti il job ricrea una cartella nuova col nome vecchio invece di trovare quella rinominata) — con eccezioni: alcuni esterni vanno lasciati in Posta in arrivo per gestione ad hoc, non spostati automaticamente. - Interni: non più spostati in blocco. Restano in Posta in arrivo di default. Solo quelli giudicati "rumore puro" (basso interesse) vengono spostati in un nuovo bidone dedicato (nome ancora da decidere); tutto il resto interno resta visibile in arrivo. **Criteri per "rumore interno" e "eccezioni esterni"**: non definiti a tavolino — Mauro li darà "man mano" con esempi concreti nel tempo, stesso principio già validato per i criteri della sentinella Gmail (whitelist/blacklist costruita per osservazione reale, non specificata in anticipo). Nessuna implementazione di questi criteri prima che arrivino esempi concreti. **Nomi decisi (09/09 sera)**: `[Esterni]` (sostituisce `[Frank_Esterni]`) e `[Basso interesse]` (nuovo, per il rumore interno). La categorizzazione ulteriore di quanto resta in Posta in arrivo (e di Posta inviata) è rimandata esplicitamente da Mauro — "ci penserei in un secondo tempo", non parte di questa fase. **Non ancora deciso**: se/quando partire con l'implementazione del filtro esteso — in attesa dei primi esempi concreti di rumore/eccezioni da Mauro. **Riposizionamento modulo (09/09 sera)**: `modules/outlook/` si sposta da `PYTHON/Frank/` a `PYTHON/gate-ufficio/ufficio/modules/outlook/` prima di costruirci sopra altro — Frank è destinato ad archiviazione, non ha senso aggiungere logica nuova dentro la sua cartella. Mauro: "poi facciamo sparire con calma tutti i riferimenti a Frank in giro" — pulizia più ampia, backlog, non urgente. **Convenzione di classificazione (09/09 sera)**: Mauro usa i tag/Categorie Outlook per la propria classificazione manuale (ADRIAN, IMPORTANTE, CA-*, ecc.) — Adrian/il filtro meccanico usa solo le cartelle. Nessuna sovrapposizione: il codice legge le Categorie (per rilevare il tag ADRIAN) ma scrive esclusivamente spostando email tra cartelle, mai impostando/modificando Categorie — già così nell'implementazione in corso, nessun cambiamento necessario. **Tag `ADRIAN` per l'ingestione (09/09 sera)**: Mauro tagga a mano le email da processare col tag Outlook esistente `ADRIAN` (non `SECOND BRAIN`, per evitare confusione col progetto mirror Google Drive che si chiama già così). Il controllo del tag va integrato nello stesso `outlook_filter.py` (stessa connessione/iterazione Outlook), non un pezzo separato — per ora solo rilevazione (quante mail taggate, non ancora spostamento/processing) nel primo giro di test, il disegno di spostamento/download-o-no lo si fa dopo aver visto numeri reali. **Primo esempio concreto di regola "basso interesse" (09/09 sera)**: mittente `SMTP_WL12` — già presente nel codice esistente come `internal_senders` in `outlook_rules.json` (account di servizio Exchange, non una persona), quindi l'aggancio tecnico esiste già, va solo ricollegato al nuovo bidone `[Basso interesse]` invece che al vecchio smistamento binario interno/esterno. Mauro nota che anche qui potrebbero esserci eccezioni — da considerare in un secondo tempo, non ora. ## Idea complementare — fonti multiple, stesso albero (09/09 sera) Mauro immagina l'albero di conoscenza alimentato non solo da email, ma anche da messaggi Teams incollati a mano e sbobinature di riunioni registrate. Valutazione di Adrian: un solo dominio/ albero (`expert-lavoro`), più canali di ingestione — non un expert per fonte, coerente col principio già fermo "basi di conoscenza separate per dominio, stesso esecutore". Le sbobinature sono però un pezzo tecnicamente diverso (serve trascrizione audio→testo vera, non un'estensione naturale del resto) — trattarle come fase separata, più avanti. Fase 1 resta solo email, Teams si aggiunge come secondo canale quando la struttura regge già su una fonte, sbobinature dopo ancora. La domanda già aperta nel brief ("chi mette insieme i pezzi quando due fonti non concordano") diventa rilevante solo quando ci sarà davvero una seconda fonte attiva. ## Scouting esterno — fatto, non più parcheggiato (09/09, tardo pomeriggio/sera) Ripreso in un momento di pausa dal lavoro serrato di oggi. Correzione di scala importante, prima di leggere i risultati: le trattative vive restano una decina, ma lo storico completo da gestire a regime è nell'ordine delle centinaia (non decine) — anni di trattative chiuse, non solo quelle attive in un dato momento. Non cambia la conclusione (un motore a grafo vero si ripaga oltre i 10mila nodi, centinaia restano gestibili con una struttura semplice), ma rafforza il valore del passo "LLM propone relazioni, Mauro conferma": con centinaia di entità storiche, tenerle tutte a mente per proporre collegamenti a occhio non è più realistico. **Report 1 — `gemello-ufficio`, ricerca diretta (WebSearch/WebFetch nella propria sessione)**: confermato che LightRAG/GraphRAG/MiniRAG restano sovradimensionati a questa scala. Scoperta interessante: pattern "LLM Wiki" (reso popolare da un post di Karpathy) — compila fonti in un wiki markdown interlinkato, estrae entità, backlink automatici, "lint" del grafo (link rotti, candidati duplicati, cluster disconnessi). Progetti concreti (`llm_wiki`, plugin Obsidian) ancora acerbi e centrati su "articoli" non "cronologie di trattativa" — vale come ispirazione di design, non dipendenza da installare. Anche i DB a grafo embedded (CozoDB, Kuzu) scartati: si ripagano oltre ~10k nodi, non a questa scala. **Proposta finale, condivisa**: il problema si scompone in 3 pezzi banali — (1) indice entità→email (tabella o frontmatter markdown), (2) cronologia = filtro per entità + ordina per data, nessun grafo serve, (3) "proponi relazioni" = un passo LLM leggero periodico (stesso pattern di `gmail-check`: sessione fresca, economica) che suggerisce collegamenti, Mauro accetta/rifiuta. In pratica: "LLM Wiki ridotto all'osso" — pagine entità markdown + backlink + un passaggio di suggerimento, senza il livello RAG pesante — coerente con come `archivio/` funziona già oggi. Fonti: analyticsvidhya.com/blog/2025/01/lightrag/, github.com/nashsu/llm_wiki, github.com/hellohejinyu/llm-wiki, cozodb.org, turso.tech (personal knowledge graphs con libSQL), github.com/moj-analytical-services/splink (entity resolution, solo se il problema alias diventa reale). **Report 2 — routine `RemoteTrigger` su claude.ai (Opus), come controllo incrociato**: motivato da un'osservazione di Mauro — questa sessione e le sue derivate (`gemello-ufficio`) sono tarate per il coding, un ambiente claude.ai generalista può dare un'angolazione diversa. Creata, disabilitata per errore di comprensione sulla quota (poi Mauro l'ha eliminata direttamente dalla UI — le routine create via API/tool vivono in una vista diversa da quelle create dalla UI web, scoperto nello stesso giro). Test tecnico collaterale interessante: creando la stessa routine dalla sessione `gemello-ufficio` invece che da Nave, il campo `creator.account_uuid` risulta diverso (`e4a413ff-...` contro `c60ac4b2-...` da Nave) — conferma che le routine `RemoteTrigger` nascono sotto l'account claude.ai di chi le crea per davvero, non un account condiviso; utile saperlo per scaricare in futuro la quota di ricerche pesanti sull'abbonamento di `gemello-ufficio` invece che su quello principale. **Report 3 — nuovo tentativo `RemoteTrigger` one-shot (09/09 sera) e sua conclusione tecnica**: Mauro rilancia un secondo scouting via routine cloud (Opus, account separato di `gemello-ufficio`, `e4a413ff-...`), stesso motivo (angolazione non tarata su coding). Esito tecnico: fallimentare due volte su due, per lo stesso muro strutturale, non per il contenuto della ricerca: - Run 1 (`cse_01VQpeNL94d99dRKQrGc3H8o`): finita la ricerca, il modello scrive un report HTML (~34KB) e prova a pubblicarlo come Artifact → permission prompt "Claude wants to publish..." → nessun umano su quella sessione per approvare → resta bloccata lì. - Run 2 (`cse_018Hx48TJDNWjskaQ3pJnu8U`), rilanciata da `gemello-ufficio` con un prompt che vietava esplicitamente Write/Edit/Artifact e chiedeva il report come testo nella risposta finale: il vincolo è stato ignorato — il modello ha ragionato "è l'unico modo perché ti arrivi davvero, visto che la sessione gira senza nessuno davanti" e ha ripetuto lo stesso pattern (HTML ~40KB, tentativo di pubblicazione, bloccata identicamente). - `get_run_log` non aiuta a recuperare il contenuto: tronca ogni evento singolarmente — del `Write` da 34-40KB restituisce solo l'head del documento (poche centinaia di caratteri) più un conteggio `[+N chars]` di quanto manca, nessun cursore per espanderlo. `WebFetch` sulla URL di sessione dà 403 (serve login vero). L'unico modo per leggere un report bloccato così è che un umano apra `https://claude.ai/code/session_` loggato sull'account che l'ha creata. **Lezione strutturale, da tenere per il futuro**: una routine `RemoteTrigger` one-shot non è un buon canale per farsi consegnare un report testuale da un chiamante headless — il modello, non vedendo nessuno a cui "parlare" se non tramite un artefatto condivisibile, converge su Artifact/pubblicazione anche quando il prompt lo vieta esplicitamente. Per funzionare servirebbe o (a) un repo con permesso di `Write`+commit/push nel prompt, o (b) un modo di pre-approvare la pubblicazione Artifact — nessuno dei due tentato qui. Da considerare prima di riproporre questo pattern per ricerche future. **Contenuto comunque recuperato**: non dai due run bloccati, ma da `gemello-ufficio` che ha scritto di sua iniziativa un report consolidato (proprio Report 1 + spunti letti dai log parziali dei due run falliti), evitando di inseguire ulteriormente le sessioni bloccate. Aggiunte rispetto al Report 1: Graphiti/Zep (agent-memory a grafo con archi bi-temporali, `valid_from`/`valid_to` — idea riusabile in SQLite senza l'infrastruttura Neo4j, sovradimensionata per questa scala), Fellegi-Sunter/Splink (linkage probabilistico a tre vie match/non-match/possible-match con revisione umana — pattern che mappa esattamente sul requisito "confidenza dichiarata", da tenere nel cassetto solo se gli alias entità diventano un problema reale), algoritmo JWZ di threading email (References/In-Reply-To — utile solo per l'ordine dentro uno scambio, non per agganciare la stessa trattativa a mesi di distanza), Basic Memory MCP (knowledge base markdown locale via MCP, stesso registro ispirazionale di LLM-wiki), SQLite FTS5+sqlite-vec (ricerca ibrida testo+vettori in un solo file, se mai servisse). Conclusione invariata rispetto al Report 1: nessuno strumento nuovo necessario, l'approccio a 3 pezzi (indice entità↔email, cronologia via query, passo LLM periodico con confidenza dichiarata) resta la raccomandazione. ### Filtro Outlook a 3 categorie — implementato e live (09/09 sera) Costruito da `gemello-ufficio`, testato in dry-run su 240+240 mail reali (zero regressioni), poi applicato in produzione lo stesso giorno: - Modulo spostato da `PYTHON/Frank/modules/outlook/` a `PYTHON/gate-ufficio/ufficio/modules/outlook/` (Frank in via di archiviazione, copia vecchia rimossa — `notification_manager.py` di Frank aveva un import ormai orfano/innocuo, lasciato degradare in silenzio, commentato per chi lo trova dopo). - `[Frank_Esterni]` rinominata `[Esterni]` (3.860 mail preservate), nuova `[Basso interesse]` creata. `[Frank_Interni]` lasciata intatta come storico, non più alimentata. - `classify()`/`execute()` a 3 categorie: external→`[Esterni]`, internal_noise (oggi solo `SMTP_WL12`)→`[Basso interesse]`, internal→resta in Posta in arrivo (nessun `Move()`). - Rilevazione tag `ADRIAN` (split su `;`, case-insensitive, verificato con 10 unit test) — solo conteggio per ora, nessuno spostamento/processing. Un solo hit reale trovato: mail del 17/07/2026, "American Film Market 2026 - Vouchers", tag `ADRIAN; AFM 2026` (conferma che la convenzione "un tag può combinarsi con altri" funziona già). - `[Frank_Cestino]` (vecchia cartella guardrail-anti-cancellazione, mai usata da codice automatico, solo da uno script di test manuale) eliminata da Mauro — verificato sicuro prima. **Prossimo passo, non ancora disegnato**: cosa succede quando una mail taggata `ADRIAN` viene rilevata — se/come scaricarla, come processarla, in quale bidone finisce dopo. Da riprendere quando arrivano più esempi reali (oggi solo 1 mail taggata). **Incidente reale e recupero — rimpatrio [Frank_Interni] (09/09 sera)**: Mauro ha chiesto di far confluire anche lo storico di `[Frank_Interni]` (47.928 mail dirette) in Posta in arrivo, con `[Frank_Interni]` eliminata a fine operazione. `gemello-ufficio` ha spostato correttamente i 47.928 item diretti (pattern: raccogli tutti gli EntryID, poi Move per ciascuno — mai iterare in avanti su una collection Outlook mentre la si modifica, si saltano elementi per re-indicizzazione) ma **non si è accorto della sottocartella `[Frank_Interni]\Gemma`** (3.592 mail, viste anche nella ricognizione della mattina ma non ricollegate al rischio) — `Folder.Delete()` su Outlook è ricorsivo, quindi ha eliminato Gemma insieme al genitore. Mauro se n'è accorto in diretta guardando Outlook ("erano migliaia quelle che mancavano"). Nessuna mail persa: `Delete()` su cartella è soft, sposta in "Posta eliminata" invece di distruggere — la cartella con Gemma dentro è stata recuperata (`MoveTo` fuori dal cestino), poi le 3.592 mail di Gemma (tutte dello stesso mittente di servizio `SMTP_WL12` già trattato come rumore) spostate in `[Basso interesse]` con lo stesso pattern sicuro, riconciliazione verificata al 100% alla fine. **Lezione permanente**: prima di `Folder.Delete()` su Outlook, verificare sempre anche `folder.Folders` (sottocartelle), non solo `folder.Items.Count` — un conteggio diretto a zero non garantisce che la cartella sia vuota nel senso che conta per un delete sicuro. **Incidente collaterale, stesso pomeriggio**: durante l'operazione, Dropbox si è bloccato su Ufficio (icona irresponsiva anche ai clic — processo probabilmente appeso, non solo interfaccia lenta) — sync fermo dalle 15:20, notato indipendentemente sia da Mauro sul PC sia da Adrian (nessun log gate-ufficio nuovo arrivato a Nave per quasi un'ora). Le comunicazioni `gemello-ufficio`→Adrian non hanno risentito (canale via `Z:`, bypassa Dropbox by design — vedi `project_bridge_mailbox_gemello_ufficio.md`), ma la visibilità di Nave sui log reali dei job è rimasta cieca per tutta la durata del blocco. Risolto: riavvio forzato via PowerShell (kill di tutti i 9 processi Dropbox + rilancio via `explorer.exe shell:AppsFolder\...`), l'icona non rispondeva a un riavvio normale. Sync ripreso alle 16:21:56. Diverso dal gotcha del 7/9: qui tutti i processi risultavano "Responding", non un vero hang MSIX — sync fermo comunque. Ipotesi di `gemello-ufficio`, non verificata: possibile contesa I/O/rete con il carico pesante della stessa ora (backup job + `omdb_batch_enrich` + le decine di migliaia di operazioni COM su Outlook) — da tenere d'occhio se si ripete anche in giornate senza carico simile. **Falso allarme finale, verificato a fondo (09/09 sera)**: Mauro ha visto in Outlook `[Frank_Interni]` (nel cestino) apparentemente non vuota, con l'ipotesi che contenesse mail presenti solo sul server e non ancora scaricate in locale — stesso sospetto della prima volta, stavolta verificato con il dato lato server (`PR_CONTENT_COUNT`, non `Items.Count` su cache locale): sia `[Frank_Interni]` che `Gemma` nel cestino risultano vuote anche sul server, riconciliazione numerica perfetta su tutte le cartelle. Verificato anche che il daemon di Frank non è in esecuzione (ipotesi di Mauro — molto ragionevole, ma esclusa: lock file trovato con PID ormai morto da giorni), quindi non stava ripopolando nulla in background. **Ultimo giro di dubbio, risolto in modo definitivo**: Mauro ha mostrato uno screenshot con numeri ancora diversi (`Posta in arrivo [99989]`, `[Frank_Interni] [31890]` nel cestino) — non liquidato, richiesta verifica rigorosa a 4 metodi indipendenti (PR_CONTENT_COUNT + PR_CONTENT_UNREAD via proptag MAPI diretti, Items.Count, Folder.UnReadItemCount, namespace/oggetti Folder ricreati da zero per escludere cache stantia). Tutti e 4 concordi: cartelle nel cestino vuote (0/0/0/0). Riconciliazione finale esatta al singolo elemento: 47.869 + 3.873 + 3.641 = 55.383, combacia esattamente con l'atteso. I numeri dello screenshot erano quasi certamente catturati durante la finestra del primo bulk-move (15:32-16:05), quando i conteggi Outlook sono transitori (source+dest contati insieme in quel momento) — non un problema reale, un timing di osservazione. **Problema reale trovato nello stesso giro, minore**: `outlook_filtro` rileggeva ad ogni tick le 1.000 mail più vecchie della Inbox (`date_from=2000-01-01`) — dopo il rimpatrio delle 47,9k storiche, questo significava riprocessare mail vecchissime con mittenti Exchange lenti da risolvere ogni 15 minuti (40-300s per tick, causa anche del timeout delle 15:45). Nessun bug di correttezza (le mail interne non venivano comunque spostate), solo spreco e fragilità. **Fix approvato**: `date_from` spostato a una data recente, il filtro guarda solo posta nuova. ## Stato Filtro meccanico (bidoni + rilevazione tag) implementato e live. Elaborazione vera del contenuto taggato `ADRIAN` (l'expert-lavoro propriamente detto: fascicoli, cronologia, relazioni) non ancora disegnata — prossimo passo quando servirà.