How to Map Semantic Patterns to Visual Types in Diagram Design

Diagram Design enforces a strict two-layer architecture where semantic patterns define behavioral concerns and visual types provide layout grammars, with the mapping validated through semantic-patterns.md and enforced by verify-semantic-motion.py.

Diagram Design separates what a system does (semantic patterns) from how the information is arranged (visual types). When you map semantic patterns to visual types in this repository, you ensure that domain-specific constraints—such as stage gates or traceable decompositions—drive the diagram's meaning while reusable layout engines handle the geometry. This approach prevents layout logic from polluting domain semantics and maintains a stable taxonomy across all visual outputs.

The Two-Layer Architecture

The cathrynlavery/diagram-design repository implements a strict separation between semantic patterns and visual types.

Semantic patterns are documented in skills/diagram-design/references/semantic-patterns.md. Each pattern describes a repeatable behavioral concern—such as "Stage framework with semantic slots" or "Traceable block decomposition"—and defines the semantic primitives (slots, budgets, and anti-patterns) that the diagram must respect.

Visual types supply the layout grammar that governs how nodes, edges, and containers are drawn. These definitions live in the type-*.md reference files, such as type-process.md, type-flowchart.md, and type-tree.md. A visual type never introduces new semantics; it only provides the geometric rules for rendering.

Step-by-Step Mapping Workflow

Select a Semantic Pattern from the Registry

All valid semantic patterns are cataloged in semantic-patterns.md. Each entry describes a specific behavioral concern and lists the constraints the diagram must honor.

When selecting a pattern, you identify:

  • The semantic primitives (e.g., step slots, budget limits)
  • The anti-patterns to avoid
  • The nearest visual type that supports the layout requirements

Resolve the Nearest Visual Type

Inside semantic-patterns.md, every pattern specifies a "Nearest visual type"—such as Process, Data flow, Flowchart, or Tree. This routing determines which layout engine will render the diagram.

The visual type definitions in type-process.md or type-tree.md supply the specific grammar for connector rules, node nesting, and styling. The pattern does not override this grammar; it parameterizes it with semantic constraints.

Load References Before Rendering

According to SKILL.md §3, you must load the visual type reference before drawing:

"Always load the chosen type reference linked in the guide before drawing … When routed above, also load semantic-patterns.md"

This ensures the layout engine initializes with the correct geometric rules before applying pattern-specific semantic constraints.

Render with Pattern-Type Validation

The CLI tool validates the mapping during execution. If you supply a --pattern argument, the tool checks that the pattern's nearest visual type matches the --type flag. The script scripts/verify-semantic-motion.py enforces this contract, raising an error if the semantic pattern is incompatible with the requested visual layout.

Implementation Examples

Command-Line Interface Mapping

Use the diagram-design CLI with explicit --pattern and --type flags. The tool automatically loads the appropriate references and validates the mapping.

Mapping a stage framework to a Process visual type:

diagram-design \
  --input my-diagram.mmd \
  --pattern "Stage framework with semantic slots" \
  --type process \
  --output diagram.html
  • The CLI loads type-process.md for the layout grammar
  • It applies the "Stage framework with semantic slots" constraints from semantic-patterns.md
  • The output respects both the process flow geometry and the stage slot semantics

Mapping traceable decomposition to a Tree with registry export:

diagram-design \
  --input architecture.drawio \
  --pattern "Traceable block decomposition" \
  --type tree \
  --registry \
  --output arch.html

Python API Integration

Programmatically map patterns to types using the DiagramDesigner class:

from diagram_design import DiagramDesigner

designer = DiagramDesigner()
designer.load_pattern("Secure paved roads")      # semantic pattern

designer.set_type("architecture")                # nearest visual type

html = designer.render("secure.drawio")
with open("secure.html", "w") as f:
    f.write(html)

The load_pattern method fetches the pattern definition from semantic-patterns.md, while set_type forces the corresponding visual type. The designer internally validates the mapping against the routing table before rendering, ensuring the "Secure paved roads" semantics align with the Architecture layout grammar.

Why Semantic-First Design Matters

This two-step mapping enables behavior-first design. When meaning—such as risk enforcement or state changes—dictates the diagram, the semantic pattern ensures the correct primitives and budget constraints apply before any layout decisions occur.

Simultaneously, layout re-use keeps the system maintainable. Visual types are reusable across many patterns; a pattern never introduces a new layout grammar, only a new set of semantics. This architectural constraint preserves taxonomy stability, as documented in ADR 0002 – semantic-patterns.do.not.expand.the.taxonomy.

Summary

  • Semantic patterns define behavioral concerns and constraints in semantic-patterns.md, while visual types define layout grammars in type-*.md files.
  • Each pattern declares a nearest visual type that provides the compatible rendering engine.
  • The CLI and Python API validate mappings using verify-semantic-motion.py, ensuring type-pattern compatibility before rendering.
  • The --registry flag enables metadata export for patterns like "Traceable block decomposition" per export-registry.md.
  • This separation follows ADR 0002, keeping the visual type taxonomy stable while allowing unlimited semantic expressiveness.

Frequently Asked Questions

What is the difference between a semantic pattern and a visual type in Diagram Design?

A semantic pattern describes what behavior the diagram represents—such as stage gates or secure paved roads—and defines constraints like slots and budgets. A visual type describes how the diagram is laid out, supplying the grammar for nodes, edges, and containers. The pattern selects the type, but the type knows nothing of the pattern's domain semantics.

How does the CLI validate that a semantic pattern matches its visual type?

The diagram-design CLI uses scripts/verify-semantic-motion.py to check that the --type argument matches the nearest visual type listed for the --pattern in semantic-patterns.md. If you attempt to render a "Traceable block decomposition" pattern (which routes to Tree) with --type process, the tool raises a validation error before rendering begins.

Can I use a visual type without specifying a semantic pattern?

Yes, you can invoke the CLI with only the --type flag to use the layout grammar directly. However, SKILL.md §3 recommends loading a semantic pattern first to ensure the diagram conveys specific behavioral meaning rather than just geometric structure. Without a pattern, the tool skips the semantic validation and constraint application steps.

Where are the layout rules for visual types defined?

Visual type specifications live in the skills/diagram-design/references/ directory as type-*.md files. For example, type-process.md defines the layout grammar for process diagrams, while type-tree.md defines hierarchical tree rendering rules. These files are loaded automatically when you specify the corresponding --type flag or call set_type() in the Python API.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →