Every software project has two versions of its architecture.
The first version is the diagram. It lives in a README, a Confluence page, a Miro board, or a decisions document. It was accurate on the day it was drawn. Within weeks it begins to drift from reality — a new system gets added, a dependency gets removed, a data flow gets rerouted. The diagram does not know. Nobody updates it. Eventually it becomes archaeology: a record of what someone believed was true at a specific moment in the past.
The second version is the code. It is always accurate. It cannot lie. But it is also illegible to anyone who has not spent significant time inside it. The mental model a developer needs to work effectively in a complex system — which component fires when, what triggers what, where state lives and how it travels — that model cannot be read from source files. It has to be accumulated through exploration, through breakpoints, through console logs, through asking someone who has been here longer.
Most documentation lives in the first version. Most understanding lives in the second. The gap between them is where new developers get lost, where onboarding takes weeks instead of days, and where AI agents — which have to reconstruct context from scratch each session — struggle most.
I want to describe a third option.
A Diagram Built From Signals
When we built the endless runner framework, Phase 7 produced a debug panel with four tabs. The fourth tab was an architecture diagram. But it was not a static diagram. It was a canvas that updated on every animation frame, and when any framework system fired, that system’s node on the diagram would pulse.
The EventBus fires — its node glows and emits a small dot that travels along the edge to the ReactiveState node, which then glows in turn. The CommandQueue processes a jump input — its node pulses, sends a dot to the StateMachine, which pulses and sends dots to both the BehaviorStack and the UI. The SnapshotManager runs its 3-second interval — its node glows briefly and fades.
While the game is running, the diagram breathes. Every part of the system that is active makes itself visible at the moment it is active.
The implementation is simple. Each system calls a single method at the point where it does its work:
arch.pulse('eventBus', '#00ffcc');
The diagram class maintains a timestamp per node. On every draw frame, it calculates how long ago each node last pulsed and renders a glow that decays with that elapsed time. Packet animations travel along pre-defined directed edges between nodes. That is the entire mechanism.
No system knows anything about the diagram. The diagram knows nothing about any system except node IDs and edges. The coupling is one directional and trivially reversible.
Why This Matters More Than It Seems
The obvious value is visual appeal. A pulsing architecture diagram in the corner of a game demo looks impressive. But that is the least important thing about it.
The deep value is this: it eliminates the gap between the first version and the second.
When a developer opens this framework for the first time — or when an AI agent begins a new session on this codebase — the question is not “what does this code do?” The question is “what is actually running right now, and in what order?”
That question cannot be answered by reading source files. It can only be answered by observing the system under load. The live diagram is that observation made explicit and continuous. You do not need to add breakpoints or console logs. You do not need to ask someone how the system flows. You watch it run and it shows you.
This is especially valuable for AI-assisted development. An agent working on a complex system in a new session has to reconstruct its mental model of what exists from whatever context is available: memory files, file reads, the conversation history. The live diagram does not help with that reconstruction — it is a runtime artifact, not a static document. But it represents a principle that does transfer: the system should explain itself.
A system that explains itself at runtime can also be made to explain itself at read time. The same pulse signals that drive the diagram can write structured logs. The same node graph that shows data flow in the browser can be serialized to a JSON file that an agent reads at session start. The architecture is not just running code anymore — it is a documented, structured, observable object.
Living Documentation
There is a term for this in observability engineering: instrumentation. Every production system worth running has metrics, traces, and structured logs. Developers in operations treat this as obvious. Developers building application frameworks treat it as optional, something to add later if there is time.
The live diagram is instrumentation applied to the framework layer rather than the infrastructure layer. The systems being observed are not database queries or HTTP requests — they are the game’s own components. The EventBus, the BehaviorStack, the ChunkRegistry. The things that junior developers and AI agents struggle to understand because they are abstract and internal.
Instrumentation makes the abstract concrete and the internal visible.
There is an important distinction between documentation and instrumentation. Documentation describes what was built. Instrumentation shows what is running. Documentation goes stale. Instrumentation cannot — it is derived from the live system at observation time. If the system changes, the instrumentation changes with it automatically. The diagram shows the truth because it is reading the truth directly.
This is why the architectural commitment matters. The diagram class does not parse source code or read configuration files. It does not try to be clever about inferring system topology. It only knows what it is told, at the moment it is told, through the pulse interface. That narrowness is what makes it accurate. There is no interpretation layer where staleness can enter.
The Pattern Generalized
You do not need a game or a canvas renderer to apply this principle.
Any complex system — a framework, a CLI tool, an API server — can instrument itself in the same way. The components emit signals when they do work. A listener aggregates those signals into a structured trace. The trace is readable both by a human (as a visualization or log) and by a machine (as a JSON structure an AI agent can consume at session start).
The implementation cost is close to zero. One method call per system at the point of action. A listener that is decoupled from everything it observes. A rendering layer that reads timestamps and computes glow values — or, in a non-browser context, writes structured lines to a file.
The return on that investment compounds. Every new developer who works in this codebase, every AI agent that begins a new session, every debugging session after a production incident — all of them start from a system that has been showing its own structure since the day it was built.
The diagram you draw on the first day of a project is outdated by the second day. The diagram that pulses while the code runs is always accurate, because it is not a diagram at all. It is the code, made visible.
One Implementation Note
The hardest part of building a live architecture diagram is not the rendering. It is resisting the temptation to make it smarter.
The first instinct is to make the diagram automatically discover the system topology — parse imports, trace call stacks, infer edges from data flow. This is a seductive idea and a bad one. Auto-discovery is fragile, slow, and produces diagrams that are technically accurate but architecturally misleading, because they show all the edges, not the important ones.
The value of the live diagram comes from intentionality. A human — or an AI agent working with a human — decides which nodes matter, which edges represent the conceptually significant data flows, and where in each system’s code the pulse call belongs. That decision process forces an act of architectural reflection that is itself valuable, separate from the diagram it produces.
The diagram is a form. Filling in the form forces you to understand what you built.
Build it. Fill it in. Then let it run.