ADR 0216 — Quatro idiomas, com pt-BR como FONTE e padrão: a documentação e a interface em português, inglês, russo e chinês simplificado
Status
Accepted. 2026-10-15 (AT-545, épico EP-032; decisões do dono de 15/10).
O dono pediu a documentação (site e README) e a interface em quatro idiomas —
português do Brasil (PADRÃO), inglês, russo e mandarim (chinês simplificado) —,
em FASES, e respondeu as quatro perguntas abertas deste ADR (ver a Decisão,
itens 4, 9 e 10). Modelo de README e de localização medida: o repositório
storytold/photocraft (README.md, docs/localization.md,
docs/localization-parity.md).
Tema: docs. Reverte o inglês como padrão da interface, que veio da fundação
de i18n (RN-432) sem ADR, e o defaultLocale: 'en' do site. Nenhum ADR aceito
é editado: a RN-432 ganha revisão por RN nova no PR da interface.
Context
Medido em origin/dev (f0a355fe5a):
- O site declara
defaultLocale: 'en'elocales: ['en', 'pt-BR'](website/docusaurus.config.ts:109-116), edocs/é a árvore do locale padrão. Mas, dos 261 arquivos dedocs/(5,7 M caracteres), 92 estão em pt-BR no corpo — as RNs (business-rules.md, 1,58 M, ebusiness-rules/autenticacao.md), os ADRs desde a 0127 e o histórico de fases —, cerca de 2,7 M caracteres. O site "en" serve esse texto em português. A casca do site (barra lateral, navbar, rodapé) também está em pt-BR, sem arquivo de tradução nenhum. - As traduções em
website/i18n/pt-BR/cobrem 135 das 261 páginas, e 97 delas têm a fonte alterada depois do último commit da tradução. Nada diz isso ao leitor nem ao autor do PR: a regratraducao-pt-brdo docmap éwarne não mede nada. - Dos 100 ADRs com cópia pt-BR, 66 são, byte a byte, o texto do commit que
criou o ADR: os ADRs 0001–~0103 foram escritos em português, e o que está
em
docs/adr/é a tradução para o inglês. - A interface tem
encomo padrão só no web (apps/web/src/lib/idioma.ts:38,i18n.ts:52); a api já gravapt-BRcomo padrão deusers.locale(apps/api/src/db/schema/iam.ts:87). São 2.310 textos em 27 namespaces, cerca de 90 mil caracteres por idioma. - O idioma das RESPOSTAS dos agentes já é lista aberta de BCP-47 (ADR 0177, RN-618/622) e não depende do idioma da interface.
- O tema do Docusaurus traz traduções de
pt-BR,ruezh-Hans(@docusaurus/theme-translations@3.10.2);zh-CNnão existe lá. A busca local (@easyops-cn/docusaurus-search-local) segmenta chinês com jieba e indexa russo porlunr-languages.
Decision
- pt-BR é a FONTE e o padrão, nos dois produtos. No site,
docs/passa a ser a árvore pt-BR (defaultLocale: 'pt-BR'), een,ruezh-Hansmoram emwebsite/i18n/<locale>/. A alternativa — manter o inglês como fonte e só abrir o site em pt-BR porlocaleConfigs.<locale>.baseUrl— é possível no Docusaurus 3.10 e foi recusada: todo texto novo nasceria em inglês, e os 2,7 M caracteres em português continuariam servidos sob o rótulo de inglês. Na interface,pt-BRé o padrão do web e ofallbackLng, e é a referência dos testes de paridade. - Os códigos são
pt-BR,en,ruezh-Hans, os mesmos no Docusaurus, no i18next, no<html lang>e emusers.locale. A busca local usa os códigos dela (pt,en,ru,zh). - Resolução de locale na interface: a escolha gravada na conta vence sempre
e nunca é sobrescrita por detecção. Sem escolha, o navegador sugere:
pt*→pt-BR;zh,zh-CN,zh-SGezh-Hans*→zh-Hans;ru*→ru;en*→en. - Idioma sem catálogo cai no pt-BR (decisão do dono): alemão, chinês tradicional e qualquer outro abrem no padrão, não no inglês. Texto que falta num locale cai na fonte pt-BR — e não falta na interface, porque a paridade reprova.
- A virada do site é um PR só, por
git mv: o inglês atual vai parawebsite/i18n/en/; as traduções pt-BR EM DIA substituem a fonte; as defasadas e as inexistentes deixam a página no idioma em que está até o lote dela, com aviso; ewebsite/i18n/pt-BR/docusaurus-plugin-content-docssai no MESMO PR, senão a pasta do locale padrão sobreporiadocs/e as 97 cópias defasadas iriam ao ar. - Página não traduzida, ou cuja fonte mudou depois da tradução, DIZ isso,
no idioma de quem lê: um wrapper de
DocItem/Contentdistingue fonte de tradução pelometadata.source, e cada página traduzida leva no frontmattertraducao_de: <commit da fonte>. - A paridade é MEDIDA e o relatório é GERADO pelo
pnpm docs:generate(docs/reference/paridade-de-traducao.md,generated: true; o--checkreprova o arquivo fora de dia): por locale, páginas e caracteres traduzidos sobre a fonte, páginas defasadas, data de revisão, revisão nativa e o que fica sem tradução por decisão; na interface, chaves por namespace contra o pt-BR e as formas de plural deIntl.PluralRules(pt-BR: one/many/other;en: one/other;ru: one/few/many/other;zh-Hans: other). As regras escritas moram emdocs/explanation/localizacao.md, com uma nota de terminologia por idioma — o que nunca se traduz: Brabo, os nomes de agente e papel do glossário, dados do usuário, comandos e números de RN/ADR. - O README é vitrine, no modelo do photocraft, com o pt-BR como fonte e
README.en.md,README.ru.mdeREADME.zh-Hans.md. As traduções não carregam versão nem contagens derivadas: linkam o pt-BR, que é o aferido. - Os ADRs 0001–~0103 voltam ao texto original em pt-BR em
docs/adr/(decisão do dono), e o inglês vai parawebsite/i18n/en/. Não é editar uma decisão aceita: é restaurar o texto que foi aceito, que hoje está na cópia pt-BR. Vale só para a cópia que for byte a byte o texto do commit de criação; a que divergir fica como está e é dita no relatório de paridade. - Até os lotes de inglês chegarem, o site em inglês mostra em português as
RNs e os ADRs recentes, com a faixa avisando (decisão do dono). E os
links antigos
/brabo/<ambiente>/pt-BR/…são reescritos pelo 404 da raiz para/brabo/<ambiente>/…, como o/main/→/prd/do ADR 0073; o inglês sai da raiz para/brabo/<ambiente>/en/…(decisão do dono). - Fases. Fase 1: a virada do site, as páginas de entrada (
intro,getting-started,glossarye o tutorial do zero ao entregável) nos quatro idiomas, os quatro READMEs, a interface completa emruezh-Hans, e a paridade medida. Fase 2 em diante: lotes por categoria da barra lateral × locale, um PR cada — primeiro o pt-BR das 97 páginas defasadas e das 26 só em inglês, depois o inglês das páginas pt-BR, depoisruezh-Hans.
Consequences
- O docmap troca a regra
traducao-pt-brportraducao,warne NUNCAblock: exigir tradução em todo PR de doc custaria quatro traduções por mudança. Quem segura a defasagem é o relatório gerado e a faixa na página. - Frase ancorada no código (
verificarFrasesAncoradasNoCodigo, contagens) em página que vira pt-BR reprova comoCEGOaté o padrão acompanhar, no PR do lote — de propósito. São 19 frases hoje. O mesmo vale para o cabeçalho queprocedimentos-do-runbook.mjsprocura e para os títulos dedocs/adr/temas.ymlquando o índice virar. ancoras-de-rn.mjspassa a conferir as RNs dos três locales traduzidos, elinks-do-locale.mjspassa a conheceren,ruezh-Hanscomo locales com prefixo.users.localeganharuezh-Hans(enum do Postgres, DTOs, tipos gerados). O idioma das respostas não muda de mecanismo — uma conta emrujá recebe a orientação genérica por BCP-47 —, e textos nativos de orientação e a detecção de cirílico e Han ficam como melhoria medida, não pré-requisito.- Custos declarados: o build do site compila quatro locales (cerca do dobro de
hoje, não medido); o índice de busca cresce (não medido); traduzir tudo é
cerca de 2,9 M caracteres para o inglês e 5,3 M para cada um de russo e
chinês; todo PR que muda uma fonte traduzida precisa rodar
pnpm docs:generate; o inglês sai da raiz do ambiente para/en/. - Sem revisão nativa, russo e chinês saem como tradução de máquina revisada por agente, e o relatório diz "revisão nativa: não" até um humano revisar.
Fora do escopo
docs/reference/**(gerado) continua fora da tradução, e o gerador continua escrevendo em inglês.- Idiomas além dos quatro, chinês tradicional e escrita da direita para a esquerda.
- Traduzir o conteúdo que o usuário e os agentes produzem (artefatos, mensagens): isso é o idioma do PROJETO e das respostas (ADR 0177), não da interface.