


Faça a IA Seguir o Estilo e as Regras de Módulos de um Grande Backend Java
Use quando uma IA trabalha num grande servidor Java de módulos e provedores. Ela lê primeiro os pontos de entrada, segue o estilo verificado no build e a versão mínima de Java, declara cada módulo que usa, confere no código antes de afirmar e testa localmente antes de fazer push.
Para usar estas regras de IA
## Antes de Editar, Entenda Como Módulos e Provedores se Encaixam
Um servidor grande desse tipo é montado a partir de módulos, e não escrito como uma única aplicação. Uma declaração de módulo dá nome ao módulo e às interfaces de serviço que ele expõe; um provedor implementa esses serviços com uma tecnologia específica; os demais módulos consomem apenas as interfaces declaradas. Os provedores são descobertos pelo mecanismo de service loader da plataforma e seguem um ciclo de vida fixo: uma fase de preparação que constrói objetos e lê a configuração, e em seguida uma fase de início que ativa os serviços.
### Rastreie o pipeline antes de mexer em um estágio
Os coletores enviam telemetria pela camada de transporte, os plugins receptores a analisam e validam, o motor de análise a agrega por meio das linguagens de domínio próprias do projeto, os plugins de armazenamento persistem o resultado e os plugins de consulta o entregam à interface. Uma mudança em um estágio geralmente exige uma contrapartida em outro.
### Leia primeiro os pontos de entrada
Antes de editar, leia a definição do módulo core, a classe base do sistema de módulos, os arquivos de gramática das linguagens específicas de domínio, o ponto de entrada da aplicação e a documentação de arquitetura. Um nome não diz como um recurso funciona.
## Siga o Estilo de Código que o Build Verifica Automaticamente
Aqui o estilo é verificado por máquina, então uma violação bloqueia o build em vez de iniciar um debate. Não imprima na saída padrão; use a fachada de logging do projeto. Não adicione anotações de autor. Não use caracteres de tabulação, imports com asterisco, imports não usados ou redundantes, instruções vazias ou várias linhas em branco consecutivas. Mantenha uma instrução por linha, mantenha espaço em branco depois de vírgulas, ponto e vírgula e casts, e mantenha espaço em branco ao redor dos operadores.
### Padrões obrigatórios
Anote os métodos sobrescritos. Sobrescreva igualdade e hash em conjunto. Dê uma descrição real a cada tag de parâmetro, retorno e exceção da documentação. Escreva constantes long com uma letra de sufixo em maiúscula. Coloque o ramo default por último em um switch. Respeite o comprimento máximo de arquivo e divida qualquer arquivo que esteja chegando perto dele.
### Nomenclatura
Constantes e variáveis estáticas usam maiúsculas com sublinhados, parâmetros de tipo usam maiúsculas, tipos usam pascal case, e locais, parâmetros e membros usam camel case. Prefira as fábricas de coleções imutáveis e o processador de anotações do projeto ao boilerplate escrito à mão, e prefira locais e parâmetros final.
### Não use nomes de classe totalmente qualificados inline
Adicione um import e use o nome curto em declarações de campo, assinaturas de método, variáveis locais e argumentos genéricos. As únicas exceções aceitáveis são uma colisão real de nomes simples entre duas classes importadas e um único link de documentação em que o nome curto seria ambíguo para quem lê.
### Não escreva métodos delegadores de uma linha
Um wrapper cujo único corpo repassa para outra classe acrescenta um salto sem valor. Coloque a chamada inline no ponto de uso ou chame o objeto subjacente diretamente, inclusive por referência de método.
### Cabeçalhos de licença
Arquivos de código-fonte, de marcação e de configuração carregam o cabeçalho de licença do projeto. Formatos que não podem conter comentários são excluídos pela configuração de licença; siga essa configuração em vez de adicionar cabeçalhos à mão onde eles não pertencem.
## Nomeie Classes e Métodos pela Função, Não por Metáforas
Classes e métodos são nomeados por sua função, não por uma metáfora abstrata. Prefira verbos concretos como carregar, aplicar, desregistrar, compilar, verificar, confirmar e reverter, em vez de verbos metafóricos como semear, hidratar, inicializar (bootstrap) e preparar (prime).
### Deixe o nome declarar a tarefa
Uma classe que carrega regras estáticas é nomeada pelo carregamento de regras estáticas, não por uma imagem evocativa. Um temporizador que sincroniza o estado do banco de dados segundo uma programação é nomeado por essa sincronização, não por um tique.
### Uma metáfora é um sinal para dividir
Se você não consegue nomear um método sem recorrer a uma metáfora, provavelmente o método está fazendo coisas demais. Divida-o até que cada parte tenha um nome funcional simples.
## Comente Só o que o Código Não Explica Sozinho
Não explique o que o código já declara. Comente apenas onde ler o código não é suficiente: uma invariante que não está visível neste método, uma restrição de ordem transversal, por que existe um ramo não óbvio, por que uma chamada aparentemente redundante é necessária. Se o código está claro, não escreva comentário nenhum.
### Conecte lógicas que vivem separadas
Uma verificação que existe apenas por causa de uma garantia feita em outro lugar merece um ponteiro de uma linha para essa garantia. Uma solução de contorno para um defeito conhecido em outro lugar merece um link para ele.
### Corte documentação que apenas repete o código
A documentação de método descreve o contrato, não o corpo. Justificativas de vários parágrafos pertencem ao documento de design, não ao arquivo de código-fonte.
## Use as Asserções do Framework e Pergunte Antes de Mudar Testes
Sempre use os métodos de asserção do framework de testes. Nunca use a instrução de asserção nativa da linguagem em um teste. Mesmo onde o executor de testes por acaso habilite essas instruções, as asserções do framework são a convenção no restante da base de código, sobrevivem a qualquer configuração de executor e produzem uma falha estruturada que informa o valor real em vez de um erro sem contexto.
### Corrija testes que falham, não os altere silenciosamente
Se testes unitários, de integração ou de ponta a ponta existentes falharem, tente corrigi-los. Se um caso de teste precisar ser modificado, ou se código de teste precisar ser excluído, essa mudança deve ser conferida por um humano antes de ser aplicada: apresente a modificação ou exclusão proposta e o raciocínio, e aguarde aprovação explícita em vez de alterar ou remover o teste por conta própria.
### Combine o tipo de teste com o escopo
Os escopos unitário e de integração usam padrões diferentes e harnesses diferentes. Comprove o comportamento no escopo em que ele de fato vive, em vez de duplicar a mesma asserção em todos os níveis.
## Escreva Código que Compile na Versão Mínima Suportada de Java
Um projeto que dá suporte a vários releases de suporte de longo prazo precisa compilar e rodar no mais antigo deles, mesmo quando a máquina de build tem um compilador mais novo. Assuma o mínimo, não o que seu editor aceita.
### Construções a evitar quando o mínimo é mais antigo
Expressões switch na forma de seta, o terminal de stream que retorna uma lista diretamente, blocos de texto, tipos record, pattern matching em uma verificação de tipo e tipos selados são todos mais novos que uma baseline antiga. Use, em vez disso, um switch tradicional com cases e breaks explícitos, um collector para construir a lista, concatenação de strings, uma classe comum com acessores gerados, um cast explícito após a verificação de tipo, e uma classe ou interface comum.
### Construções que são seguras
As fábricas de coleções imutáveis, os métodos mais novos de optional, expressões lambda, referências de método e a própria interface de stream estão disponíveis em uma baseline antiga e não precisam de solução de contorno.
### Verifique buscando, não confiando no build
Busque cada construção proibida na árvore de código-fonte e confirme que não há ocorrências antes de afirmar compatibilidade. Um build em um compilador mais novo não vai pegar isso para você.
## Mantenha Submódulos e Código Gerado em Sincronia com o Build
As definições de protocolo e a interface web podem viver em submódulos. Sempre clone com os submódulos incluídos e atualize-os explicitamente quando uma mudança de protocolo exigir isso. Uma mudança de protocolo que não esteja refletida no ponteiro do submódulo não vai compilar para mais ninguém.
### Gere antes de analisar
Execute a etapa de compilação antes de analisar código gerado, e instale o projeto para que o precompilador e as classes geradas sejam exportados antes de rodar os testes. Nunca edite classes geradas à mão; altere a definição que as produz e reconstrua.
### Reconstrua o projeto inteiro após mudanças entre módulos
Se você alterou mais de dois módulos, ou fez pull ou rebase a partir do remoto, construa o projeto inteiro em vez de selecionar módulos individuais. Builds incrementais de um único módulo podem deixar arquivos obsoletos no repositório local ou no diretório de bibliotecas quando o tamanho do arquivo não muda mas o conteúdo sim, o que produz falhas em tempo de execução muito difíceis de rastrear.
## Mantenha a Documentação e o Changelog Corretos e Bem Exibidos
A documentação é renderizada por um motor markdown, então considere como ela vai ficar, e não apenas como o código-fonte se lê. Caminhos de arquivo relativos são válidos e funcionam tanto no repositório quanto no site de documentação; continue usando-os em vez de links absolutos. Atualize o changelog sempre que o comportamento mudar.
### Mantenha cada item do changelog em uma única linha
Não quebre uma frase manualmente em várias linhas de código-fonte dentro de um item; subitens aninhados são aceitáveis porque são itens de lista reais. O changelog vira o corpo do release, e o renderizador de release transforma uma única quebra de linha contínua em uma quebra visível, de modo que itens quebrados aparecem com cortes irregulares no meio da frase na página do release, mesmo que o site de documentação refaça o fluxo do texto e esconda o problema.
### Congele uma proposta de design assim que ela for entregue
Quando a implementação de uma proposta de design é concluída, sincronize a proposta uma vez com o que foi realmente construído: cada mudança proposta escrita no passado, sem nenhuma linguagem remanescente de trabalho pendente, trabalho futuro, dependência em aberto ou "vazio até que", para qualquer coisa dentro do seu escopo. Após essa sincronização, a proposta fica congelada. Métricas adicionais, dashboards e melhorias incrementais vão para a documentação viva de operação. Apenas desdobramentos opcionais genuinamente pequenos podem permanecer sob trabalho futuro; nunca uma mudança grande.
### Faça referências cruzadas com links de âncora
Referencie outra seção com um link de âncora em markdown, nunca com um símbolo de seção nem com um número de seção solto. Verifique que cada âncora resolve para um heading real segundo as regras de slug do site, porque uma âncora quebrada é renderizada silenciosamente como texto simples.
## Declare Cada Módulo que o Seu Código Procura
Toda busca por um serviço de outro módulo precisa estar respaldada por uma declaração. Se o código pede ao gerenciador de módulos que encontre um módulo, direta ou indiretamente por meio de um helper, o nome desse módulo precisa aparecer na lista de módulos requeridos do provedor. Uma declaração ausente não falha na inicialização; ela lança na primeira vez que aquele caminho de código é executado. Envolver a chamada em um catch amplo não é um substituto: declare o módulo e mantenha o tratamento defensivo apenas para indisponibilidades transitórias do provedor. Ao auditar um branch, busque em cada módulo tocado por buscas ao gerenciador de módulos e confirme que cada alvo está declarado.
### Atualize todas as implementações, não apenas a principal
Quando você adiciona um serviço à lista de serviços de um módulo core, atualize todas as implementações de provedor daquele módulo, incluindo os provedores mock usados por ferramentas standalone e harnesses de teste. Busque subclasses na árvore em vez de supor que existe apenas uma. O servidor principal não é o único empacotamento; ferramentas standalone iniciam com provedores mock e um subconjunto de módulos, então mudanças nos contratos dos módulos core precisam alcançá-las também, ou essas ferramentas falham na inicialização.
### Prefira o serviço já populado ao módulo de coordenação
Módulos receptores e analisadores geralmente não declaram o módulo de coordenação do cluster, então buscá-lo diretamente lança em tempo de execução. Passe pelo serviço de gerenciamento de peers do módulo core, que a camada de coordenação já popula e que expõe a lista de peers de que a maioria dos componentes precisa. Se um módulo realmente precisar de primitivas de coordenação, declare esse módulo explicitamente.
### Não roteie intenção por canais laterais thread-local
Passar a intenção de quem chama por um thread-local que o código a jusante lê cria acoplamento invisível entre caminhos de código distantes, vaza através de passagens assíncronas como executores e event loops, e torna o comportamento impossível de entender a partir da assinatura de um método. Estenda a interface em vez disso: adicione um parâmetro, um método ou um valor de modo que apareça na assinatura, mesmo que custe mais linhas. As raras exceções são a propagação de contexto, em que toda a indústria padronizou o uso de um thread-local, e principais de segurança impostos por um framework.
## Espere a Mudança de Esquema Chegar a Todos os Nós Antes de Escrever Dados
Quando mudanças de esquema ou de metadados são transmitidas aos nós coordenadores e propagadas aos nós de dados de forma assíncrona, uma chamada de definição retorna assim que o coordenador a aceita, carregando um marcador de revisão, sem esperar pelos demais nós. Uma escrita de dados cuja definição ainda não se propagou é descartada no nó que a executa, registrada em log e ignorada, então uma barreira é necessária.
### Espere pela marca d'água de revisão
Depois de emitir uma mudança de definição, bloqueie no observador de esquema do cliente até que todo nó ativo reporte que aplicou pelo menos a revisão retornada, limitado por um timeout, antes de liberar as escritas dependentes. Uma verificação de leitura-após-escrita contra o registro não prova a propagação.
### Trate exclusões e stores síncronos
Quando uma exclusão não retorna um marcador de revisão utilizável, recorra à chamada dedicada de espera por exclusão. Stores cujas instruções de definição são síncronas no coordenador não precisam de barreira alguma. Não reintroduza o idioma mais antigo de fazer polling da chamada de consulta até conseguir ler a própria escrita; ele é anterior à interface de barreira e já foi substituído.
### Verifique qual biblioteca cliente você está lendo
Os tipos de barreira e de observador podem viver em um fork do cliente dentro da árvore, e não no cliente publicado standalone. A ausência deles no cliente publicado não é prova de que a interface sumiu.
## Confira o Código e a Documentação em Vez de Adivinhar
Nunca adivinhe nem especule. Toda análise deve estar fundamentada em código-fonte, documentação ou comportamento observado. Leia a implementação em vez de supor como um recurso funciona a partir do nome dele ou da convenção. Leia a documentação do projeto, os arquivos de orientação dentro dos submódulos e os arquivos readme antes de propor um design.
### Verifique configurações e flags
Confira quais flags e variáveis de ambiente realmente existem, quais são seus valores padrão e como são interpretados, incluindo qualquer convenção de prefixo que vincule flags a variáveis de ambiente automaticamente.
### Leia os projetos dos quais você depende
Antes de supor uma capacidade, leia o código-fonte e a documentação das dependências e dos projetos companheiros envolvidos: charts de implantação para os campos suportados, infraestrutura de testes para as opções suportadas, bibliotecas cliente para as chamadas disponíveis. Se um projeto companheiro provavelmente estiver clonado localmente, peça o caminho local, porque buscar em um clone local é muito mais rápido do que baixar arquivos um a um de uma interface remota.
## Rode o Código e os Testes Localmente Antes de Depender da Integração Contínua (CI)
Rode o código, suba o contêiner e execute o teste localmente antes de fazer push. A integração contínua não é um ambiente de tentativa e erro.
### Valide caminhos e estruturas de diretórios
Confira onde os dados realmente vão parar em vez de supor um nome de diretório a partir do nome de uma flag; uma opção de caminho raiz frequentemente cria abaixo dela um subdiretório com nome diferente.
### Valide configuração gerada ou editada
Depois de editar arquivos de configuração, especialmente com editores de fluxo ou scripts, valide-os com um parser de verdade antes de fazer commit. Configuração corrompida causa falhas silenciosas na automação.
### Confirme que imagens e binários existem
Verifique se a imagem de contêiner está de fato publicada antes de escrever configuração de pipeline ou de ponta a ponta que dependa dela, e confirme quais binários, shells e diretórios existem dentro da imagem antes de escrever comandos que os usem. A disponibilidade da imagem depende de os workflows de publicação terem concluído. Observe onde as imagens ficam: imagens próprias do projeto podem estar em um registro do host de código, com identificadores de commit completos como tags, enquanto imagens oficiais e de terceiros ficam no registro público, com tags convencionais.
## Faça Push pelo Fluxo de Submissão do Projeto e pela Automação Aprovada
Use o fluxo de submissão dedicado do projeto para fazer commit e push para um branch de revisão. Ele roda verificações prévias como compilação, checagem de estilo e verificação de cabeçalho de licença antes de cada push, e abre a solicitação de revisão caso ainda não exista uma.
### Respeite a lista de permissões de automação
A organização pode impor uma lista de permissões para etapas de automação de terceiros, exigindo que cada uma seja fixada em um identificador de revisão aprovado em vez de uma tag de versão. Se uma revisão for bloqueada porque uma etapa não é permitida, consulte a lista aprovada e atualize os arquivos de workflow para usar o pin aprovado. Etapas mantidas pelo fornecedor da plataforma ou pela própria organização são geralmente permitidas sem pin.
### Diga o que está faltando em vez de adivinhar
Se você não conseguir encontrar o código-fonte, não souber como rodar alguma coisa, ou o código não deixar a resposta clara, pergunte em vez de especular. Ao investigar comportamento em tempo de execução, monte um teste local com dados reais e observe a saída real em vez de prevê-la.
