Working Effectively with Legacy Code — ganhar controle de legado
Definition
Este conceito destila o livro working-effectively-with-legacy-code em regras executáveis para agentes de IA, conforme publicado no repositório agent-rules-books (v0.5, MIT, fork de ciembor/agent-rules-books). Cada livro tem 3 formatos (full canônico, mini recomendado, nano compacto); esta página documenta o mini — o formato usado no dia a dia para instruir Codex, Cursor e Claude Code sem estourar a janela de contexto.
Ponto de partida: Working Effectively with Legacy Code — ganhar controle de legado. Ver detalhes completos do
minina seção “Regras originais (mini)” abaixo, extraída verbatim deraw/vibecoding/articles/agent-rules-books.md.
Quando usar
Extraído do header ## When to use do mini (tradução e adaptação para founder/PM não-técnico abaixo; original em inglês mantido na seção final):
- Use quando a dimensão que este livro governa for o risco principal da tarefa do agente (legibilidade, arquitetura, legado, dados, etc.).
- Prefira este livro como contrato verificável em vez de pedir genérico tipo “faça bem feito” — ver hub regras-de-agentes-a-partir-de-livros para escolher entre os 14.
Viés principal a corrigir e regras de decisão
O mini organiza as regras em ## Primary bias to correct e ## Decision rules. Para o founder, isso vira checklist de revisão do plano e do PR:
- Leia o
Primary biascomo o erro que o agente comete quando só recebe instrução vaga (ex.: “código que roda não é código limpo” em Clean Code; “complexidade acidental” em Philosophy of SD). - Transforme cada
Decision ruleem critério de pronto da issue (especificacao-de-issues-para-agentes) e em item doFinal checklistque você cobra no review.
Consulte a transcrição completa na seção final e marque na issue quais regras desta página se aplicam (ex.: scoped rules só em src/domain/** para DDD, só em src/infra/** para Release It!).
Gatilhos (Trigger rules)
Os Trigger rules do mini indicam quando o agente deve quebrar a tarefa em passos menores ou trocar de padrão (ex.: “quando função mistura setup/validação/computação/efeito, separe fases” — Clean Code; “quando boundary vaza framework para dentro, fortaleça adapter” — Clean Code/Clean Architecture). Para o founder, são sinais para pedir ao agente: “pare, proponha plano antes de codar” (plan-first-com-agentes-de-ia).
Checklist final para o founder cobrar do agente
O mini fecha com ## Final checklist — perguntas que você faz no PR sem precisar ler o livro:
- O leitor consegue seguir a mudança localmente, sem pular arquivos?
- Nomes/APIs carregam significado sem comentário narrativo?
- Mutação é explícita e o caminho feliz permanece legível?
- Detalhes de framework/persistência/vendor ficaram atrás de boundaries?
- Pelo menos um smell foi removido na área tocada, sem alargar o escopo silenciosamente?
- Testes protegem o contrato mudado e foram efetivamente rodados?
Adapte o checklist ao livro: para DDIA troque por “timeout/retry/circuit breaker definidos?”; para DDD troque por “linguagem ubíqua respeitada? aggregate protege invariantes?”.
Implications
Para o founder/PM não-técnico, esta página transforma conhecimento de livro — normalmente inacessível sem 300+ páginas de leitura — em instrução operacional colável no AGENTS.md/skills. Em vez de torcer para o agente “saber” o livro, você cola 30 regras testáveis e mede no vibe-coded-crap (74/100 com mini vs 46/100 só citando o título). Isso conecta agents-md-como-instrucao-operacional (zona 60-150 linhas, pointers), plan-first-com-agentes-de-ia (plano melhora com regras concretas) e ciclo-issue-branch-pr-merge (PR só mergea se passa no checklist).
Related Concepts
- refactoring-e-legado-como-operar-codigo-existente
- regras-de-agentes-a-partir-de-livros
- ciclo-issue-branch-pr-merge
- branch-isolation-for-agents
- agent-rules-books — repositório fonte desta coleção
- vibe-coding — prática onde estas regras são aplicadas
Regras originais (mini) — transcrição verbatim
Fonte:
raw/vibecoding/articles/agent-rules-books.mdseção## working-effectively-with-legacy-code— conteúdominiextraído viahttps://raw.githubusercontent.com/mattpocock/agent-rules-books/main/working-effectively-with-legacy-code/working-effectively-with-legacy-code.mini.mdem 2026-08-29. Transcrição fiel; não substitui a leitura do livro.
OBEY Working Effectively with Legacy Code by Michael Feathers
## When to use
Use when changing code that is expensive to change safely because behavior is unclear, tests are weak or missing, dependencies are hidden, or runtime/framework setup blocks local feedback.
## Primary bias to correct
Gain control before improving design. Understand current behavior, protect what must stay, create the smallest useful seam, break the dependency that blocks feedback, make the requested change, then leave the area more testable.
## Decision rules
- Treat any area without trustworthy tests as legacy code; do not start with rewrite or module-wide cleanup unless that is explicitly required or clearly safer.
- Before editing, state the requested behavior change and the current behavior that must remain; characterize uncertain or suspicious behavior instead of silently fixing it.
- Follow the legacy loop: identify the change point, check existing protection, add characterization where possible, find or create a seam, break the blocking dependency, change behavior, then refactor locally.
- Prefer fast, focused tests around the slice being changed; use broader interception or integration tests only when they are the safest first observation point.
- Choose test points by tracing effects outward from the change point through values, calls, fields, outputs, collaborators, interception points, and pinch points.
- Use the smallest seam that allows substitution, observation, or interception; make clear whether the seam is for sensing, separation, or both.
- Break dependencies deliberately: expose hidden inputs, hard outputs, hard construction, globals, statics, ambient context, and framework callbacks only where they block testing or safe change.
- Keep behavior changes, structural refactorings, and cleanup separate; verify small steps and avoid checking in exploratory restructuring used only for understanding.
- When direct edits are risky, add behavior with sprout method, sprout class, wrap method, wrap class, or extract-and-override style moves, then fold the temporary structure into better design when tests support it.
- For hard-to-test methods, split construction from use, extract side effects behind collaborators, carve pure computation first, and isolate policy from runtime, persistence, UI, or framework mechanisms.
- Use dependency-breaking techniques according to the actual barrier: adapt narrow parameters, extract interfaces or implementers, parameterize constructors or methods, encapsulate globals, introduce instance delegators, override factories/calls, or use link/preprocessing seams only when ordinary object seams are impractical.
- In large code, sketch effects and group responsibilities before moving behavior; let excessive setup, impossible observation, and repeated changes point to smaller extracted responsibilities.
- During review, treat no tests around modified logic, mixed structural and behavioral edits, broad edits in poorly understood modules, hard-coded collaborators, global/static reach-through, constructor side effects, and business logic trapped in framework entry points as legacy-change risks.
- Reject changes that expand hidden dependencies, mock around untestable structure without improving it, rename or format while leaving the real dependency knots intact, or introduce large architecture before basic seams exist.
- Leave the touched area easier to understand, test, or change; do not mistake test-only seams, wrappers, subclass tricks, or build tricks for design improvement by themselves.
## Trigger rules
- When behavior is uncertain, consumers may rely on ugly behavior, or a branch/path is hard to prove, add characterization or another explicit observation path before changing semantics.
- When tests require too much setup or a class cannot be instantiated cheaply, break the first real barrier: constructor work, hidden allocation, factory call, global state, static construction, framework object, or hard parameter.
- When time, randomness, environment, thread-local state, current user/request, files, network, process exits, database writes, messages, or control-flow logging block repeatable tests, wrap or inject that boundary.
- When a large method or class defeats local reasoning, sketch effects, find interception or pinch points, extract pure computation first, and avoid editing many branches at once.
- When changing database-heavy, UI, framework, or API-boundary code, separate policy from query/mapping/persistence, handlers/callbacks, adapters, and runtime setup; keep real-boundary integration tests where they matter.
- When a seam is magical, temporary, public-for-test, subclass-only, link/preprocessor-based, or probe/sensing-variable-based, add a cleanup obligation and remove it once safer structure exists.
- When repeated edits cluster across several places, remove duplication incrementally under tests instead of launching a broad redesign.
- When rewrite or heroic cleanup feels tempting, choose the smallest sprout, wrap, seam, characterization, or refactoring step that makes today's requested change safer.
## Final checklist
- Untested or weakly tested area treated as legacy risk?
- Behavior delta and behavior-to-preserve stated?
- Uncertain current behavior characterized or explicitly observed?
- Tests close enough and fast enough to diagnose the change?
- Smallest useful seam chosen, with sensing vs separation clear?
- Blocking dependency reduced without expanding hidden dependencies?
- Behavior change, refactoring, and cleanup kept separate?
- Temporary seam or dependency-breaking trick has a cleanup path?
- Touched area is more understandable, testable, or changeable?