# Travel Run — Manuale operativo verificato

Solo procedure con status VERIFIED possono essere inserite nelle istruzioni del futuro runner.

## TR-002 — Dashboard Travel Run in HTTP 403

**Problema:** Il virtual host Nginx di travel-run restituiva 403 Forbidden pur con configurazione valida.

**Causa confermata:** Il file index.html era distribuito con permessi 0600 e non era leggibile dal worker Nginx.

**Soluzione:** Impostare permessi di lettura 0644 sugli asset pubblici e mantenere la directory accessibile (0755); non esporre registri interni sensibili.

**Verifica:** Richiesta HTTPS alla origin con host travel-run.mclmedia.eu restituisce HTTP 200.

**Regola runner:** Per dashboard statiche controllare separatamente permessi directory e file; un 403 da Nginx non significa automaticamente problema DNS o TLS.

## TR-004 — Timeout non valido per MCL MCP run_command

**Problema:** La lettura di tre pagine con run_command è stata rifiutata prima dell’esecuzione con INVALID_ARGUMENT e messaggio: il timeout deve essere tra 1 e 25 secondi. Il valore richiesto era 35.

**Causa confermata:** Parametro timeout fuori dall’intervallo ammesso dallo schema del tool (1–25 secondi).

**Soluzione:** Usare timeout compresi tra 1 e 25 secondi, suddividendo letture o comandi lunghi in passaggi circoscritti e idempotenti.

**Verifica:** Rilanciata la stessa lettura con timeout=25: comando eseguito, tre snapshot CMS letti correttamente.

**Regola runner:** Per MCL MCP 2026 run_command usare timeout tra 1 e 25 secondi. Se la richiesta richiede più tempo, dividerla; non inviare 30/35/60 secondi.

## TR-005 — Errore di sintassi negli script di revisione in lotto

**Problema:** Il primo script per la revisione di più siti non partiva: SyntaxError: unterminated string literal su un blocco HTML che conteneva un apostrofo.

**Causa confermata:** Una stringa Python delimitata da apici singoli incorporava un apostrofo non escapato nel testo HTML italiano.

**Soluzione:** Per lunghi blocchi HTML usare stringhe multilinea triple e compilare lo script con python3 -m py_compile prima di eseguire qualunque step mutativo. Usare preflight per ogni sito e interrompere il singolo ramo se lo script non è valido.

**Verifica:** Script corretto e compilato; successivamente due dry-run validi, due apply riusciti e due QA live HTTP 200 con contenuto aggiornato.

**Regola runner:** Prima di eseguire un batch generato, validare sintassi del file e schema dei payload; in caso di SyntaxError non procedere alla fase write. Correggere e rieseguire la validazione; mai dare per eseguite operazioni non partite.

## TR-007 — Marcatore eventi rimosso durante la riscrittura HTML

**Problema:** La prima bozza Alberobello ha fallito un assert preflight: mancava il commento HTML <!-- eventi:fine --> dopo la sostituzione di una sezione.

**Causa confermata:** La modifica per intervallo ha rimpiazzato anche il marker che delimitava la sezione eventi nel body originale.

**Soluzione:** Preflight riutilizzabile in /srv/mcl-workspace/travel_run_preflight.py: verifica hash originale, singolo marker e singolo H2 Calendario in breve, nessun H1, preservazione link e widget; blocco automatico se una condizione fallisce. Richiede inoltre controllo live prima di qualsiasi scrittura.

**Verifica:** Test sul caso Alberobello: originale valido accettato e cinque modifiche intenzionalmente difettose respinte (marker mancante, duplicato, calendario mancante, link e widget rimossi).

**Regola runner:** Ogni revisione body passa un preflight non mutativo: marker_count == 1, calendar_count == 1, href interni originali conservati, widget/contenuti protetti preservati; se fallisce, stop prima del deploy.

