8  C4 Architecture Projections

Quarto-Needs integrates the C4 model (Context, Container, Component, Code) into the canonical engineering graph. Rather than creating architecture diagrams in external drawing tools that drift from requirements, architecture elements are first-class engineering objects connected by typed relations.

8.1 Architecture Elements

C4 elements are authored using standard .need blocks with dedicated types:

Type C4 Level Suggested Prefix Role
system Context / Container SYS- architecture-element
external-system Context EXT- architecture-element
actor Context ACTOR- architecture-element
container Container CONTAINER- architecture-element
component Component COMP- architecture-element
source-module Code SRC- implementation-artifact
deployment-node Deployment DEPLOY- architecture-element

8.2 Hierarchical Relations

C4 diagrams derive structure from two primary relations:

  1. part-of: defines structural containment.
    • container is part-of a system
    • component is part-of a container
    • source-module is part-of a component
  2. depends-on: defines interaction and dependencies between elements. It may carry inline attributes: label overrides the relationship description in every diagram, and technology is rendered as the relationship technology where the backend supports it (Rel(..., "label", "technology") in Mermaid and PlantUML; folded into the edge label in D2).
  3. deployed-on: places an artifact on a deployment node (container or component is deployed-on a deployment-node), and nested deployment nodes are part-of their parent node.
  4. interacts-with: an ordered runtime interaction between two elements for a dynamic view (initiator is interacts-with participant). The order attribute sequences the interactions; label and technology render like any other relationship.

Example:

::: {.need #SYS-APP type="system" status="approved"}
## Enterprise Application
Core transaction and management platform.
:::

::: {.need #CONTAINER-API type="container" status="approved" technology="FastAPI / Python" part-of="SYS-APP"}
## REST API Container
Handles business logic and external integrations.
:::

::: {.need #COMP-AUTH type="component" status="implemented" part-of="CONTAINER-API"}
## Authentication Service
Validates bearer tokens and enforces permissions.
:::

8.3 Modeling cookbook

8.3.1 Modeling a deployment

Declare one deployment-node per place things run, put nested nodes part-of their parent, and place each artifact on a node with deployed-on:

::: {.need #DEPLOY-PROD type="deployment-node" status="approved" environment="production"}
## Production
The managed runtime that serves the containers.
:::

::: {.need #CONTAINER-API type="container" status="approved" technology="FastAPI / Python" part-of="SYS-APP" deployed-on="DEPLOY-PROD"}
## REST API Container
:::
{{< need-c4 root="DEPLOY-PROD" level="deployment" >}}

level="deployment" requires a deployment-node focus. The view draws the node’s boundary with its nested nodes and the containers/components deployed on it; an artifact with no deployed-on edge is simply not shown. deployed-on is the authoring direction (artifact → node); deploys is its accepted inverse. Mermaid renders C4Deployment, PlantUML includes C4_Deployment, Structurizr uses a deploymentEnvironment, and D2 nests packages.

8.3.2 Modeling a dynamic scenario

Order runtime interactions with interacts-with and an order attribute; label and technology render like any other relationship:

::: {.need #ACTOR-ENGINEER type="actor" status="approved" interacts-with='CONTAINER-WEB order="1" label="submits a request"'}
## Engineer
:::

::: {.need #CONTAINER-WEB type="container" status="approved" technology="React" part-of="SYS-APP" interacts-with='CONTAINER-API order="2" label="calls the API" technology="HTTPS/JSON"'}
## Web Application
:::
{{< need-c4 root="SYS-APP" level="dynamic" >}}

level="dynamic" requires a system focus. Participants are the focus, its direct containers, and every interaction partner of that set — an interaction between two containers is drawn even though neither touches the system directly. Interactions are numbered by order (un-ordered edges sort last, deterministically). Mermaid renders C4Dynamic with RelIndex, PlantUML a sequence diagram, Structurizr a dynamic view, and D2 a sequence diagram.

8.4 Rendering C4 Diagrams

Use the {{< need-c4 >}} shortcode to render architecture views:

{{< need-c4 root="SYS-APP" level="context" >}}
{{< need-c4 root="SYS-APP" level="container" >}}
{{< need-c4 root="CONTAINER-API" level="component" >}}
{{< need-c4 root="COMP-AUTH" level="code" >}}
{{< need-c4 root="DEPLOY-PROD" level="deployment" >}}
{{< need-c4 root="SYS-APP" level="dynamic" >}}

8.4.1 Supported Levels

  • context: Focuses on a system and its interactions with actors and external-systems.
  • container: Zooms into a system to show its constituent containers and external connections.
  • component: Zooms into a container to reveal internal components and dependencies.
  • code: Materializes the implementation surface as a structured Markdown table of source-module artifacts, file paths, languages, and requirements implemented.
  • deployment: Focuses on a deployment-node, showing nested nodes and the artifacts deployed-on it.
  • dynamic: Focuses on a system and draws its ordered runtime interactions as a numbered sequence (Mermaid C4Dynamic, a PlantUML sequence diagram, a Structurizr dynamic view, or a D2 sequence diagram).

8.4.2 Multiple Diagramming Backends

Quarto-Needs supports multiple diagramming backends via the backend argument:

{{< need-c4 root="SYS-APP" level="container" backend="mermaid" >}}
{{< need-c4 root="SYS-APP" level="container" backend="plantuml" >}}
{{< need-c4 root="SYS-APP" level="container" backend="structurizr" >}}
{{< need-c4 root="SYS-APP" level="container" backend="d2" >}}
  • mermaid (default): Embedded directly in HTML as responsive inline SVG.
  • plantuml, structurizr, d2: If the respective tool is installed locally, pre-renders SVG/PNG assets; otherwise falls back gracefully to syntax-highlighted diagram source code.

Deployment-level PlantUML output includes the C4_Deployment stdlib; a PlantUML old enough to lack that file falls back to source text exactly like a missing backend.

Because that fallback is silent, a publishing pipeline can ship source code where diagrams belong. Run tools/install_diagram_backends.sh to provision all three on Linux; CI runs the same script and then fails the build if any diagram rendered as source.

8.5 Architecture Governance (C4 Rules)

The C4 rule engine validates diagram structural integrity:

Rule Check
C4001 In a Container view, every container must declare its parent system via part-of
C4002 In a Component view, every component must declare its parent container via part-of
C4003 Inter-element relations must have a descriptive label
C4004 Hierarchy violations (e.g. cyclic containment or orphan boundaries) are rejected