Build·Raw Blue

Build

Build with raw Blue

Raw Blue is the lowest-level and most precise way to author the system. Direct control over types, fields, participants, contracts, workflows, and references — no abstraction layer between you and the language.

Why use raw Blue?

Use raw Blue when you want:

  • exact control over the document structure
  • protocol-level understanding
  • portable document definitions
  • a better understanding of what Blink or the SDK is generating

A guided walk: build a Counter step by step

Step 1 — content only

Start with pure state. No rules, no behavior.

yaml
name: Demo Counter
counter: 0

This is a perfectly valid Blue document. No participants yet, no operations.

Step 2 — bind a channel to a timeline

To let any participant act on this document, declare a Conversation/Timeline Channel:

yaml
name: Demo Counter
counter: 0
contracts:
  ownerChannel:
    type: Conversation/Timeline Channel
    timelineId: owner-1

The owner's timeline can now feed entries into the document — but the document does not yet know what to do with them.

Step 3 — declare an operation

Tell the document there is an operation called increment on the owner channel, expecting an integer request:

yaml
contracts:
  ownerChannel:
    type: Conversation/Timeline Channel
    timelineId: owner-1
  increment:
    type: Conversation/Operation
    channel: ownerChannel
    request:
      type: Integer

This says this operation exists. It does not yet say what to do when invoked.

Step 4 — implement the operation with a workflow

Add a Conversation/Sequential Workflow Operation handler that runs one Conversation/Update Document step:

yaml
contracts:
  ownerChannel:
    type: Conversation/Timeline Channel
    timelineId: owner-1
  increment:
    type: Conversation/Operation
    channel: ownerChannel
    request:
      type: Integer
  incrementHandler:
    type: Conversation/Sequential Workflow Operation
    operation: increment
    steps:
      - name: ApplyIncrement
        type: Conversation/Update Document
        changeset:
          - op: replace
            path: /counter
            val: ${event.message.request + document('/counter')}

The expression in val reads the request payload from the timeline entry and the current value of /counter, then writes the sum back. That is what makes the document live.

Step 5 — send a timeline entry

To trigger the operation, write a Conversation/Timeline Entry whose message is a Conversation/Operation Request:

yaml
type: Conversation/Timeline Entry
timeline:
  timelineId: owner-1
message:
  type: Conversation/Operation Request
  operation: increment
  request: 5
  allowNewerVersion: true

Send this entry to the document via the processor and /counter moves from 0 to 5. The entry's BlueId becomes the prevEntry.blueId of the next one on this channel.

Open this in the stepper → The document stepper ships exactly this Counter as its preloaded sample. You can submit different values, watch the diff, and see totalGas reported by the real processor.

What raw Blue should teach you

Blue is not "YAML as configuration." Blue is a structured language for interactions. YAML is just one authoring form.

A useful progression

  1. Read the mental model first.
  2. Inspect one generated block from MyOS.
  3. Compare it to the raw Blue form above.
  4. Run it in the stepper.
  5. Then read the spec for exact semantics.