ADR-0001 — Declare structure, not layout

Marrow computes exactly one layout from declared meaning. There is no layout key and no manual arrangement.

Status: accepted

Topology YAML has no way to choose or influence a layout. Authors declare what things aretier, zone, ha_pair_with — and the compiler classifies the topology into one of six archetypes, computes a single layout, and lints the result. Meaning is declared and never inferred from names.

Why

The alternative — letting authors pick a layout, or nudge positions — makes the diagram's arrangement a second source of truth that has to be maintained alongside the network description. Every subsequent change then has two edits: what changed, and where it should now sit. That is precisely the maintenance burden that makes hand-drawn network diagrams rot.

Deriving layout from meaning means a change to the network is a change to one place. It also makes a fleet of diagrams consistent with each other: tier: core produces the same visual rank in every file anyone authors, without a style guide anybody has to follow.

There is a second, harder reason: this is what makes the tool drivable by an agent. An agent can reliably state that a device is a core switch. It cannot reliably decide that the core switch belongs 340 pixels from the left. Removing position from the authoring surface removes the part an agent is worst at. See ADR-0002.

Consequences

You cannot nudge anything. When a diagram looks wrong, the description is wrong. This is genuinely frustrating the first few times and is the most common complaint the design will attract.

pin: exists as an escape hatch and is discouraged. It bypasses placement, so it can produce the overlaps the geometry linter then refuses to build, and it rots as the topology changes around it.

Classification rules are a public contract. Because authors control layout only through classification, the rules must be documented precisely and changed carefully — the hub-spoke purity requirement in particular has surprising consequences (one spoke-to-spoke link drops the whole topology to layered).

The archetype is surfaced in the output. Every diagram shows its chosen layout in the sidebar, because a user who can't influence the choice at least needs to see it.

Considered and rejected

A layout: key. Rejected: reintroduces the second source of truth, and the engine would have to handle layouts that don't suit the declared structure.

Inferring structure from naming conventions (core-* → tier core). Rejected: silently wrong on the first network that doesn't follow the guessed convention, and impossible to debug when it misfires.

Multiple layout variants per topology, as v1 did with its engine × layout matrix. Rejected in v2: it multiplied output without helping anyone choose. The inert x-v1-config: block is the fossil of this.