Network Working Group Christopher Ross Internet-Draft Independent Intended status: Experimental 11 September 2026 Expires: 11 March 2027 Mercurius Window System (MWS) draft-ross-mercurius-06 Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This document is an individual submission to the IETF. Distribution of this document is unlimited. This Internet-Draft will expire on 11 March 2027. The latest version of this draft can be found at: https://mercurius.tebibyte.org/draft-ross-mercurius.txt Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Abstract The Mercurius Window System (MWS) is a zero-trust, network-native window system for contemporary desktops. It combines persistent, detachable graphical Sessions with network transparency. MWS works on a workstation without requiring network connectivity. The same Session model allows users to start a new Session or resume a detached Session, either at the workstation itself or from another device across the network. MWS complements local display systems such as Wayland. Applications and their state remain on the workstation, while a Portal provides the user's display and input facilities. Modern graphics APIs and authenticated transport support this separation between where applications execute and where a user interacts with them. This document specifies the Session, Window, and communication behaviour needed for independent implementations to interoperate. Executive Summary (Non-Normative) Mercurius is a zero-trust network-native window system intended to bring network transparency to contemporary graphical desktops, while making persistent Sessions useful on a single machine. A Session is a collection of applications, Windows, and working state maintained by a workstation. A user can explicitly detach from it and later return to the same applications and Windows without starting them again, subject to the workstation's policy. Zero-trust means that neither a device's location nor possession of that device establishes authority to access the workstation. Users authenticate before attaching to a Session, and the workstation validates requests against that Session's permissions and resources. These rules apply equally at the local console and across the network. For example, a user may keep separate Sessions for development and other tasks, detach from one, and resume another. This works at the workstation's own console without any network connection. Connecting from another device extends the same arrangement: the Session remains on its workstation, and the user can resume it from wherever a suitable Portal is available. Network transparency means that local and network access share the same Session behaviour. A Portal is the software and local facilities through which the user sees Windows, hears audio, and supplies input. It may run on the workstation itself or on another computer. Applications execute and render on the workstation; the Portal presents their output and returns the user's input. Changing Portals changes the place from which the user accesses a Session, while its applications and working state remain on the original workstation. Mercurius complements Wayland and other local display systems. A Portal can use Wayland to display application Windows alongside other Windows on the local desktop and to receive keyboard and pointer input. Mercurius supplies the Session continuity and workstation access, while the local display system handles presentation and interaction at the user's device. Network use is a capability of this window system; its Session model also applies when everything runs locally. Detachment explicitly requests preservation of a Session; an unexpected disconnection instead starts a bounded reconnection grace period. The remainder of this document defines the communication and state-management rules that implement this model. Table of Contents 1. Introduction 1.1. Scope and Applicability 1.2. Design Rationale 1.3. Cloud and Distributed Computing Context 1.4. High-Performance Rendering and Gaming 1.5. Portal Requirements and Wireless Considerations 1.6. Session Mobility and Detachable Operation 2. Conventions Used in This Document 2.1. Requirements Language 2.2. Referenced Terminology 2.3. General Terminology 2.4. Protocol Roles 2.5. Additional Terms and Threat-Model Names 2.6. Wire-Format Conventions 3. System Architecture 3.1. Architectural Principles 3.2. Protocol Endpoints 3.3. Workstation-Centric Model 3.4. Rendering and Surface Model 3.5. Session Model 3.6. Zero-Trust Portal Model 3.7. Network Considerations 3.8. Transport Requirements 4. Detailed Architecture 4.1. Sessions 4.2. Seats 4.3. Windows 4.4. Server Window Management 4.5. Rendering Model 4.6. Audio Model 4.7. Stream Allocation 4.7.1. Session Identity and Message Routing 4.8. Session Lifecycle 4.9. Session and Seat Model 4.10. Local Transport Profile (Non-Normative) 4.11. Security Model 5. Protocol Specification 5.1. Message Framing 5.1.1. Transport Fragmentation 5.2. Control Messages (Stream 0) 5.2.1. Initial Handshake (001-099) 5.2.1.1. Session Identifier Semantics 5.2.2. Session Management (100-199) 5.2.2.1. Resume Semantics 5.2.3. Window Lifecycle (200-299) 5.2.3.1. Window Identifier Scope 5.3. Rendering Messages (300-399) 5.4. Input Plane (400-499) -- Stream 2 5.4.1. Pointer Motion Events 5.4.2. Keyboard Events 5.4.3. Text Input Events 5.5. Video Fallback (500-599) -- Stream 3 5.6. Audio Plane (600-699) -- Stream 4 5.6.1. Session Media Timeline 5.7. Protocol State Machine 5.7.1. Initial Connection 5.7.2. Session Resume 5.8. WSI Extension (Surface Creation) 5.8.1. Surface Binding and Session Validation 5.8.2. Vulkan Extension Registration 5.9. Error Handling (700-799) 5.9.1. Session and Resource Validation Errors 6. Implementation Guidance 6.1. Endpoint Independence 6.2. Portal Processing Model 6.3. Concurrency and Backpressure 6.4. Version Scope 6.5. Reference Implementation Components 6.6. Usage Examples 6.6.1. SSH and MWS 6.6.2. Session Selection 6.6.3. Detach and Resume 6.6.4. Local and Remote Portals 6.6.5. Independent Portals 7. Implementation Requirements and Validation 7.1. Test Matrix 7.1.1. Core Validation Tests 7.2. GPU Isolation Requirements 7.3. Bandwidth and Transport Isolation Requirements 8. Performance Considerations 9. Security Considerations 9.1. DANE Deployment (Non-Normative) 10. IANA Considerations 11. Acknowledgements 12. References 12.1. Normative References 12.2. Informative References Appendix A. MWS Opcode Registry A.1. Handshake and Authentication (000-099) A.2. Session Management (100-199) A.3. Window Lifecycle (200-299) A.4. Rendering Messages (300-399) A.5. Input Plane (400-499) A.6. Video Plane (500-599) A.7. Audio Plane (600-699) A.8. Error Reporting (700-799) A.9. Transport Services (800-899) A.10. Experimental and Vendor-Specific (900-999) Appendix B. Authentication Mechanism Registry B.1. Standard Mechanisms B.2. Extensible Mechanisms B.3. Private and Experimental Mechanisms B.4. Registration Policy Appendix C. SCTP Stream Usage Summary C.1. Stream 0 -- Control Plane C.2. Stream 1 -- Rendering Messages C.3. Stream 2 -- Input Plane C.4. Stream 3 -- Video Plane C.5. Stream 4 -- Audio Plane C.6. Additional Streams Appendix D. Protocol State Machine Diagrams D.1. Initial Connection State Machine D.2. Session Resume State Machine D.3. Error Handling State Machine D.4. Stream Interaction Summary Author's Address 1. Introduction The Mercurius Window System (MWS), named for Mercurius, the Roman messenger god of swift communication, is a secure window system for both local and remote use. A user may work directly at the console of a workstation as on a conventional Unix-like desktop, with full access to its GPU, input devices, audio devices, and local display. The same session may also be accessed from lightweight, mobile, or untrusted portal devices elsewhere, without replicating the workstation's software environment or exposing its data or GPU resources. Compute, storage, rendering, and audio processing remain on the workstation; Portals provide authenticated display, input, and audio endpoints. MWS is intended to let a workstation remain itself while being reached from elsewhere. The workstation is treated as a long-lived environment that accumulates tools, history, and identity; remote devices are simply places from which the user inhabits that environment. A user may begin work at a powerful machine in the office and later continue the same session from a laptop, thin portal, or secondary desktop in another location, without maintaining multiple environments or synchronising state. Remote access is an extension of the local workstation rather than a separate mode of operation. MWS is not merely a remote framebuffer protocol. It defines structured, message-oriented semantics for presence, Sessions, Windows, input, audio, and rendering state on a workstation. Even when carrying presented pixel buffers, it preserves the identity, ownership, geometry, lifecycle, and routing of each Window. The Transport is optimised for SCTP's multi-stream, message-oriented semantics [RFC9260], with separate streams assigned or reserved for control, rendering, input, video, and audio. This architecture continues the lineage of early Unix window systems such as X11, which supported network-transparent interaction with applications running on central servers, while applying modern zero-trust security [NIST800-207], authenticated multi-stream transport [RFC9260][RFC4895], and GPU isolation. Earlier systems such as NeWS also explored server-side rendering. Wayland defines direct interaction between applications and a local compositor, including shared rendering buffers [WAYLAND]. MWS instead specifies authenticated network attachment and Session continuity between a workstation and a Portal, while preserving local operation. 1.1. Scope and Applicability This document specifies the Mercurius Window System (MWS) protocol, the transport-level protocol used by MWS to establish, authenticate, and maintain a user's graphical presence on a workstation. The MWS protocol defines Message framing, authentication, Session attachment, Window lifecycle, and rendering presentation over a secure transport profile based on DTLS 1.3 [RFC9147] over SCTP [RFC9260], using the mapping defined by [I-D.6083BIS]. It specifies the semantics and requirements of the input, video, and audio planes. Where this version does not define a payload encoding, it explicitly prohibits senders from emitting the affected Message. MWS is intended for environments where: * applications execute on a central workstation or server * users may work locally at the console or remotely from other devices * portals may be untrusted, mobile, or ephemeral * users may relocate sessions across devices * GPU-accelerated workloads must remain server-resident * audio capture and playback must remain server-resident or explicitly brokered * network transparency is a first-class requirement * loss or theft of a device must not compromise workstation security. MWS does not replace local display protocols such as Wayland, nor does it extend them. It provides a complementary mechanism for secure local and remote presence in multi-user and distributed environments where local display protocols do not apply. 1.2. Design Rationale Early Unix window systems, including X11, were explicitly designed for network transparency: applications executed on powerful central servers while users interacted from remote terminals. This model proved valuable in multi-user and distributed environments. MWS retains network transparency while specifying authenticated, Session-scoped authority and server-side validation of Portal input and resource references. Wayland combines display-server and compositor responsibilities and permits direct Client rendering into shared buffers [WAYLAND]. MWS defines the separate workstation-to-Portal boundary, with explicit network transport and Session attachment semantics. This distinction does not preclude a Wayland compositor from offering its own remoting facilities or serving as a Portal's native display system. MWS intentionally revives and modernises the network-transparent workstation model. It retains the architectural advantages of centralised execution and remote interaction while adopting a zero-trust security model based on DTLS 1.3 [RFC9147], authenticated SCTP [RFC9260][RFC4895] streams, and per-portal GPU isolation. Rendering is server-resident and GPU-accelerated; Portals receive presentation Messages produced by the workstation, and audio is carried as explicit timestamped streams rather than device-local side effects. All compositor policy, input routing, and window management occur on the server, ensuring multi-user correctness and preventing privilege escalation. Crucially, possession of a portal device is never sufficient to access the workstation. Session resume requires fresh user authentication. Authoritative application data remains on the workstation; the limits of protection against a compromised active Portal are described in Section 3.6. The result is a window system that provides deterministic semantics, strong isolation, and relocatable sessions, enabling users to inhabit remote workstations with the performance and responsiveness of a local environment, whilst preserving first-class local console operation. 1.3. Cloud and Distributed Computing Context Many organisations operate private cloud or workstation-cluster environments where users access centralised compute and GPU resources from Portals on fixed or mobile devices. Public cloud deployments exhibit similar characteristics: applications execute on remote servers while portals roam across untrusted networks. MWS aligns with this model by centralising execution and distributing only the user interface. This avoids the inefficiencies of distributed compute systems whilst preserving the benefits of remote access, session mobility, and strong isolation between users. Because portals are untrusted, MWS confines each authenticated association to its authorised Session. A compromised active Portal remains a risk to its user, as described in Section 3.6. 1.4. High-Performance Rendering and Gaming MWS is primarily intended for workstation and private-cloud deployments in which portals connect over well-provisioned LANs and VPNs, typically with DANE [RFC6698][RFC7671] authenticating DTLS 1.3 [RFC9147] carried over SCTP as defined by [I-D.6083BIS]. In these environments, modern GPUs provide hardware-accelerated AV1 encoding [NVENC], which could support a future encoded-video profile. This revision reserves the Video Plane payloads rather than defining an AV1 streaming implementation. All workstation rendering in MWS is performed using the Vulkan [VK14] API. Nevertheless, the same architecture could accommodate high-performance remote rendering workloads, including interactive 3D applications and games. Support for such workloads is a stretch goal rather than a primary target, but these use cases inform the design of the transport, security, and rendering model to ensure that MWS remains viable for demanding graphical applications. 1.5. Portal Requirements and Wireless Considerations MWS portals are treated as untrusted endpoints. Practical deployments assume a minimum level of capability. A typical portal is expected to provide a modern CPU, a hardware-accelerated GPU capable of AV1 decoding, and at least gigabit-class network connectivity. Higher resolutions or refresh rates benefit from greater bandwidth, but MWS remains usable at reduced quality on lower-capacity links. Wireless performance depends on contention, interference, signal quality, and the complete network path. Implementations should measure available throughput and latency rather than infer interactive performance from a wireless standard or advertised link rate. 1.6. Session Mobility and Detachable Operation Because sessions in MWS are server-resident and independent of portal connections, the system naturally supports detachable operation. A user may disconnect from one portal and later resume the same session from another device, with all windows, GPU state, and compositor context preserved. This model is conceptually similar to terminal multiplexers such as screen or tmux, but applied to a full GPU-accelerated graphical environment. Session mobility is a core design goal of MWS and informs its authentication, transport, and rendering architecture. Deployments are expected to configure a reconnection grace period so that brief network outages or short unscheduled breaks such as to move or charge a portal device do not cause the user's session to be lost. 2. Conventions Used in This Document 2.1. Requirements Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 2.2. Referenced Terminology Terminology relating to Vulkan follows the definitions and naming conventions of the Vulkan 1.4 specification [VK14]. Terminology relating to SCTP follows the Stream Control Transmission Protocol specification [RFC9260]. Terminology relating to DTLS 1.3 follows the Datagram Transport Layer Security specification [RFC9147]. 2.3. General Terminology Unless otherwise stated: * "workstation" refers to the system on which applications execute, and where all rendering, compositing, and session management occur. * "server" refers to the MWS server daemon (mwsd) running on the workstation. In this document, "workstation" and "server" refer to the same system at different levels of abstraction. * "portal device" refers to the physical device through which a user interacts with the workstation. Examples include laptops, tablets, phones, dedicated terminals, and embedded devices. * "Portal" refers to the user-facing MWS endpoint: either the portal device as a whole or the MWS Portal software (mwsc) running on it, as the context requires. The Portal displays output, captures user interaction, communicates with the Server, and provides a Seat for a Session. It is not a Client. * "session" refers to a persistent graphical environment maintained on the workstation independently of portal connections. * "association" refers to a transport-bound communication channel between a portal and the server. When SCTP is used as the transport, an association corresponds exactly to the SCTP association defined in [RFC9260] and is identified by the SCTP implementation's assoc_id. An association is ephemeral and exists only for the lifetime of the underlying transport connection. * "seat" refers to a set of input devices and output mappings associated with a session and bound to a portal. * "surface" refers to a drawable region managed by the compositor and rendered by the workstation's GPU. 2.4. Protocol Roles The following capitalised names identify MWS protocol roles and resources. They describe protocol endpoints, authority, and addressing; they do not prescribe an implementation's internal object model: * "Message" is one complete, addressed MWS message exchanged by protocol endpoints. * "Client" is an application running on the workstation on the user's behalf, such as radialblur. A Client creates and renders Windows within the user's Session. It is distinct from both the Library and the Portal. * "Library" is the complete workstation-local adaptation subsystem between a Client and the Server. It presents the ordinary graphical APIs expected by an unmodified Client and carries the resulting Messages over the local client channel. An implementation may divide this role between compatibility interposition and underlying protocol facilities. The Client does not know about, call, or link against Mercurius. * "Server" is the MWS protocol endpoint on the workstation. It is authoritative for Sessions, Windows, resources, and policy. * "Application" identifies a Client through its authenticated local client channel at the Server. An application_id is a non-zero, Session-scoped identifier assigned by the Server for this purpose. It is not a process identifier or an implementation object pointer. * "Window" is a Session-scoped graphical window, including a top-level, transient, or popup Window. Lowercase "window" retains its ordinary graphical meaning. * "Session" is one authenticated user's server-resident graphical environment and the resources within it. * "Transport" is the protocol service that carries complete MWS Messages between a Portal and the Server. Transport-reserved Messages are exchanged only between peer transport endpoints. Conforming implementations MAY organise their internals in any manner, but MUST preserve the specified Message semantics, authority boundaries, addressing, and routing. 2.5. Additional Terms and Threat-Model Names * "command stream" refers to the structured Mercurius protocol messages exchanged on SCTP stream 0 (control stream). * "video surface" refers to a high-motion region encoded using a hardware-accelerated codec such as AV1. * The names Alice, Bob, Eve, and Mallory are used in their standard roles from security literature. Alice and Bob denote honest users, Eve denotes a passive eavesdropper, and Mallory denotes an active attacker. These names are used solely for threat-model examples and do not correspond to real users or implementation artefacts. 2.6. Wire-Format Conventions Wire formats are described in terms of octets and fixed-width integers. C structures, C type names, alignment, padding, and host byte order are not part of the protocol. All multi-octet integers are transmitted in network byte order unless explicitly specified otherwise. Signed integers use two's complement representation. Lengths are measured in octets. Receivers MUST validate lengths, reserved fields, and arithmetic before allocating storage or using a payload. Unless explicitly allowed, trailing octets are invalid. Unless otherwise specified, text fields in MWS messages are encoded as length-prefixed UTF-8 [RFC3629] strings ("Pascal strings"). A length-prefixed string consists of an unsigned length field (for example, a one-octet or two-octet unsigned integer) followed immediately by that many octets of UTF-8 text. No NUL terminator is transmitted on the wire; the length is authoritative. Opaque variable-length fields use the same representation: an explicitly sized unsigned length field followed immediately by that many octets. Opaque fields are not implicitly text, do not carry a terminator, and have no alignment padding. 3. System Architecture This section provides a high-level overview of the Mercurius Window System (MWS). It describes the conceptual model, major components, and architectural principles that inform the detailed design in Section 4 and the protocol specification in Section 5. MWS is designed around a workstation-centric model in which all rendering, compositing, audio processing, session management, and window-management policy reside on a central server. Portal devices act solely as authenticated display, audio, and input endpoints. This model preserves the semantics of a local workstation while enabling secure remote presence across modern networks. MWS assumes portal devices with at least gigabit-class connectivity, including modern Wi-Fi networks that routinely exceed 1 Gb/s. The protocol is optimised for 10 GbE LANs, where uncompressed or lightly compressed surfaces, high-motion content, and low-latency audio can be delivered with minimal delay. Devices with substantially lower bandwidth may operate at reduced quality but are not a primary design target. The Audio Plane uses a dedicated stream suitable for workstation-class media workloads. This revision defines negotiated S16, S24 and F32 linear PCM playback and capture lifecycles. It does not make quantitative latency guarantees. 3.1. Architectural Principles The design of MWS is guided by the following principles: * Applications execute on a central workstation or server. * Local and remote interaction share identical session semantics. * Portal devices may be untrusted, mobile, or ephemeral. * Users may relocate sessions across devices without restarting applications. * GPU-accelerated workloads remain server-resident. * Real-time audio is a first-class subsystem with strict latency and ordering requirements. * Network transparency is a first-class requirement. * Loss or theft of a portal device must not compromise workstation security. These principles reflect the goal of treating the workstation as a long-lived environment with continuity of storage, configuration, and identity. Alternative transports such as QUIC were considered. However, SCTP's native multi-streaming, message-oriented delivery, and support for partial reliability align directly with the requirements of MWS. QUIC's multiplexed byte-stream model, together with the absence of partially reliable streams, would require additional framing and scheduling logic to emulate SCTP semantics. For these reasons, SCTP is the primary transport for MWS. The protocol's guarantees depend on transport properties that SCTP provides natively, including independent ordered streams, preservation of message boundaries, optional partial reliability, avoidance of cross-stream head-of-line blocking, and stable SCTP associations. These properties are required to ensure deterministic compositor behaviour, responsive input under load, support for high-motion video surfaces, low-latency audio transport, relocatable sessions, and multi-seat concurrency. TCP does not provide these properties without substantial additional protocol machinery. A TCP-based transport would therefore be unable to meet the latency, isolation, and concurrency requirements of MWS as defined in this document, and is out of scope for this specification. 3.2. Protocol Endpoints MWS has two network protocol endpoints: the Server on the workstation and the Portal on the user's portal device. The Server maintains authoritative Sessions, Windows, rendering, focus, input routing, and policy. The Portal presents graphical and audio output and sends user input to the Server. A workstation Client uses its ordinary graphical APIs. The MWS client library transparently adapts those calls to the local client channel to create Windows and provide rendering content. The complete path is Client -> Library -> Server -> Portal, and the reverse path applies to Portal-originated interaction and server notifications. The client channel is distinct from the authenticated Portal association and carries only Messages whose definitions explicitly permit that scope. This specification does not prescribe how an implementation divides these responsibilities among internal components. 3.3. Workstation-Centric Model The workstation is the authoritative environment. It owns all GPU resources, logical audio devices, compositor state, and input-routing policy. Applications run exclusively on the workstation, and all rendering and audio processing are performed on workstation-resident hardware. Portal devices own their physical input hardware. Input events are generated on the portal and forwarded to the workstation, which applies focus, routing, and seat semantics. The workstation never interacts with the portal's physical devices directly; it operates only on the logical input events they produce. GPU resources are exposed to MWS exclusively through the Vulkan API. The workstation enumerates all available GPUs using vkEnumeratePhysicalDevices() and creates one compositor instance per physical device in the reference implementation. An interoperable implementation may organise its GPU resources differently. No Vulkan object or native handle is transmitted to a Portal. Audio resources are exposed to MWS through audio devices, each of which represents a physical or virtual playback or capture endpoint. Audio streams are created dynamically to transport PCM audio between the workstation and portal devices. A user may interact with the workstation in two ways: * Local console mode, using the workstation's own keyboard, pointer, display, and audio hardware. * Remote presence mode, using an authenticated portal device elsewhere on the network. Local and remote interaction share the same compositor, window tree, audio devices, and session state. Remote presence is an extension of the local workstation, not a separate mode of operation. Sessions persist across transient disconnections, but long-term persistence requires explicit detachment. 3.4. Rendering and Surface Model The MWS architecture distinguishes two classes of graphical output: * rendering updates, representing Window content prepared for presentation by the Portal * video surfaces, representing high-motion content encoded using hardware-accelerated codecs such as AV1 The compositor selects the appropriate representation based on surface characteristics and available bandwidth. This allows MWS to adapt its presentation to the available network capacity. This revision defines pixel-based rendering updates; encoded video remains reserved as specified in Section 5.5. Surfaces represent drawable regions within the server's graphical environment. Windows reference one or more surfaces, and the compositor determines whether a surface is transmitted as rendering updates or as a video stream. The renderer executes Vulkan command streams on the workstation. The Server sends the resulting Portal-ready representation, while video surfaces are encoded using hardware acceleration when available. 3.5. Session Model Sessions are server-resident and persist independently of portal connections, but long-term persistence requires explicit detachment. MWS tolerates transient network interruptions; if a portal reconnects within the configured grace period, the session continues without interruption. If a portal disappears without detaching, the session is preserved only for the duration of this grace period. Once the period expires, the session is closed, and applications terminate in the same manner as they do in a workstation session without an active seat. Because all application, window, and session state resides on the workstation, failure, loss, or destruction of a portal device does not by itself risk loss of in-progress work; the session remains intact on the server and may be resumed from another device, subject only to the reconnection grace period. A user may explicitly detach a session to preserve it beyond the reconnection grace period and may later resume it from any authorised device. A single transport association may provide multiple seats for a session when permitted by policy. The precise rules governing how many transport associations may attach to a session over time, and under what conditions, are defined in Section 4.8. Sessions contain seats, each of which aggregates input devices, audio streams, and presentation state for a particular user interaction context. Multiple seats may be active concurrently, enabling multi-user or multi-portal operation. This model enables mobility across devices while preserving the semantics of a traditional workstation and avoiding long-lived orphaned sessions. 3.6. Zero-Trust Portal Model All portal devices are treated as untrusted endpoints, even on local LANs. Trust is established exclusively through cryptographic identity and explicit authorisation rather than network location. A portal device is not an identity and is not authorised to access a session by virtue of its presence on the network; only the user is authorised. A Portal's location and native display system do not establish its authority. MWS derives that authority from the authenticated user and confines it to the attached Session. The Server must validate each operation even when the Portal is on the local network or workstation. Server identity is established during the DTLS 1.3 handshake carried over SCTP for each transport association. Deployments SHOULD use DNS-Based Authentication of Named Entities (DANE) [RFC6698][RFC7671] to bind the server's certificate to DNSSEC-protected TLSA records, allowing portals to verify that they are communicating with the correct workstation without relying on public certificate authorities or assumptions about local network topology. User authentication is performed at the application layer using the mechanism-agnostic model defined in Section 5.2.1. The server advertises supported mechanisms (for example, "PAM", "FIDO2"), and the portal selects one. This allows deployments to integrate password-based, hardware-token, federated, or certificate-based user authentication without modifying the protocol. A portal device is assumed to be mobile and at risk of loss or theft. User files and authoritative Session state remain on the workstation and are not replicated to the Portal. A Portal may, however, hold reusable authentication material such as an encrypted private key, and an active Portal necessarily observes displayed content and user input. A compromised active Portal can therefore compromise the user operating it. The zero-trust boundary is server-side authority. Possession or compromise of one Portal MUST NOT grant authority over another user's Session, reveal resources outside the attached Session, or make Portal-supplied identifiers authoritative. Deployments that require proof of user presence MUST choose an authentication mechanism that provides it; the base protocol does not infer user presence merely from possession of a device or private key. 3.7. Network Considerations MWS is designed to operate over untrusted IP networks, including public networks and variable-quality wireless links. The protocol does not assume that portals are located on the same LAN as the workstation, nor that any network segment provides meaningful security. A portal on a local LAN and a portal on a remote network are treated identically by the workstation. MWS is designed for modern networks: * 10 GbE provides optimal performance and headroom for multiple high-resolution seats on a single workstation. * Wi-Fi 6/6E/7 provides multi-gigabit throughput with variable jitter and is fully supported for single-seat portals. * 1 GbE provides a usable baseline for typical desktop workloads and a small number of seats on a workstation. * Sub-gigabit links are outside the primary design envelope and are not expected to provide an acceptable experience for high-resolution, high-refresh workloads or low-latency audio. The transport layer adapts to available bandwidth through dynamic surface encoding, selective use of video surfaces, adaptive refresh rates, and prioritised input, audio, and control streams. The detailed architecture is specified in Section 4, and the wire protocol is defined in Section 5. 3.8. Transport Requirements MWS requires a transport that provides structured, message-oriented delivery with support for multiple independently ordered channels. The transport MUST preserve message boundaries, MUST support concurrent streams with independent ordering, and SHOULD provide mechanisms for partial reliability to avoid retransmission of stale high-volume data such as video surfaces and real-time audio frames. The transport MUST avoid cross-stream head-of-line blocking. Input events, control messages, rendering updates, audio streams, and video surfaces are logically independent flows, and the correctness of compositor behaviour depends on their timely and ordered delivery within their respective channels. A transport that enforces global ordering across all data would introduce latency coupling between these flows and would not meet the responsiveness requirements of MWS. A server carrying more than one association MUST apply backpressure per association. Readiness of a shared transport endpoint MUST NOT be interpreted as evidence that any particular association can accept more data. A congested or stalled portal MUST NOT block transport progress for other portals. The transport MUST support stable associations that survive supported path changes for the lifetime of the association. Mobility which cannot preserve that association uses fresh authentication and Session resumption. SCTP multihoming does not by itself guarantee uninterrupted connectivity across arbitrary networks or NATs. SCTP satisfies these requirements through its native multi-streaming model, message-oriented delivery, optional partial reliability, and support for multi-homing. These properties align directly with the architectural principles defined in Section 3.1 and are required for deterministic compositor behaviour, responsive input under load, support for high-motion video surfaces, low-latency audio transport, relocatable sessions, and multi-seat concurrency. MWS protects SCTP user messages with DTLS 1.3 using the DTLS-over-SCTP mapping defined by [I-D.6083BIS]. That work replaces the DTLS 1.0 mapping specified by [RFC6083] with a mapping for DTLS 1.3. Unlike TLS over SCTP [RFC3436], the DTLS mapping preserves message boundaries, unordered delivery, and PR-SCTP. The cited mapping remains work in progress; this experimental profile depends on the specific revision cited in Section 12.1, including its revised SCTP-AUTH dependency. Both endpoints MUST negotiate the ALPN identifier "mws" [RFC7301] during DTLS establishment and abort if it is not selected. The SCTP association MUST provide at least five streams in each direction. DTLS records use the MWS-over-DTLS PPID requested as TBD2 in Section 10. MWS Control uses Stream 0, which it shares with DTLS handshake and alert traffic; other MWS planes use their assigned streams. TCP does not provide these properties without substantial additional protocol machinery. TCP offers only a single in-order byte stream, lacks message boundaries, enforces global head-of-line blocking, and provides no support for partial reliability or multi-streaming. A TCP-based transport would therefore be unable to meet the latency, isolation, and concurrency requirements of MWS as defined in this document, and is out of scope for this specification. 4. Detailed Architecture The Mercurius Window System (MWS) is structured around a central server (mwsd) that owns all GPU resources, audio devices, input routing, and compositor state, and a set of untrusted portal devices that connect over a secure, message-oriented transport. Once connected, a portal device acts as a portal providing a seat. This section describes the architectural model of sessions, seats, windows, rendering, and compositor behaviour. The wire protocol and message formats are defined in Section 5. 4.1. Sessions A session represents the complete graphical environment associated with a single authenticated user, including windows, workspaces, GPU resources, audio devices, and compositor state. Sessions are server-resident and MAY persist independently of portal connections when explicitly detached. User identity is established during the application-layer authentication phase of the handshake (Section 5.2.1). The authenticated identity (for example, a local username, a portal certificate subject, or a federated identity token) is mapped to a local user account via the system's authentication framework (such as PAM). 4.2. Seats A seat represents a set of input devices, audio streams, and an output binding for a session. A session MAY have multiple seats simultaneously. Each seat corresponds to a particular portal, whether that portal is the local console or a remote portal device acting in the portal role. Input belongs to a Seat, and the compositor routes it according to seat-specific focus and pointer state. Section 5.4 defines the base Seat and logical input devices. Additional Seats, device enumeration, and seat-specific output and audio routing require an extension. 4.3. Windows Windows are server-managed objects representing top-level application surfaces, including related transient and popup Windows. Each window belongs to exactly one session and is associated with one or more rendering surfaces (structured swapchains or video surfaces) depending on compositor policy. Window identifiers are scoped to a session. A portal MUST NOT reference or interact with windows belonging to any other session. The server MUST enforce this isolation and MUST reject or ignore any protocol message that attempts to target a window outside the authenticated session. 4.4. Server Window Management The Server maintains the global window tree, stacking order, focus, workspaces, and output mappings for each session. It is responsible for: * applying window-management policy * routing input events based on seat and focus * managing swapchains and presentation timing * selecting between rendering updates and video fallback * revoking or reconfiguring windows according to policy The Server SHOULD expose a user-visible mechanism to forcibly terminate an unresponsive window. This mechanism is implementation-defined (for example, a "kill window" gesture similar to Ctrl-Alt-Esc in KDE). The Server MAY revoke swapchains, reconfigure windows, or migrate them between outputs according to local policy, resource constraints, or security requirements. When a swapchain is revoked, the server notifies the portal and MAY substitute a placeholder or video surface. The Server is responsible for isolating and coordinating its GPU and output resources. The internal division of device contexts, queues, swapchains, and associated GPU buffers is implementation-defined. 4.5. Rendering Model Rendering in MWS is workstation-side. Clients use the workstation's graphics APIs and GPU through the Library adaptation path. The Server validates the resulting client-channel Messages and manages Window presentation. The defined pixel Messages do not carry Vulkan command buffers. Portals do not access workstation GPU resources directly. The compositor selects the appropriate representation for each surface: * rendering updates for low-motion or interactive content * video surfaces for high-motion or bandwidth-sensitive content Because rendering is server-resident, a stalled or misbehaving portal cannot block the compositor. The server MAY revoke a window's rendering resources, substitute a placeholder surface, or terminate the portal if rendering deadlines are repeatedly missed. The MWS specification assumes a modern explicit GPU API for rendering and composition (for example, Vulkan [VK14]) and requires that all rendering and presentation operations be performed through the compositor's device-level abstraction. Portal devices are not required to implement any graphics API. 4.6. Audio Model The audio subsystem manages audio devices and audio streams between the workstation and Portal devices. Audio is a first-class architectural subsystem with strict latency and ordering requirements. Its traffic is logically independent of rendering and control traffic while sharing the secure, multi-stream Transport. An audio device represents a physical or virtual playback or capture endpoint on the workstation, such as speakers, headphones, microphones, instrument inputs, multichannel mixers, loopback devices, and virtual sinks. Devices are enumerated and managed on the server. A Portal manages its own physical playback and capture hardware and exposes only the negotiated logical streams to the Server. Logical audio streams are created dynamically to carry PCM samples between the workstation and the portal. Each audio stream is bound to a specific audio device and seat, and is direction-specific (playback or capture). Workstation-originated playback uses the Session media timeline; capture uses the Portal capture clock, as specified in Section 5.6.1. The Portal maintains bounded playout buffers. Playback streams carry audio from applications on the workstation to the portal device for presentation. Capture streams carry audio from portal-attached input devices to the workstation, where the audio is delivered to the appropriate session and applications according to policy. The server MAY apply policy to limit or redirect capture streams (for example, to prevent inadvertent capture in shared environments, or to restrict which multichannel devices are exposed to a given session). The Audio Plane uses Stream 4, separate from control, rendering, input, and video. Its Message lifecycle and current payload requirements are specified in Section 5.6. 4.7. Stream Allocation MWS assigns SCTP streams by Message class: * Stream 0: control * Stream 1: rendering * Stream 2: input * Stream 3: video * Stream 4: audio These assignments are fixed. A Window is identified by Message addressing and is not assigned an SCTP stream. Multiple Windows may therefore use the same rendering or video stream without changing their identity, ownership, or routing. Streams 5-15 are reserved for future standard assignments. Streams 16 and above MAY be used by experimental or vendor-specific extensions as described in Appendix C.6. 4.7.1. Session Identity and Message Routing Each transport association is attached to at most one portal session at any point in time. A session MAY be attached to different transport associations over its lifetime (for example, after detachment and resume), but a given transport association MUST NOT carry traffic for more than one session concurrently. The server MUST treat the transport association (for example, an SCTP association as defined in [RFC9260]) as the authoritative source of session context for message routing. No portal-supplied field may override the Session to which ordinary traffic is delivered. The offered identifier in MWS_SESSION_RESUME_REQUEST is a selection request, validated under Section 5.2.2.1, rather than routing authority. After successful user authentication, the server creates a bootstrap Session through which the Portal can interact with a Session selector. The bootstrap Session is the association's active Session until the user either continues it as a new Session or selects an existing Session as defined in Section 5. Until bootstrap Session establishment completes, the server MUST reject non-handshake traffic as specified in Section 5.2.1. For any message received on a non-zero stream, the server MUST: * identify the session currently attached to the transport association * verify that the session is active * dispatch the message to the subsystem corresponding to the stream * reject or ignore the message if it is malformed or references resources outside the session Messages referencing windows, seats, or other resources not owned by the attached session MUST be rejected with MWS_ERROR_SESSION (type=702, fatal=0). Except for an authorised resumption request, a Message carrying a session_id inconsistent with its association MUST be rejected with MWS_ERROR_SESSION (type=702, fatal=0). On an association with an active handshake but no established Session, only the handshake and applicable error Messages are permitted. A Message received after the association has been closed MUST be discarded without allocating Session resources. 4.8. Session Lifecycle A session is a long-lived server-side construct that persists independently of any particular network connection. A session becomes ACTIVE when a portal completes Session establishment as defined in Section 5 and remains ACTIVE until it is detached, abandoned, explicitly terminated, or reclaimed by policy. Authentication creates a new bootstrap Session, but does not by itself resume any existing Session. A Portal MUST explicitly request either continuation of the bootstrap Session as a new Session or resumption of a Session offered by the server. If an existing Session is resumed, it atomically replaces the bootstrap Session on the association and the server destroys the bootstrap Session. The server MUST NOT reattach an existing Session solely on the basis of matching user identity. A portal MAY explicitly detach from an ACTIVE session. Detach transitions the session from ACTIVE to DETACHED. In the DETACHED state, it has no attached transport association. Its Clients, windows, compositor state, audio stream state, and GPU resources remain server-resident. DETACHED sessions MAY be resumed by any authenticated portal device belonging to the same user, subject to server policy. When explicitly detaching a Session, the user MUST be able to request either that its Clients continue executing in the background or that they are suspended until a Portal resumes the Session. This is a server-side user-interface and policy requirement: this revision does not encode that choice in the empty MWS_SESSION_DETACH payload. The Server MAY accept, reject, or override that request according to policy, but MUST report the effective choice to the user and retain it as Session state. The policy for an unplanned transition to GRACE is server-defined. In either state, the Clients MUST remain present and MUST NOT be restarted merely because the Session resumes. A Server that permits background execution MUST define and enforce appropriate resource, timer, and externally visible I/O policy. Loss of the transport association (for example, network outage, SCTP association failure, timeout, or portal crash) while a session is ACTIVE does not immediately terminate the session. Instead, the server MUST transition the session to a GRACE state and start a reconnection grace timer. In the GRACE state, the session remains active but has no attached portal. If a portal reconnects and successfully resumes the session before the grace timer expires, the server MUST transition the session back to ACTIVE and the session continues without loss of state. If the reconnection grace period expires without a successful resume, the server MUST treat the session as ABANDONED unless the user has explicitly detached it. ABANDONED sessions MUST be terminated and all associated resources reclaimed. Implementations MUST provide a configurable reconnection grace interval and SHOULD allow values sufficient to tolerate brief network outages on typical Wi-Fi and WAN links. Servers SHOULD return a specific error status when a resume request targets an expired session. Long-term persistence is an explicit, opt-in behaviour: a session continues to exist beyond the reconnection grace period only if the user has explicitly detached it or otherwise marked it for later resumption. Implementations MUST NOT retain ABANDONED or stale sessions indefinitely. The server SHOULD reclaim resources associated with inactive sessions according to local policy (for example, idle timeout, logout event, or administrative limits). A Session MUST NOT have more than one attached transport association (Portal instance) at a time in the base protocol. That association MAY provide one or more seats for the session, subject to server policy. An implementation MAY provide a mechanism that allows additional associations to attach to the same session (for example, for technical support), but such behaviour is outside the scope of this specification and MUST NOT alter the semantics defined for the single-association model above. 4.9. Session and Seat Model Sessions MAY persist independently of portal connections. When a portal device disconnects (for example, when its transport association is lost), the associated session and its windows MAY remain active in either the GRACE or DETACHED state. The compositor MAY blank or lock the session's outputs according to local policy while no seat is attached. When a user resumes a session (from GRACE or DETACHED), the server: 1. Attaches the authenticated association to the Session. 2. Sends the current Window list, geometry, visibility, and stacking order as defined in Section 5.2.2. 3. Re-establishes the base Seat and input state under Section 5.4 and reopens Audio streams under Section 5.6. Additional output mappings and device enumeration require later extensions. MWS supports both independent sessions and multi-seat attachment within a single session. A user may maintain multiple concurrent sessions (for example, two independent desktop environments), or may attach multiple seats to the same session via a single transport association, subject to the single-association model defined in Section 4.8. MWS also supports explicit session detachment. A user may detach a running session, preserving its Clients while leaving its windows, compositor state, audio stream state, and GPU resources resident on the server without any attached seats. The user may then initiate a new session on the same portal device (for example, to perform unrelated work) and later resume the detached session exactly where it was left. This behaviour is directly analogous to detaching and reattaching a GNU Screen or tmux session, but applied to a full graphical desktop environment spanning one or more seats. 4.10. Local Transport Profile (Non-Normative) Although MWS treats all portal devices as untrusted endpoints and applies the same protocol semantics regardless of network location, implementations may apply transport-layer optimisations when the portal and server reside on the same physical host. These optimisations must not alter protocol semantics, message ordering, authentication requirements, or session isolation, and must remain transparent to the portal. Permitted implementation-level optimisations include: * loopback-specific SCTP acceleration * reduced cryptographic overhead * shared-memory fast paths * GPU-direct resource sharing where supported These optimisations must not: * grant additional privileges to local portals * bypass certificate validation or user authentication * modify the behaviour of control, input, audio, or rendering streams * introduce protocol features unavailable to remote portals MWS remains a network-transparent window system. Local optimisations exist solely to ensure that portal devices running on the same host as the server achieve performance comparable to traditional local-only systems without compromising the zero-trust security model. 4.11. Security Model All portals are treated as untrusted. Trust is established exclusively through cryptographic identity and explicit authorisation rather than network location. The server enforces strict isolation between users, sessions, seats, and windows. In particular: * at any point in time, a session is attached to at most one transport association in the base protocol, and the server uses the association on which a message is received as the authoritative source of session context; portals cannot select or override the session by supplying identifiers * window identifiers are scoped to a session and cannot be referenced by other sessions * input events are scoped to a seat and session, and cannot target windows outside that session * portals cannot observe, enumerate, or reference resources belonging to other sessions * all portal-originated messages are validated before being processed Transport security is provided by DTLS 1.3 carried over SCTP using the mapping defined by [I-D.6083BIS]. The mapping requires the revised SCTP-AUTH extension it references, derived from [RFC4895], including authentication of DATA and, when used, FORWARD-TSN chunks. Implementations MUST follow the mapping's chunk-authentication and key-management requirements; implementing [RFC4895] alone is not sufficient. SCTP-AUTH does not encrypt MWS Messages. DTLS provides confidentiality and integrity for MWS Messages. Deployments SHOULD use DNS-Based Authentication of Named Entities (DANE) to bind the server's certificate to DNSSEC-protected TLSA records, allowing portals to verify that they are communicating with the correct workstation even in the presence of compromised or mis-issued CA certificates. Device identity is not part of the trust model; access to user sessions is determined solely by user authentication and server policy. The DTLS profile is part of the base protocol. An external secure tunnel MAY provide defence in depth but does not replace DTLS or relax any MWS authentication requirement. Deployments MAY additionally require portal authentication at the transport layer (for example, mutual DTLS), but such device identity is always subordinate to user-level authorisation. User authentication is performed at the application layer using the mechanism-agnostic model defined in Section 5.2.1. The server advertises supported mechanisms (for example, "PAM" and "FIDO2"), and the portal selects one. This separation of device and user identity ensures that device identity alone does not grant access to a user's Session. The server validates all portal-originated messages, including input events. A portal may not reference windows, sessions, or resources outside its authenticated session. Attempts to do so are rejected with MWS_ERROR_SESSION (type=702, fatal=0). Malformed or semantically invalid messages are ignored, and the session continues unless the error is marked fatal. The server does not trust the Portal as an authority over Session state. The user nevertheless entrusts an active Portal with the content it displays, the input it captures, and any authentication material used there. If a portal disconnects unexpectedly, the session persists only for the duration of the reconnection grace period unless the user has explicitly detached. After this period, the session is closed and applications terminate. Loss of the transport association for any reason (network failure, timeout, endpoint crash) is treated as a fatal transport error. The session MAY persist according to the rules in Section 4.8 and MAY be resumed from another portal subject to policy. 5. Protocol Specification 5.1. Message Framing All MWS messages consist of a fixed-size header followed by an optional payload. The header declares the exact payload length; a message is therefore self-delimiting. The header format is: magic 4-octet unsigned integer type 2-octet unsigned integer reserved 2-octet unsigned integer length 4-octet unsigned integer magic MUST contain 0x4d657263, the ASCII octets "Merc". type is the opcode registered in Appendix A. reserved MUST be zero. length is the payload length in octets and does not include the header. The 32-bit length field can represent payload lengths from zero to 4294967295 octets. This is the framing limit, not a requirement that an endpoint accept a payload of every representable size. During Session establishment, each endpoint declares the largest logical payload it has resources to accept. A sender MUST NOT send a logical Message whose declared payload length exceeds the peer's limit. A receiver MUST validate the header against that limit before allocating storage or processing the payload. Exceeding the advertised limit is a resource error, not malformed framing. Implementations MAY choose different receive limits according to available memory and local policy. The payload immediately follows the header. Implementations MUST validate the magic value, type, and declared payload length before processing the completed Message. An invalid header is a fatal protocol error. The receiver MUST terminate the association and SHOULD first send MWS_ERROR_PROTOCOL (type=701, fatal=1) when it can safely construct and transmit that response within the peer's limits. Integer and variable-length fields follow the wire-format conventions in Section 2.6. A Window identifier is not part of the common header because not every MWS Message concerns a Window. Except for Error Messages, every Message carrying a window_id MUST place it in the first four octets of its payload. This conditional common prefix allows a recipient to determine which Window a Message concerns without interpreting the remainder of that Message's payload. Error Messages are the exception: their diagnostic window_id follows the four-octet error-correlation prefix specified in Section 5.9. When a complete Portal-association MWS Message, including its 12-octet header, fits within the peer's max_user_message_size, it is carried as the plaintext of one DTLS record in one SCTP user message. In this document, max_user_message_size measures that plaintext, including the outer MWS header but excluding DTLS and SCTP overhead. Section 5.1.1 defines Transport fragmentation for a larger logical Message. MWS opcodes form a common Message vocabulary between Mercurius endpoints. Not every MWS Message crosses the Portal association. A "Portal-association" Message crosses that authenticated association. A "client-channel" Message crosses the workstation-local boundary between the Library and the Server. A Message MUST NOT cross a boundary for which its definition does not permit it. A Message may retain its opcode and payload while moving from one scope to another. Some events are deliberately delivered across more than one boundary so that each endpoint sees the Message appropriate to its responsibility. These classifications describe semantic wire senders and recipients, not internal server dispatch. 5.1.1. Transport Fragmentation Fragmentation is a Transport concern. The protocol component sending an ordinary MWS Message and its recipient operate only on the complete logical Message. They do not inspect, originate, receive, or handle the Transport Messages defined in this section. If an ordinary complete MWS Message fits within the peer's declared max_user_message_size, the Transport MUST send it unchanged. If it does not fit, the Transport MUST send one MWS_MESSAGE_START. It MUST then send as many MWS_MESSAGE_APPEND Messages as are required to complete the logical Message, or send MWS_MESSAGE_ABANDON. Every outer Message, including its 12-octet outer header, MUST fit within the peer's max_user_message_size. MWS_MESSAGE_START (type=800) -- transport endpoint -> transport endpoint The payload consists of the original 12-octet MWS header, copied unchanged in network byte order, followed by zero or more initial octets of the original payload. The outer payload length MUST be at least 12. The retained original header MUST be valid, MUST declare a payload no larger than the receiver's max_payload_size, and MUST NOT contain type 800, 801, or 802. MWS_MESSAGE_APPEND (type=801) -- transport endpoint -> transport endpoint The payload consists of one or more consecutive octets of the original payload. An empty MWS_MESSAGE_APPEND is a protocol error. MWS_MESSAGE_ABANDON (type=802) -- transport endpoint -> transport endpoint Abandons the active fragmented logical Message on the same association and SCTP stream. Its payload MUST be empty. The receiver MUST maintain at most one active fragmented logical Message for each association and SCTP stream pair. It validates and retains the original raw header from MWS_MESSAGE_START, then appends payload octets from successive MWS_MESSAGE_APPEND Messages on that association and stream. It MUST deliver exactly one reconstructed ordinary Message only after accumulating the payload length declared in the retained original header. While a fragmented Message is active on an association and stream: * MWS_MESSAGE_APPEND is valid only for that active Message. * MWS_MESSAGE_ABANDON discards the active Message and all of its accumulated payload without delivering or acting upon it. * A second MWS_MESSAGE_START on the same association and stream is a protocol error. * An ordinary MWS Message on the same association and stream is a protocol error. * Accumulating more payload octets than the retained original header declares is a protocol error. MWS_MESSAGE_START, MWS_MESSAGE_APPEND, and MWS_MESSAGE_ABANDON MUST use reliable, ordered delivery. A fragmented sequence MUST NOT use partial reliability or unordered delivery. Once a sender has emitted MWS_MESSAGE_START, it MUST complete or abandon that logical Message before sending another Message on the same association and stream. In this revision, a fragmented MWS_RENDER_PRESENT MUST be completed, not abandoned, so its generation can be included in cumulative Render retirement. Unsent Render work may still be discarded before START. MWS_MESSAGE_ABANDON without an active fragmented Message is a protocol error. After an active Message has been abandoned, the next ordinary Message or MWS_MESSAGE_START on that stream is valid. Loss of an association discards every incomplete fragmented Message for that association. An incomplete Message MUST NOT be delivered or acted upon. A malformed sequence is a fatal protocol error and the receiver MUST terminate the association after sending MWS_ERROR_PROTOCOL when it is possible to do so safely. A receiver MUST apply its declared payload and buffering limits before allocating reassembly storage. Reassembly state and queued fragment data MUST be bounded independently for each association so that one peer cannot consume resources belonging to another. Fragmentation is available only after the two-way MWS_SESSION_INFO exchange. Before that exchange, endpoints MUST accept complete MWS handshake Messages up to 16384 octets, including the MWS header. Senders MUST fit them within that bound and any smaller negotiated DTLS record limit. Credentials which cannot fit MUST be rejected; handshake fragmentation is not defined. An endpoint's max_user_message_size MUST be at least 68 octets, allowing the unfragmented 56-octet MWS_SESSION_INFO payload and its header. This also accommodates the two headers in MWS_MESSAGE_START. 5.2. Control Messages (Stream 0) Control messages manage authentication, session establishment, window lifecycle, and compositor state. All Portal-association control Messages MUST be sent on SCTP stream 0. The control channel is strictly ordered and defines the protocol state machine for session creation, resumption, and teardown. Rendering, input, audio, and video streams operate independently and are not blocked by control-plane latency. 5.2.1. Initial Handshake (001-099) The initial handshake establishes user identity and Session parameters. DTLS 1.3 [RFC9147] over SCTP using [I-D.6083BIS], optionally validated using DANE (Section 9.1), authenticates the server and protects the transport. The application-layer handshake authenticates the user and establishes a session. The handshake and the resulting Session have different security obligations: 1. The handshake must be cheap and fail fast so that an unauthenticated peer cannot consume disproportionate server resources. 2. The Session must remain secure against a capable, persistent attacker after authentication has succeeded. MWS_QUERY is deliberately an empty Message under the first of these rules. Receiving it MUST NOT cause the server to parse peer-supplied negotiation data or allocate Session resources. Authentication failures, malformed handshake Messages, and unsupported mechanisms MUST be rejected without creating a Session. User authentication is mechanism-agnostic. The server advertises one or more supported authentication mechanisms, and the portal selects one. This allows deployments to integrate PAM, WebAuthn, FIDO2, Kerberos, OAuth2, or future mechanisms without modifying the protocol. The handshake proceeds as follows on SCTP stream 0: 1. MWS_QUERY (type=001) -- Portal -> Server Requests the server's authentication challenge. MWS_QUERY has no payload. A non-zero payload length is a protocol error. 2. MWS_AUTH_CHALLENGE (type=002) -- Server -> Portal Advertises the available authentication mechanisms. The payload contains a list of mechanism identifiers followed by a fresh per-association authentication nonce. Payload format: mechanism_count 1-octet unsigned integer repeated mechanism_count times: name_len 1-octet unsigned integer name name_len octets nonce_len 1-octet unsigned integer nonce nonce_len octets Mechanism names are UTF-8 strings and are not NUL-terminated. name_len MUST be between 1 and 64 octets, as specified in Appendix B. mechanism_count MAY be zero, in which case the portal MUST abort the handshake. nonce_len MUST be 32. The nonce MUST be generated using a cryptographically secure random number generator and MUST be unique to the transport association. Mechanism-specific use of the nonce is defined by that mechanism. SSHKEY binds its proof to the association through tls-exporter, as specified in Appendix B.1. PAM transmits a password inside the authenticated encrypted channel; it is not a nonce-based proof. 3. MWS_AUTH_RESPONSE (type=003) -- Portal -> Server Selects an authentication mechanism and provides mechanism-specific credentials. Payload format: mech_name_len 1-octet unsigned integer mechanism mech_name_len octets credential_len 2-octet unsigned integer credential credential_len octets mechanism MUST exactly match one of the names advertised in MWS_AUTH_CHALLENGE. If the mechanism is unknown or the payload length is inconsistent, the server MUST respond with MWS_ERROR_PROTOCOL (type=701, fatal=1). A cryptographic mechanism that proves possession of a reusable credential MUST bind that proof to the current DTLS association. Such a proof MUST NOT consist only of data supplied by the Portal or of the reusable MWS_AUTH_CHALLENGE payload. The SSHKEY mechanism uses the tls-exporter channel binding defined by [RFC9266], as specified in Appendix B.1. 4. Bootstrap Session establishment The server creates a bootstrap Session and completes the two-way MWS_SESSION_INFO exchange. This Session provides the environment in which a Session selector can communicate with the Portal. 5. MWS_SESSION_RESUME_OFFER (type=100) -- Server -> Portal Lists the authenticated user's resumable Sessions. The server sends this Message even when the list is empty. Its payload is defined in Section 5.2.2. 6. Session selection -- Portal -> Server The Portal selects with MWS_SESSION_NEW_REQUEST (type=104) or MWS_SESSION_RESUME_REQUEST (type=101). MWS_SESSION_NEW_REQUEST continues the bootstrap Session. MWS_SESSION_RESUME_REQUEST replaces it with the selected Session. 7. Resumed Session establishment When an existing Session was selected, the peers perform a new two-way MWS_SESSION_INFO exchange for that Session before its state is reconstructed. MWS_SESSION_INFO (type=004) -- Server <-> Portal For each exchange, the Server MUST send this Message first. The Portal MUST reply with exactly one MWS_SESSION_INFO carrying the same Session identifier and its own receive limits. The same exchange establishes the bootstrap Session and a resumed Session. Payload format: session_id 4-octet unsigned integer max_payload_size 4-octet unsigned integer max_user_message_size 4-octet unsigned integer receive_mtu 4-octet unsigned integer render_limit_bytes 8-octet unsigned integer render_limit_presents 4-octet unsigned integer render_rate_hint_kbps 4-octet unsigned integer playback_min_rate_hz 4-octet unsigned integer playback_max_rate_hz 4-octet unsigned integer playback_channels_formats 4-octet unsigned integer capture_min_rate_hz 4-octet unsigned integer capture_max_rate_hz 4-octet unsigned integer capture_channels_formats 4-octet unsigned integer All fields are in network byte order. session_id is assigned by the Server and MUST be non-zero. max_payload_size is the largest payload of a complete logical MWS Message the sending endpoint will accept. It MUST be at least 56 and MUST NOT exceed 4294967295. max_user_message_size includes the complete outer MWS header and payload carried in one SCTP user message. It MUST be at least 68 octets, sufficient for an unfragmented MWS_SESSION_INFO. The Session-info payload length MUST be exactly 56 octets. receive_mtu is the largest SCTP packet, in the path-MTU units defined by [RFC6458], that the endpoint can receive without IP fragmentation. A value of zero means unknown. An endpoint uses the smaller of its own SCTP path estimate and the peer's non-zero receive_mtu for that association. This field does not limit the size of a logical MWS Message or SCTP user message. In the Server-to-Portal form, render_limit_bytes, render_limit_presents, render_rate_hint_kbps and the six Audio fields MUST be zero. In the Portal-to-Server form, render_limit_bytes and render_limit_presents declare the maximum Render work the Portal can safely have outstanding on this association while retaining sufficient capacity for Control, status and recovery. Both limits MUST be non-zero. The Server MUST NOT exceed either limit. render_rate_hint_kbps is the Portal's advisory initial Render rate in kilobits per second, or zero when unknown. It MAY be derived from the interface selected by the route to the Server. It is neither an end-to-end capacity guarantee nor an admission limit. The Server MAY use it to choose an initial pace but MUST remain within the declared Render flight and SHOULD refine pacing from MWS_SESSION_STATUS. When the Server also knows the advertised rate of its route-selected interface, it MUST NOT pace Render above the lesser non-zero endpoint rate. Subsequent status may reduce the working rate below that ceiling but does not increase the endpoint link hint. The playback fields declare the inclusive PCM sample-rate envelope, maximum interleaved channel count and sample formats which the Portal can play. The capture fields declare the corresponding envelope for a Portal-attached capture device. In each channels_formats field, the high 16 bits contain the channel count and the low 16 bits contain the format set. Bit zero advertises S16, bit one S24 and bit two F32. An implementation MUST omit a format unsupported in that direction. All three fields for an unsupported direction MUST be zero. For a supported direction, the rate bounds, channel count, and format set MUST be non-zero, the maximum rate MUST be at least the minimum rate, and undefined format bits MUST be zero. An endpoint MUST NOT send a logical payload larger than the peer's declared max_payload_size or a complete outer MWS Message larger than the peer's declared max_user_message_size. The advertised value MUST also conform to the DTLS-over-SCTP profile defined by [I-D.6083BIS]. A max_user_message_size smaller than 68 is a protocol error and terminates Session establishment. In the absence of a negotiated DTLS extension increasing the plaintext record limit, max_user_message_size MUST NOT exceed 2^14 octets. Transport fragmentation therefore permits a logical MWS payload to remain larger than one DTLS record without changing the ordinary Message seen by its sender or recipient. Other presentation, input, and subsystem capabilities are negotiated by their respective protocol Messages after this base Session exchange. The Render-flight fields above are the explicit admission envelope, not implicit implementation defaults. For a new Session, establishment completes after the server has received and accepted the Portal's bootstrap MWS_SESSION_INFO. The bootstrap Session is then ACTIVE and can run the Session selector, including its Window, Input, Render, and Audio traffic, while the selection offer remains outstanding. MWS_SESSION_NEW_REQUEST ends selection without repeating establishment. For a resumed Session, the server then sends MWS_SESSION_RESUME_COMPLETE as defined in Section 5.2.2; establishment completes when that Message is sent. Ordinary traffic for a resumed Session MUST NOT be processed before that boundary. Before bootstrap establishment, either endpoint MUST reject non-handshake traffic. From the Server's target Session-info Message through resumption completion, only that exchange, the reconstruction sequence, and fatal error handling are permitted on Stream 0. Section 5.2.2.1 defines how in-flight bootstrap traffic is drained before the association changes Session. 5.2.1.1. Session Identifier Semantics The session identifier returned in MWS_SESSION_INFO is assigned solely by the server. Portals MUST treat this value as opaque and MUST NOT attempt to select, predict, or construct session identifiers. All portal-originated messages that include a session_id field convey no routing authority. The Server validates ordinary traffic against the attached Session and resumption requests against the outstanding offer, as defined in Section 4.7.1. A portal MUST NOT assume that a session identifier remains valid across reconnects unless the server has explicitly offered the session for resumption. An identifier assigned to a live, detached, or grace-period Session MUST NOT be reused. A server that reuses an identifier after its former Session has terminated MUST ensure that no association, resume offer, or retained protocol state can still refer to the former Session. Possession of a session identifier alone never conveys authority. MWS_SESSION_INFO does not carry a resume token. Resumable Sessions are advertised explicitly with MWS_SESSION_RESUME_OFFER after fresh authentication. 5.2.2. Session Management (100-199) Session resume allows a portal to reattach to an existing session previously detached by the user or preserved during the reconnection grace period. MWS_SESSION_RESUME_OFFER (type=100) -- Server -> Portal After bootstrap establishment, lists the Sessions that the already authenticated user may resume. Payload format: session_count 2-octet unsigned integer repeated session_count times: session_id 4-octet unsigned integer All fields are in network byte order. session_count MAY be zero. Every listed session_id MUST be non-zero and MUST appear at most once. An offer authorises a resumption request only on the association on which it was sent and only until Session selection succeeds or the association ends. MWS_SESSION_RESUME_REQUEST (type=101) -- Portal -> Server Requests resumption of one Session from the preceding offer. Payload format: session_id 4-octet unsigned integer session_id is in network byte order and MUST identify a Session in the preceding offer. MWS_SESSION_RESUME_COMPLETE (type=102) -- Server -> Portal Confirms that Session resumption and state reconstruction are complete. This Message has no payload. A non-zero payload length is a protocol error. MWS_SESSION_DETACH (type=103) -- Portal -> Server Requests deliberate detachment of the current Session. This Message has no payload; the Session is identified by the authenticated association on which the Message arrives; the common MWS header contains no Session identifier. A non-zero payload length is a protocol error. On accepting the request, the server MUST preserve the Session and its Clients for later resumption subject to local policy, and detach the Portal. The Server MAY continue executing the Clients or MAY suspend them while detached. The detached association MUST NOT retain authority to send Session traffic. MWS_SESSION_DETACH does not terminate the Session. MWS_SESSION_NEW_REQUEST (type=104) -- Portal -> Server Selects the existing bootstrap Session as the user's new Session. This Message has no payload. A non-zero payload length is a protocol error. MWS_SESSION_STATE_BEGIN (type=105) -- Server -> Portal (Portal association) Begins reconstruction of a resumed Session. The Portal MUST discard any presentation state retained for the Session before accepting the reconstruction sequence in Section 5.2.2.1. Payload format: window_count 4-octet unsigned integer window_count is in network byte order and declares the exact number of Windows in that sequence. Each is introduced by one MWS_WINDOW_CREATED and followed by the metadata Messages specified in Section 5.2.2.1. window_count MAY be zero. The payload length MUST be exactly four octets. MWS_SESSION_STATUS (type=106) -- Portal -> Server (Portal association) Occasionally reports cumulative Session rendering progress. This unsolicited control-plane Message is inspired by Saratoga STATUS [SARATOGA]: rendering proceeds within a bounded unconfirmed horizon rather than requiring an acknowledgement for every presentation. The payload is: status_epoch 8-octet unsigned integer retired_sequence 8-octet unsigned integer retained_bytes 8-octet unsigned integer render_limit_bytes 8-octet unsigned integer retained_presentations 8-octet unsigned integer render_limit_presentations 8-octet unsigned integer render_state 4-octet unsigned integer reserved 4-octet unsigned integer status_epoch starts at 1 and increases for each snapshot on the current Session attachment. retired_sequence starts at zero. retired_sequence is the highest Session render sequence through which no work still consumes Portal capacity. A presentation is retired after it has been presented, deliberately superseded, or made stale by newer current state. It does not acknowledge every intervening frame. retained_bytes and retained_presentations report work currently owned by the Portal. render_limit_bytes and render_limit_presentations are absolute safe ceilings offered by the Portal. The Server MUST NOT admit Render work which would exceed either ceiling. A later snapshot may tighten a ceiling while already admitted work drains. render_state is 0 for healthy, 1 for constrained, 2 for drain-only and 3 when the Portal cannot make Render progress. reserved MUST be zero. Every integer is in network byte order. retired_sequence MUST NOT exceed a sequence sent on the current association. Snapshots whose status_epoch is not newer than the last accepted epoch MUST be ignored. A newer snapshot MUST NOT reduce retired_sequence. Epochs and Render sequences MUST NOT wrap; a new association is required before exhaustion. Both reset on Session replacement. The Server MUST retain enough sequence-to-message-length state to convert the cumulative report into released byte credit. It SHOULD use retirement progress and retained work to learn a conservative healthy rate, then pace later Render admission within the hard safe ceilings in the latest accepted status, initially established by MWS_SESSION_INFO. Status is not a prerequisite for the first frame and MUST NOT be sent in response to each Render presentation. The Portal MUST eventually send a status snapshot when retirement releases credit, even if no further Render work arrives; otherwise a sender at its limit could stall forever. MWS_SESSION_STATUS MUST be sent reliably and in order on Stream 0 and MUST be prioritised over bulk rendering. A status report MUST NOT wait for bulk Render processing. Byte credit counts the complete logical Message (12-octet MWS header plus payload), excluding DTLS/SCTP and fragmentation overhead. A presentation consumes one presentation credit. Credit is reserved before transmission and released only by cumulative retirement. Decoded images and reassembly also require locally bounded storage; wire byte credit is not a decoded-memory limit. Server-side application launch allows a Portal to request that the Server start a Client under the authenticated Session. For example, radialblur is the Client when requested and run this way. MWS_EXEC_REQUEST (type=110) -- Portal -> Server Requests execution of a program under the current Session. Payload format: request_id 4-octet unsigned integer exec_flags 2-octet unsigned integer argument_count 2-octet unsigned integer arguments argument_count argument fields Each argument field has this format: argument_len 2-octet unsigned integer argument argument_len octets request_id MUST be non-zero and identifies this request within the Session. Each response Message caused by this request MUST carry the same request_id. A Portal MUST NOT reuse a request_id while the corresponding request remains outstanding. The Server MUST reject a duplicate outstanding request_id. request_id is correlation data only and conveys no authority over a Client or any other Session resource. Each argument is a UTF-8 string without a terminating NUL and MUST NOT contain U+0000. The following exec_flags values are defined: 0x0001 RETURN_STDOUT 0x0002 RETURN_STDERR RETURN_STDOUT requests that the Server return the Client's standard-output stream to the Portal. RETURN_STDERR requests the corresponding standard-error stream. The values are protocol flags rather than file-descriptor numbers; their correspondence with POSIX descriptors 1 and 2 is mnemonic. Flags may be combined. Undefined bits are reserved and MUST be zero. When argument_count is non-zero, the first argument names the program and MUST NOT be empty. Subsequent arguments MAY be empty. An argument_count of zero requests the Server's default Session program; the reference implementation uses mwsdm. This distinguishes an explicit default-program request from the absence of a request. argument_count MUST NOT exceed 65535; argument_len MUST NOT exceed 65535 octets; and the complete payload MUST NOT exceed 65535 octets. Argument boundaries are significant. The Server MUST pass the decoded arguments directly to the requested program without joining them into a command line or invoking a command-language interpreter. This argument-vector model follows the exec family specified by POSIX.1-2024 [POSIX-EXEC]. The Server resolves and launches the named program according to local policy. It MUST reject a request which exceeds the host's argument and environment limit. Environment changes are not defined by this version. MWS_EXEC_RESULT (type=111) -- Server -> Portal Reports that the program requested by MWS_EXEC_REQUEST has terminated or could not be launched. Payload format: request_id 4-octet unsigned integer kind 1-octet unsigned integer flags 1-octet unsigned integer reserved 2-octet unsigned integer code 4-octet unsigned integer diagnostic_len 1-octet unsigned integer diagnostic diagnostic_len octets request_id MUST identify the corresponding MWS_EXEC_REQUEST. Multi-octet integers are in network byte order. diagnostic is an opaque variable-length field as defined in Section 2.6: diagnostic_len gives its exact length and the octets follow immediately, without a terminator. reserved MUST be zero. kind is 0 when the program exited normally, 1 when it was terminated by a signal, and 2 when it could not be launched. code is respectively the exit status or signal number. It MUST be zero when kind is 2. A Portal MUST NOT infer a signal from an exit status. diagnostic is a bounded final sequence of output retained for an unsuccessful request when neither live output stream was requested. It MUST NOT exceed 255 octets and MUST be empty after successful execution or when either RETURN_STDOUT or RETURN_STDERR was requested. Bit 0 of flags indicates that further diagnostic output was discarded; all other flag bits MUST be zero. The payload length MUST equal thirteen plus diagnostic_len. Servers MUST NOT include internal path, policy, loader, or other implementation details merely to explain a rejected launch. MWS_EXEC_STDOUT (type=112) -- Server -> Portal MWS_EXEC_STDERR (type=113) -- Server -> Portal Carries bytes read from the requested Client's standard-output or standard-error stream when the corresponding MWS_EXEC_REQUEST flag was set. Payload format: request_id 4-octet unsigned integer output remaining payload octets request_id MUST identify the corresponding MWS_EXEC_REQUEST. output is an opaque sequence of one or more octets; it is not necessarily UTF-8 and has no terminator. output MUST NOT exceed 4096 octets. Empty output Messages MUST NOT be sent. The Server MUST send output promptly as it reads it rather than retaining it until Client termination. Byte order is preserved independently within each output stream. The order between MWS_EXEC_STDOUT and MWS_EXEC_STDERR is the order in which the Server reads their chunks; no ordering of writes across the two Client streams is implied. These Messages use the reliable ordered Control stream. The Server MUST send every final output Message before the corresponding MWS_EXEC_RESULT. Output not requested by exec_flags MUST NOT be sent. An output Message MUST NOT contain bytes from another Client, request, or Session. Output pending when the association is lost MAY be discarded. MWS_CONFIG_QUERY (type=120) -- Client -> Portal Requests one desktop configuration value on demand. The Message crosses the Client Channel from Library to Server and the Portal association from Server to Portal. Payload format: application_id 4-octet unsigned integer request_id 4-octet unsigned integer namespace_len 2-octet unsigned integer key_len 2-octet unsigned integer namespace namespace_len octets key key_len octets A Client MUST set application_id to zero. The Server MUST replace it with the non-zero Session-scoped identifier of the sending Application before forwarding the query. request_id MUST be non-zero and outstanding identifiers MUST be unique within that Application. namespace and key are non-empty UTF-8 strings without terminators and MUST NOT exceed 255 octets each. Names use the freedesktop.org Settings vocabulary [XDG-SETTINGS] where applicable. A Portal MUST expose only supported configuration values; this Message is not a general D-Bus or native desktop API proxy. XDG Desktop Portal is a local desktop service, distinct from an MWS Portal. An MWS Portal can consult its Settings interface to obtain supported preferences. MWS does not require D-Bus, an XDG service, or a particular desktop environment at either endpoint. Desktop-specific extensions are not universal XDG settings. MWS_CONFIG_RESULT (type=121) -- Portal -> Client Reports the outcome of MWS_CONFIG_QUERY through the Server. Payload format: application_id 4-octet unsigned integer request_id 4-octet unsigned integer status 2-octet unsigned integer value_type 2-octet unsigned integer value_len 4-octet unsigned integer value value_len octets application_id and request_id MUST equal the values in the query. The Server MUST deliver the result only to that Application. status is 0 for success, 1 not found, 2 unavailable, 3 not supported, or 4 invalid. An unsuccessful result MUST use value_type 0 and an empty value. Successful value types are 1, an unsigned 32-bit integer; 2, UTF-8 text; and 3, three unsigned 16-bit red, green and blue components. All integers use network byte order. value_len MUST NOT exceed 4096 octets and MUST exactly match the remaining payload. These Messages use the reliable ordered Control stream. Desktop configuration MUST NOT be included speculatively in MWS_SESSION_INFO; a Client requests only values it needs. 5.2.2.1. Resume Semantics A session becomes resumable when the user has explicitly detached it or when the transport association (for example, an SCTP association) has been lost and the session has entered the reconnection grace period defined in Section 4.8. The server MUST NOT offer resumption for sessions that have been terminated or reclaimed by policy. After successful user authentication, the server MUST send exactly one MWS_SESSION_RESUME_OFFER (type=100), after the bootstrap MWS_SESSION_INFO exchange. An empty offer tells the Portal that no resumable Session is available while preserving the same state-machine ordering in both cases. The Portal MUST answer with MWS_SESSION_NEW_REQUEST or MWS_SESSION_RESUME_REQUEST. Only one selection request may be outstanding. A rejected resume request MAY be followed by another selection request against the same offer. On MWS_SESSION_NEW_REQUEST, the bootstrap Session continues as the user's selected Session. It is not destroyed and recreated. To resume a session, the portal sends MWS_SESSION_RESUME_REQUEST (type=101) specifying the session identifier. The server MUST validate that the requested session: * belongs to the authenticated user * is currently resumable * is not attached to or reserved for another Portal Before sending MWS_SESSION_RESUME_REQUEST, the Portal MUST stop originating bootstrap Session traffic and wait for SCTP acknowledgement of all previously transmitted bootstrap Messages on every stream. The Server continues processing bootstrap traffic until that request arrives. If the request is rejected, bootstrap traffic may continue. If validation succeeds, the Server reserves the target Session and stops originating bootstrap traffic. It MUST finish sending queued bootstrap Messages, or discard unsent work, and wait for SCTP acknowledgement of transmitted bootstrap Messages before sending the target's MWS_SESSION_INFO. The Portal drains received bootstrap Messages before replying with the target's MWS_SESSION_INFO. Both endpoints MUST finish or discard queued bootstrap processing before changing Session context. This transition barrier prevents traffic without an explicit session_id from being interpreted in the resumed Session. Implementations MUST NOT infer a cross-stream barrier merely from Stream 0 message ordering. After accepting the Portal's MWS_SESSION_INFO, the Server atomically replaces and destroys the bootstrap Session and cancels the target's reconnection grace timer. It takes a consistent snapshot of the target's Windows. This provisional binding authorises reconstruction only. The following logical Messages MUST be sent consecutively on Stream 0: 1. MWS_SESSION_STATE_BEGIN with the snapshot's Window count. 2. Exactly that many MWS_WINDOW_CREATED Messages, in bottom-to-top stacking order. Each carries the current Window identifier, extent, and title, with request_id zero to mark reconstruction. The Portal creates provisional, initially unmapped Windows. 3. For each Window in the same order: MWS_CONFIGURE_WINDOW, MWS_WINDOW_STATE, MWS_WINDOW_RELATION, MWS_WINDOW_ICON, and exactly one of MWS_MAP_WINDOW or MWS_UNMAP_WINDOW. These carry the current geometry, constraints, relationship, icon, and visibility. Default state is sent explicitly. All referenced parent Windows have already been introduced in step 2. 4. MWS_SESSION_RESUME_COMPLETE. MWS_SESSION_RESUME_COMPLETE is the commit boundary. The Portal MUST NOT expose partial reconstruction or originate ordinary resumed-Session traffic before receiving it. The Server attaches the Portal and marks the Session ACTIVE when sending it. Live changes made after the snapshot MUST follow that boundary. A fatal error may abort reconstruction at any point; no other unrelated logical Message may interrupt the sequence. Transport fragmentation wrappers do not count as intervening Messages. The Portal MUST reject a wrong count, a zero or duplicate Window identifier, a wrong Message order, invalid metadata, or a reference to a Window outside the snapshot. These are fatal protocol errors. On association loss before completion, partial Portal state is discarded, the reservation is released, and the target Session follows Section 4.8; a target not yet rebound retains its previous state and grace deadline. Render and Audio Messages can arrive before Stream 0's commit boundary. The Portal MUST retain such data within its advertised limits until reconstruction completes, or terminate on resource exhaustion. After reconstruction, the Server MUST establish complete pixel content before sending partial updates for each Window. The base Seat is re-established under Section 5.4; Audio streams are reopened under Section 5.6. Focus is determined afresh by the Portal's native focus events. Additional Seats, device enumeration, and output mappings require later extensions. If validation fails, the server MUST reject the request with MWS_ERROR_SESSION (type=702, fatal=0), MUST NOT alter the requested Session, and MUST NOT reveal the existence or attributes of Sessions belonging to other users. The Portal remains in Session selection state and MAY request a new Session or another Session from the same offer. At most one Portal may be attached to a Session at a time. The Server MUST reject competing requests once the target is reserved or ACTIVE. Forced takeover of an active Session is outside this base protocol. 5.2.3. Window Lifecycle (200-299) Window creation, destruction, mapping, and configuration are managed through the following Messages. A user action at a Portal does not make the Portal the owner of the resulting Window operation. Input is delivered to the workstation; the Client or server-side window-management policy then originates any required request. MWS_CREATE_WINDOW (type=200) -- Library -> Server (client channel) Reports the Client's request to create a new top-level Window within its Session. This Message is not sent on the Portal association. Payload format: request_id 4-octet unsigned integer width 4-octet unsigned integer height 4-octet unsigned integer title_len 1-octet unsigned integer title title_len octets request_id is a non-zero value selected by the Library to identify this request; it is not a definitive window_id. A Library MAY place a provisional Window identifier in this field, but the Server MUST treat it only as request correlation data. width and height are in pixels and MUST be non-zero. title is UTF-8 and is not NUL-terminated. The payload length MUST equal 13 + title_len. MWS_WINDOW_CREATED (type=201) -- Server -> Library (client channel) -- Server -> Portal (Portal association) Confirms Window creation and supplies its window_id and initial geometry. The response retains the identifying data from the original request so the Library can match concurrent requests; the Portal uses it to create the corresponding presentation surface. Payload format: window_id 4-octet unsigned integer request_id 4-octet unsigned integer width 4-octet unsigned integer height 4-octet unsigned integer title_len 1-octet unsigned integer title title_len octets window_id is assigned by the Session and MUST be non-zero. It is definitive: the Library MUST replace any provisional value with this identifier. Window addressing is scoped by the tuple (association_id, session_id, window_id), and only the Session may assign its window_id component. For ordinary creation, request_id, width, height, title_len, and title MUST be copied unchanged from MWS_CREATE_WINDOW. During resume reconstruction, request_id MUST be zero and the other fields describe the current Window, as in Section 5.2.2.1. The payload length MUST equal 17 + title_len. MWS_DESTROY_WINDOW (type=202) -- Library -> Server (client channel) Reports the Client's request to destroy a Window in its Session. This Message is not sent on the Portal association. Payload format: window_id 4-octet unsigned integer MWS_WINDOW_DESTROYED (type=203) -- Server -> Library (client channel) -- Server <-> Portal (Portal association) Reports that a Window has been destroyed. When destruction originates at the workstation, the Portal is notified over the Portal association. When the native Portal UI closes the presentation surface, the Portal reports that event and the Library translates the event for the owning Client. Payload format: window_id 4-octet unsigned integer MWS_MAP_WINDOW (type=204) -- Library -> Server (client channel) and Server -> Portal (Portal association) Reports that the Client requested a Window become visible. After accepting the Message, the Server sends it to the Portal. Payload format: window_id 4-octet unsigned integer MWS_UNMAP_WINDOW (type=205) -- Library -> Server (client channel) and Server -> Portal (Portal association) Reports that the Client requested a Window become hidden. After accepting the Message, the Server sends it to the Portal. Payload format: window_id 4-octet unsigned integer MWS_CONFIGURE_WINDOW (type=206) -- Portal -> Server (Portal association) -- Server -> Library (client channel) Reports geometry changes made by the Portal's native window system. During resume reconstruction only, this Message also travels Server -> Portal to restore retained geometry. The Portal defers any resulting native geometry notification until after MWS_SESSION_RESUME_COMPLETE. In ordinary operation, the Server delivers the Portal-originated Message to the Library, which translates it for the owning Client. Payload format: window_id 4-octet unsigned integer x 4-octet signed integer y 4-octet signed integer width 4-octet unsigned integer height 4-octet unsigned integer width and height are in pixels and MUST be non-zero. The payload length MUST be exactly 20 octets. MWS_FOCUS_WINDOW (type=207) -- Portal -> Server (Portal association) -- Server -> Library (client channel) Reports that a Window has gained or lost keyboard focus. The Server updates its authoritative focus state and notifies the Library, which translates the transition for the Client. Payload format: window_id 4-octet unsigned integer focused 4-octet unsigned integer focused MUST be zero when the Window lost focus and one when it gained focus. Other values are invalid. The payload length MUST be exactly 8 octets. MWS_SWAPCHAIN_REVOKED (type=208) -- Server -> Library (client channel) Indicates that a Window's swapchain has been revoked due to policy, timeout, or resource constraints. The Library must cause the Client to recreate its presentation resources and redraw the Window through ordinary graphical API semantics. Payload format: window_id 4-octet unsigned integer MWS_WINDOW_STATE (type=209) -- Library -> Server (client channel) -- Server -> Portal (Portal association) Reports the Client-selected state and size constraints of one Window. After accepting the Message, the Server records the state and sends it to the Portal. The Server also sends the current state of every live Window while reconstructing a resumed Session. Payload format: window_id 4-octet unsigned integer flags 4-octet unsigned integer minimum_width 4-octet unsigned integer minimum_height 4-octet unsigned integer maximum_width 4-octet unsigned integer maximum_height 4-octet unsigned integer Bit 0 of flags is FULLSCREEN. When set, the Portal enters its native fullscreen state and reports the resulting extent using MWS_CONFIGURE_WINDOW so the Client can render at that native resolution. Bit 1 of flags is FULLSCREEN_SCALED. It is valid only when FULLSCREEN is also set. The Portal then retains the Client's logical content extent, aspect-fits it into the native fullscreen extent, and maps absolute Input coordinates back into the Client's logical coordinate space. Scaling applies equally when the native extent is larger or smaller than the Client content. All other flag bits MUST be zero. A zero minimum or maximum dimension means that no bound is specified on that axis. Equal non-zero minimum and maximum dimensions describe a fixed-size Window. When both bounds on an axis are non-zero, the minimum MUST NOT exceed the maximum. Fullscreen temporarily suspends these constraints. The payload length MUST be exactly 24 octets. MWS_WINDOW_RELATION (type=210) -- Library -> Server -> Portal (client channel, then Portal association) Describes a Window's role and its relationship to an optional parent Window. The Server validates and retains the relationship before forwarding it to the Portal. Payload format: window_id 4-octet unsigned integer parent_id 4-octet unsigned integer role 4-octet unsigned integer flags 4-octet unsigned integer x 4-octet signed integer y 4-octet signed integer role is 0 for an independent top-level Window, 1 for a transient Window, and 2 for a popup. Other values are invalid. Bit 0 of flags requests modal treatment; all other bits MUST be zero. For role 0, parent_id and flags MUST be zero. For roles 1 and 2, parent_id MUST identify a different live Window owned by the same Application in the same Session. Cyclic relationships MUST be rejected. The payload length MUST be exactly 24 octets. For a related Window, x and y are offsets in pixels from its parent's content origin. For role 0, they are advisory Portal placement coordinates. Native placement and modal behaviour remain subject to Portal policy and MUST NOT confer authority over unrelated Windows or the Portal desktop. A new Window is independent until a valid relationship is received. Removing a parent MUST also remove or clear relationships which refer to it. MWS_WINDOW_TITLE (type=211) -- Library -> Server (client channel) -- Server -> Portal (Portal association) Replaces the user-visible UTF-8 title of an existing Window. This Message permits titles assigned or changed after native Window creation to reach the Portal without recreating that Window. Payload format: window_id 4-octet unsigned integer title_len 2-octet unsigned integer title title_len octets title is well-formed UTF-8 without a terminator and MUST NOT exceed 255 octets. An empty title is valid. The payload length MUST equal 6 + title_len. The Server MUST verify that the sending Application owns window_id before recording and forwarding the replacement. MWS_WINDOW_ICON (type=212) -- Library -> Server -> Portal Replaces the icon of an existing Window. The Server MUST verify that the sending Application owns window_id before retaining and forwarding the replacement. This is Window metadata, not Render content, and travels on the Control stream. Payload format: window_id 4-octet unsigned integer edge 2-octet unsigned integer reserved 2 octets, MUST be zero rgba edge * edge * 4 octets The image is square, top row first, tightly packed, with channel octets R,G,B,A and straight (not premultiplied) alpha. edge MUST NOT exceed 256. This wire limit bounds Window metadata separately from arbitrary-size Render content. The exact payload length is 8 + edge * edge * 4. edge zero, with no pixels, restores the Portal's Mercurius fallback icon. New Windows use that fallback until an icon is supplied. Recipients MUST reject malformed extents and reserved bits before interpreting or allocating pixel storage. The Portal MAY adapt the icon to native decoration facilities. A native environment without per-Window icon support MAY retain its default icon. Icon updates MUST NOT change Application identity, focus, geometry or authority. Recreated Window identities need a new icon Message; hiding or resizing a Window does not clear it. Examples of native integration are the X11 _NET_WM_ICON property [EWMH] and the optional Wayland xdg-toplevel-icon-v1 protocol [XDG-ICON]. These are local presentation mechanisms, not MWS wire encodings. The Portal converts the validated RGBA pixels to the native format; no remote filesystem path or desktop icon name needs to be resolved. Compositor support and policy determine whether a native icon is displayed. Every multi-octet field above is in network byte order. Except for MWS_CREATE_WINDOW, every Window lifecycle payload begins with a non-zero window_id. A recipient MUST reject an incorrect payload length, a zero identifier, invalid UTF-8, or a Window outside the permitted Session scope. 5.2.3.1. Window Identifier Scope Window identifiers are scoped to the Session that created them. A Portal MUST NOT reference, manipulate, or query Windows belonging to any other Session. For every wire Window Message received from a Portal association, the server MUST validate that the window_id belongs to the Session associated with that SCTP association. If a portal attempts to reference a window outside its session, the server MUST reject the message with MWS_ERROR_SESSION (type=702, fatal=0). The server MUST NOT reveal the existence, geometry, focus state, or any other attributes of windows belonging to other sessions. A window_id MUST be unique among live Windows in its Session. The same numeric value MAY occur in another Session because the Session context is part of the Message address. The server MUST never resolve a window_id outside the Session selected by the authenticated association, regardless of numeric equality. These rules ensure that windows are private to the session that owns them and that portals cannot observe or interfere with the graphical state of other users. 5.3. Rendering Messages (300-399) Portal-association rendering Messages are delivered on SCTP stream 1. Client-channel rendering Messages are exchanged between the Library and the Server. Each is validated against the Window and resources belonging to the addressed Session. MWS_RENDER_PRESENT (type=300) -- Server -> Portal (Portal association) Presents a rendering update on the Portal. The server sends portal-ready rendering data for the addressed Window. Payload format: window_id 4-octet unsigned integer x 4-octet signed integer y 4-octet signed integer width 4-octet unsigned integer height 4-octet unsigned integer damage_x 4-octet unsigned integer damage_y 4-octet unsigned integer damage_width 4-octet unsigned integer damage_height 4-octet unsigned integer buffer_size 4-octet unsigned integer encoding 4-octet unsigned integer data_size 4-octet unsigned integer generation 8-octet unsigned integer media_time 8-octet unsigned integer data data_size octets window_id, width, and height MUST be non-zero. x and y are the Window position in compositor coordinates. buffer_size MAY be zero, in which case the Message changes no pixel content and every damage field and data_size MUST be zero. Otherwise, damage_width and damage_height MUST be non-zero and the damage rectangle MUST lie wholly within width and height. encoding is 0 for uncompressed BGRA8888 data or 1 for a Zstandard frame [RFC8878] containing exactly buffer_size decompressed octets. Compressed frames MUST NOT require an external dictionary. data_size is the number of encoded data octets following the fixed header. A sender SHOULD use encoding 1 only when doing so reduces the total Message size. A receiver MUST reject an unknown encoding, malformed compressed data, or data which does not decode to exactly buffer_size octets. generation is the Session render sequence. It MUST be 1 at the start of each Session attachment and increase by one for every MWS_RENDER_PRESENT actually transmitted on the association, irrespective of the addressed Window. A queued presentation discarded before transmission consumes no sequence. media_time is the non-zero Workstation Session monotonic time, in nanoseconds, at which the Application submitted the image for presentation. It is captured before readback, compression, pacing, or network transmission and is interpreted as described in Section 5.6.1. For a geometry-only update, encoding MUST be zero; media_time records the Workstation time of that update. A non-zero pixel buffer is tightly packed BGRA8888 in VK_FORMAT_B8G8R8A8_UNORM byte order. Each row contains exactly damage_width * 4 octets and buffer_size MUST equal damage_width * damage_height * 4. For encoding 0, data_size MUST equal buffer_size. The payload length MUST equal 64 + data_size. A sender whose source image has a larger row stride MUST repack it before constructing this Message. MWS_RENDER_SYNC (type=301) -- Server -> Portal (Portal association) Requests synchronisation of rendering state on the portal. The server uses this command to ensure that the portal has retired all preceding MWS_RENDER_PRESENT work for the Window before processing later Render operations for it. This is a Portal-local barrier and has no reply; the Server observes cumulative progress through MWS_SESSION_STATUS. Control processing MUST remain responsive while this Render barrier is pending. Payload format: window_id 4-octet unsigned integer MWS_RENDER_DESTROY (type=302) -- Server -> Portal (Portal association) Requests destruction of rendering resources associated with a window or pipeline on the portal. The portal releases any corresponding portal-side rendering state when it is safe to do so. Payload format: window_id 4-octet unsigned integer MWS_RENDER_UPLOAD (type=303) -- Library -> Server (client channel) Provides new rendering content for a window's surface. The Library translates completed Client rendering into a bounded update to the Window's image data or GPU-resident resources on the Server. This Message does not cross the Portal association. Payload format: window_id 4-octet unsigned integer width 4-octet unsigned integer height 4-octet unsigned integer stride 4-octet unsigned integer buffer_size 4-octet unsigned integer media_time 8-octet unsigned integer pixels buffer_size octets Pixels are BGRA8888 in VK_FORMAT_B8G8R8A8_UNORM byte order. window_id, width, height, stride, buffer_size, and media_time MUST be non-zero. stride MUST be at least width * 4. buffer_size MUST equal stride * height, and the payload length MUST equal 28 + buffer_size. media_time has the same meaning as in MWS_RENDER_PRESENT and MUST be preserved by the Server. Arithmetic validation MUST detect overflow. MWS_RENDER_DAMAGE (type=304) -- Library -> Server (client channel) Replaces one rectangular region of the Window's retained canonical image. A complete MWS_RENDER_UPLOAD MUST establish that image before the first MWS_RENDER_DAMAGE. The update and its rectangle are one atomic Message; damage never describes a later Message. Payload format: window_id 4-octet unsigned integer surface_width 4-octet unsigned integer surface_height 4-octet unsigned integer damage_x 4-octet unsigned integer damage_y 4-octet unsigned integer damage_width 4-octet unsigned integer damage_height 4-octet unsigned integer stride 4-octet unsigned integer buffer_size 4-octet unsigned integer media_time 8-octet unsigned integer pixels buffer_size octets Every dimension, stride, buffer_size, and media_time MUST be non-zero. The damage rectangle MUST lie wholly within the surface. Pixels are tightly packed BGRA8888 in VK_FORMAT_B8G8R8A8_UNORM byte order; stride MUST equal damage_width * 4, buffer_size MUST equal stride * damage_height, and the payload length MUST equal 44 + buffer_size. The surface dimensions MUST equal those of the retained image. A receiver which has no retained image, or whose retained extent differs, MUST reject the update without changing its retained content. MWS_RENDER_FENCE (type=305) -- Library <-> Server (client channel) Reserved for synchronising rendering progress. Its payload and semantics are not defined by this version. A sender MUST NOT emit this Message until a later specification defines it. A partial update MUST NOT be applied without a retained complete image of the same extent. The first pixel update after creation, resize, resource destruction, or resume MUST cover the complete Window image. Superseding an update is permitted only when later retained content includes its effects. In particular, dropping an independent damage rectangle must not erase changes needed by a later partial update. A Portal MUST handle cross-stream arrival without assuming that a Window creation on Stream 0 is processed before its Render data. It may retain early data within its limits until creation is processed. A destroyed Window's in-flight Render data is discarded and retired. Window identifiers MUST NOT be reused on the same Session attachment. Every multi-octet field above is in network byte order. Every defined rendering payload begins with a non-zero window_id. A recipient MUST reject an incorrect payload length, inconsistent geometry or buffer size, arithmetic overflow, or a Window outside the permitted Session. 5.4. Input Plane (400-499) -- Stream 2 SCTP Stream 2 is reserved for Input Plane Messages. Portal-to-server Messages describe seat-scoped events without coupling the protocol to a particular Portal window system. Client-to-Portal Messages request Window-scoped input behaviour through the authoritative server. This version defines pointer focus, ordinary pointer motion, pointer-button transitions, physical-key transitions, and pointer modes. Other device classes retain the common event envelope but require later definitions of their event data. MWS_INPUT_EVENT (type=400) -- Portal -> Server Delivers an input event from an authorised Seat. Payload envelope: window_id 4-octet unsigned integer seat_id 4-octet unsigned integer device_id 4-octet unsigned integer sequence 4-octet unsigned integer timestamp_ms 4-octet unsigned integer event_type 2-octet unsigned integer event_data_len 2-octet unsigned integer event_data event_data_len octets window_id identifies the destination Window within the Session. seat_id identifies the Seat within the authenticated Session. device_id identifies an input device attached to that Seat. None of these Portal-provided identifiers confers authority: the server MUST resolve all three within the Session bound to the association and MUST reject an unauthorised or unknown value. sequence is scoped to the Portal association. It MUST begin at a non-zero value, increase for every emitted Input event, and skip zero when it wraps. Ordering uses the 32-bit serial-number arithmetic of [RFC1982]; an ambiguous half-range difference is invalid. The receiver MUST reject a duplicate or older sequence. timestamp_ms is the low 32 bits of a monotonic Portal-local millisecond clock. It establishes timing between events from that Portal and is not wall-clock time. event_type selects the interpretation of event_data. The payload length MUST equal 24 + event_data_len. Unknown event types MUST be rejected unless a negotiated extension defines them. MWS_INPUT_ACK (type=401) -- Server -> Portal Acknowledges an input event when its event class requires an explicit acknowledgement. This version defines no event requiring an acknowledgement; a sender MUST NOT emit MWS_INPUT_ACK. MWS_INPUT_POINTER_MODE (type=402) -- Client -> Server -> Portal Requests pointer behaviour for a Window owned by the Client. Payload: window_id 4-octet unsigned integer modes 4-octet unsigned integer window_id identifies the Window within the Session. The server MUST verify that the sending Client owns that Window before forwarding the Message. A Portal MUST NOT treat this request as authority over another Window or over the Portal desktop. modes is a bit mask. Bit zero requests relative pointer motion, bit one requests confinement to the Window, and bit two requests that the native pointer image be hidden while the Window has focus. Bits three through 31 MUST be zero. A zero value releases all requested pointer behaviour. Pointer behaviour is Window-scoped and active only while that Window has focus. The Portal MUST release native confinement and restore its pointer image when focus is lost, the Window is unmapped or destroyed, or the Session ends. Portal policy and an unconditional Portal-local escape mechanism take precedence over a Client request. seat_id MUST be non-zero and unique among the live Seats in its Session. device_id MUST be non-zero and unique among the live input devices attached to that Seat. Both identifiers are opaque protocol values except for the following base assignments. After Session establishment, the Server and Portal use Seat 1, logical pointer device 1, and logical keyboard/text device 2. These are Session-scoped logical devices, not physical hardware identifiers. Pointer events MUST use device 1; keyboard and TEXT events MUST use device 2. A Portal may aggregate native devices into those logical devices. This revision defines no wire exchange to create additional Seats or devices; such identifiers MUST NOT be used without an applicable extension. On detach, association loss, or resume, the Server MUST clear held keys, buttons, and focus from the old attachment. The resumed Portal starts with fresh device state and sequence numbering. Input Messages in this revision MUST use reliable, ordered delivery on Stream 2. Coalescing is permitted only before transmission and only as specified below. The Server forwards accepted events on the owning Application's client channel; pointer-mode requests travel Library -> Server -> Portal. The base Input Plane and any future extensions MUST satisfy the following requirements where applicable: * An extension adding device discovery MUST describe capabilities, identity, attachment to a Seat, hot-plug, and removal without coupling MWS to a particular Portal operating system or input API. * The workstation MUST remain authoritative for focus, routing, grabs, policy, and the interpretation of which Client and Window may receive an event. * Key transitions, button transitions, and other state-changing events MUST be delivered reliably and in order. They MUST NOT be discarded, coalesced, or reordered across one another. * Superseded pointer or tablet motion MAY be coalesced only when doing so cannot cross or alter the meaning of an intervening state-changing event. Both relative and absolute motion MUST be representable. * Events MUST carry sufficient sequencing and timing information to preserve their intended order and identify stale or invalid device state. Event batching MUST NOT change event semantics. * Physical key events MUST remain distinguishable from text entry and input-method composition. The protocol MUST NOT assume that a keyboard layout or input method is shared by both endpoints. * Device loss or Portal disconnection MUST resolve held keys, buttons, touches, and similar state without leaving input stuck in the workstation Session. * The vocabulary MUST be extensible to touch, tablet pressure and tilt, accessibility devices, and control surfaces without weakening the Session and Seat authority rules. * Where a device requires feedback, such as keyboard indicator or haptic state, the workstation-to-Portal direction MUST be represented explicitly and subject to the same Seat scoping. 5.4.1. Pointer Motion Events Pointer events use the following event_type values: 1 POINTER_MOTION 2 BUTTON_PRESS 3 BUTTON_RELEASE 7 POINTER_ENTER 8 POINTER_LEAVE Each carries this 20-octet event_data: x 4-octet unsigned integer y 4-octet unsigned integer delta_x 2-octet signed integer delta_y 2-octet signed integer buttons 4-octet unsigned integer button 2-octet unsigned integer reserved 2-octet unsigned integer x and y are unsigned Window-content-local pixel coordinates. delta_x and delta_y are signed changes since the preceding pointer event for this device. A zero delta reports no relative movement. buttons is the complete state after this event. Bit zero represents primary button 1, bit one middle button 2, and bit two secondary button 3; subsequent bits represent additional pointer buttons in ascending order. For BUTTON_PRESS and BUTTON_RELEASE, button identifies the changed button and MUST be in the range 1 through 32. For POINTER_MOTION, POINTER_ENTER, and POINTER_LEAVE, button MUST be zero. reserved MUST be zero. POINTER_ENTER reports that the pointer entered the Window content and POINTER_LEAVE reports that it left. These events are distinct from keyboard focus and MUST reflect the Portal's native pointer-focus transitions. They carry the pointer position and complete button state at the transition. Button and pointer-focus transitions MUST be delivered reliably and in sequence order. POINTER_MOTION may be coalesced only with later motion for the same Seat, device, and Window, and only when no button or other state-changing event intervenes. The resulting event MUST retain the newest absolute position and button state, and the sum of relative deltas. If that sum does not fit the signed fields, the events MUST remain separate. This version requires no MWS_INPUT_ACK for pointer events. 5.4.2. Keyboard Events Keyboard events use the following event_type values: 4 KEY_PRESS 5 KEY_RELEASE Each carries this 8-octet event_data: usage 4-octet unsigned integer modifiers 4-octet unsigned integer usage identifies the physical control using the extended Usage encoding defined by the USB HID Usage Tables [HUT17]. The most significant 16 bits contain the Usage Page and the least significant 16 bits contain the Usage ID. Both parts MUST be non-zero, and their combination MUST identify an assigned Usage in [HUT17]. This single namespace includes the Keyboard/Keypad Page, the Consumer Page used by media controls, and the other controls defined by that specification; MWS does not maintain a separate key registry. KEY_PRESS and KEY_RELEASE describe physical transitions and MUST remain distinct from text entry or input-method composition. A Portal MUST map its native input identifier to the corresponding HID Usage without assuming that the Portal and workstation share a keyboard layout. modifiers contains the complete modifier state accompanying the transition. Bits zero through seven correspond directly to the modifier byte in a USB HID keyboard report: Left Control, Left Shift, Left Alt, Left GUI, Right Control, Right Shift, Right Alt, and Right GUI, respectively. In keyboard layouts which define an AltGr modifier, Right Alt commonly supplies that function. Bits eight through 31 MUST be zero in this version. Key transitions MUST be delivered reliably and in sequence order. They MUST NOT be discarded, coalesced, or reordered. This version requires no MWS_INPUT_ACK for keyboard events. 5.4.3. Text Input Events Text input uses this event_type value: 6 TEXT event_data contains between 1 and 31 octets of well-formed UTF-8 text. It MUST NOT contain U+0000. A Portal MUST divide longer committed text into consecutive TEXT events at UTF-8 character boundaries. TEXT reports text committed by the Portal's active keyboard layout or input method. It is distinct from the physical KEY_PRESS and KEY_RELEASE events which may have contributed to that text. A Portal MUST perform layout selection, dead-key handling, compose processing, and input-method composition locally; the server MUST NOT infer text from HID Usages or assume that both endpoints share a keyboard layout. device_id identifies the keyboard or other text-input device associated with the commit. TEXT events MUST be delivered reliably and in sequence order. They MUST NOT be discarded, coalesced, or reordered. 5.5. Video Fallback (500-599) -- Stream 3 Video fallback is intended for a Window whose presentation is more appropriately represented as encoded video than as ordinary rendering updates. Stream 3 is reserved for that traffic so that loss or congestion does not block control or rendering Messages. MWS_AV1_FRAME (type=500) -- Server -> Portal Delivers an AV1-encoded video frame for presentation in a Window. MWS_PLACEHOLDER_FRAME (type=501) -- Server -> Portal Delivers a placeholder when current Window content is unavailable. This version does not define these payload encodings. A later specification MUST define Window and frame identity, dimensions, timestamps, AV1 configuration and random-access state, fragmentation, and the effect of loss or expiration on decoder state. It MUST define partial-reliability and ordering semantics that permit obsolete frames to be discarded without corrupting subsequent presentation. A sender MUST NOT emit either Video Plane Message until a later specification defines its payload encoding. 5.6. Audio Plane (600-699) -- Stream 4 The Audio Plane is intended to provide full-duplex, timestamped audio between workstation and Portal. Playback carries audio from the workstation to the Portal; capture carries audio from a Portal-attached device to the workstation. Stream 4 is reserved so that audio does not share control, rendering, input, or video traffic. Each logical audio stream has a 32-bit stream_id assigned by the Server. Application-local identifiers are translated at the Server when necessary to avoid collisions on the Portal association. A Session MAY have zero or more playback and capture streams. An opener proposes the stream parameters; the peer accepts or rejects them before any data is sent. MWS_AUDIO_PLAYBACK_OPEN (type=600) -- Server -> Portal Proposes a playback stream and its parameters. MWS_AUDIO_PLAYBACK_ACCEPT (type=601) -- Portal -> Server Accepts the proposed playback stream. MWS_AUDIO_PLAYBACK_REJECT (type=602) -- Portal -> Server Rejects the proposed playback stream. The server MUST NOT send playback data for the rejected stream_id. MWS_AUDIO_PLAYBACK_DATA (type=603) -- Server -> Portal Carries timestamped audio for an accepted playback stream. MWS_AUDIO_PLAYBACK_CLOSE (type=604) -- Server -> Portal Ends a playback stream and permits its resources to be reclaimed. MWS_AUDIO_PLAYBACK_CAPABILITIES (type=605) -- Server -> Library Repeats the Portal playback envelope from MWS_SESSION_INFO across the private client channel. This Message does not traverse the network association. It lets the Library reject unsupported playback-open requests before forwarding them to the Server. The payload contains minimum and maximum sample rates as two four-octet unsigned integers, followed by a two-octet maximum channel count and a two-octet set of sample formats. Every field is in network byte order and has the same meaning as its MWS_SESSION_INFO counterpart. MWS_AUDIO_PLAYBACK_OPEN has the following payload: Field Size Meaning ----------------- ------ ------------------------------------ stream_id 4 Non-zero proposed stream identifier sample_rate 4 Sample frames per second channel_count 2 Interleaved channels per frame sample_format 2 Sample representation (see below) frames_per_packet 4 Preferred packet duration in frames MWS_AUDIO_PLAYBACK_ACCEPT and MWS_AUDIO_PLAYBACK_REJECT each carry only the four-octet stream_id to which the reply applies. MWS_AUDIO_PLAYBACK_DATA has the following fixed header followed immediately by interleaved PCM sample data: Field Size Meaning ------------ ------ ----------------------------------------- stream_id 4 Accepted playback stream sequence 4 Monotonically increasing packet sequence frame_offset 8 First frame's offset from stream start frame_count 4 Complete sample frames in this Message media_time 8 Session monotonic time of the first frame samples variable Interleaved PCM sample data MWS_AUDIO_PLAYBACK_CLOSE carries only the four-octet stream_id. All integer fields are unsigned and in network byte order. A stream_id or sequence value of zero is invalid. A stream_id MUST be unique among all open or pending Audio streams in the Session. It MUST NOT be reused until the old stream and its queued data are retired. sequence starts at 1 and increases by one per DATA Message; the stream MUST be closed and reopened before sequence exhaustion. frame_offset uses sample frames as its timebase; the first DATA Message normally has frame_offset zero. Later Messages MUST begin at the end of the preceding Message's frame range. frame_count MUST be non-zero. Arithmetic overflow is invalid. DATA payload length MUST equal 28 plus the sample data size. media_time is a non-zero unsigned 64-bit count of nanoseconds on the Workstation Session media timeline. For a stream with start time T and sample rate R, the timestamp of frame offset F is T + floor(F * 1000000000 / R). The Portal MUST validate that timestamps and frame offsets describe one monotonic stream. Audio sample formats are identified using conventional shorthand widely used in digital audio APIs: * S16 -- signed 16-bit linear PCM (sample_format 1) * S24 -- signed 24-bit linear PCM (sample_format 2) * F32 -- IEEE 754 binary32 PCM [IEEE754] (sample_format 3) These identifiers correspond to formats commonly supported by ALSA, PulseAudio, PipeWire, CoreAudio, WASAPI, JACK and other audio subsystems. Implementations that do not support a given format MUST omit it from their advertised Audio capabilities. PCM sample values use little-endian wire representation; Audio header integers remain in network byte order. Signed PCM uses two's complement. S16 occupies two octets, S24 occupies three packed octets, and F32 occupies four octets. A Portal may pad S24 when passing it to a local audio API, but padding is not sent on the wire. The samples field therefore contains frame_count multiplied by channel_count and the selected format's wire width. Channels are interleaved in frame order. The meaning of channel positions is mono for one channel and left followed by right for two. For larger counts, channels are discrete, numbered in interleaving order from zero; no surround-speaker layout is implied by channel count. The Portal MUST either open a playback endpoint with exactly the proposed parameters and send MWS_AUDIO_PLAYBACK_ACCEPT, or send MWS_AUDIO_PLAYBACK_REJECT. It MUST NOT silently resample or change the channel layout. The server MUST NOT send DATA before ACCEPT or after CLOSE or REJECT. sample_rate, channel_count, and frames_per_packet MUST be non-zero. The rate, channel count, and sample format MUST fit the advertised capability envelope. The preferred packet duration is not a requirement to fill every packet; senders MUST fit each Message within the peer's receive limits. MWS_AUDIO_CAPTURE_OPEN (type=620) -- Server -> Portal Relays an Application request for a Portal capture stream and its exact parameters. MWS_AUDIO_CAPTURE_ACCEPT (type=621) -- Portal -> Server Accepts the proposed capture stream. The Server relays the answer to the Application across its private client channel. MWS_AUDIO_CAPTURE_REJECT (type=622) -- Portal -> Server Rejects the proposed capture stream. The Portal MUST NOT send capture data for the rejected stream_id. The Server relays the answer to the Application across its private client channel. MWS_AUDIO_CAPTURE_DATA (type=623) -- Portal -> Server Carries timestamped audio for an accepted capture stream. MWS_AUDIO_CAPTURE_CLOSE (type=624) -- Server -> Portal Relays the Application's request to end a capture stream and permits its resources to be reclaimed. MWS_AUDIO_CAPTURE_CAPABILITIES (type=625) -- Server -> Library Repeats the Portal capture envelope from MWS_SESSION_INFO across the private client channel. This Message does not traverse the network association. Its payload has the same layout as MWS_AUDIO_PLAYBACK_CAPABILITIES and describes capture rather than playback. Capture OPEN, ACCEPT, REJECT, DATA and CLOSE use the corresponding playback payload layouts above. Their stream identifiers occupy the same Session namespace. The Application opens and closes capture; the Portal accepts or rejects the exact parameters and originates DATA after acceptance. Later specifications may define clock-domain and drift handling, flow control, loss and device-removal semantics. No payload may depend on a programming-language type or host representation. All Audio Messages in this revision MUST use reliable, ordered delivery on Stream 4. Control of an Audio stream stays on Stream 4 with its DATA. The corresponding OPEN, ACCEPT, REJECT, DATA, and CLOSE Messages may also cross the owning Application's client channel via the Library; they never grant access to another Application's Audio stream. A receiver MUST reject DATA for an unknown or unaccepted stream, a wrong direction, an invalid format, an inconsistent length, or a non-monotonic frame range. Queues MUST be bounded per stream and per association. A sender unable to sustain playback within those bounds MUST close the stream instead of accumulating unbounded data. A Portal unable to sustain capture or receive playback MUST report MWS_ERROR_RESOURCE; if it cannot safely continue, it MUST make the error fatal and close the association. This revision has no Portal-originated per-stream stop Message. A recoverable error alone does not change stream state. CLOSE is valid for a pending or accepted stream. A reply already in flight when CLOSE was sent may be discarded for that closed stream. In-flight capture DATA sent before the Portal receives CLOSE may also be discarded. Detach or association loss ends the negotiated Portal streams; resumed Sessions MUST negotiate fresh OPEN/ACCEPT exchanges against the new Portal's capabilities before transmitting Audio DATA. 5.6.1. Session Media Timeline Playback Audio and Render presentation share one Session media timeline. Its values are unsigned 64-bit nanosecond counts obtained from a monotonic Workstation clock. They are neither UTC nor SMPTE timecodes, and the Portal is not required to synchronise its clock with the Workstation clock. A Portal maintains one mapping from the Workstation Session timeline to its own monotonic clock. The first timestamp received for either Audio or Render begins a bounded acquisition interval during which the other plane may arrive. Once established, the same mapping applies to both planes. The Portal presents each item at the corresponding Portal time, subject to bounded lateness and the applicable stale-work policy. Acquisition MUST be bounded. Audio-only and Render-only Sessions MUST begin without waiting indefinitely for an absent plane. When both planes are active, a Portal MAY briefly retain early work so their relative timing can be preserved. The server validates and routes timestamps but MUST NOT rewrite them or create a second server-side presentation clock. Capture is a separate clock domain. MWS_AUDIO_CAPTURE_DATA carries non-zero nanoseconds from a monotonic Portal capture clock; its frame-offset formula is the same as for playback, with T in that clock domain. The Server preserves those timestamps when delivering samples to the Library. This revision does not specify synchronisation of capture with the Workstation timeline; receivers MUST NOT compare those clocks as if they shared an epoch. 5.7. Protocol State Machine 5.7.1. Initial Connection portal server streams ====== ====== ======= MWS_QUERY -------------------------------------> Stream 0 MWS_AUTH_CHALLENGE <------- MWS_AUTH_RESPONSE -----------------------------> Stream 0 MWS_SESSION_INFO <---------(bootstrap session_id and server receive limits) MWS_SESSION_INFO ------------------------------> Stream 0 (bootstrap session_id and portal receive limits) MWS_SESSION_RESUME_OFFER <-- MWS_SESSION_NEW_REQUEST ------------------------> Stream 0 [bootstrap Session continues] 5.7.2. Session Resume portal server ====== ====== (DTLS/SCTP handshake) MWS_QUERY -------------------> <------------------ MWS_AUTH_CHALLENGE MWS_AUTH_RESPONSE -----------> <------------------ MWS_SESSION_INFO (bootstrap) MWS_SESSION_INFO ------------> <------------------ MWS_SESSION_RESUME_OFFER MWS_SESSION_RESUME_REQUEST --> <------------------ MWS_SESSION_INFO MWS_SESSION_INFO ------------> <------------------ MWS_SESSION_STATE_BEGIN <------------------ Window snapshot (Section 5.2.2.1) <------------------ MWS_SESSION_RESUME_COMPLETE 5.8. WSI Extension (Surface Creation) MWS describes a provisional Vulkan WSI integration for creating presentation surfaces associated with Mercurius Windows. The extension is an integration boundary used beneath the Library's transparent adaptation of an ordinary Client's native WSI calls. It does not require the Client to know about Mercurius, enable a Mercurius extension, include a Mercurius header, or call a Mercurius entry point. An MWS surface is created for a window that has previously been created by the Library after translating the Client's ordinary native Window operation. The Library exposes an opaque window token to the WSI implementation. Neither the token nor any SCTP stream, association, Session, or Window identifier is exposed to the Client. The declarations below use the C language conventions of the Vulkan specification. They illustrate a proposed Vulkan API binding, not an MWS wire format or an allocated Khronos extension. Registration is addressed in Section 5.8.2. typedef uint64_t VkMercuriusWindowTokenMWS; typedef VkFlags VkMercuriusSurfaceCreateFlagsMWS; typedef struct VkMercuriusSurfaceCreateInfoMWS { VkStructureType sType; const void* pNext; VkMercuriusSurfaceCreateFlagsMWS flags; VkMercuriusWindowTokenMWS windowToken; VkExtent2D initialExtent; } VkMercuriusSurfaceCreateInfoMWS; VkResult vkCreateMercuriusSurfaceMWS( VkInstance instance, const VkMercuriusSurfaceCreateInfoMWS* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface ); VkMercuriusWindowTokenMWS is opaque. Zero is not a valid token. The proposed flags field has no defined flags and is zero. Surface creation proceeds as follows: 1. An unmodified Client creates a native window and requests its ordinary platform Vulkan surface. 2. The Library translates the native Window operation into an MWS Window and associates it with an opaque Mercurius window token. 3. Beneath the intercepted native WSI boundary, the Library uses VK_MWS_surface and calls vkCreateMercuriusSurfaceMWS() with that token and the requested initial extent. 4. The Library resolves the token to the corresponding MWS Window and sends the surface creation request to the Server. 5. The Server validates the request against the Client and Session associated with the local client channel, then creates and binds the presentation surface for the corresponding Window. 6. The Client continues to perform ordinary Vulkan WSI operations, including vkGetPhysicalDeviceSurfaceCapabilitiesKHR(), vkGetPhysicalDeviceSurfaceFormatsKHR(), and vkCreateSwapchainKHR(). The Library transparently adapts those operations where required. Window tokens are valid only within the creating process and MUST NOT be serialised, persisted, or shared between processes. Their format is implementation-defined. The Library MUST treat each token as an uninterpreted value and MUST NOT expose it or derive Mercurius protocol identifiers, Session identifiers, stream identifiers, or transport information from it. The initialExtent field expresses the Client's preferred initial swapchain dimensions for the window. The server MAY clamp, adjust, or reject this request according to compositor policy and Vulkan surface capabilities. 5.8.1. Surface Binding and Session Validation The windowToken field in VkMercuriusSurfaceCreateInfoMWS is not authoritative. It is treated only as a request to bind a Vulkan presentation surface to a Window already known to the Library. The Library MUST maintain sufficient local state to associate each exported windowToken with the corresponding Mercurius window, rendering stream, and Library-managed presentation state. This state is internal to the Library and is not part of the Client's native WSI ABI. When the Server receives a WSI surface creation request, it MUST validate the request against the Client and Session associated with the local client channel and against the server-side state associated with the resolved Window. In particular: * The token MUST resolve to a Window owned by the Session to which the requesting Client belongs. * The resolved window MUST still exist and be eligible for presentation. * The Library-managed presentation state associated with the resolved Window MUST correspond to presentation resources owned by the requesting Client's Session. * The server MUST reject any request that attempts to bind a Vulkan surface to presentation resources not associated with the authenticated session. If validation fails, the server MUST reject the request with MWS_ERROR_SESSION (type=702, fatal=0). The server MUST NOT reveal the existence, geometry, ownership, visibility, or presentation state of windows belonging to other sessions. These rules ensure that Vulkan surface creation cannot be used to infer or access graphical resources belonging to another user while still permitting the Library to maintain the internal per-window state required for ordinary Vulkan applications. 5.8.2. Vulkan Extension Registration Vulkan extension names, structure types, and other Vulkan registry values are allocated by the Khronos Group. This document does not allocate them. The names used in Section 5.8 describe the required Library-to-Vulkan integration semantics and are provisional until the corresponding Vulkan extension is registered. Implementations MUST NOT infer or privately assign a Vulkan numeric value from this document. Once registered, the extension specification and Khronos registry are authoritative for the WSI integration ABI. Such registration does not alter the MWS wire protocol. The type VkMercuriusWindowTokenMWS is an opaque unsigned integer type used solely for Library-initiated surface creation. Its numeric value has no protocol meaning outside the Library. 5.9. Error Handling (700-799) Errors are six distinct MWS Message types: MWS_ERROR (type=700) An error for which no more specific type applies. MWS_ERROR_PROTOCOL (type=701) A malformed Message, unknown opcode, invalid state transition, wrong stream, or other violation of this specification. MWS_ERROR_SESSION (type=702) An invalid Session, Seat, Window, or other Session-scoped reference. MWS_ERROR_TRANSPORT (type=703) A failure while carrying a Message over the Transport. MWS_ERROR_POLICY (type=704) A request rejected by authentication, authorisation, compositor, or other local policy. MWS_ERROR_RESOURCE (type=705) A request that cannot be accepted because a required resource is unavailable or the peer's declared resource limit was exceeded. The error type is carried by the MWS header. It is not repeated in the payload. Every error Message has the following payload: in_reply_to 2-octet unsigned integer reserved 2-octet unsigned integer window_id 4-octet unsigned integer fatal 4-octet unsigned integer description_len 4-octet unsigned integer description description_len octets All integer fields are in network byte order. in_reply_to is the opcode of the Message whose processing produced the error, or zero when no decoded opcode is available. It lets the recipient associate the error with the failed operation; the error classification remains the type in the MWS header. reserved MUST be zero. window_id is the relevant Window identifier, or zero when the error does not concern a Window or disclosing its identifier would reveal information outside the peer's Session. fatal MUST be zero or one. description is an optional UTF-8 diagnostic without a terminating NUL; description_len MAY be zero. The payload length MUST equal 16 plus description_len. Error Messages MUST be sent reliably and in order on Stream 0. An endpoint MUST NOT answer an Error Message with another Error Message; malformed errors are discarded or cause association termination. Handshake failures and malformed framing or fragmentation are fatal. Other rejected operations may use a recoverable error unless their definitions require termination. Receipt of a recoverable error does not report the eventual outcome of any other accepted Message. It reports only that the indicated Message could not be accepted or completed by the object reporting the error. A fatal error requires the sender to close the association after attempting to transmit the error. If the association has already been lost, or the failed Message header cannot be parsed sufficiently to address a reply, no error Message can be sent. Recoverable errors (fatal=0) indicate that the indicated Message has been ignored and the session MAY continue. Fatal errors (fatal=1) indicate that the SCTP association MUST be closed immediately after transmitting the error, unless the error prevents the message from being parsed. Loss of the SCTP association for any reason (network failure, timeout, endpoint crash) is treated as a fatal error. The session MAY persist according to the rules in Section 4.8. All error payload fields follow the network-byte-order rules defined in Section 5.1. 5.9.1. Session and Resource Validation Errors The server MUST validate that all window_id, seat_id, and session_id fields in portal-originated messages refer to resources owned by the authenticated session associated with the transport association on which the Message was received. This does not require any particular internal table or association-ID type. The following conditions constitute session and resource validation errors (a subclass of semantic errors) and MUST be reported using MWS_ERROR_SESSION (type=702, fatal=0): * referencing a window belonging to another session * referencing a seat belonging to another session * attempting to bind a Vulkan surface to a window outside the authenticated session * attempting to create or bind a Vulkan surface using Library-managed presentation state that does not belong to the authenticated session * attempting to resume a Session not authorised by the outstanding offer, or to manipulate resources outside the attached Session * providing a session_id that does not match the authenticated session When reporting such errors, the server MUST NOT reveal the existence, geometry, focus state, or any other attributes of resources belonging to other sessions. The window_id field in the error message MUST be set to zero if revealing the true identifier would disclose cross-session state. These rules ensure that portals cannot infer the presence of other users, windows, or seats, and that all resource identifiers remain strictly scoped to the authenticated session. 6. Implementation Guidance This section is non-normative. It describes one way to organise an MWS implementation without requiring any programming language, operating system, toolkit, class hierarchy, or command-line interface. Conformance is determined solely by the normative requirements elsewhere in this document. 6.1. Endpoint Independence A Portal is an independent protocol endpoint. It need not share source code, data structures, graphics libraries, or an implementation language with the Server. For example, a Portal written in Rust or Ruby can interoperate with a Server written in C by implementing the framing, transport, state machines, payload encodings, and security requirements defined by this document. Protocol fields must be decoded from their specified wire representation. An implementation must not depend on C structure layout, host byte order, pointer size, alignment, enum representation, or private Server object types. Capitalised roles such as Portal, Server, Session, and Window name protocol concepts rather than required classes. 6.2. Portal Processing Model A Portal implementation will commonly perform the following operations: 1. Establish the authenticated Transport association and complete the Stream 0 handshake in the order specified by Section 5.2. 2. Record the negotiated Session identifier and both peers' receive limits from the two-way MWS_SESSION_INFO exchange. 3. Maintain independent receive processing for each allocated stream, while preserving the ordering requirements within each stream. 4. Maintain a Session-scoped table of Windows using only identifiers assigned by the Server. Create, configure, map, unmap, focus, and destroy native presentation resources in response to the applicable Window Messages. 5. Decode Render Messages on Stream 1 and deliberately supersede obsolete presentations where permitted. Maintain the highest contiguous retired Session render sequence and send MWS_SESSION_STATUS on Stream 0 without waiting for rendering or native display work. 6. Send input on Stream 2 using the Seat and Window identifiers belonging to the attached Session. Do not infer authority from identifiers alone. 7. On detach, association loss, or resume, discard or reconstruct local presentation state exactly as required by the Session state machine. A Portal may use threads, asynchronous tasks, an event loop, or another concurrency model. The observable Message ordering and prioritisation are the interoperability requirements. 6.3. Concurrency and Backpressure Control processing must remain available while rendering is slow or blocked. In particular, a Portal must be able to originate MWS_SESSION_STATUS, process errors, and respond to Session and Window lifecycle Messages without waiting for a native renderer to finish a presentation. Render flight limits constrain cumulative outstanding work; payload and user-message limits constrain individual Messages. None is a suggested allocation size. A Portal must advertise limits it can actually sustain and must account for fragmented Messages until they are completed or abandoned. Independent associations and Sessions must have independent state; a slow Session must not consume another Session's identifiers, progress frontier, or flow-control credit. Implementations should validate lengths and identifiers before allocation or dispatch. Bounded queues, checked arithmetic, explicit ownership, and timely disposal of superseded Render data are particularly important when Messages originate from an untrusted endpoint. 6.4. Version Scope An implementation may omit an optional facility, but it must not emit a Message whose payload this version leaves undefined. Reserved opcodes and streams remain reserved. Unknown or misplaced Messages are handled according to Section 5.9; an implementation must not guess their layout from an opcode range or from another implementation's private behaviour. This experimental revision changes wire formats from earlier drafts. It defines no revision-negotiation field. Deployments must configure both endpoints for this revision; the ALPN identifier alone does not establish draft-version compatibility. Implementers may use published source code and test programs as additional interoperability evidence, but such material does not extend or override this specification. 6.5. Reference Implementation Components The Mercurius reference implementation provides the following components. Their names and internal division are non-normative; an interoperable implementation may organise the same protocol roles differently. mwsd The Server daemon. It owns authoritative Session, Window, rendering, application-execution, and policy state and accepts Portal associations and local client channels. mwsc The Portal program. It authenticates to a Server, presents Session Windows through the native display system, and returns user interaction and Portal status to the Server. libmws/compat and libmws These divide the Library role defined in this document. libmws/compat supplies compatibility interposition for unmodified Clients; libmws supplies the underlying Mercurius protocol facilities. An ordinary Client such as radialblur neither calls Mercurius interfaces nor links directly against libmws. mwsdm The Session selector used when no Client command is specified. It runs in the authenticated bootstrap Session and allows the user to continue that Session as new or replace it with an eligible existing Session. mlogo A minimal demonstration Client deliberately linked against libmws. Inspired by xlogo, it is the "is this thing on?" proof of a Mercurius installation. Launching, displaying, resizing, and closing mlogo exercises the core Client launch, local client-channel, Window lifecycle, rendering, and Portal-association path without compatibility interposition. 6.6. Usage Examples This section is non-normative. It uses commands from the reference implementation to illustrate the MWS usage model. Other implementations may provide different user interfaces while producing the same protocol behaviour. These examples include the intended detach/resume workflow; they do not assert that every described facility is implemented in the current reference software. In particular, transport encryption and explicit detach/resume remain implementation work. Assume xavier.example is a workstation running an MWS Server, while flash and torch are devices acting as Portals. 6.6.1. SSH and MWS SSH and MWS provide complementary ways to use the same workstation: flash$ ssh alice@xavier.example uptime flash$ mwsc alice@xavier.example mlogo The first command runs a command-line program through SSH. The second asks the MWS Server to run a graphical Client in Alice's Session and present its Window on flash. MWS does not carry this connection over SSH; the similarity is the user-facing model of authenticating to a workstation and requesting a program there. 6.6.2. Session Selection Omitting a Client command requests the graphical Session selector: flash$ mwsc alice@xavier.example The Portal authenticates Alice before the bootstrap Session is established. The Server then runs mwsdm in that Session. Because the remote user is already authenticated, mwsdm does not request the credentials again. It offers Alice the choice of continuing the bootstrap Session as a new Session or replacing it with one of Alice's eligible existing Sessions. In a local-console deployment, the local Portal and Server perform the same protocol roles and still require authentication before establishing the bootstrap Session. A local login interface may collect credentials before that exchange; this does not grant an unauthenticated Session. 6.6.3. Detach and Resume Alice may explicitly detach a Session on flash and request either that its Clients continue executing or that they remain suspended, subject to Server policy. Later, from torch, Alice connects to the same workstation: torch$ mwsc alice@xavier.example After authentication, the Session selector offers the detached Session. If Alice resumes it, its server-resident Clients remain the same Clients and its Windows are reconstructed on torch; they are not restarted merely because a different Portal now provides the Seat. An unexpected network interruption is different from explicit detach. It places the Session in the bounded GRACE state described in Section 4.8 rather than granting indefinite lifetime. 6.6.4. Local and Remote Portals A Portal may be on the workstation itself or on another device. The reference Portal selects the local Transport when the named host is the workstation on which it is running, including when that host is named by its short hostname or by a fully qualified name which resolves to a local address. Local selection therefore does not require localhost or an explicit local option. For example, each of the following selects the local Transport: xavier$ mwsc -l mlogo xavier$ mwsc --local mlogo xavier$ mwsc localhost mlogo flash$ mwsc alice@flash mlogo flash$ mwsc alice@flash.example mlogo A remote Portal selects the network Transport: flash$ mwsc alice@xavier.example mlogo The protocol's Session, Window, and Seat semantics are identical in both cases. Local operation is not a separate window-system mode and does not imply a single console, Portal, Seat, or user. A workstation may serve multiple local users concurrently through independent local Portal associations, for example using displays and input devices attached through one or more USB-C docks. Each local association remains bound to its own authenticated Session and receives the same identifier, authority, and isolation treatment as a network association. 6.6.5. Independent Portals Several users or Sessions may use one Server concurrently: flash$ mwsc alice@xavier.example mlogo torch$ mwsc bob@xavier.example mlogo Each association has its own authenticated Session context, identifiers, flow-control state, and rendering progress. Slowness or failure at one Portal must not block control processing or reserve another Portal's capacity. 7. Implementation Requirements and Validation This section defines normative requirements for any conformant MWS implementation. These requirements ensure correct behaviour under load, predictable session semantics, and robust isolation between portals. 7.1. Test Matrix An implementation of MWS MUST demonstrate correct behaviour across four major dimensions: * Session semantics -- creation, resume, detachment, identifier stability, and state continuity. * Window lifecycle -- creation, mapping, resizing, destruction, and identifier scoping. * Rendering correctness -- surface creation, command ordering, GPU isolation, and frame delivery. * Transport behaviour -- SCTP stream allocation, ordering guarantees, error handling, and reconnection. The following matrix defines the minimum set of tests required to validate interoperability between an MWS portal and server. These tests are not exhaustive; they represent the baseline necessary to confirm that the architectural components described in this document behave as specified. 7.1.1. Core Validation Tests Bootstrap and rendering: Establish a Session between independently implemented endpoints and render a minimal surface. An initial frame MUST be displayed by the Portal, and the Session MUST terminate or detach cleanly. Window lifecycle: Create, map, unmap, and destroy a Window while observing compositor events. The CREATE, MAP, UNMAP, and DESTROY sequence MUST be correct, and no resources may be orphaned. Session persistence: Start a Session, detach it or allow the Portal to disconnect, and then resume it using the same Session identifier. The compositor state MUST be reconstructed as defined in Sections 4.8, 4.9, and 5.2.2, and the Portal MUST be able to redraw without a protocol violation. GPU isolation: Run multiple Portals concurrently, each creating independent surfaces. There MUST be no cross-Session resource leakage; surfaces and Windows MUST remain isolated. Transport stream allocation: Exercise the defined control, rendering, input, and audio traffic. Verify that reserved Video Plane Messages are not emitted. Messages MUST NOT be reordered where their class requires ordered delivery, and routing by Session, Seat, logical stream, and Window identifier MUST remain correct. Transport fragmentation: Negotiate max_user_message_size below the size of a MWS_RENDER_PRESENT. Transport MUST emit a valid MWS_MESSAGE_START and MWS_MESSAGE_APPEND sequence, and the peer MUST deliver exactly one reconstructed MWS_RENDER_PRESENT with an identical header and payload. Simultaneous associations with different limits MUST reassemble independently. Losing an association with a fragmented Message in progress MUST NOT deliver an incomplete Message or consume a later Message as continuation data. MWS_MESSAGE_ABANDON MUST discard an incomplete Message and permit the next Message on that stream to be processed normally. Error handling: Send invalid identifiers, malformed Messages, and protocol violations. The server MUST return the applicable error Message from the 700-799 range while preserving Session integrity unless the error is fatal. 7.2. GPU Isolation Requirements Implementations MUST ensure that GPU workloads from one session cannot compromise the integrity or confidentiality of another session's resources, regardless of whether the server contains a single GPU or multiple GPUs. * The server SHOULD avoid allowing GPU workloads from one session to starve or block those of another. Implementations MAY use separate Vulkan queues, queue subsets, per-session scheduling domains, or multi-GPU distribution strategies to achieve this. * The workstation MUST isolate Client GPU execution through its graphics stack and operating-system protection boundaries. An implementation accepting untrusted command submissions MUST validate or contain them sufficiently to prevent out-of-bounds access to another Session's resources. The MWS wire protocol does not require a Portal to submit Vulkan command buffers. * The server MUST enforce per-session limits on GPU resource usage, including device memory, descriptor sets, and command buffer size. When limits are exceeded, the server MAY throttle, reject further submissions, or terminate the session. On systems with multiple GPUs, implementations MAY assign sessions to different GPUs to improve isolation or load distribution. * The server SHOULD implement watchdog mechanisms to detect and recover from GPU hangs attributable to a particular session. Recovery MAY include resetting portal queues, revoking swapchains, or terminating the offending session while preserving other sessions. On multi-GPU systems, recovery MAY include migrating unaffected sessions to other GPUs. 7.3. Bandwidth and Transport Isolation Requirements Implementations MUST ensure that control and input remain responsive under load and that one portal cannot monopolise transport resources to the detriment of others. * Servers using a one-to-many SCTP socket MUST NOT treat writable readiness of that socket as readiness of a particular association. The SCTP sockets API explicitly permits writable readiness to mean that only one of the represented associations is writable [RFC6458]. To keep the handshake cheap, implementations SHOULD defer association-specific resources until authentication has succeeded. They SHOULD then isolate the association with sctp_peeloff(), or use an equivalent association-specific readiness and queueing mechanism, before sending MWS_SESSION_INFO. * Outbound buffering and backpressure MUST be tracked per association. A stalled association MUST NOT delay sends to another association. Implementations MUST bound per-association queued data so that one portal cannot exhaust workstation memory. * Stream 0 (control) MUST use reliable, ordered delivery and MUST be prioritised over bulk data on other streams. Input delivery follows Section 5.4. * Stream 1 (rendering Messages) MUST use reliable, ordered delivery. The server MAY impose rate limits on MWS_RENDER_PRESENT and client-channel rendering Messages to prevent excessive queueing. * Stream 2 carries input according to the per-event reliability, ordering, and coalescing requirements in Section 5.4. * Stream 3 carries video and MAY use partial reliability where the Message definition permits obsolete frames to be discarded. * Stream 4 carries audio. Each audio Message definition MUST state its ordering, loss, buffering, and flow-control requirements. * The server SHOULD implement per-session or per-portal bandwidth limits to prevent link saturation. Limits MAY be enforced at the SCTP layer, via traffic shaping, or using equivalent mechanisms. * The server MUST be able to unilaterally terminate a misbehaving portal without impacting other sessions. Termination SHOULD be signalled with the applicable fatal error Message followed by closure of the SCTP association, as defined in Section 5.9. Termination MUST release all GPU, transport, and compositor resources owned solely by that Portal attachment. Server-resident Session resources follow the GRACE and DETACHED lifecycles in Section 4.8; other active Sessions MUST NOT be affected. 8. Performance Considerations MWS was designed only after exploratory measurements indicated that the intended network-native architecture was technically plausible. These measurements were a feasibility study, not a benchmark of a complete Mercurius implementation. In the reference environment, the prospective Portal and workstation were located in different buildings. The path crossed a 10 GbE link, two switches, and a 10 Gbit/s fibre link. A 20-second, single-flow TCP test using fio's network engine and an I/O depth of one reported sustained throughput of approximately 1.3-1.5 Gbit/s. Representative ICMP measurements within the same site reported round-trip times of 0.181-0.339 ms, with a mean of 0.293 ms. These observations established that neither available bandwidth nor site-network propagation delay was an immediate obstacle to exploring a network-native Window system. They do not measure SCTP or DTLS overhead, GPU encoding, Portal decoding, display scheduling, or the complete input-to-display path. The completion latency reported by a local socket write is likewise not a measurement of network transit time. The reference workstation contains an NVIDIA GeForce RTX 5070. NVIDIA documents that device as providing a ninth-generation NVENC encoder with AV1 support [RTX50]. NVENC is dedicated encoding hardware and can operate independently of the graphics and CPU cores [NVENC]. These published capabilities supported the feasibility decision, but they are not measurements of Mercurius encode latency, processor use, or achievable resolution and refresh rate. No end-to-end performance figures are claimed by this specification. Implementations should measure at least transport latency and throughput, encode and decode latency, display scheduling delay, input-to-display latency, processor and GPU utilisation, and tail latency under concurrent Session load. Results should identify the measured boundary, topology, Message sizes, transport security, sample count, and percentile distribution. The protocol nevertheless provides mechanisms intended to avoid unnecessary interference between traffic classes. Control, rendering, input, and audio use separate SCTP streams. A further stream is reserved for video, and buffering is bounded per association. These properties reduce avoidable head-of-line blocking but do not guarantee any particular latency, throughput, or user experience. 9. Security Considerations MWS is designed according to zero-trust principles: no portal device, network segment, or intermediary is implicitly trusted. All trust is derived from cryptographic identity and explicit authorisation rather than network location. The protocol assumes that portal devices may be compromised, mobile, or operating on hostile networks, and that attackers may observe, inject, or replay traffic unless prevented by cryptographic protections. Transport security is provided by DTLS 1.3 over SCTP using [I-D.6083BIS]. The Portal authenticates the server certificate, and DTLS provides confidentiality and integrity for MWS traffic. When DANE is deployed, the server certificate is validated against DNSSEC-protected TLSA records. Deployments without DNSSEC or without control over their DNS zone SHOULD use traditional PKI validation instead. User authentication is performed at the application layer using the mechanism-agnostic model defined in Section 5.2.1. The server advertises supported mechanisms (for example, "PAM", "FIDO2") as UTF-8 identifiers in MWS_AUTH_CHALLENGE, and the portal selects one. This separation of device and user identity ensures that device identity alone does not grant access to a user's Session. Cryptographic proofs of possession of reusable credentials MUST be bound to the current DTLS association. In particular, SSHKEY signs the tls-exporter channel binding defined by [RFC9266]. A response captured on one association therefore cannot authenticate a new association. PAM is a password transfer rather than such a proof and has the limitations stated in Appendix B.1. Authentication data received from a Portal MUST NOT be treated as evidence of freshness unless the server can derive and verify that freshness independently. Each user is given an isolated session and compositor context. Portals cannot observe or interfere with other users' windows, input events, or rendering state. Window identifiers are scoped to a session, and all portal-originated messages are validated by the server. Attempts to reference resources outside the authenticated session are rejected with MWS_ERROR_SESSION (type=702) as described in Section 5.9. Portal-association rendering Messages use a dedicated SCTP stream. Input and Audio use Streams 2 and 4 with the validation and ordering rules in Sections 5.4 and 5.6. A Server MUST restrict input to the attached Session and capture to accepted streams. Capture requires Portal-local permission and remains subject to server policy. Implementations MUST bound decompression, reassembly, Render, and Audio buffers before consuming untrusted data. Stream 3 remains reserved for a later video definition, which MUST preserve these Session boundaries and specify its loss and resource-limit semantics. The server does not trust a Portal as an authority over Session state or resources. An active Portal is nevertheless trusted by its user with displayed content, captured input, and any reusable credential stored or entered there. Compromise of that Portal can compromise that user, but MUST NOT cross Session or user boundaries. If a portal disconnects unexpectedly, the session persists only for the duration of the reconnection grace period unless the user has explicitly detached. After this period, the session is terminated and all associated resources are destroyed, as defined in Section 4.8. Loss of the transport association for any reason (network failure, timeout, endpoint crash) is treated as a fatal transport error. The session MAY persist according to the rules in Section 4.8 and MAY be resumed from another portal subject to policy. Explicit detachment is requested with MWS_SESSION_DETACH (type=103). It is distinct from unexpected association loss: detachment records the user's intention to detach and preserve the Session, whereas association loss enters the bounded reconnection grace period. 9.1. DANE Deployment (Non-Normative) Deployments that operate their own DNS infrastructure may use DNSSEC and TLSA records (DANE) to authenticate server certificates during the DTLS/SCTP handshake. When DNSSEC validation is available, DANE provides a robust mechanism for binding workstation identity to DNS without relying on public certificate authorities. In this model, the portal validates the server's certificate against DNSSEC-protected TLSA records before proceeding with the MWS handshake, ensuring that it is communicating with the intended workstation even in the presence of compromised or mis-issued CA certificates. DANE is optional and does not alter protocol semantics. When enabled, it reduces operational complexity in closed trust domains by eliminating external trust dependencies and mitigating man-in-the-middle attacks even in the event of public CA compromise. Deployments without DNSSEC or without administrative control over their DNS zone should use traditional PKI validation instead. 10. IANA Considerations This document requests three IANA actions: 1. Register the following entry in the Service Name and Transport Protocol Port Number Registry: Service Name: mws Port Number: TBD1 Transport Protocol: SCTP Description: Mercurius Window System Assignee: IESG Contact: IETF Chair Reference: This document IANA is requested to allocate TBD1 from the Registered Port range. The RFC Editor is requested to replace every occurrence of TBD1 with the assigned port number before publication. 2. Register the following entry in the TLS Application-Layer Protocol Negotiation (ALPN) Protocol IDs registry [RFC7301]: Protocol: Mercurius Window System Identification Sequence: 0x6d 0x77 0x73 ("mws") Reference: This document 3. Register an entry in the SCTP Payload Protocol Identifiers registry, following Section 4.3 of [I-D.6083BIS]: Value: TBD2 SCTP Payload Protocol Identifier: Mercurius Window System over DTLS Reference: This document The cited mapping does not assign a generic DTLS PPID. TBD2 identifies SCTP user messages carrying DTLS records for MWS; ALPN identifies the application protocol during DTLS establishment. The RFC Editor is requested to replace TBD2 with the assigned PPID before publication. TBD1 and TBD2 are allocation placeholders, not wire values. Experiments before allocation require explicitly agreed local values and MUST NOT represent those values as IANA assignments. No other registries are required. In particular, MWS message types, opcodes, and SCTP stream assignments are managed entirely within the protocol and do not require IANA allocation. 11. Acknowledgements Christopher Ross (chris@tebibyte.org) provided the initial design and the reference implementation. The reference implementation described in Section 6 is maintained in the Mercurius source code repository. Git and SSH access are available to contributors on request via mercurius@tebibyte.org. Additional background material, including architectural rationale, design philosophy, and example use cases, is available from the Mercurius project website . This information is provided for context only and is non-normative; the protocol defined in this document is complete and does not depend on any specific implementation or external documentation. 12. References 12.1. Normative References [HUT17] USB Implementers Forum, "HID Usage Tables", Version 1.7, 27 January 2026, . [I-D.6083BIS] Tuexen, M., Tschofenig, H., and T. Reddy, "Datagram Transport Layer Security (DTLS) 1.3 for Stream Control Transmission Protocol (SCTP)", Work in Progress, Internet-Draft, draft-tuexen-tsvwg-rfc6083-bis-07, 21 April 2025, . [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", IEEE Std 754-2019, July 2019, . [POSIX-EXEC] The Open Group, "exec", The Open Group Base Specifications, Issue 8, POSIX.1-2024, . [RFC1982] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982, DOI 10.17487/RFC1982, August 1996, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, . [RFC4251] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH) Protocol Architecture", RFC 4251, DOI 10.17487/RFC4251, January 2006, . [RFC4253] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH) Transport Layer Protocol", RFC 4253, DOI 10.17487/RFC4253, January 2006, . [RFC4895] Tuexen, M., Stewart, R., and P. Lei, "Authenticated Chunks for Stream Control Transmission Protocol (SCTP)", RFC 4895, DOI 10.17487/RFC4895, August 2007, . [RFC6458] Stewart, R., Tuexen, M., Poon, K., Lei, P., and V. Yasevich, "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)", RFC 6458, DOI 10.17487/RFC6458, December 2011, . [RFC6698] Hoffman, P. and J. Schlyter, "The DNS-Based Authentication of Named Entities (DANE) Transport Layer Security (TLS) Protocol: TLSA", RFC 6698, DOI 10.17487/RFC6698, August 2012, . [RFC7301] Friedl, S., Popov, A., Langley, A., and E. Stephan, "Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension", RFC 7301, DOI 10.17487/RFC7301, July 2014, . [RFC7671] Dukhovni, V. and W. Hardaker, "The DNS-Based Authentication of Named Entities (DANE) Protocol: Updates and Operational Guidance", RFC 7671, DOI 10.17487/RFC7671, October 2015, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8332] Bider, D., "Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol", RFC 8332, DOI 10.17487/RFC8332, March 2018, . [RFC8709] Harris, B. and L. Velvindron, "Ed25519 and Ed448 Public Key Algorithms for the Secure Shell (SSH) Protocol", RFC 8709, DOI 10.17487/RFC8709, February 2020, . [RFC8878] Collet, Y. and M. Kucherawy, Ed., "Zstandard Compression and the 'application/zstd' Media Type", RFC 8878, DOI 10.17487/RFC8878, February 2021, . [RFC9147] Rescorla, E., Tschofenig, H., and N. Modadugu, "The Datagram Transport Layer Security (DTLS) Protocol Version 1.3", RFC 9147, DOI 10.17487/RFC9147, April 2022, . [RFC9260] Stewart, R., Tuexen, M., and K. Nielsen, "Stream Control Transmission Protocol", RFC 9260, DOI 10.17487/RFC9260, June 2022, . [RFC9266] Whited, S., "Channel Bindings for TLS 1.3", RFC 9266, DOI 10.17487/RFC9266, July 2022, . [VK14] Khronos Group, "Vulkan 1.4 Specification", version 1.4.362, September 2026, . 12.2. Informative References [EWMH] freedesktop.org, "Extended Window Manager Hints", Section 5, "Application Window Properties", . [NIST800-207] National Institute of Standards and Technology, "Zero Trust Architecture", NIST Special Publication 800-207, DOI 10.6028/NIST.SP.800-207, August 2020, . [NVENC] NVIDIA Corporation, "NVENC Application Note", NVIDIA Video Codec SDK 13.0, 2025, . [RFC3436] Jungmaier, A., Rescorla, E., and M. Tuexen, "Transport Layer Security over Stream Control Transmission Protocol", RFC 3436, DOI 10.17487/RFC3436, December 2002, . [RFC6083] Tuexen, M., Seggelmann, R., and E. Rescorla, "Datagram Transport Layer Security (DTLS) for Stream Control Transmission Protocol (SCTP)", RFC 6083, DOI 10.17487/RFC6083, January 2011, . [RTX50] NVIDIA Corporation, "GeForce RTX 50 Series GPUs Double Creative Performance", January 2025, . [SARATOGA] Wood, L., Eddy, W., Smith, C., Ivancic, W., and C. Jackson, "Saratoga: A Scalable Data Transfer Protocol", Work in Progress, Internet-Draft, draft-wood-tsvwg-saratoga-22, 17 December 2017, . [WAYLAND] Wayland project, "Wayland Architecture", . [XDG-ICON] Wayland project, "xdg-toplevel-icon-v1", version 1, wayland-protocols staging protocol, . [XDG-SETTINGS] XDG Desktop Portal authors, "Settings", . Appendix A. MWS Opcode Registry This appendix defines the MWS opcode allocations for this revision. All opcodes are 16-bit unsigned integers. Opcodes are grouped into 100-entry ranges according to functional category. Implementations MUST treat unknown opcodes as protocol errors and respond with MWS_ERROR_PROTOCOL (type=701) as described in Section 5.9. Within each standard category, offsets 00-49 are available for Messages in the current protocol family. Values not allocated below are unassigned and remain available for future specifications. Offsets 50-99 are reserved to leave substantial space for later major revisions of Mercurius. The experimental range is the exception to this convention. Opcodes 1000-65535 are unassigned and MUST NOT be emitted by implementations of this revision. A.1. Handshake and Authentication (000-099) NOTE: Type 000 is reserved and MUST be treated as a NULL/invalid value. Implementations encountering type=000 MUST respond with MWS_ERROR_PROTOCOL (type=701, fatal=1). 001 MWS_QUERY 002 MWS_AUTH_CHALLENGE 003 MWS_AUTH_RESPONSE 004 MWS_SESSION_INFO 005-049 Unassigned 050-099 Reserved for later protocol revisions A.2. Session Management (100-199) 100 MWS_SESSION_RESUME_OFFER 101 MWS_SESSION_RESUME_REQUEST 102 MWS_SESSION_RESUME_COMPLETE 103 MWS_SESSION_DETACH 104 MWS_SESSION_NEW_REQUEST 105 MWS_SESSION_STATE_BEGIN 106 MWS_SESSION_STATUS 107-109 Unassigned 110 MWS_EXEC_REQUEST 111 MWS_EXEC_RESULT 112 MWS_EXEC_STDOUT 113 MWS_EXEC_STDERR 114-119 Unassigned 120 MWS_CONFIG_QUERY 121 MWS_CONFIG_RESULT 122-149 Unassigned 150-199 Reserved for later protocol revisions A.3. Window Lifecycle (200-299) 200 MWS_CREATE_WINDOW 201 MWS_WINDOW_CREATED 202 MWS_DESTROY_WINDOW 203 MWS_WINDOW_DESTROYED 204 MWS_MAP_WINDOW 205 MWS_UNMAP_WINDOW 206 MWS_CONFIGURE_WINDOW 207 MWS_FOCUS_WINDOW 208 MWS_SWAPCHAIN_REVOKED 209 MWS_WINDOW_STATE 210 MWS_WINDOW_RELATION 211 MWS_WINDOW_TITLE 212 MWS_WINDOW_ICON 213-249 Unassigned 250-299 Reserved for later protocol revisions A.4. Rendering Messages (300-399) 300 MWS_RENDER_PRESENT 301 MWS_RENDER_SYNC 302 MWS_RENDER_DESTROY 303 MWS_RENDER_UPLOAD 304 MWS_RENDER_DAMAGE 305 MWS_RENDER_FENCE 306-349 Unassigned 350-399 Reserved for later protocol revisions A.5. Input Plane (400-499) 400 MWS_INPUT_EVENT 401 MWS_INPUT_ACK 402 MWS_INPUT_POINTER_MODE 403-449 Unassigned 450-499 Reserved for later protocol revisions A.6. Video Plane (500-599) 500 MWS_AV1_FRAME 501 MWS_PLACEHOLDER_FRAME 502-549 Unassigned 550-599 Reserved for later protocol revisions A.7. Audio Plane (600-699) 600 MWS_AUDIO_PLAYBACK_OPEN 601 MWS_AUDIO_PLAYBACK_ACCEPT 602 MWS_AUDIO_PLAYBACK_REJECT 603 MWS_AUDIO_PLAYBACK_DATA 604 MWS_AUDIO_PLAYBACK_CLOSE 605 MWS_AUDIO_PLAYBACK_CAPABILITIES 606-619 Unassigned 620 MWS_AUDIO_CAPTURE_OPEN 621 MWS_AUDIO_CAPTURE_ACCEPT 622 MWS_AUDIO_CAPTURE_REJECT 623 MWS_AUDIO_CAPTURE_DATA 624 MWS_AUDIO_CAPTURE_CLOSE 625 MWS_AUDIO_CAPTURE_CAPABILITIES 626-649 Unassigned 650-699 Reserved for later protocol revisions A.8. Error Reporting (700-799) 700 MWS_ERROR 701 MWS_ERROR_PROTOCOL 702 MWS_ERROR_SESSION 703 MWS_ERROR_TRANSPORT 704 MWS_ERROR_POLICY 705 MWS_ERROR_RESOURCE 706-749 Unassigned 750-799 Reserved for later protocol revisions A.9. Transport Services (800-899) 800 MWS_MESSAGE_START 801 MWS_MESSAGE_APPEND 802 MWS_MESSAGE_ABANDON 803-849 Unassigned for Transport-to-Transport Messages 850-899 Reserved for later protocol revisions A.10. Experimental and Vendor-Specific (900-999) 900-999 Experimental, vendor-specific, or implementation-defined opcodes. These MUST NOT be used in interoperable deployments and MUST NOT be relied upon in Internet-scale deployments. Appendix B. Authentication Mechanism Registry MWS supports a mechanism-agnostic authentication model. During the initial handshake, the server advertises one or more authentication mechanisms using MWS_AUTH_CHALLENGE (type=002). The portal selects a mechanism and responds with MWS_AUTH_RESPONSE (type=003), providing mechanism-specific credentials or authentication data. This appendix defines the registry of authentication mechanism identifiers. Mechanism identifiers are UTF-8 strings and are compared using case-sensitive bytewise comparison. Identifiers MUST NOT exceed 64 bytes in length. Implementations MUST ignore unknown mechanism identifiers and MUST NOT attempt to interpret their payloads. Servers MUST NOT advertise mechanisms they do not fully support. B.1. Standard Mechanisms The following mechanism identifiers are defined by this specification: "PAM" The server authenticates the user using the system's Pluggable Authentication Modules (PAM) stack. The credential payload contains a NUL-terminated UTF-8 username followed by a NUL-terminated UTF-8 password, with no trailing octets. This is an explicit exception to the length-prefixed text convention. The username MUST be non-empty. A password MAY be empty if local policy permits it. This mechanism supports one username/password exchange, not arbitrary interactive PAM conversations. The Server MUST reject authentication requiring unsupported additional steps. PAM relies on server-authenticated DTLS confidentiality; a malicious Portal or Server can observe and reuse the password. "SSHKEY" The Portal proves possession of an SSH private key whose public key is authorised for the requested user. The private key is never transmitted. OpenSSH key files and authorized_keys files MAY be used as local storage formats; those formats do not form part of the MWS wire protocol. The SSHKEY credential has the following format: username_len 1-octet unsigned integer username username_len octets algorithm_len 1-octet unsigned integer algorithm algorithm_len octets public_key_len 2-octet unsigned integer public_key public_key_len octets signature_len 2-octet unsigned integer signature signature_len octets Length fields are in network byte order where they occupy more than one octet. Strings are UTF-8 and are not NUL-terminated. Every length MUST be non-zero, and the credential MUST contain exactly the declared fields with no trailing octets. algorithm identifies the SSH signature algorithm. This specification defines ssh-ed25519 [RFC8709], rsa-sha2-256, and rsa-sha2-512 [RFC8332]. The public_key field contains an SSH public-key blob: ssh-ed25519 for an Ed25519 key or ssh-rsa for an RSA key. The signature field is an SSH signature blob containing the same signature algorithm identifier and the signature octets. SSH string and public-key encodings follow [RFC4251] and [RFC4253], with the algorithm-specific formats in [RFC8709] and [RFC8332]. These inner SSH strings retain their four-octet lengths; the outer MWS lengths above do not replace them. The Portal and server independently obtain the 32-octet tls-exporter channel binding for the current DTLS association as defined by [RFC9266]. The Portal signs the following byte string: domain_len 1-octet unsigned integer domain domain_len octets username_len 1-octet unsigned integer username username_len octets channel_binding_len 1-octet unsigned integer channel_binding channel_binding_len octets domain is the ASCII string "MWS-SSHKEY", without a terminating NUL, and channel_binding_len is 32. The username fields MUST be identical to those in the credential. The server MUST construct this byte string from the received username and its own channel binding; it MUST NOT accept a signing envelope supplied by the Portal. The server authenticates the user only if the public key is authorised for username and the signature verifies over this exact byte string. A malformed credential, an algorithm mismatch, an unauthorised key, or an invalid signature fails authentication. B.2. Extensible Mechanisms The following identifiers are reserved for future specifications or external standards. Their payload formats are not defined by this document. "FIDO2" Authentication using a FIDO2 authenticator. "WEBAUTHN" Authentication using a WebAuthn ceremony. "KERBEROS" Authentication using a Kerberos AP-REQ exchange. "OAUTH2" Authentication using an OAuth 2.0 device or authorisation-code flow. A reserved mechanism MUST NOT be advertised or selected until an applicable specification defines its payload and authentication semantics. Implementations MUST NOT guess an encoding from its name. B.3. Private and Experimental Mechanisms Mechanism identifiers beginning with the prefix "X-" are reserved for private, experimental, or vendor-specific use. These identifiers MUST NOT appear in interoperable deployments or Internet-facing services. Examples: "X-FINGERPRINT" "X-HARDWARE-TOKEN" "X-SSO-PROTOTYPE" B.4. Registration Policy New mechanism identifiers MAY be defined by future MWS extensions or external standards. To avoid collisions, new identifiers must be documented by an extension specifying their payload, security properties, and allocation. This document creates no IANA registry for authentication mechanisms (Section 10). Until such time, implementers SHOULD use the "X-" prefix for experimental mechanisms and MUST NOT assume global uniqueness. Appendix C. SCTP Stream Usage Summary MWS uses multiple SCTP streams to isolate control, rendering, input, video, and audio traffic. This appendix summarises the required stream assignments. All Portal-association streams use DTLS for confidentiality and integrity. Stream assignments are fixed and MUST NOT be repurposed for other message classes. Implementations MAY open additional streams for experimental or vendor-specific extensions, provided they do not conflict with the assignments below. C.1. Stream 0 -- Control Plane Stream 0 carries all ordered control-plane traffic, including: * handshake messages (001-099) * session-management messages (100-199) (including MWS_SESSION_STATUS render-progress control) * Portal-association Window lifecycle Messages (200-299) * error messages (700-799) Messages on Stream 0 MUST be delivered reliably and in order. A logical Message larger than max_user_message_size is fragmented by Transport as defined in Section 5.1.1. C.2. Stream 1 -- Rendering Messages Stream 1 carries Portal-association rendering Messages, currently MWS_RENDER_PRESENT, MWS_RENDER_SYNC, and MWS_RENDER_DESTROY. MWS_RENDER_UPLOAD and MWS_RENDER_DAMAGE are client-channel Messages and MUST NOT be sent on an SCTP Portal association. Portal-association rendering Messages travel from server to Portal. MWS_RENDER_FENCE is reserved and MUST NOT be sent by implementations of this version. Messages on Stream 1 MUST be delivered reliably and in order. A logical Message larger than max_user_message_size is fragmented by Transport as defined in Section 5.1.1. C.3. Stream 2 -- Input Plane Stream 2 carries Input Plane Messages (400-499) in both directions. Delivery semantics depend on the Message and event class as specified in Section 5.4: state transitions and pointer-mode requests are reliable and ordered, while superseded motion may be coalesced only where doing so preserves intervening state. C.4. Stream 3 -- Video Plane Stream 3 is reserved for video Messages (500-599). This revision prohibits their transmission because their payloads are undefined. A later definition may permit partial reliability where obsolete frames can be discarded without invalidating decoder state. C.5. Stream 4 -- Audio Plane Stream 4 carries Audio Messages (600-699). Playback and capture streams use Session-unique stream_id values and the lifecycles specified in Section 5.6. This revision defines both payload families as ordered linear PCM. Later Audio Plane definitions MUST state any additional loss, buffering and flow-control semantics. C.6. Additional Streams Streams 5-15 are reserved for future standard extensions. Such extensions MUST specify: * reliability requirements (reliable, PR-SCTP, unordered) * congestion-control expectations * interaction with the control plane Experimental or vendor-specific extensions SHOULD use streams >=16 to avoid collision with future standardised assignments. Appendix D. Protocol State Machine Diagrams This appendix provides normative state-machine diagrams for the MWS protocol. These diagrams illustrate the ordered interactions between portal and server during initial connection, session resumption, and normal operation. All Portal-association control-plane transitions occur on SCTP Stream 0. Portal-association rendering, input, video, and audio traffic occur on their respective streams as defined in Appendix C. D.1. Initial Connection State Machine +------------------+ | TRANSPORT_UP | +------------------+ | | MWS_QUERY (001) | MWS_AUTH_CHALLENGE (002) | MWS_AUTH_RESPONSE (003) v +------------------+ | AUTH_VERIFY | +------------------+ | | failure -> fatal error and association loss | success -> two-way MWS_SESSION_INFO (004) v +------------------+ | BOOTSTRAP_ACTIVE | +------------------+ | | MWS_SESSION_RESUME_OFFER (100) | MWS_SESSION_NEW_REQUEST (104) v +------------------+ | ACTIVE_SESSION | +------------------+ | | normal Session traffic on Streams 0-4 v +------------------+ | RUNNING | +------------------+ D.2. Session Resume State Machine +------------------+ | RESUME_OFFERED | +------------------+ | | MWS_SESSION_RESUME_REQUEST (101) v +------------------+ | RESUME_VERIFY | +------------------+ | | failure -> MWS_ERROR_SESSION (702, fatal=0), | return to RESUME_OFFERED | success -> reserve Session v +------------------+ | RESUME_PENDING | +------------------+ | | server MWS_SESSION_INFO (004) | Portal MWS_SESSION_INFO (004) | MWS_SESSION_STATE_BEGIN (105) | Window snapshot (Section 5.2.2.1) | MWS_SESSION_RESUME_COMPLETE (102) v +------------------+ | ACTIVE_SESSION | +------------------+ | | normal operation resumes: | * Portal-association rendering on Stream 1 | * input on Stream 2 | * Stream 3 remains reserved for video | * audio on Stream 4 v +------------------+ | RUNNING | +------------------+ D.3. Error Handling State Machine Errors may occur at any point in the protocol. The following diagram illustrates the error-handling model: +------------------+ | ANY_STATE | +------------------+ | | recoverable error | MWS_ERROR_* (700-705, fatal=0) v +------------------+ | CONTINUE | +------------------+ | | fatal error | MWS_ERROR_* (700-705, fatal=1) v +------------------+ | TERMINATE | +------------------+ | | SCTP association closed v +------------------+ | END | +------------------+ D.4. Stream Interaction Summary The following summary illustrates the concurrency model across SCTP streams: Stream 0 (control): ordered, reliable * handshake (001-099) * session management (100-199) * window lifecycle (200-299) * error reporting (700-799) Stream 1 (rendering): ordered, reliable * rendering Messages (300-399), including pixel buffers Stream 2 (input): delivery policy depends on event class * input Messages (400-499) Stream 3 (video): partial reliability where defined * video Messages (500-599) Stream 4 (audio): ordered, reliable PCM * audio Messages (600-699) These streams have independent delivery ordering. Implementations MUST NOT impose a shared application processing queue that blocks Control behind Render work. SCTP congestion control and shared network capacity can still delay more than one stream. Author's Address Christopher Ross Independent Email: chris@tebibyte.org Project Website: https://mercurius.tebibyte.org