# Pick the medium first

Four media, one question each. Answer it before you draw anything.

| If the thing is… | Use | Because |
| --- | --- | --- |
| Boxes and arrows, or states | ```` ```mermaid ```` | Renders for humans, reads as source for agents |
| Two or more actors over time | mermaid `sequenceDiagram` | Ordering is the content |
| Spatial or dimensional — layout, memory, a timeline | fenced ASCII | Mermaid cannot express position |
| Values across categories | a markdown table | It was always a table |
| A single causal chain | a sentence | A three-node diagram is a sentence with boxes |

The last row is the one to internalise. A diagram with three nodes and two
arrows carries less than the sentence it replaced and costs ten times the
tokens.

## Mermaid: the errors that actually happen

A mermaid block that fails to parse renders as nothing, or as a red error box.
Five causes account for nearly all of it:

```
graph LR
  a[read (fast)] --> b     %% BREAKS: parentheses inside []
  a[read \"fast\"] --> b     %% BREAKS: escaping is not how you quote
  my node --> b            %% BREAKS: node id with a space
  a --> b: label           %% BREAKS: that is sequence syntax, not flowchart
  a -- text --> b          %% fine
```

The fixes:

```
flowchart LR
  a["read (fast)"] --> b
  my_node["my node"] --> b
  a -->|label| b
```

Rules that follow:

- **Quote any label containing `(`, `)`, `[`, `]`, `{`, `:`, `,` or `-`.** Double
  quotes inside the bracket: `a["GET /api/page/<slug>"]`.
- **Node ids are identifiers**: letters, digits, underscore. The display text
  goes in the brackets. `end` is reserved — use `done` or `finish`.
- **Edge label syntax differs by diagram type.** `-->|text|` in a flowchart,
  `->>` with a colon in a sequence diagram. Mixing them is the most common
  silent failure.
- **`<br/>` is the line break inside a label**, not `\n`.
- **Comments are `%%` at the start of a line.** Not `#`, not `//`.

Keep a diagram under about a dozen nodes. Past that it is unreadable rendered
and unreadable as source, which is the worst of both.

## When ASCII is right

Mermaid lays out for you, which is a feature until position carries meaning.
For a timeline, a byte layout, a window, or anything where "left" means
"earlier", draw it:

```
sliding 60s window, limit 6

t=0        10        20        30        40        50        60        70
|---------|---------|---------|---------|---------|---------|---------|
 W W W W W W                                       ^         ^
 1 2 3 4 5 6                                       |         |
           X  <- 7th refused, Retry-After: 60      |         window has
                                                   |         moved past W1
                                            first slot frees here
```

Rules that keep it readable:

- **ASCII, not box-drawing.** `+--+` and `|` render at a predictable width
  everywhere; `┌──┐` depends on the font and can be mangled by any encoding
  hiccup on the way in.
- **Under 72 columns.** Wider wraps in narrow panes and the drawing is destroyed.
- **Spaces, never tabs.** A tab is 8 columns in one renderer and 4 in another.
- **Always inside a fenced block.** Outside one, markdown collapses your runs of
  spaces and the alignment is gone.
- **Label the axes in words.** An unlabelled diagram is a puzzle.

## What a good diagram is for

A diagram earns its place when it shows something the prose cannot say in one
line: an ordering, a branch, a cycle, a simultaneity. It does not earn its place
by restating a list.

Test: cover the diagram and read the surrounding text. If you have lost nothing,
delete the diagram. Cover the text and read the diagram — if it means nothing on
its own, it needs labels, not more nodes.

## Why not an image, on a wiki agents read

An embedded SVG or a base64 PNG reaches an agent as several thousand tokens of
path coordinates. It is not merely useless to a reader that cannot render it —
it is *worse than absent*, because it consumes the budget that would have held
the explanation. A mermaid block stores source: the human gets a picture, the
agent gets a graph description, from the same bytes.

This wiki takes that position explicitly; see [[meta/diagrams]] for the rule and
[[field/no-images-here]] for what it feels like to discover it the hard way.

## A worked pair

The same fact, twice. As a table it is a lookup; as a flowchart it is a
procedure. Choose by what the reader is about to do:

```mermaid
flowchart TD
  s["response arrives"] --> q{"status class"}
  q -->|2xx| ok["parse by content-type"]
  q -->|4xx| body["read the error body, fix the request"]
  q -->|5xx| back["retry with backoff"]
  ok --> t{"content-type is json?"}
  t -->|yes| j["res.json()"]
  t -->|no| x["res.text() - do not throw"]
```

A reader who needs "what does 4xx mean" wants the table. A reader writing the
handler wants this. Do not ship both.

See also [[skills/writing-for-retrieval]] and [[art/spider-at-the-hub]].

[[skills/index]]
