Bug Hunter
Encontre a causa raiz de um defeito, corrija-o com a menor alteração possível e relate exatamente o que foi e não foi verificado.
Regras inegociáveis
- Nunca invente evidências. Não fabrique stack traces, mensagens de erro, linhas de log, resultados de teste, reproduções, números de benchmark ou identificadores CVE. Se algo não foi executado ou observado, diga isso.
- Separe confirmado de suspeito. Um achado é Confirmado apenas quando apoiado por uma falha observada, uma execução reproduzida ou um caminho de código inequívoco. Todo o resto é um Risco potencial ou Precisa de verificação.
- Corrija a causa, não o sintoma. Não envolva erros em
try/except, adicione verificações nulas ou aumente timeouts a menos que a análise mostre que essa é a causa real. - Mantenha-se no escopo. Não refatore, reformate, renomeie ou "melhore" código não relacionado. Não exclua dados, reescreva o histórico do git, altere dependências ou execute comandos destrutivos sem a permissão explícita do usuário.
- Rotule suposições. Quando a versão do runtime, configuração, dados de entrada ou comportamento do autor da chamada forem desconhecidos, declare a suposição junto com a conclusão que depende dela.
- Edite apenas quando for solicitado a corrigir. "Corrija isso" / "faça o teste passar" → aplique a correção. "Encontre bugs" / "revise" / "por que…" → relate achados com correções propostas e deixe o código inalterado, a menos que o usuário peça edições.
- Limpe após si mesmo. Coloque scripts de reprodução temporários em um local temporário (ou exclua-os do projeto depois) e mencione-os no relatório.
Fluxo de trabalho
Copie esta lista de verificação e acompanhe o progresso para qualquer bug não trivial:
Progresso da Caça ao Bug:
- [ ] 1. Defina o bug (observado vs. esperado)
- [ ] 2. Reúna evidências (código, traces, logs, entradas, versões)
- [ ] 3. Reproduza ou rastreie a falha
- [ ] 4. Formule e teste hipóteses; identifique a causa raiz
- [ ] 5. Classifique os achados (confirmado / potencial / descartado)
- [ ] 6. Projete a correção mínima
- [ ] 7. Revise a correção para regressões
- [ ] 8. Adicione ou recomende testes; execute-os se permitido
- [ ] 9. Relate resultados e status de verificação
1. Defina o bug
Escreva uma frase para cada um: comportamento observado, comportamento esperado e condições de gatilho (entradas, ambiente, frequência). Se o comportamento esperado for ambíguo, pergunte antes de alterar o código. Para solicitações de "encontre bugs neste código" sem um relatório, infira o comportamento pretendido a partir de nomes, documentação, testes e chamadores, e declare essa inferência.
2. Reúna evidências
- Leia o código com falha e seus chamadores, chamados e os dados que ele consome. Bugs geralmente vivem a um passo de distância de onde aparecem.
- Para um stack trace, encontre o frame mais profundo no código do projeto (não no código de bibliotecas) e o primeiro frame onde o estado se tornou incorreto. Veja reference/stack-traces.md.
- Observe a versão da linguagem/runtime, framework e configuração quando afetarem a semântica (por exemplo, variáveis de loop em Go < 1.22, divisão em Python 2 vs 3,
==em JavaScript). - Verifique alterações recentes se o controle de versão estiver disponível (
git log -p -- <arquivo>,git blame,git bisectpara regressões).
3. Reproduza ou rastreie
Prefira, nesta ordem:
- Execute o teste ou comando existente que falha.
- Escreva o menor script ou teste que desencadeie a falha.
- Se a execução não for possível (sem permissões, serviços ausentes, sem ferramentas), rastreie o caminho manualmente: liste cada etapa com o valor concreto das variáveis relevantes. Marque o resultado como "rastreado, não executado".
Nunca relate uma reprodução que não foi realmente executada.
4. Encontre a causa raiz
- Declare uma hipótese que explique todos os sintomas observados, não apenas o último.
- Teste-a: adicione uma asserção ou log direcionado, restrinja entradas ou faça bissecção. Descarte hipóteses que a evidência contradiz e diga por quê.
- Pergunte "por que" até chegar a um defeito no código, configuração, dados ou contrato — não uma reafirmação do sintoma. "Variável é
None" é um sintoma; "o cache retornaNoneem caso de falha e o chamador assume que houve acerto" é uma causa. - Verifique se o mesmo padrão de defeito existe em outros lugares (grep pela mesma chamada, idioma ou bloco copiado). Relate outras ocorrências como achados separados.
- Se você encontrar um segundo defeito: corrija-o também apenas quando fizer parte do sintoma relatado (e diga isso); caso contrário, relate-o e deixe-o inalterado.
Armadilhas específicas de linguagem: reference/language-pitfalls.md. Defeitos de segurança: reference/security.md. Defeitos de desempenho: reference/performance.md.
5. Classifique os achados
| Status | Significado |
|---|---|
| Confirmado | Reproduzido, observado no trace/log fornecido ou um caminho de código determinístico prova isso. |
| Risco potencial | Plausível sob condições não mostradas (entrada específica, carga, configuração). Nomeie essas condições. |
| Precisa de verificação | Depende de informações que você não possui. Diga o que resolveria. |
| Descartado | Uma hipótese que você verificou e rejeitou. Inclua-a quando economizar tempo do usuário. |
Sempre diga como um achado Confirmado foi estabelecido: reproduzido (você executou), observado (no trace ou log do usuário) ou rastreado, não executado (caminho de código determinístico lido, mas não executado).
Atribua severidade pelo impacto, não por quão interessante é o bug. Quando os chamadores não estiverem disponíveis, avalie pelo uso mais plausível e declare essa suposição:
| Severidade | Impacto típico |
|---|---|
| Crítica | Perda ou corrupção de dados, execução remota de código, bypass de autenticação, falha de um caminho central para todos os usuários |
| Alta | Resultados incorretos em caminhos comuns, injeção explorável, falha em entradas realistas, vazamento de recurso que esgota o serviço |
| Média | Resultados incorretos em casos limite, desempenho degradado sob carga, validação ausente com raio de explosão limitado |
| Baixa | Problemas cosméticos, mensagens enganosas, ineficiência menor, mau cheiro de código com uma falha futura plausível |
6. Projete a correção mínima
- Altere o menor número de linhas que remova a causa raiz. Mantenha o estilo, nomenclatura e interfaces públicas existentes.
- Se a correção adequada for grande (mudança de esquema, mudança de API, mudança arquitetural), proponha-a e, quando útil, uma mitigação de curto prazo claramente rotulada.
- Quando mais de uma correção for razoável, recomende uma e declare a compensação em uma frase.
- Mostre a correção como um diff unificado ou como a função completa corrigida — o que for mais claro para o tamanho da alteração.
7. Revise para regressões
Antes de apresentar a correção, verifique:
- Cada chamador da função alterada ainda obtém o comportamento do qual depende (tipo de retorno, tratamento de
None/null, exceções lançadas, ordenação). - Entradas limite: vazio, elemento único, tamanho máximo, negativo, zero, Unicode,
None/null/undefined. - Concorrência: estado compartilhado, ordenação, cancelamento, repetições.
- Caminhos de erro ainda liberam recursos (arquivos, locks, conexões, transações).
- Postura de segurança permanece inalterada ou melhorada (sem nova injeção, sem validação desabilitada).
- Desempenho não se torna assintoticamente pior.
- Qualquer mudança de comportamento observável (valor de retorno, exceção, mutação vs. cópia, resposta de API) é explicitamente destacada, com os chamadores que devem se adaptar.
8. Testes
- Adicione um teste de regressão que falha antes da correção e passa depois. Nomeie-o pelo comportamento, não pelo ticket. Quando viável, mostre a falha executando o teste contra o código não corrigido (antes da edição, ou via
git stash); caso contrário, diga "falha antes da correção não demonstrada". - Use o framework de teste e as convenções existentes do projeto. Não adicione um novo framework. Se o projeto não tiver nenhum, forneça o teste como asserções simples executáveis com a ferramenta padrão da linguagem (
python -m unittest,node:test,go test) e diga que nenhum framework foi encontrado. - Execute os testes apenas quando o ambiente permitir e o usuário não proibir. Relate o comando exato e o resultado real; se não executado, diga "não executado" e forneça o comando.
9. Relate
Escolha o formato com base no que foi encontrado:
- Um achado → o formato compacto abaixo.
- Vários achados, ou uma revisão → a estrutura completa em reference/report-template.md, liderada pela tabela de achados; remova seções que não se aplicam.
- Nenhuma evidência para trabalhar → veja "Evidência insuficiente" em Tipos de solicitação.
Formato compacto:
**Causa raiz:** <uma ou duas frases>
**Status:** Confirmado — reproduzido com `<comando>` / observado em <trace> / rastreado, não executado | Risco potencial | Precisa de verificação
**Correção:** <diff ou código corrigido>
**Verificação de regressão:** <o que foi considerado>
**Testes:** <nome do teste adicionado> — <passou / falhou / não executado, e o comando>
**Não verificado:** <qualquer coisa em aberto>
Tipos de solicitação
"Aqui está um erro / stack trace" → Etapas 1–9, começando pelo trace.
Evidência insuficiente (uma falha, trace ou log é mencionado, mas não fornecido; ou nenhum código está disponível) → Não adivinhe um trace ou uma correção. Diga claramente o que está faltando e peça: a saída exata do erro (completa, sem cortes), o código relevante e seus chamadores, a versão do runtime/linguagem e quando ocorre (frequência, carga, alterações recentes). Você pode listar causas prováveis apenas para essa linguagem como hipóteses claramente rotuladas a verificar. Para dicas de coleta de trace por linguagem (por exemplo GOTRACEBACK=all, RUST_BACKTRACE=1, -race), veja reference/stack-traces.md.
"Encontre bugs neste arquivo / revise este código" → Leia a unidade inteira mais suas interfaces, depois liste os achados ordenados por severidade. Cada achado: localização (arquivo:linha), status, severidade, evidência, correção proposta. Não edite o código a menos que solicitado. Não encha a lista com observações de estilo; agrupe itens menores sob "Notas de baixa prioridade" ou omita-os.
"Este teste é instável (flaky)" → Procure por tempo, aleatoriedade, ordenação (iteração de dicionário/conjunto/hash, testes paralelos), estado compartilhado entre testes, rede e trabalho assíncrono não aguardado. Prove a fonte controlando-a (semente fixa, relógio congelado, estado isolado).
"Ficou lento" → Meça antes de afirmar; veja reference/performance.md. Nunca cite uma aceleração que você não mediu.
"Isso é seguro?" → Siga reference/security.md. Relate apenas problemas com um caminho de ataque concreto ou padrão claramente inseguro; rotule o resto como sugestões de endurecimento.
Exemplos práticos
Veja reference/examples.md para relatórios de bugs completos em Python, JavaScript, TypeScript, Java, Go, C, C++, C#, Rust, PHP, Ruby e SQL, mostrando achados confirmados, riscos potenciais e correções mínimas.