How it works
Why you can trust a generated diagram
Architecture documentation usually rots because nothing connects it to the code. nunki's answer is that every claim carries the line it came from, and that line is checked against the commit.
Evidence, not assertion
Each element, edge, operation and flow step records a file path, a line range and, where it applies,
a symbol name. On every run those references are verified against the working tree and the commit
they were pinned to. A reference whose lines have changed becomes stale; one whose file has
gone becomes broken. The book reports its own counts rather than presenting everything as
equally certain, and nunki check turns that into a build failure.
This is also why the tool refuses to guess. Business intent, service ownership and the reason behind
a design are not in the source, so they are marked needs input and left for a human to write
in authored.json — kept visibly apart from what was measured.
A typed IR, not a picture
Nothing draws SVG directly. Every figure is compiled from DiagramIR, a versioned,
schema-checked document describing nodes, edges, containers, evidence and intent. That indirection is
what makes the output editable and reviewable: an IR file diffs in a pull request, survives
regeneration, and can be produced by an agent that is told precisely what is wrong with its draft.
nunki schema # the JSON Schema
nunki validate diagrams/x.ir.json # diagnostics, exit 1 on errors
nunki render diagrams/x.ir.json # compile to HTML or SVG
Diagnostics are machine-actionable. A rejection names the offending element and, where the fix is mechanical, carries a JSON Patch that applies it — which is how the agent loop converges without a human in the middle.
Diagrams chosen for the question they answer
A diagram that shows everything answers nothing. nunki picks the view that fits the question and holds it to a budget: visual density at or below 0.40, at most two focal points, orthogonal routing, and a layout contract enforced by property tests over hundreds of random graphs.
| System context | What the system is and who it talks to. |
|---|---|
| Container | The deployable pieces and what runs between them. |
| Component | Inside one container: modules and their dependencies. |
| Sequence | One request or job, hop by hop, each message linked to the line that sends it. |
| Entity-relationship | The data model: keys, cardinality, ownership. |
| Lifecycle | States read from status fields and the code that changes them. |
| Data flow | Where data enters, is stored and leaves. |
When a repository is too large for one honest picture, the book splits rather than crams: capability groups for a large API, per-domain pages for a large data model, module pages for a modular monolith.
How a flow is traced
A request flow starts at a handler and follows what the code actually does: local calls expanded inline, calls to other services, reads and writes, and published events continued into the handlers that consume them. Resolution follows the language's own idioms — an interface to its implementation, a struct field chain to the type that owns the method, a port to its one adapter — because that is how the dispatch is written, and a trace by name alone stops at the first layer.
A flow is only drawn when it says something a table would not. A request and its reply are not a diagram; a request that writes two stores and publishes an event is.
A system, not a checkout
Most systems are several repositories. Name the others in [workspace] members and a call
that leaves this one is resolved against the service that answers it, with the same matching rule used
inside a single repository — so the flow crosses the boundary and comes back, and the contract on the far
side is described rather than guessed at.
A path stops being an address once there is more than one root, so every citation says which repository it was read from, is verified in that repository at that repository's commit, and links there. A member's operations are never claimed as this repository's own: no requirement, no flow of its own, not in its API surface. It is a dependency, and the book says whose.
The cost is stated rather than hidden. A book describing several checkouts is out of date when any of
them moves, so nunki check fails and names the repository that moved; and a member that is
not checked out is reported, never guessed at — the call stays unresolved and the book says so.
What it cannot see
A book is read from the source, not from the running system. Extraction is necessarily heuristic, and misses dynamic routing, reflection, configuration injected at deploy time, generated code, indirect dependencies and infrastructure provisioned outside the repository. Source files too large to parse are named on the evidence page rather than dropped quietly.
So treat a book as a well-evidenced starting point to review, not as the authority on the architecture.
The citations tell you exactly where each claim came from, which is what makes reviewing it quick — and
the authored.json overlay is where what the tool got wrong or could not know gets corrected.
What it will not do
- Invent intent. If the code does not show why, the book says so.
- Trust a manifest over a call site. A dependency in
go.modis not evidence that the code uses it; the line that calls it is. - Draw a figure it cannot validate, or hide a citation it could not verify.
- Send your source anywhere. Everything runs locally, and the book embeds only the excerpts it cites.