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.
| Schema | Layer |
|---|---|
defs.json | Shared wire primitives (NodeId, NodeKey, NodeState, IpcValue, ShmBlobRef, WireStamp) |
snapshot.json | IPC — Snapshot message (externally-tagged {"Snapshot": …} envelope) |
delta.json | IPC — Delta message (externally-tagged {"Delta": …}, all 7 DeltaOp variants) |
ffi.json | Cross-language FFI boundary |
signaling.json | Signaling (WebSocket) |
distributed.json | Distributed — CrdtSync message ({"CrdtSync": …}) + CRDT/cell-model types |
receipts.json | Causal receipts ({"CausalReceipts": …}) + terminal outcome projection |
message-passing.json | Command / RPC message plane (CommandSubmit / CommandCancel / CommandEvents / CommandProjection) |
statechart.json | Compute (Harel/SCXML chart form — not a wire message) |
stdlib-fixture.schema.json | Deterministic Timer, Timeout, and RevisionBarrier conformance scenarios |
assertion-blocks.json | Routed, 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
}
]
}
}
}