Pular para o conteúdo

Compatibilidade

Uma CLI instalada não é atualizada quando o portal é. Mudar o que o portal responde quebra máquinas que ninguém tocou — e a quebra não aparece em lugar nenhum até alguém rodar um pipeline que já funcionava.

São duas camadas que quebram de formas diferentes, e é fácil confundi-las.

Os campos que o portal inventa: namespace, nome, versao, efeitos, privilegioMaximo, dependenciasAdicionais, depreciada.

Regra dentro de /api/v1: só adição.

Mudança Permitida Por quê
campo novo sim a CLI ignora o que não conhece
renomear campo não a CLI lê pelo nome
remover campo não idem
trocar o tipo não "1" e 1 não são a mesma coisa do outro lado
campo sempre-presente virar às-vezes-ausente não é remoção condicional

Nulos viajam explícitos: motivoDepreciacao vem como null quando não há depreciação, em vez de sumir. A forma da resposta não muda conforme o dado.

Quebrar qualquer uma dessas regras exige /api/v2 servido em paralelo — v1 não sai do ar enquanto houver CLI antiga instalada, e não há como saber que não há.

O que garante. CatalogoApiTest congela a forma de cada resposta, incluindo a contagem de campos. Renomear um campo de record deixa o teste vermelho. Foi verificado que ele falha de verdade quando isso acontece — um teste de contrato que não pega a quebra é pior que nenhum, porque dá confiança falsa.

Quando o portal recusa, o corpo é um ProblemDetail (RFC 9457) com três coisas, e cada uma serve a um leitor diferente:

Campo Para quem Estabilidade
status HTTP a CLI contrato
codigo a CLI contrato
detail a pessoa nenhuma — é prosa, e muda de idioma
problemas a pessoa lista, só em 422

O codigo existe porque status sozinho não basta: dois 403 podem pedir ações opostas. “Você não é membro da organização” manda pedir o papel; “esta task tem mantenedores e você não é um deles” manda pedir a manutenção — e mandar a primeira a quem já é publicador faz a pessoa procurar um acesso que ela tem.

A CLI decidia isso procurando a palavra mantenedores dentro do detail. Funcionava, e teria parado de funcionar em silêncio na primeira tradução do portal: dica errada, sem falha, mesmo código de saída. É o pior tipo de quebra — a que não aparece.

Regras, iguais às da camada 1: código novo é adição, renomear ou remover não. O status é fixo por código: o mesmo código respondendo 400 aqui e 403 ali obrigaria a CLI a olhar os dois. E uma CLI nunca falha diante de um código que não conhece — cai no genérico do status, que é o que permite ao portal ganhar motivos novos antes de as CLIs serem atualizadas.

O idioma. O detail sai no idioma do Accept-Language da requisição — inglês por padrão, português se pedido, inglês para qualquer outro. A resposta declara o que fez em Content-Language. O codigo não muda com o idioma: é o ponto todo de ele existir.

O que garante. CodigoDeErroTest congela a lista à mão — derivá-la do enum faria o teste concordar com a mudança que ele deveria impedir. Ele também exige mensagem em inglês para todo código, senão a chave crua vazaria para a tela. IdiomaDaRespostaTest vai pela ponta: o que quebrou uma vez foi a ligação entre o resolver e o cabeçalho, não cada peça isolada.

O documento é o task.yaml como foi publicado. O portal não o inventa: ele pertence ao spec, e é versionado pelo apiVersion que carrega dentro (oren.sh/v1).

Aqui a quebra é mais sutil, porque não passa pelo portal. Os schemas do spec são estritos (additionalProperties: false em 4 lugares no de task, 7 no de implementation). Então:

Se o spec ganhar um campo, e alguém publicar um documento que o use, toda CLI anterior àquele campo rejeita o documento — com “não satisfaz o schema”, que não explica nada para quem consome.

Não é um bug do portal e ele não pode evitar sozinho. Decorre de duas escolhas que continuam certas: schema estrito (foi o que teria pego o incremenMajorVersion que passou 16 releases) e servir o documento íntegro.

Regra: dentro de oren.sh/v1, o spec só admite adições opcionais. Um campo novo exige oren.sh/v2, e aí é a CLI que decide se sabe ler.

O que o portal garante hoje. ValidadorDeDocumentos recusa na publicação qualquer documento que não satisfaça o schema que o portal conhece. Isso impede o caso comum — publicar lixo — mas não o caso da camada 2, que é publicar algo válido demais para uma CLI velha.

Três lugares, uma regra: inglês por padrão, português quando pedido, inglês para qualquer outro idioma.

Onde De onde vem a escolha Catálogo
CLI OREN_LANG > LC_ALL > LC_MESSAGES > LANG cli/src/i18n/
Portal (API) Accept-Language da requisição portal/src/main/resources/messages*.properties
Portal (web) escolha no seletor > navigator.languages portal/web/src/app/i18n/

O inglês é o canônico nos três: nos catálogos em TypeScript ele define o TIPO que as outras línguas precisam satisfazer, e no messages.properties ele é o arquivo SEM sufixo, que é o fallback de qualquer locale.

As duas pontas mandam Accept-Language com o idioma que ELAS escolheram, não o do sistema. Sem isso a tela sai numa língua e a mensagem de erro dentro dela em outra — o que acontecia com quem escolhia português num navegador configurado em inglês.

O que NÃO é traduzido: os nomes dos comandos (oren run é a mesma palavra em todo lugar), os metavalores do help (<source>, [pipeline]), os papéis (publicador, admin — são valores do banco e aparecem na API), e a lista problemas de um 422, que vem do validador de schema em inglês.

  • A ordem das implementações. É apresentação, calculada por privilégio. Mudar o critério não quebra ninguém: a CLI não escolhe pelo ranking, quem escolhe é o oren.yaml.
  • As colunas derivadas do banco. efeitos, privilegio_max e companhia são recalculáveis do documento. O schema do banco pode mudar; a resposta, não.