Concrete Message Schemas¶
Field |
Value |
|---|---|
Status |
Draft |
Related RFC |
|
Related drafts |
Logical wire message model, JSON serialization, Error codes, Operations, Capabilities, Protocol Contexts, Content representation |
This document maps each message kind in the logical wire model to a concrete logical body schema. It defines fields and their conditions independently of the selected JSON serialization, OSC carrier, and framing mechanism.
2. Envelope Field Matrix¶
version, kind, and body are required on every Message. The remaining
envelope fields are permitted only as follows:
Message kind |
|
|
|
|---|---|---|---|
|
required |
absent |
absent |
|
required |
absent |
absent |
|
required |
absent |
absent |
|
required |
absent |
success only |
|
required |
absent |
required |
|
required |
absent |
required |
|
absent |
required |
required |
|
absent |
required |
required |
|
absent |
required |
required |
|
absent |
required |
required |
|
absent |
required |
required |
|
absent |
required |
required |
An envelope field appearing where this table marks it absent makes the whole
Message invalid. For context.open.response, context_id is required for an
opened outcome and absent for an error outcome.
A correlated control response uses the same protocol version as its request.
A protocol.error uses the same protocol version as its rejected Operation.
3. Capability Messages¶
The queried protocol version is the envelope’s version, so the query body
is empty:
capability.query body {}
The response echoes the request ID and uses exactly one of these bodies:
capability.response body =
| {
outcome: supported
optional_content_types: ContentType[]
}
| {
outcome: unsupported
}
| {
outcome: error
error: ControlFailure
}
supported confirms the complete baseline for the envelope’s version. Its
list contains only optional content types and may be empty; baseline
text/plain support is implied and is not listed. unsupported is the normal
negative negotiation result. error reports a reliably correlated request
failure and does not establish protocol support.
4. Context Messages¶
Opening a Context requires no parameters beyond the common envelope:
context.open body {}
context.open.response body =
| {
outcome: opened
}
| {
outcome: error
error: ControlFailure
}
An opened response carries the newly allocated context_id in its envelope.
An error response carries no Context ID and creates no Context.
Context closure addresses the Context through the envelope, so its request body is also empty:
context.close body {}
context.close.response body =
| {
outcome: closed
}
| {
outcome: error
error: ControlFailure
}
Both closure messages carry the addressed context_id. A closed outcome
means the ordered closure boundary has completed. An error outcome leaves
an open Context unchanged.
5. Block Operation Messages¶
Append carries everything needed to create one complete Block:
block.append body {
block_id: BlockId
lifecycle: mutable | sealed
content: ContentSnapshot
}
Update replaces the complete content value while retaining Block identity, lifecycle, and append position:
block.update body {
block_id: BlockId
content: ContentSnapshot
}
Extend adds a non-empty text/plain fragment to the current logical tail and
names the exact content state on which it depends:
block.extend body {
block_id: BlockId
base_operation_id: OperationId
fragment: NonEmptyText
}
The target Block must already use text/plain; Extend does not carry or change
its Content Type. An empty fragment violates this body schema. A valid base
field whose value does not equal the Block’s current content-state Operation
ID is a semantic content_state_mismatch, not a structural failure.
ReplaceSuffix removes a non-empty suffix and replaces it with text that may be empty:
block.replace_suffix body {
block_id: BlockId
base_operation_id: OperationId
retain: ScalarCount
replacement: Text
}
retain counts Unicode scalar values from the beginning of the current
text/plain content. The target Block must already use text/plain;
ReplaceSuffix does not carry or change its Content Type. The body is
structurally valid when retain is a ScalarCount; semantic evaluation
additionally requires it to be less than the current scalar-value length.
Otherwise, the Operation reports invalid_content_boundary.
Seal changes only the lifecycle of its target:
block.seal body {
block_id: BlockId
}
The Context ID and Operation ID belong to the common envelope rather than these bodies. Successful Operations have no response.
6. Protocol Error Message¶
A rejected, reliably identified Block Operation produces:
protocol.error body {
code: OperationErrorCode
message?: DiagnosticText
}
The error echoes the rejected Operation’s context_id and operation_id in
its envelope. Block identity is not repeated generically: when relevant, its
value can appear in the human diagnostic, while machine behavior is selected
by the stable error code and correlated Operation identity.
7. Validation¶
The receiver first validates the common envelope and then the body schema
selected by version and kind. Tagged response alternatives are exclusive:
fields belonging to another outcome are unknown fields and invalidate the
complete Message.
Schema validity does not imply semantic validity. For example, a structurally
valid block.update can still fail because its Block is unknown or sealed,
and a structurally valid block.extend or block.replace_suffix can name a
stale content state.
Structural and semantic failures apply no requested Context or Block change.
Correlation bookkeeping and error reporting follow the
logical wire model, including
non-reuse of a reliably identified failed Operation’s ID.
Baseline text/plain uses the Text schema above. Its display and native-text
processing are defined in Plain Text Content; the schema does
not normalize its data or reject the controls represented by visible labels.