Claude Code em código legado sem testes: por onde começar sem quebrar o que já funciona

Usar Claude Code em código legado pede uma ordem diferente: entender, provar e só então mudar. Antes do primeiro prompt, deixe a árvore do git limpa, isole o trabalho com claude –worktree nome e revise as regras em /permissions (a avaliação é deny, depois ask, depois allow). Aí explore em plan mode (Shift+Tab), use o subagent Explore pra ler, rode /init pra gerar o CLAUDE.md e fixe o comportamento atual com um characterization test antes de qualquer refatoração. Se algo escapar, /rewind desfaz edições feitas pelas ferramentas de edição de arquivo, mas não desfaz comando bash.
Fala aí, beleza? Todo mundo já sentiu aquele frio na barriga de abrir um projeto de anos atrás, sem teste nenhum, e ter que mudar UMA coisinha lá dentro
O medo não é da mudança em si
O medo é não conseguir provar que o resto continua funcionando depois dela
O Michael Feathers, no livro Working Effectively with Legacy Code, define código legado de um jeito bem seco: é código sem testes. E o raciocínio dele é direto, sem teste você não tem como saber se a sua mudança melhorou ou piorou o comportamento do sistema
Isso vira o jogo na hora de usar Claude Code em código legado. Não é que a IA seja perigosa ali, é que a base não tem rede de proteção nenhuma, então a ordem de trabalho tem que mudar: entender antes de mexer, criar prova antes de refatorar
Bora ver na prática? 🙂
O que preparar antes de soltar o Claude Code no projeto antigo
Essa parte vem antes por um motivo simples: sem esses freios, nada do resto do post segura nada
É igual mexer em fiação velha, tu desliga o disjuntor primeiro
1. Repositório versionado e árvore limpa. Se o git status não estiver limpo, você perde a única régua confiável pra saber o que foi a IA e o que já era seu. Commita ou guarda o que estiver pendente antes de começar
2. Isole o trabalho num worktree. O próprio Claude Code faz isso pra você: passando --worktree (ou o atalho -w) com um nome, ele cria um worktree isolado e já inicia a sessão nele
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 120 aulas
- 4 projetos
- 9h 48min
claude --worktree modulo-cobranca
Por padrão esse worktree é criado em .claude/worktrees/<nome>/ na raiz do repositório, num branch novo chamado worktree-<nome>. Ou seja, o que a sessão fizer não encosta no seu branch de trabalho
3. Leve os arquivos gitignored junto. Projeto antigo quase sempre depende de um .env que nunca foi versionado. Criando um arquivo .worktreeinclude, os arquivos ignorados pelo git (o .env, por exemplo) passam a ser carregados automaticamente em todo worktree novo
4. Revise as permissões ANTES do primeiro prompt. O comando /permissions abre a interface que lista todas as regras ativas e mostra de qual arquivo settings.json cada uma veio. As permissões ficam em arquivos .claude/settings.json, com listas de allow e deny
E tem um detalhe que vale ouro em base legada: as regras são avaliadas na ordem deny, depois ask, depois allow. O primeiro match nessa ordem decide, e a especificidade da regra NÃO muda essa ordem
Se você ainda está dando os primeiros passos e quer um caminho pra aprender o Claude Code do zero, vale fechar essa base antes de encarar um projeto sem testes
Passo a passo: a ordem de trabalho em uma base sem testes
A espinha da sequência é o fluxo recomendado na documentação oficial de boas práticas: Explore, Plan, Code, Commit. A doc justifica separar pesquisa e planejamento da implementação por um motivo bem prático, evitar que o Claude saia resolvendo o problema errado
Em legado isso pesa o dobro, porque o problema errado ali costuma ser caro
1. Explorar sem poder editar: plan mode
O primeiro contato com a base tem que ser somente leitura. Pra isso existe o plan mode, e dá pra entrar nele de três jeitos:
- apertando
Shift+Tabaté a barra de status mostrar o plan mode ativo - prefixando um prompt único com
/plan - iniciando a sessão já nele
claude --permission-mode plan
Nesse modo o Claude lê arquivos, roda comandos de exploração e escreve um plano, mas não edita o código-fonte. Comandos fora do conjunto read-only embutido pedem aprovação, inclusive com o auto-allow do sandbox ligado
E se o plano vier ruim? Shift+Tab de novo sai do plan mode sem aprovar o plano
O erro comum deste passo: achar que sair do plan mode significa aceitar o que foi proposto. Não significa. Sair e aprovar são coisas diferentes, e em legado é bem comum descartar o primeiro plano inteiro
2. Fan-out de leitura com o subagent Explore
Base antiga é grande e cheia de arquivo morto. Ler tudo na sessão principal entope o contexto rápido
O Claude Code traz tipos de subagent embutidos, e entre eles está o Explore, otimizado pra busca rápida e somente leitura no código. Cada subagent roda no próprio context window, com system prompt próprio, acesso a ferramentas específico e permissões independentes. Quando termina, o que volta pra sessão principal é só a mensagem final mais metadados
É como mandar um estagiário ler o arquivo de 4 mil linhas e voltar com o resumo, em vez de despejar as 4 mil linhas na sua mesa
O erro comum deste passo: assumir que o subagent conhece as convenções do projeto. Explore e Plan são os únicos subagents que omitem o CLAUDE.md e o git status. Então o contexto que ele precisa (nome do módulo, pasta, o que você suspeita) vai TODO no prompt, escrito na mão
3. Gravar o mapa num CLAUDE.md

VPS Hostinger para seu sistema
10% OFF extraVPS com SSD NVMe e backups semanais. O cupom MATHEUSHORADECODAR é aplicado automaticamente pelo link.
Ver planos com 10% OFF →Descobriu como o projeto funciona? Grava, senão você vai redescobrir amanhã
/init
O /init analisa a base (arquivos de pacote, documentação existente, arquivos de configuração e estrutura do código) e gera um CLAUDE.md inicial com comandos de build, instruções de teste, diretórios-chave e convenções detectadas
O CLAUDE.md do projeto pode ficar em ./CLAUDE.md ou em ./.claude/CLAUDE.md. E pra aquelas preferências suas que não devem ir pro versionamento, cria um CLAUDE.local.md na raiz e adiciona ele ao .gitignore
Vale saber COMO isso é carregado: os arquivos CLAUDE.md e CLAUDE.local.md na hierarquia de diretórios acima do diretório de trabalho entram por inteiro no início da sessão, enquanto os de subdiretórios carregam sob demanda, quando o Claude lê arquivos daqueles diretórios
O erro comum deste passo: despejar preferência pessoal ("sempre me responda em português", "eu odeio tal padrão") no arquivo versionado, que o time inteiro vai carregar em toda sessão. Isso é vida de CLAUDE.local.md
4. Fixar o comportamento atual com characterization test
Aqui é o passo que quase todo mundo pula, e é o mais importante
Characterization test é um conceito do Feathers: é um teste que caracteriza o comportamento REAL do código hoje. Ele não verifica se o código está correto, ele só fixa o que a coisa faz atualmente, servindo pra preservar e documentar o comportamento existente antes da mudança
Ou seja, ele não julga. Ele fotografa
O prompt muda de cara quando você entende isso:
Escreva testes que capturem o comportamento ATUAL da função
calculaDesconto, incluindo os casos esquisitos e os que parecem
errados. Não corrija nada. Se o retorno de hoje for estranho,
o teste deve esperar esse retorno estranho mesmo assim.
O erro comum deste passo: pedir "escreva testes pra esse módulo" e aceitar o que vier. Você recebe teste do comportamento IDEAL, ele falha na primeira rodada, e aí você vai "consertar" o código antes de ter qualquer prova do que ele fazia. Exatamente a ordem invertida
5. Planejar a mudança e EDITAR o plano
Com o mapa gravado e o comportamento fotografado, aí sim volta pro plan mode e pede o plano da mudança
E não precisa aceitar o plano como veio: Ctrl+G abre o plano no editor de texto pra edição direta, antes do Claude prosseguir
Tome cuidado aqui! Em legado, corrigir uma linha do plano custa segundos, corrigir a mesma linha depois de virar código espalhado em oito arquivos custa a tarde
O erro comum deste passo: aprovar um plano que menciona "limpar", "padronizar" ou "aproveitar e ajustar" coisas que você não pediu. Corta isso do plano com Ctrl+G e deixa pra outra sessão
6. Abrir o /rewind antes de refatorar, mudar em fatia pequena e commitar
Antes de aprovar a primeira fatia de refatoração, abre o botão de emergência e olha ele com calma: rodar /rewind, ou apertar Esc duas vezes com o campo de prompt vazio, abre o menu de rewind
Ele lista cada prompt enviado na sessão, e ao escolher um ponto você tem quatro ações: restaurar código e conversa, restaurar conversa, restaurar código, ou resumir a partir dali
Fazer isso ANTES muda o tamanho da fatia que você se permite arriscar, porque você já sabe até onde consegue voltar (os limites do checkpointing eu abro logo abaixo, e eles são bem específicos)
Aí sim vem a última fase do fluxo oficial, o Commit, que existe pra fechar o ciclo em pedaços pequenos: uma fatia, teste rodando, commit
Depois volta pro Explore da próxima fatia
Quanto menor a fatia, mais barato é o "opa, não era isso"
O erro comum deste passo: deixar cinco mudanças acumularem sem commit intermediário, porque "tá indo bem". Aí quando quebra, você não tem ponto de retorno limpo e o histórico não te ajuda a achar o culpado
O que delegar de cara e o que jamais delegar de primeira
A régua aqui não é confiança, é reversibilidade
Tarefa que a ferramenta consegue desfazer, ou que nem toca no fonte, entra cedo. Tarefa cujo estrago mora FORA do sistema de arquivos fica pra depois, quando já existe teste protegendo
| Tarefa | Delega de cara? | Por quê |
|---|---|---|
| Ler e explicar um módulo | Sim | plan mode não edita o fonte |
| Mapear dependências e chamadas | Sim | leitura pura, cabe no subagent Explore |
| Rascunhar characterization test | Sim, revisando | teste novo é arquivo novo, fácil de descartar |
| Resumir o que um script antigo faz | Sim | não muda nada, só te dá contexto |
| Migração de esquema de banco | Não | o efeito não vive no sistema de arquivos |
| Script destrutivo em arquivo ou dado | Não | os rm -rf da vida não perdoam |
| Comando de infraestrutura | Não | precisa de regra deny e aprovação humana |
| Mudar comportamento sem teste que o proteja | Não | é exatamente o que o passo 4 existe pra evitar |

Crie sistemas com IA para vender
Prompts, modelos e checklists para criar e publicar seu sistema com IA e preparar a oferta para o primeiro cliente.
Quero o e-book gratuito Receba o livro e os bônus no seu e-mail.Essa separação não é achismo, ela se apoia no que a ferramenta garante de verdade
O plan mode garante que o fonte não é editado. O checkpointing garante o retorno das edições feitas pelas ferramentas de edição de arquivo do Claude, e só delas. E uma regra deny ampla barra família inteira de comando: um Bash(aws *) no deny bloqueia toda chamada que casa, INCLUSIVE as que também casam com um allow mais estreito tipo Bash(aws s3 ls). A mesma precedência vale entre ask e allow
Repara no que sobra de fora dessas três garantias: banco de dados, chamada de API, arquivo mexido na mão. É bem aí que mora o que você não delega de primeira
Quando a base já tiver teste segurando o comportamento, a conversa muda de figura e dá pra partir pra refatorar um projeto legado com muito mais folga
Quando algo dá errado: sintomas comuns e como voltar atrás
Vai dar errado alguma hora, e tudo bem. O que não pode é você descobrir o botão de emergência DEPOIS de precisar dele
Sintoma: "quero desfazer o que ele acabou de fazer"
Causa: uma sequência de edições que pareceu boa nos primeiros dois arquivos e azedou no terceiro
Solução: aquele menu de rewind do passo 6, agora valendo. Escolhe o prompt anterior ao estrago e decide entre restaurar código e conversa, restaurar conversa, restaurar código, ou resumir a partir dali
Agora os limites duros, e eles são importantes: os checkpoints cobrem APENAS as edições feitas pelas ferramentas de edição de arquivo do Claude. Edições que você fez na mão e comandos bash não são rastreados
Tem mais: ao escolher restaurar código (ou código e conversa), o Claude Code pula qualquer caminho rastreado que seja symlink ou hard link, e mostra um aviso. E os checkpoints não são eternos, eles são apagados junto com as sessões depois de 30 dias
Como prevenir: commit pequeno e frequente, como no passo 6. O rewind é rede de segurança da sessão, não substituto de git
Sintoma: "o Claude parou de entender o projeto"
Causa: contexto lotado. Depois de horas lendo arquivo velho e log gigante, o histórico da conversa vira uma pilha de coisa que já não importa
Solução: começa medindo. O comando /context mostra um detalhamento ao vivo por categoria, com sugestões de otimização, incluindo quais arquivos CLAUDE.md e de memória automática foram carregados
Com isso na mão, você escolhe:
/compactresume a conversa até ali e substitui o histórico por esse resumo, liberando contexto. Ele aceita opcionalmente instruções de foco pro resumo, tipo pedir pra manter o que foi descoberto sobre um módulo específico/clearinicia uma conversa nova com contexto vazio. A anterior continua acessível pelo/resume, e o CLAUDE.md e os arquivos do projeto seguem disponíveis, só o histórico de chat sai
Como prevenir: o passo 3 de novo. Descoberta que está gravada no CLAUDE.md sobrevive ao /clear, descoberta que só existe no chat morre com ele
Sintoma: "ele rodou um comando que eu não queria"
Causa: regra de permissão frouxa, ou allow que você achou que estivesse coberto por algo mais específico
Solução: abre o /permissions e olha de qual settings.json a regra veio. Lembrando da ordem: deny, depois ask, depois allow, primeiro match decide
Pra caso que exige lógica, e não só padrão de texto, dá pra usar hook. Em hooks PreToolUse, o exit code 2 bloqueia a chamada da ferramenta e o stderr vira a mensagem de erro. O PreToolUse também permite allow, deny, ask ou defer da chamada
E aqui vai a pegadinha que morde geral: sem JSON válido no stdout, o Claude Code trata o exit code 1 como erro NÃO bloqueante e segue com a ação, mesmo o 1 sendo o código de falha convencional no Unix. Se o seu hook de proteção sai com 1 achando que travou tudo, ele não travou nada… o número que bloqueia é o 2. E se o hook sai com 2, qualquer JSON é ignorado
Conclusão
A ordem é o conteúdo inteiro deste post: entender, provar, então mudar
Em base legada, a pressa de pular direto pro "muda isso aqui" é exatamente o que transforma uma tarefa de trinta minutos num dia inteiro caçando o que quebrou
Se quiser um próximo passo pequeno e concreto pra hoje: roda /init no projeto antigo, abre uma sessão em plan mode e sai dela com um characterization test do módulo que te dá mais medo
Sem encostar no código de produção
Só isso já te dá algo que o projeto não tinha ontem: prova
até o próximo post! 😀
Perguntas frequentes
Como desfazer uma alteração do Claude Code em código legado sem perder o histórico da conversa?
Rodando /rewind, ou apertando Esc duas vezes com o campo de prompt vazio, abre o menu de rewind. Ele lista cada prompt enviado na sessão e, ao escolher um ponto, dá pra restaurar código e conversa, só a conversa, só o código, ou resumir a sessão a partir dali.
O checkpointing do Claude Code cobre qualquer mudança feita no código legado?
Não. Os checkpoints cobrem só as edições feitas pelas ferramentas de edição de arquivo do próprio Claude, edição manual sua e comando bash não entram nesse rastro. Symlinks e hard links também ficam de fora: ao restaurar código, o Claude Code pula esses caminhos e avisa.
Por quanto tempo os checkpoints do Claude Code ficam disponíveis num projeto antigo?
30 dias. Depois desse prazo o Claude Code apaga os checkpoints junto com as sessões, então não dá pra contar com eles como backup de longo prazo.
Qual a diferença entre /clear e /compact ao mexer numa base sem testes?
/clear inicia uma conversa nova com contexto vazio, mas a conversa anterior continua acessível pelo /resume e o CLAUDE.md com os arquivos do projeto seguem disponíveis. Já o /compact resume o que já foi conversado e substitui o histórico por esse resumo, liberando espaço no contexto sem cortar o fio da meada.
O que é um characterization test e por que ele importa antes de refatorar código legado?
É um conceito do Michael Feathers: um teste que caracteriza o comportamento real do código hoje, sem julgar se esse comportamento está certo. Ele serve pra fixar e documentar o que o sistema faz atualmente, criando uma referência antes de qualquer mudança.
Dá para bloquear automaticamente uma ação arriscada do Claude Code num projeto sensível?
Sim, com um hook PreToolUse: se ele sair com exit code 2, a chamada da ferramenta é bloqueada e o stderr vira a mensagem de erro mostrada. Vale reparar que exit code 1 sem JSON válido no stdout NÃO bloqueia nada, o Claude Code trata como erro não bloqueante e segue com a ação.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 30min
Blog | Mais populares
Bateu o limite de uso do Claude Code? Como retomar a tarefa sem refazer tudo
Bateu o limite de uso do Claude Code? Veja como retomar a tarefa de onde parou com /usage, CLAUDE.md e --continue, sem refazer nada.
Como pagar o Claude Code no Brasil: cartão, dólar, IOF e quanto fica em reais
Claude Code preço Brasil na prática: câmbio, IOF de 3,5% e quanto fica na fatura. Planos Pro e Max convertidos em reais e como pagar com cartão.

O que é o JEV e para que ele serve no Claude Code?
O que é JEV no Claude Code? Entenda o modelo da TypeSafe AI, como instalar a skill e quanto custa por milhão de tokens.
