infraviz

Anything an LLM writes about your code is a claim, not a fact.

infraviz maps your API's real architecture — request flow, risk, what to fix first — using the coding agent you already have. Every claim it makes must carry an exact substring from the file it cites. One command re-reads your source and tells you which claims still hold.

No account, no server, no telemetry. It runs on your machine and writes JSON into your repo.

$ npx infraviz view or open the desktop app and drop a folder on it
MIT licensed 2 runtime dependencies 0 network calls in the CLI 127.0.0.1 only

I.  The rule everything hangs on

A citation you can check is worth more than a paragraph you can't.

Ask any coding agent to document your architecture and you get something plausible. Plausible is the problem: a hallucinated finding and a real one look identical on the page, so the whole document has to be re-derived by hand before anyone can act on it — which is why nobody does.

infraviz makes that check mechanical. Each finding carries a fingerprint: a short, exact, character-for-character quote from the file it names.

{ "title": "GET /api/media/:id hands any attachment to any caller", "file": "backend/lib/wavelink_web/controllers/media_controller.ex", "fingerprint": "def show(conn, %{\"id\" => id}) do", "breaks": "show/2 performs no ownership or membership check — it forwards the id to media-service and returns the record along with a signed URL for the bytes. Media ids are generated from a timestamp, so they can be walked rather than guessed.", "fix": "Build the media_id → conversation_id index the comment says is missing, and confirm the caller is a member before resolving." }

npx infraviz verify opens the real file and looks for that substring. If the code moved on, the claim fails — visibly, next to the finding, labelled unverified claim rather than quietly dropped.

$ npx infraviz verify infraviz verify ~/portfolio/demo/chat-demo schema ok · 27 verified · 0 failed · 0 judgment-only
That output is real, and so was the failure before it. Generating the example on this page, one fingerprint didn't match — a quote copied across two lines that doesn't exist as a contiguous substring. verify caught it, named the file, and the claim was fixed before anything shipped. That is the entire mechanism working, and it is worth more than a page of assurances.

Two consequences follow, and they are the reason to bother:

  • Hallucinations become visible instead of indistinguishable from real findings.
  • The docs can't rot silently. verify --strict is a CI gate that fails when the diagrams drift away from the code they describe.

The spec also permits the agent to report nothing. A generator forced to produce five findings will invent five, and one invented finding devalues every real one beside it.

II.  It has no model of its own

It drives the agent already sitting in your editor.

There is no infraviz account, no infraviz API key and no infraviz inference bill, because infraviz does no inference. It ships a specification — the schema, the evidence rules, the prompts — and hands it to whichever agent you use. Claude Code, Cursor, or Codex, on your machine, under your existing subscription.

Two paths, and they write the same files, so you can switch mid-way. Run it from the app if an agent CLI is on your PATH. Or copy a prompt and paste it into your IDE — the open page picks up the files as they land, with no reload.

The infraviz start screen, showing that Claude Code was detected on the PATH, with model and effort selectors, next to a card offering a copyable prompt for your IDE instead.
detected Claude Code v2.1.224 was found on this machine's PATH. Both paths are offered as equals — nothing here is unavailable if you have no CLI installed.

III.  An end-to-end run, start to finish

One real repository, from an empty page to a ranked list of fixes.

Everything below came out of one actual run against wavelink — a Phoenix chat backend in Elixir with a React client, seven HTTP surfaces, DynamoDB behind it and an external Go service for attachments. The steps are screenshots, because they show states you have to be mid-run to see. The result is the viewer itself, embedded below and loaded with that run's real output. Nothing here is a mockup.

01

Open it on a repository

The desktop app starts with no repository loaded and asks for one — pick a folder or drop it on the window. From a terminal, npx infraviz view does the same thing for the directory you are standing in.

The infraviz desktop app's opening screen, headlined 'See what your system actually does', with a diagram showing a background write that outlives the HTTP response, and a 'Choose a repository' button.
02

Read what you are agreeing to, before anything is read

Nothing touches the codebase until this is acknowledged, and the local server enforces that rather than merely displaying it — the run endpoint returns 403 without a recorded acceptance. The wording separates what infraviz does from what your agent does, because claiming "no data leaves your machine" would be false. It is recorded per repository, so a different repo asks again.

The consent gate, naming the repository path and listing five points: infraviz receives nothing, your coding agent is what reads your code, cloud connectors only look, the output is confidential, and the agent may run your tests.
gate Five points, including the two that are inconvenient to say: your agent reads more of the repo than a normal question would, and it may run your test suite.
03

Choose the model and how hard it should think

The picker is available at every run, not just the first, because the choice is not one decision. A cheap scan maps the whole repository; the expensive per-service passes come later and can use a different model. This run used Sonnet.

The same start screen with the model selector open on 'Sonnet 5 — balanced' and an effort selector set to medium.
04

Watch it work

A scan takes minutes, and a page that sits still for minutes is indistinguishable from a page that has hung. So the agent reports each step as it goes, and the server streams those steps straight into the open tab — including when the agent is running in your IDE rather than here.

A live progress panel reading 'Scanning your codebase', 1m 06s, 4 steps, with timestamped lines: reading the Phoenix router and controllers, found 5 HTTP endpoints across 4 controllers, reading conversation, inbox and directory channels.
live Real timestamps from the run that produced this page. The agent followed the thin routers into the channels and the domain modules underneath, which is where wavelink's real behaviour lives.
05

The overview leads with what it cannot answer yet

Four questions, scored separately, because different questions need different artifacts. A half-analysed system that presents itself as complete is worse than one that admits the gap — so coverage is stated per question, and any partial answer names which services it covers.

Underneath, everything found so far collapses into one ranked list across the whole system. Ranking is mechanical and stated rather than a black box: risk before improvement, low effort before high, and a boost for anything landing in several services — because that is one change, not five. Findings citing the same substring in the same file are merged, so three services reporting the same shared-module problem become one item, not three tickets that never get made.

Depth is tiered on purpose, and abstaining is a correct answer. wavelink's health check is ten lines with no branches. Its entire entry reads: "Returns a static ok without checking any dependency, which is the correct shape for a load balancer liveness probe." No findings, no diagrams. Padding it would only train you to skim past the real ones.
06

Then go one service deep, on the services you choose

Per-service passes are the expensive part, so they are never done for the whole repo at once. You pick. Each service gets a sequence diagram of what actually happens in order, a topology of who talks to whom, and a ranked list of what to improve. Look for the boxed phases in the diagram: one marks a synchronous call to a third-party service standing between the user and the durable write, the other marks work that keeps running after the response was already sent — which is where the interesting failure modes live.

Live  not a screenshot

Everything above, running.

This is the viewer itself, loaded with that run's output — the overview, all seven services, the sequence diagrams and every lens. Open Conversation Channel or Media in the sidebar, click a step and watch the matching hop light up with its code location. Nothing here can start a run or copy a prompt: there is no agent behind this page, so those controls are absent rather than dead.

wavelink · read only ↗ New tab

The viewer needs about 1024px to show its sidebar, and the sidebar is how you move between services. In a window this narrow it reads far better in a tab of its own.

Open the viewer ↗
live Same bundle as npx infraviz view, in read-only mode against a static snapshot of that run. Fullscreen keeps this bar, so the way back out is where the way in was — or press Esc.

IV.  What you get

Seven lenses, and the honesty to leave one blank.

Not every lens applies to every service, and none of them are offered when the data behind them does not exist.

Flow
The real call graph. Click a step, the matching hop highlights, with its code location.
Load / scaling
Measured numbers when they exist — otherwise it says plainly that load is not measured.
Security
Findings anchored to the hop they affect, in severity colour, each citing a line.
Compliance
Data handling, retention, egress.
Reliability
Compounding failure across dependencies. Drag the fan-out slider and watch end-to-end success collapse.
Deployment
What is actually running and what it actually costs — provisioned against observed, from a read-only cloud session you already have.
Optimise
Ranked improvements: cost of inaction, gain, effort, mechanism. Each copyable as a task for your agent.

Plus a sequence diagram per service, auto-laid-out, including the work that continues after the HTTP response. And production checks that follow from what kind of system you actually built — an LLM application and a CRUD endpoint fail in different ways. Every check names an established reference, and a check nobody examined reads as unknown, never as a pass.

V.  Who this is for

The people who need this are the ones who already stopped trusting generated documentation.

If you have never been burned by a confident, wrong diagram, you may not need the citations.

You inherited the system

A map of a codebase nobody currently understands, where every line can be traced back to the file it came from — so you can check the parts you doubt instead of accepting all of it.

You are about to be on call for it

The compounding-failure view and the work-after-the-response boxes surface the failure modes that only show up at 3am, before they do.

You need to justify the next quarter

One ranked list across the whole system, deduplicated, with the cost of inaction stated per item — which is the shape a prioritisation argument actually needs.

Your docs drift the week they are written

verify --strict in CI fails the build when the diagrams stop describing the code, which is the only version of documentation maintenance that survives contact with a deadline.

VI.  What it costs you

The case against, stated by the people who built it.

None of this is disqualifying, and all of it is easier to hear now than after you have pointed it at a work repository.

Your code still goes to your AI vendor — and more of it than usual

infraviz sends nothing anywhere. Your agent does, exactly as it does for every other request you make of it. But the spec asks it to read broadly: your routers, the modules they import, your infrastructure config, and your tests. That is more of your repository than a typical question touches. If your organisation restricts which repos may be sent to an AI provider, that restriction applies here unchanged.

The output is more sensitive than your source

.infraviz/ holds verbatim code snippets and a prioritised, file-accurate map of your weak points. That is useful to you and equally useful to an attacker. Gitignore it by default — infraviz does this for you — and never commit it to a public repo. It is not "safe to commit".

The agent may run your test suite

The spec tells it to, because tests reveal what is actually exercised. On a work machine that could reach real dev services, write cache files, or consume API quota. Tell it not to, if that matters — it will listen.

Depth costs real money and real time

The scan is cheap. Per-service passes are not, which is exactly why they are opt-in one service at a time rather than a single whole-repo run that bills for hours and produces more output than anyone reads.

The consent gate cannot stop your agent reading your files

It refuses to hand over the prompts until you accept, so the analysis proper cannot proceed. But an agent already has your file tools, and no third-party package can gate them. If you want nothing touched before you have read the notice, say so in your first message — that is the only instruction with enough weight, and it works.

Not everything is built

The cost and rate-limit lenses aren't portable yet, so they are not offered rather than showing someone else's numbers. The MCP server is under consideration rather than planned. The desktop app is an Electron shell still being finished. All three are absent on purpose instead of faked.

VII.  What infraviz itself receives

Nothing. There is no service behind it.

This is structural rather than a promise, and it is checkable from the published package.

Network calls in the CLI
None. The npm download is the only network activity.
Server binding
127.0.0.1 only — not reachable from your network.
Telemetry & analytics
None.
Third-party dependencies
Two — zod and cross-spawn.
Cloud connectors
Use the aws/oc/kubectl session you already have. No token field, nothing stored, and every command is checked to be read-only before it runs.