diff --git a/docs/matrix.md b/docs/matrix.md index e6c75d90..5c27216f 100644 --- a/docs/matrix.md +++ b/docs/matrix.md @@ -33,29 +33,39 @@ Two distinct hostnames: *irrevocably* in every `@user:` and `!room:` identifier minted on this homeserver. Cannot be changed later without abandoning every account and chat history. Defaults to the - bare `services.hyperhive.domain`; clients auto-discover the actual - API endpoint via the `.well-known/matrix/{client,server}` routes - the hive-gateway serves at that domain. + bare `services.hyperhive.swarm.domain`; clients auto-discover the + actual API endpoint via the `.well-known/matrix/{client,server}` + routes the gateway serves at that domain. - **`gatewayHost`** — the API listener hostname, where the gateway's matrix vhost proxies `/_matrix/*` to tuwunel. Defaults to - `chat.` — the **swarm's** domain, - because a swarm runs one homeserver. Set to `null` to skip the + `chat.`. Set to `null` to skip the gateway vhost (tuwunel stays direct on `httpPort`). - ⚠️ Only this one moved. `serverName` still defaults to the bare hive - domain, and the two are independent by design: `gatewayHost` is a - routing detail clients rediscover through `.well-known`, while - `serverName` is baked into every user and room id. A deployment that - wants its old API hostname pins - `gatewayHost = "matrix."` — exactly what the previous - default rendered. +Both now default under the **swarm** domain, because a swarm runs one +homeserver: tying its identity to a single hive's domain would make +relocating the container between hives look like a different +homeserver. -**Breaking change**: `serverName` used to default to -`matrix.${services.hyperhive.domain}`. Existing homeservers must set -the option explicitly to preserve their existing user / room IDs -before rebuilding. The default flipped because the bare hive-domain -makes for cleaner matrix IDs and `.well-known` delegation hides the -sub-domain from the user-facing identifier. +⚠️ **They are still not interchangeable, and the difference is the +cost of changing one.** `gatewayHost` is a routing detail clients +rediscover through `.well-known`, so it is safe to move on a running +deployment. `serverName` is baked into every user and room id, so +adopting a new one does **not** rename the existing users and rooms — +it strands them, because their ids still name a homeserver that no +longer answers. + +**Breaking change — pin `serverName` before rebuilding.** Its default +has now moved twice: from `matrix.${services.hyperhive.domain}`, to +the bare hive domain, and now to the swarm domain. Any homeserver that +has already minted ids must name the value it minted them under: + +```nix +services.hyperhive.swarm.matrix = { + # whichever this deployment already uses + serverName = config.services.hyperhive.domain; + gatewayHost = "matrix.${config.services.hyperhive.domain}"; +}; +``` ## Default-closed firewall diff --git a/nix/host-modules/hive-matrix.nix b/nix/host-modules/hive-matrix.nix index fef052f5..f3b62abf 100644 --- a/nix/host-modules/hive-matrix.nix +++ b/nix/host-modules/hive-matrix.nix @@ -7,14 +7,29 @@ let cfg = config.services.hyperhive.swarm.matrix; networkCfg = config.services.hyperhive.network; - hyperhiveDomain = config.services.hyperhive.domain; swarmDomain = config.services.hyperhive.swarm.domain; - # ⚠️ Falls back to the HIVE domain, and must keep doing so even though - # `gatewayHost` moved to the swarm's: `serverName` is the matrix - # identifier baked into every user and room id, so changing it is a - # different homeserver rather than a rename. The two are independent on - # purpose — see the `gatewayHost` description below. - effectiveServerName = if cfg.serverName != null then cfg.serverName else hyperhiveDomain; + # Falls back to the SWARM domain: a swarm runs one homeserver, so its + # identifier belongs to the swarm rather than to whichever hive happens + # to host it — otherwise moving the container between hives would look + # like a different homeserver. + # + # ⚠️ Changing this default is a BREAKING change in a way that moving + # `gatewayHost` was not: `serverName` is baked irrevocably into every + # user and room id, so a deployment that rebuilds onto a new one is a + # *different homeserver*, not a renamed one. Existing hives pin the old + # value explicitly (see the option's description); the default is what + # a fresh swarm gets. + # + # Total on a null swarm domain, deliberately: the required-domain + # assertion in hive-network.nix is what should fire, not a coercion + # error from an unrelated option interpolating null. + effectiveServerName = + if cfg.serverName != null then + cfg.serverName + else if swarmDomain != null then + swarmDomain + else + "invalid"; # fluffychat-web build fixes: nixpkgs's `flutter341.buildFlutterApplication` # skips the dart web-worker compile + the emscripten native_imaging @@ -137,21 +152,32 @@ in Matrix `server_name` — the host part of every user ID (`@argus:`) and room ID minted on this homeserver. CRITICAL: must be stable from day one because - it's embedded irrevocably in the identifiers. Defaults to - `services.hyperhive.domain` (the bare hive domain). Combined - with the `.well-known/matrix/{client,server}` routes the - hive-gateway serves at that domain, clients auto-discover the + it's embedded irrevocably in the identifiers. + + Defaults to `services.hyperhive.swarm.domain` (the bare swarm + domain), because **a swarm runs one homeserver** — tying its + identity to a single hive's domain would make relocating the + container between hives look like a different homeserver. + Combined with the `.well-known/matrix/{client,server}` routes + the gateway serves at that domain, clients auto-discover the actual matrix endpoint without needing a subdomain. Override here only if you need a different server_name shape (e.g. - `matrix.` if you want the subdomain split, or `chat.example.org` for a bespoke hostname). - **Breaking change**: this used to default to - `matrix.''${services.hyperhive.domain}`. matrix IDs embed - the server_name irrevocably, so existing homeservers must - set `services.hyperhive.swarm.matrix.serverName = "matrix.''${services.hyperhive.domain}";` - explicitly to preserve their existing user / room IDs - before rebuilding. + **Breaking change, and the one on this page that cannot be + undone by rebuilding.** This default has now moved twice — from + `matrix.''${services.hyperhive.domain}`, then to the bare hive + domain, and now to the swarm domain. Every existing homeserver + must pin whichever value it already minted ids under, e.g. + + ```nix + services.hyperhive.swarm.matrix.serverName = + config.services.hyperhive.domain; # or "matrix.''${…domain}" + ``` + + before rebuilding. Adopting a new `server_name` does not rename + the old users and rooms — it strands them, because their ids + still name a homeserver that no longer answers. ''; }; @@ -219,13 +245,14 @@ in bottom of that doc. ⚠️ **`gatewayHost` and `serverName` are different things, and - only this one moved.** `gatewayHost` is the API listener - hostname (where nginx proxies `/_matrix/*`) and is free to - change: it is a routing detail clients rediscover through - `.well-known`. `serverName` is the matrix-identifier domain - embedded **irrevocably** in every user and room id — changing - that is a different homeserver, not a rename, so it still - defaults to the bare hive domain and is untouched here. + they carry very different costs.** `gatewayHost` is the API + listener hostname (where nginx proxies `/_matrix/*`) and is + free to change: it is a routing detail clients rediscover + through `.well-known`. `serverName` is the matrix-identifier + domain embedded **irrevocably** in every user and room id — + adopting a new one is a different homeserver, not a rename. + Both defaults now sit under the swarm domain, but only this + one is safe to move on a running deployment. A deployment that was running before this moved keeps its current name by pinning