feat: RFC 0043 Mermaid diagram standards

Establishes mandatory standards for Mermaid diagrams in Blue documents:
- Neutral theme required for dark/light mode compatibility
- Leaf node counting for LR flow warnings (>3 nodes)
- Plain text for architecture labels (no emoji color injection)
- Shape semantics advisory for new diagrams
- Auto-fix for theme declaration only (colors require manual review)

Includes alignment dialogue with 10/10 tensions resolved across 3 rounds.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Eric Garcia 2026-01-30 11:58:32 -05:00
parent 88da94af8d
commit 006546b2fd
3 changed files with 808 additions and 0 deletions

View file

@ -0,0 +1,250 @@
# Alignment Dialogue: RFC 0043 Mermaid Diagram Standards
**Date**: 2026-01-30 17:30Z
**Status**: CONVERGED ✓
**Participants**: 💙 Judge, 🧁 Muffin, 🧁 Cupcake, 🧁 Scone, 🧁 Eclair, 🧁 Donut
**RFC**: 0043-mermaid-diagram-standards
**Rounds**: 3 (0, 1, 2)
**Tensions**: 10 raised → 10 resolved
## Expert Panel
| Agent | Role | Tier | Relevance | Emoji |
|-------|------|------|-----------|-------|
| 💙 Judge | Orchestrator | — | — | 💙 |
| 🧁 Muffin | Technical Writer | Core | 0.95 | 🧁 |
| 🧁 Cupcake | UX Architect | Core | 0.90 | 🧁 |
| 🧁 Scone | DevOps Architect | Adjacent | 0.70 | 🧁 |
| 🧁 Eclair | Quality Engineer | Adjacent | 0.65 | 🧁 |
| 🧁 Donut | First Principles Reasoner | Wildcard | 0.40 | 🧁 |
## Alignment Scoreboard — FINAL
| Agent | Wisdom | Consistency | Truth | Relationships | **Total** |
|-------|--------|-------------|-------|---------------|----------|
| 🧁 Muffin | 7 | 8 | 7 | 6 | **28** |
| 🧁 Cupcake | 10 | 8 | 7 | 7 | **32** |
| 🧁 Scone | 9 | 9 | 8 | 7 | **33** |
| 🧁 Eclair | 7 | 9 | 7 | 7 | **30** |
| 🧁 Donut | 10 | 8 | 6 | 6 | **30** |
**Total ALIGNMENT**: 153
**Velocity**: 55 → 104 → 153 (+49, +49)
## Perspectives Inventory
| ID | Agent | Perspective | Round |
|----|-------|-------------|-------|
| P01 | 🧁 Muffin | Node counting heuristic fragility for subgraphs | 0 |
| P02 | 🧁 Muffin | `blue_lint` crate doesn't exist; needs clarification | 0 |
| P03 | 🧁 Cupcake | Emoji subgraph labels inject platform-dependent color | 0 |
| P04 | 🧁 Cupcake | 15-char edge label limit needs exception framework | 0 |
| P05 | 🧁 Scone | Lint should extend existing lint.rs, not new crate | 0 |
| P06 | 🧁 Scone | Auto-fix for custom colors is unsafe | 0 |
| P07 | 🧁 Eclair | Auto-fix will erase semantic color intent | 0 |
| P08 | 🧁 Eclair | Existing lint infrastructure already exists | 0 |
| P09 | 🧁 Donut | Implementation timing: templates before lint | 0 |
| P10 | 🧁 Donut | count_top_level_nodes is undefined complexity | 0 |
| P11 | 🧁 Cupcake | LR orientation serves legitimate horizontal architectures | 1 |
| P12 | 🧁 Eclair | lint.rs extension needs Mermaid block extraction | 1 |
## Tensions Tracker — FINAL
| ID | Tension | Status | Resolution |
|----|---------|--------|------------|
| T01 | Auto-fix scope | **RESOLVED** | Theme prepend: auto-fix. Colors: error + manual migration |
| T02 | Shape semantics conflicts | **RESOLVED** | Advisory for new diagrams, legacy exempt |
| T03 | LR viewport assumptions | **RESOLVED** | Subsumed by T07 |
| T04 | Hexagon notation conflict | **RESOLVED** | Advisory status removes conflict |
| T05 | Shape/emoji precedence | **RESOLVED** | Subsumed by T08 |
| T06 | Lint infrastructure location | **RESOLVED** | Extend `crates/blue-mcp/src/handlers/lint.rs` |
| T07 | Node counting specification | **RESOLVED** | Count leaf nodes (terminal visual elements) |
| T08 | Emoji color injection | **RESOLVED** | Plain text for architecture; emoji for annotations |
| T09 | Implementation timing | **RESOLVED** | Parallel track with warning-only lint |
| T10 | Edge label limits | **RESOLVED** | Advisory at 15 chars, not prescriptive |
---
## Round 0: Opening Arguments
### 🧁 Muffin
[PERSPECTIVE P01: Node counting heuristic fragility]
The lint rule proposes counting "top-level nodes" to trigger warnings on LR diagrams with >3 nodes, but the RFC doesn't specify how to handle subgraphs with nested nodes or how to distinguish layout-relevant nodes from connection points.
[PERSPECTIVE P02: Premature lint crate assumption]
The RFC specifies implementation in a `blue_lint` crate that doesn't exist in the current codebase.
[TENSION T01: Auto-fix scope ambiguity]
Unclear whether auto-fix should strip prohibited `fill:#` directives entirely or just flag them.
### 🧁 Cupcake
[PERSPECTIVE P03: Emoji subgraph labels create platform-dependent rendering risks]
Emojis render inconsistently across Mermaid versions, GitHub vs VS Code vs offline viewers. The RFC prohibits custom fills but doesn't address emoji color injection.
[PERSPECTIVE P04: 15-char edge label limit needs exception framework]
No guidance for when technical precision demands more characters.
[TENSION T02: Shape semantics standardization conflicts with existing Blue document patterns]
### 🧁 Scone
[PERSPECTIVE P05: Lint implementation belongs in existing lint handler]
`crates/blue-mcp/src/handlers/lint.rs` already implements RFC header linting. Creating a separate crate introduces unnecessary overhead.
[PERSPECTIVE P06: Auto-fix for custom colors is unsafe without semantic preservation]
Custom `fill:#` colors encode semantic intent. Auto-stripping loses author intent.
[TENSION T03: LR-versus-TB rule assumes viewport constraints that may not hold]
### 🧁 Eclair
[PERSPECTIVE P07: Auto-fix will erase semantic color intent]
In the wip spike, colors distinguish deployment environments that neutral grayscale won't preserve.
[PERSPECTIVE P08: Existing lint infrastructure already exists]
The `blue_lint` handler already detects RFC docs and runs header format checks.
[TENSION T04: Shape semantics table conflicts with existing hexagon usage]
### 🧁 Donut
[PERSPECTIVE P09: lint enforcement timing is backwards]
Templates should generate compliant output first, then lint catches legacy violations.
[PERSPECTIVE P10: count_top_level_nodes is undefined complexity]
Node counting in Mermaid is non-trivial due to subgraphs and multi-line definitions.
[TENSION T05: shape semantics conflict with emoji convention]
---
## 💙 Judge: Round 0 Synthesis
**Converged**: Neutral theme correct. Auto-fix for theme safe. Auto-fix for colors unsafe. Extend lint.rs.
**Open**: Shape semantics, emoji injection, LR counting, edge labels, timing.
**Velocity**: 55 → Round 1
---
## Round 1: Consensus Building
### 🧁 Muffin
- [RESOLVED T06]: Extend existing lint.rs
- [RESOLVED T01]: Auto-fix for theme only; error for colors
- [REFINEMENT T07]: Container vs leaf counting needs spec
- [CONCESSION]: Shape semantics need migration audit
### 🧁 Cupcake
- [RESOLVED T06, T01]
- [PERSPECTIVE P11]: LR orientation serves legitimate horizontal architectures
- [REFINEMENT]: Emoji exception framework needed
- [CONCESSION]: Shape semantics need gradual adoption
### 🧁 Scone
- [RESOLVED T06, T01]
- [CONCESSION T03]: Subsumed by T07 (node counting is real issue)
- [REFINEMENT]: Leaf node counting specification
### 🧁 Eclair
- [RESOLVED T06, T01]
- [PERSPECTIVE P12]: lint.rs extension needs Mermaid block extraction
- [CONCESSION]: Hexagon less critical than emoji-shape precedence
### 🧁 Donut
- [RESOLVED T06, T01]
- [CONCESSION T05]: Subsumed by T08 (emoji injection is deeper)
- [REFINEMENT T09]: Parallel track may work
---
## 💙 Judge: Round 1 Synthesis
**Resolved**: T01, T03, T05, T06 (5 of 10)
**Near-resolved**: T07 (leaf vs container), T09 (parallel track)
**Advisory path**: T02, T04 (shape semantics)
**Open**: T08 (emoji), T10 (edge labels)
**Velocity**: 104 (+49)
---
## Round 2: Full Convergence
### 🧁 Muffin
- [RESOLVED T07]: Count leaf nodes—Scone's approach yields predictable results
- [RESOLVED T08]: Plain text for architecture diagrams
- [RESOLVED T09]: Parallel track with flag-only mode
- [RESOLVED T10]: Edge labels advisory at 15 chars
- [RESOLVED T02, T04]: Shape semantics advisory for new diagrams
### 🧁 Cupcake
- [RESOLVED T07]: Leaf nodes provide predictable lint behavior
- [RESOLVED T08]: Emoji prohibited in architecture diagrams
- [RESOLVED T09]: Parallel implementation acceptable
- [RESOLVED T10]: Edge label limit advisory only
- [RESOLVED T02, T04]: Advisory for new diagrams with legacy exemption
### 🧁 Scone
- [RESOLVED T07]: Leaf node counting is implementation-testable
- [RESOLVED T08]: Plain text labels for architecture clarity
- [RESOLVED T09]: Parallel track with flag-only mode
- [RESOLVED T10]: Edge labels advisory with soft limit
- [RESOLVED T02, T04]: Shape semantics advisory, no forced migration
### 🧁 Eclair
- [RESOLVED T07]: Leaf node counting
- [RESOLVED T08]: Prohibit emoji in architecture labels, allow in annotations
- [RESOLVED T09]: Parallel implementation viable
- [RESOLVED T10]: Edge label limits advisory
- [RESOLVED T02, T04]: Advisory stance removes conflicts
### 🧁 Donut
- [RESOLVED T07]: Leaf nodes—containers are organizational, not cognitive load
- [RESOLVED T08]: Plain text for neutral theme consistency
- [RESOLVED T09]: Parallel track confirmed viable
- [RESOLVED T10]: Advisory with "consider abbreviating" warning
- [RESOLVED T02, T04]: Advisory status resolves all shape conflicts
---
## 💙 Judge: Convergence Declaration
**STATUS: CONVERGED** ✓
All 10 tensions resolved by unanimous consensus across 5 experts in 3 rounds.
### Final Resolutions for RFC 0043 Amendment
| Category | Resolution |
|----------|------------|
| **Theme** | `%%{init: {'theme': 'neutral'}}%%` REQUIRED |
| **Lint location** | Extend `crates/blue-mcp/src/handlers/lint.rs` |
| **Auto-fix scope** | Theme prepend: auto-fix. Colors: error + manual migration |
| **Node counting** | Count leaf nodes (terminal visual elements), not containers |
| **LR threshold** | Advisory warning at >3 leaf nodes |
| **Emoji guidance** | Plain text for architecture diagrams; emoji for annotations only |
| **Shape semantics** | Advisory for new diagrams; legacy exempt |
| **Edge labels** | Advisory 15-char limit, not prescriptive |
| **Implementation** | Parallel track: templates + lint with warning-only mode |
### RFC Amendments Required
1. Replace "blue_lint crate" with "extend lint.rs handler"
2. Split auto-fix: theme=auto, colors=error
3. Add leaf node counting specification
4. Make shape semantics table "Recommended Patterns"
5. Add emoji guidance section (plain text for architecture)
6. Make edge label limit advisory
7. Reorder tasks: parallel track acceptable
---
*Dialogue concluded 2026-01-30. ALIGNMENT achieved through 3 rounds of deliberation.*

View file

@ -0,0 +1,275 @@
# RFC 0043: Mermaid Diagram Standards for Blue Documents
| | |
|---|---|
| **Status** | Accepted |
| **Created** | 2026-01-30 |
| **Spike** | [2026-01-30T1521Z-mermaid-diagram-style-guide](../spikes/2026-01-30T1521Z-mermaid-diagram-style-guide-for-blue-documents.done.md) |
| **Dialogue** | [2026-01-30T1730Z-rfc-0043-mermaid-diagram-standards](../dialogues/2026-01-30T1730Z-rfc-0043-mermaid-diagram-standards.dialogue.recorded.md) |
---
## Summary
Establish mandatory standards for Mermaid diagrams in all Blue-generated documents, ensuring readability in both light and dark modes through the `neutral` theme, vertical flow preference, and automated lint enforcement.
---
## Problem
Mermaid diagrams in Blue documents have inconsistent styling that causes readability issues:
1. **Dark mode incompatibility** — Custom fill colors (`#e8f5e9`, `#e3f2fd`) designed for light mode become unreadable in dark mode
2. **Invisible text** — Dark nodes with no explicit text color disappear against dark backgrounds
3. **Subgraph label contrast** — Colored subgraph backgrounds obscure labels
4. **Horizontal sprawl**`flowchart LR` requires horizontal scrolling on narrow viewports
5. **No enforcement** — Authors must remember style rules manually
This affects:
- ADRs with architecture diagrams
- RFCs with system designs
- Dialogue recordings with flow visualizations
- Any document Blue generates containing Mermaid
---
## Proposal
### 1. Mandatory Theme Declaration
All Mermaid diagrams MUST begin with the neutral theme declaration:
```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TB
...
```
### 2. Flow Direction Guidelines
| Direction | When to Use | Enforcement |
|-----------|-------------|-------------|
| `TB` (top-to-bottom) | Default for all diagrams | — |
| `LR` (left-to-right) | Only when ≤3 leaf nodes | Advisory warning |
The constraint is **horizontal space**. `LR` with 4+ nodes forces horizontal scrolling on narrow viewports.
**Node Counting**: Count leaf nodes (terminal visual elements), not container subgraphs. A diagram with 2 subgraphs each containing 4 nodes counts as 8 nodes for threshold purposes.
### 3. Prohibited Styling
The following are NOT ALLOWED:
```mermaid
%% PROHIBITED
style NODE fill:#e8f5e9
style NODE fill:#any-color
classDef custom fill:#color
```
The neutral theme provides sufficient visual distinction through grayscale shading.
### 4. Emoji Guidance
| Context | Emoji Allowed | Rationale |
|---------|---------------|-----------|
| Architecture component labels | **No** | Platform-dependent color rendering undermines neutral theme |
| Subgraph titles | **No** | Same dark-mode readability issues as custom fills |
| Annotations/comments | Yes | Non-critical context where variance is acceptable |
**Example**:
```mermaid
%% GOOD: Plain text architecture labels
subgraph SV["Superviber Control Plane"]
ORCH["Orchestration"]
end
%% BAD: Emoji injects platform-dependent color
subgraph SV["☁️ Superviber Cloud"]
```
### 5. Recommended Shape Semantics
*Advisory for new diagrams. Legacy documents exempt.*
| Shape | Syntax | Semantic |
|-------|--------|----------|
| Rectangle | `[text]` | Services, components, processes |
| Rounded | `(text)` | User-facing elements, entry points |
| Database | `[(text)]` | Data stores, persistence |
| Stadium | `([text])` | External systems, third-party |
| Hexagon | `{{text}}` | Decision points, conditionals |
| Circle | `((text))` | Events, triggers |
### 6. Edge Label Guidelines
*Advisory, not prescriptive.*
- Recommended maximum: 15 characters
- Use abbreviations: `mTLS`, `gRPC`, `REST`
- Longer labels acceptable when clarity requires it
### 7. Lint Rule Enforcement
Extend `crates/blue-mcp/src/handlers/lint.rs` (existing infrastructure):
```rust
/// Mermaid diagram linting for Blue documents
fn check_mermaid_blocks(content: &str) -> Vec<Diagnostic> {
let mut diagnostics = vec![];
for block in extract_mermaid_blocks(content) {
// REQUIRED: Neutral theme declaration
if !block.contains("'theme': 'neutral'")
&& !block.contains("\"theme\": \"neutral\"") {
diagnostics.push(Diagnostic {
severity: Severity::Error,
message: "Mermaid diagram must use neutral theme".into(),
suggestion: Some("Add: %%{init: {'theme': 'neutral'}}%%".into()),
auto_fix: Some(AutoFix::PrependLine(
"%%{init: {'theme': 'neutral'}}%%".into()
)),
});
}
// PROHIBITED: Custom fill colors (NO auto-fix - preserves semantic intent)
if block.contains("fill:#") || block.contains("fill: #") {
diagnostics.push(Diagnostic {
severity: Severity::Error,
message: "Custom fill colors prohibited in Mermaid diagrams".into(),
suggestion: Some("Remove style directives manually; review semantic intent".into()),
auto_fix: None, // Intentionally no auto-fix
});
}
// ADVISORY: LR flow with >3 leaf nodes
if block.contains("flowchart LR") || block.contains("graph LR") {
let leaf_count = count_leaf_nodes(&block);
if leaf_count > 3 {
diagnostics.push(Diagnostic {
severity: Severity::Warning,
message: format!(
"LR flow with {} leaf nodes may cause horizontal scrolling",
leaf_count
),
suggestion: Some("Consider flowchart TB for better viewport fit".into()),
auto_fix: None,
});
}
}
}
diagnostics
}
/// Count leaf nodes (terminal visual elements, not container subgraphs)
fn count_leaf_nodes(mermaid_content: &str) -> usize {
// Count node definitions: ID[label], ID(label), ID[(label)], etc.
// Exclude: subgraph, end, style, classDef, linkStyle
let node_pattern = regex::Regex::new(r"^\s*(\w+)\s*[\[\(\{\<]").unwrap();
let exclude_keywords = ["subgraph", "end", "style", "classDef", "linkStyle"];
mermaid_content
.lines()
.filter(|line| {
let trimmed = line.trim();
!exclude_keywords.iter().any(|kw| trimmed.starts_with(kw))
&& node_pattern.is_match(trimmed)
})
.count()
}
```
### 8. Template Integration
Update Blue's document templates to generate compliant Mermaid by default:
```rust
fn generate_mermaid_block(diagram_type: &str, content: &str) -> String {
format!(
"```mermaid\n%%{{init: {{'theme': 'neutral'}}}}%%\n{} TB\n{}\n```",
diagram_type,
content
)
}
```
---
## Migration
### Auto-Fix Scope
| Issue | Auto-Fix | Rationale |
|-------|----------|-----------|
| Missing theme declaration | ✓ Yes | Non-destructive prepend |
| Custom fill colors | ✗ No | Preserves semantic intent; requires manual review |
| LR with >3 nodes | ✗ No | Advisory only; architectural choice |
### Migration Process
1. Run lint with `--fix` to auto-add theme declarations
2. Manual review for custom colors (lint reports, human decides)
3. Priority: ADRs > RFCs > Dialogues
### Implementation Track
Templates and lint can proceed in parallel:
- Templates: Generate compliant diagrams for new documents
- Lint: Flag violations in existing documents (warning-only mode during transition)
---
## Alternatives Considered
### A. `dark` Theme Only
**Rejected**: Looks poor in light mode. We need both-mode compatibility.
### B. `base` Theme with Custom Variables
**Rejected**: Requires verbose `themeVariables` block in every diagram. High maintenance burden.
### C. Pre-render to SVG at Build Time
**Rejected**: Loses live preview in editors. Adds build complexity.
### D. Documentation Only (No Enforcement)
**Rejected**: Relies on authors remembering. Inconsistency will creep back.
### E. New `blue_lint` Crate
**Rejected**: Existing lint infrastructure in `crates/blue-mcp/src/handlers/lint.rs` already handles RFC docs. Extend, don't duplicate.
---
## Success Criteria
1. All Mermaid diagrams pass `blue_lint` without errors
2. Diagrams readable in VS Code light theme, VS Code dark theme, GitHub light, GitHub dark
3. No custom `fill:#` directives in any Blue document
4. Template generates compliant diagrams by default
5. Lint runs in parallel with template development
---
## References
- [Spike: Mermaid Diagram Style Guide](../spikes/2026-01-30T1521Z-mermaid-diagram-style-guide-for-blue-documents.done.md)
- [Alignment Dialogue](../dialogues/2026-01-30T1730Z-rfc-0043-mermaid-diagram-standards.dialogue.recorded.md) — 10/10 tensions resolved
- [Mermaid Theming Documentation](https://mermaid.js.org/config/theming.html)
- [ADR 0005: Single Source of Truth](../adrs/0005-single-source.accepted.md)
---
## Tasks
- [ ] Extend `lint.rs` with Mermaid block extraction
- [ ] Implement theme declaration check with auto-fix
- [ ] Implement fill color check (error, no auto-fix)
- [ ] Implement leaf node counting for LR warning
- [ ] Update document generation templates
- [ ] Migrate existing diagrams in ADRs (manual color review)
- [ ] Migrate existing diagrams in RFCs (manual color review)
- [ ] Add Mermaid cheatsheet to `.blue/docs/`

View file

@ -0,0 +1,283 @@
# Spike: Mermaid Diagram Style Guide for Blue Documents
| | |
|---|---|
| **Status** | Done |
| **Date** | 2026-01-30 |
| **Time Box** | 30 minutes |
---
## Question
How can we ensure Mermaid diagrams in Blue documents are readable in both light and dark modes, prefer vertical flow, and have consistent styling?
---
## Problem Analysis
From the screenshot, the current diagram has these issues:
1. **Subgraph labels unreadable** — "Superviber Control Plane" and "Client Infrastructure" use dark text on colored backgrounds
2. **Fill colors designed for light mode**`#e8f5e9`, `#e3f2fd`, `#fff3e0` are light pastels that look washed out in dark mode
3. **Node text invisible** — Dark nodes (`#333`) have no explicit text color
4. **Horizontal sprawl** — Some diagrams use `LR` when `TB` would be more readable
## Mermaid Theme Options
### Option A: Use `dark` Theme
```mermaid
%%{init: {'theme': 'dark'}}%%
flowchart TB
A[Node A] --> B[Node B]
```
**Problem**: Still doesn't control subgraph label colors well.
### Option B: Use `base` Theme with Custom Variables
```mermaid
%%{init: {
'theme': 'base',
'themeVariables': {
'primaryColor': '#4a5568',
'primaryTextColor': '#fff',
'primaryBorderColor': '#718096',
'lineColor': '#718096',
'secondaryColor': '#2d3748',
'tertiaryColor': '#1a202c'
}
}}%%
```
**Problem**: Verbose, must repeat in every diagram.
### Option C: Use `neutral` Theme (Recommended)
```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TB
subgraph SV["Superviber Control Plane"]
ORCH[Orchestration]
BILL[Billing]
end
```
**Benefit**: Works in both light and dark modes. Grayscale palette avoids color contrast issues.
---
## Recommended Style Guide
### 1. Always Use `neutral` Theme
```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TB
...
```
### 2. Prefer Top-to-Bottom Flow (`TB`)
```mermaid
flowchart TB ← vertical flow
```
Not:
```mermaid
flowchart LR ← horizontal, requires scrolling
```
### 3. Avoid Custom Fill Colors
**Don't do this:**
```mermaid
style CLIENT fill:#e8f5e9
```
**Do this instead:**
```mermaid
%% Let neutral theme handle colors
%% Use node shapes for visual distinction
```
### 4. Use Subgraph Labels Without Styling
```mermaid
subgraph CLIENT["Client Infrastructure"]
%% No style directive needed
end
```
### 5. Use Shape Variations for Distinction
| Shape | Syntax | Use Case |
|-------|--------|----------|
| Rectangle | `[text]` | Services, components |
| Rounded | `(text)` | User-facing elements |
| Database | `[(text)]` | Data stores |
| Stadium | `([text])` | External systems |
| Hexagon | `{{text}}` | Decision points |
### 6. Keep Edge Labels Short
```mermaid
A -->|"mTLS"| B ← good
A -->|"Mutual TLS encrypted connection over port 443"| B ← too long
```
---
## Example: ADR 0017 Diagram Rewritten
### Before (problematic)
```mermaid
flowchart TB
subgraph CLIENT["Client Infrastructure"]
AGENT["Superviber Agent<br/>(Claude Code)"]
CODE[("Source Code<br/>Credentials<br/>Secrets")]
end
subgraph SV["Superviber Control Plane"]
ORCH["Orchestration"]
BILL["Billing"]
TELEM["Telemetry"]
end
style CLIENT fill:#e8f5e9
style SV fill:#e3f2fd
```
### After (neutral theme, readable)
```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TB
subgraph USER["Developer"]
WEB["Web Interface"]
end
subgraph SV["Superviber Control Plane"]
ORCH["Orchestration"]
BILL["Billing"]
TELEM["Telemetry"]
end
subgraph CLIENT["Client Infrastructure"]
AGENT["Superviber Agent"]
CODE[("Source Code<br/>Credentials")]
end
WEB -->|"Session"| ORCH
ORCH -->|"Route"| AGENT
AGENT <-->|"Local"| CODE
AGENT -->|"Metrics"| TELEM
TELEM --> BILL
```
---
## Implementation Options
### Option 1: Style Guide Only (Documentation)
Add to `.blue/docs/style-guide.md`:
- Always use `%%{init: {'theme': 'neutral'}}%%`
- Prefer `flowchart TB`
- Avoid custom `style` directives
**Pros**: Simple, no tooling
**Cons**: Relies on authors remembering
### Option 2: Lint Rule
Add to `blue_lint`:
```rust
// Check for Mermaid blocks missing neutral theme
if mermaid_block && !contains("theme': 'neutral'") {
warn("Mermaid diagram should use neutral theme for dark mode compatibility")
}
```
**Pros**: Automated enforcement
**Cons**: Requires implementation
### Option 3: Pre-render with Consistent Theme
Use `mmdc` CLI to pre-render all Mermaid to SVG/PNG with fixed theme at build time.
**Pros**: Guaranteed consistency
**Cons**: Loses live preview in editors
---
## Decision
**Chosen approach**: Option C (`neutral` theme) + Option 2 (Lint rule)
### Why `neutral` Theme
- Works in both light and dark modes without customization
- Grayscale palette avoids color contrast issues
- No need to repeat verbose `themeVariables` in every diagram
- Subgraph labels are readable by default
### Lint Rule Specification
Add to `blue_lint`:
```rust
/// Checks Mermaid code blocks for neutral theme declaration
fn lint_mermaid_theme(content: &str) -> Vec<LintWarning> {
let mut warnings = vec![];
// Find all mermaid code blocks
for (line_num, block) in find_mermaid_blocks(content) {
if !block.contains("'theme': 'neutral'") && !block.contains("\"theme\": \"neutral\"") {
warnings.push(LintWarning {
line: line_num,
message: "Mermaid diagram should use neutral theme: %%{init: {'theme': 'neutral'}}%%".into(),
severity: Severity::Warning,
});
}
}
warnings
}
```
### Implementation Tasks
1. ✅ **Document decision** — This spike
2. ⬜ **Update ADR 0017** — Apply neutral theme to diagram
3. ⬜ **Add lint rule** — Implement in `blue_lint` crate
4. ⬜ **Create style guide** — Add `.blue/docs/mermaid-style-guide.md`
---
## Quick Reference Card
```markdown
## Blue Mermaid Cheatsheet
Always start with:
```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TB
```
Shapes:
- [Rectangle] — services
- (Rounded) — user-facing
- [(Database)] — data stores
- {{Hexagon}} — decisions
Don't use:
- style X fill:#color
- flowchart LR (prefer TB)
- Long edge labels
```
---
*Investigation by Blue*