Compare commits

..
12 changed files with 34 additions and 50 deletions

View file

@ -3,7 +3,7 @@
Private Matrix homeserver (matrix-tuwunel — the conduwuit
successor) wrapped in a nixos-container, plus optional fluffychat-web
client at `matrix.<hive>/`. Configured via
`services.hyperhive.swarm.matrix.*`; vhost routing lives in
`services.hyperhive.matrix.*`; vhost routing lives in
[`gateway.md`](gateway.md).
## Container shape
@ -60,7 +60,7 @@ client needs to reach the client-server API directly.
**Breaking change**: used to default to `true`. Operators relying on
external reach must add
`services.hyperhive.swarm.matrix.openFirewall = true;` before rebuilding.
`services.hyperhive.matrix.openFirewall = true;` before rebuilding.
Federation port 8448 is intentionally not opened here — tuwunel
serves the federation API on the same `httpPort` as client-server
@ -119,7 +119,7 @@ Initial rollout settings:
`yes_i_am_very_very_sure_…_open_registration_…` flag keeps the
server closed to anyone without the token.
- `allow_encryption` — server-side E2EE switch, sourced from
`services.hyperhive.swarm.matrix.allowEncryption` (**default `false`**, opt-in).
`services.hyperhive.matrix.allowEncryption` (**default `false`**, opt-in).
Off by default because on the hive-internal homeserver the operator
already controls the transport; turn it on for encrypted rooms on
external / federated homeservers or to keep contents opaque to the
@ -168,7 +168,7 @@ re-creation (e.g. after a homeserver wipe).
## Configuration tuning
```nix
services.hyperhive.swarm.matrix = {
services.hyperhive.matrix = {
trustedServers = [ "matrix.org" "example.com" ]; # default: []
maxRequestSize = 20000000; # default: 20 MB
};

View file

@ -58,7 +58,7 @@ hivectl forge reconcile-config iris --verbose # include the full diff, not
Manual entry to the same idempotent matrix provisioning flow
`hive-c0re` runs at boot. Requires the `hive-matrix` container to be
running (`services.hyperhive.swarm.matrix.enable = true`).
running (`services.hyperhive.matrix.enable = true`).
```bash
hivectl matrix create-user iris # provision (or re-provision) matrix account for agent `iris`
@ -315,5 +315,5 @@ an error.
A surface has no URL when it isn't browser-reachable: `home` needs
`services.hyperhive.domain`; `forge` needs
`services.hyperhive.forge.behindGateway = true`; `matrix` needs
`services.hyperhive.swarm.matrix.gui.enable = true`. In those cases the command
`services.hyperhive.matrix.gui.enable = true`. In those cases the command
exits with a hint naming the option to set.

View file

@ -679,9 +679,9 @@ existing in the page DOM.
A static matrix web client (default `pkgs.fluffychat-web` rebuilt
with `--base-href /matrix/`, swappable via
`services.hyperhive.swarm.matrix.gui.package`) served by the hive-gateway
`services.hyperhive.matrix.gui.package`) served by the hive-gateway
nginx container at `/matrix/` when
`services.hyperhive.swarm.matrix.gui.enable` is on (defaults to
`services.hyperhive.matrix.gui.enable` is on (defaults to
`matrix.enable`). c0re signals availability via the
`HIVE_MATRIX_GUI_ENABLED` env var → `state.matrix_gui_enabled` in
`/api/state`; the gateway does the actual static serving.

View file

@ -84,7 +84,7 @@ pub(super) struct StateSnapshot {
forge_present: bool,
/// Whether the matrix GUI is reachable at `/matrix/`. Sourced from
/// `HIVE_MATRIX_GUI_ENABLED` env var (set by the c0re NixOS module
/// when `services.hyperhive.swarm.matrix.gui.enable` is on). The gateway
/// when `services.hyperhive.matrix.gui.enable` is on). The gateway
/// (hive-gateway.nix) does the actual `/matrix/` static serving;
/// this flag is just an availability signal for iris's dashboard
/// chrome so the `M4TR1X →` tab doesn't flash when the GUI is off.

View file

@ -1,8 +1,7 @@
//! Optional matrix-tuwunel wiring: shared registration token (host) +
//! per-agent UIAA registration → `<agent-state>/matrix-token`. No-op
//! when the `hive-matrix` container isn't running, so operators who
//! haven't flipped `services.hyperhive.swarm.matrix.enable = true` pay
//! nothing.
//! haven't flipped `hyperhive.matrix.enable = true` pay nothing.
//!
//! See `docs/matrix.md::Provisioning flow (registration token)` for
//! the full UIAA round-trip, token-file shape, and host/container
@ -17,7 +16,7 @@ use crate::coordinator::Coordinator;
/// Client-server API base this daemon provisions against, from
/// `HIVE_MATRIX_API_URL` (set by `hive-c0re.nix` from
/// `services.hyperhive.swarm.matrix.apiUrl`).
/// `hyperhive.matrix.apiUrl`).
///
/// `None` means **this hive has no homeserver to provision against** and
/// every matrix path no-ops — see [`is_present`]. There is deliberately no
@ -44,8 +43,7 @@ fn matrix_http() -> Option<&'static str> {
/// rather than the missing variable.
fn matrix_base() -> Result<&'static str> {
matrix_http().context(
"matrix: no homeserver configured \
(services.hyperhive.swarm.matrix.apiUrl / HIVE_MATRIX_API_URL) \
"matrix: no homeserver configured (hyperhive.matrix.apiUrl / HIVE_MATRIX_API_URL) — \
this path should have been gated on matrix::is_present()",
)
}

View file

@ -472,8 +472,8 @@ fn require_matrix_present() -> Result<()> {
return Ok(());
}
anyhow::bail!(
"no matrix homeserver configured — set services.hyperhive.swarm.matrix.enable = true to run one \
here, or services.hyperhive.swarm.matrix.apiUrl to point at an existing one, before \
"no matrix homeserver configured — set services.hyperhive.matrix.enable = true to run one \
here, or services.hyperhive.matrix.apiUrl to point at an existing one, before \
provisioning matrix users"
)
}

View file

@ -30,7 +30,7 @@ pub(crate) async fn open_url(socket: &Path, target: OpenTarget) -> Result<()> {
),
OpenTarget::Matrix => (
urls.matrix,
"the matrix GUI URL needs `services.hyperhive.swarm.matrix.gui.enable = true`",
"the matrix GUI URL needs `services.hyperhive.matrix.gui.enable = true`",
),
};
let url = url.with_context(|| format!("no URL available for this surface — {hint}"))?;

View file

@ -44,7 +44,7 @@ let
boot.loader.grub.enable = false;
system.stateVersion = "25.11";
services.hyperhive.enable = lib.mkForce false;
services.hyperhive.swarm.matrix.enable = lib.mkForce false;
services.hyperhive.matrix.enable = lib.mkForce false;
}
)
];

View file

@ -102,10 +102,7 @@ in
}
//
lib.optionalAttrs
(
config.services.hyperhive.swarm.matrix.enable
&& config.services.hyperhive.swarm.matrix.gatewayHost != null
)
(config.services.hyperhive.matrix.enable && config.services.hyperhive.matrix.gatewayHost != null)
{
# In-cluster matrix homeserver URL for each agent's
# hive-matrix-daemon — the gateway vhost (`matrix.<domain>`).
@ -120,12 +117,12 @@ in
# forward leaves `hyperhive.matrix.url` null and the daemon no-ops;
# that is the honest answer when the hive has no matrix vhost to point
# at.
HIVE_MATRIX_URL = "http://${config.services.hyperhive.swarm.matrix.gatewayHost}";
HIVE_MATRIX_URL = "http://${config.services.hyperhive.matrix.gatewayHost}";
}
// lib.optionalAttrs (config.services.hyperhive.swarm.matrix.apiUrl != null) {
// lib.optionalAttrs (config.services.hyperhive.matrix.apiUrl != null) {
# Client-server API base hive-c0re uses to provision matrix (register
# agent users, create the hive space + chat room, invite members).
# Supplied by `services.hyperhive.swarm.matrix.apiUrl`, which the matrix
# Supplied by `services.hyperhive.matrix.apiUrl`, which the matrix
# module fills in with its own loopback listener when it is the thing
# running tuwunel — and which the operator sets by hand when the
# homeserver lives on another machine.
@ -134,9 +131,9 @@ in
# vhost, and it is absent whenever there is no vhost. Reusing it here
# would silently stop provisioning on a hive that runs matrix without
# one.
HIVE_MATRIX_API_URL = config.services.hyperhive.swarm.matrix.apiUrl;
HIVE_MATRIX_API_URL = config.services.hyperhive.matrix.apiUrl;
}
// lib.optionalAttrs config.services.hyperhive.swarm.matrix.gui.enable {
// lib.optionalAttrs config.services.hyperhive.matrix.gui.enable {
# Availability flags read by the dashboard's `/api/state`.
# Matrix GUI lives entirely on the gateway nginx (matrix tab
# only shows when both flags are on). Gateway routing detail:
@ -165,15 +162,14 @@ in
//
lib.optionalAttrs
(
config.services.hyperhive.swarm.matrix.gui.enable
&& config.services.hyperhive.swarm.matrix.gatewayHost != null
config.services.hyperhive.matrix.gui.enable && config.services.hyperhive.matrix.gatewayHost != null
)
{
# Browser-facing matrix GUI (fluffychat) URL — the gateway
# vhost (`matrix.<domain>`). Surfaced via the daemon's `Urls`
# request for `hivectl open matrix`. Absent when the GUI is off
# or no gatewayHost is set (no browser-reachable matrix vhost).
HIVE_MATRIX_PUBLIC_URL = "https://${config.services.hyperhive.swarm.matrix.gatewayHost}/";
HIVE_MATRIX_PUBLIC_URL = "https://${config.services.hyperhive.matrix.gatewayHost}/";
}
// lib.optionalAttrs (config.services.hyperhive.swarm.snapshotStore.address != null) {
# `host:port` of the swarm's single snapshot store, for pushing agent

View file

@ -15,7 +15,7 @@
let
cfg = config.services.hyperhive.gateway;
hyperhiveDomain = config.services.hyperhive.domain;
matrixCfg = config.services.hyperhive.swarm.matrix;
matrixCfg = config.services.hyperhive.matrix;
forgeCfg = config.services.hyperhive.swarm.forge;
networkCfg = config.services.hyperhive.network;

View file

@ -5,7 +5,7 @@
...
}:
let
cfg = config.services.hyperhive.swarm.matrix;
cfg = config.services.hyperhive.matrix;
networkCfg = config.services.hyperhive.network;
hyperhiveDomain = config.services.hyperhive.domain;
effectiveServerName = if cfg.serverName != null then cfg.serverName else hyperhiveDomain;
@ -86,17 +86,7 @@ in
# settings: docs/matrix.md. Vhost map + discovery flow + tuning
# knobs: docs/gateway.md.
# Matrix moved under `swarm` when the swarm-global services were
# consolidated. One rename for the namespace: the subtree comes with it,
# so existing hives keep evaluating and get one warning naming both paths.
imports = [
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "matrix" ]
[ "services" "hyperhive" "swarm" "matrix" ]
)
];
options.services.hyperhive.swarm.matrix = {
options.services.hyperhive.matrix = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
@ -139,7 +129,7 @@ in
**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}";`
set `services.hyperhive.matrix.serverName = "matrix.''${services.hyperhive.domain}";`
explicitly to preserve their existing user / room IDs
before rebuilding.
'';
@ -161,8 +151,8 @@ in
type = lib.types.nullOr lib.types.str;
default = if cfg.enable then "http://127.0.0.1:${toString cfg.httpPort}" else null;
defaultText = lib.literalExpression ''
if services.hyperhive.swarm.matrix.enable
then "http://127.0.0.1:''${toString services.hyperhive.swarm.matrix.httpPort}"
if services.hyperhive.matrix.enable
then "http://127.0.0.1:''${toString services.hyperhive.matrix.httpPort}"
else null
'';
example = "https://matrix.example.com";
@ -223,7 +213,7 @@ in
**Breaking change**: this used to default to `true`. If you
relied on the old default for external reach, add
`services.hyperhive.swarm.matrix.openFirewall = true;` to your host
`services.hyperhive.matrix.openFirewall = true;` to your host
config before rebuilding.
Note: federation (the matrix-spec well-known port 8448) is
@ -300,7 +290,7 @@ in
enable = lib.mkOption {
type = lib.types.bool;
default = cfg.enable;
defaultText = lib.literalExpression "config.services.hyperhive.swarm.matrix.enable";
defaultText = lib.literalExpression "config.services.hyperhive.matrix.enable";
description = ''
Serve a matrix web client at `matrix.''${services.hyperhive.domain}/`.
Requires `matrix.gatewayHost != null` (default `matrix.<hive>`
@ -340,7 +330,7 @@ in
{
assertion = cfg.gatewayHost == null || cfg.gatewayHost != "";
message = ''
services.hyperhive.swarm.matrix.gatewayHost = "" is rejected. The
services.hyperhive.matrix.gatewayHost = "" is rejected. The
rendered URLs would be invalid (nginx wildcard catch-all for
an empty server_name, /etc/hosts rejects empty entries).
Use `null` to disable the gateway vhost entirely (tuwunel

View file

@ -36,7 +36,7 @@
example = "darkest.space";
description = ''
Canonical host domain for hyperhive subsystems that need a
stable name (currently: `services.hyperhive.swarm.matrix.serverName`
stable name (currently: `services.hyperhive.matrix.serverName`
derives from this, defaulting to
`matrix.''${services.hyperhive.domain}` when `serverName` is
null). **Required** when `services.hyperhive.enable` eval fails