Skip to content

Draw the machine as a Mermaid state diagram - #3

Merged
floatdrop merged 1 commit into
mainfrom
mermaid
Oct 3, 2026
Merged

floatdrop merged 1 commit into
mainfrom
mermaid

Conversation

@floatdrop

Copy link
Copy Markdown
Owner

Machine.Mermaid() renders what DOT() renders, for a ```mermaid block in Markdown that GitHub draws in place. It's motivated by the grpcproc leader README, which will embed its election, singleton and peer-view machines and keep them current with a test.

  • Groups become composite states. They nest, and a group that only partly overlaps another is left out with a %% comment, both exactly as DOT handles clusters. An inherited transition is drawn once from the composite, under DOT's three conditions.
  • Internal transitions (Stay) are lines inside their state, below its name, rather than loops.
  • [*] points at the Initial state, and every terminal state points at [*].
  • Shared layout. DOT and Mermaid draw from one layout (boxed and unboxed groups, nesting, owners, boundary tails and skips), so the two diagrams can't disagree. DOT's output is byte-identical; every existing golden test passes unchanged.
  • Escaping. Names are only labels, behind positional ids (s0, g0). Characters Mermaid reads as syntax or markup become entity codes, including in the comment for an undrawn group, because Mermaid applies a %%{…}%% directive even inside a comment. An empty name becomes a zero-width space, and the title is strconv.Quoted YAML.

Every pinned shape was rendered with @mermaid-js/mermaid-cli, along with the four grpcproc leader machines. That includes edges between states in different composites: Mermaid's docs call them unsupported, but it draws them.

Tests: golden outputs for nesting and crossing groups, internal transitions, guards, no-Initial and escapes; ExampleMachine_Mermaid; determinism in FuzzMachineInvariants; and the concurrent-introspection test. Coverage stays at 100%. A code review ran and its findings are addressed; the claim about cross-composite edges was refuted by rendering.

🤖 Generated with Claude Code

Machine.Mermaid renders what DOT renders, for a mermaid block in Markdown
that GitHub draws in place: groups are composite states, nested and left
out exactly as DOT's clusters, with inherited transitions drawn once from
the composite under the same conditions; an internal transition is a line
inside its state; [*] marks the start and follows a terminal.

The two renderers share one layout, so they cannot disagree about which
states a group holds or which arrows leave its boundary. Names are only
labels, behind positional ids, and every character Mermaid reads as syntax
or markup is written as an entity code, in the comment for an undrawn
group too, since Mermaid applies a %%{ directive even there. Every shape
the tests pin was rendered with mermaid-cli.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@floatdrop
floatdrop merged commit 3e70872 into main Oct 3, 2026
1 check passed
@floatdrop
floatdrop deleted the mermaid branch October 3, 2026 19:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant