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 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 | NonEmptySpanList | NonEmptyLineList
}
The fragment shape follows the target Block’s current content type: text for
text/plain, a span list for text/styled (Styled Text Content),
a line list for text/lines (Line Layout Text Content).
Extend does not carry or change the Content Type, and a fragment whose shape
does not match the Block’s current content type is a semantic
invalid_content failure. 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 content that may be empty:
block.replace_suffix body {
block_id: BlockId
base_operation_id: OperationId
retain: ScalarCount
replacement: Text | SpanList | LineList
}
retain counts Unicode scalar values from the beginning of the current
logical text. The replacement shape follows the target Block’s current content
type: text for text/plain, a span list for text/styled (Styled Text
Content), a line list for text/lines (Line Layout Text
Content). 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.
The first optional content type, text/styled, is mapped in Styled Text
Content, and text/lines in Line Layout Text
Content.