How to Get an AI Coding Agent to Explain Legacy Code

Run an AI coding agent through four comprehension prompts before refactoring a legacy codebase: trace real requests, map the data model, and surface undocumented business rules.

Steve Jefferson
Steve Jefferson
Developer Advocate
28 August 20261 min read

When you inherit a legacy codebase, the instinct is to ask an AI coding agent to explain it in one shot: "summarize this codebase" or "what does this project do." That produces a vague overview you could have gotten from the README, if the README were current. A genuinely useful explanation comes from running the agent through a specific sequence of comprehension prompts before it touches a single line of code: trace one real request end to end, map the actual data model, find every place a key field gets mutated, and pull out the business rules the code enforces that nobody wrote down anywhere. Do this first. Refactoring is a separate, later step.

Understanding first, refactoring second

Most guides on AI and legacy code jump straight to the fun part: refactoring, modernizing, cleaning up dead branches. That is the wrong place to start. If you want the mechanics of turning an agent loose on the actual rewrite safely and incrementally, that is covered in how to use AI to refactor legacy code. This post is about the step that has to happen before any of that: getting the agent, and you, to actually understand what the code does and why, before either of you decides what to change. Skip this step and every refactor suggestion the agent makes is a guess dressed up as confidence.

This works with any agent capable of reading and navigating your repository, from a lightweight autocomplete-style assistant to a fully autonomous coding agent. If you have not settled on which one fits your workflow, this rundown of AI coding tools covers the tradeoffs worth weighing first.

The four comprehension prompts to run first

Skip the one-shot summary request entirely. It invites the model to pattern-match against generic project structures instead of reading your actual code. Instead, work through these four prompts in order. Each one forces the agent to open real files and trace real logic, and each surfaces something a general summary always misses.

  1. Trace a real, specific user-facing request end to end through the codebase, from the entry point all the way to the database write and back to the response.

  2. Map the core data model: every table or model, the fields on each one, and how they relate to each other.

  3. Find every location in the codebase where one particular field or value gets read, set, or mutated, not just the obvious file where you'd expect it.

  4. Extract the business rules actually enforced by the code, and compare them against whatever existing documentation, comments, or README claims about how the system behaves.

Prompt 1: Trace a real request end to end

Architecture diagrams go stale within a quarter. Comments rot faster than that. But asking an agent to trace one concrete, specific action, not "how does checkout work" in the abstract, but exactly what happens when a user clicks one particular button, forces it to open every file in the actual call path in order. You can then verify that trace against the running app in about two minutes, which is more than you can say for most existing documentation.

Here is the prompt, close to verbatim:

Trace what happens end to end when a user clicks "Submit Order" on the checkout page. Start at the frontend event handler, follow it through every controller, service, queue, or background job it touches, list every table it reads from or writes to, and note any external API calls or side effects such as emails, webhooks, or third-party charges. Show the full path as a numbered list of files and functions, in the order they execute.

Run this for two or three of the most important flows in the product, not just one. The checkout flow and the signup flow usually touch completely different parts of the codebase, and the second trace often reveals a shared utility, or a duplicated one, that the first trace never mentioned.

Prompt 2: Map the core data model and its relationships

Ask the agent to enumerate every table or model, its fields, and its relationships to every other table, in plain language rather than a raw schema dump you already have access to. The value here is not the list itself, it is the agent walking the actual migrations and model files instead of trusting a stale ER diagram someone drew two years and forty migrations ago. Ask it explicitly to flag any relationship implied by naming or comments that the current schema does not actually enforce, foreign keys that got dropped, columns that got repurposed, tables that look related but aren't anymore. That gap between the implied model and the enforced one is usually where the surprises live.

A good ask sounds like this: "List every table in this codebase with its columns, then describe in one sentence how each table relates to the others it references. Cross-check each relationship against the actual foreign keys and migration history, not just the model definitions, and call out any relationship that the code assumes but the schema no longer enforces." That last clause is the one people forget to add, and it is usually the part that pays off.

Prompt 3: Find every place a field gets mutated

Pick one field that carries real weight, something like order.status, user.plan, or invoice.paid_at, and ask the agent to search the entire repository for every place that field gets written, not read, written. Controllers, background jobs, webhooks, admin panels, one-off scripts, database migrations that backfilled it once. This is where the undocumented behavior hides: a nightly cron job that silently flips a status the main application logic assumes only a user action can change, or an internal admin route that bypasses the validation everyone assumes is universal.

This step matters even more on a codebase with no tests, since nothing will fail loudly when you later touch code that assumed only one path could ever set that value. Finding every mutation site now, before you change anything, is what makes the difference between a safe edit and a quiet regression three weeks later.

Prompt 4: Extract the real business rules versus what the docs claim

Documentation describes intent at the moment someone wrote it down. The code describes what the system actually does today, which is frequently a different thing after eighteen months of quick fixes. Ask the agent to list the business rules it can actually find enforced in the code: discount thresholds, retry limits, eligibility checks, rate limits, whatever governs the domain. Then, separately, ask it to summarize what the README, wiki, or inline comments claim about the same behavior, and flag every contradiction between the two lists.

These contradictions are gold. A rule that the code enforces but the docs never mention is a landmine for the next person, human or agent, who assumes the docs are complete. A rule the docs describe that the code no longer enforces is either a bug or a decision nobody documented, and either way you want to know before you build on top of it.

Turn the answers into a shared reference

Save all four outputs into a single file in the repository, something like CODEBASE_NOTES.md, rather than letting them live only in a chat transcript that scrolls away. That file becomes the starting context for every future session, human or agent, and it means the next comprehension pass starts from what you already learned instead of from zero. While you are producing it, you will likely notice which files and variables were confusing enough to slow the agent down; a codebase where names actually describe what they hold is one where an agent stops reinventing existing helper functions because it never found the ones already there, and stops guessing at intent because the intent is spelled out in the name.

Expect this whole pass to take an afternoon on a small service and a few days on a genuinely large monolith, mostly because you should be reading the agent's output critically rather than accepting it wholesale. Ask it to cite the actual file and line for every claim it makes, and spot-check a handful of them yourself. An agent that traces a request flow with total confidence but skips a conditional branch it did not notice will hand you a trace that looks complete and isn't, and the only way to catch that is to open a few of the files it cited and confirm the branch it described is really the only one.

When you are ready to refactor

Once you can trace the real request flows, you have an accurate map of the data model, you know every place a critical field gets touched, and you have reconciled what the code actually does against what the documentation claims, you are finally in a position to say what is safe to change. That is a distinct job from the one covered here, with its own practices around scope, testing, and rollback safety. When you get there, it is worth breaking the actual rewrite into small, reviewable tasks rather than one sprawling change, which is its own skill worth reading up on separately.

Skipping straight to "clean this up" without doing this groundwork is how legacy rewrites turn into six-month projects that quietly reintroduce the exact bugs the original code had learned to avoid. The comprehension pass is slower than asking for a summary. It is also the only version of "understanding the codebase" that survives contact with the actual code.

How did this land?

About the author

Steve Jefferson
Steve Jefferson

Developer Advocate

Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.

How to Get an AI Coding Agent to Explain Legacy Code | swarmz.net