Skip to content

feat(mermaid): spar-mermaid foundation with flowchart emitter (v0.10.x)#220

Merged
avrabe merged 6 commits into
mainfrom
feat/v0.10.x-mermaid-foundation
May 14, 2026
Merged

feat(mermaid): spar-mermaid foundation with flowchart emitter (v0.10.x)#220
avrabe merged 6 commits into
mainfrom
feat/v0.10.x-mermaid-foundation

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 13, 2026

Motivation

The current SVG rendering path (via etch) has known quality pain documented in docs/plans/2026-03-17-rendering-quality-design.md. Mermaid addresses both rendering quality and machine-parseability: rivet renders Mermaid in-place in requirement/test descriptions, and the text output is diff-able and round-trip-testable.

Scope — emit only, library only

This PR is the M1 foundation. It adds one new crate with no CLI surface and no renderer dependency.

In this PR:

  • New crate spar-mermaid (version 0.9.3, workspace edition)
  • emit_flowchart(instance: &SystemInstance, opts: &MermaidOptions) -> String — walks the component arena and emits flowchart TD
  • MermaidOptions with categories filter, max_depth filter, include_connections flag
  • 6 unit tests covering the full option surface
  • REQ-MERMAID-001 + TEST-MERMAID-FLOWCHART in artifact tracker

Follow-on PRs (out of scope here):

  • CLI subcommand
  • classDiagram, requirementDiagram, block-beta
  • SysML2 → Mermaid bridge
  • Round-trip topology-preservation tests (need mermaid parser)
  • stateDiagram per SOM (v0.11.0)
  • Trace-topology overlay (v0.11.0)

MWE — sample emitted Mermaid

From the canonical test instance (root system + 3 threads + 1 processor + 2 connections):

flowchart TD
    cpu["processor: cpu"]
    root["system: root"]
    t1["thread: t1"]
    t2["thread: t2"]
    t3["thread: t3"]
    t1 --> t2
    t2 --> t3
Loading

Paste into https://mermaid.live to verify visually.

Design notes

  • ConnectionEnd holds subcomponent: Option<Name> + feature: Name (not a direct ComponentInstanceIdx). Endpoint resolution uses case-insensitive name lookup against the owner's children — consistent with AADL §3.1 case-insensitive identifiers.
  • SemanticConnection (which does carry direct idx pairs) is deliberately not used here: those entries are computed post-instantiation from a GlobalScope and aren't available in manually-constructed test instances. The ConnectionInstance path is sufficient for foundation emission.
  • Cycle safety: SystemInstance::instantiate already detects circular containment; the emitter trusts that guarantee and documents the assumption. max_depth provides a natural bound for manually-constructed instances with depth limits set.

Checklist

  • cargo build -p spar-mermaid — clean
  • cargo test -p spar-mermaid — 6/6 pass
  • cargo clippy -p spar-mermaid -- -D warnings — clean
  • rivet validate — REQ-MERMAID-001 + TEST-MERMAID-FLOWCHART present and linked (pre-existing unrelated YAML issue at line 1615 of verification.yaml is not introduced by this PR)

🤖 Generated with Claude Code

Adds the new `spar-mermaid` crate (emit-only, library-only) that walks a
`SystemInstance` arena and produces a `flowchart TD` Mermaid diagram.
Nodes are filtered by ComponentCategory set and max parent-hop depth;
ConnectionInstance edges are resolved by subcomponent name lookup and
deduplicated. Six unit tests cover the canonical 3-thread/1-processor
instance, category filter, depth filter, edge suppression, label format,
and ID sanitisation. Registers REQ-MERMAID-001 and TEST-MERMAID-FLOWCHART
in the artifact tracker.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@avrabe avrabe enabled auto-merge (squash) May 13, 2026 19:06
@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

❌ Patch coverage is 98.80478% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/spar-mermaid/src/lib.rs 98.80% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

avrabe and others added 5 commits May 14, 2026 06:47
…ster in workspace.dependencies

Aligns spar-mermaid with the per-crate convention used by every other
spar-* crate in this repo:

- crates/spar-mermaid/Cargo.toml: replace path literal with
  `spar-hir-def.workspace = true` (matches spar-trace-topology, sysml2,
  analysis, etc.).
- Cargo.toml: register `spar-mermaid` under [workspace.dependencies] so
  follow-on crates (CLI integration, SysML2 bridge) can depend on it
  via `spar-mermaid.workspace = true` without re-spelling the path.

No behavior change. Build + test still pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
No behavior change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
# Conflicts:
#	artifacts/requirements.yaml
#	artifacts/verification.yaml
# Conflicts:
#	artifacts/requirements.yaml
#	artifacts/verification.yaml
# Conflicts:
#	artifacts/requirements.yaml
#	artifacts/verification.yaml
@avrabe avrabe merged commit b7c8834 into main May 14, 2026
17 checks passed
@avrabe avrabe deleted the feat/v0.10.x-mermaid-foundation branch May 14, 2026 15:36
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