Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

JSON Schemas

Schemas are provided as JSON Schema (Draft 2020-12). Each implementation must validate against these schemas. The JSON representation of the wire format is normative; future binary codecs encode the same shapes.

SchemaLayer
defs.jsonShared wire primitives (NodeId, NodeKey, NodeState, IpcValue, ShmBlobRef, WireStamp)
snapshot.jsonIPC — Snapshot message (externally-tagged {"Snapshot": …} envelope)
delta.jsonIPC — Delta message (externally-tagged {"Delta": …}, all 7 DeltaOp variants)
ffi.jsonCross-language FFI boundary
signaling.jsonSignaling (WebSocket)
distributed.jsonDistributed — CrdtSync message ({"CrdtSync": …}) + CRDT/cell-model types
receipts.jsonCausal receipts ({"CausalReceipts": …}) + terminal outcome projection
message-passing.jsonCommand / RPC message plane (CommandSubmit / CommandCancel / CommandEvents / CommandProjection)
statechart.jsonCompute (Harel/SCXML chart form — not a wire message)
stdlib-fixture.schema.jsonDeterministic Timer, Timeout, and RevisionBarrier conformance scenarios
assertion-blocks.jsonRouted, fail-closed schemas for every canonical assertions / expect / expected object

The IPC schemas describe the normative externally-tagged envelope that every binding serializes (the single-key {"Snapshot": …} / {"Delta": …} / {"CrdtSync": …} form), with node addressing and value bytes as JSON arrays of u8 (not base64). Shared wire primitives live in defs.json and are referenced via absolute $ref so the primitive definitions never copy-drift. Every conformance fixture’s wire field validates against its schema — enforced by make test-schemas (see tests/test_schema_conformance.py).

Assertion blocks are validated independently of their fixture’s wire or compute schema, so families without a whole-fixture schema still reject unknown claim keys and stale value shapes. See Assertion-Block Schemas.

defs.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/defs.json",
  "title": "Shared wire primitive definitions",
  "description": "Primitive types shared across the lazily IPC schemas (snapshot, delta, distributed). Referenced via absolute $ref so every wire schema stays codec-faithful to protocol.md without copy-drift.",
  "$defs": {
    "NodeId": {
      "type": "integer",
      "minimum": 0,
      "maximum": 18446744073709551615,
      "description": "Wire-stable node identifier (u64). The full u64 range is wire-valid; the 2^53-1 bound is a PRODUCER obligation on peers whose runtime represents integers as IEEE-754 doubles, and a decoder that cannot represent a received value exactly MUST reject the frame rather than round it (protocol.md § NodeId / PeerId, #lzspecdecoderbound). Schema validity is therefore u64-wide — a narrower binding refuses at decode, not here."
    },
    "PeerId": {
      "type": "integer",
      "minimum": 0,
      "maximum": 18446744073709551615,
      "description": "Wire-stable peer identifier (u64). Same producer bound and decoder obligation as NodeId (#lzspecdecoderbound). This carried maximum 9007199254740991 until that audit, which contradicted both the u64 wire type and protocol.md's producer-only wording."
    },
    "NodeKey": {
      "type": "string",
      "minLength": 1,
      "maxLength": 1024,
      "pattern": "^[^/]+(/[^/]+)*$",
      "description": "Optional wire-stable keyed address: a '/'-joined path (e.g. 'scores/alice'). The pattern rejects empty/leading/trailing/double slashes; construction-time code also enforces the ≤1024 *byte* and ≤32 *segment* bounds (see protocol.md § NodeKey). Serialized as a bare string; the field is omitted in self-describing codecs when absent."
    },
    "ShmBlobRef": {
      "type": "object",
      "description": "Descriptor into a blob backend (zero-copy transport). The standard fields locate and integrity-check a byte range within the backend's resolved buffer; `backend` selects which pluggable backend resolves it ('shm' = POSIX shared memory, the default for backward compatibility; 'arrow' = Apache Arrow IPC/Flight; 'in_process' = an in-process arena). See protocol.md § Zero-copy transport. `backend` is optional and defaults to 'shm' so legacy descriptors validate unchanged.",
      "required": ["offset", "len", "generation", "epoch", "checksum"],
      "additionalProperties": false,
      "properties": {
        "offset": { "type": "integer", "minimum": 0 },
        "len": { "type": "integer", "minimum": 0 },
        "generation": { "type": "integer", "minimum": 0 },
        "epoch": { "type": "integer", "minimum": 0 },
        "checksum": { "type": "integer", "minimum": 0 },
        "backend": { "type": "string", "enum": ["shm", "arrow", "in_process"], "default": "shm", "description": "Which pluggable backend holds the blob. Optional; defaults to 'shm' (POSIX shared memory) for backward compatibility. The receiver routes resolution by this discriminator." }
      }
    },
    "NodeState": {
      "description": "Externally-tagged node body: concrete bytes, a shared-memory value, or an opaque (visible but non-serializable) node.",
      "oneOf": [
        {
          "type": "object",
          "title": "Payload",
          "required": ["Payload"],
          "additionalProperties": false,
          "properties": {
            "Payload": {
              "type": "array",
              "items": { "type": "integer", "minimum": 0, "maximum": 255 },
              "description": "Serialized value bytes as JSON array of u8 (NOT base64)."
            }
          }
        },
        {
          "type": "object",
          "title": "SharedBlob",
          "required": ["SharedBlob"],
          "additionalProperties": false,
          "properties": { "SharedBlob": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/ShmBlobRef" } }
        },
        { "type": "string", "title": "Opaque", "const": "Opaque" }
      ]
    },
    "IpcValue": {
      "description": "Externally-tagged delta payload: inline bytes or a shared-memory blob reference.",
      "oneOf": [
        {
          "type": "object",
          "title": "Inline",
          "required": ["Inline"],
          "additionalProperties": false,
          "properties": {
            "Inline": {
              "type": "array",
              "items": { "type": "integer", "minimum": 0, "maximum": 255 },
              "description": "Inline serialized bytes as JSON array of u8 (NOT base64)."
            }
          }
        },
        {
          "type": "object",
          "title": "SharedBlob",
          "required": ["SharedBlob"],
          "additionalProperties": false,
          "properties": { "SharedBlob": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/ShmBlobRef" } }
        }
      ]
    },
    "WireStamp": {
      "type": "object",
      "description": "Wire mirror of the runtime HLC stamp — a total order (wall_time, logical, peer).",
      "required": ["wall_time", "logical", "peer"],
      "additionalProperties": false,
      "properties": {
        "wall_time": { "type": "integer", "minimum": 0, "description": "Wall-clock microseconds since the Unix epoch." },
        "logical": { "type": "integer", "minimum": 0, "description": "Logical counter advancing causality within equal wall_time." },
        "peer": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/PeerId", "description": "Originating peer; final tiebreak so equal (wall, logical) is a total order." }
      }
    }
  }
}

snapshot.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/snapshot.json",
  "title": "Snapshot",
  "description": "Full graph state IPC message. Normative form (protocol.md § IPC) is the EXTERNALLY-TAGGED envelope {\"Snapshot\": {...}} — not a \"type\" discriminant. Serialized value bytes are JSON arrays of u8, not base64. A NodeSnapshot's optional `key` (NodeKey) is omitted when absent.",
  "type": "object",
  "required": ["Snapshot"],
  "additionalProperties": false,
  "properties": {
    "Snapshot": {
      "type": "object",
      "required": ["epoch", "nodes", "edges", "roots"],
      "additionalProperties": false,
      "properties": {
        "epoch": { "type": "integer", "minimum": 0, "description": "Current IPC epoch." },
        "nodes": { "type": "array", "items": { "$ref": "#/$defs/NodeSnapshot" }, "description": "All serialized nodes." },
        "edges": { "type": "array", "items": { "$ref": "#/$defs/EdgeSnapshot" }, "description": "Dependency edges (dependent → dependency)." },
        "roots": { "type": "array", "items": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" }, "description": "Cell and source slot ids." }
      }
    }
  },
  "$defs": {
    "NodeSnapshot": {
      "type": "object",
      "description": "Full state for one node in a snapshot.",
      "required": ["node", "type_tag", "state"],
      "additionalProperties": false,
      "properties": {
        "node": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" },
        "type_tag": { "type": "string", "description": "Stable cross-process type key for decoding state." },
        "state": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeState" },
        "key": {
          "description": "Optional wire-stable keyed address. A conforming ENCODER omits it when absent; an explicit null is also wire-valid and a decoder MUST read both forms as absent (protocol.md § NodeKey, #lzkeynullstrict). This carried a bare NodeKey $ref until that audit, which made a frame the spec now requires decoders to accept schema-invalid.",
          "oneOf": [
            { "type": "null" },
            { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeKey" }
          ]
        }
      }
    },
    "EdgeSnapshot": {
      "type": "object",
      "description": "Directed dependency edge (dependent → dependency).",
      "required": ["dependent", "dependency"],
      "additionalProperties": false,
      "properties": {
        "dependent": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" },
        "dependency": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" }
      }
    }
  }
}

delta.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/delta.json",
  "title": "Delta",
  "description": "Incremental change-set IPC message. Normative form (protocol.md § IPC) is the EXTERNALLY-TAGGED envelope {\"Delta\": {...}} — not a \"type\" discriminant. Each DeltaOp variant is itself externally tagged by its PascalCase name (single-key object). Serialized value bytes are JSON arrays of u8, not base64. NodeAdd's optional `key` (NodeKey) is omitted in JSON when absent.",
  "type": "object",
  "required": ["Delta"],
  "additionalProperties": false,
  "properties": {
    "Delta": {
      "type": "object",
      "required": ["base_epoch", "epoch", "ops"],
      "additionalProperties": false,
      "properties": {
        "base_epoch": { "type": "integer", "minimum": 0, "description": "Epoch this delta applies to (must equal the receiver's last_epoch)." },
        "epoch": { "type": "integer", "minimum": 0, "description": "New epoch, >= base_epoch + 1. Usually base_epoch + 1; a multi-epoch-span delta has epoch > base_epoch + 1 (epoch - base_epoch = accepted-event span). See protocol.md § Multi-epoch-span delta." },
        "ops": { "type": "array", "items": { "$ref": "#/$defs/DeltaOp" }, "description": "Ordered operations." }
      }
    }
  },
  "$defs": {
    "DeltaOp": {
      "description": "One incremental graph mutation. Externally tagged: a single-key object whose key is the PascalCase variant name.",
      "oneOf": [
        {
          "type": "object",
          "title": "CellSet",
          "required": ["CellSet"],
          "additionalProperties": false,
          "properties": { "CellSet": { "$ref": "#/$defs/CellSetBody" } }
        },
        {
          "type": "object",
          "title": "SlotValue",
          "required": ["SlotValue"],
          "additionalProperties": false,
          "properties": { "SlotValue": { "$ref": "#/$defs/SlotValueBody" } }
        },
        {
          "type": "object",
          "title": "Invalidate",
          "required": ["Invalidate"],
          "additionalProperties": false,
          "properties": { "Invalidate": { "$ref": "#/$defs/NodeBody" } }
        },
        {
          "type": "object",
          "title": "NodeAdd",
          "required": ["NodeAdd"],
          "additionalProperties": false,
          "properties": { "NodeAdd": { "$ref": "#/$defs/NodeAddBody" } }
        },
        {
          "type": "object",
          "title": "NodeRemove",
          "required": ["NodeRemove"],
          "additionalProperties": false,
          "properties": { "NodeRemove": { "$ref": "#/$defs/NodeBody" } }
        },
        {
          "type": "object",
          "title": "EdgeAdd",
          "required": ["EdgeAdd"],
          "additionalProperties": false,
          "properties": { "EdgeAdd": { "$ref": "#/$defs/EdgeBody" } }
        },
        {
          "type": "object",
          "title": "EdgeRemove",
          "required": ["EdgeRemove"],
          "additionalProperties": false,
          "properties": { "EdgeRemove": { "$ref": "#/$defs/EdgeBody" } }
        },
        {
          "type": "object",
          "title": "QueuePush",
          "description": "Op-log delta form for a QueueCell node: append `payload` to the tail. The op-log delta is the incremental counterpart to the storage-snapshot form (cell-model.md § Wire and snapshot shape); a run of same-direction QueuePush ops fuses into one multi-epoch batch Delta (protocol.md § Backpressure & outbox coalescing).",
          "required": ["QueuePush"],
          "additionalProperties": false,
          "properties": { "QueuePush": { "$ref": "#/$defs/CellSetBody" } }
        },
        {
          "type": "object",
          "title": "QueuePop",
          "description": "Op-log delta form for a QueueCell node: remove the head. Carries no value (the popped element is determined by ordered replay); a re-delivered pop is Ignored by the epoch gap rule. Crosses the wire only when consumption is authoritatively replicated (mirror sync); in the default producer→consumer sync the remote consumer's pops are local. A QueuePop/QueueClose is a fusion boundary (order-sensitive).",
          "required": ["QueuePop"],
          "additionalProperties": false,
          "properties": { "QueuePop": { "$ref": "#/$defs/NodeBody" } }
        },
        {
          "type": "object",
          "title": "QueueClose",
          "description": "Op-log delta form for a QueueCell node: mark closed (idempotent, terminal — Closed is distinct from Empty). A fusion boundary.",
          "required": ["QueueClose"],
          "additionalProperties": false,
          "properties": { "QueueClose": { "$ref": "#/$defs/NodeBody" } }
        }
      ]
    },
    "CellSetBody": {
      "type": "object",
      "required": ["node", "payload"],
      "additionalProperties": false,
      "properties": {
        "node": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" },
        "payload": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/IpcValue" }
      }
    },
    "SlotValueBody": {
      "type": "object",
      "required": ["node", "payload"],
      "additionalProperties": false,
      "properties": {
        "node": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" },
        "payload": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/IpcValue" }
      }
    },
    "NodeBody": {
      "type": "object",
      "required": ["node"],
      "additionalProperties": false,
      "properties": { "node": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" } }
    },
    "NodeAddBody": {
      "type": "object",
      "required": ["node", "type_tag", "state"],
      "additionalProperties": false,
      "properties": {
        "node": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" },
        "type_tag": { "type": "string" },
        "state": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeState" },
        "key": {
          "description": "Optional wire-stable keyed address. A conforming ENCODER omits it when absent; an explicit null is also wire-valid and a decoder MUST read both forms as absent (protocol.md § NodeKey, #lzkeynullstrict). This carried a bare NodeKey $ref until that audit, which made a frame the spec now requires decoders to accept schema-invalid.",
          "oneOf": [
            { "type": "null" },
            { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeKey" }
          ]
        }
      }
    },
    "EdgeBody": {
      "type": "object",
      "required": ["dependent", "dependency"],
      "additionalProperties": false,
      "properties": {
        "dependent": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" },
        "dependency": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" }
      }
    }
  }
}

ffi.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/ffi.json",
  "title": "FFI Types",
  "description": "C ABI types for the lazily FFI boundary",

  "$defs": {
    "LazilyFfiBytes": {
      "type": "object",
      "description": "Owned byte buffer crossing the FFI boundary",
      "properties": {
        "ptr": { "type": "integer", "minimum": 0, "description": "Pointer to byte buffer" },
        "len": { "type": "integer", "minimum": 0, "description": "Buffer length in bytes" }
      },
      "required": ["ptr", "len"],
      "additionalProperties": false
    },
    "LazilyFfiStatus": {
      "type": "integer",
      "enum": [0, 1, 2, 3, 4, 5],
      "description": "FFI operation status code",
      "oneOf": [
        { "const": 0, "title": "Ok" },
        { "const": 1, "title": "Empty" },
        { "const": 2, "title": "NullPointer" },
        { "const": 3, "title": "InvalidMessage" },
        { "const": 4, "title": "EncodeFailed" },
        { "const": 5, "title": "Panic" }
      ]
    },
    "LazilyFfiMessageKind": {
      "type": "integer",
      "enum": [0, 1, 2, 3, 4, 5],
      "description": "IPC message kind discriminator. 4/5 are the reliable-sync (#lzsync) reverse-channel control-frame variants ResyncRequest/OutboxAck (protocol.md § Reliable Sync).",
      "oneOf": [
        { "const": 0, "title": "Unknown" },
        { "const": 1, "title": "Snapshot" },
        { "const": 2, "title": "Delta" },
        { "const": 3, "title": "CrdtSync" },
        { "const": 4, "title": "ResyncRequest" },
        { "const": 5, "title": "OutboxAck" }
      ]
    }
  }
}

signaling.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/signaling.json",
  "title": "Signaling Protocol",
  "description": "WebSocket signaling frames for lazily peer discovery",
  "$comment": "Validates both client→server and server→client frames",

  "oneOf": [
    {
      "title": "ClientMessage",
      "oneOf": [
        {
          "type": "object",
          "title": "Join",
          "properties": {
            "type": { "const": "join" },
            "peer": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
            "capabilities": { "type": "array", "items": { "type": "string" } }
          },
          "required": ["type", "peer"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "Offer",
          "properties": {
            "type": { "const": "offer" },
            "to": { "type": "integer", "minimum": 0 },
            "sdp": { "type": "string" }
          },
          "required": ["type", "to", "sdp"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "Answer",
          "properties": {
            "type": { "const": "answer" },
            "to": { "type": "integer", "minimum": 0 },
            "sdp": { "type": "string" }
          },
          "required": ["type", "to", "sdp"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "Ice",
          "properties": {
            "type": { "const": "ice" },
            "to": { "type": "integer", "minimum": 0 },
            "candidate": { "type": "string" }
          },
          "required": ["type", "to", "candidate"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "Relay",
          "properties": {
            "type": { "const": "relay" },
            "to": { "type": "integer", "minimum": 0 },
            "payload": {}
          },
          "required": ["type", "to", "payload"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "Leave",
          "properties": {
            "type": { "const": "leave" }
          },
          "required": ["type"],
          "additionalProperties": false
        }
      ]
    },
    {
      "title": "ServerMessage",
      "oneOf": [
        {
          "type": "object",
          "title": "Welcome",
          "properties": {
            "type": { "const": "welcome" },
            "peer": { "type": "integer", "minimum": 0 },
            "peers": {
              "type": "array",
              "items": { "type": "integer", "minimum": 0 }
            }
          },
          "required": ["type", "peer", "peers"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "PeerJoined",
          "properties": {
            "type": { "const": "peer-joined" },
            "peer": { "type": "integer", "minimum": 0 }
          },
          "required": ["type", "peer"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "PeerLeft",
          "properties": {
            "type": { "const": "peer-left" },
            "peer": { "type": "integer", "minimum": 0 }
          },
          "required": ["type", "peer"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "ForwardedOffer",
          "properties": {
            "type": { "const": "offer" },
            "from": { "type": "integer", "minimum": 0 },
            "sdp": { "type": "string" }
          },
          "required": ["type", "from", "sdp"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "ForwardedAnswer",
          "properties": {
            "type": { "const": "answer" },
            "from": { "type": "integer", "minimum": 0 },
            "sdp": { "type": "string" }
          },
          "required": ["type", "from", "sdp"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "ForwardedIce",
          "properties": {
            "type": { "const": "ice" },
            "from": { "type": "integer", "minimum": 0 },
            "candidate": { "type": "string" }
          },
          "required": ["type", "from", "candidate"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "ForwardedRelay",
          "properties": {
            "type": { "const": "relay" },
            "from": { "type": "integer", "minimum": 0 },
            "payload": {}
          },
          "required": ["type", "from", "payload"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "Error",
          "properties": {
            "type": { "const": "error" },
            "code": { "type": "string" },
            "message": { "type": "string" }
          },
          "required": ["type", "code", "message"],
          "additionalProperties": false
        }
      ]
    }
  ]
}

distributed.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/distributed.json",
  "title": "Distributed (CRDT) Message",
  "description": "CRDT anti-entropy IPC message (protocol.md § Distributed). The CrdtSync message rides the same lazily-ipc transport as Snapshot/Delta as a third IpcMessage variant: the externally-tagged envelope {\"CrdtSync\": {...}}. Supporting distributed/cell-model types are kept under $defs.",
  "type": "object",
  "required": ["CrdtSync"],
  "additionalProperties": false,
  "properties": {
    "CrdtSync": {
      "type": "object",
      "description": "Anti-entropy sync frame: the sender advertises its per-peer stamp frontier and ships an op batch.",
      "required": ["ops"],
      "additionalProperties": false,
      "properties": {
        "frontier": {
          "type": "array",
          "items": { "$ref": "#/$defs/StampFrontierEntry" },
          "description": "Per-peer highest observed stamp. Retained in full (not permission-filtered) so the receiver can compute a sound causal-stability watermark. Optional under #lzspecfrontiersuppress: omit (or send []) when unchanged since the last accepted frame; the receiver reuses its last-merged frontier."
        },
        "ops": {
          "type": "array",
          "items": { "$ref": "#/$defs/CrdtOp" },
          "description": "Op batch this frame ships; permission-filtered by omission before serialization."
        }
      }
    }
  },
  "$defs": {
    "NodeId": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeId" },
    "PeerId": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/PeerId" },
    "NodeKey": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/NodeKey" },
    "WireStamp": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/WireStamp" },
    "IpcValue": { "$ref": "https://lazily.dev/schemas/defs.json#/$defs/IpcValue" },
    "OpKind": {
      "type": "string",
      "enum": ["read", "write", "trigger_effect"],
      "description": "Permission-gated operation kind. The three kinds are gated independently."
    },
    "RemoteOp": {
      "type": "object",
      "description": "Gated, serializable unit a peer requests.",
      "properties": {
        "kind": { "$ref": "#/$defs/OpKind" },
        "node": { "$ref": "#/$defs/NodeId" }
      },
      "required": ["kind", "node"],
      "additionalProperties": false
    },
    "MergeMechanism": {
      "type": "string",
      "enum": ["crdt", "lww", "ot", "lease", "custom"],
      "description": "Convergence mechanism for a multi-write cell. `crdt` is the first normative mechanism (converges without coordination); the rest are reserved extension points (see cell-model.md). Every mechanism MUST be deterministic. An implementation MUST reject an unimplemented mechanism explicitly rather than aliasing it to `crdt`."
    },
    "CellKind": {
      "description": "Static classification of a cell by concurrent-writer count. Single-writer cells take no merge; multi-write cells carry a pluggable merge mechanism. Multi-write is NOT a hardcoded `crdt` kind — see cell-model.md.",
      "oneOf": [
        {
          "type": "object",
          "properties": { "kind": { "const": "single_writer" } },
          "required": ["kind"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "kind": { "const": "multi_write" },
            "merge": { "$ref": "#/$defs/MergeMechanism" }
          },
          "required": ["kind", "merge"],
          "additionalProperties": false
        }
      ]
    },
    "CellRegisterType": {
      "type": "string",
      "enum": ["lww", "mv", "pn-counter"],
      "description": "CRDT register type for a `merge: crdt` cell (the value shape within the CRDT mechanism); distinct from MergeMechanism."
    },
    "StampFrontierEntry": {
      "type": "array",
      "description": "A (peer, WireStamp) tuple in the per-peer stamp frontier.",
      "prefixItems": [
        { "$ref": "#/$defs/PeerId" },
        { "$ref": "#/$defs/WireStamp" }
      ],
      "minItems": 2,
      "maxItems": 2,
      "items": false
    },
    "CrdtOp": {
      "type": "object",
      "description": "One CRDT cell op on the wire (state-based / CvRDT): the converged register/sequence/text state for `node`, tagged with the WireStamp that produced it and an optional wire-stable NodeKey. State-based, idempotent — safe to resend.",
      "required": ["node", "key", "stamp", "state"],
      "additionalProperties": false,
      "properties": {
        "node": { "$ref": "#/$defs/NodeId", "description": "Volatile target id; pair with `key` for stable addressing." },
        "key": {
          "description": "Wire-stable keyed address, or null when unset. Mirrors the lazily-rs derived struct: `key` is always present (null when unset), unlike NodeSnapshot/NodeAdd which omit it.",
          "oneOf": [
            { "type": "null" },
            { "$ref": "#/$defs/NodeKey" }
          ]
        },
        "stamp": { "$ref": "#/$defs/WireStamp" },
        "state": { "$ref": "#/$defs/IpcValue", "description": "The converged CRDT state to merge." }
      }
    }
  }
}

receipts.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/receipts.json",
  "title": "Causal Receipts",
  "description": "Generic receipt/outcome projection for causally-linked commands or effect requests. This is not a transport ACK plane; observed/accepted are non-terminal, applied/rejected are terminal.",
  "type": "object",
  "required": ["CausalReceipts"],
  "additionalProperties": false,
  "properties": {
    "CausalReceipts": {
      "type": "object",
      "required": ["receipts"],
      "additionalProperties": false,
      "properties": {
        "receipts": {
          "type": "array",
          "items": { "$ref": "#/$defs/CausalReceipt" }
        }
      }
    }
  },
  "$defs": {
    "ReceiptOutcome": {
      "type": "string",
      "enum": ["observed", "accepted", "applied", "rejected"],
      "description": "Outcome vocabulary. observed/accepted are non-terminal; applied/rejected are terminal."
    },
    "OptionalString": {
      "oneOf": [
        { "type": "null" },
        { "type": "string" }
      ]
    },
    "CausalReceipt": {
      "type": "object",
      "required": [
        "receipt_id",
        "causation_id",
        "observer",
        "generation",
        "outcome",
        "reason",
        "payload_hash"
      ],
      "additionalProperties": false,
      "properties": {
        "receipt_id": {
          "type": "string",
          "minLength": 1,
          "description": "Idempotency key for this receipt event."
        },
        "causation_id": {
          "type": "string",
          "minLength": 1,
          "description": "Stable id of the command, event, or effect request this receipt observes."
        },
        "observer": {
          "type": "string",
          "minLength": 1,
          "description": "Peer, process, or subsystem that produced the receipt."
        },
        "generation": {
          "type": "integer",
          "minimum": 0,
          "description": "Producer/editor generation. Consumers discard receipts outside the current generation for the causation id."
        },
        "outcome": { "$ref": "#/$defs/ReceiptOutcome" },
        "reason": { "$ref": "#/$defs/OptionalString" },
        "payload_hash": { "$ref": "#/$defs/OptionalString" }
      }
    }
  }
}

message-passing.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/message-passing.json",
  "title": "Command / RPC Message Plane",
  "description": "Evented command message plane (command-plane-v1). CommandSubmit/CommandCancel/CommandEvents/CommandProjection are an additive sibling family to Snapshot/Delta/CrdtSync. RPC is a facade over this plane; transport ACKs and non-terminal events are NOT authority. Terminal command outcomes fold through CausalReceipt (receipts.json).",
  "oneOf": [
    { "$ref": "#/$defs/CommandSubmitFrame" },
    { "$ref": "#/$defs/CommandCancelFrame" },
    { "$ref": "#/$defs/CommandEventsFrame" },
    { "$ref": "#/$defs/CommandProjectionFrame" }
  ],
  "$defs": {
    "CommandId": {
      "type": "string",
      "minLength": 1,
      "description": "Stable, replay-safe id for a command. Dedupe and reconnect projection key off this id."
    },
    "OptionalString": {
      "oneOf": [{ "type": "null" }, { "type": "string" }]
    },
    "DedupePolicy": {
      "type": "string",
      "enum": ["none", "same_idempotency_key", "same_command_id"],
      "description": "How the admitter collapses concurrent/duplicate submits."
    },
    "CommandPolicy": {
      "type": "object",
      "required": ["dedupe", "supersede", "cancel_on_preempt"],
      "additionalProperties": false,
      "properties": {
        "dedupe": { "$ref": "#/$defs/DedupePolicy" },
        "supersede": {
          "type": "boolean",
          "description": "If true, a newer submit with the same idempotency key supersedes an older non-terminal command."
        },
        "cancel_on_preempt": {
          "type": "boolean",
          "description": "If true, the admitter may cancel a still-non-terminal command when it is preempted."
        }
      }
    },
    "CommandSubmit": {
      "type": "object",
      "required": [
        "command_id",
        "causation_id",
        "source",
        "target",
        "namespace",
        "name",
        "authority_generation",
        "idempotency_key",
        "deadline_ms",
        "policy",
        "payload_type",
        "payload_hash",
        "payload",
        "required_features"
      ],
      "additionalProperties": false,
      "properties": {
        "command_id": { "$ref": "#/$defs/CommandId" },
        "causation_id": {
          "type": "string",
          "minLength": 1,
          "description": "Causal parent id (a command id or event id). Self-caused submits set this equal to command_id."
        },
        "source": {
          "type": "string",
          "minLength": 1,
          "description": "Identity of the submitter (e.g. 'vscode-plugin', 'jetbrains-plugin')."
        },
        "target": {
          "type": "string",
          "minLength": 1,
          "description": "Identity of the intended handler (e.g. 'project-controller')."
        },
        "namespace": {
          "type": "string",
          "minLength": 1,
          "description": "Domain namespace that owns the payload schema (e.g. 'agent-doc'). Lazily owns the envelope, not the namespace."
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "description": "Command name within the namespace (e.g. 'editor_route')."
        },
        "authority_generation": {
          "type": "integer",
          "minimum": 0,
          "description": "Authority/controller generation. Receipts and events outside this generation are stale and never update the projection."
        },
        "idempotency_key": {
          "type": "string",
          "minLength": 1,
          "description": "Dedupe/supersede key (e.g. 'project-root:doc:run')."
        },
        "deadline_ms": {
          "type": "integer",
          "minimum": 0,
          "description": "Deadline in milliseconds. 0 means no deadline."
        },
        "policy": { "$ref": "#/$defs/CommandPolicy" },
        "payload_type": {
          "type": "string",
          "minLength": 1,
          "description": "Fully-qualified domain payload type (e.g. 'agent-doc.editor_route.v1')."
        },
        "payload_hash": {
          "type": "string",
          "minLength": 1,
          "description": "Content hash of the payload body (e.g. 'sha256:...')."
        },
        "payload": {
          "$ref": "https://lazily.dev/schemas/defs.json#/$defs/IpcValue",
          "description": "Domain payload as inline bytes or shared-memory blob reference. Lazily does not interpret the body."
        },
        "required_features": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Features the target must advertise or the submit fails closed."
        }
      }
    },
    "CommandCancel": {
      "type": "object",
      "required": [
        "command_id",
        "causation_id",
        "source",
        "authority_generation",
        "reason"
      ],
      "additionalProperties": false,
      "properties": {
        "command_id": { "$ref": "#/$defs/CommandId" },
        "causation_id": {
          "type": "string",
          "minLength": 1,
          "description": "Id of the cancel request itself (for its own receipt/replay)."
        },
        "source": { "type": "string", "minLength": 1 },
        "authority_generation": {
          "type": "integer",
          "minimum": 0,
          "description": "Generation the cancel targets. A stale-generation cancel is ignored."
        },
        "reason": { "$ref": "#/$defs/OptionalString" }
      }
    },
    "CommandEventKind": {
      "type": "string",
      "enum": [
        "observed",
        "accepted",
        "started",
        "progress",
        "cancelled",
        "superseded",
        "timed_out"
      ],
      "description": "Progress/detail kinds. These are UX/diagnostics only and are NEVER terminal proof; terminal proof folds through CausalReceipt. cancelled/superseded/timed_out are surfaced here for UX but their terminal authority is a matching rejected receipt."
    },
    "CommandEvent": {
      "type": "object",
      "required": ["event_id", "command_id", "kind", "generation", "detail"],
      "additionalProperties": false,
      "properties": {
        "event_id": {
          "type": "string",
          "minLength": 1,
          "description": "Idempotency key for this event. Duplicate event_ids are no-ops."
        },
        "command_id": { "$ref": "#/$defs/CommandId" },
        "kind": { "$ref": "#/$defs/CommandEventKind" },
        "generation": {
          "type": "integer",
          "minimum": 0,
          "description": "Authority generation. Events outside the current generation for the command are ignored."
        },
        "detail": {
          "$ref": "#/$defs/OptionalString",
          "description": "Optional human/diagnostics detail (queue position, retry advice, copied CLI output). Not proof of effect."
        }
      }
    },
    "CommandEventsFrame": {
      "type": "object",
      "required": ["CommandEvents"],
      "additionalProperties": false,
      "properties": {
        "CommandEvents": {
          "type": "object",
          "required": ["events"],
          "additionalProperties": false,
          "properties": {
            "events": {
              "type": "array",
              "items": { "$ref": "#/$defs/CommandEvent" }
            }
          }
        }
      }
    },
    "CommandStatus": {
      "type": "string",
      "enum": [
        "submitted",
        "accepted",
        "running",
        "applied",
        "rejected",
        "cancelled",
        "superseded",
        "timed_out"
      ],
      "description": "Folded projection status. submitted/accepted/running are non-terminal; applied/rejected/cancelled/superseded/timed_out are terminal and backed by a terminal CausalReceipt."
    },
    "CommandProjectionEntry": {
      "type": "object",
      "required": [
        "command_id",
        "status",
        "terminal",
        "generation",
        "reason",
        "terminal_receipt_id",
        "last_event_id"
      ],
      "additionalProperties": false,
      "properties": {
        "command_id": { "$ref": "#/$defs/CommandId" },
        "status": { "$ref": "#/$defs/CommandStatus" },
        "terminal": {
          "type": "boolean",
          "description": "True iff a terminal CausalReceipt has folded into this command. accepted/queued/admission never sets terminal."
        },
        "generation": {
          "type": "integer",
          "minimum": 0,
          "description": "Current authority generation for the command."
        },
        "reason": {
          "$ref": "#/$defs/OptionalString",
          "description": "Terminal reason (rejection cause, cancel reason, timeout); null while non-terminal or applied without reason."
        },
        "terminal_receipt_id": {
          "$ref": "#/$defs/OptionalString",
          "description": "Receipt id that made the command terminal, or null when non-terminal."
        },
        "last_event_id": {
          "$ref": "#/$defs/OptionalString",
          "description": "Last folded event id for incremental resync, or null when none."
        }
      }
    },
    "CommandProjectionFrame": {
      "type": "object",
      "required": ["CommandProjection"],
      "additionalProperties": false,
      "properties": {
        "CommandProjection": {
          "type": "object",
          "required": ["generation", "commands"],
          "additionalProperties": false,
          "properties": {
            "generation": {
              "type": "integer",
              "minimum": 0,
              "description": "Authority generation this projection image was taken at."
            },
            "commands": {
              "type": "array",
              "items": { "$ref": "#/$defs/CommandProjectionEntry" }
            }
          }
        }
      }
    },
    "CommandSubmitFrame": {
      "type": "object",
      "required": ["CommandSubmit"],
      "additionalProperties": false,
      "properties": { "CommandSubmit": { "$ref": "#/$defs/CommandSubmit" } }
    },
    "CommandCancelFrame": {
      "type": "object",
      "required": ["CommandCancel"],
      "additionalProperties": false,
      "properties": { "CommandCancel": { "$ref": "#/$defs/CommandCancel" } }
    }
  }
}

statechart.json

This is a compute schema, not a wire message. It normatively defines the declarative Harel/SCXML chart form used by conformance fixtures and cross-language chart definitions. A chart is never serialized as a distinct wire kind; only its converged active configuration crosses IPC/FFI as an ordinary cell Payload. See State Charts.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/statechart.json",
  "title": "StateChart",
  "description": "Declarative form of a lazily state chart (Harel/SCXML subset). This is COMPUTE, not a wire message: a chart is never serialized over IPC/FFI as a distinct type — only its converged active configuration crosses the wire as an ordinary cell Payload. This schema fixes the cross-language declarative form used by conformance fixtures and chart definitions.",
  "type": "object",
  "required": ["initial", "states"],
  "additionalProperties": false,
  "properties": {
    "initial": {
      "description": "Default entry state of the root region. MUST resolve to a leaf by descending compound `initial`s (or, for a parallel root, to one leaf per region).",
      "type": "string"
    },
    "context": {
      "description": "Optional extended-state schema: host-resolved caller state over which guard expressions evaluate. Never serialized as part of the active configuration.",
      "type": "object"
    },
    "states": {
      "type": "object",
      "minProperties": 1,
      "additionalProperties": {"$ref": "#/$defs/State"}
    }
  },
  "$defs": {
    "State": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "parent": {
          "description": "Parent state id. Exactly one state (the root) has no parent.",
          "type": "string"
        },
        "kind": {
        "description": "Authoritative structural kind. If present, it MUST agree with the state's structural fields and child relation; contradictory declarations are malformed. If omitted, it is inferred: `history` when `history` is set; `parallel` when `parallel` is true; `compound` when the state has children; otherwise `atomic`. `final` cannot be inferred.",
          "enum": ["atomic", "compound", "parallel", "history", "final"]
        },
        "parallel": {
          "description": "If true, this state is an AND-state: its children are concurrent regions, all of which are active whenever this state is active. Mutually exclusive with `initial`.",
          "type": "boolean"
        },
        "initial": {
          "description": "Default child entered when this compound state is entered. Required for compound states; forbidden for parallel states.",
          "type": "string"
        },
        "history": {
          "description": "Marks this state as a history pseudo-state. `shallow` records/restores the direct children of the parent region; `deep` records/restores the full active leaf configuration. Resolve to `default` on first entry (no recorded history).",
          "enum": ["shallow", "deep"]
        },
        "default": {
          "description": "Default target for a history state when no configuration has been recorded for its region yet.",
          "type": "string"
        },
        "on": {
          "description": "Event → transition table. An event maps to a target id or a transition object. Transitions on compound/parallel states are reachable from any active descendant (event bubbling).",
          "type": "object",
          "additionalProperties": {"$ref": "#/$defs/Transition"}
        },
        "entry": {
          "description": "Ordered actions fired when this state is entered, after its ancestors' entry actions.",
          "type": "array",
          "items": {"$ref": "#/$defs/Action"}
        },
        "exit": {
          "description": "Ordered actions fired when this state is exited, before its ancestors' exit actions.",
          "type": "array",
          "items": {"$ref": "#/$defs/Action"}
        },
        "run": {
          "description": "Ongoing (do) actions started on entry and cancelled on exit. Host-managed; not part of conformance replay.",
          "type": "array",
          "items": {"$ref": "#/$defs/Action"}
        }
      },
      "allOf": [
        {
          "if": {"required": ["parallel"], "properties": {"parallel": {"const": true}}},
          "then": {"not": {"required": ["initial"]}}
        },
        {
          "if": {"required": ["history"]},
          "then": {"not": {"anyOf": [{"required": ["initial"]}, {"required": ["parallel"]}]}}
        }
      ]
    },
    "Transition": {
      "description": "A transition. A bare string is shorthand for `{\"target\": <string>}`.",
      "oneOf": [
        {"type": "string"},
        {
          "type": "object",
          "required": ["target"],
          "additionalProperties": false,
          "properties": {
            "target": {
              "description": "Target state id. MAY be compound or parallel; entry descends via `initial` (compound) or enters every region (parallel). MAY target a history state to resume its parent region.",
              "type": "string"
            },
            "guard": {"$ref": "#/$defs/Guard"},
            "action": {
              "description": "Ordered actions fired after the exit set and before the enter set.",
              "type": "array",
              "items": {"$ref": "#/$defs/Action"}
            },
            "internal": {
              "description": "If true, an internal transition: the source state is not exited/re-entered even when the target is the source or a descendant. Defaults to false (external).",
              "type": "boolean"
            }
          }
        }
      ]
    },
    "Guard": {
      "description": "A guard predicate. A bare string is a named guard resolved by the caller's guard resolver (fail-closed if absent). An object is an extended-state expression the host evaluates against `context`.",
      "oneOf": [
        {"type": "string"},
        {
          "type": "object",
          "required": ["expr"],
          "additionalProperties": false,
          "properties": {
            "expr": {"type": "string"}
          }
        }
      ]
    },
    "Action": {
      "description": "An action. A bare string is a named action resolved by the caller's action handler. An object carries an action name plus an opaque payload.",
      "oneOf": [
        {"type": "string"},
        {
          "type": "object",
          "required": ["name"],
          "additionalProperties": false,
          "properties": {
            "name": {"type": "string"},
            "payload": {}
          }
        }
      ]
    }
  }
}

stdlib-fixture.schema.json

This compute schema validates the portable standard-library fixture corpus. It is not a wire message. See Portable Standard Library.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lazily.dev/schemas/stdlib-fixture.schema.json",
  "title": "Portable Lazily stdlib conformance fixture",
  "type": "object",
  "required": [
    "fixture_version",
    "feature",
    "scenario_floor",
    "assertion_floor",
    "mutation_floor",
    "scenarios",
    "mutations"
  ],
  "properties": {
    "$schema": {
      "type": "string",
      "const": "https://lazily.dev/schemas/stdlib-fixture.schema.json"
    },
    "fixture_version": {
      "const": 1
    },
    "feature": {
      "enum": [
        "stdlib_timer_v1",
        "stdlib_timeout_v1",
        "stdlib_revision_barrier_v1"
      ]
    },
    "scenario_floor": {
      "type": "integer",
      "minimum": 1
    },
    "assertion_floor": {
      "type": "integer",
      "minimum": 1
    },
    "mutation_floor": {
      "type": "integer",
      "minimum": 1
    },
    "scenarios": {
      "type": "array",
      "minItems": 1
    },
    "mutations": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/mutation"
      }
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "feature": {
            "const": "stdlib_timer_v1"
          }
        }
      },
      "then": {
        "properties": {
          "scenarios": {
            "items": {
              "$ref": "#/$defs/timerScenario"
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "feature": {
            "const": "stdlib_timeout_v1"
          }
        }
      },
      "then": {
        "properties": {
          "scenarios": {
            "items": {
              "$ref": "#/$defs/timeoutScenario"
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "feature": {
            "const": "stdlib_revision_barrier_v1"
          }
        }
      },
      "then": {
        "properties": {
          "scenarios": {
            "items": {
              "$ref": "#/$defs/barrierScenario"
            }
          }
        }
      }
    }
  ],
  "additionalProperties": false,
  "$defs": {
    "u64": {
      "type": "integer",
      "minimum": 0,
      "maximum": 18446744073709551615
    },
    "nullableU64": {
      "oneOf": [
        {
          "$ref": "#/$defs/u64"
        },
        {
          "type": "null"
        }
      ]
    },
    "expect": {
      "type": "object",
      "required": [
        "outcome"
      ],
      "properties": {
        "outcome": {
          "enum": [
            "pending",
            "fired",
            "completed",
            "timed_out",
            "cancelled",
            "unavailable",
            "satisfied",
            "disposed"
          ]
        },
        "deadline": {
          "$ref": "#/$defs/nullableU64"
        },
        "fired_at": {
          "$ref": "#/$defs/nullableU64"
        },
        "value": {
          "type": [
            "string",
            "null"
          ]
        },
        "reason": {
          "type": [
            "string",
            "null"
          ]
        },
        "revision": {
          "$ref": "#/$defs/nullableU64"
        },
        "generation": {
          "$ref": "#/$defs/nullableU64"
        },
        "operation_calls": {
          "type": "integer",
          "minimum": 0,
          "maximum": 1
        },
        "cancellation_calls": {
          "type": "integer",
          "minimum": 0,
          "maximum": 1
        }
      },
      "additionalProperties": false
    },
    "mutation": {
      "type": "object",
      "required": [
        "operator",
        "must_fail"
      ],
      "properties": {
        "operator": {
          "type": "string",
          "minLength": 1
        },
        "must_fail": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "minLength": 1
          }
        }
      },
      "additionalProperties": false
    },
    "timerScenario": {
      "type": "object",
      "required": [
        "id",
        "steps"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "steps": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/timerStep"
          }
        }
      },
      "additionalProperties": false
    },
    "timerStep": {
      "oneOf": [
        {
          "type": "object",
          "required": [
            "op",
            "now",
            "duration",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "start"
            },
            "now": {
              "$ref": "#/$defs/u64"
            },
            "duration": {
              "$ref": "#/$defs/u64"
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "op",
            "now",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "observe"
            },
            "now": {
              "$ref": "#/$defs/u64"
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        }
      ]
    },
    "timeoutScenario": {
      "type": "object",
      "required": [
        "id",
        "steps"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "steps": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/timeoutStep"
          }
        }
      },
      "additionalProperties": false
    },
    "timeoutStep": {
      "oneOf": [
        {
          "type": "object",
          "required": [
            "op",
            "now",
            "duration",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "start"
            },
            "now": {
              "$ref": "#/$defs/u64"
            },
            "duration": {
              "$ref": "#/$defs/u64"
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "op",
            "now",
            "operation",
            "cancellation",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "poll"
            },
            "now": {
              "$ref": "#/$defs/u64"
            },
            "operation": {
              "enum": [
                "pending",
                "completed",
                "unavailable"
              ]
            },
            "value": {
              "type": "string"
            },
            "cancellation": {
              "enum": [
                "pending",
                "cancelled",
                "unavailable"
              ]
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        }
      ]
    },
    "barrierScenario": {
      "type": "object",
      "required": [
        "id",
        "steps"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "steps": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/barrierStep"
          }
        }
      },
      "additionalProperties": false
    },
    "barrierStep": {
      "oneOf": [
        {
          "type": "object",
          "required": [
            "op",
            "revision",
            "required_revision",
            "deadline",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "start"
            },
            "revision": {
              "$ref": "#/$defs/u64"
            },
            "required_revision": {
              "$ref": "#/$defs/u64"
            },
            "deadline": {
              "$ref": "#/$defs/nullableU64"
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "op",
            "now",
            "predicate",
            "cancellation",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "observe"
            },
            "now": {
              "$ref": "#/$defs/u64"
            },
            "predicate": {
              "type": "boolean"
            },
            "cancellation": {
              "enum": [
                "pending",
                "cancelled",
                "unavailable"
              ]
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "op",
            "now",
            "observed_revision",
            "predicate",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "register_recheck"
            },
            "now": {
              "$ref": "#/$defs/u64"
            },
            "observed_revision": {
              "$ref": "#/$defs/u64"
            },
            "predicate": {
              "type": "boolean"
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "op",
            "revision",
            "predicate",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "advance"
            },
            "revision": {
              "$ref": "#/$defs/u64"
            },
            "predicate": {
              "type": "boolean"
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "op",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "dispose"
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "op",
            "key",
            "expect"
          ],
          "properties": {
            "op": {
              "const": "receipt"
            },
            "key": {
              "type": "string",
              "minLength": 1
            },
            "expect": {
              "$ref": "#/$defs/expect"
            }
          },
          "additionalProperties": false
        }
      ]
    }
  }
}