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

Concept 03 of 08

Contracts

A record tells you what is true. It never tells you what happens next. In every conventional system, "what happens next" lives somewhere else — a service, a queue worker, a deployment — and the document is just its residue. Blue puts the behavior in the document.

One small boundary

The whole processing model is one function:

PROCESS(document, event) → new document + emitted events + gas used

Deterministic, atomic, no wall clock, no network, no hidden state. Same document, same event — same result, on any conforming implementation, forever. If processing fails, the previous document stands untouched. There is no half-applied state to clean up, because half-applied states cannot be expressed.

Events arrive through channels

A document declares named routes through which events may enter:

contracts:
  restaurantChannel:
    type: Timeline Channel
    # bound to the restaurant's verified history — see Timelines

Where those events come from and why they're trustworthy is the Timelines section's job. For now: an event enters through a channel, and behavior binds to channels — not to "anything that looks right."

Handlers and Operations

A Handler reacts to events on its channel. The most useful kind is an Operation — a named, callable capability. Here is a dinner order the restaurant can confirm:

name: Dinner Order
status: proposed

contracts:
  restaurantChannel:
    type: Timeline Channel

  confirm:
    type: Sequential Workflow Operation
    channel: restaurantChannel
    request:
      reference:
        type: Text
    steps:
      - name: Apply Confirmation
        type: Compute
        do:
          - $appendChange:
              op: replace
              path: /status
              val: confirmed
          - $appendEvent:
              type: Order Confirmed
          - $return: true

Interface and implementation, visible in one place: the operation is confirm, it belongs to the restaurant's channel, it takes a reference, and its exact steps are right there — with their own BlueId, like everything else.

Nobody writes /status directly. A caller submits an Operation Request:

type: Operation Request
channel: restaurantChannel
operation: confirm
request:
  reference: DINNER-8841

The operation owns the transition. That single discipline — requests name operations, operations own state — is what keeps invariants enforceable and history explainable. It matters doubly once callers include machines: an operation surface is discoverable and constrainable; raw writes are neither.

Documents have lifecycles

Documents aren't rows that exist until deleted. They initialize, live, and terminate — and each phase is processed behavior:

initialize → active → ... → terminated

Initialization is itself processed: handlers can react to Document Processing Initiated like any other event — establishing derived state, checking required configuration, or failing deterministically before anything else runs. Termination is graceful: handlers get to react, the final state remains inspectable, and the history explains why it ended.

Different documents live differently, with no extra machinery:

  • a standing agreement initializes once and lives through months of operations;
  • a one-shot approval initializes, processes one decision, emits a result, terminates;
  • an embedded order is born when its parent creates it and reaches a terminal state without ending the parent;
  • a Mandate moves Pending → Active → Terminated, and its current stage is its authority.

Nothing vanishes; things conclude — with an exact final state and a reason.

BEX: logic as data

The do: blocks above are BEX — Blue's deterministic expression language, written as data, not as code strings. A BEX program reads the document and event, computes values, and returns effects — changes and events — which the processor applies under its own rules. Because BEX programs are Blue nodes, they have BlueIds: behavior is versioned, referenced, and audited exactly like data. No clock, no randomness, no network — by construction.

Gas

Deterministic processing needs a deterministic budget, or a malformed document could react forever. Gas is Blue's answer, and it belongs to the language's processing model as a whole — not to any single runtime. The processor meters everything it does — patches, event routing, validation, lifecycle — and every runtime it hosts reports into the same ledger; BEX contributes its own counters (expressions evaluated, reads, items examined) as one participant among others.

Two properties matter. The total is identical across implementations: same document, same event, same gas, on a laptop or a server farm. And it is representation-neutral: warm caches and pre-expanded nodes make processing faster, never cheaper — and a workflow that never reads a ten-thousand-node archive pays nothing for the archive's existence. Gas prices meaning, not plumbing.

Next concept

Timelines