Blog

Onboarding onto a New Codebase with AI

The first week on an unfamiliar codebase goes on questions the code can already answer: where a request comes in, which module owns billing, what sits between a button and the row it writes. You open files, follow imports by hand, and build a mental model out of fragments. An AI coding agent starts from the same blank page with one extra handicap: it cannot skim. It searches for a string, reads whatever comes back, and forms an opinion from the sample that search happened to return. The way through, for you and the agent both, is to get the shape of the system before chasing any single behavior, and to check impact before anything gets edited.

Orientation is a mapping problem

Ask a new joiner what they did on day one and the answer is usually "read the folder tree". The tree records filing decisions, some of them years old, and says nothing about which module calls which when the program runs. Two files in the same directory can share no code path at all, and a single import can bind directories at opposite ends of the tree.

The map worth having is computed from the calls. Parse the repository into symbols and edges, cluster those edges by how densely groups of symbols call each other, and the modules that exist in behavior fall out, each with the symbol most of the traffic routes through. That is what dependency mapping produces: a few dozen named clusters with weighted arrows between them, derived from call behavior and frequently disagreeing with the directory layout. Read the disagreements closely: a cluster spanning four top-level folders marks a real seam the directory layout hides.

Pair the map with the entry points: HTTP routes, CLI commands, queue consumers, scheduled jobs. Execution begins at one of them, and so does every trace you will run this week.

What to ask in the first hour

With the graph served to your agent over MCP, the opening questions have short answers that fit in a working context. Four asks cover most of day one.

  • The module map for the repository, with the hub symbol inside each module. This is the shape of the system in a page.
  • The symbols carrying the most inbound calls. High fan-in marks the code you will meet again, so read it early and touch it carefully.
  • The handler behind a route you care about, by method and path. find_http_route goes straight there with no guessing about the project's naming conventions.
  • A behavior question in plain words: how this project does authentication, where retries live, what happens after checkout. ask_codebase answers with file citations you can open.

Each answer arrives as names, file paths, and line bounds. A whole-file read to settle a one-line question spends budget you need later in the session, and those tokens sit in the window for every turn that follows. Context engineering for coding agents works through the arithmetic.

Trace the behavior you were handed

Onboarding usually ends with a ticket, and a ticket names a behavior. "Bookings sometimes send two confirmation emails." Nothing in that sentence is a symbol, so the first job is turning it into one.

Start at the entry point: resolve the route or the job that begins the flow, then walk the call chain out of its handler. A graph traversal follows the calls the parser resolved, including the hop where a call site names an interface method and the concrete implementation carries a different name. Text search cannot make that hop, and it is the hop most likely to hide the code you actually want.

Read source last, and only the spans the traversal named. By then you know which file to open and which twenty lines inside it carry the behavior. That is a different exercise from opening a file to find out whether it matters at all, and the difference compounds over a week of them.

Where a grep-only agent loses the thread

An agent onboarding without a graph searches for sendConfirmation, gets nine matches, and opens all nine. Two are comments. One is a changelog entry. One is a method of the same name on an unrelated class. The real call site, routed through a Notifier interface, never appears in the results. The agent then explains the flow with total confidence, built from the five files it happened to read.

The gap widens with the repository. On a small project the sample is most of the code, so guessing works well enough to feel like understanding. On a monorepo, or across the four repositories a production system actually spans, the sample is a rounding error, and the failure modes get specific: why AI coding agents fail on large codebases walks through each one. Onboarding is where you feel it first, because everything is unfamiliar and you carry no prior knowledge to catch a wrong answer with.

The first change is an impact question

A new joiner's first pull request is small on purpose, and a small diff can still reach a long way. getHttpError, a nineteen-line cal.com helper measured at commit 176037d for an earlier post here, has 2 callers, both sitting in the file with it. Read the callers alone and you ship the edit in a minute. Its blast radius, walked outward from those two, is 77 symbols across 66 files, and the named set includes both booking endpoints, the tRPC handler factory, and a payment refund. Same nineteen lines, two very different reviews.

So the order before an edit is callers first, then the downstream set, then whichever tests already stand over the symbol. Those calls cost less than one file read and they change what the pull request looks like. This is also the step where a new joiner is weakest, because knowing which parts of a system are load-bearing is exactly the instinct you have not built yet. A number substitutes for the missing instinct: fourteen callers across three repositories means the change wants splitting, and zero callers usually means dead code.

Three passes over an unfamiliar codebase: orient with a module map and entry points, trace a route to its handler and the call chain through it, then size the edit with callers, downstream symbols, and covering tests, with source opened last
Three passes before the first edit. Names and file paths travel through the session; source gets opened last, only where the earlier passes pointed. Link to this diagram Open full size

A loop for the first week

The version that holds up, run with the graph in the agent's tool list:

  1. Pull the module map and the entry-point list. Learn names before files.
  2. Pick the entry point closest to your first ticket and trace its chain to the leaf.
  3. Ask the behavior question in words and open the citations that come back.
  4. Before any edit, pull callers, blast radius, and covering tests for every symbol you plan to touch.
  5. Open source last, only the spans the earlier steps located.

Steps 1 through 4 return identifiers, so the window stays mostly free until step 5, the first moment real source enters it. The loop is the one an experienced engineer runs from memory; the graph supplies the memory you have not built yet. Wiring it takes one command in Claude Code, and Cursor, Windsurf, and the other MCP clients call the same tools.

Known limits

A parsed graph sees what the source says. Dependency injection keyed by string, a handler wired from a config file, a plugin loaded by scanning a directory: those edges come back weak or missing, and in a codebase leaning on them the blast radius understates the true reach. Treat a suspiciously low number in that kind of area as a prompt to go look.

The graph also cannot tell you why. It shows that a module exists and where its traffic goes. The reason it was split from its neighbor two years ago lives in a pull request description or in someone's head, and asking that person is still the fastest route to it.

An index trailing the branch you are working on describes a codebase you are not editing, and it describes it confidently. Per-branch indexing, plus a way to overlay the edits you have not pushed, is what keeps the map pointed at the code in front of you.

Onboarding is the stretch where confident wrong answers cost the most, because you have nothing to check them against. Symvanta gives your AI coding agent your codebase's real call graph over MCP, so it stops guessing and knows what breaks before it edits. The module map is there on day one, the caller list before the first pull request, and the answers hold whether the code is one repository or four. Point it at the repository you just inherited and see what the first hour turns up.

Start free trial →