--- name: schedulatore-job-status description: "Stato attuale di gate-ufficio — job ricorrenti e backup del PC ufficio, chi gira dove, retention, salute. Specchio di schedule.json + frank.db, non narrativa: la storia (tunnel dismantellato, migrazione da Frank) vive solo nei log commit git." metadata: type: reference --- # gate-ufficio — stato attuale Esecutore muto che sostituisce Frank sul PC ufficio, comandato indirettamente da Nave/Adrian tramite commit su `PYTHON/gate-ufficio/` (repo git dedicato). Nessuna intelligenza/decisione lato ufficio — legge `nave/schedule.json`, esegue, scrive un log. `scheduler_locale.py` (un solo processo, gira solo su Ufficio) più `run_job.py` (ogni job come processo OS a sé). Dettaglio tecnico completo: `PYTHON/gate-ufficio/CLAUDE.md`. Questo file è solo lo stato — cosa gira, quando, con quale retention — aggiornato leggendo `schedule.json`/`frank.db` direttamente, non a memoria. ## Job ricorrenti **6 di 6 migrati da Frank** — Frank stesso non ancora decommissionato (righe in `frank.db` inerti, non disattivate). - `backup`: ogni 2h — restic, vedi sezione Backup sotto. - `check_doppi_gemma`: lun-ven 11:30, timeout 3600s — in produzione da settimane. - `check_prodotti_acquistati`: mer 12:30, timeout 3600s — in produzione da settimane. - `gemma_report`: mer 11:00, timeout 300s — migrato 04/09, primo run reale mercoledì prossimo. - `osservatorio_report`: mer 11:15, timeout 300s — migrato 04/09, primo run reale mercoledì prossimo. - `outlook_filtro`: ogni 15 min, timeout 300s — migrato 04/09, confermato stabile (più run reali positivi lo stesso giorno). - `imdb_update`: gio 14:00, timeout 36000s (10h) — migrato 04/09, un primo run reale fallito per una contaminazione ambientale della sessione che ha avviato lo scheduler (`NoDefaultCurrentDirectoryInExePath`, vedi `gemello-nave/archivio/conoscenza-nave.md`), corretto con fix difensivo su tutti i `.bat`; non ancora riverificato con un secondo run. - `omdb_batch_enrich`: lun-ven 13:30, timeout **21600s (6h)** — migrato 04/09, stesso schema originale di `frank.db` (job id 19). Sbloccato solo dopo un fix in `MyICR_Suite` (`mark_omdb_not_found` non aggiornava `scaricato_il` su stub esistenti, sprecava quota OMDB indefinitamente — corretto 04/09, commit `b65261d`). **Primo run reale (04/09, venerdì)**: timeout originale di 7200s (2h) troppo corto — ritmo osservato ~6.6s/record (rate-limit OMDB, `delay=5.0s`), 2000 record di Fase 1 richiedono da soli ~3h40min, oltre il vecchio limite. Nessun danno (commit per-record, i non processati tornano in coda al run successivo) ma il job non arrivava mai a completarsi in una finestra da 2h. Timeout portato a 21600s (6h, commit `71d2f79`) da `gemello-ufficio`: 3h40 stimate per Fase 1 + margine prudente di 2h20 per la Fase 2 (refresh poster, durata ancora senza dati reali). Vale dal prossimo run di lunedì. **Esito reale del primo run (04/09)**: non ucciso dal timeout — **crashato** dopo 81min (exit_code=1) con `sqlite3.OperationalError: database is locked` dentro `mark_omdb_not_found` (record 729/2000), causa probabile contesa di rete su `mediatrack.db` (`database_logic.py` apre/ chiude una connessione per ogni chiamata helper, nessun retry sul lock). Nessuna perdita dati (commit per-record). **Stato complessivo arricchimento OMDB su tutto l'archivio**: 14.004/23.890 prodotti eleggibili arricchiti (**58,6%**), 9.172 ancora in coda. Fix del lock **in coda, non prioritario** (deciso con Mauro 04/09) — dettaglio/proposta: `archivio/Adrian/progetti/ project_expert_myicr.md`. Anche il fix alla soglia di errore troppo permissiva del job (commit `6842ed9`, stesso giorno) non è mai stato raggiunto dal crash — da verificare al prossimo run utile. - `archivio_raw_conversazioni`: ogni giorno alle 11:00, timeout 300s — aggiunto 07/09 (non una migrazione da Frank, job nuovo: copia meccanica dei trascritti `.jsonl` di Claude Code verso il ponte Dropbox `claude-raw-archive/`, dettaglio `archivio/Adrian/progetti/ project_archivio_raw_conversazioni.md`). - `check_dropbox_health`: ogni 15 min, timeout 60s — watchdog Dropbox MSIX (kill+rilancio su "Not Responding"), **esteso 07/09** con un secondo controllo indipendente dal primo: scarto di dimensione locale-vs-`Z:` (WebDAV verso Nave) sul file `mailbox.log` come canary, soglia 20 min prima di segnalare "sync fermo" e tentare comunque il ciclo di recovery — colma il gap reale scoperto in un incidente quella sera (sync Dropbox fermo 40+ minuti, `Responding=True` per tutto il tempo, nessun alert). Dettaglio completo dell'incidente e della scelta di design: `archivio/Adrian/progetti/project_bridge_mailbox_gemello_ufficio.md`. Testato il percorso "sano" in produzione (`run_job.py` diretto, exit_code=0); il percorso "sync fermo" verificato solo a livello di codice, non ancora osservato dal vivo. Nota: `ReportPdf` esiste in `frank.db` ma disabilitato a livello di job (non solo di schedule) — diagnosticato morto, non migrato, non fa parte di questo elenco. ## Backup **In produzione dal 03/09, primo giro completo confermato.** - Scope: `I:\lavori`, `I:\SOFTWARE`, `I:\Budget`, `W:\GemmaLoader`, `X:\MonitorOsservatorio` — quote di rete Mediaset, non coperte da Dropbox. Stesso scope del vecchio profilo Frank. - Motore: `restic` (repository `D:\backups\restic-repo`, password in `secrets/restic_password`, mai hardcoded) — versionato con retention, non un mirror semplice, per poter tornare a una data specifica anche in caso di errore umano/cancellazione, non solo guasto disco. - Retention: `keep 7 daily, 4 weekly, 12 monthly` — stessa policy del backup Nave, non i 30gg fissi del vecchio profilo Frank. - `X:\MonitorOsservatorio` risulta intermittente (drive di rete mappato che va in idle-disconnect periodico su questa macchina) — tollerato dalla convenzione `exit_code=3`=OK, tentativo di fix a path UNC diretto scartato il 04/09 dopo verifica (peggiorava la situazione, non migliorava — la lettera mappata si è dimostrata più affidabile del path diretto in quel momento). - Salute: `PYTHON/gate-ufficio/nave/check_job_health.py` (cron Nave 05:50) legge il log più recente per ciascun job in `schedule.json`, segnala se manca oltre la tolleranza attesa (`backup`: 3gg fissi; altri job: prossima occorrenza cron attesa + 6h) — nessun accesso diretto a Ufficio, legge solo i log sincronizzati via Dropbox. In tempo reale invece: `servizio-gate-watch` (meccanico, zero LLM, sostituisce dal 04/09 la vecchia `sentinella-gate-ufficio` — fa girare `monitor_executions.py`, un fallimento lancia una slave one-shot che spiega la causa via `SendMessage`, solo se una sessione Adrian è viva in quel momento, nessun fallback). - **Aperto**: seconda copia offsite via Dropbox — idea aperta, non implementata. Il repository restic è già cifrato di suo (password del repository), non serve un altro strato se si sincronizza il repository intero. Non ancora deciso: intero repository (oggi ~13.5GB) o solo un export più leggero; dove dentro `Dropbox\adrian\` (cartella dedicata esclusa da git); cadenza (probabilmente settimanale, non ogni 2h). ## Decommissioning Frank **Non ancora fatto.** Tutti i 6 job sono su `gate-ufficio`, ma `frank.db` non è stato toccato — le righe restano tecnicamente `enabled=1`, solo inerti perché il daemon Frank stesso non gira più. Da fare quando tutti i job avranno avuto almeno un ciclo reale confermato: disattivare le righe in `frank.db`, poi decidere con Mauro se archiviare o cancellare `PYTHON/Frank/`.