Skip to content

Advisories

An advisory is a finding about a spec that parses fine but reads badly: a vague label, an isolated node, a box too wide to fit. Advisories never stop a render. They are for the author, and for an agent that writes specs and lints them before showing anything.

diago check prints the findings of a spec and lays nothing out:

Terminal window
diago check spec.json # one line per finding, exit 0
diago check -strict spec.json # exit 1 when any finding remains
diago check -json spec.json # {"warnings": [...]}

Every render and diff prints the same findings on stderr after the output, each line led by warning: . check never lays out, so two rules can only appear on render and diff: text-label-dropped (text format) and flat-edge-ranked (any format, and only when a flat edge falls back). edge-without-id also needs one of them, because it only matters under render -previous and diff, where ids decide which element is which.

This is diago check on a flow spec with a node nothing connects to and a vague label:

isolated-node nodes[3]: node "cache" is connected to nothing; connect it or remove it
vague-edge-label edges[0]: edge web->api label "uses" says little; prefer a specific verb phrase like "validates order" or "publishes event"

<rule> <field>: <message>, or <rule>: <message> for a finding about the whole diagram. field is a path into the spec, in the same form as a validation error’s, such as nodes[3]. On render and diff the line starts with warning: , and in a diff the field is prefixed before. or after.. A finding both versions raise alike, with the same rule, field and message, is listed once, under after.. Findings are sorted by rule, then by field in natural order (nodes[9] before nodes[10]), then by message, so the output can be compared between runs.

Node and actor ids are written into messages as they are, so an id with quotes or control characters can make a line awkward to parse. -json is the machine-readable form:

{
"warnings": [
{
"rule": "isolated-node",
"message": "node \"cache\" is connected to nothing; connect it or remove it",
"field": "nodes[3]"
},
{
"rule": "vague-edge-label",
"message": "edge web->api label \"uses\" says little; prefer a specific verb phrase like \"validates order\" or \"publishes event\"",
"field": "edges[0]"
}
]
}

A finding about the whole diagram has no field key. With no findings, warnings is an empty array.

diago check -strict exits 1 while any finding remains. That is not the exit 1 of render and diff, which means a validation error: with -strict the findings are printed as usual and the exit code is the verdict. It suits a lint step before a diagram is shown or committed.

A spec silences rules with a top-level ignore array:

"ignore": ["vague-edge-label"]

The array applies to every finding of that spec, including text-label-dropped and flat-edge-ranked. A name that is not a rule below is a validation error on ignore[n] (unknown advisory rule "nope"; see diago check, exit 1). Ignore a rule only when the finding is deliberate; otherwise fix the spec.

Each diagram type runs its own rules. A class diagram runs only the class rules, plus edge-without-id over its relations, empty-group over its packages and text-label-dropped; unknown-field and removed-field run on every type. All 23 rules, by name:

Rule Diagrams Fires when Usual fix
deep-nesting sequence A fragment is nested more than 3 levels deep, by range containment. Flatten it, or split the diagram.
duplicate-edge flow Two edges have the same from, to and label. Drop one, or give them different labels.
edge-without-id flow, class A labeled edge, or any class relation, has no id. Only under render -previous and diff. Give it a stable id that survives edits.
empty-group flow, class A group, or a class package, whose contains is empty. Fill it or remove it.
flat-edge-ranked flow A flat edge has no clean side route and is laid out as an ordinary edge, or is kept as one from an earlier anchored layout. render and diff only. Accept it (the diagram still renders, the two ends just do not sit side by side), drop flat from the edge, or keep one ordinary link on its nodes. Under -strict, add the rule to ignore for that version only.
god-class class A class has more than 15 attributes and methods together. Split its responsibilities into smaller classes.
isolated-class class A class no relation touches, in a spec of two or more classes. Connect it or remove it.
isolated-node flow A node no edge touches, in a spec of two or more nodes. Connect it or remove it.
long-label flow, sequence A node, group, actor, message or section label is over 60 characters. Shorten it or move the detail elsewhere.
no-entry flow Every node has an incoming edge. Self-loops and flat edges do not count as incoming. Add a start node, or break a cycle.
overlong-member class A member line (visibility, a space, then the text) is over 40 characters. It widens the box. Shorten the signature or its types.
oversized-class-diagram class More than 20 classes. Split into linked sub-diagrams.
removed-field flow, class A spec still carries a removed top-level key: style, hints or alignment on a flow spec, style on a class spec. The key is ignored. Delete it. diago is orthogonal-only.
seq-too-many-participants sequence More than 8 actors. Split into focused diagrams, or collapse minor participants.
shape-soup flow More than 5 distinct node shapes. Reserve each shape for one consistent role.
text-label-dropped flow, class The text renderer could not place an edge label or a cardinality without overwriting other ink. render and diff with -format text only; the line has no field. Shorten the label.
too-large flow More than 20 nodes. Groups never count. Split into linked sub-diagrams.
unbreakable-token flow, sequence A run of over 24 characters without whitespace in a label that long-label covers. Wrapping only breaks at whitespace, so it widens its box. Shorten it or add separators.
unknown-field all A JSON key the schema does not know, at any depth. The key is ignored; the message suggests the nearest known key. Fix the spelling, or delete the key. A "$schema" key is reported too.
unlabeled-alt-section sequence An alt section has no guard label. Label each section with its condition.
unlabeled-branch flow A diamond has two or more outgoing edges and one of them has no label. A flat edge is not a branch and is not counted. Label every branch with its condition.
vague-edge-label flow An edge label is one of uses, has, is, does, calls, handles, data, flow, in any case. Use a specific verb phrase such as “validates order”.
vague-message-label sequence A message label is one of those same words. Use a specific verb phrase.

flat-edge-ranked belongs to the format rendered: text art and SVG are laid out differently and can decide a flat edge differently. A message that says the edge was kept from the previous or before layout, rather than that no side route exists, comes from -previous or diff anchoring. The names above are also the only ones ignore accepts.