#!/usr/bin/env python3 """servizio-inbox-watch — sorveglianza meccanica di inbox-documenti/, nessun LLM. Sostituisce la vecchia sentinella persistente `sentinella-inbox-documenti` (04/09/2026): qui il trigger (accorgersi di un file nuovo) e' un demone Python puro, non una sessione Claude Code sempre accesa. Per ogni file nuovo lancia una slave one-shot (scripts/avvia_slave.sh) che applica PROTOCOLLO.md a quel solo file e poi muore — nessuna sessione che accumula contesto all'infinito. Vedi memory/MEMORY.md, thread token consumo istanze secondarie, per la diagnosi che ha motivato il cambio. Girato come servizio systemd (vedi servizio-inbox-watch.service), Restart=on-failure. """ import subprocess import time from datetime import datetime, timezone from pathlib import Path ROOT = Path("/mnt/ssd/data/Dropbox/adrian") INBOX = ROOT / "inbox-documenti" LOG = Path(__file__).parent / "watch.log" EXCLUDE = {".gitkeep", "README.md"} POLL_SECONDS = 30 def log(msg: str) -> None: line = f"{datetime.now(timezone.utc).isoformat()} {msg}" print(line, flush=True) with open(LOG, "a") as f: f.write(line + "\n") def list_files() -> set[str]: if not INBOX.exists(): return set() return {p.name for p in INBOX.iterdir() if p.name not in EXCLUDE} def process(name: str) -> None: path = INBOX / name task = ( f"Nuovo file arrivato in inbox-documenti/: {path}. " "Applica il protocollo di archiviazione descritto in " "gemello-nave/inbox-watch/PROTOCOLLO.md a questo singolo file, " "poi termina — non restare in attesa, non processare altri file." ) log(f"nuovo file rilevato: {name} — lancio slave") result = subprocess.run( ["bash", str(ROOT / "scripts" / "avvia_slave.sh"), task], cwd=str(ROOT), capture_output=True, text=True, ) if result.returncode != 0: log(f"slave per {name} terminata con errore (exit {result.returncode}): {result.stderr[:500]}") else: log(f"slave per {name} completata") def main() -> None: # Baseline = stato gia' presente in inbox-documenti/ all'avvio del servizio — mai # trattare il backlog gia' presente come "nuovo" (stesso bug gia' noto e gia' corretto # nella vecchia sentinella, 29/08/2026). prev = list_files() log(f"avvio, baseline: {sorted(prev) or '(vuota)'}") while True: time.sleep(POLL_SECONDS) cur = list_files() for name in sorted(cur - prev): process(name) prev = cur if __name__ == "__main__": main()