Skip to content
language.blue
repo.blue ↗ Open Playground
Blue/Concepts/Embedded Documents

Concept 05 of 08

Embedded Documents

The most interesting documents are not pages — they are containers of living things. An agreement holds orders; an order holds a reservation; a payment participates in several relationships at once. Embedding is how Blue builds realities out of realities without collapsing them into one blob.

Embedding is declared, not inferred

Nested YAML is just data. A child becomes a living part of its parent only by declaration:

contracts:
  embedded:
    type: Process Embedded
    paths:
      - /orders/flowers
      - /orders/dinner
      - /payment

Each declared path is now an owned processing scope: its own contracts, channels, lifecycle, and checkpoints — inside the parent's committed reality. And it's recursive: the dinner order can declare its own embedded reservation, forming ownership chains as deep as the domain requires:

Agreement
├── /orders/flowers        (declared by Agreement)
│   └── /fulfillment       (declared by Flower Order)
└── /orders/dinner
    └── /reservation

One rule holds everything together: one root, one commit. When the restaurant confirms dinner, the order changes, the agreement reacts, and both changes land in a single atomic transition. There is no moment where dinner says confirmed while the agreement still says waiting — the half-updated state that plagues every integration project simply cannot be expressed. This is also why completeness is gathered across the root and all embedded documents before processing: one atomic reality deserves one closed window of evidence.

Documents listen to each other

An embedded child keeps its own channels — the dinner order listens to the restaurant's Timeline directly, no parent proxying required. And the parent listens to the child:

contracts:
  dinnerEvents:
    type: Embedded Node Channel
    childPath: /orders/dinner

Now events cascade with reinterpretation at each level:

Reservation emits Capacity Held
  → Dinner Order emits Order Confirmed
    → Agreement marks a condition satisfied
      → Payment sees all conditions met, requests capture

Each scope speaks its own vocabulary; each ancestor translates local facts into broader ones. This is how you get elaborate coordination without one monstrous workflow that hard-codes every branch at the top. And the boundary is disciplined: internal events stay internal unless the root explicitly emits its own — the root alone speaks publicly for the root.

One document, many realities

"The payment is part of the agreement and part of the order." Blue makes you say which of three things you mean — and rewards the precision:

  1. Shared immutable content. Both reference the same payment-terms node by BlueId. Pure reuse; nothing to coordinate.
  2. Two occurrences of one type. Each context owns its own payment process, instantiated from a shared definition. Shared behavior, separate lives.
  3. One autonomous document, observed by many. The payment is its own root, evolving under its own providers. It publishes events — Authorized, Captured, Reversed — onto a Timeline; the agreement, the order, and an invoice each observe those events through their own channels and react in their own contexts.

The third form is the profound one: the documents share evidence, not memory. Nobody owns anyone else's state; everyone reacts to the same verified facts. A payment becomes a fact of reality that means settlement to the agreement, fulfillment to the order, and reconciliation to the invoice — simultaneously, consistently, without a central coordinator. That is what "connecting different parts of reality" means, concretely.

Choosing between the three is usually mechanical:

You needUse
Shared unchanging content — terms, policies, workflow bodiesa plain reference
An owned part that must commit atomically with its parentan embedded document
An independent life that several documents observean autonomous document publishing events

Next concept

Mandates