Ir para o conteúdo
14 de ago. de 2026·8 min de leitura

Como recuperar o conhecimento do código legado depois da saída do autor

Saiba como recuperar o conhecimento do código legado com análise da fonte, evidências de produção, testes de paridade e registro das perdas reais.

Como recuperar o conhecimento do código legado depois da saída do autor

Quando o autor de um sistema antigo sai, o conhecimento não desaparece em um único evento. Parte dele continua executável no código-fonte. Outra parte sobrevive apenas nos dados de produção, agendas, hábitos dos operadores e integrações. Algumas informações nunca foram registradas e se perderam. Uma reconstrução responsável separa essas classes, em vez de fingir que uma revisão bastante inteligente do código consegue recuperar tudo.

O objetivo não é explicar cada função. É reconstruir um relato apoiado por evidências sobre o que o sistema faz, qual comportamento sustenta a operação e onde ainda existe incerteza. Já vi equipes passarem meses anotando ramificações mortas enquanto o contrato real estava em uma entrega noturna de arquivos e na planilha de um contador. Comece pelas evidências, preserve as contradições e faça o substituto provar equivalência onde ela importa.

O código mostra o mecanismo, não o contrato inteiro

O código-fonte pode revelar fluxo de controle, transformações de dados, regras de validação, cálculos, formatos de mensagem, acesso ao banco e a ordem das chamadas a sistemas externos. Muitas vezes ele responde a perguntas precisas: quais estados interrompem a cobrança? Como os juros são arredondados? Quais campos tornam um registro apto para exportação? Quando uma nova tentativa termina? Esses fatos merecem extração automática.

O código sozinho não informa se uma regra observada é a política atual, uma solução antiga ou um defeito ao qual os usuários se adaptaram. Uma ramificação que aplica tratamento fiscal diferente à classe de cliente 17 prova que o programa faz isso. Não prova por que a classe 17 existe, se a exceção continua legal ou se alguém ainda cria esses clientes. Comentários raramente resolvem a questão. Eles podem descrever a regra pretendida quando foram escritos, enquanto a produção segue um caminho alterado há dez anos.

Mantenha três conceitos separados. Implementação é o que o código pode executar. Comportamento observado é o que o sistema implantado realmente fez com certas entradas e condições. Intenção de negócio é o motivo pelo qual alguém quis aquele resultado. Uma reescrita precisa dos dois primeiros para manter o serviço, mas apenas pessoas, políticas, contratos ou decisões da época podem estabelecer o terceiro. Confundir intenção com implementação transforma acidentes em requisitos. Ignorar o comportamento observado quebra consumidores que dependem desses acidentes.

Essa distinção também encerra a discussão comum sobre o código ser a especificação. O código tem autoridade sobre suas instruções possíveis, sujeito à configuração e às dependências de execução. As evidências de produção têm autoridade sobre quais possibilidades ocorreram. Nenhum dos dois prova o que deve acontecer no próximo ano. Atribua uma origem a cada afirmação em vez de obrigar um artefato a responder a todas as perguntas.

Mapeie as evidências antes de interpretar o programa

Um mapa de evidências deve identificar todos os lugares onde o comportamento pode ser observado ou limitado antes que alguém comece a escrever documentação narrativa. Caso contrário, o repositório mais fácil vira o centro da investigação, mesmo quando o comportamento de maior consequência está fora dele.

Organize as evidências em quatro grupos:

  • Material executável: fonte, scripts de compilação, JCL, procedimentos armazenados, expressões de relatórios, fórmulas de planilhas, código gerado e binários implantados.
  • Material de execução: configuração, sinalizadores de recursos, definições do agendador, variáveis de ambiente, esquemas de banco, filas, formatos de arquivo e pontos de acesso.
  • Observações: logs de solicitações, exemplos de mensagens, entradas e saídas em lote, alterações no banco, relatórios impressos, chamados de falha e manuais de operação.
  • Registros de autoridade: contratos, manuais de políticas, interpretações regulatórias, pedidos de mudança aprovados e decisões dos responsáveis pelo processo.

Registre origem, período, ambiente, responsável, retenção e lacunas conhecidas de cada item. Um log de produção sem sua versão de configuração pode enganar. Uma cópia do banco sem data de negócio pode fazer a lógica de fechamento parecer aleatória. Uma árvore de fontes sem o binário implantado não prova que o repositório corresponde à produção.

Use um registro pequeno de evidências, não um documento narrativo enorme:

claim: invoices with hold_code R are not exported
status: observed
evidence:
  - export_job.cob lines 1840-1868
  - nightly output sample 2024-01-16
  - scheduler definition AR_EXPORT
contradiction:
  - runbook says only hold_code L blocks export
owner_needed: accounts receivable
confidence: medium

A contradição é a parte útil. Não a resolva escolhendo o arquivo mais novo ou a pessoa mais confiante. Reproduza a entrada, siga a ramificação, confira saídas históricas e pergunte ao responsável pelo processo se a diferença reflete uma política ou uma deriva. O registro torna a disputa visível e oferece ao revisor posterior algo que pode ser refutado.

Defina regras de acesso e tratamento antes de tocar nos dados de produção. Capturas podem conter credenciais, dados pessoais, informações de pagamento ou texto confidencial. Reduza campos, oculte-os de forma consistente, restrinja o acesso às evidências brutas e guarde um mapeamento apenas quando a reprodução realmente exigir. A reconstrução não justifica criar um segundo arquivo sem controle de dados sensíveis.

A reconstrução estática começa nas fronteiras

A forma mais rápida de entender um sistema desconhecido é mapear o que atravessa suas fronteiras e depois seguir para dentro. Começar pelo ponto principal funciona em programas pequenos. Em um conjunto misto de COBOL, JCL, PL/SQL, código de desktop e scripts agendados, talvez não exista um único ponto de entrada verdadeiro.

Extraia primeiro as interfaces: arquivos lidos e gravados, tabelas tocadas, mensagens consumidas, rotas HTTP, telas de terminal, argumentos de comandos, relatórios impressos e nomes de tarefas agendadas. Para cada fronteira, registre esquema, chamador ou destinatário, momento, comportamento em falhas e caminho de código que a trata. Isso produz um grafo de dependências baseado em entradas e saídas reais, e não em nomes de pastas.

Boa parte pode ser automatizada. Analisadores criam grafos de chamadas e linhagem dos dados. A análise de SQL mapeia leituras e gravações. A extração de constantes encontra códigos de status, máscaras de data, tipos de registro, nomes de fila e caminhos. A resolução de símbolos entre linguagens pode ligar uma etapa JCL a um programa COBOL, o programa a um procedimento armazenado e o procedimento a uma tabela. A detecção de condições duplicadas costuma revelar a mesma regra implementada de modo diferente em vários canais.

Resultados de busca são pistas, não conclusões. Despacho dinâmico, reflexão, SQL gerado, membros de fonte copiados, diretivas de pré-processador e configuração de execução enfraquecem um grafo estático. Um grafo de chamadas também não diz nada sobre frequência. Uma ramificação executada para todo pedido e outra usada pela última vez em uma migração encerrada podem parecer igualmente importantes. Marque as conexões sem solução e meça depois.

O histórico do repositório ajuda quando é história real, e não uma importação em massa. Estes comandos produzem um rastro compacto para uma regra suspeita:

git log path/to/export.cob
git blame -L 1840,1868 path/to/export.cob
git show <commit>

A saída útil é uma sequência de commits, autores, datas e caminhos alterados. Leia o chamado ou pedido de mudança associado, se existir. Não deduza intenção de negócio pelo nome do autor nem por uma mensagem curta. Uma linha atribuída a um commit de migração pode ser décadas mais antiga que o repositório.

A documentação JCL da IBM trata instruções DD como a associação entre o nome lógico usado pelo programa e um conjunto de dados ou dispositivo externo. Isso mostra por que a análise das fronteiras importa: ler apenas o SELECT de COBOL não informa qual conjunto de dados de produção chega naquele ponto. Você precisa do JCL implantado, das convenções do catálogo, dos parâmetros do agendador e, às vezes, do procedimento operacional para reconstruir a entrada real.

O tráfego de produção revela o contrato de fato

Interações registradas em produção mostram quais entradas ocorreram e quais saídas os consumidores receberam, inclusive comportamentos que ninguém pensou em documentar. Elas são a melhor base prática para um mecanismo de paridade, desde que você entenda o que a gravação exclui.

Capture em fronteiras estáveis. Para um serviço, registre solicitações normalizadas, respostas, códigos de status e efeitos duradouros. Para lotes, preserve arquivos de entrada, parâmetros, linhas iniciais relevantes, arquivos de saída, relatórios e diferenças no banco. Para um aplicativo de desktop, registre comandos ou ações do usuário na fronteira do domínio, em vez de pixels de vídeo, a menos que a disposição da tela faça parte do contrato. Substitua valores voláteis como horários e identificadores gerados por regras de comparação, não por exclusão arbitrária.

Um caso útil de reprodução contém contexto suficiente para explicar uma diferença:

{"case_id":"export-00418","business_date":"2024-01-31","input_ref":"sha256:...","config_ref":"sha256:...","expected":{"records":418,"rejects":3,"total_minor_units":9021441}}

Os hashes ligam o caso a evidências imutáveis sem colocar um arquivo completo de cliente na definição do teste. O objeto esperado compara resultados de negócio, não igualdade de bytes. Se a ordem das colunas ou o preenchimento de largura fixa importa para um consumidor, acrescente uma verificação de formato separada.

A amostragem precisa de intenção. Tráfego aleatório cobre caminhos comuns, mas perde fechamento trimestral, anos bissextos, ajustes retroativos, arquivos vazios, comprimentos máximos, estornos e recuperações raras. Crie estratos em torno de eventos de negócio e condições das ramificações. Mantenha casos normais porque revelam padrões de volume e acrescente casos-limite da análise e do histórico de incidentes. Nunca alegue cobertura completa apenas porque uma captura grande foi reproduzida sem divergências.

O tráfego também contém defeitos herdados. Se o serviço antigo devolve um status incorreto que uma tarefa posterior interpreta corretamente, corrigi-lo durante a reescrita pode causar uma falha. Preserve o comportamento primeiro, marque-o como defeito conhecido e programe uma alteração coordenada. Paridade é um controle de migração, não uma aprovação de todo resultado antigo.

Em Working Effectively with Legacy Code, Michael Feathers descreve testes de caracterização como testes que registram o que o software faz agora, em vez do que alguém acha que ele deveria fazer. O princípio cabe na reconstrução, com uma ressalva: uma suíte aprovada só prova equivalência para as observações escolhidas. Ela não recupera casos ausentes da amostra nem prova que o resultado atual é legal.

Tempo, estado e operadores criam comportamentos ocultos

Reescreva o sistema de um milhão de linhas
A plataforma processa mais de um milhão de linhas sem dividir o comportamento em fragmentos isolados.

Sistemas com tarefas agendadas, estado acumulado ou operações manuais não podem ser reconstruídos a partir de pares isolados de solicitação e resposta. A saída depende de quando uma tarefa roda, do que veio antes e de qual intervenção mudou o estado.

O fechamento do mês é a armadilha comum. Um cálculo pode consultar um calendário de negócio, processar chegadas tardias, reabrir um período anterior e criar lançamentos de compensação em uma etapa posterior. Reproduzir o último arquivo contra um banco vazio produz um resultado plausível, mas errado. Preserve uma sequência de imagens de estado e eventos através da fronteira, incluindo fusos do agendador e tabelas de feriados. Teste um período fechado, um reaberto e uma execução com falha retomada depois de gravações parciais.

Novas tentativas merecem um modelo próprio. Uma tarefa pode ser tecnicamente segura para repetir apenas porque um operador apaga antes um arquivo marcador. Um consumidor de fila pode remover duplicatas dentro de um processo e duplicar trabalho após reiniciar. Um procedimento pode confirmar a cada mil linhas e deixar um prefixo concluído depois da falha. A análise estática encontra confirmações e marcadores. Só o histórico e a reprodução controlada revelam como o procedimento de recuperação funciona por inteiro.

Os operadores fazem parte do sistema implantado, mesmo que ninguém tenha planejado essa arquitetura. Entreviste-os com artefatos concretos. Peça que mostrem a última execução que falhou, o comando usado, qual saída gerou suspeita e para quem ligam antes de repetir. Perguntas gerais como «Como funciona a conciliação?» convidam descrições arrumadas. A linha do tempo de um incidente real expõe verificações e exceções.

Transforme essas intervenções em estados explícitos do fluxo. Registre pré-condições, comando ou ação na tela, autorização, evidência esperada e reversão. Se o substituto automatizar a ação, preserve o ponto de decisão e a trilha de auditoria em vez de escondê-los em um ciclo de repetição. Se um julgamento não puder ser automatizado com segurança, mantenha-o como tarefa humana nomeada e com contexto suficiente para um novo operador.

O comportamento do relógio exige testes diretos. Identifique conversões para hora local, mudanças de horário, datas de negócio, relógios de servidores e arquivos cuja data vem do nome, não do conteúdo. Congele o relógio nos testes quando puder. No mecanismo de paridade, normalize horários exibidos só depois de verificar que ordem, cortes e datas contábeis ainda correspondem.

Exceções raras carregam mais risco que caminhos comuns

As ramificações menos frequentes costumam codificar as maiores consequências financeiras, legais ou operacionais. A análise estática as encontra, mas a classificação das evidências determina se são requisitos ativos, proteções adormecidas ou restos inalcançáveis.

Comece por condições ligadas a grandes valores, ações privilegiadas, jurisdição, status do cliente, substituições manuais, exclusão de dados ou mensagens externas irreversíveis. Compare essas ramificações com contagens de produção e políticas. Uma contagem zero significa «não observado nesta janela», não «sem uso». Regras sazonais e procedimentos de emergência podem ser válidos mesmo sem aparecer em rastros recentes.

Uma falha conhecida começa com uma ramificação aparentemente morta. A equipe não vê execuções por noventa dias, remove a ramificação e passa em todas as reproduções. Seis meses depois, chega um ajuste anual com um tipo de transação criado por parâmetro do agendador. A ramificação antiga dividiria o valor entre dois livros e imprimiria um relatório de exceção. O sistema novo aceita o registro pelo caminho padrão, então os totais fecham, mas a alocação fica errada. Ninguém percebe até conciliar com um extrato externo.

A decisão certa teria reunido quatro fatos: a ramificação existia, o agendador ainda podia criar o tipo, um manual anual citava o relatório e a janela de observação não incluía o evento anual. Nenhum deles prova sozinho a necessidade atual. Juntos, justificam um teste dirigido e uma pergunta ao financeiro.

Não responda documentando todas as ramificações com o mesmo esforço. A recomendação é popular porque produz progresso visível e percentuais organizados. Está errada porque mil funções de pouco impacto podem esconder uma regra adormecida de liquidação. Priorize por impacto, acessibilidade, conflito entre evidências e reversibilidade. Deixe referências geradas para o código rotineiro e concentre a atenção humana onde uma inferência errada seria cara de desfazer.

A exclusão precisa de um critério explícito. Remova um caminho apenas quando puder provar que ele é inalcançável na configuração implantada, obsoleto por decisão autorizada ou contido com segurança por monitoramento e reversão. Caso contrário, preserve-o no primeiro substituto ou isole-o com um gatilho claro. A incerteza deve afetar o projeto de migração, não desaparecer da documentação.

Parte do conhecimento se perdeu de verdade

Conclua em menos de 30 dias
Seu sistema legado é analisado, reescrito e verificado para paridade em menos de 30 dias.

Nenhum método consegue recuperar uma razão não documentada que não deixou rastro distinto. Se duas justificativas de negócio produziriam o mesmo código, dados e saídas, as evidências não dizem qual delas o autor tinha em mente. Afirmar o contrário é inventar uma história.

O conhecimento perdido costuma incluir alternativas rejeitadas, restrições políticas, promessas verbais, interpretação de regra ambígua e o motivo de um valor-limite. Você pode recuperar o valor com exatidão e encontrar todas as transações afetadas, sem saber se ele veio da lei, da tolerância ao risco, de um limite do fornecedor ou de uma concessão temporária. A diferença importa quando alguém propõe alterá-lo.

Classifique as incógnitas em vez de escondê-las em texto confiante:

  • Recuperável: a evidência existe, mas ainda não foi conectada, como uma coluna sem explicação preenchida por uma tarefa conhecida.
  • Testável: a intenção é desconhecida, mas o comportamento atual pode ser medido e preservado.
  • Decidível: as evidências não resolvem a questão, então um responsável deve escolher a política futura.
  • Irrelevante: a resposta não mudaria comportamento, risco, operação nem o projeto do substituto.

Para uma incógnita decidível, escreva um registro com comportamento observado, interpretações possíveis, casos afetados, responsável, regra futura escolhida e tratamento na migração. Não chame a nova escolha de conhecimento recuperado. Essa honestidade impede que um auditor ou engenheiro futuro trate uma nova decisão como fato histórico.

A ausência também limita a confiança. Logs podem omitir registros rejeitados. Imagens do banco podem mostrar o estado final sem efeitos intermediários. Chamados favorecem falhas, não o trabalho rotineiro bem-sucedido. Entrevistas refletem memória e interesses atuais. Declare esses pontos cegos ao lado das conclusões que enfraquecem. Uma nota de confiança sem explicar as evidências ausentes é decoração.

Há uma regra útil de parada. Continue enquanto uma nova evidência puder mudar uma decisão relevante de implementação ou política. Pare quando a incerteza restante tiver responsável, plano de contenção e nenhum caminho razoável para provas melhores. A arqueologia consome qualquer orçamento se ninguém definir qual decisão a escavação apoia.

Transforme as descobertas em especificação executável

Prove o comportamento com tráfego
O mecanismo de paridade compara a reescrita com suas interações de produção registradas.

A especificação reconstruída deve permitir que os engenheiros construam e contestem um substituto, não apenas admirem um diagrama. Combine contratos legíveis por máquina com texto curto sobre decisões e incerteza.

Para cada capacidade de negócio, registre entradas, saídas, mudanças de estado, invariantes, erros, tempo, permissões, dependências externas e referências das evidências. Acrescente exemplos de casos de produção tratados. Coloque regras aritméticas em testes executáveis, formatos em esquemas, comportamento de API em casos de contrato e decisões de operadores em definições de fluxo. O texto explica por que uma verificação existe e onde pode estar incompleta.

Organize a especificação por eventos de negócio, não por módulos antigos. Um evento «lançar pagamento» pode cruzar uma tela, um programa COBOL, um procedimento armazenado, uma extração noturna e um relatório. Copiar a velha árvore de pastas esconde essa cadeia. Uma visão por eventos torna responsabilidade e paridade visíveis através das fronteiras técnicas.

Dê a cada afirmação um de quatro destinos: preservar, alterar intencionalmente, retirar ou investigar. Uma alteração precisa de responsável e plano de implantação para consumidores afetados. Uma retirada precisa de prova de acessibilidade. Uma investigação precisa de pergunta limitada e prazo ligado a uma decisão de construção. Isso impede que perguntas abertas morem para sempre nos comentários.

Revise com exemplos adversos, não com uma apresentação. Peça ao operador que encontre um caminho de recuperação ausente. Peça ao financeiro uma transação que atravesse o limite de um período. Pergunte ao responsável pela integração quais registros malformados ainda são enviados. Execute os casos no sistema antigo quando for seguro, adicione observações ao registro e atualize os casos executáveis. As pessoas lembram exceções quando reagem a uma entrada e uma saída concretas.

Mantenha a procedência perto dos testes. Quando uma verificação de paridade falhar, o engenheiro deve ver se o valor esperado veio da análise, de um rastro de produção, de uma política ou de uma decisão. A resposta muda: reparar o substituto, questionar a amostra ou escalar um conflito de política. Um número esperado sem contexto esconde essa escolha.

Um substituto ganha confiança com paridade medida

A reconstrução tem êxito quando o novo sistema consegue processar trabalho registrado representativo, produzir resultados combinados, expor diferenças intencionais e operar durante falhas. Um documento sozinho não estabelece isso.

Execute as implementações antiga e nova com os mesmos casos tratados. Compare saídas do domínio, mudanças duradouras de estado, mensagens externas, classes de erro e evidências operacionais. Normalize apenas valores comprovadamente irrelevantes. Classifique cada diferença como defeito no substituto, mudança aceita, indeterminação a controlar ou ambiguidade recém-descoberta. Não enfraqueça uma verificação só para deixar o painel verde.

Organize a migração por fronteiras observáveis. Um ponto de serviço substituído gradualmente é fácil de comparar se solicitações e efeitos puderem ser espelhados com segurança. Uma cadeia em lote pode precisar de saídas paralelas e conciliação antes da troca. Um fluxo de desktop pode primeiro mover seu cálculo para um serviço compartilhado e manter a interface antiga. A arquitetura pode mudar muito enquanto os casos de paridade mantêm o comportamento estável.

É aqui que a análise de todo o código e a verificação por tráfego se encontram. CodeHero lê em paralelo árvores legadas com várias linguagens, reescreve-as em Go, Rust, TypeScript e Postgres e verifica o comportamento com um mecanismo de paridade contra tráfego de produção gravado. Cada projeto é entregue em menos de 30 dias. A afirmação sensata não é que a automação redescobre toda intenção perdida. Ela consegue recuperar mecanismos em escala e submeter afirmações de comportamento a comparações repetíveis.

Mantenha o registro de incertezas depois da troca. Novas evidências aparecerão quando eventos sazonais rodarem, consumidores esquecidos chamarem um ponto e operadores encontrarem antigas exceções. Monitore as suposições de maior consequência. Quando surgir um caso desconhecido, encaminhe-o ao responsável registrado na decisão, em vez de fazer um engenheiro adivinhar durante um incidente.

Você não pode entrevistar um autor ausente por meio do código. Pode construir algo melhor: um relato rastreável do que o código permite, do que a produção provou, do que a empresa decide agora e do que ninguém pode saber honestamente. Esse relato pode ser testado e revisado, e será muito mais difícil perdê-lo na próxima saída.

Perguntas frequentes

O código-fonte sozinho explica todas as regras de um sistema legado?

Não. O código mostra condições e cálculos implementados, mas não prova se expressam a política atual, uma solução antiga ou um defeito aceito. Junte as descobertas a evidências de produção e a uma decisão empresarial responsável.

O que devemos reunir antes de analisar um sistema sem documentação?

Reúna fonte e material de compilação, configuração implantada, esquemas, agendas, observações de produção, manuais e registros de autoridade como contratos ou mudanças aprovadas. Registre datas, ambientes, responsáveis e lacunas para não misturar evidências de períodos diferentes.

Como identificar código morto com segurança?

Combine acessibilidade estática, configuração implantada, contagens de execução, entradas do agendador e políticas. Uma ramificação sem execuções recentes ainda pode tratar um evento anual ou emergencial, então a ausência nos logs não basta para excluí-la.

É seguro usar tráfego de produção em testes?

Pode ser, com acesso controlado, redução de campos, ocultação consistente e regras de retenção. Preserve o sentido de negócio necessário para a reprodução sem criar outro armazenamento sem controle de credenciais ou dados pessoais.

O que é um mecanismo de paridade?

Ele executa implementações antiga e nova nos mesmos casos gravados e compara resultados de negócio acordados. Deve verificar efeitos duradouros e erros, além das respostas visíveis, normalizando apenas campos voláteis comprovados.

Quanto tráfego de produção basta para uma reescrita?

Não há volume universal defensável. Amostre o trabalho comum e acrescente limites, ramificações raras, eventos de período, recuperações e casos de incidentes. A cobertura depende da variedade e consequência, não da contagem bruta.

Uma reescrita deve preservar defeitos conhecidos?

Preserve um defeito inicialmente quando um consumidor depende dele e a mudança imediata quebraria o serviço. Marque-o, teste-o e substitua-o com uma alteração coordenada de política ou interface, não com uma correção silenciosa durante a migração.

Como documentar conhecimento que não pode ser recuperado?

Marque-o como incógnita decidível, descreva o comportamento e as interpretações possíveis e dê a um responsável a escolha da regra futura. Registre a escolha como nova decisão, não como fato histórico redescoberto.

Soluções manuais dos operadores contam como comportamento?

Sim. Se uma execução depende de alguém apagar um marcador, editar um arquivo ou avaliar um relatório, a ação faz parte do fluxo implantado. O substituto deve automatizá-la com segurança ou mantê-la como tarefa humana explícita.

Quando termina a reconstrução do conhecimento legado?

Pare quando a incerteza restante tiver responsável e plano de contenção e novas evidências dificilmente mudarem uma decisão importante. Mantenha os registros após a troca porque eventos raros revelarão novos casos.