


Alterar o código de um banco de dados de alto desempenho sem perder velocidade nem compatibilidade
Use quando uma IA altera um banco de dados focado em velocidade que envolve Java, SQL, Rust, código nativo e CI. Define regras de estilo, NULL, liberação de memória, testes de consultas, falhas, pull requests e build, e termina com uma checagem antes de dar o trabalho como concluído.
Para usar estas regras de IA
## Manter os módulos do banco de dados separados e proteger os caminhos de dados sem alocações
- Preserve limites explícitos entre os módulos do mecanismo de armazenamento, mecanismo SQL, protocolos de rede, utilitários, filas de workers, registro de logs, tarefas em segundo plano, benchmarks, testes de compatibilidade e exemplos.
- Mantenha o código de produção separado de benchmarks, utilitários de build, exemplos e wrappers de plataforma.
- Trate um repositório cliente aninhado ou submódulo como um repositório independente, com seus próprios commits e objetivo de compatibilidade.
- Identifique o ponto de entrada correto antes de alterar o comportamento: inicialização do servidor, mecanismo de armazenamento, compilador SQL, leitor de tabelas ou gravador de tabelas.
- Proteja os caminhos de dados sem alocações durante a execução de consultas e a ingestão.
- Prefira pools de objetos, buffers reutilizáveis, armazenamento orientado a colunas, execução vetorizada e aceleração nativa quando a arquitetura exigir esses recursos.
- Não introduza dependências de runtime de terceiros quando o projeto implementar deliberadamente algoritmos críticos para o desempenho por conta própria.
- Limite o código nativo às operações que justifiquem seus riscos de memória, plataforma e falha.
## Ordenar os membros das classes Java e manter a compatibilidade com clientes Java antigos
- Agrupe os membros da classe por categoria estática ou de instância e por visibilidade; depois, mantenha os membros em ordem alfabética dentro de cada grupo.
- Insira novos campos e métodos na posição correta da ordenação, em vez de criar grupos de seções decorativos.
- Nunca adicione comentários em forma de faixa como títulos artificiais de seções Java.
- Use os recursos modernos da linguagem aceitos pelo módulo principal, incluindo `switch` aprimorado, strings multilinha e variáveis de padrão.
- Respeite versões mais antigas da linguagem nos módulos de compatibilidade; não permita que a sintaxe do módulo principal passe para um cliente destinado a uma versão anterior do Java.
- Prefixe variáveis, campos e métodos booleanos com `is` ou `has`, conforme apropriado.
- Use estritamente caracteres ASCII nas mensagens de log quando o pipeline de registro não conseguir renderizar pontuação ou símbolos Unicode com confiabilidade.
- Use os tipos de coleção do projeto que consideram recursos, em vez de arrays genéricos de objetos, quando eles se integrarem aos utilitários de limpeza estabelecidos.
- Siga os padrões existentes de nomenclatura, propriedade e alocação antes de introduzir uma nova abstração.
## Definir o tratamento de NULL e liberar a memória em cada caminho de erro
- Defina explicitamente o comportamento de NULL para dados de colunas, resultados de expressões, instruções SQL e estados intermediários.
- Diferencie um sentinela NULL que significa “ainda não inicializado” de um NULL real nos dados.
- Rastreie cada alocação e recurso fechável pelos caminhos de sucesso, erro, cancelamento e retorno antecipado.
- Use de modo consistente os utilitários de limpeza do repositório para listas e elementos fecháveis.
- Trate a prevenção de vazamentos como um requisito de projeto, não como uma preocupação exclusiva dos testes.
- Adicione aos testes que alocam memória nativa asserções para detectar vazamentos de memória.
- Testes unitários restritos que comprovadamente não alocam memória nativa podem omitir o mecanismo de detecção de vazamentos.
- Verifique a limpeza em todos os caminhos de erro relevantes, não apenas no caminho bem-sucedido.
- Nunca esconda uma ambiguidade de propriedade por trás de um contêiner ou utilitário conveniente.
## Testar consultas com asserções rigorosas que releem os resultados
- Prefira o framework fluente canônico de asserções de consulta aos utilitários legados que imprimem e comparam em uma única passagem.
- Para consultas determinísticas, exija uma segunda passagem do cursor, verificações cruzadas de tamanho, verificações de colunas variáveis e asserções relevantes de propriedades da factory.
- Use uma asserção de passagem única somente quando a projeção for realmente instável entre releituras e informe o motivo.
- Exemplos válidos de instabilidade incluem funções aleatórias sem seed definido e funções que variam com o tempo.
- Execute DDL e outras instruções que não sejam consultas pelo caminho de execução destinado a elas.
- Valide os planos de execução com os utilitários de plano do framework quando o comportamento do otimizador fizer parte do contrato.
- Use uma única instrução `INSERT` para várias linhas de teste quando o dialeto oferecer suporte a isso.
- Use strings multilinha para SQL longo e resultados esperados com várias linhas.
- Escreva as palavras-chave SQL de forma consistente, de preferência em letras maiúsculas.
- Separe milhares com sublinhados em literais de cinco ou mais dígitos quando essa sintaxe for aceita.
## Seguir o dialeto SQL e apontar o erro no caractere exato
- Trate tipos de arrays multidimensionais como tipos distintos quando a dimensionalidade estiver codificada no tipo da coluna.
- Use de forma consistente a sintaxe de conversão preferida pelo dialeto, em vez de misturar formas equivalentes.
- Mantenha o suporte a separadores numéricos alinhado entre o parser, o código de implementação e os testes.
- Não suponha que os recursos do SQL padrão existam; documente e teste as operações sem suporte.
- Quando a exclusão de linhas não for aceita, modele explicitamente a exclusão lógica na lógica da aplicação.
- Mantenha as operações de descarte no nível de partição separadas da exclusão no nível de linha, pois seus escopos e sua segurança são diferentes.
- Faça a posição de um erro SQL informado apontar para o caractere exato que causou o erro, não apenas para o início da expressão.
- Teste os erros do parser verificando tanto a mensagem quanto a posição exata.
- Preserve a diferença entre erros de sintaxe, semântica, tipo e execução.
## Tratar cada teste com falha como um defeito real até que as evidências mostrem o contrário
- Trate cada teste vermelho, job de CI com falha e entrada de log surpreendente como um defeito ativo até que as evidências demonstrem o contrário.
- “Preexistente”, “intermitente”, “não relacionado” e “problema conhecido” são hipóteses, não conclusões.
- Reproduza na linha de base relevante, examine o histórico de versões, meça as restrições de tempo e consulte os relatos oficiais do projeto de origem.
- Deixe uma falha de lado somente quando as evidências impuserem essa conclusão.
- Relate as evidências que justificaram a classificação para que outra pessoa responsável pela revisão possa verificá-las.
- Não trate uma nova execução bem-sucedida como a única prova de que uma falha era inofensiva.
- Investigue falhas de interação quando várias alterações compartilharem a mesma linhagem de CI.
- Preserve logs, entradas que causam falha e a menor reprodução confiável necessária para o diagnóstico.
- Mantenha a correção concentrada na causa comprovada e adicione um teste de regressão que falhe sem ela.
## Ajustar branches e pull requests ao tipo de merge e ao custo de CI
- Ajuste a estratégia de branches e pull requests ao modelo de merge do repositório e aos custos da CI.
- Em um fluxo de squash merge, não gaste esforço aprimorando um histórico de branch que será descartado.
- Adicione um commit de correção claro, em vez de reescrever commits anteriores ou executar um force push apenas por razões estéticas no histórico.
- Agrupe correções relacionadas quando a separação multiplicar execuções longas de CI, exposição a testes intermitentes e coordenação de merges.
- Divida as alterações somente quando o usuário solicitar ou quando elas precisarem ser incorporadas ou revertidas de forma independente.
- Ao atualizar um pull request existente, sincronize com o head remoto, adicione as alterações a esse branch e atualize seus metadados.
- Não abra um segundo pull request apenas para executar novamente a validação da mesma linhagem de alterações.
- Não crie worktrees de revisão nem faça checkout de branches quando a política do repositório definir outro branch como o estado canônico para revisão.
- Obtenha o diff de um pull request sem trocar de branch quando apenas o diff for necessário.
- Faça o commit interno de um repositório aninhado antes de registrar o ponteiro do submódulo no repositório pai.
## Escrever pull requests e commits que mostrem igualmente os prós e os contras
- Use a convenção de título de pull request exigida pelo repositório e torne a descrição significativa para os usuários finais.
- Descreva efeitos positivos, efeitos negativos, regressões e concessões com o mesmo destaque.
- Evite linguagem publicitária, superlativos, métricas seletivas e ênfase decorativa.
- Faça referência a um issue corrigido no formato de encerramento exigido no início do corpo do pull request.
- Mantenha os títulos de commits curtos, descritivos e no estilo exigido pelo repositório.
- Inclua um corpo de commit substantivo que explique a alteração, em vez de repetir o título.
- Use marcadores simples nos planos de teste quando caixas de seleção ou marcas de verificação forem proibidas.
- Aplique rótulos que correspondam ao domínio e ao título da alteração.
- Use voz ativa em commits, pull requests e comentários de código.
- Nomeie a classe, o método, o chamador ou o componente que executa a ação, em vez de ocultá-lo em construções passivas.
## Verificar o ambiente e depois fazer build e testes a partir do menor escopo
- Verifique o runtime da linguagem, a ferramenta de build, a arquitetura e as variáveis de ambiente exigidos antes de executar o build.
- Escolha o menor perfil de build que comprove a alteração atual e use perfis mais completos quando artefatos web ou nativos forem afetados.
- Recompile os módulos dependentes quando um cache local de artefatos puder conter um cliente ou uma biblioteca desatualizados.
- Execute invocações de teste caras em sequência quando builds paralelos interferirem entre si.
- Comece pela classe ou pelo método de teste relevante mais restrito e depois amplie conforme o risco e a política do repositório.
- Não trate apenas a compilação como prova do comportamento em runtime.
- Valide o servidor pelo caminho de inicialização aceito e examine o endpoint ou a interface diretamente afetados.
- Mantenha os artefatos de build nos locais designados e pertencentes aos respectivos módulos.
- Registre o comando exato que falhou e o primeiro erro que permita uma ação quando o build parar.
## Zerar os avisos do Rust e impedir que um panic derrube a JVM via JNI
- Antes de concluir um trabalho em Rust, execute formatação, compilação de todos os alvos, lint e testes da biblioteca a partir da raiz do crate.
- Exija zero erros e zero avisos em todas as verificações obrigatórias.
- Meça a cobertura depois de adicionar ou alterar testes.
- Para cada linha sem cobertura, adicione um teste ou prove que a linha é inalcançável e marque explicitamente essa invariante.
- Nunca chame `unwrap()` ou `expect()` em dados provenientes de arquivos ou fornecidos externamente.
- Propague falhas recuperáveis com `Result`, `Option` e a propagação de erros padrão da linguagem.
- Lembre-se de que um panic do Rust que atravesse a JNI pode abortar toda a JVM sem possibilidade de recuperação.
- Compile bibliotecas nativas em C e C++ com a configuração de release do repositório e verifique os artefatos esperados.
- Trate propriedade, tempo de vida, alinhamento e conversão de erros na FFI como contratos explícitos.
- Teste falhas de fronteira em todas as plataformas aceitas que forem afetadas pela alteração.
## Evitar alocações no heap e medir o ganho de velocidade com benchmarks
- Evite alocação no heap em caminhos de dados nos quais o comportamento sem coleta de lixo seja um requisito de arquitetura.
- Reutilize buffers e objetos de pools e torne explícita a transferência de propriedade.
- Armazene dados analíticos por coluna quando a compactação e as operações vetorizadas dependerem dessa organização.
- Mantenha SIMD, gerenciamento de memória e otimizações específicas de plataforma por trás de limites nativos restritos.
- Separe armazenamento, parsing, planejamento, geração de código, execução, tratamento de protocolos e trabalho em segundo plano.
- Use coleções personalizadas somente quando o comportamento de alocação e limpeza delas for compreendido e testado.
- Meça as alterações de desempenho com benchmarks representativos, não por intuição.
- Acompanhe uma otimização de testes de correção, verificações de recursos e uma concessão documentada.
- Não enfraqueça a compatibilidade nem a precisão dos erros para obter uma aceleração não medida.
## Revisar o diff final e relatar os resultados antes de dar o trabalho como concluído
- Revise o diff final quanto à ordenação de membros, aos limites de compatibilidade, ao comportamento de NULL, à propriedade de recursos e à presença acidental de Unicode nos logs.
- Execute as verificações direcionadas de Java, SQL, Rust, código nativo e integração afetadas pela alteração.
- Confirme que as consultas determinísticas usam o caminho forte de asserção com releitura.
- Confirme que entradas externas não podem provocar um panic nativo irrecuperável.
- Verifique se toda falha investigada tem uma classificação fundamentada em evidências e uma reprodução relatada.
- Garanta que metadados, rótulos, plano de teste, texto de commit e referências a issues do pull request estejam de acordo com a política do repositório.
- Verifique se repositórios aninhados e ponteiros do repositório pai foram registrados em commits na ordem correta.
- Não declare a conclusão enquanto as verificações obrigatórias tiverem erros ou avisos.
- Relate os comandos executados, os resultados observados, os riscos restantes e o escopo intencionalmente não testado.
