{
 "grupo": "depuracao",
 "descricao": "Depuração",
 "itens": [
  {
   "id": "dep-reproduzir",
   "nome": "Reproduzir o bug",
   "receita": "ache o menor comando/entrada que falha; copie a saída exata",
   "prova": "comando que falha 3 de 3 vezes"
  },
  {
   "id": "dep-ler-erro",
   "nome": "Ler uma pilha de erro",
   "receita": "comece pela última linha (o erro), depois o primeiro frame no SEU código",
   "prova": "frase: \"falha em X porque Y\""
  },
  {
   "id": "dep-bisect-comentar",
   "nome": "Isolar por eliminação",
   "receita": "comente metade do código/entrada; o bug sumiu? está na metade tirada; repita",
   "prova": "trecho de até 10 linhas"
  },
  {
   "id": "dep-print-certo",
   "nome": "Logar com método",
   "receita": "log antes e depois da suspeita com valores reais (JSON.stringify), não \"chegou aqui\"",
   "prova": "valor inesperado visto"
  },
  {
   "id": "dep-undefined",
   "nome": "undefined / null inesperado",
   "receita": "ache onde o valor nasce, não onde quebra; confira nome, caminho e forma do dado",
   "prova": "valor aparece no log com o formato certo"
  },
  {
   "id": "dep-async",
   "nome": "Ordem errada de async",
   "receita": "procure await esquecido, promessa solta, callback chamado duas vezes; log com timestamp",
   "prova": "ordem dos logs confere"
  },
  {
   "id": "dep-so-na-minha",
   "nome": "Funciona aqui e não lá",
   "receita": "compare versão, SO, variáveis, dados e rede; liste a 1ª diferença real",
   "prova": "diferença nomeada e igualada"
  },
  {
   "id": "dep-flaky",
   "nome": "Teste intermitente",
   "receita": "rode 20x em laço; procure tempo, ordem, estado compartilhado, rede real",
   "prova": "20 de 20 verdes"
  },
  {
   "id": "dep-memoria",
   "nome": "Vazamento de memória",
   "receita": "meça RSS ao longo do tempo; heap snapshot antes/depois; procure listeners e caches sem limite",
   "prova": "curva de memória estável"
  },
  {
   "id": "dep-loop-infinito",
   "nome": "Programa travado",
   "receita": "kill -QUIT (Node/Java mostra pilha) ou py-spy dump; veja onde está parado",
   "prova": "linha onde trava identificada"
  },
  {
   "id": "dep-regressao",
   "nome": "Quebrou depois de uma mudança",
   "receita": "git diff da última boa; git bisect",
   "prova": "commit culpado"
  },
  {
   "id": "dep-http-erro",
   "nome": "Erro de HTTP",
   "receita": "curl -v: status, headers, corpo; compare com a documentação; token expirado?",
   "prova": "resposta 2xx"
  },
  {
   "id": "dep-cors",
   "nome": "Erro de CORS",
   "receita": "CORS é do SERVIDOR: header Access-Control-Allow-Origin certo e resposta ao OPTIONS",
   "prova": "chamada do navegador passa"
  },
  {
   "id": "dep-import",
   "nome": "Módulo não encontrado",
   "receita": "confira nome, caminho relativo, extensão, ESM x CJS e se o pacote está no package.json",
   "prova": "import resolve"
  },
  {
   "id": "dep-build",
   "nome": "Build falha",
   "receita": "leia o PRIMEIRO erro, não os 50 seguintes; limpe cache só depois de entender",
   "prova": "build termina com código 0"
  },
  {
   "id": "dep-porta",
   "nome": "Servidor não sobe",
   "receita": "erro EADDRINUSE: porta ocupada; EACCES: permissão; veja o log inteiro",
   "prova": "curl na porta responde"
  },
  {
   "id": "dep-lento",
   "nome": "Algo ficou lento",
   "receita": "meça com profiler/time; ache o gargalo antes de mexer",
   "prova": "número antes e depois"
  },
  {
   "id": "dep-encoding",
   "nome": "Acento quebrado",
   "receita": "confira UTF-8 da origem ao destino (arquivo, banco, header Content-Type)",
   "prova": "texto com acento ida e volta"
  },
  {
   "id": "dep-fuso",
   "nome": "Data/hora errada",
   "receita": "tudo em UTC no banco; converta só na borda; confira Date vs timezone",
   "prova": "mesma data em duas zonas"
  },
  {
   "id": "dep-numero",
   "nome": "Conta com decimal errada",
   "receita": "nunca float para dinheiro: inteiro em centavos ou decimal",
   "prova": "0.1+0.2 não aparece no resultado"
  },
  {
   "id": "depuracao-bug-que-so-acontece-em-producao",
   "nome": "Bug que só acontece em produção",
   "receita": "compare versão, variáveis, dados e carga; reproduza localmente com a configuração e os dados de produção sanitizados",
   "prova": "o bug reproduzido fora da produção"
  },
  {
   "id": "depuracao-erro-sem-mensagem-util",
   "nome": "Erro sem mensagem útil",
   "receita": "aumente o nível de log, capture a exceção original (cause) e imprima a pilha completa",
   "prova": "a causa raiz aparece no log"
  },
  {
   "id": "depuracao-promise-rejeitada-sem-tratamento",
   "nome": "Promise rejeitada sem tratamento",
   "receita": "ative o evento unhandledrejection e adicione catch ou try/await no ponto certo",
   "prova": "nenhum aviso de rejeição não tratada"
  },
  {
   "id": "depuracao-await-esquecido",
   "nome": "Await esquecido",
   "receita": "procure funções async chamadas sem await que devolvem Promise; use lint (no-floating-promises)",
   "prova": "o lint zerado e o valor chega pronto"
  },
  {
   "id": "depuracao-funcao-async-dentro-de-foreach",
   "nome": "Função async dentro de forEach",
   "receita": "troque por for...of com await, ou Promise.all com map",
   "prova": "os itens processados na ordem pretendida"
  },
  {
   "id": "depuracao-condicao-de-corrida",
   "nome": "Condição de corrida",
   "receita": "registre a ordem dos eventos com timestamps, force o intervalo com sleep e proteja com trava, fila ou operação atômica",
   "prova": "100 execuções concorrentes sem inconsistência"
  },
  {
   "id": "depuracao-estado-compartilhado-mutado",
   "nome": "Estado compartilhado mutado",
   "receita": "procure objeto global ou default mutável; copie ou torne imutável",
   "prova": "duas chamadas seguidas não afetam uma à outra"
  },
  {
   "id": "depuracao-cache-servindo-dado-velho",
   "nome": "Cache servindo dado velho",
   "receita": "desligue o cache para confirmar, depois cheque chave, TTL e invalidação",
   "prova": "o dado novo aparece após a escrita"
  },
  {
   "id": "depuracao-dado-antigo-no-navegador",
   "nome": "Dado antigo no navegador",
   "receita": "teste em janela anônima e com cache desativado; confira cabeçalhos Cache-Control e service worker",
   "prova": "sem cache o comportamento está correto"
  },
  {
   "id": "depuracao-service-worker-prendendo-versao-antiga",
   "nome": "Service worker prendendo versão antiga",
   "receita": "Application, Service Workers, Unregister, e versione o cache",
   "prova": "a nova versão carrega depois de atualizar"
  },
  {
   "id": "depuracao-funciona-no-meu-computador",
   "nome": "Funciona no meu computador",
   "receita": "compare versões (Node, SO), lockfile, variáveis de ambiente e fuso horário",
   "prova": "as duas máquinas dão o mesmo resultado"
  },
  {
   "id": "depuracao-diferenca-entre-dev-e-build",
   "nome": "Diferença entre dev e build",
   "receita": "rode o build de produção localmente e compare minificação, variáveis e SSR",
   "prova": "o erro reproduz com o build local"
  },
  {
   "id": "depuracao-variavel-de-ambiente-indefinida",
   "nome": "Variável de ambiente indefinida",
   "receita": "imprima quais chaves existem (sem valores), confira onde o .env é lido e o prefixo exigido (NEXT_PUBLIC_, VITE_)",
   "prova": "a variável aparece com o valor esperado"
  },
  {
   "id": "depuracao-porta-ocupada-ao-iniciar",
   "nome": "Porta ocupada ao iniciar",
   "receita": "ache o processo com lsof -i :PORTA e encerre, ou mude a porta",
   "prova": "o servidor inicia sem EADDRINUSE"
  },
  {
   "id": "depuracao-permissao-negada-em-arquivo",
   "nome": "Permissão negada em arquivo",
   "receita": "ls -l para dono e modo; confira o usuário do processo",
   "prova": "o processo lê e escreve o arquivo"
  },
  {
   "id": "depuracao-caminho-relativo-quebrado",
   "nome": "Caminho relativo quebrado",
   "receita": "imprima process.cwd() e __dirname; monte o caminho a partir de __dirname",
   "prova": "o arquivo é encontrado de qualquer diretório"
  },
  {
   "id": "depuracao-importacao-circular",
   "nome": "Importação circular",
   "receita": "procure o ciclo (madge) e mova o código compartilhado para um terceiro módulo",
   "prova": "o madge sem ciclos e o undefined sumiu"
  },
  {
   "id": "depuracao-versao-de-dependencia-incompativel",
   "nome": "Versão de dependência incompatível",
   "receita": "npm ls pacote mostra duplicatas; alinhe versões e use overrides",
   "prova": "uma única versão na árvore"
  },
  {
   "id": "depuracao-lockfile-desatualizado",
   "nome": "Lockfile desatualizado",
   "receita": "apague node_modules e instale com npm ci",
   "prova": "a instalação reproduz a árvore do lockfile"
  },
  {
   "id": "depuracao-erro-de-tipo-no-typescript",
   "nome": "Erro de tipo no TypeScript",
   "receita": "leia o primeiro erro, não o último; corrija a origem do tipo, não com any",
   "prova": "tsc --noEmit sem erros"
  },
  {
   "id": "depuracao-tipo-diz-uma-coisa-e-o-dado-outra",
   "nome": "Tipo diz uma coisa e o dado outra",
   "receita": "valide o dado externo em tempo de execução (zod) e derive o tipo do schema",
   "prova": "o dado inválido é recusado na borda"
  },
  {
   "id": "depuracao-nan-ou-infinity-inesperado",
   "nome": "NaN ou Infinity inesperado",
   "receita": "rastreie a operação (divisão por zero, parseInt de texto) e valide antes de calcular",
   "prova": "a conta com a entrada ruim retorna erro claro"
  },
  {
   "id": "depuracao-comparacao-que-falha",
   "nome": "Comparação que falha",
   "receita": "cheque tipos (== versus ===), espaços, caixa e Unicode (normalize); imprima com JSON.stringify",
   "prova": "a comparação verdadeira com o dado real"
  },
  {
   "id": "depuracao-ordenacao-estranha",
   "nome": "Ordenação estranha",
   "receita": "sort numérico precisa de comparador (a,b)=>a-b; texto com localeCompare",
   "prova": "a ordem correta com números e acentos"
  },
  {
   "id": "depuracao-fuso-horario-errado",
   "nome": "Fuso horário errado",
   "receita": "guarde em UTC, converta só na exibição, e confira o fuso do servidor e do navegador",
   "prova": "a mesma hora correta em dois fusos"
  },
  {
   "id": "depuracao-hora-de-verao",
   "nome": "Hora de verão",
   "receita": "teste datas de transição de horário; use biblioteca de datas com fuso (Temporal, luxon)",
   "prova": "soma de 24 h não vira 23 nem 25 sem querer"
  },
  {
   "id": "depuracao-arredondamento-monetario",
   "nome": "Arredondamento monetário",
   "receita": "use inteiros em centavos ou decimal; arredonde só no fim, com a regra definida",
   "prova": "a soma das parcelas bate com o total"
  },
  {
   "id": "depuracao-ponto-flutuante",
   "nome": "Ponto flutuante",
   "receita": "0.1+0.2 não é 0.3; compare com tolerância ou use decimal",
   "prova": "o teste usa toBeCloseTo ou aritmética decimal"
  },
  {
   "id": "depuracao-encoding-quebrado",
   "nome": "Encoding quebrado",
   "receita": "identifique a codificação (file -i) e converta para UTF-8 na entrada e declare charset",
   "prova": "os acentos corretos em tela e banco"
  },
  {
   "id": "depuracao-json-invalido",
   "nome": "JSON inválido",
   "receita": "valide com jq . e olhe o caractere do erro (vírgula sobrando, aspas simples, BOM)",
   "prova": "o parse funciona e o erro aponta a linha certa"
  },
  {
   "id": "depuracao-regex-que-trava",
   "nome": "Regex que trava",
   "receita": "procure quantificadores aninhados; use âncoras e limite; teste com entrada longa",
   "prova": "a regex responde em milissegundos na entrada hostil"
  },
  {
   "id": "depuracao-loop-infinito",
   "nome": "Loop infinito",
   "receita": "adicione contador de segurança, logue a condição de saída e reproduza com entrada mínima",
   "prova": "o laço termina com a condição correta"
  },
  {
   "id": "depuracao-recursao-sem-fim",
   "nome": "Recursão sem fim",
   "receita": "confira o caso base e se o argumento se aproxima dele a cada chamada",
   "prova": "a pilha não estoura na entrada máxima"
  },
  {
   "id": "depuracao-estouro-de-memoria",
   "nome": "Estouro de memória",
   "receita": "tire um heap snapshot, compare dois e ache o que cresce; limite caches",
   "prova": "a memória estabiliza após carga repetida"
  },
  {
   "id": "depuracao-vazamento-de-listener",
   "nome": "Vazamento de listener",
   "receita": "registre quantos listeners existem e remova no cleanup",
   "prova": "o contador volta ao valor inicial"
  },
  {
   "id": "depuracao-vazamento-de-conexoes",
   "nome": "Vazamento de conexões",
   "receita": "conte conexões abertas do pool e garanta close/release em finally",
   "prova": "o pool volta ao total livre após as requisições"
  },
  {
   "id": "depuracao-descritores-de-arquivo-esgotados",
   "nome": "Descritores de arquivo esgotados",
   "receita": "lsof -p PID | wc -l e feche os streams; suba o limite (ulimit -n) só depois",
   "prova": "o número de arquivos abertos estável"
  },
  {
   "id": "depuracao-cpu-em-100",
   "nome": "CPU em 100%",
   "receita": "capture um perfil (node --cpu-prof, py-spy, perf), ache a função quente",
   "prova": "o perfil mostra a função e o tempo cai após a correção"
  },
  {
   "id": "depuracao-lentidao-que-so-aparece-com-dados-reais",
   "nome": "Lentidão que só aparece com dados reais",
   "receita": "teste com volume parecido com produção e leia o EXPLAIN das consultas",
   "prova": "o tempo com dados reais dentro do orçamento"
  },
  {
   "id": "depuracao-requisicao-que-demora",
   "nome": "Requisição que demora",
   "receita": "separe o tempo (DNS, conexão, servidor, download) com curl -w e logs de cada etapa",
   "prova": "a etapa lenta identificada"
  },
  {
   "id": "depuracao-timeout-intermitente",
   "nome": "Timeout intermitente",
   "receita": "registre o id da requisição, cheque pool esgotado, DNS e dependência lenta",
   "prova": "o log mostra onde ficou parado"
  },
  {
   "id": "depuracao-erro-500-sem-pista",
   "nome": "Erro 500 sem pista",
   "receita": "procure o requestId nos logs do servidor, reproduza com o mesmo corpo e habilite a pilha em dev",
   "prova": "a exceção que gerou o 500"
  },
  {
   "id": "depuracao-erro-401-ou-403",
   "nome": "Erro 401 ou 403",
   "receita": "compare o token enviado, expiração, escopo, relógio e cabeçalho; confira a autorização do recurso",
   "prova": "a requisição com o token certo retorna 200"
  },
  {
   "id": "depuracao-erro-404-estranho",
   "nome": "Erro 404 estranho",
   "receita": "confira a rota, a barra final, o prefixo e a base da URL e o método",
   "prova": "a URL exata aparece no log do servidor"
  },
  {
   "id": "depuracao-erro-429",
   "nome": "Erro 429",
   "receita": "leia Retry-After, reduza a taxa, adicione backoff e cache",
   "prova": "as chamadas respeitam o limite sem perder dados"
  },
  {
   "id": "depuracao-erro-502-ou-504",
   "nome": "Erro 502 ou 504",
   "receita": "verifique se o serviço de trás está de pé, timeouts do proxy e tempo da aplicação",
   "prova": "o proxy alcança o serviço e responde 200"
  },
  {
   "id": "depuracao-redirecionamento-em-laco",
   "nome": "Redirecionamento em laço",
   "receita": "siga com curl -IL; confira HTTPS forçado em dois lugares e cookies",
   "prova": "a cadeia termina em 200"
  },
  {
   "id": "depuracao-cookie-que-nao-grava",
   "nome": "Cookie que não grava",
   "receita": "veja SameSite, Secure, domínio e caminho e se o navegador bloqueia terceiros",
   "prova": "o cookie aparece em Application, Cookies"
  },
  {
   "id": "depuracao-sessao-que-cai-sozinha",
   "nome": "Sessão que cai sozinha",
   "receita": "confira expiração, armazenamento da sessão entre instâncias e segredo igual em todas",
   "prova": "a sessão persiste após reiniciar uma instância"
  },
  {
   "id": "depuracao-cors-que-ainda-bloqueia",
   "nome": "CORS que ainda bloqueia",
   "receita": "o erro vem do navegador: confira origem exata, preflight e cabeçalhos permitidos na resposta",
   "prova": "a aba Network mostra o Access-Control-Allow-Origin certo"
  },
  {
   "id": "depuracao-mixed-content",
   "nome": "Mixed content",
   "receita": "troque URLs http por https ou relativas",
   "prova": "console sem aviso de mixed content"
  },
  {
   "id": "depuracao-hidratacao-divergente",
   "nome": "Hidratação divergente",
   "receita": "o HTML do servidor difere do cliente: remova dado dependente de tempo, aleatório e window no render",
   "prova": "sem aviso de hydration mismatch"
  },
  {
   "id": "depuracao-react-re-renderiza-demais",
   "nome": "React re-renderiza demais",
   "receita": "use o Profiler, ache a prop instável e estabilize; mova o estado",
   "prova": "menos renderizações no mesmo gesto"
  },
  {
   "id": "depuracao-useeffect-em-laco",
   "nome": "useEffect em laço",
   "receita": "confira dependências, objetos recriados e setState no efeito",
   "prova": "o efeito roda a quantidade esperada de vezes"
  },
  {
   "id": "depuracao-estado-que-nao-atualiza",
   "nome": "Estado que não atualiza",
   "receita": "setState é assíncrono e guarda cópia; use a forma funcional e novas referências",
   "prova": "a interface reflete a mudança"
  },
  {
   "id": "depuracao-evento-que-dispara-duas-vezes",
   "nome": "Evento que dispara duas vezes",
   "receita": "modo estrito em dev, listener duplicado ou submit duplo; remova o duplicado",
   "prova": "um clique gera uma chamada"
  },
  {
   "id": "depuracao-css-que-nao-aplica",
   "nome": "CSS que não aplica",
   "receita": "inspecione o seletor vencedor, especificidade e ordem; cheque o carregamento do arquivo",
   "prova": "o computed mostra o valor desejado"
  },
  {
   "id": "depuracao-layout-quebrado-em-um-navegador",
   "nome": "Layout quebrado em um navegador",
   "receita": "isole o trecho, teste no navegador, veja prefixos e suporte (caniuse)",
   "prova": "o layout idêntico nos dois"
  },
  {
   "id": "depuracao-z-index-que-nao-funciona",
   "nome": "z-index que não funciona",
   "receita": "o contexto de empilhamento é criado por transform, opacity e position; ajuste o pai",
   "prova": "o elemento passa à frente"
  },
  {
   "id": "depuracao-fonte-nao-carrega",
   "nome": "Fonte não carrega",
   "receita": "confira o caminho, o CORS do arquivo, formato e font-face",
   "prova": "a aba Network com 200 na fonte"
  },
  {
   "id": "depuracao-imagem-nao-aparece",
   "nome": "Imagem não aparece",
   "receita": "status na Network, caminho relativo, content-type e permissão do bucket",
   "prova": "a imagem renderiza com 200"
  },
  {
   "id": "depuracao-teste-passa-sozinho-e-falha-em-conjunto",
   "nome": "Teste passa sozinho e falha em conjunto",
   "receita": "ache o estado compartilhado (banco, global, mock não restaurado) e limpe em afterEach",
   "prova": "a suíte inteira passa em ordem aleatória"
  },
  {
   "id": "depuracao-mock-que-vaza-entre-testes",
   "nome": "Mock que vaza entre testes",
   "receita": "restaure mocks (restoreAllMocks) e crie dublês dentro de cada teste",
   "prova": "o resultado independe da ordem"
  },
  {
   "id": "depuracao-teste-falha-so-no-ci",
   "nome": "Teste falha só no CI",
   "receita": "compare versões, fuso, locale, paralelismo e variáveis; rode no mesmo container",
   "prova": "o mesmo comando falha ou passa nos dois lugares"
  },
  {
   "id": "depuracao-snapshot-quebrado",
   "nome": "Snapshot quebrado",
   "receita": "leia o diff, decida se é regressão ou mudança intencional e atualize só nesse caso",
   "prova": "o diff explicado no PR"
  },
  {
   "id": "depuracao-cobertura-enganosa",
   "nome": "Cobertura enganosa",
   "receita": "linhas executadas não são linhas verificadas; adicione asserções e teste de mutação",
   "prova": "o mutante que sobrevivia agora é detectado"
  },
  {
   "id": "depuracao-migracao-falhou-no-meio",
   "nome": "Migração falhou no meio",
   "receita": "leia o erro, confira o estado do schema, desfaça manualmente e reaplique",
   "prova": "o schema_migrations consistente e o app sobe"
  },
  {
   "id": "depuracao-deadlock-no-banco",
   "nome": "Deadlock no banco",
   "receita": "leia o log do banco para as duas transações, padronize a ordem de acesso",
   "prova": "sem deadlock sob carga paralela"
  },
  {
   "id": "depuracao-constraint-violada",
   "nome": "Constraint violada",
   "receita": "veja qual restrição e que dado a causou; corrija o dado ou a regra",
   "prova": "a inserção válida passa e a inválida erra com mensagem clara"
  },
  {
   "id": "depuracao-consulta-retorna-dado-a-mais-ou-a-menos",
   "nome": "Consulta retorna dado a mais ou a menos",
   "receita": "imprima a SQL e rode no console; confira joins, WHERE, NULL e duplicatas",
   "prova": "a contagem bate com o esperado"
  },
  {
   "id": "depuracao-join-que-multiplica-linhas",
   "nome": "Join que multiplica linhas",
   "receita": "confira o grão das tabelas e use agregação antes de juntar",
   "prova": "o total não infla"
  },
  {
   "id": "depuracao-dado-duplicado",
   "nome": "Dado duplicado",
   "receita": "procure a origem (retry sem idempotência, corrida) e crie restrição única",
   "prova": "inserção repetida falha ou é ignorada"
  },
  {
   "id": "depuracao-fila-acumulando",
   "nome": "Fila acumulando",
   "receita": "compare taxa de entrada e saída, workers vivos e jobs presos",
   "prova": "o tamanho da fila volta a zero"
  },
  {
   "id": "depuracao-job-executou-duas-vezes",
   "nome": "Job executou duas vezes",
   "receita": "torne idempotente e use chave de deduplicação",
   "prova": "duas execuções com o mesmo efeito de uma"
  },
  {
   "id": "depuracao-webhook-nao-chega",
   "nome": "Webhook não chega",
   "receita": "confira URL pública, assinatura, resposta 2xx e o painel de entregas do provedor",
   "prova": "o evento de teste registrado"
  },
  {
   "id": "depuracao-e-mail-nao-chega",
   "nome": "E-mail não chega",
   "receita": "SPF, DKIM, spam, endereço e o log do provedor",
   "prova": "o e-mail de teste na caixa de entrada"
  },
  {
   "id": "depuracao-upload-falha",
   "nome": "Upload falha",
   "receita": "limite de tamanho do proxy e do app, tipo, tempo e permissão no destino",
   "prova": "o arquivo grande chega inteiro"
  },
  {
   "id": "depuracao-download-corrompido",
   "nome": "Download corrompido",
   "receita": "compare tamanho e checksum; cheque content-length, encoding e transferência parcial",
   "prova": "o hash do arquivo baixado igual ao da origem"
  },
  {
   "id": "depuracao-docker-nao-sobe",
   "nome": "Docker não sobe",
   "receita": "docker logs, docker inspect e rodar o comando na mão dentro da imagem",
   "prova": "o container permanece em Running"
  },
  {
   "id": "depuracao-container-sem-rede",
   "nome": "Container sem rede",
   "receita": "nome do serviço na rede do compose, porta certa e o host (não localhost)",
   "prova": "um curl dentro do container responde"
  },
  {
   "id": "depuracao-imagem-muito-grande",
   "nome": "Imagem muito grande",
   "receita": "docker history mostra a camada pesada; multi-stage e .dockerignore",
   "prova": "o tamanho cai (docker images)"
  },
  {
   "id": "depuracao-build-lento",
   "nome": "Build lento",
   "receita": "meça por etapa, cache de dependências e paralelização",
   "prova": "o tempo total cai"
  },
  {
   "id": "depuracao-erro-so-em-um-sistema-operacional",
   "nome": "Erro só em um sistema operacional",
   "receita": "caminhos, fim de linha, maiúsculas e minúsculas no nome e permissões",
   "prova": "o mesmo teste verde nos dois sistemas"
  },
  {
   "id": "depuracao-erro-de-certificado",
   "nome": "Erro de certificado",
   "receita": "confira a cadeia (openssl s_client), data do certificado, hora do sistema e CA",
   "prova": "o handshake completa sem erro"
  },
  {
   "id": "depuracao-erro-de-dns",
   "nome": "Erro de DNS",
   "receita": "dig e nslookup contra resolvedores diferentes e confira /etc/hosts",
   "prova": "o nome resolve para o IP esperado"
  },
  {
   "id": "depuracao-programa-congelado",
   "nome": "Programa congelado",
   "receita": "capture uma pilha das threads (jstack, py-spy dump, kill -QUIT) e ache o ponto de espera",
   "prova": "o ponto de bloqueio identificado"
  },
  {
   "id": "depuracao-crash-sem-mensagem",
   "nome": "Crash sem mensagem",
   "receita": "rode com handlers de uncaughtException, código de saída e core dump habilitados",
   "prova": "a causa registrada antes de encerrar"
  },
  {
   "id": "depuracao-bug-que-sumiu-ao-logar",
   "nome": "Bug que sumiu ao logar",
   "receita": "suspeite de tempo (corrida) ou valor com efeito colateral no log; use depurador",
   "prova": "a causa explicada e o bug reproduzível"
  },
  {
   "id": "depuracao-bisect-automatizado",
   "nome": "Bisect automatizado",
   "receita": "git bisect run script que sai com 0 ou 1",
   "prova": "o primeiro commit ruim apontado sozinho"
  },
  {
   "id": "depuracao-escrever-o-relato-de-bug",
   "nome": "Escrever o relato de bug",
   "receita": "passos, esperado, obtido, versão, ambiente e log mínimo",
   "prova": "outra pessoa reproduz em 5 minutos"
  },
  {
   "id": "depuracao-hipotese-por-vez",
   "nome": "Hipótese por vez",
   "receita": "escreva a hipótese, o teste que a derruba e o resultado; descarte e siga",
   "prova": "a lista de hipóteses testadas e a vencedora"
  },
  {
   "id": "depuracao-explicar-o-bug-ao-pato",
   "nome": "Explicar o bug ao pato",
   "receita": "descreva em voz alta o que o código deveria fazer, linha por linha",
   "prova": "a divergência apontada"
  },
  {
   "id": "depuracao-depurador-passo-a-passo",
   "nome": "Depurador passo a passo",
   "receita": "ponto de parada condicional, inspeção de variáveis e pilha",
   "prova": "o valor errado visto no instante em que surge"
  },
  {
   "id": "depuracao-log-temporario-e-remocao",
   "nome": "Log temporário e remoção",
   "receita": "use um prefixo único para os logs de depuração e apague todos antes de commitar",
   "prova": "grep do prefixo não encontra nada"
  },
  {
   "id": "depuracao-postmortem-curto",
   "nome": "Postmortem curto",
   "receita": "linha do tempo, causa raiz, o que detectou, o que corrige e como evitar",
   "prova": "documento com ações e responsáveis"
  }
 ]
}
