System design

From system design to code.

What has to be true for a drawing to become a build.

Download for macOS
v0.1.33 · .dmg · Apple Silicon & Intel
Signed & notarized by Apple · opens without a Gatekeeper warning
sha256 698955a0187bc039f4c74f5d05a9f10fbb27376a45788a0a241d1326b73873c7
Download for Windows instead
$curl -fsSL https://lucidtrain.com/install.sh | sh

Turning a system design into code requires the design to be a structured model rather than a picture: components, the edges between them, and the file each one maps to. Lucid Train generates a specification from the drawn system and hands it to the coding agent as the brief, then applies each sub-agent's work through an isolated git worktree so a multi-component change can be built in parallel without conflicting edits.

A drawing is not a specification

Boxes and arrows carry almost no information a machine can act on. Two rectangles joined by a line could be an HTTP call, a queue subscription, a shared table or a build dependency, and an agent given the picture alone will guess. The step that makes the handoff work is converting the drawn system into text that names each component, the relationship on every edge, and the path in the repository where that component lives.

The specification the agent receives

Lucid Train derives the brief from the same scene the canvas draws, so the specification and the picture cannot disagree about what the system contains. Each node carries a real path relative to the repository root, which means the agent starts with the files it needs open rather than searching for them, and a claim about a component can be checked against the file it cites.

Building the parts in parallel

A design change that touches five components is five edits that mostly do not overlap, and running them sequentially wastes most of the available time. Lucid Train executes sub-agents in isolated git worktrees and applies the resulting diff back, so parallel work cannot produce the half-applied edits that concurrent writes to one checkout otherwise cause. A worktree that comes back unchanged is discarded.

Catching the drift

The implementation will diverge from the design, usually in the first week. What makes that survivable is the return path: redraw the architecture from the repository and compare it to what was agreed. Because the layout is solved rather than dragged, the two pictures are directly comparable, and a component that has quietly grown four new dependencies is visible rather than buried in a diff.

Verification before a human looks

The step people skip is checking the agent's output before reading it. Computational checks are the cheap ones and should run first: type checkers, linters and tests are deterministic, take seconds, and answer reliably. Inferential checks such as an LLM reviewing a diff are slower, cost more and are non-deterministic, so they belong after the cheap checks have already rejected the obvious failures.

The prompt that starts the loop

shell
$ Draw the architecture of this repository, then implement the new notification service against it.
FAQ

Questions

How does a diagram become code?

The drawn system is converted into a written specification naming each component, the relationship on each edge and the file path it maps to. That specification becomes the coding agent's brief.

Can several components be built at once?

Yes. Sub-agents run in isolated git worktrees and their diffs are applied back, so parallel edits do not overwrite one another. Setup costs a few hundred milliseconds and disk per agent, so it is worth it for genuinely independent work.

What stops the code and the diagram diverging?

Nothing stops it, and expecting otherwise is the mistake. The architecture is redrawn from the repository so that divergence becomes visible, which is the achievable goal.

Related