


Faça mudanças pequenas e compatíveis em um projeto Java dividido em módulos
Para quando uma IA altera um projeto Java dividido em módulos. Confere primeiro as regras de build e CI, mantém funcionando versões antigas do Java e as dependências entre módulos, testa na camada certa e pergunta antes de mudanças amplas ou arriscadas.
Para usar estas regras de IA
## Confira as regras de build, formatação e CI antes de editar
Trate as orientações do repositório, a configuração de compilação, as regras de formatação e as verificações de integração contínua como contratos executáveis. Leia as instruções aplicáveis antes de editar e identifique quais regras são impostas mecanicamente.
- Localize o wrapper oficial de compilação, o formatador, as verificações estáticas, os comandos de teste e a política de contribuição.
- Antes de alterar o código, rastreie o módulo responsável e suas dependências.
- Prefira os utilitários e padrões estabelecidos do projeto a alternativas que sejam convenientes apenas no ambiente local.
- Diferencie compatibilidade do código-fonte, requisitos das ferramentas de compilação, suporte ao ambiente de execução e comportamento da distribuição.
- Não desative um controle de qualidade apenas para fazer uma mudança ser aprovada.
Use a menor entrada oficial que controle o comportamento solicitado.
## Mantenha o código compatível com a versão do Java e as dependências declaradas
Uma compilação pode exigir um conjunto de ferramentas mais recente, mesmo que seu código-fonte permaneça compatível com um ambiente de execução mais antigo. Compile e teste de acordo com o nível de código-fonte declarado; não suponha que um ambiente local mais recente permita usar recursos novos da linguagem ou APIs novas de bibliotecas.
- Substitua APIs convenientes sem suporte por equivalentes compatíveis.
- Quando necessário, use os namespaces de dependências realocados ou sombreados do repositório.
- Prefira os utilitários do próprio projeto para validação, serialização, coleções, arquivos, Future e tempo.
- Evite importações diretas de terceiros quando a distribuição isolar essas bibliotecas.
- Antes de adicionar uma dependência, discuta a compatibilidade, o licenciamento, o empacotamento e o impacto transitivo.
Verifique a compatibilidade pelo alvo de compilação designado pelo repositório, não apenas por uma compilação local.
## Use factories, builders e resultados imutáveis nas APIs públicas
Marque as APIs de acordo com a estabilidade pretendida: contratos públicos estáveis, contratos públicos em evolução e superfícies internas de implementação devem permanecer distintos.
- Faça as fábricas retornarem interfaces e oculte a construção atrás de construtores privados ou métodos estáticos de criação.
- Use builders em configurações de várias etapas, com métodos fluentes e um único ponto de construção validado.
- Mantenha os objetos de resultado imutáveis, com estado declarado como final, sem setters e com implementações completas de igualdade, hash e representação em texto.
- Forneça interfaces genéricas e tipadas quando os chamadores precisarem das duas formas sem conversões inseguras.
- Documente os requisitos de segurança entre threads nos tipos públicos.
Alterar um contrato público exige uma análise de compatibilidade e o caminho de versionamento adequado.
## Mantenha as dependências entre módulos em uma só direção
Mapeie o grafo de módulos antes da implementação. Os módulos fundamentais devem conter os tipos e interfaces compartilhados; as camadas de protocolo ou transporte são construídas acima deles; módulos equivalentes de cliente e servidor não devem depender um do outro; as integrações devem ficar acima das camadas inferiores estáveis.
- Defina interfaces compartilhadas no módulo apropriado de nível mais baixo e coloque as implementações acima dele.
- Impeça que conectores e integrações opcionais vazem dependências para o núcleo.
- Evite dependências circulares e importações entre módulos pares motivadas apenas pela conveniência.
- Reproduza nos testes a estrutura de pacotes do código de produção.
- Coloque o código gerado, os recursos de distribuição, os geradores de documentação e os utilitários de teste em seus módulos designados.
Quando uma funcionalidade atravessar limites, altere explicitamente cada camada responsável, em vez de contornar a arquitetura.
## Separe os tipos de erro e proteja o estado compartilhado com locks
Valide as entradas nos limites da API com os utilitários de precondições padrão do projeto e com mensagens que indiquem como agir. Preserve a hierarquia de exceções para que os chamadores possam diferenciar erros do usuário, falhas que permitem nova tentativa e falhas internas não verificadas.
- Propague falhas assíncronas pelos utilitários de Future e pelos manipuladores de erros estabelecidos.
- Componha o trabalho assíncrono em vez de bloqueá-lo sem uma justificativa documentada.
- Proteja o estado mutável compartilhado com bloqueios explícitos e documente os campos protegidos.
- Use primitivas de visibilidade somente quando o acesso fora do bloqueio as exigir.
- Feche os recursos por meio do gerenciamento estruturado de recursos.
- Torne as operações de fechamento idempotentes quando a limpeza puder ser repetida.
Não oculte falhas verificadas nem reúna erros que permitem nova tentativa e erros permanentes em uma única exceção sem distinção.
## Mantenha compatíveis as chaves de configuração e os esquemas de mensagens
Quando aplicável, defina configurações por meio de builders tipados com valores padrão, descrições, valores opcionais e tratamento de chaves obsoletas. Use chaves hierárquicas e consistentes e acesse os valores pela abstração de configuração do repositório.
Para serialização e mensagens remotas:
- preserve o esquema e a versão do protocolo declarados;
- use somente formatos de campo aceitos por essa versão;
- gere novamente o código com o gerador oficial após alterações no esquema;
- mantenha as mensagens de transporte imutáveis e marque adequadamente os tipos internos de transporte;
- represente campos opcionais de forma explícita;
- nunca edite arquivos gerados quando um fluxo de geração for responsável por eles.
Atualize os testes de compatibilidade e a documentação gerada sempre que um contrato de configuração ou transporte mudar.
## Escreva testes unitários e de integração com as ferramentas do projeto
Use o framework de testes, a biblioteca de asserções, as convenções de nomenclatura, as extensões e os fixtures básicos escolhidos pelo repositório. Não misture asserções alternativas nem mecanismos de tempo limite que entrem em conflito com a infraestrutura global de testes.
- Escreva testes unitários focados no comportamento local e testes de integração para contratos entre componentes.
- Use nomes de teste descritivos que indiquem o comportamento em avaliação.
- Verifique tanto os resultados bem-sucedidos quanto as falhas esperadas.
- Reutilize os fixtures compatíveis de cluster, armazenamento ou serviço, em vez de criar uma infraestrutura paralela.
- Execute primeiro o teste afetado mais restrito e depois o conjunto diretamente afetado.
- Confirme que o teste falha pelo motivo pretendido antes de usá-lo como prova de uma correção.
Teste por meio do comportamento público sempre que um detalhe interno de implementação não fizer parte do contrato.
## Compile e verifique pelo wrapper de build do projeto
Use o wrapper do repositório para compilação, formatação, análise estática, verificações de licença, geração de código e testes. Os comandos oficiais podem preparar recursos gerados ou impor requisitos de compatibilidade que chamadas diretas às ferramentas não detectam.
- Compile com o conjunto de ferramentas documentado, preservando o alvo de código-fonte declarado.
- Inicie as dependências e os componentes de serviços locais na ordem documentada.
- Edite somente os arquivos e valores de configuração aceitos.
- Execute a formatação antes das verificações estáticas.
- Execute os conjuntos afetados antes de uma verificação mais ampla.
- Use o perfil de cobertura quando a mudança puder alterar o comportamento em avaliação.
Entenda as etapas da integração contínua e reproduza localmente a etapa relevante antes de informar a conclusão.
## Siga o formatador e não misture mudanças não relacionadas no diff
Siga a ordem imposta para importações e modificadores, a sintaxe de arrays, as regras de chaves, a política de espaços em branco e as convenções de nomenclatura. Deixe o formatador oficial resolver o estilo mecânico.
- Evite importações curinga e marcadores de comentários ou etiquetas de atribuição proibidos pelo repositório.
- Mantenha as APIs public e protected documentadas quando o projeto exigir.
- Respeite os limites de tamanho de arquivo extraindo responsabilidades coerentes, não compactando o código em prejuízo da legibilidade.
- Atualize a documentação quando comandos, configurações, compatibilidade ou comportamento público mudarem.
- Revise a diferença final em busca de reescritas sem relação, edições acidentais de arquivos gerados, segredos e limpeza incompleta.
Não combine uma mudança de comportamento bem delimitada com uma refatoração sem relação.
## Publique mudanças por branches de revisão, nunca com force-push
Trabalhe em uma ramificação autorizada e verifique cada repositório remoto antes de fazer push. Mantenha protegidas as ramificações ascendentes ou compartilhadas; publique as mudanças pelo caminho de revisão do projeto, em vez de gravar diretamente em alvos protegidos.
- Faça rebase ou atualize a partir da ramificação base oficial por meio do fluxo documentado.
- Escreva um assunto de commit conciso e limitado ao componente e, quando necessário, explique a motivação no corpo.
- Revise a diferença completa da ramificação antes de publicar.
- Execute a formatação, as verificações estáticas e de licença e os testes afetados.
- Inclua um resumo simples e um plano de testes na solicitação de revisão.
- Identifique as mudanças feitas com assistência para revisão humana quando a política de contribuição exigir.
Nunca faça force-push em uma ramificação compartilhada nem use operações destrutivas no histórico sem autorização explícita.
## Pergunte antes de trabalhos amplos ou destrutivos, como novas dependências ou resets
Avance de forma autônoma com leituras delimitadas, compilações locais, testes, formatação, diagnósticos e correções que sigam as regras existentes. Peça permissão antes de trabalhos amplos ou de grande impacto, como refatorações entre módulos, dependências novas, migrações de esquema, alterações no sistema de compilação, alterações na integração contínua ou operações destrutivas.
Sem permissão explícita, nunca:
- inclua credenciais ou valores confidenciais em um commit;
- faça push diretamente para um alvo ascendente protegido;
- faça force-push no histórico compartilhado ou apague ramificações;
- execute hard reset ou uma limpeza destrutiva;
- contorne hooks, verificações estáticas ou regras de formatação;
- modifique os resultados gerados em vez dos arquivos-fonte correspondentes;
- enfraqueça os controles de qualidade para obter um resultado aprovado.
Antes de concluir, verifique os testes, a formatação, as verificações estáticas, os cabeçalhos obrigatórios e toda a diferença pretendida. Quando o escopo ou a reversibilidade forem incertos, pare e explique a decisão necessária.
