Open source · Rust engine · AGPL-3.0

Understandable code
holds its shape.

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

93.7%call-edge recall
98.6%precision
15dedicated parsers
15MCP tools for agents
4shape tiers per folder
Measured against a rust-analyzer oracle, not asserted. Which languages, and how far →

The new constraint

Writing code stopped being the bottleneck.
Understanding it didn't.

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.

01

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.

02

The mental model has no owner

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.

03

An agent is only as good as its understanding of the code

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

You cannot read your way out of a tangle.

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 →

  1. 0
    Cyclic nothing — this is the floor
  2. 1
    Tangled acyclicity
  3. 2
    Hierarchical layering
  4. 3
    Fractal breadth, branching, doors, and children that hold the same shape

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

Four pain points. Four answers, from one graph.

Not four products — four ways of reading the same derived structure, one for each thing that broke.

answers 01

Review the shape, not every line

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 mental model is derived, so nobody has to own it

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

Hand the agent the architecture up front

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

Keep the structure worth reading

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

Every tool you have is at the wrong altitude.

LSP

precise · pointwise

Exact go-to-definition. For one symbol, one hop, one question at a time.

grep & reading

flexible · structureless

Finds any string anywhere. Returns text, never entities — you rebuild the structure in your head, every time.

Documentation

high-level · stale

Written once, true for a quarter. The diagram in the wiki describes a system that shipped two refactors ago.

Mezzanine

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

Seven graphs, analyzed by the engine you'd install.

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

Everything Mezzanine does is a different way of asking the same graph a question.

Cartographer

“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.

maptraceoverview

Auditor

“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.

qualityhotspots

Impact analyst

“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.

impacttests_forassess_change

Implementation support

“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.

contextsimilar

Organiser

“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.

qualityreshapecheck

The full surface — metrics, smells, the languages, the limits →

What you actually install

Three pieces, and only one of them is mandatory.

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.

What each piece needs, and the three ways in →

One floor up

Elevator: the domain, above the code.

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.

Read the language →
spec/code_graph.elv
# 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
}
.mcp.json
{
  "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

An agent will happily generate a tangle.

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

We measured it. Here is where it stops.

What was measured

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.

What that means

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.

What isn't measured

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 →

Install as much as you need.

One command for the engine alone; one script for all three. No account, no service, no telemetry — the analysis never leaves your machine.

~ install
# 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