From 7c39427d8b33073f55883debd0913f998620d122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= <76261501+zecakeh@users.noreply.github.com> Date: Wed, 17 Dec 2025 14:13:51 +0100 Subject: [PATCH 01/19] Spec device management for application services (#2267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per MSC4190. Signed-off-by: Kévin Commaille --- .../newsfragments/2267.feature | 1 + .../client_server/newsfragments/2267.feature | 1 + content/application-service-api.md | 102 ++++++++++++++---- content/client-server-api/_index.md | 13 ++- data/api/client-server/cross_signing.yaml | 8 +- data/api/client-server/device_management.yaml | 45 ++++++-- data/api/client-server/login.yaml | 9 +- data/api/client-server/registration.yaml | 15 +++ 8 files changed, 161 insertions(+), 33 deletions(-) create mode 100644 changelogs/application_service/newsfragments/2267.feature create mode 100644 changelogs/client_server/newsfragments/2267.feature diff --git a/changelogs/application_service/newsfragments/2267.feature b/changelogs/application_service/newsfragments/2267.feature new file mode 100644 index 00000000..92a03203 --- /dev/null +++ b/changelogs/application_service/newsfragments/2267.feature @@ -0,0 +1 @@ +Allow application services to manage devices and register users without the legacy authentication API, as per [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190). diff --git a/changelogs/client_server/newsfragments/2267.feature b/changelogs/client_server/newsfragments/2267.feature new file mode 100644 index 00000000..92a03203 --- /dev/null +++ b/changelogs/client_server/newsfragments/2267.feature @@ -0,0 +1 @@ +Allow application services to manage devices and register users without the legacy authentication API, as per [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190). diff --git a/content/application-service-api.md b/content/application-service-api.md index cc2c25ca..5f6b17ab 100644 --- a/content/application-service-api.md +++ b/content/application-service-api.md @@ -428,6 +428,8 @@ imports and similar behaviour). #### Server admin style permissions +{{% changed-in v="1.17" %}} + The homeserver needs to give the application service *full control* over its namespace, both for users and for room aliases. This means that the AS should be able to manage any users and room alias in its namespace. No additional API @@ -444,33 +446,59 @@ achieved by including the `as_token` on a `/register` request, along with a login type of `m.login.application_service` to set the desired user ID without a password. - POST /_matrix/client/v3/register - Authorization: Bearer YourApplicationServiceTokenHere +```http +POST /_matrix/client/v3/register +Authorization: Bearer YourApplicationServiceTokenHere +``` - Content: - { - "type": "m.login.application_service", - "username": "_irc_example" - } +```json +{ + "type": "m.login.application_service", + "username": "_irc_example" +} +``` -Similarly, logging in as users needs API changes in order to allow the AS to -log in without needing the user's password. This is achieved by including the -`as_token` on a `/login` request, along with a login type of -`m.login.application_service`: +{{% boxes/note %}} +{{% added-in v="1.17" %}} +Servers MUST still allow application services to use the `/register` endpoint +with a login type of `m.login.application_service` even if they don't support +the [Legacy Authentication API](/client-server-api/#legacy-api). + +In that case application services MUST set the `"inhibit_login": true` parameter +as they cannot use it to log in as users. If the `inhibit_login` parameter is +not set to `true`, the server MUST return a 400 HTTP status code with an +`M_APPSERVICE_LOGIN_UNSUPPORTED` error code. +{{% /boxes/note %}} + +Similarly, logging in as users using the [Legacy authentication API](/client-server-api/#legacy-api) +needs API changes in order to allow the AS to log in without needing the user's +password. This is achieved by including the `as_token` on a `/login` request, +along with a login type of `m.login.application_service`: {{% added-in v="1.2" %}} - POST /_matrix/client/v3/login - Authorization: Bearer YourApplicationServiceTokenHere +```http +POST /_matrix/client/v3/login +Authorization: Bearer YourApplicationServiceTokenHere +``` - Content: - { - "type": "m.login.application_service", - "identifier": { - "type": "m.id.user", - "user": "_irc_example" - } - } +```json +{ + "type": "m.login.application_service", + "identifier": { + "type": "m.id.user", + "user": "_irc_example" + } +} +``` + +{{% boxes/note %}} +{{% added-in v="1.17" %}} +Application services MUST NOT use the `/login` endpoint if the server doesn't +support the Legacy authentication API. If `/login` is called with the +`m.login.application_service` login type the server MUST return a 400 HTTP +status code with an `M_APPSERVICE_LOGIN_UNSUPPORTED` error code. +{{% /boxes/note %}} Application services which attempt to create users or aliases *outside* of their defined namespaces, or log in as users outside of their defined @@ -512,6 +540,38 @@ client-server endpoint. {{% http-api spec="client-server" api="appservice_room_directory" %}} +#### Device management + +{{% added-in v="1.17" %}} + +Application services need to be able to create and delete devices to manage the +encryption for their users without having to rely on `/login`, which also +generates an access token for the user, and which might not be available for +homeservers that only support the [OAuth 2.0 API](/client-server-api/#oauth-20-api). + +##### Creating devices + +Application services can use the [`PUT /_matrix/client/v3/devices/{deviceId}`](/client-server-api/#put_matrixclientv3devicesdeviceid) +endpoint to create new devices. + +##### Deleting devices + +The following endpoints used to delete devices MUST NOT require [User-Interactive +Authentication](/client-server-api/#user-interactive-authentication-api) when +used by an application service: + +* [`DELETE /_matrix/client/v3/devices/{deviceId}`](/client-server-api/#delete_matrixclientv3devicesdeviceid) +* [`POST /_matrix/client/v3/delete_devices`](/client-server-api/#post_matrixclientv3delete_devices) + +#### Cross-signing + +{{% added-in v="1.17" %}} + +Appservices need to be able to verify themselves and replace their cross-signing +keys, so the [`POST /_matrix/client/v3/keys/device_signing/upload`](/client-server-api/#post_matrixclientv3keysdevice_signingupload) +endpoint MUST NOT require [User-Interactive Authentication](/client-server-api/#user-interactive-authentication-api) +when used by an application service, even if cross-signing keys already exist. + ### Referencing messages from a third-party network Application services should include an `external_url` in the `content` diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 2460776f..4c76d6a5 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -477,8 +477,7 @@ the API that was used to obtain their current access token. {{% boxes/note %}} Currently the OAuth 2.0 API doesn't cover all the use cases of the legacy API, -such as automated applications that cannot use a web browser, or -user management by [application services](application-service-api/#server-admin-style-permissions). +such as automated applications that cannot use a web browser. {{% /boxes/note %}} ### Authentication API discovery @@ -502,6 +501,12 @@ user must do that directly in the homeserver's web UI. However, the client can signal to the homeserver that the user wishes to create a new account with the [`prompt=create`](#user-registration) parameter during authorization. +{{% boxes/note %}} +{{% added-in v="1.17" %}} +Application services can use the `/register` endpoint to create users regardless +of the authentication API supported by the homeserver. +{{% /boxes/note %}} + ### Login With the legacy API, a client can obtain an access token by using one of the @@ -1562,6 +1567,10 @@ If the access token does correspond to an appservice, but the user id does not lie within its namespace then the homeserver will respond with an errcode of `M_EXCLUSIVE`. +{{% added-in v="1.17" %}} If this login type is used and the server doesn't +support logging in via the Legacy authentication API, it MUST return a 400 HTTP +status code with an `M_APPSERVICE_LOGIN_UNSUPPORTED` error code. + ##### Login Fallback If a client does not recognize any or all login flows it can use the diff --git a/data/api/client-server/cross_signing.yaml b/data/api/client-server/cross_signing.yaml index ec490b2a..f340bd59 100644 --- a/data/api/client-server/cross_signing.yaml +++ b/data/api/client-server/cross_signing.yaml @@ -21,13 +21,17 @@ paths: x-addedInMatrixVersion: "1.1" x-changedInMatrixVersion: "1.11": UIA is not always required for this endpoint. + "1.17": |- + This endpoint no longer requires User-Interactive Authentication when used by an + application service. summary: Upload cross-signing keys. description: |- Publishes cross-signing keys for the user. - This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api). + This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api), + except when used by an application service. - User-Interactive Authentication MUST be performed, except in these cases: + User-Interactive Authentication MUST be performed for regular clients, except in these cases: - there is no existing cross-signing master key uploaded to the homeserver, OR - there is an existing cross-signing master key and it exactly matches the cross-signing master key provided in the request body. If there are any additional diff --git a/data/api/client-server/device_management.yaml b/data/api/client-server/device_management.yaml index 1b245e78..94dde899 100644 --- a/data/api/client-server/device_management.yaml +++ b/data/api/client-server/device_management.yaml @@ -87,8 +87,21 @@ paths: tags: - Device management put: - summary: Update a device - description: Updates the metadata on the given device. + summary: Create or update a device + x-changedInMatrixVersion: + "1.17": The ability to create new devices was added. + description: |- + Updates the metadata on the given device, or creates a new device. + + The ability to create new devices is only available to application + services: regular clients may only update existing devices. + + When a new device was created, the homeserver MUST return a 201 HTTP + status code. It MUST return a 200 HTTP status code if a device was + updated. + + This endpoint is rate-limited for device creation. Servers MAY use login + rate limits. operationId: updateDevice security: - accessTokenQuery: [] @@ -127,19 +140,34 @@ paths: examples: response: value: {} + "201": + description: |- + The device was successfully created by the application service. + content: + application/json: + schema: + type: object + examples: + response: + value: {} "404": description: The current user has no device with the given ID. tags: - Device management delete: summary: Delete a device + x-changedInMatrixVersion: + "1.17": |- + This endpoint no longer requires User-Interactive Authentication when used by an + application service. description: |- - This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api). + This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api), + except when used by an application service. Deletes the given device, and invalidates any access token associated with it. {{% boxes/warning %}} - Since this endpoint uses User-Interactive Authentication, it cannot be used when the access token was obtained + When this endpoint requires User-Interactive Authentication, it cannot be used when the access token was obtained via the [OAuth 2.0 API](/client-server-api/#oauth-20-api). {{% /boxes/warning %}} operationId: deleteDevice @@ -190,13 +218,18 @@ paths: /delete_devices: post: summary: Bulk deletion of devices + x-changedInMatrixVersion: + "1.17": |- + This endpoint no longer requires User-Interactive Authentication when used by an + application service. description: |- - This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api). + This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api), + except when used by an application service. Deletes the given devices, and invalidates any access token associated with them. {{% boxes/warning %}} - Since this endpoint uses User-Interactive Authentication, it cannot be used when the access token was obtained + When this endpoint requires User-Interactive Authentication, it cannot be used when the access token was obtained via the [OAuth 2.0 API](/client-server-api/#oauth-20-api). {{% /boxes/warning %}} operationId: deleteDevices diff --git a/data/api/client-server/login.yaml b/data/api/client-server/login.yaml index 4eba954e..7251d4ff 100644 --- a/data/api/client-server/login.yaml +++ b/data/api/client-server/login.yaml @@ -243,8 +243,13 @@ paths: } } "400": - description: Part of the request was invalid. For example, the login type may - not be recognised. + description: |- + Part of the request was invalid. For example, the login type may not be recognised. + + Specific error codes used with this status code include: + * {{% added-in v="1.17" %}} `M_APPSERVICE_LOGIN_UNSUPPORTED`: an application service + used the `m.login.application_service` type, but the server doesn't support logging + in via the Legacy authentication API. content: application/json: schema: diff --git a/data/api/client-server/registration.yaml b/data/api/client-server/registration.yaml index e7ede561..7a923f9e 100644 --- a/data/api/client-server/registration.yaml +++ b/data/api/client-server/registration.yaml @@ -60,6 +60,18 @@ paths: Any user ID returned by this API must conform to the grammar given in the [Matrix specification](/appendices/#user-identifiers). + + {{% boxes/note %}} + {{% added-in v="1.17" %}} + Even if the server doesn't support the Legacy authentication API, it + MUST support this endpoint for application services to be able to + [create users](/application-service-api/#server-admin-style-permissions). + + In that case application services MUST set the `"inhibit_login": true` + parameter as they cannot use it to log in as users. If the + `inhibit_login` parameter is not set to `true`, the server MUST return a + 400 HTTP status code with an `M_APPSERVICE_LOGIN_UNSUPPORTED` error code. + {{% /boxes/note %}} operationId: register parameters: - in: query @@ -203,6 +215,9 @@ paths: * `M_INVALID_USERNAME` : The desired user ID is not a valid user name. * `M_EXCLUSIVE` : The desired user ID is in the exclusive namespace claimed by an application service. + * {{% added-in v="1.17" %}} `M_APPSERVICE_LOGIN_UNSUPPORTED`: an application service + used the `m.login.application_service` type without setting `inhibit_login` to `true`, + but the server doesn't support logging in via the Legacy authentication API. These errors may be returned at any stage of the registration process, including after authentication if the requested user ID was registered From 9e959f3922f1b3594602a9832660ef70b6171e3a Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:59:18 +0000 Subject: [PATCH 02/19] Add a list of endpoints to the top of each spec (#2262) Fixes #784 Add a collapsible list of endpoints to the top of the page for each distinct spec. We do this by storing endpoint metadata on $page and creating a new partial, endpoints-toc.html, which renders it. --- assets/scss/_styles_project.scss | 65 +++++++++++++- .../internal/newsfragments/2262.clarification | 1 + content/application-service-api.md | 14 ++- content/client-server-api/_index.md | 90 +++++++++---------- content/identity-service-api.md | 16 ++-- content/push-gateway-api.md | 7 +- content/server-server-api.md | 79 ++++++++-------- layouts/_partials/endpoints-toc.html | 61 +++++++++++++ layouts/_partials/openapi/render-api.html | 12 ++- .../_partials/openapi/render-operation.html | 25 ++++++ layouts/_partials/spec-content.html | 14 +++ layouts/_shortcodes/cs-module.html | 29 +++++- layouts/_shortcodes/http-api.html | 16 +++- layouts/content.html | 4 - layouts/docs/list.html | 18 ++-- layouts/docs/single.html | 19 ++++ 16 files changed, 345 insertions(+), 125 deletions(-) create mode 100644 changelogs/internal/newsfragments/2262.clarification create mode 100644 layouts/_partials/endpoints-toc.html create mode 100644 layouts/_partials/spec-content.html delete mode 100644 layouts/content.html create mode 100644 layouts/docs/single.html diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index 0131f1f1..f20dc096 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -257,6 +257,69 @@ Custom SCSS for the Matrix spec } +.endpoints-toc { + summary { + cursor: pointer; + font-weight: $font-weight-bold; + font-size: 1.05rem; + margin-bottom: 0.5rem; + } + + .endpoint-list { + list-style: none; + padding-left: 0; + margin: 0; + } + + .endpoint-list li { + margin: 0.2rem 0; + } + + .endpoint-list a { + text-decoration: none; + color: inherit; + padding: 0.05rem 0.25rem; + border-radius: 0.2rem; + + &:hover { + background-color: $secondary-background; + } + } + + .endpoint-list .http-api-method { + margin-right: 0.35rem; + font-weight: $font-weight-bold; + } + + .endpoint-path { + font-family: $font-family-monospace; + color: $secondary; + } + + .endpoint-deprecated { + color: $danger; + font-weight: $font-weight-bold; + margin-left: 0.35rem; + } + + .endpoint-module { + &:not(:first-child) { + margin-top: 0.75rem; + } + } + + .endpoint-module-title { + // font-weight: $font-weight-bold; + font-size: 1.20rem; + margin-bottom: 0.35rem; + } +} + +.page-description { + margin-bottom: 1rem; + color: inherit; +} + /* Styles for alert boxes */ .alert { &.note { @@ -581,4 +644,4 @@ dd { .breadcrumb { margin: 0; } -} \ No newline at end of file +} diff --git a/changelogs/internal/newsfragments/2262.clarification b/changelogs/internal/newsfragments/2262.clarification new file mode 100644 index 00000000..117c2bec --- /dev/null +++ b/changelogs/internal/newsfragments/2262.clarification @@ -0,0 +1 @@ +Add a list of endpoints to the top of each spec page. \ No newline at end of file diff --git a/content/application-service-api.md b/content/application-service-api.md index 5f6b17ab..d1b9c638 100644 --- a/content/application-service-api.md +++ b/content/application-service-api.md @@ -2,16 +2,14 @@ title: "Application Service API" weight: 30 type: docs +description: | + The Matrix client-server API and server-server APIs provide a consistent, + self-contained federated messaging fabric but leave little room for custom + server-side behaviour such as gateways, filters, or extensible hooks. The + Application Service API defines a standard way to add this extensible + functionality, independent of the underlying homeserver implementation. --- -The Matrix client-server API and server-server APIs provide the means to -implement a consistent self-contained federated messaging fabric. -However, they provide limited means of implementing custom server-side -behaviour in Matrix (e.g. gateways, filters, extensible hooks etc). The -Application Service API (AS API) defines a standard API to allow such -extensible functionality to be implemented irrespective of the -underlying homeserver implementation. - ## Application Services Application services are passive and can only observe events from the diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 4c76d6a5..8f8092b5 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -2,14 +2,14 @@ title: "Client-Server API" weight: 10 type: docs +description: | + The client-server API allows clients to send messages, control rooms and + synchronise conversation history. It is designed to support both lightweight + clients which store no state and lazy-load data from the server as required, + as well as heavyweight clients which maintain a full local persistent copy of + server state. --- -The client-server API allows clients to -send messages, control rooms and synchronise conversation history. It is -designed to support both lightweight clients which store no state and -lazy-load data from the server as required - as well as heavyweight -clients which maintain a full local persistent copy of server state. - ## API Standards {{% boxes/note %}} @@ -3962,42 +3962,42 @@ operations and run in a resource constrained environment. Like embedded applications, they are not intended to be fully-fledged communication systems. -{{% cs-module name="instant_messaging" %}} -{{% cs-module name="rich_replies" %}} -{{% cs-module name="voip_events" %}} -{{% cs-module name="typing_notifications" %}} -{{% cs-module name="receipts" %}} -{{% cs-module name="read_markers" %}} -{{% cs-module name="presence" %}} -{{% cs-module name="content_repo" %}} -{{% cs-module name="send_to_device" %}} -{{% cs-module name="device_management" %}} -{{% cs-module name="end_to_end_encryption" %}} -{{% cs-module name="secrets" %}} -{{% cs-module name="history_visibility" %}} -{{% cs-module name="push" %}} -{{% cs-module name="third_party_invites" %}} -{{% cs-module name="search" %}} -{{% cs-module name="guest_access" %}} -{{% cs-module name="room_previews" %}} -{{% cs-module name="tags" %}} -{{% cs-module name="account_data" %}} -{{% cs-module name="admin" %}} -{{% cs-module name="event_context" %}} -{{% cs-module name="sso_login" %}} -{{% cs-module name="dm" %}} -{{% cs-module name="ignore_users" %}} -{{% cs-module name="stickers" %}} -{{% cs-module name="report_content" %}} -{{% cs-module name="third_party_networks" %}} -{{% cs-module name="openid" %}} -{{% cs-module name="server_acls" %}} -{{% cs-module name="mentions" %}} -{{% cs-module name="room_upgrades" %}} -{{% cs-module name="server_notices" %}} -{{% cs-module name="moderation_policies" %}} -{{% cs-module name="spaces" %}} -{{% cs-module name="event_replacements" %}} -{{% cs-module name="event_annotations" %}} -{{% cs-module name="threading" %}} -{{% cs-module name="reference_relations" %}} +{{% cs-module name="Instant Messaging" filename="instant_messaging" %}} +{{% cs-module name="Rich replies" filename="rich_replies" %}} +{{% cs-module name="Voice over IP" filename="voip_events" %}} +{{% cs-module name="Typing Notifications" filename="typing_notifications" %}} +{{% cs-module name="Receipts" filename="receipts" %}} +{{% cs-module name="Read and unread markers" filename="read_markers" %}} +{{% cs-module name="Presence" filename="presence" %}} +{{% cs-module name="Content repository" filename="content_repo" %}} +{{% cs-module name="Send-to-Device messaging" filename="send_to_device" %}} +{{% cs-module name="Device Management" filename="device_management" %}} +{{% cs-module name="End-to-End Encryption" filename="end_to_end_encryption" %}} +{{% cs-module name="Secrets" filename="secrets" %}} +{{% cs-module name="Room History Visibility" filename="history_visibility" %}} +{{% cs-module name="Push Notifications" filename="push" %}} +{{% cs-module name="Third-party invites" filename="third_party_invites" %}} +{{% cs-module name="Server Side Search" filename="search" %}} +{{% cs-module name="Guest Access" filename="guest_access" %}} +{{% cs-module name="Room Previews" filename="room_previews" %}} +{{% cs-module name="Room Tagging" filename="tags" %}} +{{% cs-module name="Client Config" filename="account_data" %}} +{{% cs-module name="Server Administration" filename="admin" %}} +{{% cs-module name="Event Context" filename="event_context" %}} +{{% cs-module name="SSO client login/authentication" filename="sso_login" %}} +{{% cs-module name="Direct Messaging" filename="dm" %}} +{{% cs-module name="Ignoring Users" filename="ignore_users" %}} +{{% cs-module name="Sticker Messages" filename="stickers" %}} +{{% cs-module name="Reporting Content" filename="report_content" %}} +{{% cs-module name="Third-party Networks" filename="third_party_networks" %}} +{{% cs-module name="OpenID" filename="openid" %}} +{{% cs-module name="Server Access Control Lists (ACLs) for rooms" filename="server_acls" %}} +{{% cs-module name="User and room mentions" filename="mentions" %}} +{{% cs-module name="Room Upgrades" filename="room_upgrades" %}} +{{% cs-module name="Server Notices" filename="server_notices" %}} +{{% cs-module name="Moderation policy lists" filename="moderation_policies" %}} +{{% cs-module name="Spaces" filename="spaces" %}} +{{% cs-module name="Event replacements" filename="event_replacements" %}} +{{% cs-module name="Event annotations and reactions" filename="event_annotations" %}} +{{% cs-module name="Threading" filename="threading" %}} +{{% cs-module name="Reference relations" filename="reference_relations" %}} diff --git a/content/identity-service-api.md b/content/identity-service-api.md index 3c20a12a..8946ad34 100644 --- a/content/identity-service-api.md +++ b/content/identity-service-api.md @@ -2,17 +2,15 @@ title: "Identity Service API" weight: 40 type: docs +description: | + The Matrix client-server and server-server APIs are largely expressed in + Matrix user identifiers. Sometimes it is useful to refer to users by other + (“third-party”) identifiers such as email addresses or phone numbers. The + Identity Service API describes how mappings between 3PIDs and Matrix user + IDs can be established, validated, and used; in practice this has been + applied to email addresses and phone numbers. --- -The Matrix client-server and server-server APIs are largely expressed in -Matrix user identifiers. From time to time, it is useful to refer to -users by other ("third-party") identifiers, or "3PID"s, e.g. their email -address or phone number. This Identity Service Specification describes -how mappings between third-party identifiers and Matrix user identifiers -can be established, validated, and used. This description technically -may apply to any 3PID, but in practice has only been applied -specifically to email addresses and phone numbers. - ## General principles The purpose of an identity server is to validate, store, and answer diff --git a/content/push-gateway-api.md b/content/push-gateway-api.md index 161cf24f..f74decd9 100644 --- a/content/push-gateway-api.md +++ b/content/push-gateway-api.md @@ -2,12 +2,11 @@ title: "Push Gateway API" weight: 50 type: docs +description: | + Clients may want to receive push notifications when events are received at the + homeserver. This is managed by a distinct entity called the Push Gateway. --- -Clients may want to receive push notifications when events are received -at the homeserver. This is managed by a distinct entity called the Push -Gateway. - ## Overview A client's homeserver forwards information about received events to the diff --git a/content/server-server-api.md b/content/server-server-api.md index ca1cdd2e..1ab7e3ba 100644 --- a/content/server-server-api.md +++ b/content/server-server-api.md @@ -2,49 +2,46 @@ title: "Server-Server API" weight: 20 type: docs +description: | + Matrix homeservers use the Federation APIs (also known as server-server APIs) + to communicate with each other. Homeservers use these APIs to push messages in + real-time, retrieve historic messages, and query profile or presence + information about users on other servers. The APIs are implemented over HTTPS, + with authentication provided by public key signatures both at the TLS + transport layer and in HTTP Authorization headers. + + There are three main kinds of communication that occur between + homeservers: + + Persistent Data Units (PDUs): + These events are broadcast from one homeserver to any others that have + joined the same room (identified by Room ID). They are persisted in + long-term storage and record the history of messages and state for a + room. + + Like email, it is the responsibility of the originating server of a PDU + to deliver that event to its recipient servers. However PDUs are signed + using the originating server's private key so that it is possible to + deliver them through third-party servers. + + Ephemeral Data Units (EDUs): + These events are pushed between pairs of homeservers. They are not + persisted and are not part of the history of a room, nor does the + receiving homeserver have to reply to them. + + Queries: + These are single request/response interactions between a given pair of + servers, initiated by one side sending an HTTPS GET request to obtain + some information, and responded by the other. They are not persisted and + contain no long-term significant history. They simply request a snapshot + state at the instant the query is made. + + EDUs and PDUs are further wrapped in an envelope called a Transaction, + which is transferred from the origin to the destination homeserver using + an HTTPS PUT request. + --- -Matrix homeservers use the Federation APIs (also known as server-server -APIs) to communicate with each other. Homeservers use these APIs to push -messages to each other in real-time, to retrieve historic messages from -each other, and to query profile and presence information about users on -each other's servers. - -The APIs are implemented using HTTPS requests between each of the -servers. These HTTPS requests are strongly authenticated using public -key signatures at the TLS transport layer and using public key -signatures in HTTP Authorization headers at the HTTP layer. - -There are three main kinds of communication that occur between -homeservers: - -Persistent Data Units (PDUs): -These events are broadcast from one homeserver to any others that have -joined the same room (identified by Room ID). They are persisted in -long-term storage and record the history of messages and state for a -room. - -Like email, it is the responsibility of the originating server of a PDU -to deliver that event to its recipient servers. However PDUs are signed -using the originating server's private key so that it is possible to -deliver them through third-party servers. - -Ephemeral Data Units (EDUs): -These events are pushed between pairs of homeservers. They are not -persisted and are not part of the history of a room, nor does the -receiving homeserver have to reply to them. - -Queries: -These are single request/response interactions between a given pair of -servers, initiated by one side sending an HTTPS GET request to obtain -some information, and responded by the other. They are not persisted and -contain no long-term significant history. They simply request a snapshot -state at the instant the query is made. - -EDUs and PDUs are further wrapped in an envelope called a Transaction, -which is transferred from the origin to the destination homeserver using -an HTTPS PUT request. - ## API standards The mandatory baseline for server-server communication in Matrix is diff --git a/layouts/_partials/endpoints-toc.html b/layouts/_partials/endpoints-toc.html new file mode 100644 index 00000000..f5a652ef --- /dev/null +++ b/layouts/_partials/endpoints-toc.html @@ -0,0 +1,61 @@ +{{/* + + Renders a list of API endpoints for the current page, given: + + The outer page's Scratch must contain an "api_endpoints" key, which is either + a slice of maps (a list of endpoint metadata dicts) or a map of module name -> + slice of endpoint metadata dicts (representing the API modules and the + endpoints they each contain). Each endpoint dict must contain the following + keys: + + * `anchor`: the HTML anchor for the endpoint + * `method`: the HTTP method + * `endpoint`: the endpoint path + * `summary`: a short summary of the endpoint + * `deprecated`: whether the endpoint is deprecated + * `module`: the CS API module name, if any, for grouping purposes. If empty, + the endpoint is considered "base" or "required". + +*/}} + +{{ $raw := .Scratch.Get "api_endpoints" }} +{{/* Normalize to a slice */}} +{{ $endpoints := slice }} +{{ if reflect.IsSlice $raw }} + {{ $endpoints = $raw }} +{{ else if reflect.IsMap $raw }} + {{ range $raw }} + {{ $endpoints = append $endpoints . }} + {{ end }} +{{ end }} +{{ if gt (len $endpoints) 0 }} +
+
+ List of Endpoints + {{/* Sort by module to group visually */}} + {{ $sorted := sort $endpoints "module" }} + {{ $current := "" }} + {{ range $sorted }} + {{ $mod := .module }} + {{/* Set a title for the base endpoints */}} + {{ if not $mod }}{{ $mod = "Required" }}{{ end }} + {{ if ne $mod $current }} + {{ if $current }}
{{ end }} +
+
{{ $mod }}
+
{{ end }} + + +{{ end }} diff --git a/layouts/_partials/openapi/render-api.html b/layouts/_partials/openapi/render-api.html index 608cfa33..92d2bdd8 100644 --- a/layouts/_partials/openapi/render-api.html +++ b/layouts/_partials/openapi/render-api.html @@ -7,6 +7,8 @@ of each value in `paths` to get a complete URL. * `anchor_base`: an optional prefix for the HTML IDs generated by this template. + * `page`: the (Hugo) Page object to store endpoint metadata in the Scratch of. Used to build the endpoints TOC. + * `module`: the current CS API module name, if any. Used to group endpoints in the TOC. This template replaces the old {{*_http_api}} template. @@ -15,6 +17,8 @@ {{ $api_data := index .api_data }} {{ $base_url := .base_url }} {{ $anchor_base := .anchor_base }} +{{ $page := .page }} +{{ $module := .module }} {{ range $path_name, $path_data := $api_data.paths }} @@ -26,28 +30,28 @@ {{ with $path_data.get }} - {{ $operation_params := merge $params (dict "method" "GET" "operation_data" . "anchor_base" $anchor_base) }} + {{ $operation_params := merge $params (dict "method" "GET" "operation_data" . "anchor_base" $anchor_base "page" $page "module" $module) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} {{ with $path_data.post }} - {{ $operation_params := merge $params (dict "method" "POST" "operation_data" . "anchor_base" $anchor_base) }} + {{ $operation_params := merge $params (dict "method" "POST" "operation_data" . "anchor_base" $anchor_base "page" $page "module" $module) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} {{ with $path_data.put }} - {{ $operation_params := merge $params (dict "method" "PUT" "operation_data" . "anchor_base" $anchor_base) }} + {{ $operation_params := merge $params (dict "method" "PUT" "operation_data" . "anchor_base" $anchor_base "page" $page "module" $module) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} {{ with $path_data.delete }} - {{ $operation_params := merge $params (dict "method" "DELETE" "operation_data" . "anchor_base" $anchor_base) }} + {{ $operation_params := merge $params (dict "method" "DELETE" "operation_data" . "anchor_base" $anchor_base "page" $page "module" $module) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} diff --git a/layouts/_partials/openapi/render-operation.html b/layouts/_partials/openapi/render-operation.html index c1e34ddf..d90a1d7e 100644 --- a/layouts/_partials/openapi/render-operation.html +++ b/layouts/_partials/openapi/render-operation.html @@ -7,6 +7,8 @@ * `operation_data`: the OpenAPI data for the operation * `anchor_base`: an optional prefix for the HTML IDs generated by this template. + * `page`: the (Hugo) Page object to store endpoint metadata in the Scratch of. Used to build the endpoints TOC. + * `module`: the current CS API module name, if any. Used to group endpoints in the TOC. This template renders the operation as a `
` containing: @@ -22,6 +24,8 @@ {{ $method := .method }} {{ $endpoint := .endpoint }} {{ $operation_data := .operation_data }} +{{ $page := .page }} +{{ $module := .module }} {{ $anchor := "" }} {{ if .anchor_base }} @@ -29,6 +33,27 @@ {{ end }} {{ $anchor = printf "%s%s%s" $anchor (lower $method) (anchorize $endpoint) }} +{{/* Collect endpoints for the on-page endpoints TOC */}} +{{ if $page }} + {{/* Store each endpoint's metadata in a scratch variable */}} + {{ $entry := dict "anchor" $anchor "method" $method "endpoint" $endpoint "summary" $operation_data.summary "deprecated" $operation_data.deprecated "module" $module }} + {{ if not ($page.Scratch.Get "api_endpoints_seen") }} + {{ $page.Scratch.Set "api_endpoints_seen" dict }} + {{ end }} + {{/* Keep a map of seen endpoints. This is necessary as this partial may be + rendered multiple times for the same endpoint (e.g. in the TOC and + in the main content), leading to duplicates. */}} + {{ $seen := $page.Scratch.Get "api_endpoints_seen" }} + {{ $key := printf "%s|%s" $method $endpoint }} + {{ if not (index $seen $key) }} + {{ if not (reflect.IsSlice ($page.Scratch.Get "api_endpoints")) }} + {{ $page.Scratch.Set "api_endpoints" (slice) }} + {{ end }} + {{ $page.Scratch.Add "api_endpoints" (slice $entry) }} + {{ $page.Scratch.SetInMap "api_endpoints_seen" $key true }} + {{ end }} +{{ end }} +
diff --git a/layouts/_partials/spec-content.html b/layouts/_partials/spec-content.html new file mode 100644 index 00000000..23e5a807 --- /dev/null +++ b/layouts/_partials/spec-content.html @@ -0,0 +1,14 @@ +{{- /* Shared render for spec pages: title, optional description, endpoints list, body, and last-mod info. */ -}} +
+

{{ .Title }}

+ {{ with .Params.description }}

{{ . | markdownify }}

{{ end }} + + {{/* + Render an endpoints table of contents. This is the main difference + between our templates (which call the spec-content partial) and the default + Docsy template. + */}} + {{ partial "endpoints-toc.html" . }} + + {{ .Content }} +
\ No newline at end of file diff --git a/layouts/_shortcodes/cs-module.html b/layouts/_shortcodes/cs-module.html index 52c9a5d9..6385d914 100644 --- a/layouts/_shortcodes/cs-module.html +++ b/layouts/_shortcodes/cs-module.html @@ -3,14 +3,39 @@ This template is used to render a Client-Server API Module. Modules are defined alongside the `_index.md` for the CS API. - The `name` parameter is the file name without extension. + The following parameters are expected: + + * `filename` the name of the module file to render, without extension (i.e. `spaces`). + * `name` the display name of the module (i.e. `Spaces`). */}} {{ $name := .Params.name }} +{{ $filename := .Params.filename }} {{ with .Site.GetPage "client-server-api/modules" }} - {{ with .Resources.GetMatch (printf "%s%s" $name ".md") }} + {{ with .Resources.GetMatch (printf "%s%s" $filename ".md") }} + {{/* Preserve previous scratch values so nested modules don't leak */}} + {{ $prevPage := .Scratch.Get "endpoint_page" }} + {{ $prevModule := .Scratch.Get "endpoint_module" }} + + {{/* Allow endpoints rendered in the module to accumulate on the parent page */}} + {{ .Scratch.Set "endpoint_page" $.Page }} + {{/* Name the module for grouping in the endpoints list */}} + {{ .Scratch.Set "endpoint_module" $name }} + {{ .RenderShortcodes }} + + {{/* Restore previous scratch values */}} + {{ if $prevPage }} + {{ .Scratch.Set "endpoint_page" $prevPage }} + {{ else }} + {{ .Scratch.Delete "endpoint_page" }} + {{ end }} + {{ if $prevModule }} + {{ .Scratch.Set "endpoint_module" $prevModule }} + {{ else }} + {{ .Scratch.Delete "endpoint_module" }} + {{ end }} {{ end }} {{ end }} diff --git a/layouts/_shortcodes/http-api.html b/layouts/_shortcodes/http-api.html index b5201c49..a5268323 100644 --- a/layouts/_shortcodes/http-api.html +++ b/layouts/_shortcodes/http-api.html @@ -23,6 +23,20 @@ {{ $api := .Params.api}} {{ $anchor_base := .Params.anchor_base}} +{{/* + + Figure out which Page object to pass to the `openapi/render-api` partial. + Either our own, or one stored under `endpoint_page` in the Scratch, if one + exists. + +*/}} +{{ $target_page := .Page }} +{{ with .Page.Scratch.Get "endpoint_page" }} + {{ $target_page = . }} +{{ end }} + +{{ $module_name := .Page.Scratch.Get "endpoint_module" }} + {{ $api_data := index .Site.Data.api .Params.spec .Params.api }} {{ $base_url := (index $api_data.servers 0).variables.basePath.default }} {{ $path := delimit (slice "api" $spec $api) "/" }} @@ -30,4 +44,4 @@ {{ $api_data = partial "json-schema/resolve-refs" (dict "schema" $api_data "path" $path) }} {{ $api_data = partial "json-schema/resolve-allof" $api_data }} -{{ partial "openapi/render-api" (dict "api_data" $api_data "base_url" $base_url "anchor_base" $anchor_base) }} +{{ partial "openapi/render-api" (dict "api_data" $api_data "base_url" $base_url "anchor_base" $anchor_base "page" $target_page "module" $module_name) }} diff --git a/layouts/content.html b/layouts/content.html deleted file mode 100644 index e58073f3..00000000 --- a/layouts/content.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

{{ .Title }}

- {{ .Content }} -
diff --git a/layouts/docs/list.html b/layouts/docs/list.html index 01145138..6bd0dcb5 100644 --- a/layouts/docs/list.html +++ b/layouts/docs/list.html @@ -1,13 +1,19 @@ {{/* - A simplified version of the list.html partial in Docsy. + Override the `layouts/docs/list.html` template from Docsy. While this template + is equivalent to `single.html`, it's necessary to override both templates to + avoid falling back to the default Docsy templates. + + https://gohugo.io/templates/types/#list + + We use this list template to render the Client-Server API spec page and each + of its modules. + + The contents of the "main" block below are inserted into the `./baseof.html` + base template. */}} {{ define "main" }} -
-

{{ .Title }}

- {{ with .Params.description }}
{{ . | markdownify }}
{{ end }} - {{ .Content }} -
+ {{ partial "spec-content.html" . }} {{ end }} diff --git a/layouts/docs/single.html b/layouts/docs/single.html new file mode 100644 index 00000000..67b0dae0 --- /dev/null +++ b/layouts/docs/single.html @@ -0,0 +1,19 @@ +{{/* + + Override the `layouts/docs/single.html` template from Docsy. While this template + is equivalent to `list.html`, it's necessary to override both templates to + avoid falling back to the default Docsy templates. + + https://gohugo.io/templates/types/#single + + We use this single template to render the all API spec pages *except* the + Client-Server API. The Client-Server API spec page contains modules, and thus + is handled separately, via the `layouts/docs/list.html` template. + + The contents of the "main" block below are inserted into the `./baseof.html` + base template. + +*/}} +{{ define "main" }} + {{ partial "spec-content.html" . }} +{{ end }} From a1c930d0d1cb0e6046896e13756d40cd122975b4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 18 Dec 2025 15:53:35 +0000 Subject: [PATCH 03/19] Prepare v1.17 release --- .../newsfragments/2213.clarification | 1 - .../newsfragments/2221.feature | 1 - .../newsfragments/2267.feature | 1 - .../client_server/newsfragments/2186.removal | 1 - .../newsfragments/2214.clarification | 1 - .../newsfragments/2215.clarification | 1 - .../newsfragments/2216.clarification | 1 - .../newsfragments/2217.clarification | 1 - .../client_server/newsfragments/2221.feature | 1 - .../newsfragments/2223.clarification | 1 - .../newsfragments/2224.clarification | 1 - .../newsfragments/2225.clarification | 1 - .../newsfragments/2227.clarification | 1 - .../newsfragments/2231.clarification | 1 - .../newsfragments/2232.clarification | 1 - .../newsfragments/2233.clarification | 1 - .../client_server/newsfragments/2234.feature | 1 - .../newsfragments/2240.clarification | 1 - .../newsfragments/2245.clarification | 1 - .../newsfragments/2246.clarification | 1 - .../newsfragments/2250.clarification | 1 - .../newsfragments/2255.clarification | 1 - .../client_server/newsfragments/2267.feature | 1 - .../internal/newsfragments/2219.clarification | 1 - .../internal/newsfragments/2226.clarification | 1 - .../internal/newsfragments/2238.clarification | 1 - .../internal/newsfragments/2239.clarification | 1 - .../internal/newsfragments/2241.clarification | 1 - .../internal/newsfragments/2242.clarification | 1 - .../internal/newsfragments/2256.clarification | 1 - .../internal/newsfragments/2258.clarification | 1 - .../internal/newsfragments/2259.clarification | 1 - .../internal/newsfragments/2260.clarification | 1 - .../internal/newsfragments/2261.clarification | 1 - .../internal/newsfragments/2262.clarification | 1 - .../internal/newsfragments/2264.clarification | 1 - .../internal/newsfragments/2268.clarification | 1 - .../newsfragments/2220.clarification | 1 - .../newsfragments/2249.clarification | 1 - config/_default/hugo.toml | 6 +- content/changelog/v1.17.md | 92 +++++++++++++++++++ 41 files changed, 95 insertions(+), 42 deletions(-) delete mode 100644 changelogs/application_service/newsfragments/2213.clarification delete mode 100644 changelogs/application_service/newsfragments/2221.feature delete mode 100644 changelogs/application_service/newsfragments/2267.feature delete mode 100644 changelogs/client_server/newsfragments/2186.removal delete mode 100644 changelogs/client_server/newsfragments/2214.clarification delete mode 100644 changelogs/client_server/newsfragments/2215.clarification delete mode 100644 changelogs/client_server/newsfragments/2216.clarification delete mode 100644 changelogs/client_server/newsfragments/2217.clarification delete mode 100644 changelogs/client_server/newsfragments/2221.feature delete mode 100644 changelogs/client_server/newsfragments/2223.clarification delete mode 100644 changelogs/client_server/newsfragments/2224.clarification delete mode 100644 changelogs/client_server/newsfragments/2225.clarification delete mode 100644 changelogs/client_server/newsfragments/2227.clarification delete mode 100644 changelogs/client_server/newsfragments/2231.clarification delete mode 100644 changelogs/client_server/newsfragments/2232.clarification delete mode 100644 changelogs/client_server/newsfragments/2233.clarification delete mode 100644 changelogs/client_server/newsfragments/2234.feature delete mode 100644 changelogs/client_server/newsfragments/2240.clarification delete mode 100644 changelogs/client_server/newsfragments/2245.clarification delete mode 100644 changelogs/client_server/newsfragments/2246.clarification delete mode 100644 changelogs/client_server/newsfragments/2250.clarification delete mode 100644 changelogs/client_server/newsfragments/2255.clarification delete mode 100644 changelogs/client_server/newsfragments/2267.feature delete mode 100644 changelogs/internal/newsfragments/2219.clarification delete mode 100644 changelogs/internal/newsfragments/2226.clarification delete mode 100644 changelogs/internal/newsfragments/2238.clarification delete mode 100644 changelogs/internal/newsfragments/2239.clarification delete mode 100644 changelogs/internal/newsfragments/2241.clarification delete mode 100644 changelogs/internal/newsfragments/2242.clarification delete mode 100644 changelogs/internal/newsfragments/2256.clarification delete mode 100644 changelogs/internal/newsfragments/2258.clarification delete mode 100644 changelogs/internal/newsfragments/2259.clarification delete mode 100644 changelogs/internal/newsfragments/2260.clarification delete mode 100644 changelogs/internal/newsfragments/2261.clarification delete mode 100644 changelogs/internal/newsfragments/2262.clarification delete mode 100644 changelogs/internal/newsfragments/2264.clarification delete mode 100644 changelogs/internal/newsfragments/2268.clarification delete mode 100644 changelogs/room_versions/newsfragments/2220.clarification delete mode 100644 changelogs/room_versions/newsfragments/2249.clarification create mode 100644 content/changelog/v1.17.md diff --git a/changelogs/application_service/newsfragments/2213.clarification b/changelogs/application_service/newsfragments/2213.clarification deleted file mode 100644 index a8c06342..00000000 --- a/changelogs/application_service/newsfragments/2213.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix JSON formatting in the "Server admin style permissions" examples. diff --git a/changelogs/application_service/newsfragments/2221.feature b/changelogs/application_service/newsfragments/2221.feature deleted file mode 100644 index 400d98ef..00000000 --- a/changelogs/application_service/newsfragments/2221.feature +++ /dev/null @@ -1 +0,0 @@ -Allow application services to masquerade as specific devices belonging to users, as per [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326). \ No newline at end of file diff --git a/changelogs/application_service/newsfragments/2267.feature b/changelogs/application_service/newsfragments/2267.feature deleted file mode 100644 index 92a03203..00000000 --- a/changelogs/application_service/newsfragments/2267.feature +++ /dev/null @@ -1 +0,0 @@ -Allow application services to manage devices and register users without the legacy authentication API, as per [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190). diff --git a/changelogs/client_server/newsfragments/2186.removal b/changelogs/client_server/newsfragments/2186.removal deleted file mode 100644 index c40f001f..00000000 --- a/changelogs/client_server/newsfragments/2186.removal +++ /dev/null @@ -1 +0,0 @@ -Remove legacy mentions, as per [MSC4210](https://github.com/matrix-org/matrix-spec-proposals/issues/4210). diff --git a/changelogs/client_server/newsfragments/2214.clarification b/changelogs/client_server/newsfragments/2214.clarification deleted file mode 100644 index 50121eaa..00000000 --- a/changelogs/client_server/newsfragments/2214.clarification +++ /dev/null @@ -1 +0,0 @@ -Push rule IDs are globally unique within their kind. diff --git a/changelogs/client_server/newsfragments/2215.clarification b/changelogs/client_server/newsfragments/2215.clarification deleted file mode 100644 index f76c952d..00000000 --- a/changelogs/client_server/newsfragments/2215.clarification +++ /dev/null @@ -1 +0,0 @@ -Don't advertise `creator` field in description of room creation. diff --git a/changelogs/client_server/newsfragments/2216.clarification b/changelogs/client_server/newsfragments/2216.clarification deleted file mode 100644 index a777ad87..00000000 --- a/changelogs/client_server/newsfragments/2216.clarification +++ /dev/null @@ -1 +0,0 @@ -`room_id` is required for peeking via `/_matrix/client/v3/events`. diff --git a/changelogs/client_server/newsfragments/2217.clarification b/changelogs/client_server/newsfragments/2217.clarification deleted file mode 100644 index ea895054..00000000 --- a/changelogs/client_server/newsfragments/2217.clarification +++ /dev/null @@ -1 +0,0 @@ -The `server-name` segment of MXC URIs is sanitised differently from the `media-id` segment. diff --git a/changelogs/client_server/newsfragments/2221.feature b/changelogs/client_server/newsfragments/2221.feature deleted file mode 100644 index 400d98ef..00000000 --- a/changelogs/client_server/newsfragments/2221.feature +++ /dev/null @@ -1 +0,0 @@ -Allow application services to masquerade as specific devices belonging to users, as per [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/2223.clarification b/changelogs/client_server/newsfragments/2223.clarification deleted file mode 100644 index 401a1f95..00000000 --- a/changelogs/client_server/newsfragments/2223.clarification +++ /dev/null @@ -1 +0,0 @@ -Add note to each endpoint that uses capability negotiation. diff --git a/changelogs/client_server/newsfragments/2224.clarification b/changelogs/client_server/newsfragments/2224.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/2224.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/2225.clarification b/changelogs/client_server/newsfragments/2225.clarification deleted file mode 100644 index 6a62eb99..00000000 --- a/changelogs/client_server/newsfragments/2225.clarification +++ /dev/null @@ -1 +0,0 @@ -Additional OpenGraph properties can be present in URL previews. diff --git a/changelogs/client_server/newsfragments/2227.clarification b/changelogs/client_server/newsfragments/2227.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/2227.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/2231.clarification b/changelogs/client_server/newsfragments/2231.clarification deleted file mode 100644 index 58343ac0..00000000 --- a/changelogs/client_server/newsfragments/2231.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the special casing of membership events and redactions in power levels. diff --git a/changelogs/client_server/newsfragments/2232.clarification b/changelogs/client_server/newsfragments/2232.clarification deleted file mode 100644 index 78304051..00000000 --- a/changelogs/client_server/newsfragments/2232.clarification +++ /dev/null @@ -1 +0,0 @@ -`M_RESOURCE_LIMIT_EXCEEDED` is now listed as a common error code. diff --git a/changelogs/client_server/newsfragments/2233.clarification b/changelogs/client_server/newsfragments/2233.clarification deleted file mode 100644 index 9c4afa28..00000000 --- a/changelogs/client_server/newsfragments/2233.clarification +++ /dev/null @@ -1 +0,0 @@ -Add `m.login.terms` to enumeration of authentication types. diff --git a/changelogs/client_server/newsfragments/2234.feature b/changelogs/client_server/newsfragments/2234.feature deleted file mode 100644 index 2dd33f67..00000000 --- a/changelogs/client_server/newsfragments/2234.feature +++ /dev/null @@ -1 +0,0 @@ -Add the `m.oauth` authentication type for User-Interactive Authentication as per [MSC4312](https://github.com/matrix-org/matrix-spec-proposals/pull/4312). diff --git a/changelogs/client_server/newsfragments/2240.clarification b/changelogs/client_server/newsfragments/2240.clarification deleted file mode 100644 index 07081f28..00000000 --- a/changelogs/client_server/newsfragments/2240.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify how to use `state_after` ahead of declaring full support for its spec version. diff --git a/changelogs/client_server/newsfragments/2245.clarification b/changelogs/client_server/newsfragments/2245.clarification deleted file mode 100644 index 2d0453a2..00000000 --- a/changelogs/client_server/newsfragments/2245.clarification +++ /dev/null @@ -1 +0,0 @@ -`device_one_time_keys_count` is only optional if no unclaimed one-time keys exist. diff --git a/changelogs/client_server/newsfragments/2246.clarification b/changelogs/client_server/newsfragments/2246.clarification deleted file mode 100644 index 7d2625a6..00000000 --- a/changelogs/client_server/newsfragments/2246.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that servers may choose not to use `M_USER_DEACTIVATED` at login time, for example for privacy reasons when they can't authenticate deactivated users. diff --git a/changelogs/client_server/newsfragments/2250.clarification b/changelogs/client_server/newsfragments/2250.clarification deleted file mode 100644 index 12efe875..00000000 --- a/changelogs/client_server/newsfragments/2250.clarification +++ /dev/null @@ -1 +0,0 @@ -Minor grammatical fix in the Secrets module description. \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/2255.clarification b/changelogs/client_server/newsfragments/2255.clarification deleted file mode 100644 index 4429fccf..00000000 --- a/changelogs/client_server/newsfragments/2255.clarification +++ /dev/null @@ -1 +0,0 @@ -Usage of the `event_id_only` format for push notifications is not mandatory. diff --git a/changelogs/client_server/newsfragments/2267.feature b/changelogs/client_server/newsfragments/2267.feature deleted file mode 100644 index 92a03203..00000000 --- a/changelogs/client_server/newsfragments/2267.feature +++ /dev/null @@ -1 +0,0 @@ -Allow application services to manage devices and register users without the legacy authentication API, as per [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190). diff --git a/changelogs/internal/newsfragments/2219.clarification b/changelogs/internal/newsfragments/2219.clarification deleted file mode 100644 index ef0721b4..00000000 --- a/changelogs/internal/newsfragments/2219.clarification +++ /dev/null @@ -1 +0,0 @@ -Swapped icon for X (fka. twitter) to updated logo in footer. \ No newline at end of file diff --git a/changelogs/internal/newsfragments/2226.clarification b/changelogs/internal/newsfragments/2226.clarification deleted file mode 100644 index 68758818..00000000 --- a/changelogs/internal/newsfragments/2226.clarification +++ /dev/null @@ -1 +0,0 @@ -Inline Olm & Megolm specifications. diff --git a/changelogs/internal/newsfragments/2238.clarification b/changelogs/internal/newsfragments/2238.clarification deleted file mode 100644 index b91abc53..00000000 --- a/changelogs/internal/newsfragments/2238.clarification +++ /dev/null @@ -1 +0,0 @@ -Silence failing redocly-cli rule. diff --git a/changelogs/internal/newsfragments/2239.clarification b/changelogs/internal/newsfragments/2239.clarification deleted file mode 100644 index 6b8cf712..00000000 --- a/changelogs/internal/newsfragments/2239.clarification +++ /dev/null @@ -1 +0,0 @@ -Use NPM Trusted Publishers for publishing `@matrix-org/spec` to npm. \ No newline at end of file diff --git a/changelogs/internal/newsfragments/2241.clarification b/changelogs/internal/newsfragments/2241.clarification deleted file mode 100644 index 68758818..00000000 --- a/changelogs/internal/newsfragments/2241.clarification +++ /dev/null @@ -1 +0,0 @@ -Inline Olm & Megolm specifications. diff --git a/changelogs/internal/newsfragments/2242.clarification b/changelogs/internal/newsfragments/2242.clarification deleted file mode 100644 index 68758818..00000000 --- a/changelogs/internal/newsfragments/2242.clarification +++ /dev/null @@ -1 +0,0 @@ -Inline Olm & Megolm specifications. diff --git a/changelogs/internal/newsfragments/2256.clarification b/changelogs/internal/newsfragments/2256.clarification deleted file mode 100644 index 468f55d5..00000000 --- a/changelogs/internal/newsfragments/2256.clarification +++ /dev/null @@ -1 +0,0 @@ -Add version picker in the navbar. diff --git a/changelogs/internal/newsfragments/2258.clarification b/changelogs/internal/newsfragments/2258.clarification deleted file mode 100644 index 468f55d5..00000000 --- a/changelogs/internal/newsfragments/2258.clarification +++ /dev/null @@ -1 +0,0 @@ -Add version picker in the navbar. diff --git a/changelogs/internal/newsfragments/2259.clarification b/changelogs/internal/newsfragments/2259.clarification deleted file mode 100644 index 468f55d5..00000000 --- a/changelogs/internal/newsfragments/2259.clarification +++ /dev/null @@ -1 +0,0 @@ -Add version picker in the navbar. diff --git a/changelogs/internal/newsfragments/2260.clarification b/changelogs/internal/newsfragments/2260.clarification deleted file mode 100644 index de578d64..00000000 --- a/changelogs/internal/newsfragments/2260.clarification +++ /dev/null @@ -1 +0,0 @@ -Add version picker in the navbar. \ No newline at end of file diff --git a/changelogs/internal/newsfragments/2261.clarification b/changelogs/internal/newsfragments/2261.clarification deleted file mode 100644 index 468f55d5..00000000 --- a/changelogs/internal/newsfragments/2261.clarification +++ /dev/null @@ -1 +0,0 @@ -Add version picker in the navbar. diff --git a/changelogs/internal/newsfragments/2262.clarification b/changelogs/internal/newsfragments/2262.clarification deleted file mode 100644 index 117c2bec..00000000 --- a/changelogs/internal/newsfragments/2262.clarification +++ /dev/null @@ -1 +0,0 @@ -Add a list of endpoints to the top of each spec page. \ No newline at end of file diff --git a/changelogs/internal/newsfragments/2264.clarification b/changelogs/internal/newsfragments/2264.clarification deleted file mode 100644 index 468f55d5..00000000 --- a/changelogs/internal/newsfragments/2264.clarification +++ /dev/null @@ -1 +0,0 @@ -Add version picker in the navbar. diff --git a/changelogs/internal/newsfragments/2268.clarification b/changelogs/internal/newsfragments/2268.clarification deleted file mode 100644 index 468f55d5..00000000 --- a/changelogs/internal/newsfragments/2268.clarification +++ /dev/null @@ -1 +0,0 @@ -Add version picker in the navbar. diff --git a/changelogs/room_versions/newsfragments/2220.clarification b/changelogs/room_versions/newsfragments/2220.clarification deleted file mode 100644 index 4141e31a..00000000 --- a/changelogs/room_versions/newsfragments/2220.clarification +++ /dev/null @@ -1 +0,0 @@ -In room versions 8 through 12, clarify that "sufficient permission to invite users" on restricted joins also includes being a joined member of the room. \ No newline at end of file diff --git a/changelogs/room_versions/newsfragments/2249.clarification b/changelogs/room_versions/newsfragments/2249.clarification deleted file mode 100644 index 7578edc3..00000000 --- a/changelogs/room_versions/newsfragments/2249.clarification +++ /dev/null @@ -1 +0,0 @@ -In room versions 3 through 12, clarify that when you have the power to redact, it is possible to redact events that you don't have the power to send. \ No newline at end of file diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml index b09b9562..a1501ac1 100644 --- a/config/_default/hugo.toml +++ b/config/_default/hugo.toml @@ -70,13 +70,13 @@ copyright = "The Matrix.org Foundation CIC" [params.version] # must be one of "unstable", "current", "historical" # this is used to decide whether to show a banner pointing to the current release -status = "unstable" +status = "stable" # A URL pointing to the latest, stable release of the spec. To be shown in the unstable version warning banner. current_version_url = "https://spec.matrix.org/latest" # The following is used when status = "stable", and is displayed in various UI elements on a released version # of the spec. -# major = "1" -# minor = "16" +major = "1" +minor = "17" [[params.versions]] # We must include this parameter to enable docsy's version picker in the navbar. The picker diff --git a/content/changelog/v1.17.md b/content/changelog/v1.17.md new file mode 100644 index 00000000..3597f7ba --- /dev/null +++ b/content/changelog/v1.17.md @@ -0,0 +1,92 @@ +--- +title: v1.17 Changelog +linkTitle: v1.17 +type: docs +layout: changelog +outputs: + - html + - checklist +date: 2025-12-18 +--- + +## Client-Server API + +**Removed Endpoints** + +- Remove legacy mentions, as per [MSC4210](https://github.com/matrix-org/matrix-spec-proposals/issues/4210). ([#2186](https://github.com/matrix-org/matrix-spec/issues/2186)) + +**Backwards Compatible Changes** + +- Allow application services to masquerade as specific devices belonging to users, as per [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326). ([#2221](https://github.com/matrix-org/matrix-spec/issues/2221)) +- Add the `m.oauth` authentication type for User-Interactive Authentication as per [MSC4312](https://github.com/matrix-org/matrix-spec-proposals/pull/4312). ([#2234](https://github.com/matrix-org/matrix-spec/issues/2234)) +- Allow application services to manage devices and register users without the legacy authentication API, as per [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190). ([#2267](https://github.com/matrix-org/matrix-spec/issues/2267)) + +**Spec Clarifications** + +- Push rule IDs are globally unique within their kind. ([#2214](https://github.com/matrix-org/matrix-spec/issues/2214)) +- Don't advertise `creator` field in description of room creation. ([#2215](https://github.com/matrix-org/matrix-spec/issues/2215)) +- `room_id` is required for peeking via `/_matrix/client/v3/events`. ([#2216](https://github.com/matrix-org/matrix-spec/issues/2216)) +- The `server-name` segment of MXC URIs is sanitised differently from the `media-id` segment. ([#2217](https://github.com/matrix-org/matrix-spec/issues/2217)) +- Add note to each endpoint that uses capability negotiation. ([#2223](https://github.com/matrix-org/matrix-spec/issues/2223)) +- Fix various typos throughout the specification. ([#2224](https://github.com/matrix-org/matrix-spec/issues/2224), [#2227](https://github.com/matrix-org/matrix-spec/issues/2227)) +- Additional OpenGraph properties can be present in URL previews. ([#2225](https://github.com/matrix-org/matrix-spec/issues/2225)) +- Clarify the special casing of membership events and redactions in power levels. ([#2231](https://github.com/matrix-org/matrix-spec/issues/2231)) +- `M_RESOURCE_LIMIT_EXCEEDED` is now listed as a common error code. ([#2232](https://github.com/matrix-org/matrix-spec/issues/2232)) +- Add `m.login.terms` to enumeration of authentication types. ([#2233](https://github.com/matrix-org/matrix-spec/issues/2233)) +- Clarify how to use `state_after` ahead of declaring full support for its spec version. ([#2240](https://github.com/matrix-org/matrix-spec/issues/2240)) +- `device_one_time_keys_count` is only optional if no unclaimed one-time keys exist. ([#2245](https://github.com/matrix-org/matrix-spec/issues/2245)) +- Clarify that servers may choose not to use `M_USER_DEACTIVATED` at login time, for example for privacy reasons when they can't authenticate deactivated users. ([#2246](https://github.com/matrix-org/matrix-spec/issues/2246)) +- Minor grammatical fix in the Secrets module description. ([#2250](https://github.com/matrix-org/matrix-spec/issues/2250)) +- Usage of the `event_id_only` format for push notifications is not mandatory. ([#2255](https://github.com/matrix-org/matrix-spec/issues/2255)) + + +## Server-Server API + +No significant changes. + + +## Application Service API + +**Backwards Compatible Changes** + +- Allow application services to masquerade as specific devices belonging to users, as per [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326). ([#2221](https://github.com/matrix-org/matrix-spec/issues/2221)) +- Allow application services to manage devices and register users without the legacy authentication API, as per [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190). ([#2267](https://github.com/matrix-org/matrix-spec/issues/2267)) + +**Spec Clarifications** + +- Fix JSON formatting in the "Server admin style permissions" examples. ([#2213](https://github.com/matrix-org/matrix-spec/issues/2213)) + + +## Identity Service API + +No significant changes. + + +## Push Gateway API + +No significant changes. + + +## Room Versions + +**Spec Clarifications** + +- In room versions 8 through 12, clarify that "sufficient permission to invite users" on restricted joins also includes being a joined member of the room. ([#2220](https://github.com/matrix-org/matrix-spec/issues/2220)) +- In room versions 3 through 12, clarify that when you have the power to redact, it is possible to redact events that you don't have the power to send. ([#2249](https://github.com/matrix-org/matrix-spec/issues/2249)) + + +## Appendices + +No significant changes. + + +## Internal Changes/Tooling + +**Spec Clarifications** + +- Swapped icon for X (fka. twitter) to updated logo in footer. ([#2219](https://github.com/matrix-org/matrix-spec/issues/2219)) +- Inline Olm & Megolm specifications. ([#2226](https://github.com/matrix-org/matrix-spec/issues/2226), [#2241](https://github.com/matrix-org/matrix-spec/issues/2241), [#2242](https://github.com/matrix-org/matrix-spec/issues/2242)) +- Silence failing redocly-cli rule. ([#2238](https://github.com/matrix-org/matrix-spec/issues/2238)) +- Use NPM Trusted Publishers for publishing `@matrix-org/spec` to npm. ([#2239](https://github.com/matrix-org/matrix-spec/issues/2239)) +- Add version picker in the navbar. ([#2256](https://github.com/matrix-org/matrix-spec/issues/2256), [#2258](https://github.com/matrix-org/matrix-spec/issues/2258), [#2259](https://github.com/matrix-org/matrix-spec/issues/2259), [#2260](https://github.com/matrix-org/matrix-spec/issues/2260), [#2261](https://github.com/matrix-org/matrix-spec/issues/2261), [#2264](https://github.com/matrix-org/matrix-spec/issues/2264), [#2268](https://github.com/matrix-org/matrix-spec/issues/2268)) +- Add a list of endpoints to the top of each spec page. ([#2262](https://github.com/matrix-org/matrix-spec/issues/2262)) From 27315feb178a7db6e490ae446065085e3c38f214 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 18 Dec 2025 15:57:59 +0000 Subject: [PATCH 04/19] Minor changelog edits --- content/changelog/v1.17.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/changelog/v1.17.md b/content/changelog/v1.17.md index 3597f7ba..cd3378e4 100644 --- a/content/changelog/v1.17.md +++ b/content/changelog/v1.17.md @@ -28,7 +28,6 @@ date: 2025-12-18 - `room_id` is required for peeking via `/_matrix/client/v3/events`. ([#2216](https://github.com/matrix-org/matrix-spec/issues/2216)) - The `server-name` segment of MXC URIs is sanitised differently from the `media-id` segment. ([#2217](https://github.com/matrix-org/matrix-spec/issues/2217)) - Add note to each endpoint that uses capability negotiation. ([#2223](https://github.com/matrix-org/matrix-spec/issues/2223)) -- Fix various typos throughout the specification. ([#2224](https://github.com/matrix-org/matrix-spec/issues/2224), [#2227](https://github.com/matrix-org/matrix-spec/issues/2227)) - Additional OpenGraph properties can be present in URL previews. ([#2225](https://github.com/matrix-org/matrix-spec/issues/2225)) - Clarify the special casing of membership events and redactions in power levels. ([#2231](https://github.com/matrix-org/matrix-spec/issues/2231)) - `M_RESOURCE_LIMIT_EXCEEDED` is now listed as a common error code. ([#2232](https://github.com/matrix-org/matrix-spec/issues/2232)) @@ -36,8 +35,8 @@ date: 2025-12-18 - Clarify how to use `state_after` ahead of declaring full support for its spec version. ([#2240](https://github.com/matrix-org/matrix-spec/issues/2240)) - `device_one_time_keys_count` is only optional if no unclaimed one-time keys exist. ([#2245](https://github.com/matrix-org/matrix-spec/issues/2245)) - Clarify that servers may choose not to use `M_USER_DEACTIVATED` at login time, for example for privacy reasons when they can't authenticate deactivated users. ([#2246](https://github.com/matrix-org/matrix-spec/issues/2246)) -- Minor grammatical fix in the Secrets module description. ([#2250](https://github.com/matrix-org/matrix-spec/issues/2250)) - Usage of the `event_id_only` format for push notifications is not mandatory. ([#2255](https://github.com/matrix-org/matrix-spec/issues/2255)) +- Fix various typos throughout the specification. ([#2224](https://github.com/matrix-org/matrix-spec/issues/2224), [#2227](https://github.com/matrix-org/matrix-spec/issues/2227), [#2250](https://github.com/matrix-org/matrix-spec/issues/2250)) ## Server-Server API From ce5ae4d371718f8798c4e1f8961bf9533a8048e2 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 18 Dec 2025 16:07:32 +0000 Subject: [PATCH 05/19] missing comma --- content/changelog/v1.17.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/changelog/v1.17.md b/content/changelog/v1.17.md index cd3378e4..b154b32c 100644 --- a/content/changelog/v1.17.md +++ b/content/changelog/v1.17.md @@ -18,7 +18,7 @@ date: 2025-12-18 **Backwards Compatible Changes** - Allow application services to masquerade as specific devices belonging to users, as per [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326). ([#2221](https://github.com/matrix-org/matrix-spec/issues/2221)) -- Add the `m.oauth` authentication type for User-Interactive Authentication as per [MSC4312](https://github.com/matrix-org/matrix-spec-proposals/pull/4312). ([#2234](https://github.com/matrix-org/matrix-spec/issues/2234)) +- Add the `m.oauth` authentication type for User-Interactive Authentication, as per [MSC4312](https://github.com/matrix-org/matrix-spec-proposals/pull/4312). ([#2234](https://github.com/matrix-org/matrix-spec/issues/2234)) - Allow application services to manage devices and register users without the legacy authentication API, as per [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190). ([#2267](https://github.com/matrix-org/matrix-spec/issues/2267)) **Spec Clarifications** From 6b5ff04d00b49e87757101b21e7f3f1bfa49dc01 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 18 Dec 2025 16:30:28 +0000 Subject: [PATCH 06/19] Return `main` to unstable status --- config/_default/hugo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml index a1501ac1..e773d13e 100644 --- a/config/_default/hugo.toml +++ b/config/_default/hugo.toml @@ -70,13 +70,13 @@ copyright = "The Matrix.org Foundation CIC" [params.version] # must be one of "unstable", "current", "historical" # this is used to decide whether to show a banner pointing to the current release -status = "stable" +status = "unstable" # A URL pointing to the latest, stable release of the spec. To be shown in the unstable version warning banner. current_version_url = "https://spec.matrix.org/latest" # The following is used when status = "stable", and is displayed in various UI elements on a released version # of the spec. -major = "1" -minor = "17" +#major = "1" +#minor = "17" [[params.versions]] # We must include this parameter to enable docsy's version picker in the navbar. The picker From 2f6867348f0add793fabc7b4a5f548c6abd8aacc Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Fri, 19 Dec 2025 15:59:08 +0000 Subject: [PATCH 07/19] Replace Twitter link in footer with Masto/Bluesky (#2282) --- .../internal/newsfragments/2282.clarification | 1 + config/_default/hugo.toml | 31 +++++++++++-------- 2 files changed, 19 insertions(+), 13 deletions(-) create mode 100644 changelogs/internal/newsfragments/2282.clarification diff --git a/changelogs/internal/newsfragments/2282.clarification b/changelogs/internal/newsfragments/2282.clarification new file mode 100644 index 00000000..25fafc6f --- /dev/null +++ b/changelogs/internal/newsfragments/2282.clarification @@ -0,0 +1 @@ +Replace the Twitter link in the footer with our BlueSky and Mastodon socials. \ No newline at end of file diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml index e773d13e..2fb69279 100644 --- a/config/_default/hugo.toml +++ b/config/_default/hugo.toml @@ -106,25 +106,30 @@ sidebar_menu_compact = true # desc = "Matrix on GitHub" # Custom links shown in the center of the footer. (Only supported by our fork of docsy's 'footer/central' partial.) [[params.links.bottom]] - name = "GitHub" - url = "https://github.com/matrix-org" - icon = "fab fa-github" + name = "GitHub" + url = "https://github.com/matrix-org" + icon = "fab fa-github" desc = "Matrix on GitHub" [[params.links.bottom]] - name = "GitLab" - url = "https://gitlab.matrix.org/matrix-org" - icon = "fab fa-gitlab" + name = "GitLab" + url = "https://gitlab.matrix.org/matrix-org" + icon = "fab fa-gitlab" desc = "Matrix on GitLab" [[params.links.bottom]] - name = "YouTube" - url = "https://www.youtube.com/channel/UCVFkW-chclhuyYRbmmfwt6w" - icon = "fab fa-youtube" + name = "YouTube" + url = "https://www.youtube.com/channel/UCVFkW-chclhuyYRbmmfwt6w" + icon = "fab fa-youtube" desc = "Matrix YouTube channel" [[params.links.bottom]] - name = "Twitter" - url = "https://twitter.com/matrixdotorg" - icon = "fab fa-x-twitter" - desc = "Matrix on Twitter" + name = "Mastodon" + url = "https://mastodon.matrix.org/@matrix" + icon = "fab fa-mastodon" + desc = "Matrix on Mastodon" +[[params.links.bottom]] + name = "Bluesky" + url = "https://bsky.app/profile/matrix.org" + icon = "fab fa-bluesky" + desc = "Matrix on Bluesky" # configuration for the hugo development server From d55acfda2ed6ed6ec05ae5cdf748bfe8fa8b9fc7 Mon Sep 17 00:00:00 2001 From: Kim Brose <2803622+HarHarLinks@users.noreply.github.com> Date: Tue, 30 Dec 2025 19:20:39 +0000 Subject: [PATCH 08/19] Update non-historic mentions of matrix-doc repo to matrix-spec(-proposals) (#2280) --- changelogs/client_server/newsfragments/2280.clarification | 1 + content/client-server-api/modules/content_repo.md | 2 +- content/client-server-api/modules/end_to_end_encryption.md | 2 +- data/api/client-server/rooms.yaml | 2 +- data/api/client-server/third_party_lookup.yaml | 2 +- scripts/proposals.js | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2280.clarification diff --git a/changelogs/client_server/newsfragments/2280.clarification b/changelogs/client_server/newsfragments/2280.clarification new file mode 100644 index 00000000..38fa5012 --- /dev/null +++ b/changelogs/client_server/newsfragments/2280.clarification @@ -0,0 +1 @@ +Update non-historic mentions of matrix-doc repo to matrix-spec/-proposals. Contributed by @HarHarLinks. diff --git a/content/client-server-api/modules/content_repo.md b/content/client-server-api/modules/content_repo.md index 39fe33ec..ad65ea42 100644 --- a/content/client-server-api/modules/content_repo.md +++ b/content/client-server-api/modules/content_repo.md @@ -87,7 +87,7 @@ Matrix 1.12 is expected to be released in the July-September 2024 calendar quart The homeserver SHOULD be able to supply thumbnails for uploaded images and videos. The exact file types which can be thumbnailed are not currently specified - see [Issue -\#1938](https://github.com/matrix-org/matrix-doc/issues/1938) for more +\#1938](https://github.com/matrix-org/matrix-spec/issues/453) for more information. The thumbnail methods are "crop" and "scale". "scale" tries to return an diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 97786f59..25617978 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -921,7 +921,7 @@ collaborate to create a common set of translations for all languages. {{% boxes/note %}} Known translations for the emoji are available from - + and can be translated online: {{% /boxes/note %}} diff --git a/data/api/client-server/rooms.yaml b/data/api/client-server/rooms.yaml index a5c9977e..3716b6a4 100644 --- a/data/api/client-server/rooms.yaml +++ b/data/api/client-server/rooms.yaml @@ -223,7 +223,7 @@ paths: type: string # XXX: As mentioned in MSC1227, replacing `[not_]membership` with a JSON # filter might be a better alternative. - # See https://github.com/matrix-org/matrix-doc/issues/1337 + # See https://github.com/matrix-org/matrix-doc/issues/1227 - in: query name: membership description: |- diff --git a/data/api/client-server/third_party_lookup.yaml b/data/api/client-server/third_party_lookup.yaml index 152f277d..32adb094 100644 --- a/data/api/client-server/third_party_lookup.yaml +++ b/data/api/client-server/third_party_lookup.yaml @@ -78,7 +78,7 @@ paths: }, "room": { "regexp": "[^\\s]+\\/[^\\s]+", - "placeholder": "matrix-org/matrix-doc" + "placeholder": "matrix-org/matrix-spec" } }, "instances": [ diff --git a/scripts/proposals.js b/scripts/proposals.js index dc3f2895..9c9d00ed 100644 --- a/scripts/proposals.js +++ b/scripts/proposals.js @@ -6,7 +6,7 @@ * in the specification. * * In detail, it: - * - fetches all GitHub issues from matrix-doc that have the `proposal` label + * - fetches all GitHub issues from matrix-spec-proposals that have the `proposal` label * - groups them by their state in the MSC process * - does some light massaging of them so it's easier for the Hugo template to work with them * - store them at /data/msc From 690c41e33bb3117cb6517e4f0fca882f3c101896 Mon Sep 17 00:00:00 2001 From: Kim Brose <2803622+HarHarLinks@users.noreply.github.com> Date: Tue, 30 Dec 2025 19:24:38 +0000 Subject: [PATCH 09/19] Remove unintended TeX formatting (#2283) --- changelogs/client_server/newsfragments/2283.clarification | 1 + content/client-server-api/modules/instant_messaging.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2283.clarification diff --git a/changelogs/client_server/newsfragments/2283.clarification b/changelogs/client_server/newsfragments/2283.clarification new file mode 100644 index 00000000..2dc18986 --- /dev/null +++ b/changelogs/client_server/newsfragments/2283.clarification @@ -0,0 +1 @@ +Remove unintended TeX formatting. Contributed by @HarHarLinks. diff --git a/content/client-server-api/modules/instant_messaging.md b/content/client-server-api/modules/instant_messaging.md index d5c0cb6a..5c8a802c 100644 --- a/content/client-server-api/modules/instant_messaging.md +++ b/content/client-server-api/modules/instant_messaging.md @@ -119,7 +119,7 @@ Clients SHOULD verify the structure of incoming events to ensure that the expected keys exist and that they are of the right type. Clients can discard malformed events or display a placeholder message to the user. Redacted `m.room.message` events MUST be removed from the client. This -can either be replaced with placeholder text (e.g. "\[REDACTED\]") or +can either be replaced with placeholder text (e.g. "[REDACTED]") or the redacted message can be removed entirely from the messages view. Events which have attachments (e.g. `m.image`, `m.file`) SHOULD be From 5a9f3c3bca952b1e817656b7844343ad674476e5 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 5 Jan 2026 11:22:02 +0000 Subject: [PATCH 10/19] Auto-create draft releases when building release tags (#2275) Update the CI so that it drafts a release, with the correct artifacts attached and the release notes prepared, when building a release tag. --- .github/workflows/main.yml | 45 +++++++++++++++++++ .../internal/newsfragments/2275.clarification | 1 + 2 files changed, 46 insertions(+) create mode 100644 changelogs/internal/newsfragments/2275.clarification diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3bcc6010..dd320fec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -243,6 +243,14 @@ jobs: name: "🔎 Validate generated HTML" runs-on: ubuntu-latest needs: [calculate-baseurl, build-spec] + # Run even if `generate-changelog` was skipped. + # + # `build-spec` has a dependency on `generate-changelog` to ensure order of execution + # and to access `needs.generate-changelog.result`. However, `generate-changelog` is + # skipped on tag builds; even a transient dependency on `generate-changelog` is then + # enough for this step to also be skipped by default on tag builds. Hence the need for + # this explicit `if`. + if: ${{ !failure() && !cancelled() }} steps: - name: "📥 Source checkout" uses: actions/checkout@v4 @@ -305,8 +313,45 @@ jobs: - name: "📦 Tarball creation" run: tar -czf spec-historical.tar.gz spec + - name: "📤 Artifact upload" uses: actions/upload-artifact@v4 with: name: spec-historical-artifact path: spec-historical.tar.gz + + # If we're building a tag, create a release and publish the artifacts + create_release: + name: "Create release" + if: ${{ !failure() && !cancelled() && startsWith(github.ref, 'refs/tags/') }} + needs: + - build-spec + - build-historical-spec + runs-on: ubuntu-latest + steps: + - name: "📥 Check out changelogs" + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + sparse-checkout: | + content/changelog + - name: "📥 Download built spec" + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: spec-artifact + - name: "📥 Download historical spec artifact" + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: spec-historical-artifact + - name: "✨ Create draft release" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Remove front-matter from changelog + sed '1,/^---$/d' "content/changelog/${{ github.ref_name }}.md" > changelog.md + + # Create a draft release, using the changelog as release notes, and attaching the spec artifacts. + gh release create -d -t "${{ github.ref_name }}" \ + -F "changelog.md" \ + "${{ github.ref_name }}" \ + spec.tar.gz \ + spec-historical.tar.gz diff --git a/changelogs/internal/newsfragments/2275.clarification b/changelogs/internal/newsfragments/2275.clarification new file mode 100644 index 00000000..0a0f28a7 --- /dev/null +++ b/changelogs/internal/newsfragments/2275.clarification @@ -0,0 +1 @@ +Auto-create draft releases when building release tags. From fb2221aad7a659ae8fc88ec1fbb91c2c38654f88 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 6 Jan 2026 16:19:57 +0000 Subject: [PATCH 11/19] Include spec release in filenames in built tarball (#2276) It's slightly confusing that everything just ends up under `spec/`, so let's put the version number in there --- .github/workflows/main.yml | 35 +++++++++++-------- .github/workflows/netlify.yaml | 4 ++- .../internal/newsfragments/2276.feature | 1 + 3 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 changelogs/internal/newsfragments/2276.feature diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dd320fec..ef8353cc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -195,6 +195,8 @@ jobs: needs: [calculate-baseurl, build-openapi, generate-changelog] # run even if generate-changelog was skipped if: ${{ always() }} + env: + baseURL: "${{ needs.calculate-baseurl.outputs.baseURL }}" steps: - name: "➕ Setup Node" uses: actions/setup-node@v4 @@ -217,8 +219,10 @@ jobs: with: name: changelog-artifact path: content/changelog + - name: "⚙️ hugo" - run: hugo --baseURL "${{ needs.calculate-baseurl.outputs.baseURL }}" -d "spec" + run: hugo --baseURL "${baseURL}" -d "spec${baseURL}" + # We manually unpack the spec OpenAPI definition JSON to the website tree # to make it available to the world in a canonical place: # https://spec.matrix.org/latest/client-server-api/api.json @@ -229,10 +233,13 @@ jobs: name: openapi-artifact - name: "📝 Unpack the OpenAPI definitions in the right location" run: | - tar -xzf openapi.tar.gz + tar -C "spec${baseURL}" --strip-components=1 -xzf openapi.tar.gz - name: "📦 Tarball creation" - run: tar -czf spec.tar.gz spec + run: | + cd spec + tar -czf ../spec.tar.gz * + - name: "📤 Artifact upload" uses: actions/upload-artifact@v4 with: @@ -261,14 +268,9 @@ jobs: name: spec-artifact - name: "📝 Unpack the spec" - # we have to unpack it into the right path given the baseurl, so that the - # links are correct. - # eg if baseurl is `/unstable`, we want to put the site in `spec/unstable`. run: | - mkdir -p "spec${baseURL}" - tar -C "spec${baseURL}" --strip-components=1 -xvzf spec.tar.gz - env: - baseURL: "${{ needs.calculate-baseurl.outputs.baseURL }}" + mkdir spec + tar -C spec -xvzf spec.tar.gz - name: "Run htmltest" uses: wjdp/htmltest-action@master @@ -278,8 +280,10 @@ jobs: build-historical-spec: name: "📖 Build the historical backup spec" runs-on: ubuntu-latest - needs: [build-openapi] + needs: [calculate-baseurl, build-openapi] if: ${{ startsWith(github.ref, 'refs/tags/') }} + env: + baseURL: "${{ needs.calculate-baseurl.outputs.baseURL }}" steps: - name: "➕ Setup Node" uses: actions/setup-node@v4 @@ -299,9 +303,8 @@ jobs: - name: "⚙️ hugo" env: HUGO_PARAMS_VERSION_STATUS: "historical" - # Create a baseURL like `/v1.2` out of the `v1.2` tag run: | - hugo --baseURL "/${GITHUB_REF/refs\/tags\//}" -d "spec" + hugo --baseURL "${baseURL}" -d "spec${baseURL}" - name: "📥 Spec definition download" uses: actions/download-artifact@v4 @@ -309,10 +312,12 @@ jobs: name: openapi-artifact - name: "📝 Unpack the OpenAPI definitions in the right location" run: | - tar -xzf openapi.tar.gz + tar -C "spec${baseURL}" --strip-components=1 -xzf openapi.tar.gz - name: "📦 Tarball creation" - run: tar -czf spec-historical.tar.gz spec + run: | + cd spec + tar -czf ../spec-historical.tar.gz * - name: "📤 Artifact upload" uses: actions/upload-artifact@v4 diff --git a/.github/workflows/netlify.yaml b/.github/workflows/netlify.yaml index 7c59f64c..6b4258a1 100644 --- a/.github/workflows/netlify.yaml +++ b/.github/workflows/netlify.yaml @@ -45,7 +45,9 @@ jobs: name: spec-artifact - name: "📦 Extract Artifacts" - run: tar -xzvf spec.tar.gz && rm spec.tar.gz + run: | + mkdir spec + tar -C spec -xzvf spec.tar.gz && rm spec.tar.gz - name: "📤 Deploy to Netlify" id: netlify diff --git a/changelogs/internal/newsfragments/2276.feature b/changelogs/internal/newsfragments/2276.feature new file mode 100644 index 00000000..a0e2b795 --- /dev/null +++ b/changelogs/internal/newsfragments/2276.feature @@ -0,0 +1 @@ +Include the spec release version in the filenames in the tarballs generated by CI. From f2b68c716364fd320036343a090e0c86754858a4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 6 Jan 2026 17:05:59 +0000 Subject: [PATCH 12/19] Updates to release process (#2289) Some clarifications to the release process doc, particularly in view of #2275. --- .../internal/newsfragments/2289.clarification | 1 + meta/releasing.md | 30 +++++++++---------- 2 files changed, 16 insertions(+), 15 deletions(-) create mode 100644 changelogs/internal/newsfragments/2289.clarification diff --git a/changelogs/internal/newsfragments/2289.clarification b/changelogs/internal/newsfragments/2289.clarification new file mode 100644 index 00000000..7991ce2e --- /dev/null +++ b/changelogs/internal/newsfragments/2289.clarification @@ -0,0 +1 @@ +Updates to the release documentation. diff --git a/meta/releasing.md b/meta/releasing.md index f64ee354..3de220f0 100644 --- a/meta/releasing.md +++ b/meta/releasing.md @@ -50,11 +50,6 @@ First, can we even release the spec? This stage is mostly preparation work neede to ensure a consistent and reliable specification. 1. Ensure `main` is committed with all the spec changes you expect to be there. -2. Review the changelog to look for typos, wording inconsistencies, or lines which - can be merged. For example, "Fix typos" and "Fix spelling" can be condensed to - "Fix various typos throughout the specification". -3. Do a quick skim to ensure changelogs reference the MSCs which brought the changes - in. They should be linked to the GitHub MSC PR (not the markdown document). ## The release @@ -79,20 +74,24 @@ release. 2. Run `./scripts/generate-changelog.sh v1.2` (using the correct version number). The script will use the current date. If that date is wrong, correct the document by using the same `YYYY-MM-DD` date format. - 3. Commit the result. + 3. Review the changelog to look for typos, wording inconsistencies, or lines which + can be merged. For example, "Fix typos" and "Fix spelling" can be condensed to + "Fix various typos throughout the specification". + 4. Do a quick skim to ensure changelogs reference the MSCs which brought the changes + in. They should be linked to the GitHub MSC PR (not the markdown document). + 5. Commit the result. + 6. Now is a good time to have someone else review the changelog. 5. Tag the branch with the spec release with a format of `v1.2` (if releasing Matrix 1.2). 6. Push the release branch and the tag. 7. GitHub Actions will run its build steps. Wait until these are successful. If fixes need to be made to repair the pipeline or spec build, delete and re-tag the release. You may need to fix up the changelog file by hand in this case. -8. Check out and fast-forward `main` to the release branch. -9. Create a new release on GitHub from the newly created tag. - * The title should be just "v1.2" (for example). - * The description should be a copy/paste of the changelog. The generated changelog - will be at `content/changelog/v1.2.md` - copy/paste verbatim. - * Upload the artifacts of the GitHub Actions build for the release to the GitHub - release as artifacts themselves. This should be the tarball that will be deployed - to spec.matrix.org. +8. GitHub Actions should have drafted a release based on the new tag. Find it + at https://github.com/matrix-org/matrix-spec/releases. + 1. Double-check the generated release notes, and check that `spec-artifact.zip` and + `spec-historical-artifact.zip` are both attached to the draft release. + 2. Publish the draft release. +9. Check out and fast-forward `main` to the release branch. 10. Commit a reversion to `params.version` of `./config/_default/hugo.toml` on `main`: ```toml [params.version] @@ -103,7 +102,8 @@ release. ``` 11. Push pending commits and ensure the unstable spec updates accordingly from the GitHub Actions pipeline. -12. Deploy the release on the webserver. See internal wiki. +12. Deploy the release on the webserver. See "Spec release process" in the + internal handbook. ## Patching a release From 43c65786ebd39bbab5b53200d3d15745228edd1e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 6 Jan 2026 19:23:19 +0200 Subject: [PATCH 13/19] Specify that the /openid/userinfo return value must be validated (#2288) --- changelogs/server_server/newsfragments/2288.clarification | 1 + data/api/server-server/openid.yaml | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 changelogs/server_server/newsfragments/2288.clarification diff --git a/changelogs/server_server/newsfragments/2288.clarification b/changelogs/server_server/newsfragments/2288.clarification new file mode 100644 index 00000000..3558f255 --- /dev/null +++ b/changelogs/server_server/newsfragments/2288.clarification @@ -0,0 +1 @@ +Specify that callers of `/_matrix/federation/v1/openid/userinfo` must validate the returned user ID. diff --git a/data/api/server-server/openid.yaml b/data/api/server-server/openid.yaml index ce7d8866..22b7f941 100644 --- a/data/api/server-server/openid.yaml +++ b/data/api/server-server/openid.yaml @@ -43,7 +43,12 @@ paths: properties: sub: type: string - description: The Matrix User ID who generated the token. + description: | + The Matrix User ID who generated the token. + + The caller MUST validate that the returned user ID is on the server they + called (i.e. if you make a request to example.com and it returns + `@alice:matrix.org`, the result is invalid). example: "@alice:example.com" required: - sub From 70c7d59caa872dc71b54a056a80e0c1715367285 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 6 Jan 2026 20:10:10 +0100 Subject: [PATCH 14/19] Clarify vendor prefixing requirements (#2222) --- .../internal/newsfragments/2222.clarification | 1 + content/proposals.md | 130 +++++++++++------- 2 files changed, 83 insertions(+), 48 deletions(-) create mode 100644 changelogs/internal/newsfragments/2222.clarification diff --git a/changelogs/internal/newsfragments/2222.clarification b/changelogs/internal/newsfragments/2222.clarification new file mode 100644 index 00000000..188d64bb --- /dev/null +++ b/changelogs/internal/newsfragments/2222.clarification @@ -0,0 +1 @@ +Clarify vendor prefixing requirements. diff --git a/content/proposals.md b/content/proposals.md index 8abf79d1..3b9a707f 100644 --- a/content/proposals.md +++ b/content/proposals.md @@ -408,41 +408,9 @@ development or testing data. that a particular MSC works) do not have to follow this process. 1. Have an idea for a feature. -1. Implement the feature using unstable endpoints, vendor prefixes, and - unstable feature flags as appropriate. - - When using unstable endpoints, they MUST include a vendor - prefix. For example: - `/_matrix/client/unstable/com.example/login`. Vendor prefixes - throughout Matrix always use the Java package naming convention. - The MSC for the feature should identify which preferred vendor - prefix is to be used by early adopters. - - Note that unstable namespaces do not automatically inherit - endpoints from stable namespaces: for example, the fact that - `/_matrix/client/r0/sync` exists does not imply that - `/_matrix/client/unstable/com.example/sync` exists. - - If the client needs to be sure the server supports the feature, - an unstable feature flag that MUST be vendor prefixed is to be - used. This kind of flag shows up in the `unstable_features` - section of `/versions` as, for example, `com.example.new_login`. - The MSC for the feature should identify which preferred feature - flag is to be used by early adopters. - - When using this approach correctly, the implementation can - ship/release the feature at any time, so long as the - implementation is able to accept the technical debt that results - from needing to provide adequate backwards and forwards - compatibility. The implementation MUST support the flag (and - server-side implementation) disappearing and be generally safe - for users. Note that implementations early in the MSC review - process may also be required to provide backwards compatibility - with earlier editions of the proposal. - - If the implementation cannot support the technical debt (or if - it's impossible to provide forwards/backwards compatibility - - e.g. a user authentication change which can't be safely rolled - back), the implementation should not attempt to implement the - feature and should instead wait for a spec release. - - If at any point after early release, the idea changes in a - backwards-incompatible way, the feature flag should also change - so that implementations can adapt as needed. +1. Implement the feature using [unstable endpoints, vendor prefixes, and + unstable feature flags](#unstable-endpoints-features-and-vendor-prefixes) + as appropriate. 1. In parallel, or ahead of implementation, open an MSC and solicit review per above. 1. Before FCP can be called, the Spec Core Team will require evidence @@ -452,10 +420,7 @@ that a particular MSC works) do not have to follow this process. forwards/backwards compatibility concerns mentioned here. 1. The FCP process is completed, and assuming nothing is flagged the MSC lands. -1. Implementations can now switch to using stable prefixes - (for example, for an endpoint, moving from - `/unstable/org.matrix.mscxxxx/frobnicate` - to `/v1/frobnicate`), assuming that the change +1. Implementations can now switch to using stable prefixes, assuming that the change is backwards compatible with older implementations. In the rare occasion where backwards compatibility is not possible without a new spec release, implementations should continue to use unstable prefixes. @@ -471,13 +436,6 @@ that a particular MSC works) do not have to follow this process. started supporting the new spec release, some noise should be raised in the general direction of the implementation. -{{% boxes/note %}} -MSCs MUST still describe what the stable endpoints/feature looks like -with a note towards the bottom for what the unstable feature -flag/prefixes are. For example, an MSC would propose `/_matrix/client/r0/new/endpoint`, not `/_matrix/client/unstable/ -com.example/new/endpoint`. -{{% /boxes/note %}} - In summary: - Implementations MUST NOT use stable endpoints before the MSC has @@ -489,14 +447,90 @@ In summary: - Implementations SHOULD be wary of the technical debt they are incurring by moving faster than the spec. - The vendor prefix is chosen by the developer of the feature, using - the Java package naming convention. The foundation's preferred - vendor prefix is `org.matrix`. + the Java package naming convention. - The vendor prefixes, unstable feature flags, and unstable endpoints should be included in the MSC, though the MSC MUST be written in a way that proposes new stable endpoints. Typically this is solved by a small table at the bottom mapping the various values from stable to unstable. +#### Unstable endpoints, features and vendor prefixes + +Unstable endpoints MUST use `/unstable` as the endpoint version and a +vendor prefix in Java package naming format. For example: +`/_matrix/client/unstable/com.example.mscxxxx/login`. + +{{% boxes/note %}} +Proposal authors operating with a Matrix.org Foundation mandate SHOULD use +a vendor prefix within the `org.matrix` namespace. This namespace is otherwise +restricted. Authors who don't own a domain MAY use the `io.github` namespace +instead. +{{% /boxes/note %}} + +Note that unstable namespaces do not automatically inherit endpoints from +stable namespaces: for example, the fact that `/_matrix/client/v3/sync` +exists does not imply that `/_matrix/client/unstable/com.example.mscxxxx/sync` +exists. + +Vendor prefixes MUST also be used for: + +- New parameters on existing endpoints. For example: + `/_matrix/client/v3/publicRooms?com.example.mscxxxx.ordered_by=member_count`. +- New properties in existing JSON objects. For example: + + ```json + { + "avatar_url": "mxc://matrix.org/SDGdghriugerRg", + "displayname": "Alice Margatroid", + "com.example.mscxxxx.phone": [{ + "type": "landline", + "number": "+1-206-555-7000" + }], + ... + } + ``` + +- New values for existing parameters or properties. For example: + + ```json + { + "errcode": "COM.EXAMPLE.MSCXXXX.M_INVALID_EMAIL", + "error": "The email address you provided is invalid." + } + ``` + +If the client needs to be sure the server supports the feature, an +unstable feature flag that MUST also be vendor prefixed is to be used. +This flag shows up in the `unstable_features` section of +[`/_matrix/client/versions`](/client-server-api/#get_matrixclientversions) +as, for example, `com.example.mscxxxx.new_login`. + +{{% boxes/note %}} +MSCs MUST still describe what the stable endpoints/feature looks like +with a note towards the bottom for what the unstable feature +flag/prefixes are. For example, an MSC would propose `/_matrix/client/v1/new/endpoint`, +not `/_matrix/client/unstable/com.example.mscxxxx/new/endpoint`. +{{% /boxes/note %}} + +When using this approach correctly, the implementation can release +the feature at any time, so long as the implementation is able to +accept the technical debt that results from needing to provide +adequate backwards and forwards compatibility. The implementation +MUST support the flag (and server-side implementation) disappearing +and be generally safe for users. Note that implementations early in +the MSC review process may also be required to provide backwards +compatibility with earlier editions of the proposal. + +If the implementation cannot support the technical debt (or if it's +impossible to provide forwards/backwards compatibility - e.g. a user +authentication change which can't be safely rolled back), the +implementation should not attempt to implement the feature and should +instead wait for a spec release. + +If at any point after early release, the idea changes in a +backwards-incompatible way, the feature flag should also change so +that implementations can adapt as needed. + ### Placeholder MSCs Some proposals may contain security-sensitive or private context which can't be From 2cc7e13c09c4c401e4632626099954b4c1cf3296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= <76261501+zecakeh@users.noreply.github.com> Date: Fri, 9 Jan 2026 12:19:51 +0100 Subject: [PATCH 15/19] Remove unused CSS files (#2290) --- .../internal/newsfragments/2290.clarification | 1 + scripts/css/basic.css | 572 ------------------ scripts/css/blockquote.css | 4 - scripts/css/codehighlight.css | 16 - scripts/css/nature.css | 295 --------- scripts/css/pygments.css | 83 --- scripts/css/tables.css | 4 - 7 files changed, 1 insertion(+), 974 deletions(-) create mode 100644 changelogs/internal/newsfragments/2290.clarification delete mode 100644 scripts/css/basic.css delete mode 100644 scripts/css/blockquote.css delete mode 100644 scripts/css/codehighlight.css delete mode 100644 scripts/css/nature.css delete mode 100644 scripts/css/pygments.css delete mode 100644 scripts/css/tables.css diff --git a/changelogs/internal/newsfragments/2290.clarification b/changelogs/internal/newsfragments/2290.clarification new file mode 100644 index 00000000..30231938 --- /dev/null +++ b/changelogs/internal/newsfragments/2290.clarification @@ -0,0 +1 @@ +Remove unused leftover CSS files. diff --git a/scripts/css/basic.css b/scripts/css/basic.css deleted file mode 100644 index fdf2980d..00000000 --- a/scripts/css/basic.css +++ /dev/null @@ -1,572 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -img { - border: 0; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- general body styles --------------------------------------------------- */ - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { - visibility: visible; -} - -div.document p.caption { - text-align: inherit; -} - -div.document td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -.align-left { - text-align: left; -} - -.align-center { - clear: both; - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.document p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0; - border-collapse: collapse; -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -table.colwidths-auto caption { - font-family: 'Inconsolata', monospace; - font-weight: 800; - font-size: 120%; - padding: 5px; - text-align: left; - margin-bottom: 2px; -} - -.section ol, .section li { - margin: 0px 0px 0px 30px !important; -} - -p.httpheaders { - font-weight: 800; - font-size: 120%; - padding: 5px; - text-align: left; - margin-bottom: 2px; -} - -table.colwidths-auto { - width:100%; - margin-top: 20px; -} - -table.colwidths-auto tr td:nth-child(1) { - width: 15%; -} - -table.colwidths-auto tr td:nth-child(2) { - width: 15%; - font-family: 'Inconsolata', monospace; -} - -table.colwidths-auto tr td:nth-child(3) { - width: 70%; -} - - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlighted { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.refcount { - color: #060; -} - -.optional { - font-size: 1.3em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -/* -- proposals page -------------------------------------------------------- */ - -#tables-of-tracked-proposals h2 { - padding-left: 10px; - position: -webkit-sticky; - position: sticky; -} - -/* Move sticky headers below header bar on desktop */ -@media all and (min-width:980px) { - #tables-of-tracked-proposals h2 { - top: 52px; - } -} - -/* Sticky headers stick to the top on mobile */ -@media all and (min-width:0px) and (max-width: 980px) { - #tables-of-tracked-proposals h2 { - top: 0px; - } -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -tt.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -tt.descclassname { - background-color: transparent; -} - -tt.xref, a tt { - background-color: transparent; - font-weight: bold; -} - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.document div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} - diff --git a/scripts/css/blockquote.css b/scripts/css/blockquote.css deleted file mode 100644 index 05fa73bc..00000000 --- a/scripts/css/blockquote.css +++ /dev/null @@ -1,4 +0,0 @@ -blockquote { - margin: 20px 0 30px; - padding-left: 20px; -} diff --git a/scripts/css/codehighlight.css b/scripts/css/codehighlight.css deleted file mode 100644 index fafc43f4..00000000 --- a/scripts/css/codehighlight.css +++ /dev/null @@ -1,16 +0,0 @@ -pre.code .comment, code .comment { color: green } -pre.code .keyword, code .keyword { color: darkred; font-weight: bold } -pre.code .name.builtin, code .name.builtin { color: darkred; font-weight: bold } -pre.code .name.tag, code .name.tag { color: darkgreen } -pre.code .literal, code .literal { color: darkblue } -pre.code .literal.number, code .literal.number { color: blue } - - -/* HTTP Methods have class "name function" */ -pre.code.http .name.function, code.http .name.function { color: black; font-weight: bold } -/* HTTP Paths have class "name namespace" */ -pre.code.http .name.namespace, code.http .name.namespace { color: darkgreen } -/* HTTP "HTTP" strings have class "keyword reserved" */ -pre.code.http .keyword.reserved, code.http .keyword.reserved { color: black; font-weight: bold } -/* HTTP Header names have class "name attribute" */ -pre.code.http .name.attribute, code.http .name.attribute { color: black; font-weight: bold } diff --git a/scripts/css/nature.css b/scripts/css/nature.css deleted file mode 100644 index 69169129..00000000 --- a/scripts/css/nature.css +++ /dev/null @@ -1,295 +0,0 @@ -/* - * nature.css_t - * ~~~~~~~~~~~~ - * - * Sphinx stylesheet -- nature theme. - * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: Arial, sans-serif; - font-size: 100%; - /*background-color: #111;*/ - color: #555; - margin: 0; - padding: 0; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 230px; -} - -hr { - border: 1px solid #B1B4B6; -} - -/* -div.document { - background-color: #eee; -} -*/ - -div.document { - background-color: #ffffff; - color: #3E4349; - padding: 0 30px 30px 30px; - font-size: 0.9em; -} - -div.footer { - color: #555; - width: 100%; - padding: 13px 0; - text-align: center; - font-size: 75%; -} - -div.footer a { - color: #444; - text-decoration: underline; -} - -div.related { - background-color: #6BA81E; - line-height: 32px; - color: #fff; - text-shadow: 0px 1px 0 #444; - font-size: 0.9em; -} - -div.related a { - color: #E2F3CC; -} - -div.sphinxsidebar { - font-size: 0.75em; - line-height: 1.5em; -} - -div.sphinxsidebarwrapper{ - padding: 20px 0; -} - -div.sphinxsidebar h3, -div.sphinxsidebar h4 { - font-family: Arial, sans-serif; - color: #222; - font-size: 1.2em; - font-weight: normal; - margin: 0; - padding: 5px 10px; - background-color: #ddd; - text-shadow: 1px 1px 0 white -} - -div.sphinxsidebar h4{ - font-size: 1.1em; -} - -div.sphinxsidebar h3 a { - color: #444; -} - - -div.sphinxsidebar p { - color: #888; - padding: 5px 20px; -} - -div.sphinxsidebar p.topless { -} - -div.sphinxsidebar ul { - margin: 10px 20px; - padding: 0; - color: #000; -} - -div.sphinxsidebar a { - color: #444; -} - -div.sphinxsidebar input { - border: 1px solid #ccc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar input[type=text]{ - margin-left: 20px; -} - -/* -- body styles ----------------------------------------------------------- */ - -a { - color: #005B81; - text-decoration: none; -} - -a:hover { - color: #E32E00; - text-decoration: underline; -} - -div.document h1, -div.document h2, -div.document h3, -div.document h4, -div.document h5, -div.document h6 { - font-family: Arial, sans-serif; - background-color: #BED4EB; - font-weight: normal; - color: #212224; - margin: 30px 0px 10px 0px; - padding: 5px 0 5px 10px; - text-shadow: 0px 1px 0 white -} - -div.document h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } -div.document h2 { font-size: 150%; background-color: #C8D5E3; } -div.document h3 { font-size: 120%; background-color: #D8DEE3; } -div.document h4 { font-size: 110%; background-color: #D8DEE3; } -div.document h5 { font-size: 100%; background-color: #D8DEE3; } -div.document h6 { font-size: 100%; background-color: #D8DEE3; } - -a.headerlink { - color: #c60f0f; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - background-color: #c60f0f; - color: white; -} - -div.document p, div.document dd, div.document li { - line-height: 1.5em; -} - -div.admonition p.admonition-title + p { - display: inline; -} - -div.highlight{ - background-color: white; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre { - padding: 10px; - background-color: White; - color: #222; - line-height: 1.2em; - border: 1px solid #C6C9CB; - font-size: 1.1em; - margin: 1.5em 0 1.5em 0; - -webkit-box-shadow: 1px 1px 1px #d8d8d8; - -moz-box-shadow: 1px 1px 1px #d8d8d8; -} - -tt { - background-color: #ecf0f3; - color: #222; - /* padding: 1px 2px; */ - font-size: 1.1em; - font-family: monospace; -} - -.viewcode-back { - font-family: Arial, sans-serif; -} - -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} - -ul li dd { - margin-top: 0; -} - -ul li dl { - margin-bottom: 0; -} - -li dl dd { - margin-bottom: 0; -} - -dd ul { - padding-left: 0; -} - -li dd ul { - margin-bottom: 0; -} - -table { - margin-top: 10px; - margin-bottom: 10px; - border: 0; - border-collapse: collapse; -} - -td[colspan]:not([colspan="1"]) { - background: #eeeeee; - text-transform: capitalize; -} - -thead { - background: #eeeeee; -} - -div.admonition-rationale { - background-color: #efe; - border: 1px solid #ccc; -} - -div.admonition-example { - background-color: #eef; - border: 1px solid #ccc; -} - -div#table-of-contents ul { - list-style-type: none; -} diff --git a/scripts/css/pygments.css b/scripts/css/pygments.css deleted file mode 100644 index a212151a..00000000 --- a/scripts/css/pygments.css +++ /dev/null @@ -1,83 +0,0 @@ -/* -Original styles generated from: - pygmentize -f html -S colorful -a pre.code > ./scripts/css/pygments.css - -Rules for which we don't want the syntax highlighter to kick in are commented -out at the bottom. - -Windows users: if you regenerate this file, you'll need to re-save it as utf-8 -to make docutils happy. -*/ - -/* DIFFS */ -pre.code .gd { color: #A00000 } /* Generic.Deleted */ -pre.code .gi { color: #00A000 } /* Generic.Inserted */ - -/* UNUSED */ -/*pre.code .hll { background-color: #ffffcc }*/ -/*pre.code { background: #ffffff; }*/ -/*pre.code .c { color: #888888 } !* Comment *!*/ -/*pre.code .err { color: #FF0000; background-color: #FFAAAA } !* Error *!*/ -/*pre.code .k { color: #008800; font-weight: bold } !* Keyword *!*/ -/*pre.code .o { color: #333333 } !* Operator *!*/ -/*pre.code .ch { color: #888888 } !* Comment.Hashbang *!*/ -/*pre.code .cm { color: #888888 } !* Comment.Multiline *!*/ -/*pre.code .cp { color: #557799 } !* Comment.Preproc *!*/ -/*pre.code .cpf { color: #888888 } !* Comment.PreprocFile *!*/ -/*pre.code .c1 { color: #888888 } !* Comment.Single *!*/ -/*pre.code .cs { color: #cc0000; font-weight: bold } !* Comment.Special *!*/ -/*pre.code .ge { font-style: italic } !* Generic.Emph *!*/ -/*pre.code .gr { color: #FF0000 } !* Generic.Error *!*/ -/*pre.code .gh { color: #000080; font-weight: bold } !* Generic.Heading *!*/ -/*pre.code .go { color: #888888 } !* Generic.Output *!*/ -/*pre.code .gp { color: #c65d09; font-weight: bold } !* Generic.Prompt *!*/ -/*pre.code .gs { font-weight: bold } !* Generic.Strong *!*/ -/*pre.code .gu { color: #800080; font-weight: bold } !* Generic.Subheading *!*/ -/*pre.code .gt { color: #0044DD } !* Generic.Traceback *!*/ -/*pre.code .kc { color: #008800; font-weight: bold } !* Keyword.Constant *!*/ -/*pre.code .kd { color: #008800; font-weight: bold } !* Keyword.Declaration *!*/ -/*pre.code .kn { color: #008800; font-weight: bold } !* Keyword.Namespace *!*/ -/*pre.code .kp { color: #003388; font-weight: bold } !* Keyword.Pseudo *!*/ -/*pre.code .kr { color: #008800; font-weight: bold } !* Keyword.Reserved *!*/ -/*pre.code .kt { color: #333399; font-weight: bold } !* Keyword.Type *!*/ -/*pre.code .m { color: #6600EE; font-weight: bold } !* Literal.Number *!*/ -/*pre.code .s { background-color: #fff0f0 } !* Literal.String *!*/ -/*pre.code .na { color: #0000CC } !* Name.Attribute *!*/ -/*pre.code .nb { color: #007020 } !* Name.Builtin *!*/ -/*pre.code .nc { color: #BB0066; font-weight: bold } !* Name.Class *!*/ -/*pre.code .no { color: #003366; font-weight: bold } !* Name.Constant *!*/ -/*pre.code .nd { color: #555555; font-weight: bold } !* Name.Decorator *!*/ -/*pre.code .ni { color: #880000; font-weight: bold } !* Name.Entity *!*/ -/*pre.code .ne { color: #FF0000; font-weight: bold } !* Name.Exception *!*/ -/*pre.code .nf { color: #0066BB; font-weight: bold } !* Name.Function *!*/ -/*pre.code .nl { color: #997700; font-weight: bold } !* Name.Label *!*/ -/*pre.code .nn { color: #0e84b5; font-weight: bold } !* Name.Namespace *!*/ -/*pre.code .nt { color: #007700 } !* Name.Tag *!*/ -/*pre.code .nv { color: #996633 } !* Name.Variable *!*/ -/*pre.code .ow { color: #000000; font-weight: bold } !* Operator.Word *!*/ -/*pre.code .w { color: #bbbbbb } !* Text.Whitespace *!*/ -/*pre.code .mb { color: #6600EE; font-weight: bold } !* Literal.Number.Bin *!*/ -/*pre.code .mf { color: #6600EE; font-weight: bold } !* Literal.Number.Float *!*/ -/*pre.code .mh { color: #005588; font-weight: bold } !* Literal.Number.Hex *!*/ -/*pre.code .mi { color: #0000DD; font-weight: bold } !* Literal.Number.Integer *!*/ -/*pre.code .mo { color: #4400EE; font-weight: bold } !* Literal.Number.Oct *!*/ -/*pre.code .sa { background-color: #fff0f0 } !* Literal.String.Affix *!*/ -/*pre.code .sb { background-color: #fff0f0 } !* Literal.String.Backtick *!*/ -/*pre.code .sc { color: #0044DD } !* Literal.String.Char *!*/ -/*pre.code .dl { background-color: #fff0f0 } !* Literal.String.Delimiter *!*/ -/*pre.code .sd { color: #DD4422 } !* Literal.String.Doc *!*/ -/*pre.code .s2 { background-color: #fff0f0 } !* Literal.String.Double *!*/ -/*pre.code .se { color: #666666; font-weight: bold; background-color: #fff0f0 } !* Literal.String.Escape *!*/ -/*pre.code .sh { background-color: #fff0f0 } !* Literal.String.Heredoc *!*/ -/*pre.code .si { background-color: #eeeeee } !* Literal.String.Interpol *!*/ -/*pre.code .sx { color: #DD2200; background-color: #fff0f0 } !* Literal.String.Other *!*/ -/*pre.code .sr { color: #000000; background-color: #fff0ff } !* Literal.String.Regex *!*/ -/*pre.code .s1 { background-color: #fff0f0 } !* Literal.String.Single *!*/ -/*pre.code .ss { color: #AA6600 } !* Literal.String.Symbol *!*/ -/*pre.code .bp { color: #007020 } !* Name.Builtin.Pseudo *!*/ -/*pre.code .fm { color: #0066BB; font-weight: bold } !* Name.Function.Magic *!*/ -/*pre.code .vc { color: #336699 } !* Name.Variable.Class *!*/ -/*pre.code .vg { color: #dd7700; font-weight: bold } !* Name.Variable.Global *!*/ -/*pre.code .vi { color: #3333BB } !* Name.Variable.Instance *!*/ -/*pre.code .vm { color: #996633 } !* Name.Variable.Magic *!*/ -/*pre.code .il { color: #0000DD; font-weight: bold } !* Literal.Number.Integer.Long *!*/ diff --git a/scripts/css/tables.css b/scripts/css/tables.css deleted file mode 100644 index 03ee1d85..00000000 --- a/scripts/css/tables.css +++ /dev/null @@ -1,4 +0,0 @@ -/* Column with header cells */ -table.docutils tbody th.stub { - background: #eeeeee; -} From fa78688f57c0b2d79fdac39c4ead757fdf484927 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 14 Jan 2026 10:15:24 +0100 Subject: [PATCH 16/19] Spec for MSC4356: Recently used emoji (#2291) Signed-off-by: Johannes Marbach Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- .../client_server/newsfragments/2291.feature | 1 + content/client-server-api/_index.md | 2 + .../client-server-api/modules/recent_emoji.md | 40 +++++++++++++++++++ .../definitions/recent_emoji.yaml | 29 ++++++++++++++ .../examples/m.recent_emoji.yaml | 16 ++++++++ data/event-schemas/schema/m.recent_emoji.yaml | 29 ++++++++++++++ 6 files changed, 117 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2291.feature create mode 100644 content/client-server-api/modules/recent_emoji.md create mode 100644 data/api/client-server/definitions/recent_emoji.yaml create mode 100644 data/event-schemas/examples/m.recent_emoji.yaml create mode 100644 data/event-schemas/schema/m.recent_emoji.yaml diff --git a/changelogs/client_server/newsfragments/2291.feature b/changelogs/client_server/newsfragments/2291.feature new file mode 100644 index 00000000..93a509dc --- /dev/null +++ b/changelogs/client_server/newsfragments/2291.feature @@ -0,0 +1 @@ +Add `m.recent_emoji` account data event to track recently used emoji as per [MSC4356](https://github.com/matrix-org/matrix-spec-proposals/pull/4356). diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 8f8092b5..9a64b41b 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -3898,6 +3898,7 @@ that profile. | [Guest Access](#guest-access) | Optional | Optional | Optional | Optional | Optional | | [Moderation Policy Lists](#moderation-policy-lists) | Optional | Optional | Optional | Optional | Optional | | [OpenID](#openid) | Optional | Optional | Optional | Optional | Optional | +| [Recently used emoji](#recently-used-emoji) | Optional | Optional | Optional | Optional | Optional | | [Reference Relations](#reference-relations) | Optional | Optional | Optional | Optional | Optional | | [Reporting Content](#reporting-content) | Optional | Optional | Optional | Optional | Optional | | [Rich replies](#rich-replies) | Optional | Optional | Optional | Optional | Optional | @@ -3999,5 +4000,6 @@ systems. {{% cs-module name="Spaces" filename="spaces" %}} {{% cs-module name="Event replacements" filename="event_replacements" %}} {{% cs-module name="Event annotations and reactions" filename="event_annotations" %}} +{{% cs-module name="Recently used emoji" filename="recent_emoji" %}} {{% cs-module name="Threading" filename="threading" %}} {{% cs-module name="Reference relations" filename="reference_relations" %}} diff --git a/content/client-server-api/modules/recent_emoji.md b/content/client-server-api/modules/recent_emoji.md new file mode 100644 index 00000000..77c0c12b --- /dev/null +++ b/content/client-server-api/modules/recent_emoji.md @@ -0,0 +1,40 @@ +### Recently used emoji + +{{% added-in v="1.18" %}} + +This module enables clients to track a user's cumulated emoji usage across different +devices. The data is stored in the [`m.recent_emoji`](#mrecent_emoji) +global [account data](#client-config) and can, among other things, be used to +generate recommendations in emoji pickers. + +#### Events + +{{% event event="m.recent_emoji" %}} + +#### Client behaviour + +What exactly constitutes trackable emoji usage is left as an implementation detail +for clients. It is RECOMMENDED to include sending emoji in both messages and +annotations. + +When an emoji is used, the sending client moves (or adds) it to the beginning of +the `recent_emoji` array and increments (or initializes) its counter. This keeps +the array ordered by last usage time which facilitates evaluating the data. How +exactly the client evaluates and uses the collected data is deliberately left +unspecified. + +To prevent excessive growth of the event as new emoji are being used, clients +SHOULD limit the length of the `recent_emoji` array by dropping elements from +its end. A RECOMMENDED maximum length is 100 emoji. + +To enable future extension, clients MUST tolerate and preserve array elements +within `recent_emoji` regardless of whether they understand or support the +contained `emoji` value. This means ignoring entries with unrecognised values +of `emoji` when deciding what to display to the user while retaining them when +modifying the array (unless the modification is for truncation). + +To prevent undefined behavior, clients SHOULD remove array elements that +don't conform to the event schema such as elements with negative counters. + + + diff --git a/data/api/client-server/definitions/recent_emoji.yaml b/data/api/client-server/definitions/recent_emoji.yaml new file mode 100644 index 00000000..c2deab94 --- /dev/null +++ b/data/api/client-server/definitions/recent_emoji.yaml @@ -0,0 +1,29 @@ +# Copyright 2026 The Matrix.org Foundation C.I.C. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +title: Recent Emoji +type: object +properties: + emoji: + type: string + description: The Unicode emoji as string. + example: 🚀 + total: + type: number + description: |- + The number of times the emoji has been used. + MUST be non-negative and smaller than 2^53. +required: + - emoji + - total diff --git a/data/event-schemas/examples/m.recent_emoji.yaml b/data/event-schemas/examples/m.recent_emoji.yaml new file mode 100644 index 00000000..85b15cc6 --- /dev/null +++ b/data/event-schemas/examples/m.recent_emoji.yaml @@ -0,0 +1,16 @@ +{ + "$ref": "core/event.json", + "type": "m.recent_emoji", + "content": { + "recent_emoji": [{ + "emoji": "🤔", + "total": 19 + }, { + "emoji": "👍", + "total": 7 + }, { + "emoji": "😅", + "total": 84 + }] + } +} diff --git a/data/event-schemas/schema/m.recent_emoji.yaml b/data/event-schemas/schema/m.recent_emoji.yaml new file mode 100644 index 00000000..8db49a48 --- /dev/null +++ b/data/event-schemas/schema/m.recent_emoji.yaml @@ -0,0 +1,29 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Recent Emoji Event", + "description": "Lets clients maintain a list of recently used emoji.", + "allOf": [{ + "$ref": "core-event-schema/event.yaml" + }], + "properties": { + "type": { + "type": "string", + "enum": ["m.recent_emoji"] + }, + "content": { + "type": "object", + "properties": { + "recent_emoji": { + "description": "The list of recently used emoji. Elements in the list are ordered descendingly by last usage time.", + "type": "array", + "items": { + "$ref": "../../api/client-server/definitions/recent_emoji.yaml" + }, + } + }, + "required": ["recent_emoji"] + } + }, + "required": ["type", "content"] +} From c47fa4d09367dbca8a96b73558c1b94301ca6d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= <76261501+zecakeh@users.noreply.github.com> Date: Thu, 15 Jan 2026 18:01:07 +0100 Subject: [PATCH 17/19] Bump docsy to v0.13.0 (#2287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Commaille Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- .github/workflows/main.yml | 9 +- assets/js/toc.js | 8 +- assets/scss/_styles_project.scss | 216 ++++++++++-------- assets/scss/_variables_project.scss | 1 + .../internal/newsfragments/2287.clarification | 1 + config/_default/hugo.toml | 8 + go.mod | 2 +- go.sum | 6 +- layouts/_markup/render-passthrough.html | 12 +- layouts/_partials/breadcrumb.html | 45 ++-- layouts/_partials/navbar.html | 48 ++-- layouts/_partials/sidebar-tree.html | 213 ++++++++++++----- layouts/_partials/toc.html | 30 ++- layouts/docs/baseof.html | 21 +- scripts/download-katex-assets.sh | 41 ---- static/css/fonts/KaTeX_AMS-Regular.woff2 | Bin 28076 -> 0 bytes static/css/fonts/KaTeX_Caligraphic-Bold.woff2 | Bin 6912 -> 0 bytes .../css/fonts/KaTeX_Caligraphic-Regular.woff2 | Bin 6908 -> 0 bytes static/css/fonts/KaTeX_Fraktur-Bold.woff2 | Bin 11348 -> 0 bytes static/css/fonts/KaTeX_Fraktur-Regular.woff2 | Bin 11316 -> 0 bytes static/css/fonts/KaTeX_Main-Bold.woff2 | Bin 25324 -> 0 bytes static/css/fonts/KaTeX_Main-BoldItalic.woff2 | Bin 16780 -> 0 bytes static/css/fonts/KaTeX_Main-Italic.woff2 | Bin 16988 -> 0 bytes static/css/fonts/KaTeX_Main-Regular.woff2 | Bin 26272 -> 0 bytes static/css/fonts/KaTeX_Math-BoldItalic.woff2 | Bin 16400 -> 0 bytes static/css/fonts/KaTeX_Math-Italic.woff2 | Bin 16440 -> 0 bytes static/css/fonts/KaTeX_SansSerif-Bold.woff2 | Bin 12216 -> 0 bytes static/css/fonts/KaTeX_SansSerif-Italic.woff2 | Bin 12028 -> 0 bytes .../css/fonts/KaTeX_SansSerif-Regular.woff2 | Bin 10344 -> 0 bytes static/css/fonts/KaTeX_Script-Regular.woff2 | Bin 9644 -> 0 bytes static/css/fonts/KaTeX_Size1-Regular.woff2 | Bin 5468 -> 0 bytes static/css/fonts/KaTeX_Size2-Regular.woff2 | Bin 5208 -> 0 bytes static/css/fonts/KaTeX_Size3-Regular.woff2 | Bin 3624 -> 0 bytes static/css/fonts/KaTeX_Size4-Regular.woff2 | Bin 4928 -> 0 bytes .../css/fonts/KaTeX_Typewriter-Regular.woff2 | Bin 13568 -> 0 bytes static/css/katex.min.css | 1 - 36 files changed, 386 insertions(+), 276 deletions(-) create mode 100644 changelogs/internal/newsfragments/2287.clarification delete mode 100755 scripts/download-katex-assets.sh delete mode 100644 static/css/fonts/KaTeX_AMS-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Caligraphic-Bold.woff2 delete mode 100644 static/css/fonts/KaTeX_Caligraphic-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Fraktur-Bold.woff2 delete mode 100644 static/css/fonts/KaTeX_Fraktur-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Main-Bold.woff2 delete mode 100644 static/css/fonts/KaTeX_Main-BoldItalic.woff2 delete mode 100644 static/css/fonts/KaTeX_Main-Italic.woff2 delete mode 100644 static/css/fonts/KaTeX_Main-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Math-BoldItalic.woff2 delete mode 100644 static/css/fonts/KaTeX_Math-Italic.woff2 delete mode 100644 static/css/fonts/KaTeX_SansSerif-Bold.woff2 delete mode 100644 static/css/fonts/KaTeX_SansSerif-Italic.woff2 delete mode 100644 static/css/fonts/KaTeX_SansSerif-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Script-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Size1-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Size2-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Size3-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Size4-Regular.woff2 delete mode 100644 static/css/fonts/KaTeX_Typewriter-Regular.woff2 delete mode 100644 static/css/katex.min.css diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ef8353cc..92b841f4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,8 +1,9 @@ name: "Spec" env: - HUGO_VERSION: 0.148.1 + HUGO_VERSION: 0.153.3 PYTHON_VERSION: 3.13 + NODE_VERSION: 24 on: push: @@ -27,7 +28,7 @@ jobs: - name: "➕ Setup Node" uses: actions/setup-node@v4 with: - node-version: '20' + node-version: ${{ env.NODE_VERSION }} - name: "🔎 Run validator" run: | npx @redocly/cli@latest lint data/api/*/*.yaml @@ -201,7 +202,7 @@ jobs: - name: "➕ Setup Node" uses: actions/setup-node@v4 with: - node-version: '20' + node-version: ${{ env.NODE_VERSION }} - name: "➕ Setup Hugo" uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0 with: @@ -288,7 +289,7 @@ jobs: - name: "➕ Setup Node" uses: actions/setup-node@v4 with: - node-version: '20' + node-version: ${{ env.NODE_VERSION }} - name: "➕ Setup Hugo" uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0 with: diff --git a/assets/js/toc.js b/assets/js/toc.js index 89a83ced..a7103f9d 100644 --- a/assets/js/toc.js +++ b/assets/js/toc.js @@ -50,7 +50,7 @@ function getHeadings() { let headings = []; // First get the anchors in the ToC. - const toc_anchors = document.querySelectorAll("#toc nav a"); + const toc_anchors = document.querySelectorAll("#TableOfContents a"); for (const anchor of toc_anchors) { // Then get the heading from its selector in the anchor's href. @@ -59,7 +59,7 @@ function getHeadings() { console.error("Got ToC anchor without href"); continue; } - + const heading = document.querySelector(selector); if (!heading) { console.error("Heading not found for selector:", selector); @@ -122,13 +122,13 @@ function getCurrentHeading(headings, headerOffset) { */ function selectTocEntry(id) { // Deselect previously selected entries. - const activeEntries = document.querySelectorAll("#toc nav a.active"); + const activeEntries = document.querySelectorAll("#TableOfContents a.active"); for (const activeEntry of activeEntries) { activeEntry.classList.remove('active'); } // Find the new entry and select it. - const newEntry = document.querySelector(`#toc nav a[href="#${id}"]`); + const newEntry = document.querySelector(`#TableOfContents a[href="#${id}"]`); if (!newEntry) { console.error("ToC entry not found for ID:", id); return; diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index f20dc096..cd9937a9 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -76,52 +76,126 @@ Custom SCSS for the Matrix spec scroll-behavior: smooth; overscroll-behavior: contain; - &>.td-sidebar-nav__section { + & > .td-sidebar-nav__section { margin-top: 1rem; - } - .td-sidebar-nav__section .ul-1 ul { - padding-left: 0; - } - - /* This is to make the width of the items that have sub-items (like room versions) - the same as the width of items that don't (like changelog) */ - .pr-md-3, .px-md-3 { - padding-right: 0 !important; - } - - .ul-1 > li > a { - padding-left: 1rem !important; - } - - .ul-2 > li > a { - padding-left: 2rem !important; - } - - a.td-sidebar-link.tree-root { - color: $gray-800; - font-weight: $font-weight-bold; - font-size: 1.3rem; - margin-bottom: 0; - border-bottom: none; - } - - a, a.td-sidebar-link { - color: $gray-800; - font-weight: $font-weight-normal; - padding-top: .2rem; - padding-bottom: .2rem; - - display: block; - transition: all 100ms ease-in-out; - - &:hover { - background-color: $secondary-lighter-background; - color: $gray-800; + .ul-1 ul { + padding-left: 0; } - &.active, &active:hover { - background-color: $secondary-background; + /* This is to make the width of the items that have sub-items (like room versions) + the same as the width of items that don't (like changelog) */ + .pr-md-3, .px-md-3 { + padding-right: 0 !important; + } + + .ul-1 > li > a { + padding-left: 1rem !important; + } + + .ul-2 > li > a { + padding-left: 2rem !important; + } + } + + /* Styles for the table of contents */ + & > .td-toc { + padding-top: 1rem; + padding-left: 1.5rem; + /* Add border above the toc */ + border-top: 1px solid var(--bs-tertiary-color); + + ol { + padding-left: 1rem; + counter-reset: section; + list-style-type: none; + } + + #TableOfContents { + /* Remove the space between the title and the ToC */ + margin-top: 0; + + &>ol>li { + margin-bottom: .5rem; + + &>a { + font-weight: $font-weight-bold; + } + } + + ol { + padding-left: 0; + } + + &>ol>li>a { + padding-left: 1rem; + } + + &>ol>li>ol>li>a { + padding-left: 2rem; + } + + &>ol>li>ol>li>ol>li>a { + padding-left: 3rem; + } + + &>ol>li>ol>li>ol>li>ol>li>a { + padding-left: 4rem; + } + + &>ol>li>ol>li>ol>li>ol>li>ol>li>a { + padding-left: 5rem; + } + + } + + li a:before { + counter-increment: section; + content: counters(section, ".") " "; + } + + .td-toc-title { + font-weight: $font-weight-bold; + font-size: 1.3rem; + + /* Remove the border under the title */ + border-bottom: 0; + /* Remove the space under the title */ + margin-bottom: 0; + + /* Fix the top of page link color */ + a, a:hover { + color: $secondary; + } + } + } + + /* Apply the same style to links in the navigation and in the ToC */ + & > .td-sidebar-nav__section, & > .td-toc #TableOfContents { + li a.td-sidebar-link.tree-root { + color: $gray-800; + font-weight: $font-weight-bold; + font-size: 1.3rem; + margin-bottom: 0; + border-bottom: none; + } + + li a, li a.td-sidebar-link { + color: $gray-800; + font-weight: $font-weight-normal; + padding-top: .2rem; + padding-bottom: .2rem; + + transition: all 100ms ease-in-out; + + &:hover { + background-color: $secondary-lighter-background; + color: $gray-800; + } + + &.active, &active:hover { + background-color: $secondary-background; + } } } } @@ -199,64 +273,6 @@ Custom SCSS for the Matrix spec scroll-margin-top: 5.5rem; } -/* Styles for the table of contents */ -#toc { - padding-top: .5rem; - padding-left: 1.5rem; - - ol { - padding-left: 1rem; - counter-reset: section; - list-style-type: none; - } - - #TableOfContents { - &>ol>li { - margin-bottom: .5rem; - - &>a { - font-weight: $font-weight-bold; - } - } - - ol { - padding-left: 0; - } - - &>ol>li>a { - padding-left: 1rem; - } - - &>ol>li>ol>li>a { - padding-left: 2rem; - } - - &>ol>li>ol>li>ol>li>a { - padding-left: 3rem; - } - - &>ol>li>ol>li>ol>li>ol>li>a { - padding-left: 4rem; - } - - &>ol>li>ol>li>ol>li>ol>li>ol>li>a { - padding-left: 5rem; - } - - } - - li a:before { - counter-increment: section; - content: counters(section, ".") " "; - } - - #toc-title { - font-weight: $font-weight-bold; - font-size: 1.3rem; - } - -} - .endpoints-toc { summary { cursor: pointer; diff --git a/assets/scss/_variables_project.scss b/assets/scss/_variables_project.scss index c2ec03c6..75e5379f 100644 --- a/assets/scss/_variables_project.scss +++ b/assets/scss/_variables_project.scss @@ -18,6 +18,7 @@ $primary: #FFF; $secondary: #0098D4; $dark: #333; $gray-100: #FBFBFB; +$code-color: #005b7f; $secondary-background: #E5F5FB; $secondary-lighter-background: #F4FAFC; diff --git a/changelogs/internal/newsfragments/2287.clarification b/changelogs/internal/newsfragments/2287.clarification new file mode 100644 index 00000000..5d0bdcc5 --- /dev/null +++ b/changelogs/internal/newsfragments/2287.clarification @@ -0,0 +1 @@ +Upgrade to docsy v0.13.0. diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml index 2fb69279..76c3f9bb 100644 --- a/config/_default/hugo.toml +++ b/config/_default/hugo.toml @@ -166,3 +166,11 @@ sidebar_menu_compact = true mediaType = "text/markdown" isPlainText = true baseName = "checklist" + +# Add font media types for downloading KaTeX fonts. +# See: https://www.docsy.dev/docs/content/diagrams-and-formulae/#create-media-types-for-katex-fonts +[mediaTypes] + [mediaTypes.'font/woff'] + suffixes = ['woff'] + [mediaTypes.'font/woff2'] + suffixes = ['woff2'] diff --git a/go.mod b/go.mod index 60143ea9..6b13c46b 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/matrix-org/matrix-spec go 1.12 -require github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af // indirect +require github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a // indirect diff --git a/go.sum b/go.sum index ea991476..3897374a 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,4 @@ github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo= -github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af h1:XghgUC0H5BoGrvtT9/oWBUi+5Zux875qRHhpAZ0RURI= -github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af/go.mod h1:4/t21g/nPraob/DVMm3jrk26k0CDL5I7Mxf+ar0IAgs= -github.com/twbs/bootstrap v5.3.6+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0= +github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a h1:WB3unuZJy7ewAf33sxbtEwYnC+i+Jt1sJpAR3BtzvEo= +github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a/go.mod h1:mdn1m5HJug6ZddQgrOyCrXNegbtdl5evHiqqbEQLzdI= +github.com/twbs/bootstrap v5.3.8+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0= diff --git a/layouts/_markup/render-passthrough.html b/layouts/_markup/render-passthrough.html index 425471a9..d5f85ded 100644 --- a/layouts/_markup/render-passthrough.html +++ b/layouts/_markup/render-passthrough.html @@ -5,15 +5,7 @@ We use it to send the delimited passthrough element through KaTeX to render maths in the Olm / Megolm spec. - See: https://gohugo.io/functions/transform/tomath/#step-2 + See: https://www.docsy.dev/docs/content/diagrams-and-formulae/#add-passthrough-render-hook */ -}} -{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }} -{{- with try (transform.ToMath .Inner $opts) }} - {{- with .Err }} - {{- errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }} - {{- else }} - {{- .Value }} - {{- $.Page.Store.Set "hasMath" true }} - {{- end }} -{{- end -}} +{{ partial "scripts/math.html" . }} diff --git a/layouts/_partials/breadcrumb.html b/layouts/_partials/breadcrumb.html index af3a9551..bfe89399 100644 --- a/layouts/_partials/breadcrumb.html +++ b/layouts/_partials/breadcrumb.html @@ -1,28 +1,35 @@ {{/* - A copy of the breadcrumb.html partial in Docsy, modified - to: + A copy of the breadcrumb.html partial in Docsy, modified to: + + * show the breadcrumbs by default by removing the `td-breadcrumbs__single` + class * omit breadcrumbs when this is the homepage * otherwise, include the homepage in the breadcrumbs */}} -{{ if not .IsHome }} +{{ if not .IsHome -}} -{{ end }} + + +{{ end -}} -{{ define "breadcrumbnav" }} -{{ if .p1.Parent }} -{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) }} -{{ else if not .p1.IsHome }} -{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) }} -{{ end }} -{{ $isActive := eq .p1 .p2 }} - -{{ end }} +{{- define "breadcrumbnav" -}} + {{ if .p1.Parent -}} + {{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) -}} + {{ else if not .p1.IsHome -}} + {{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) -}} + {{ end -}} + {{ $isActive := eq .p1 .p2 }} + +{{- end -}} diff --git a/layouts/_partials/navbar.html b/layouts/_partials/navbar.html index 0de6f46c..0a563d8f 100644 --- a/layouts/_partials/navbar.html +++ b/layouts/_partials/navbar.html @@ -1,8 +1,11 @@ {{- /* - A version of the navbar.html partial in Docsy, only modified - to include the spec version, which is calculated using an - inline `version-string` partial. + A copy of the navbar.html partial in Docsy, modified to: + + * remove `data-bs-theme` at L20, otherwise the title disappears on hover. + * replace the site title with "specification" at L31. + * include the spec version from the config at L34-35, which is calculated + using an inline `version-string` partial. */ -}} @@ -13,8 +16,8 @@ {{ $baseURL := urls.Parse $.Site.Params.Baseurl -}} -{{ define "_partials/version-string" }} - {{ $ret := "unstable version"}} +{{- define "_partials/version-string" -}} + {{ $ret := "unstable version" -}} - {{ $status := .Site.Params.version.status }} + {{ $status := .Site.Params.version.status -}} - {{ if ne $status "unstable"}} - {{ $path := path.Join "changelogs" }} + {{ if ne $status "unstable" -}} + {{ $path := path.Join "changelogs" -}} - {{/* produces a string similar to "version v1.5" */}} - {{ $ret = delimit (slice "version v" .Site.Params.version.major "." .Site.Params.version.minor) "" }} - {{ end }} + {{/* produces a string similar to "version v1.5" */ -}} + {{ $ret = delimit (slice "version v" .Site.Params.version.major "." .Site.Params.version.minor) "" -}} + {{ end -}} - {{ return $ret }} -{{ end }} + {{ return $ret -}} +{{- end -}} diff --git a/layouts/_partials/sidebar-tree.html b/layouts/_partials/sidebar-tree.html index dba63f3a..e5f00807 100644 --- a/layouts/_partials/sidebar-tree.html +++ b/layouts/_partials/sidebar-tree.html @@ -1,37 +1,57 @@ {{- /* - A modified version of the siderbar-tree.html partial in Docsy, adding: - - * The "toc.html" partial at L45. + A copy of the siderbar-tree.html partial in Docsy, modified to: + + * Ignore the `sidebarRoot` parameter, because of this regression: + + * Add the "toc.html" partial at L68. */ -}} -{{/* We cache this partial for bigger sites and set the active class client side. */ -}} -{{ $sidebarCacheLimit := .Site.Params.ui.sidebar_cache_limit | default 2000 -}} -{{ $shouldDelayActive := ge (len .Site.Pages) $sidebarCacheLimit -}} +{{ $context := .context -}} +{{ $sidebarRoot := .sidebarRoot -}} +{{ $sidebarRootID := .sidebarRootID -}} +{{ $cacheSidebar := .cacheSidebar -}} + +{{ with $context -}} +{{/* When the sidebar is cached, "active" class is set client side. */ -}} +{{ $shouldDelayActive := $cacheSidebar -}} +
{{ if not .Site.Params.ui.sidebar_search_disable -}} + - {{ else -}} + + {{- else -}} +
- {{ end -}} + + {{- end }} + {{/* */ -}} +
+ +{{- end }}{{/* with $context */ -}} + {{ define "section-tree-nav-section" -}} -{{ $s := .section -}} -{{ $p := .page -}} -{{ $shouldDelayActive := .shouldDelayActive -}} -{{ $sidebarMenuTruncate := .sidebarMenuTruncate -}} -{{ $treeRoot := cond (eq .ulNr 0) true false -}} -{{ $ulNr := .ulNr -}} -{{ $ulShow := .ulShow -}} -{{ $active := and (not $shouldDelayActive) (eq $s $p) -}} -{{ $activePath := and (not $shouldDelayActive) (or (eq $p $s) ($p.IsDescendant $s)) -}} -{{ $show := cond (or (lt $ulNr $ulShow) $activePath (and (not $shouldDelayActive) (eq $s.Parent $p.Parent)) (and (not $shouldDelayActive) (eq $s.Parent $p)) (not $p.Site.Params.ui.sidebar_menu_compact) (and (not $shouldDelayActive) ($p.IsDescendant $s.Parent))) true false -}} -{{ $mid := printf "m-%s" ($s.RelPermalink | anchorize) -}} -{{ $pages_tmp := where (union $s.Pages $s.Sections).ByWeight ".Params.toc_hide" "!=" true -}} -{{ $pages := $pages_tmp | first $sidebarMenuTruncate -}} -{{ $truncatedEntryCount := sub (len $pages_tmp) $sidebarMenuTruncate -}} -{{ if gt $truncatedEntryCount 0 -}} - {{ warnf "WARNING: %d sidebar entries have been truncated. To avoid this, increase `params.ui.sidebar_menu_truncate` to at least %d (from %d) in your config file. Section: %s" - $truncatedEntryCount (len $pages_tmp) $sidebarMenuTruncate $s.Path -}} -{{ end -}} -{{ $withChild := gt (len $pages) 0 -}} -{{ $manualLink := cond (isset $s.Params "manuallink") $s.Params.manualLink ( cond (isset $s.Params "manuallinkrelref") (relref $s $s.Params.manualLinkRelref) $s.RelPermalink) -}} -{{ $manualLinkTitle := cond (isset $s.Params "manuallinktitle") $s.Params.manualLinkTitle $s.Title -}} -
  • - {{ if (and $p.Site.Params.ui.sidebar_menu_foldable (ge $ulNr 1)) -}} - - - {{ else -}} - {{ with $s.Params.Icon}}{{ end }}{{ $s.LinkTitle }} - {{- end }} - {{- if $withChild }} - {{- $ulNr := add $ulNr 1 }} -
      - {{ range $pages -}} - {{ if (not (and (eq $s $p.Site.Home) (eq .Params.toc_root true))) -}} - {{ template "section-tree-nav-section" (dict "page" $p "section" . "shouldDelayActive" $shouldDelayActive "sidebarMenuTruncate" $sidebarMenuTruncate "ulNr" $ulNr "ulShow" $ulShow) }} + {{/* cSpell:ignore manuallink manuallinkrelref manuallinktitle */ -}} + {{ $s := .section -}} + {{ $p := .page -}} + {{ $shouldDelayActive := .shouldDelayActive -}} + {{ $sidebarMenuTruncate := .sidebarMenuTruncate -}} + {{ $treeRoot := cond (eq .ulNr 0) true false -}} + {{ $ulNr := .ulNr -}} + {{ $ulShow := .ulShow -}} + {{ $active := and (not $shouldDelayActive) (eq $s $p) -}} + {{ $activePath := and (not $shouldDelayActive) (or (eq $p $s) ($p.IsDescendant $s)) -}} + {{ $show := cond + (or + (lt $ulNr $ulShow) + $activePath + (and (not $shouldDelayActive) (eq $s.Parent $p.Parent)) + (and (not $shouldDelayActive) (eq $s.Parent $p)) + (not $p.Site.Params.ui.sidebar_menu_compact) + (and (not $shouldDelayActive) ($p.IsDescendant $s.Parent)) + ) + true false + -}} + {{ $mid := printf "m-%s" ($s.RelPermalink | anchorize) -}} + {{ $pages_tmp := where (union $s.Pages $s.Sections).ByWeight ".Params.toc_hide" "!=" true -}} + {{ $pages := $pages_tmp | first $sidebarMenuTruncate -}} + {{ $truncatedEntryCount := sub (len $pages_tmp) $sidebarMenuTruncate -}} + + {{ if gt $truncatedEntryCount 0 -}} + {{ warnf "WARNING: %d sidebar entries have been truncated. To avoid this, increase `params.ui.sidebar_menu_truncate` to at least %d (from %d) in your config file. Section: %s" + $truncatedEntryCount (len $pages_tmp) $sidebarMenuTruncate $s.Path -}} + {{ end -}} + + {{ $withChild := gt (len $pages) 0 -}} + {{ $manualLink := + cond + (isset $s.Params "manuallink") + $s.Params.manualLink + (cond + (isset $s.Params "manuallinkrelref") + (relref $s $s.Params.manualLinkRelref) + $s.RelPermalink + ) + -}} + {{ $manualLinkTitle := + cond + (isset $s.Params "manuallinktitle") + $s.Params.manualLinkTitle + $s.Title + -}} + {{ if and $treeRoot (eq $s.Params.sidebar_root_for "self") -}} + {{ with $s.Parent -}} + {{ $manualLink = .RelPermalink -}} + {{ end -}} + {{ end -}} +
    • + {{ if (and $p.Site.Params.ui.sidebar_menu_foldable (ge $ulNr 1)) -}} + + + {{ else -}} + + {{- with $s.Params.Icon -}} + + {{- end -}} + + {{- $s.LinkTitle -}} + + {{- end -}} + {{ if $withChild -}} + {{ $ulNr := add $ulNr 1 }} +
        + {{ range $pages -}} + {{ if (not (and (eq $s $p.Site.Home) (eq .Params.toc_root true))) -}} + {{ template "section-tree-nav-section" (dict "page" $p "section" . "shouldDelayActive" $shouldDelayActive "sidebarMenuTruncate" $sidebarMenuTruncate "ulNr" $ulNr "ulShow" $ulShow) }} + {{- end }} + {{- end }} +
      {{- end }} - {{- end }} -
    - {{- end }} -
  • -{{- end -}} + +{{- end }} diff --git a/layouts/_partials/toc.html b/layouts/_partials/toc.html index 318335f2..adfbd161 100644 --- a/layouts/_partials/toc.html +++ b/layouts/_partials/toc.html @@ -1,15 +1,29 @@ {{/* - A modified version of the toc.html partial in Docsy. + A copy of the toc.html partial in Docsy, modified to: -*/}} -{{ $page := .Params }} + * show the page's title instead of "on this page" + +*/ -}} + +{{/* + + Always render the td-toc element. ScrollSpy is counting on it to exist, + even if it's empty. + + cSpell:ignore notoc +*/ -}} + +
    {{ if not .Params.notoc -}} - {{ with .TableOfContents -}} -
    -
    - {{ $page.Title }} - {{ . }} + {{ $toc := .TableOfContents -}} + {{ if and $toc (ne $toc ``) -}} +
    + {{ .Params.Title }} +
    + {{ $toc | safeHTML }} {{ end -}} {{ end -}} +
    +{{/* */ -}} diff --git a/layouts/docs/baseof.html b/layouts/docs/baseof.html index b5b7a0f0..e18864dd 100644 --- a/layouts/docs/baseof.html +++ b/layouts/docs/baseof.html @@ -1,11 +1,14 @@ {{/* - A copy of the baseof.html partial in Docsy, modified - to remove the right-hand column from the layout. + A copy of the baseof.html partial in Docsy, modified to: -*/}} + * generate a static file `versions.json` that can be used to populate the + version picker. + * remove the right-hand column from the layout. -{{/* Generate a static file versions.json that can be used to populate the version picker */}} +*/ -}} + +{{/* Generate a static file versions.json that can be used to populate the version picker */ -}} {{ if .IsHome }} {{- /* Load all changelog subpages, sorted by release date */ -}} {{ $changelog := site.GetPage "changelog" }} @@ -28,20 +31,18 @@ + class="no-js" + {{- $darkMode := partialCached "dark-mode-config.html" "dark-mode-global" -}} + {{- if $darkMode.enable }} data-theme-init{{ end }}> {{ partial "head.html" . }} - {{ if .Page.Store.Get "hasMath" }} - - - {{ end }}
    {{ partial "navbar.html" . }}
    -
    +