Skip to main content

Mercurius Window System (MWS)
draft-ross-mercurius-06

Document Type Active Internet-Draft (individual)
Author Christopher Ross
Last updated 2026-09-11
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-ross-mercurius-06
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 <iesg@ietf.org>
            Contact:             IETF Chair <chair@ietf.org>
            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
   <https://mercurius.tebibyte.org>. 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,
             <https://usb.org/document-library/hid-usage-tables-17>.

   [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,
             <https://www.ietf.org/archive/id/
             draft-tuexen-tsvwg-rfc6083-bis-07.txt>.

   [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", IEEE
             Std 754-2019, July 2019,
             <https://standards.ieee.org/ieee/754/6210/>.

   [POSIX-EXEC] The Open Group, "exec", The Open Group Base
             Specifications, Issue 8, POSIX.1-2024,
             <https://pubs.opengroup.org/onlinepubs/9799919799/
             functions/exec.html>.

   [RFC1982] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982,
             DOI 10.17487/RFC1982, August 1996,
             <https://www.rfc-editor.org/info/rfc1982>.

   [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
             Requirement Levels", BCP 14, RFC 2119, DOI
             10.17487/RFC2119, March 1997,
             <https://www.rfc-editor.org/info/rfc2119>.

   [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646",
             STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003,
             <https://www.rfc-editor.org/info/rfc3629>.

   [RFC4251] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
             Protocol Architecture", RFC 4251, DOI 10.17487/RFC4251,
             January 2006,
             <https://www.rfc-editor.org/info/rfc4251>.

   [RFC4253] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
             Transport Layer Protocol", RFC 4253, DOI 10.17487/RFC4253,
             January 2006,
             <https://www.rfc-editor.org/info/rfc4253>.

   [RFC4895] Tuexen, M., Stewart, R., and P. Lei, "Authenticated Chunks
             for Stream Control Transmission Protocol (SCTP)", RFC 4895,
             DOI 10.17487/RFC4895, August 2007,
             <https://www.rfc-editor.org/info/rfc4895>.

   [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,
             <https://www.rfc-editor.org/info/rfc6458>.

   [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,
             <https://www.rfc-editor.org/info/rfc6698>.

   [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,
             <https://www.rfc-editor.org/info/rfc7301>.

   [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,
             <https://www.rfc-editor.org/info/rfc7671>.

   [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119
             Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May
             2017,
             <https://www.rfc-editor.org/info/rfc8174>.

   [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,
             <https://www.rfc-editor.org/info/rfc8332>.

   [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,
             <https://www.rfc-editor.org/info/rfc8709>.

   [RFC8878] Collet, Y. and M. Kucherawy, Ed., "Zstandard Compression
             and the 'application/zstd' Media Type", RFC 8878, DOI
             10.17487/RFC8878, February 2021,
             <https://www.rfc-editor.org/info/rfc8878>.

   [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,
             <https://www.rfc-editor.org/info/rfc9147>.

   [RFC9260] Stewart, R., Tuexen, M., and K. Nielsen, "Stream Control
             Transmission Protocol", RFC 9260, DOI 10.17487/RFC9260,
             June 2022,
             <https://www.rfc-editor.org/info/rfc9260>.

   [RFC9266] Whited, S., "Channel Bindings for TLS 1.3", RFC 9266, DOI
             10.17487/RFC9266, July 2022,
             <https://www.rfc-editor.org/info/rfc9266>.

   [VK14] Khronos Group, "Vulkan 1.4 Specification", version 1.4.362,
             September 2026,
             <https://registry.khronos.org/vulkan/specs/latest/html/
             vkspec.html>.

12.2. Informative References

   [EWMH] freedesktop.org, "Extended Window Manager Hints", Section 5,
             "Application Window Properties",
             <https://specifications.freedesktop.org/wm/latest/
             ar01s05.html>.

   [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,
             <https://csrc.nist.gov/pubs/sp/800/207/final>.

   [NVENC] NVIDIA Corporation, "NVENC Application Note", NVIDIA Video
             Codec SDK 13.0, 2025,
             <https://docs.nvidia.com/video-technologies/
             video-codec-sdk/13.0/nvenc-application-note/>.

   [RFC3436] Jungmaier, A., Rescorla, E., and M. Tuexen, "Transport
             Layer Security over Stream Control Transmission Protocol",
             RFC 3436, DOI 10.17487/RFC3436, December 2002,
             <https://www.rfc-editor.org/info/rfc3436>.

   [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,
             <https://www.rfc-editor.org/info/rfc6083>.

   [RTX50] NVIDIA Corporation, "GeForce RTX 50 Series GPUs Double
             Creative Performance", January 2025,
             <https://blogs.nvidia.com/blog/
             generative-ai-studio-ces-geforce-rtx-50-series/>.

   [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,
             <https://datatracker.ietf.org/doc/
             draft-wood-tsvwg-saratoga/22/>.

   [WAYLAND] Wayland project, "Wayland Architecture",
             <https://wayland.freedesktop.org/architecture.html>.

   [XDG-ICON] Wayland project, "xdg-toplevel-icon-v1", version 1,
             wayland-protocols staging protocol,
             <https://gitlab.freedesktop.org/wayland/wayland-protocols/
             -/blob/main/staging/xdg-toplevel-icon/
             xdg-toplevel-icon-v1.xml>.

   [XDG-SETTINGS] XDG Desktop Portal authors, "Settings",
             <https://flatpak.github.io/xdg-desktop-portal/docs/
             doc-org.freedesktop.portal.Settings.html>.

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