ADR 008: Invariante Strutturale Bilingue — Il Symmetry Guardrail
Stato: Attivo Decisore: Architecture Lead Data: 2026-04-20 (sprint v0.7.0, D045 — Migrazione Diátaxis)
Contesto
Zenzic.dev è un sito di documentazione bilingue. L'inglese (docs/) è la fonte
autorevole; l'italiano (i18n/it/docusaurus-plugin-content-docs/current/) è lo
specchio di traduzione. Il language switcher di Docusaurus risolve le pagine
italiane specchiando il percorso del filesystem inglese: un utente su
/docs/reference/finding-codes passa a /it/docs/reference/finding-codes — e
Docusaurus serve il file al percorso corrispondente nell'albero i18n/it/.
Durante la migrazione Diátaxis v0.7.0 (D045), 29 file inglesi sono stati rinominati e spostati per allinearsi alla struttura a quattro quadranti. Diversi file italiani non sono stati spostati atomicamente nello stesso commit. Il risultato: il language switcher produceva errori 404 sulle pagine dove il file inglese era stato spostato ma lo specchio italiano no.
Questa classe di bug è particolarmente insidiosa perché:
-
Non viene prodotto alcun errore in fase di build.
onBrokenLinks: 'throw'rileva solo i riferimenti
[testo](link)interni — non valida i percorsi del language switcher. -
Il bug è invisibile in modalità sviluppo.
npm run startserve un sololocale. Il switcher è inattivo. Il 404 appare solo nell'output di
just buildquando entrambi i locale vengono compilati simultaneamente. -
La finestra di rilevamento è lunga. Un file IT mancante scoperto tre commit
dopo il rename EN richiede un
git blameforense per risalire — l'accoppiamento tra i due spostamenti non è più visibile nella storia.
Decisione
Ogni modifica strutturale a
docs/deve essere applicata atomicamente ini18n/it/docusaurus-plugin-content-docs/current/nello stesso commit.
Questa non è una raccomandazione — è un invariante rigido. Tre regole specifiche ne derivano:
Regola 1 — Spostamenti Atomici
Qualsiasi git mv applicato a un file in docs/ deve essere accompagnato da un
corrispondente git mv nello specchio italiano nello stesso commit. Una
rinomina in inglese è una rinomina in italiano.
# Corretto — entrambi i movimenti in un commit
git mv docs/guides/intro.mdx docs/tutorials/intro.mdx
git mv i18n/it/docusaurus-plugin-content-docs/current/guides/intro.mdx \
i18n/it/docusaurus-plugin-content-docs/current/tutorials/intro.mdx
git commit -m "refactor(docs): sposta intro nel quadrante tutorials (EN + IT)"
Regola 2 — Parità degli Slug
Se un valore slug: viene modificato in un file inglese, deve essere modificato
identicamente nel file italiano corrispondente. Uno slug: divergente causa un
404 nel language switcher, senza alcun avviso in fase di build.
Regola 3 — Validazione della Simmetria Prima di Ogni Commit
Prima di fare commit di qualsiasi modifica che tocchi la struttura del filesystem (rinomina, aggiunta, eliminazione), il seguente comando deve uscire con 0:
diff \
<(find docs -name "*.mdx" | sed 's|^docs/||' | sort) \
<(find i18n/it/docusaurus-plugin-content-docs/current \
-name "*.mdx" | \
sed 's|^i18n/it/docusaurus-plugin-content-docs/current/||' | sort)
Qualsiasi output di questo comando rappresenta un'asimmetria strutturale che produrrà un 404 nel language switcher italiano.
Motivazione
1. L'Italiano è un Cittadino di Prima Classe
La documentazione italiana non è un asset secondario o un "nice to have". È parte del contratto del Safe Harbor. Un link che funziona in inglese ma dà 404 in italiano è un fallimento strutturale del sistema documentale — equivalente a un link interno rotto nell'albero inglese.
2. Il Language Switcher Non Ha Reti di Sicurezza
Il onBrokenLinks: 'throw' di Docusaurus non copre i percorsi del language
switcher. Questo significa che l'unica salvaguardia è la disciplina del
contributore imposta da questo ADR. Non c'è nessun backstop in fase di build.
3. Coerenza della Storia Git
Un commit atomico che sposta sia i file EN che IT crea un'unità di storia
coerente: la rinomina è una singola operazione reversibile. I commit separati
creano rumore nella storia e rendono bisect inaffidabile quando si indagano
regressioni.
Invarianti (Non Negoziabili)
-
Il comando
diffdi simmetria deve uscire con 0 prima di qualsiasi commit chemodifica la struttura del filesystem di
docs/oi18n/it/. -
I nuovi file aggiunti a
docs/devono avere un corrispondente stub aggiunto ai18n/it/nello stesso commit — anche se il contenuto italiano è una copia dell'inglese fino a quando non viene fornita una traduzione. -
L'hook pre-commit (
pre-commit-config.yaml) impone la simmetria al gate.Aggirarlo con
--no-verifysu un commit strutturale è una violazione di Classe 1 (Technical Debt).
Conseguenze
-
Ogni contributore che rinomina o sposta un file di documentazione deve essere
consapevole dello specchio italiano — questa è una parte non opzionale del workflow di contribuzione documentato in
CONTRIBUTING.md. -
La recipe
just preflight(uvx pre-commit run --all-files) applica questocontrollo in CI. Una PR che rompe la simmetria strutturale fallirà al gate.
-
L'invariante di simmetria si applica solo alla struttura delle directory. Il
contenuto italiano può essere in ritardo rispetto all'inglese durante sprint attivi, purché il file sia presente (anche come stub). Un 404 è peggio di una traduzione obsoleta.