Code arrives faster than it can be read
A prompt produces a thousand lines in a minute. A reviewer still reads at reading speed. The queue that used to form at authoring now forms at comprehension, and it is growing.
Open source · Rust engine · AGPL-3.0
A map of a tangle is still a tangle. LLvator measures both halves of what makes a codebase readable — the structure it actually has, derived from source and never written by hand, and whether that structure holds at every level you zoom to. For the humans reviewing, and for the agents writing faster than anyone can read.
see the structure
Mezzanine — one Rust binary that parses 15 languages into a single typed graph: every entity, every relationship, complexity and blast radius, measured.
keep the structure
Folder shape — a four-tier ladder scored on the graph each folder draws, and the one move that lifts a folder one rung.
15 languages · no annotations to write · runs on your machine · nothing phones home
The new constraint
Three things changed at once, and all three land on the same place: comprehension — the one part of the loop that never got faster. There is a fourth thing, and it is the one that decides whether the other three can be fixed at all.
A prompt produces a thousand lines in a minute. A reviewer still reads at reading speed. The queue that used to form at authoring now forms at comprehension, and it is growing.
What calls this. What breaks if it changes. Which module it belongs to. That model used to live in the author's head and never got written down — and the author is now a process with no memory of last week.
Output quality is capped by how well the model grasps the system it is editing — and rebuilding that by opening files is slow, expensive and partial. Handing an agent the high-level architecture up front, without it having to read the repository to get there, is what moves the ceiling.
The fourth thing
This is the part we got wrong first. Give someone a perfect, always-current map of a badly organised codebase and they still cannot hold it — because the problem was never that the structure was invisible. It was that the structure is unholdable. Past a certain messiness the picture stops being readable, and no amount of colouring, filtering or zooming brings the reading back.
Readers who can follow one graph and not another are not reacting to size. They are reacting to shape. The drawings that survive being looked at are the ones that hold the same form at every zoom level — a handful of children at each step, each of them the same kind of thing one level down. The ones that do not are cycles and tangles, and they are unreadable at any magnification.
So Mezzanine measures that too, on a four-tier ladder, over the graph the canvas actually draws. Not a score you interpret — a named blocker and a single next move.
The ladder, the seven gates, and the one that is a convention →
The top tier is recursive by construction: a folder cannot be fractal while sitting on top of a mess. That is what makes it a claim about self-similarity across zoom levels rather than one level's opinion — and it is what turns a wall of findings into an ordered queue, deepest actionable folder first.
Folder shape, reshape and mezz check arrived in Mezzanine
1.3.0. Everything shown on /shape is verbatim output
from that binary.
What LLvator does about it
Not four products — four ways of reading the same derived structure, one for each thing that broke.
answers 01
map a folder and get its entities ranked by complexity and coupling; assess_change tells you what a diff did to those numbers, and hotspots crosses complexity with git churn so the code that is both hairy
and moving surfaces first. You still read code — you stop reading it in file order.
answers 02
The graph is recomputed from source on every save, so it cannot go stale: there is
nothing to keep up to date, because nothing was written by hand. The one layer that is authored — Elevator, for the business vocabulary a
graph cannot infer — is checked against the code, and --drift fails when a claim stops matching.
answers 03
15 read-only MCP tools: overview for the shape of a repository
it has never opened, map instead of reading ten files, impact before an edit, tests_for instead of the whole suite. Compact ranked text —
structure it would otherwise spend its whole budget reconstructing.
answers 04
quality scores every folder on the shape ladder and lists what is short of
fractal in work order; reshape hands back the folder's own drawing and the
single move that lifts it one rung. mezz check holds a bar in CI — one the
project wrote, never one Mezzanine shipped.
What this looks like on an inherited codebase, in a developer's own words →
Or the five other situations it comes up in →
The gap
precise · pointwise
Exact go-to-definition. For one symbol, one hop, one question at a time.
flexible · structureless
Finds any string anywhere. Returns text, never entities — you rebuild the structure in your head, every time.
high-level · stale
Written once, true for a quarter. The diagram in the wiki describes a system that shipped two refactors ago.
holistic · structural · derived
The whole repository as one typed graph, recomputed from source on every save — plus a reading of whether that graph can be followed at all. Nothing to keep up to date, because nothing was written by hand.
That mid-altitude view is exactly what a newcomer lacks for their first two weeks — and exactly what does not fit in an agent's context window. It is the only layer where "is this change safe?" has an answer.
Not a screenshot
Nothing here runs on a server: each graph was baked ahead of time by the same mezz analyze you get from the CLI, then frozen. Pick a repo, drag it around,
click a node.
analysing…
The red rings are code smells the analyzer flagged. Node size is degree — how much of the codebase touches it. The larger explorer lives here →
One graph, five questions
“What is the shape of this code?”
Folder-level maps with complexity and coupling annotations, shortest dependency paths between any two entities, and an interactive graph in VS Code that follows your cursor.
“Where does this code hurt?”
God Class, Dispatcher, Feature Envy, Shotgun Surgery. Ranked by composite refactor pressure, and crossed with git churn so complex-but-stable code stops shouting.
“What happens if I touch this?”
Blast radius level by level, exact at the type level in the typed-parser languages and approximate everywhere else. Which tests actually reach the entity. What your working tree did to the metrics.
“Help me write this.”
A minimal edit pack — the target plus the signatures of everything around it — and a does-this-already-exist search before you write the helper for the third time.
“Can this still be followed?”
Every folder placed on a four-tier ladder, scored over the graph it actually draws, with the one gate that capped it named rather than blended away — and the single move that lifts it one rung.
The full surface — metrics, smells, the languages, the limits →
What you actually install
The analysis, the picture and the editor integration are separate programs, and they depend on each other in one direction only. The engine has never heard of the UI; the UI has never heard of VS Code. So you can take the graph and skip the pixels — or take the whole thing.
One floor up
A graph tells you how the code is wired. It cannot tell you what the product does, or which capability a folder belongs to. Elevator is a small spec language for that layer — Categories on the ground floor, Features above them, verbs as leaves.
It is the one layer that is authored rather than derived, so it is built sketch-first: name an area in one line the day you learn it exists, deepen only the branch you just worked on. Nothing is mandatory. A body-less definition is a complete, valid map entry.
--check catches broken references, --drift catches a spec that
has quietly stopped matching the code it claims.
# Mezzanine's own domain map, one floor above its source.
c code_graph {
d: "The typed entity/relationship graph every other surface reads."
f parsers, f metrics, f smells
}
f metrics {
d: "Per-entity complexity and coupling, computed post-parse."
cr: "src/analyzer/metrics.rs"
fu computation, fu rollup
}
concept determinism {
d: "Identical trees produce byte-identical graphs — every delta is signal."
used_by: f.metrics, f.parsers
}{
"mcpServers": {
"mezz": { "command": "mezz", "args": ["mcp"] }
}
}15 read-only tools. Compact ranked text, explicitly truncated, filtered of the noise a graph accumulates — built for a consumer that pays by the token.
For the thing writing most of the code
A model optimises for the change compiling, not for the folder still being followable afterwards. Nothing in the loop pushes back: it writes the helper where it is convenient, imports across the sibling boundary because that resolves, and every one of those choices is locally reasonable and collectively a merge.
So give it the reading it is missing. map a folder instead of opening ten
files, impact before an edit, tests_for instead of the whole
suite — and reshape when a folder slips a tier, which hands back the drawing
and one specific move rather than an adjective. assess_change closes the loop
on the diff it just wrote.
Because analysis is deterministic — identical trees, byte-identical graphs — every delta the agent reports back is real signal rather than parser noise. That is what makes the shape score usable as a feedback signal at all: a number that drifted on its own could not be optimised against.
The agent loop, step by step →Honesty
Call-edge resolution against a rust-analyzer oracle: 93.7% recall at 98.6% precision, on Mezzanine itself, Rust, tests included, 3,649 exactly-resolved call edges.
Re-runnable from the repo — the benchmark script ships with it.
An empty impact result is strong evidence, not proof. Roughly one
real dependent in sixteen is still missed, so “used by (0)” on something you expected
to be called is a reason to check, not an all-clear.
That figure is one corpus in one language, because rust-analyzer is the only oracle wired up. Assume the other parsers are worse, not equal — JavaScript reads through the TypeScript walk as of 1.4.0, but no parser other than Rust has had its call-edge recall measured at all.
The full limitations page — including what the parsers still miss →
One command for the engine alone; one script for all three. No account, no service, no telemetry — the analysis never leaves your machine.
# the engine, on its own
cargo install --git https://github.com/llvator/mezzanine.git --force
# or everything, including the VS Code extension
git clone https://github.com/llvator/mezzanine.git && cd mezzanine && ./scripts/install.sh