UMA Universal Microservices Architecture Buy the book

UMA diagrams

This page collects reusable diagrams for Universal Microservices Architecture. Each section explains what the diagram is trying to make visible, when to use it, and how to adapt the underlying source for documentation, architecture reviews, and implementation discussions.

Why diagram curation matters

UMA depends on architectural visibility. The more clearly a team can show service boundaries, runtime transitions, trust decisions, and compatibility relationships, the easier the model is to teach, review, and evolve. These diagrams are designed to clarify one important boundary at a time instead of collapsing the whole architecture into one poster.

A useful UMA diagram should answer one concrete question. What is portable and what is runtime-owned? Where is a trust boundary enforced? How does a graph of compatible services emerge over time? When the question is specific, the diagram stays readable and reusable.

Diagram conventions

The diagrams on this page reuse the same conventions so readers do not need to learn a new visual language each time. Portable service behavior is highlighted as the part that must remain stable. Runtime-owned elements are shown separately so transport, policy, validation, and adapter decisions do not disappear into the background. Supporting metadata is shown as its own layer whenever it shapes compatibility or governance.

  • Portable service behavior is the durable center of the model.
  • Runtime shells, adapters, and policy decisions stay explicit.
  • Trust transitions are shown before a protected capability executes.
  • Graphs evolve through visible contracts and metadata, not hidden rewiring.

Diagram 1: Portable service boundary

This diagram shows the core UMA split between pure service behavior and the runtime shell that validates input, binds adapters, and decides where execution happens. The point is to make the portable unit of behavior explicit instead of burying it inside a stack-specific application boundary.

Caption: The service stays portable and deterministic. The runtime owns validation, transport, policy, and adapter binding.

flowchart LR
    Client["Client / Caller"] --> Runtime["Runtime shell"]
    Runtime --> Contract["Contract validation"]
    Contract --> Service["Portable UMA service"]
    Service --> Output["Deterministic result"]
    Runtime --> Adapters["Adapters / host capabilities"]
    Adapters --> Output

    classDef portable fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef runtime fill:#0d0d0d,stroke:#4a4a4a,color:#ffffff;

    class Service portable;
    class Runtime,Contract,Adapters runtime;

Use this diagram when a reader needs to understand the most important UMA boundary first: what belongs inside the portable service and what belongs in the runtime shell around it. It works well on introductory pages, capability documentation, and design reviews where teams are still separating business behavior from environment-specific concerns.

View diagram source
flowchart LR
    Client["Client / Caller"] --> Runtime["Runtime shell"]
    Runtime --> Contract["Contract validation"]
    Contract --> Service["Portable UMA service"]
    Service --> Output["Deterministic result"]
    Runtime --> Adapters["Adapters / host capabilities"]
    Adapters --> Output

    classDef portable fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef runtime fill:#0d0d0d,stroke:#4a4a4a,color:#ffffff;

    class Service portable;
    class Runtime,Contract,Adapters runtime;
Download source

Diagram 2: Runtime execution flow

UMA is not only about where behavior lives. It is also about how the runtime executes that behavior predictably. This sequence shows the flow from request to validation, service execution, adapter access, and final response without hiding the runtime decisions that shape the outcome.

Caption: The runtime remains visible. Validation and adapter binding are first-class parts of the execution model.

sequenceDiagram
    participant Caller
    participant Runtime
    participant Service
    participant Adapter

    Caller->>Runtime: Invoke capability
    Runtime->>Runtime: Validate against contract
    Runtime->>Service: Execute portable logic
    Service->>Adapter: Request host capability
    Adapter-->>Service: Return external data
    Service-->>Runtime: Produce result
    Runtime-->>Caller: Return validated response

Use this diagram when the architectural question is about execution rather than boundaries. It shows that a UMA runtime is not a black box around the service. Validation, adapter access, and response shaping are visible stages that determine whether the system behaves predictably across environments.

View diagram source
sequenceDiagram
    participant Caller
    participant Runtime
    participant Service
    participant Adapter

    Caller->>Runtime: Invoke capability
    Runtime->>Runtime: Validate against contract
    Runtime->>Service: Execute portable logic
    Service->>Adapter: Request host capability
    Adapter-->>Service: Return external data
    Service-->>Runtime: Produce result
    Runtime-->>Caller: Return validated response
Download source

Diagram 3: Trust boundary decision

Trust decisions in UMA should not be implicit. This diagram shows a simplified runtime trust flow where identity, policy, and capability intent are evaluated before the runtime allows a protected service to execute. It is a useful pattern for pages that explain trust boundaries and governed execution.

Caption: Access is not assumed. The runtime evaluates identity and policy before crossing a protected boundary.

flowchart TD
    Request["Invocation request"] --> Identity["Resolve identity"]
    Identity --> Policy["Evaluate policy"]
    Policy -->|allowed| Capability["Protected capability"]
    Policy -->|denied| Rejected["Denied decision"]
    Capability --> Audit["Audit / evidence"]

    classDef allow fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef deny fill:#151515,stroke:#666666,color:#ffffff;

    class Capability,Audit allow;
    class Rejected deny;

Use this diagram when readers need to see where governance happens. UMA is stronger when trust, identity, permissions, and audit evidence stay visible. This pattern works well for security-oriented pages, policy discussions, and runtime trust documentation where the system must explain why a protected capability was allowed or denied.

View diagram source
flowchart TD
    Request["Invocation request"] --> Identity["Resolve identity"]
    Identity --> Policy["Evaluate policy"]
    Policy -->|allowed| Capability["Protected capability"]
    Policy -->|denied| Rejected["Denied decision"]
    Capability --> Audit["Audit / evidence"]

    classDef allow fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef deny fill:#151515,stroke:#666666,color:#ffffff;

    class Capability,Audit allow;
    class Rejected deny;
Download source

Diagram 4: Service graph evolution

Once systems grow beyond one portable service, teams need to visualize how compatible capabilities form a graph. This diagram shows a simple evolution path from a single service to a governed graph, where contracts and metadata keep relationships understandable instead of turning into hidden rewiring.

Caption: Services evolve into a graph through visible contracts and metadata, not through accidental coupling.

flowchart LR
    A["Feature flag evaluator"] --> B["Post fetcher runtime"]
    B --> C["Metadata orchestration"]
    C --> D["Service graph"]
    D --> E["Trust boundaries"]
    E --> F["System evolution"]

    Meta["Contracts + metadata"] --- C
    Meta --- D
    Meta --- E

    classDef main fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef meta fill:#0d0d0d,stroke:#4a4a4a,color:#ffffff;

    class A,B,C,D,E,F main;
    class Meta meta;

Use this diagram when the conversation moves from one portable service to a broader system. It helps explain how compatible services, metadata, and policy start to form a graph that can change over time without becoming opaque. It is especially useful on pages about growth, compatibility, and runtime-governed evolution.

View diagram source
flowchart LR
    A["Feature flag evaluator"] --> B["Post fetcher runtime"]
    B --> C["Metadata orchestration"]
    C --> D["Service graph"]
    D --> E["Trust boundaries"]
    E --> F["System evolution"]

    Meta["Contracts + metadata"] --- C
    Meta --- D
    Meta --- E

    classDef main fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef meta fill:#0d0d0d,stroke:#4a4a4a,color:#ffffff;

    class A,B,C,D,E,F main;
    class Meta meta;
Download source

Diagram 5: Evolution without fragmentation

This diagram captures a progression many teams recognize but rarely name clearly. One contract anchor stretches into behavioral drift, drift leads to duplication, duplication hardens into version sprawl, and then the architecture either fragments or learns how to govern coexistence explicitly.

Caption: Governed evolution is not the absence of change. It is change that remains explainable through contracts and runtime authority.

flowchart LR
    A["Contract anchor"] --> B["Behavioral drift"]
    B --> C["Duplicate implementations"]
    C --> D["Version sprawl"]
    D --> E["Runtime-governed coexistence"]
    E --> F["Hybrid adoption"]

    classDef stable fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef risk fill:#151515,stroke:#ff8a3d,color:#ffffff;
    classDef governed fill:#151515,stroke:#4bd37b,color:#ffffff;

    class A stable;
    class B,C,D risk;
    class E,F governed;

Use this diagram when the architectural question is about long-term change rather than static structure. It helps teams talk about which stage of evolution they are actually in, why versioning alone does not prevent fragmentation, and how runtime-governed coexistence creates room for brownfield improvement.

View diagram source
flowchart LR
    A["Contract anchor"] --> B["Behavioral drift"]
    B --> C["Duplicate implementations"]
    C --> D["Version sprawl"]
    D --> E["Runtime-governed coexistence"]
    E --> F["Hybrid adoption"]

    classDef stable fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef risk fill:#151515,stroke:#ff8a3d,color:#ffffff;
    classDef governed fill:#151515,stroke:#4bd37b,color:#ffffff;

    class A stable;
    class B,C,D risk;
    class E,F governed;
Download source

Diagram 6: Discoverable decision lifecycle

This diagram shows the decision ladder that becomes a first-class architectural topic in the later UMA examples. Discoverability is not only about surfacing which capabilities exist. It is about surfacing how a projected path became a proposal, how authority validated it, where revision was allowed, and what trace remained afterward.

Caption: A discoverable system does not only execute. It exposes how an outcome moved from proposal to authoritative trace.

flowchart LR
    A["Capability projection"] --> B["Proposal"]
    B --> C["Authority validation"]
    C --> D["Bounded revision"]
    D --> E["Approved execution"]
    E --> F["Queryable trace"]

    classDef visible fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef authority fill:#151515,stroke:#4bd37b,color:#ffffff;

    class A,B,D,F visible;
    class C,E authority;

Use this diagram when the conversation is about queryable decisions instead of only runtime control. It works especially well on pages about workflows, runtime authority, and the reference application, where execution alone is not the final architectural product.

View diagram source
flowchart LR
    A["Capability projection"] --> B["Proposal"]
    B --> C["Authority validation"]
    C --> D["Bounded revision"]
    D --> E["Approved execution"]
    E --> F["Queryable trace"]

    classDef visible fill:#151515,stroke:#ffc501,color:#ffffff;
    classDef authority fill:#151515,stroke:#4bd37b,color:#ffffff;

    class A,B,D,F visible;
    class C,E authority;
Download source

How to choose the right diagram

Use the service boundary diagram when the question is about separation of concerns. Use the execution flow when the question is about what a runtime actually does. Use the trust diagram when readers need to see where permissions and policy are enforced. Use the graph evolution diagram when the system story is about growth, compatibility, and governed change. Use the evolution without fragmentation diagram when the story is specifically about drift, duplication, version sprawl, and governed coexistence. Use the discoverable decision lifecycle when the story is about how a proposal becomes an approved and traceable outcome.

These diagrams should support the prose on this site, not replace it. The right use is to put one of them next to a paragraph that answers a specific question in plain language. That makes the visual reinforce the explanation instead of competing with it.

Download the current diagram set

Every diagram on this page has a downloadable source file so the same visual models can move into repository documentation, issue discussions, architecture notes, and future chapter pages. That keeps the diagrams reusable and versionable instead of trapped inside static screenshots.

Where these diagrams connect next

The strongest next uses for these diagrams are the pages that explain service graphs, runtime trust decisions, portability, and the learning path from one portable service to governed system evolution.