|
| 1 | +id: ADR-P41 |
| 2 | +title: "P41 — Versione inglese del servizio: la lingua è resa, mai un fatto attestato" |
| 3 | +date: 2026-07-24 |
| 4 | +status: accepted |
| 5 | +context: > |
| 6 | + Il servizio è nato interamente in italiano, ma i suoi canali programmabili |
| 7 | + (pacchetto npm, MCP Registry, GitHub Action, repository pubblici) sono per |
| 8 | + natura internazionali: chi arriva da lì incontrava documentazione, pagine |
| 9 | + pubbliche e certificati in una lingua che spesso non legge. Rendere il |
| 10 | + servizio bilingue tocca però superfici molto diverse per rischio — pagine |
| 11 | + statiche, pagine generate dal Worker, messaggi d'errore dell'API e, la più |
| 12 | + delicata, il contenuto del certificato PDF, cioè l'artefatto probatorio. |
| 13 | +decision: > |
| 14 | + Scopo **MVP** deliberato: il sito resta italiano, con un percorso inglese |
| 15 | + **completo** per chi arriva dal canale programmabile — sei pagine (home, |
| 16 | + fasce e condizioni, pagina sviluppatori e le sue due sottopagine chiave API |
| 17 | + e CLI, informativa privacy) duplicate sotto `/en/`, più le due pagine HTML |
| 18 | + servite dal Worker (`/c/<sha256>`, `/agent/authorize`) e i messaggi d'errore |
| 19 | + di `/api/hash` e `/api/cert-pdf` via campo facoltativo `lang` (fallback |
| 20 | + `Accept-Language`). Restano fuori le pagine che riguardano chi è già dentro |
| 21 | + (profilo, stato, sicurezza, vetrina, changelog) e lo storico: si estendono |
| 22 | + una pagina per volta, sulla stessa infrastruttura. |
| 23 | +
|
| 24 | + **L'invariante che regge tutto il piano: `lang` non entra mai in |
| 25 | + `hmacMessage`.** Il messaggio firmato resta l'attestazione più gli eventuali |
| 26 | + metadati dichiarati in forma canonica, identico a prima di P41. La lingua è |
| 27 | + una scelta di **resa**, non un fatto sull'opera: legarla alla firma |
| 28 | + invaliderebbe in un colpo solo la verifica di tutti i certificati già |
| 29 | + emessi, senza aggiungere alcuna garanzia. Verificato in modo diretto, non |
| 30 | + assunto: la stessa coppia attestazione+HMAC produce il certificato in |
| 31 | + entrambe le lingue, `/api/verify` (che non ha né deve avere un parametro |
| 32 | + `lang`) risponde `hmac_valido: true` in entrambi i casi, e un certificato |
| 33 | + pre-P41 resta verificabile senza eccezioni. |
| 34 | +
|
| 35 | + Due scelte di trasparenza, non di comodità. **(1)** L'informativa privacy |
| 36 | + inglese è dichiarata in testa alla pagina come **traduzione di cortesia**, |
| 37 | + con la versione italiana che fa fede: chi arriva dal canale inglese incontra |
| 38 | + il flusso OAuth self-service, e servirgli l'informativa solo in italiano era |
| 39 | + una debolezza reale rispetto all'art. 12 GDPR — ma tradurre un testo con |
| 40 | + effetti giuridici senza revisione legale non lo rende ufficiale, e dirlo è |
| 41 | + più onesto che lasciarlo intendere. **(2)** Nessun rilevamento automatico |
| 42 | + della lingua e nessun reindirizzamento: solo un selettore visibile. La |
| 43 | + lingua la sceglie chi legge. |
| 44 | +
|
| 45 | + Contro il rischio di divergenza fra le due versioni — la lezione delle |
| 46 | + pagine parallele che il progetto ha già pagato una volta — una guardia di |
| 47 | + CI obbligatoria: un registro delle coppie con l'impronta SHA-256 del file |
| 48 | + italiano al momento della traduzione, e un workflow che fallisce se |
| 49 | + l'italiano cambia senza che l'inglese sia stato aggiornato. Nessuno step di |
| 50 | + build: le pagine EN sono file statici, come le italiane. |
| 51 | +
|
| 52 | + Corollari di perimetro accettati per l'MVP: le etichette AcroForm del |
| 53 | + template PDF restano italiane anche nel certificato inglese (sono grafica |
| 54 | + del template: tradurle significherebbe un secondo template da mantenere e |
| 55 | + riverificare nelle coordinate), quindi il certificato EN è misto; il QR e |
| 56 | + l'URL di verifica stampati nel PDF restano invariati per lingua e puntano |
| 57 | + alla stessa pagina canonica, che si apre nella lingua chiesta da chi la |
| 58 | + visita, non da chi ha emesso. |
| 59 | +consequences: > |
| 60 | + Il contratto API cambia in modo **puramente additivo**: senza il campo |
| 61 | + `lang` ogni risposta, ogni pagina e ogni PDF restano bit-identici a prima — |
| 62 | + criterio di accettazione verificato, non dichiarato. Nessun endpoint nuovo, |
| 63 | + nessun dato nuovo, nessun trattamento nuovo: l'informativa è stata |
| 64 | + **tradotta**, non estesa, e nessuna nuova categoria di interessati compare. |
| 65 | + Per questo P41 non introduce alcun rischio né alcun controllo nuovo nel |
| 66 | + registro: la lingua non cambia il modello di minaccia, e l'unica superficie |
| 67 | + sensibile — il messaggio firmato — è esplicitamente fuori dal suo raggio. |
| 68 | +
|
| 69 | + Rilasciato in due tempi per una ragione strutturale, non per una svista: il |
| 70 | + sito statico non ha un gate di produzione separato (pubblica al push), il |
| 71 | + Worker sì (approvazione umana). Le pagine inglesi sono quindi andate live |
| 72 | + prima del motore bilingue; nessuna dipendenza fra le due parti, verificato |
| 73 | + prima di procedere. Il deploy del Worker (imgauth 1.33.0) è passato dalla |
| 74 | + pipeline con gate approvato dal gestore, come ogni rilascio di produzione. |
| 75 | +
|
| 76 | + Il criterio per decidere se estendere lo scopo — altre pagine, altre lingue |
| 77 | + — è misurabile e già fissato: il traffico reale sulle pagine `/en/` nelle |
| 78 | + settimane successive. Se non si materializza, l'estensione non si fa. |
| 79 | +visibility: public |
0 commit comments