Use this when you need a shared visual of system architecture — from a codebase overview, RFC, meeting transcript, existing diagram, or a mix of all four. The output is a C4-style or box-and-arrow diagram rendered in Mermaid syntax, with optional export to Miro or FigJam.
Process
Step 1: Gather inputs
Ask the user:
- Input sources — what should the diagram be based on? Accept one or more:
- Codebase overview or file tree
- RFC, ADR, or design document
- Meeting transcript or conversation notes
- Existing diagram (text description, image, or Mermaid code)
- Verbal description of the system
- Diagram level — which C4 abstraction level?
- Context (default) — system and its external actors/dependencies
- Container — applications, data stores, and their interactions within one system
- Component — internal structure of a single container
- Deployment — infrastructure and deployment topology
- Focus area — the whole system, or a specific subsystem/flow?
- Notation preference -- C4 style (recommended), box-and-arrow, or sequence diagram?
- Perspective -- as-is (current state, default) or to-be (future state / proposed solution)? Future-state diagrams add sections for proposed changes, migration considerations, and decision rationale.
- Visual output -- beyond the Mermaid markdown?
- Markdown only (default) — Mermaid code block in the saved file
- FigJam diagram — visual diagram via Figma MCP (flowchart format)
- Miro board — document posted to a Miro board
- PDF slide deck — branded PDF via Marp
- Presentation (Google Slides) — via Gamma
- Multiple — any combination
Default to Context level, full system, C4 style, markdown only.
Step 2: Extract system elements
From the provided inputs, identify:
Actors and external systems:
- Users, roles, or personas that interact with the system
- External services, APIs, third-party integrations
- Data sources and sinks outside the system boundary
Internal components:
- Applications, services, microservices
- Databases, caches, message queues
- Batch jobs, scheduled tasks, background workers
Relationships:
- Synchronous calls (API, RPC, HTTP)
- Asynchronous messaging (events, queues, pub/sub)
- Data flows (reads, writes, replication)
- Dependencies (uses, depends on, authenticates via)
Boundaries:
- System boundary (what's "ours" vs. external)
- Subsystem or bounded context boundaries
- Trust boundaries (internal network vs. public)
- Team ownership boundaries (if known)
For each element, capture:
- Name — clear, consistent label
- Technology — language, framework, or platform (if known)
- Purpose — one-line description of what it does
- Relationships — what it connects to and how
Flag any elements with [INFERRED] if they came from indirect evidence rather than explicit documentation.
If perspective is "to-be" (future state): Also identify proposed new components, components being modified, and components being deprecated. Tag each with [NEW], [MODIFIED], or [DEPRECATED].
Step 3: Compose the Mermaid diagram
Generate the diagram using Mermaid syntax appropriate to the selected level and notation:
For C4 Context diagrams:
graph TB
subgraph "System Boundary"
A["Service A<br/><i>Purpose</i>"]
B["Service B<br/><i>Purpose</i>"]
end
User["Actor<br/><i>Role</i>"] -->|"Action"| A
A -->|"Sync: API call"| B
B -.->|"Async: Event"| C["External System<br/><i>Purpose</i>"]
For C4 Container diagrams:
graph TB
subgraph "System Name"
subgraph "Web Tier"
WebApp["Web App<br/><i>React, TypeScript</i>"]
end
subgraph "API Tier"
API["API Server<br/><i>Node.js, Express</i>"]
end
subgraph "Data Tier"
DB[("Database<br/><i>PostgreSQL</i>")]
Cache[("Cache<br/><i>Redis</i>")]
end
end
WebApp -->|"HTTPS/JSON"| API
API -->|"SQL"| DB
API -->|"Read/Write"| Cache
Notation conventions:
- Solid arrows (
-->) = synchronous interaction - Dashed arrows (
-.->) = asynchronous interaction - Rectangles = services, applications
- Cylinders (
[(" ")]) = data stores - Subgraphs = boundaries (system, subsystem, trust, team)
- Labels on arrows = protocol or data description
<br/><i>italics</i>= technology stack under the name
If perspective is "to-be" (future state): Use dashed subgraph borders or a style annotation for proposed/new components vs. existing. After the diagram, include:
- Proposed Changes -- list what is new, modified, or deprecated and why
- Migration Considerations -- sequencing, data migration, cutover risks, rollback strategy
- Decision Rationale -- link each proposed change to the problem it solves
Step 4: Add the legend and metadata
Include a legend explaining the notation used:
System Diagram: (System Name)
Date: (date) Level: (Context / Container / Component / Deployment) Perspective: (As-is / To-be) Sources: (list of input documents/sources used) Scope: (full system / specific subsystem or flow)
Diagram
(generated Mermaid code)
Legend
| Symbol | Meaning |
|---|---|
| Solid rectangle | Application or service |
| Cylinder | Data store (database, cache, queue) |
Solid arrow (→) | Synchronous interaction (API, RPC, HTTP) |
Dashed arrow (⇢) | Asynchronous interaction (event, message, pub/sub) |
| Subgraph boundary | System, subsystem, or trust boundary |
[INFERRED] tag | Element derived from indirect evidence — verify with team |
Components
| Component | Type | Technology | Purpose | Owner |
|---|---|---|---|---|
| (Name) | Service / DB / Queue / External | (Stack) | (One-line purpose) | (Team, if known) |
Interactions
| From | To | Type | Protocol | Description |
|---|---|---|---|---|
| (Component A) | (Component B) | Sync/Async | (HTTP, gRPC, Kafka, etc.) | (What data flows) |
Boundaries
| Boundary | Contains | Notes |
|---|---|---|
| (Boundary name) | (Components inside) | (Trust level, team, etc.) |
Inferred Elements
(List any components or relationships marked [INFERRED] with the evidence that led to the inference and what needs verification)
Open Questions
- (Ambiguities in the source material)
- (Missing information that would improve the diagram)
- (Boundary decisions that need team input)
Step 4b: Link to architecture decisions
For each significant component or boundary in the diagram, connect it to the decision that shaped it:
### Architecture decision context
| Component / Boundary | Decision | Status | Rationale summary | Trade-offs |
|---------------------|----------|--------|-------------------|-----------|
| (component name) | (ADR title or decision description) | Active / Superseded / Proposed | (why this approach was chosen) | (what was given up) |
### Constraints annotated on diagram
- (component): (constraint -- e.g., "Must remain on-prem per compliance requirement")
- (boundary): (constraint -- e.g., "Team ownership split here due to org restructure")
- (relationship): (constraint -- e.g., "Sync call required -- event-driven not viable due to consistency requirements")
If ADRs exist, reference them by ID. If they don't, flag this as an opportunity: "These decisions are currently undocumented. Consider creating ADRs for the following architectural choices: ..."
Architecture evolution tracking: When the user requests a diagram update, preserve the previous version:
- Add a
**Version:**field to the metadata (v1, v2, etc.) - Note what changed and why in a
### Change logsection - Offer to generate a before/after comparison diagram showing what shifted
Step 5: Generate visual outputs (optional)
If the user requested visual output beyond markdown, follow the visual-output-addon:
- FigJam (Path D) — convert the Mermaid diagram to a flowchart. System diagrams map well to
graph TBorgraph LRMermaid syntax, which FigJam supports natively. - Miro (Path C) — post the full diagram document (including tables and legend) as a Miro doc. For visual diagrams, use
diagram_createwith the Mermaid syntax. - PDF (Path A) — generate a slide deck with the diagram on one slide and the component/interaction tables on subsequent slides. Use the system diagram slides template if available.
- Gamma (Path B) — generate a presentation with the diagram as the hero visual and supporting detail slides.
Step 6: Iterate
Ask the user:
- Does this capture the system accurately?
- Should I zoom into any component (move from Context → Container → Component)?
- Are the
[INFERRED]elements correct? - Should I add or remove any boundaries?
- Want me to diagram an alternative architecture or a future-state version?
Offer to regenerate with adjustments. Each iteration appends to the same output file with a version note.
Uncertainty Policy
| Topic | Tolerance | Action |
|---|---|---|
| System boundary (what's in vs. out) | Low | STOP and ask — wrong boundary = wrong diagram |
| Component existence | Low | STOP and ask if not clearly evidenced in inputs |
| Interaction type (sync vs. async) | Medium | Assume + flag [INFERRED] — team validates |
| Technology stack per component | High | Best guess or "(TBD)" — non-critical for structure |
| Team ownership | High | Best guess or omit — not always available |
| Data flow details | Medium | Assume + flag [INFERRED] — verify with engineers |
Default: STOP and ask when a topic is not listed above.
Related skills
/boris-model— service relationship modeling from Event Storming (more process-oriented)/event-storm— domain event discovery (upstream input)/snap-document— detailed API/data documentation per bounded context/architecture-discovery— full discovery skill set (Event Storm → Boris → SNAP)/repository-discovery— map services to code repositories (complementary input)/codependency-analyzer— extract code dependencies (complementary input)
Output locations
| Format | Location | Notes |
|---|---|---|
| Markdown | Conversation or saved file | Always produced. Source of truth. Includes Mermaid code block. |
| FigJam diagram | FigJam | Via Figma MCP. Flowchart from Mermaid syntax. |
| Miro doc/diagram | User's specified Miro board | Via Miro MCP. Full document or visual diagram. |
./output/decks/(system-name)-system-diagram.pdf | Via Marp. Branded slides. | |
| Gamma/PPTX | Gamma URL | Via Gamma MCP. Presentation format. |
| File | ./output/system-diagrams/(system-name)-(level)-(date).md | Local file. |
Example Output
Input
- Input sources: RFC document (RFC-0041: Payment Processing Refactor) describing a move from monolithic checkout to discrete services, plus a verbal description: "We have a React storefront, a Node.js monolith that currently handles cart, orders, and payments, a PostgreSQL database, and we're adding Stripe for payment processing and sending order confirmation emails via SendGrid"
- Company / system name: Meridian Commerce —
CheckoutPlatform - Diagram level: Container (applications, data stores, and interactions within the system)
- Perspective: To-be (future state per RFC-0041)
- Visual output: Markdown only
Output
System Diagram: Meridian Commerce — CheckoutPlatform
Date: 2025-07-14 Version: v1 Level: Container Perspective: To-be (future state per RFC-0041) Sources: RFC-0041 (Payment Processing Refactor), verbal system description Scope: Full CheckoutPlatform system — cart, order, and payment flows
Diagram
graph TB
Customer["Customer<br/><i>Authenticated web user</i>"]
Stripe["Stripe<br/><i>Payment gateway API</i>"]
SendGrid["SendGrid<br/><i>Transactional email</i>"]
subgraph "Meridian Commerce — CheckoutPlatform"
subgraph "Web Tier"
Storefront["Storefront App<br/><i>React, TypeScript</i>"]
end
subgraph "API Tier"
CartService["Cart Service<br/><i>Node.js, Express</i>"]
OrderService["Order Service [NEW]<br/><i>Node.js, Express</i>"]
PaymentService["Payment Service [NEW]<br/><i>Node.js, Express</i>"]
NotificationWorker["Notification Worker [NEW]<br/><i>Node.js background worker</i>"]
Monolith["Checkout Monolith [DEPRECATED]<br/><i>Node.js, Express</i>"]
end
subgraph "Messaging"
EventBus[("Order Event Bus [NEW]<br/><i>AWS SQS</i>")]
end
subgraph "Data Tier"
CartDB[("Cart DB<br/><i>PostgreSQL</i>")]
OrderDB[("Order DB [NEW]<br/><i>PostgreSQL</i>")]
PaymentDB[("Payment DB [NEW]<br/><i>PostgreSQL</i>")]
end
end
Customer -->|"HTTPS"| Storefront
Storefront -->|"REST/JSON"| CartService
Storefront -->|"REST/JSON"| OrderService
Storefront -->|"REST/JSON"| PaymentService
CartService -->|"SQL"| CartDB
OrderService -->|"SQL"| OrderDB
PaymentService -->|"SQL"| PaymentDB
OrderService -.->|"Async: order.confirmed event"| EventBus
PaymentService -.->|"Async: payment.captured event"| EventBus
EventBus -.->|"Async: consume events"| NotificationWorker
PaymentService -->|"HTTPS: charge / refund"| Stripe
NotificationWorker -->|"HTTPS: send email"| SendGrid
Legend
| Symbol | Meaning |
|---|---|
| Solid rectangle | Application or service |
| Cylinder | Data store (database, queue) |
Solid arrow (→) | Synchronous interaction (REST, SQL) |
Dashed arrow (⇢) | Asynchronous interaction (event, message) |
| Subgraph boundary | Tier or system boundary |
[NEW] tag | Component introduced in RFC-0041 |
[DEPRECATED] tag | Component to be decommissioned post-migration |
[INFERRED] tag | Element from indirect evidence — verify with team |
Components
| Component | Type | Technology | Purpose | Owner |
|---|---|---|---|---|
| Storefront App | Service | React, TypeScript | Customer-facing checkout UI | Frontend Guild |
| Cart Service | Service | Node.js, Express | Manages cart state and item pricing | Commerce Team |
Order Service [NEW] | Service | Node.js, Express | Creates and tracks orders; split from monolith | Commerce Team |
Payment Service [NEW] | Service | Node.js, Express | Handles charge, refund, and payment state via Stripe | Payments Team |
Notification Worker [NEW] | Worker | Node.js | Consumes order/payment events; sends confirmation emails | Commerce Team |
Checkout Monolith [DEPRECATED] | Service | Node.js, Express | Current combined cart/order/payment handler; retiring post-RFC | Commerce Team |
Order Event Bus [NEW] | Queue | AWS SQS | Decouples order and payment events from notification delivery | Platform Eng |
| Cart DB | Database | PostgreSQL | Persists cart sessions and line items | Commerce Team |
Order DB [NEW] | Database | PostgreSQL | Persists order records and status history | Commerce Team |
Payment DB [NEW] | Database | PostgreSQL | Persists payment intents, charge IDs, and refund records | Payments Team |
| Stripe | External | REST API | Payment gateway — tokenization, charging, refunds | External |
| SendGrid | External | REST API | Transactional email delivery for order confirmations | External |
Interactions
| From | To | Type | Protocol | Description |
|---|---|---|---|---|
| Storefront App | Cart Service | Sync | REST/JSON | Add/update/remove cart items |
| Storefront App | Order Service | Sync | REST/JSON | Submit order from cart |
| Storefront App | Payment Service | Sync | REST/JSON | Initiate and confirm payment |
| Cart Service | Cart DB | Sync | SQL | Read/write cart sessions |
| Order Service | Order DB | Sync | SQL | Persist order records and status |
| Payment Service | Payment DB | Sync | SQL | Store charge IDs, payment intent state |
| Payment Service | Stripe | Sync | HTTPS | Create charge, capture payment, process refunds |
| Order Service | Order Event Bus | Async | AWS SQS | Publish order.confirmed event on successful order creation |
| Payment Service | Order Event Bus | Async | AWS SQS | Publish payment.captured event on successful charge |
| Order Event Bus | Notification Worker | Async | AWS SQS | Deliver events to worker for email dispatch |
| Notification Worker | SendGrid | Sync | HTTPS | Send order confirmation and payment receipt emails |
Boundaries
| Boundary | Contains | Notes |
|---|---|---|
| Web Tier | Storefront App | Public-facing; served via CDN |
| API Tier | Cart Service, Order Service, Payment Service, Notification Worker, Checkout Monolith | Internal network; services communicate via direct REST during migration |
| Messaging | Order Event Bus | AWS-managed; async decoupling between services and notification layer |
| Data Tier | Cart DB, Order DB, Payment DB | One database per service post-migration (per RFC-0041 bounded context split) |
| External | Stripe, SendGrid | Outside system boundary; accessed over public HTTPS |
Proposed Changes (RFC-0041)
[NEW]Order Service — cart-to-order submission logic extracted from the monolith to enable independent scaling and deployment[NEW]Payment Service — payment processing extracted and wired directly to Stripe, removing monolith's Stripe dependency[NEW]Notification Worker — decoupled from request path; consumes SQS events so email failures don't block checkout[NEW]Order Event Bus (SQS) — introduces async event spine; enables future consumers (loyalty, analytics) without modifying core services[NEW]Order DB / Payment DB — separate schemas enforce bounded context isolation; eliminates cross-domain joins present in the current shared PostgreSQL instance[DEPRECATED]Checkout Monolith — to be decommissioned after all traffic is routed through replacement services