# Onboarding an AI Coding Agent to an Unfamiliar Codebase

> The first hour with a repository nobody on your team wrote: map the perimeter, run the commands, write the findings to an instruction file, and delete every claim you cannot trace.

URL: https://www.matthewswong.com/en/blog/ai-agent-onboarding-unfamiliar-codebase/

- Author: Matthews Wong (https://www.matthewswong.com/en/about/)
- Published: 2026-09-16
- Updated: 2026-09-16
- Category: AI

> **Key takeaway:** Onboarding an AI coding agent to an unfamiliar codebase works when you map the perimeter first — entry points, the build and test commands that actually run, configuration, external boundaries — write the findings to a committed instruction file, and delete every claim you cannot trace to a file and a line.

The repository reached me as a Bitbucket URL and a message saying it was mine now. It ran in production and it invoiced real customers. The README had a clone command, a screenshot of a UI that no longer existed, and a setup section naming a database engine the service had stopped using. Everyone who wrote it had left.

This is the procedure I use for the first hour with a codebase nobody on my team wrote, run with a coding agent instead of by reading files in alphabetical order. It is deliberately unglamorous. The examples are Claude Code because that is what I use, and the documented behaviour is cited, but nothing in the method depends on the tool. The load-bearing part is the verification pass at the end, and it is the part almost nobody does.

## Map the perimeter before you ask about architecture

Ask an agent to understand the codebase and it hands you an architecture summary. That is the most expensive thing it can produce and the hardest thing you own to check. Spend the first hour on the perimeter instead: where the process starts, which commands the project claims to have, where configuration comes from, and which other systems it talks to. All four are answerable from manifests, imports and file names, so they are cheap to produce and, more importantly, cheap to falsify.

Perimeter work has a property architecture work does not: it fails out loud. A build command either runs or prints an error you can paste straight into the notes. A paragraph about layering is never wrong out loud — it is wrong quietly, six weeks later, inside somebody else's decision. Start where the feedback is immediate and the hour goes on accumulating facts rather than sentences.

## A command that has not been run is a claim

The scripts block in package.json is a historical document. On the service I inherited, some of the scripts named a test runner that was no longer in the dependencies at all, and the dev script bound to a port the Compose file had stopped publishing. An agent reading that file will report every one of those scripts as the project's commands, because that is what the file says, and it has no way to know the file lost an argument with reality two refactors ago.

So the second step is execution, not reading. Have the agent propose the command list, then run each one on a clean clone in a sandbox you are willing to lose, and keep the output. What you write down is not npm test. It is npm test followed by the exact failure it prints on a clean clone, because that failure is the onboarding note the rest of the team would otherwise rediscover one person at a time.

> Claude Code's /init writes a starting CLAUDE.md by exploring the codebase for build commands, test instructions and conventions, and with CLAUDE_CODE_NEW_INIT=1 it runs an interactive flow that explores with a subagent, asks follow-up questions and presents a reviewable proposal. Both are drafts. That flow also pulls in rules other tools left behind, in .cursor/rules, AGENTS.md and .windsurf/rules, and those can be exactly as stale as the README you have just stopped trusting.

## The output is a committed file, not a conversation

Onboarding produces an artefact or it produces nothing. A chat window closes at the end of the day, the next session starts from zero, and you pay the exploration cost again for slightly different answers. Put the findings where the agent loads them at startup: CLAUDE.md for Claude Code, or AGENTS.md if you want one file that several tools read — it is plain Markdown with no required fields, and its own site says over 60,000 open-source projects now carry one.

Write instructions, not description. That the API package uses Knex is a fact the agent can rediscover in ten seconds. That you must never edit a migration after it has merged, and must add a new one instead, is a rule it cannot derive from any file — and that is the sentence worth committing. Claude Code's own large-codebase guide uses exactly that pair as its example of a per-package instruction file, which is a useful calibration for what belongs in one.

## Verify every claim against a file and a line

This is the step that decides whether the hour was worth anything. In the 2025 Stack Overflow Developer Survey, 66% of respondents named answers that are almost right but not quite as their biggest frustration with AI tools, and 45% said debugging AI-generated code takes longer than they expect. An architecture summary is the purest form of that category: nothing in it is checkable at a glance, and its errors surface as a wrong decision weeks later rather than as a failing test today.

1. Ask for the summary as a list of claims, one per line, each carrying the file path and line number that proves it. Not a narrative with citations attached — a list, so that a claim without a citation is visibly missing something.
2. Open each cited line yourself, or hand the list to a second session that has never seen the first. Reading the citation is the entire check. The confidence of the wording is not evidence, and neither is how plausible it sounds.
3. Delete every claim whose citation does not say what the claim says. Do not soften it into appears to or seems to — a hedged wrong sentence is still a wrong sentence, and hedging is precisely what lets it survive review.
4. Move whatever you could not verify under an explicit Unverified heading in the same file, together with the question you would need to answer to promote it. That heading is the most useful part of the artefact on day two.

The discipline works because of an asymmetry: a file path and a line number can be falsified in seconds, and a paragraph cannot be falsified at all. It also changes what gets written. Asked for claims with citations, the agent produces noticeably fewer of them, and the ones it stops producing are the ones it had least support for — which is the filtering you wanted, happening at generation time instead of review time.

> The worst outcome of an onboarding session is a tidy, confident ARCHITECTURE.md that nobody checked. It gets committed, the next three joiners read it as ground truth, and it survives every review because reviewing it properly means redoing the original work. An unverified architecture summary is worse than no summary at all. If you cannot afford the verification pass, do not generate the summary — an empty file is honest.

*Only the bottom band produces nothing new — it removes. Skip it and the four artefacts above it survive intact and unreliable, which is the shape most onboarding sessions actually ship.*

## Five questions that expose a wrong model early

An agent's summary tends to describe a codebase's aspiration rather than what runs in it. The abstractions get named, the layering gets described, and the description would be accurate if every module were reachable and every branch were taken. These are the five questions I ask to find out whether the map matches the territory, and every one of them has to be answered with paths rather than prose.

What happens end to end when one real request arrives? Name every file it passes through, in order, from the listener to the response.

Where does this write to disk or to a database, and what else reads what it wrote?

What runs on a schedule, what triggers it, and what happens if it runs twice in the same minute?

Which files have not been touched in a year, and is anything still importing them?

Which configuration values have a default in the source that the deployment overrides?

The first question alone usually settles it. A summary that is confident about middleware, controllers and services in the abstract will, when pushed to name files in order, either produce a chain you can follow or paper over a gap with a phrase like the request is then handled by the service layer. The gap is the finding, and it is always in the part nobody documented.

## What it will confidently get wrong

Four failures recur often enough that I now check for them by name before believing anything else in a summary. They share one cause: the agent read the code, and the code is not the same object as the deployment.

|  |  |  |
| --- | --- | --- |
| Dead code described as live | The module exists, exports cleanly and is decently written, so it reads as current | Search for importers, then check the last commit date on the file |
| A deprecated path described as the current one | Both paths exist, and the old one usually has more code, more comments and more tests | Follow the entry point inwards instead of reading directories outwards |
| A config default reported as the running value | The default is in the source; the override lives in the deployment, which is not in the repository | Read the value out of the running environment, not out of the file that declares it |
| The module everyone quietly routes around | Nothing in the source marks a module as avoided, and its imports still look central | Rank files by how often they changed in the last six months |

The fourth is the failure no amount of reading will surface. Most old codebases contain a module everyone has silently agreed to work around: new code calls the thing it wraps, or reimplements the one slice of it that is needed, and nobody deleted it because deleting it is a project rather than a task. The source says it is central. The history says it is abandoned — and abandonment is a fact about people, which is precisely the layer a static read cannot see.

*The middle column is where most onboarding output lands, and the instinct there is to hedge rather than cut. Hedging keeps the sentence and throws away the warning, so cut it.*

## A map is not judgement

Everything above produces a map: where things are, which commands work, what talks to what. It does not tell you which of those things is load-bearing. The module to be most careful with is not identifiable from its imports — it is the one where a small, obviously safe change produces a support ticket three days later, and no reading of any kind finds it.

METR's 2025 study is the caution I keep in mind here. Sixteen experienced open-source maintainers working 246 issues on repositories they already knew were 19% slower with AI tools, while forecasting that they would be 24% faster and still believing afterwards that they had been 20% faster. That is the opposite situation to this one — they knew their code — but the gap between felt speed and measured speed is exactly why I write the artefact down and verify it rather than trusting an impression that the hour went well.

So the honest bound on all of this: the map is worth having on day one, and it is not understanding. Understanding arrives one way, by changing something small, shipping it, and watching what breaks. What the onboarding artefact buys you is a cheaper and safer version of that experiment, because you know how to run the tests and where the boundaries are before you touch anything.

The rule I carry now is short. The first hour with an unfamiliar repository produces a committed file rather than a conversation, every line in that file names the code that proves it, and whatever cannot be proved sits under a heading that says so. Anyone describing an agent that understands a codebase it has never deployed is describing a reading, not an understanding.

## Sources and further reading

- Claude Code documentation — Memory and project instructions, including what /init generates
- Claude Code documentation — Set up Claude Code in a monorepo or large codebase
- AGENTS.md — an open instruction-file format read by many coding agents
- Stack Overflow 2025 Developer Survey — the AI section on usage, trust and frustrations
- METR — Measuring the impact of early-2025 AI on experienced open-source developer productivity

## Source links

- https://code.claude.com/docs/en/memory
- https://code.claude.com/docs/en/large-codebases
- https://agents.md/
- https://survey.stackoverflow.co/2025/ai
- https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/

## FAQ

### How do I onboard an AI coding agent to a codebase nobody on my team wrote?

Start with the perimeter rather than the architecture: entry points, the build and test commands that actually run, where configuration comes from, and which external systems the code talks to. Run every command the project claims to have on a clean clone and record the failures verbatim, because those failures are the notes worth keeping. Then write the findings into a committed instruction file such as CLAUDE.md or AGENTS.md so the next session does not re-derive them.

### Why is an unverified AI architecture summary worse than no summary at all?

Because it reads authoritative and therefore gets trusted. A tidy generated ARCHITECTURE.md is committed, treated as ground truth by everyone who joins after you, and survives review because checking it properly means redoing the original exploration. If you cannot afford a verification pass, leaving the file empty is the more honest option.

### What is the fastest way to verify what an AI agent says about a codebase?

Ask for the summary as a list of claims, one per line, each carrying the file path and line number that proves it. Open each cited line yourself, or hand the list to a second session that never saw the first one. Delete any claim whose citation does not say what the claim says, rather than hedging it into appears to, because a hedged wrong sentence still survives review.

### What do AI coding agents most often get wrong about an unfamiliar repository?

Four failures recur: dead code described as live, a deprecated path described as the current one, a configuration default reported as the running value, and the module everyone quietly routes around. They share one cause, which is that the agent read the source and the source is not the deployment. Git history and the running environment settle all four.

### Should onboarding notes go in CLAUDE.md or AGENTS.md?

Either works, and the choice comes down to how many tools need to read the file. CLAUDE.md is what Claude Code loads at startup and what its /init command generates from an exploration of the codebase. AGENTS.md is plain Markdown with no required fields that many coding agents read, and its own site says over 60,000 open-source projects carry one. Write instructions rather than descriptions in whichever you pick.

---

- HTML version: https://www.matthewswong.com/en/blog/ai-agent-onboarding-unfamiliar-codebase/
- Bahasa Indonesia: https://www.matthewswong.com/id/blog/ai-agent-onboarding-unfamiliar-codebase/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
