T-HUB/docs/matrix-setup.md
glass beadian 4a7e78b28d Collectives P1: participation landing (ES/EN), group tree, room provisioning APIs
- 030: groups.parent_id tree + kind discriminator + group_rooms mapping
- /collectives module: create/tree/join APIs, MatrixProvisioner (open room
  public+federated, closed room E2EE-at-creation, onboarding room), NullProvisioner
  fail-soft when ARCHIVE_PROVISIONER_* unset
- web root becomes the public participation manual (ES-first + EN toggle,
  three paths: join by invite, start collective, solo account)
- participation manual content in core
2026-10-12 13:53:40 +00:00

4.5 KiB

Matrix Setup — Tactical Media Broadcast Hub team chat

OccupyMedia storage phase one adds group attachment/archive contracts and an independent files/docs scaffold. Live occ-chat remains conduwuit v0.5.0 with its existing local state/media; no volume or image switch is part of this phase. Future Tuwunel native R2 media requires a separate rehearsal and authorized upgrade. Archive mirroring is restricted to explicitly mapped unencrypted archive rooms; encrypted rooms are excluded. Collaborative ODT editing uses oCIS/Collabora WOPI, not Matrix.

Matrix (conduwuit homeserver) is the team/internal chat plane. Stream viewer chat stays on the S5 hub (docs/design/streaming-architecture.md §3). Division of labor:

Plane Tech Who it serves
Team chat, DMs, bridged Telegram channels Matrix (conduwuit + bridges) editors, reviewers, admins
Stream viewer chat S5 hub → /realtime WS Opticast app + control room
Review threads (per-post) Tactical Media Broadcast Hub native (WP5.1) editorial workflow

Deploy

  1. cp infra/matrix/.env.example infra/matrix/.env — set MATRIX_SERVER_NAME (permanent!) and a registration token
  2. Point your reverse proxy at :6167 with HTTPS (federation requires valid TLS)
  3. docker compose -f infra/matrix/docker-compose.yml up -d
  4. First account: temporarily set MATRIX_ALLOW_REGISTRATION=true, register the admin via any Matrix client (Element), then lock it back. Share the token for invites.

Rich text

Conduwuit supports formatted bodies natively — clients (Element et al.) give Markdown, media, reactions, edits, replies, threads. As good as Telegram out of the box, plus E2E encryption.

Telegram bridge (feeds WP15 — join channels & amplify)

mautrix-telegram runs alongside. One-time setup:

  1. docker compose run --rm mautrix-telegram — first boot writes /data/config.yaml; set homeserver + bridge admin
  2. In Matrix, DM @telegrambot:your-server, send login + the phone/code → your Telegram account is bridged
  3. Telegram channels you join appear as Matrix rooms; posts arrive as rich messages. The WP15 grabber (phase 2) reads those rooms → archive → review → amplify — no custom MTProto client needed, and the bridge is the battle-tested path
  4. Two-way: replying in the Matrix room posts to Telegram (subject to the same rights/attribution rules as S6)

Branding

Element Web (if self-hosted as the client) accepts custom CSS — the same propagation rule as PeerTube: repo is the source of truth, a sync script pushes (accent #FF1610 on black, solid disk mark) after any brand change. Native clients keep their own themes; brand consistency applies to web surfaces.

Provisioner bot (collectives P1)

Room provisioning for collectives (docs/design/2026-10-12-collectives-architecture.md) runs as a separate bot account from the archive bot — both are crypto-blind, but they hold different powers, so they never share credentials or a device id:

# apps/api reads these; missing config = collective creation answers 503 (never a boot failure)
ARCHIVE_PROVISIONER_HOMESERVER_URL=https://chat.example.com
ARCHIVE_PROVISIONER_USER=@hub-provisioner:chat.example.com   # create it like any bot account below
ARCHIVE_PROVISIONER_PASSWORD=...
ARCHIVE_PROVISIONER_DEVICE_ID=HUB_PROVISIONER_BOT            # stable: txn-id idempotency survives restarts

What it provisions per collective, in one pass (see apps/api/src/collectives/matrix-provisioner.ts):

Room preset / visibility federation encryption notes
Open public_chat / public on (m.federate: true) never history_visibility: shared; archive-mirrorable by definition
Closed (production) private_chat / private off at creation (m.megolm.v1.aes-sha2 in initial_state) no unencrypted form ever exists server-side
Onboarding private_chat / private off no bot posts the participation manual ES-first, then EN; disposable

Founder power level is pinned to 100, everyone else 0; the bot keeps 100 to administer the rooms it built. Room ids (never aliases) are recorded in group_rooms (migration 030), tenant-scoped and RLS'd.

Tactical Media Broadcast Hub integration points (follow-ups)

  • Inbox screen: swap fixtures for Matrix client-sdk (matrix-js-sdk) — DMs + team rooms render in-app
  • Review notifications: WP5.1 posts approval-needed events into a team room
  • WP15: grabber consumes bridged Telegram rooms (above)