Where it earns its place

Six situations, one graph.

nao does one thing — it turns a repository into a typed graph and answers questions about it. What changes is which question you are stuck on. These are the situations where that turns out to be the expensive part of the week.

Worked example

Inheriting a legacy codebase

“Two projects, both legacy, in a stack I don’t know — and I switch between them daily.”

The oldest version of the problem and still the most expensive: undocumented domain vocabulary, logic hiding in config files, and no author left to ask. A derived map removes the structural half of every reload, which is the half you were rebuilding by reading.

  1. Read the domain map before any code — or map one folder, never the root
  2. Cross complexity with churn to find where the risk actually sits
  3. Check blast radius and existing tests before touching anything
overviewmaphotspotsimpacttests_for
The full breakdown, point by point →

Reviewing code you didn’t write

“A thousand generated lines landed in my queue and the author has no memory of writing them.”

Style a reviewer can judge from the diff. Structure they cannot: what else calls this, what the new coupling does to the module, whether this is the third copy of a helper that already exists twice. Those are graph questions, and they are the ones that matter.

  1. Diff the working tree against the base — metric deltas and smell churn, not opinions
  2. Check the blast radius of anything the diff touches
  3. Search for the thing before accepting a new implementation of it
assess_changeimpactsimilarquality
Why review became the bottleneck →

Onboarding — someone else, or yourself

“I need to be useful in this repository by the end of the week.”

The first two weeks are spent rebuilding a model that already exists implicitly in the code. Reading it out of the graph instead compresses that to an afternoon, and produces the same picture for everyone rather than a different one per person.

  1. Domain map first: what the product does, and which folder claims each part
  2. Structural map of the one area you were pointed at
  3. Open the graph at landmark level, then filter down
overviewmaptracethe graph
The twenty-minute version, step by step →

Giving a coding agent the map

“My agent re-reads six files every turn to work out what calls what.”

An agent pays by the token and the global view never fits in its window. Serving it structure directly — ranked, capped, explicitly truncated — replaces the file-reading it does to reconstruct exactly that.

  1. Ground the task in the domain before opening anything
  2. Map and context instead of reading files one at a time
  3. Impact and tests before the edit; self-review on the diff after
MCP · 10 read-only tools
The eight-step agent loop →

Planning a refactor you can defend

“Everything looks scary, and I have one sprint to make it less scary.”

Complexity alone ranks the ugly. Crossed with git churn it ranks the expensive — code that is convoluted and edited every week, rather than convoluted and untouched since 2019. That difference is the whole argument you take to planning.

  1. Rank by churn × complexity to get a shortlist, not a wall
  2. Name what is wrong there — smells with remediation hints
  3. Size each candidate by blast radius before committing to it
hotspotsqualityimpactdead_code
The metrics and smells behind the ranking →

Keeping documentation true

“Our ADRs are good. Nobody can tell which ones still describe code that exists.”

Decision records age well and say nothing about the present; diagrams say something about the present and are redrawn by hand, which means never. The fix is to make every claim an anchor a machine can check — and to fail the build when one dangles.

  1. Sketch the map one line at a time; deepen only the branch you touched
  2. Point features at the code, and at the decisions that govern them
  3. Let check and drift be the radar — errors fail, hints are a to-do list
elevator --check--drift--code-mapcr.adr:
How it sits next to ADRs, C4 and glossaries →

The other half of the answer

What this is the wrong tool for.

A graph built from source knows what the code is. Every question about what it does at runtime is somebody else's job, and pretending otherwise is how tools like this get abandoned in month two.

Anything at runtime

Why it's slow, why it crashed under load, which branch actually executed. No traces, no profiler, no coverage of its own. Use a profiler and an APM; nao tells you what the suspect code is wired to, not what it did last Tuesday.

Whether the behaviour is correct

It can tell you which tests reach an entity and what a change did to complexity. It cannot tell you the change is right. That's still tests, types and review — the graph just makes each of those land in the right place.

The user's journey

The most common gap in every conversation that leads people here: you haven't used the product you're modifying. Fifteen minutes watching someone complete the workflow beats any amount of static analysis, and nothing here replaces it.

Recognise one of these?

The install is a clone and a script, the analysis runs on your machine, and the first useful answer arrives about a minute later.