Commit Graph
6392 Commits
Author SHA1 Message Date
Slavi PantaleevandClaude Opus 5 d534b00e04 Add a Molecule scenario for mautrix-meta-messenger
Stands the bridge up against the shared homeserver stub and checks that it
starts on the configuration the role rendered: the unit is active with no
automatic restarts, the appservice listener on 29319 answers, and the bridge
created its sqlite database under the role's data path as the role's uid.
Nothing is bridged - there is no Facebook or Messenger account involved and
there is deliberately never going to be one.

The thing worth proving for this role in particular is the Meta mode. One
upstream codebase serves several Meta networks, and
`matrix_bridge_mautrix_meta_messenger_meta_mode` is what picks which one; the
role expands it into an appservice id, a ghost username prefix, a bot
displayname and the bridge's `tor` switch. The scenario therefore runs in
`facebook-tor` mode rather than the role's default `messenger`, and asserts on
all four - against the parsed configuration, not substrings. The registration
namespaces are checked by what they match rather than by comparing regexes:
this mode's ghosts are covered, the default mode's are not.

Since v26.07 the Instagram bridge is published to the same image repository
with an `ig-` tag prefix, so the running image is compared against the whole
tag `defaults/main.yml` pins rather than by substring - an `ig-` prefix would
mean this role pulled the other bridge's image.

Surprising: the role's derived sqlite URI does not work. For `sqlite3-fk-wal`
it builds `sqlite:///` + the in-container path, and the bridge hands that to
go-sqlite3 as a plain filename rather than parsing it as a URL, so it dies at
startup with `unable to open database file: no such file or directory`. Every
other mautrix role here uses a bare path. The playbook selects postgres
whenever postgres is enabled, which is the default, so nothing normally reaches
that code path. The scenario overrides the URI rather than changing the role's
default, which is consumer-visible; matrix-bridge-mautrix-meta-instagram has
the same expression.

Falsified by setting `matrix_bridge_mautrix_meta_messenger_meta_mode` back to
`messenger` and re-running: the run failed at "Assert the configuration
reflects the Meta mode the scenario selected", on the
`appservice.id == 'facebook-tor'` clause.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
2026-08-27 18:02:53 +03:00
Slavi PantaleevandClaude Opus 5 7e8b3466b6 Add a Molecule scenario for hookshot, and the openssl host command to the shared context
Hookshot is the widest HTTP surface of the bridges here - an appservice port
plus a `listeners` list whose entries appear or vanish with independent
switches - so the scenario asserts on that surface rather than on "it started".

The scenario configures NO third-party service. GitHub, GitLab, Jira and Figma
each need an account and a credential somewhere else, which is where a scenario
stops testing this repository (docs/molecule-testing.md). GitLab, which the role
turns on by default, is switched off and its absence from both config.yml and
the registration's namespaces is asserted. The generic webhooks listener needs
no credential from anyone, and is what gets exercised live: a POST to an unknown
hook id comes back as `{"ok":false,"error":"Webhook not found"}`, which only
Hookshot's own generic-webhook handler produces - an Express "Cannot POST" page
there would mean the port is Hookshot's but the service was never mounted on it.

Every port the scenario sets differs from both the role's default and Hookshot's
own, and the run asserts both halves: the webhooks, metrics and appservice ports
it chose all answer, and 9000/9001/9003/9993 - what the role would have used
instead - all refuse. Metrics are off in the role's defaults, so that listener
exists only because the scenario asked for it, and /metrics answers with
`hookshot_*` series that nothing else could have produced.

config.yml and registration.yml are parsed as YAML and asserted structurally, so
a value landing under the wrong key cannot pass as a substring match.

Two things the role made necessary:

- `tasks/main.yml` opens with a block tagged `reset-hookshot-encryption`, and
  Ansible runs tagged tasks unless tags are actually selected - so any tagless
  play hits it, and it stops `matrix-hookshot.service` before that service
  exists. The scenario skips the tag, which is what the playbook effectively
  does by always running with `--tags=setup-all,start`.

- The role reads `matrix_host_command_openssl`, which matrix-base defines.
  matrix-bridge-appservice-irc reads it too, so it goes in the shared playbook
  context rather than into this scenario.

Falsified by pointing the webhooks listener at 127.0.0.1 in the role's config
template - a change no file-level assertion can see. Every config and
registration assertion still passed, and the run failed at "Assert the generic
webhooks service is mounted on that listener" with "Port 9741 did not answer as
Hookshot's generic webhooks service". Reverted afterwards.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
2026-08-27 18:02:53 +03:00
Slavi PantaleevandClaude Opus 5 0ae18e7a16 Add a Molecule scenario for matrix-reminder-bot
A bot rather than a bridge, and not an appservice: it logs into the
homeserver as an ordinary user with a password, and keeps its reminders in
a local SQLite database. That makes it a cheap second data point for the
bot shape, and it is closer to matrix-alertmanager-receiver than to the
bridges - except that it has no HTTP surface at all, so there is nothing to
probe.

What the scenario proves instead:

- The unit is active and has not restarted. The bot parses its config file
  before its own catch-all retry loop starts, so anything wrong in what the
  role rendered surfaces as a crash loop rather than as a running process.
- The bot reached "Logged in as @molecule.reminder-bot:molecule.local" in
  the journal. That line is only reached once the login call came back as
  something other than an error, so it covers the homeserver URL, the user
  ID and the password the role rendered in one go - a real login round-trip
  against the shared stub, which already answers /_matrix/client/v3/login
  with an access token. No stub changes were needed.
- The SQLite database landed at the path the role configured, owned by the
  role's uid, with the role's own default name (bot.db) absent as a negative
  control - so the storage configuration reached the running process and not
  just the file on disk.
- matrix-nio populated its encryption store under the role's data path,
  inside an otherwise read-only container.
- The container runs as the playbook context's uid:gid with the configured
  timezone on TZ, and carries the version defaults/main.yml pins.
- `..._configuration_extension_yaml` was merged over the role's template:
  device_name is hardcoded in the template, so overriding it is only
  possible through the extension.

Every value the scenario sets differs from both the role's defaults and the
bot's own fallbacks - localpart, command prefix, timezone, database
filename, both the allowlist and the blocklist.

Falsified by pointing the homeserver URL at a dead port. The service stayed
`active` with NRestarts == 0 and that assertion passed, because the bot
catches every exception and retries every 15s rather than exiting - a good
illustration of why `active` on its own proves nothing here. The run failed
at "Assert the bot logged in as the user the role configured", which is the
assertion carrying the weight.

Surprise worth recording: the journal is read through a grep rather than a
`--lines=N` tail. The startup lines are the oldest in the journal, and if
the stub ever answers /sync instantly the bot's sync loop spins fast enough
to bury them under thousands of lines within a minute.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
2026-08-27 18:02:53 +03:00
Slavi Pantaleev 6af80175dc Add a Molecule scenario for mautrix-discord
Proves the bridge starts on the configuration this role rendered: the
systemd unit is active and has not been restarting, the appservice port is
open, config.yaml and registration.yaml (parsed, not grepped) carry the
scenario's homeserver address, bot username, tokens, command prefix,
avatar-proxy key, public address and log level, the sqlite database was
created under the role's data path as the role's uid, and the running
container is the version defaults/main.yml pins.

It does not bridge anything. Discord is behind an account, which is where a
scenario stops being a test of this repository.

Two things are specific to this role rather than copied from the
mautrix-whatsapp scenario:

- mautrix-discord is the only bridge here whose validate_config.yml requires
  a public address. It is composed from hostname + scheme + path prefix, and
  those same three feed the Traefik avatar-proxy labels, so the scenario
  picks a non-`/` path prefix and a non-default scheme and asserts the
  composed router rule and strip-prefix middleware - both in the label file
  and, read back off the running container, as labels Docker accepted.
  Traefik labels are left enabled here for that reason, unlike in the
  mautrix-whatsapp scenario which asserts their absence.

- matrix_bridge_mautrix_discord_bridge_double_puppet_server_map_default in
  the role's defaults references matrix_bridge_beeper_linkedin_homeserver_domain
  and matrix_bridge_beeper_linkedin_homeserver_address - variables belonging
  to a different role, evidently copy-pasted from
  matrix-bridge-beeper-linkedin, and unique to this role among the bridges.
  A playbook run has every role's defaults in scope so it resolves silently;
  a role scenario has only this role loaded and the template fails on the
  undefined name. The scenario neutralises it in its own group_vars rather
  than touching the role.

Falsified the crash-loop assertion: pointing the in-container sqlite path at
a directory that does not exist makes the bridge exit on startup, and the run
then fails at "Assert the service is active and has not been restarting" with
"activating after 5 automatic restart(s)". Reverted, and green again since -
including idempotence.
2026-08-27 18:02:53 +03:00
Slavi PantaleevandClaude Opus 5 8cd6ea1eef Add a Molecule scenario for heisenbridge, and the hostname family to the shared context
The third shape: a non-mautrix bridge. It confirms the scaffolding is not
mautrix-specific, and it is laid out differently enough to be worth having -
everything sits directly under the base path rather than in config/ and
data/ subdirectories, the owner and homeserver URL are passed on the command
line rather than through a config file, so the unit is where they can be
checked, and identd optionally binds host port 113.

matrix-base's matrix_server_fqn_* family moved into the shared context;
18 of the roles here read one of them.

Three roles now, three shapes - HTTP receiver, mautrix bridge, non-mautrix
bridge - and the scaffolding took no per-shape special-casing beyond each
role's own variables.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 18:02:53 +03:00
Slavi PantaleevandClaude Opus 5 f320bfc93b Add a Molecule scenario for mautrix-whatsapp, and a shared playbook context
The second scenario, chosen to be a bridge rather than another HTTP
component: bridges are roughly 40 of the 70 roles here, and validating the
shape on role two is cheaper than discovering it on role forty. It found
two things the first role could not.

Bridges read a whole family of variables from outside themselves -
matrix_bridges_relay_enabled, _encryption_enabled, _encryption_default,
_msc4190_enabled, _self_sign_enabled, plus matrix_admin - all defined in
matrix-base. Since every bridge reads them, they belong in shared context
rather than in each bridge's scenario: molecule-shared/playbook-context.yml
now carries them along with the identity and path variables the first
scenario had inline. Note it is loaded through vars_files, which outranks
inventory group_vars, so it is authoritative; a scenario that wants to prove
one of these reaches the rendered configuration should say so explicitly.

Appservices call /whoami while starting and refuse to run if the id returned
is not the bot user they were configured as - mautrix-whatsapp exits 17 with
"Unexpected user ID in whoami call". The shared stub now takes the id it
should claim to be. Expect every bridge and bot to need this.

What the scenario proves: the bridge starts and stays up, opens its
appservice port, its rendered config and appservice registration carry the
scenario's tokens and bot user, it created its sqlite database under the
role's data path as the role's uid, and it runs the version the role pins.
It does not bridge anything and never will.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 18:02:53 +03:00
Slavi PantaleevandClaude Opus 5 81a0ee3d53 Share the Molecule homeserver stub between scenarios
Components here contact a homeserver while starting up and exit if it is
unreachable, so nearly every scenario will need one. Standing up a real
Synapse per role would dominate the run and drag in Postgres, and these
scenarios are not testing Synapse.

The stub answers the handful of endpoints components touch during startup
with the blandest plausible response, and is deliberately permissive: an
unrecognised path returns {} rather than 404, because the goal is to get the
component past its startup checks. It is not an authentication check or a
room state machine, and a scenario should not assert *about* it - if one
starts needing it to behave like a real homeserver, that scenario has
outgrown what these tests are for.

matrix-alertmanager-receiver now includes it instead of carrying its own
inline copy. Verified green afterwards.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 18:02:53 +03:00
Slavi PantaleevandClaude Opus 5 efe204829f Symlink the shared requirements into each Molecule scenario
Molecule checks for a requirements file at the scenario's default path
before it installs anything, and warns "Missing roles requirements file"
when it is absent - so `requirements-file` pointing elsewhere was silently
ignored and the galaxy roles were never installed. CI failed on a missing
ansible-role-docker; the local run passed only because those roles were
already in ~/.ansible/roles from earlier work, which is exactly the kind of
difference a clean CI run exists to expose.

A symlink satisfies Molecule's check while keeping one copy of the pins.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 18:02:53 +03:00
Slavi PantaleevandClaude Opus 5 9370fdf4b4 Share the Molecule scaffolding and add just molecule
Three things that would not have scaled to 70 roles:

- The Python and Ansible dependency pins were about to be copied into every
  role. They now live once in molecule-shared/, which scenarios reference
  relatively, so they cannot drift apart.
- The helper container images used for probing were hardcoded inline. They
  are pinned once in molecule-shared/vars.yml, carry `# renovate:`
  annotations, and a custom manager in .github/renovate.json keeps them
  current - verified with a local Renovate dry run, which offers
  curl 8.11.1 -> 8.21.0 and python 3.13 -> 3.14-alpine. Seventy invisible
  hardcodes is the blindness class we have been removing elsewhere.
- Running a scenario meant knowing the venv and cd incantation. `just
  molecule <role>` does it, and with no argument lists the roles that have
  a scenario.

Molecule is deliberately not wired into prek: a run takes minutes, pulls
images and needs Docker, which is fine on request and not fine per commit.

docs/molecule-testing.md covers how to run and write these, including the
four things a role here needs that a standalone role does not. AGENTS.md
points at it rather than carrying the detail.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 18:02:53 +03:00
Slavi PantaleevandClaude Opus 5 ebe13bc360 Add a Molecule scenario for matrix-alertmanager-receiver
Not for merging as-is. One role's scenario plus the workflow that would
make per-role testing affordable here, so we can see how it behaves before
deciding whether to do the other 69.

Unlike the MASH repositories, one repository holds every role, so running
everything on every push is not an option. The workflow's first job works
out which roles a push touched and builds the matrix from that; a change to
docs, or to a role with no scenario yet, runs nothing.

Three things this role needed that a MASH role does not:

- The variables matrix-base would supply (matrix_base_data_path,
  matrix_domain, matrix_user_name, matrix_group_name and the uid/gid) have
  to be provided by the scenario, and the user and group have to exist
  before the role's file tasks run.
- The service contacts the homeserver while starting up - it fetches
  /_matrix/client/v3/joined_rooms to resolve its room mapping and exits 1
  if that fails - so prepare.yml stands up a stub homeserver. Most roles
  here are bridges and bots, so this is likely the rule rather than the
  exception.
- verify.yml runs as its own play, where role defaults are out of scope, so
  the paths it reads are pinned in molecule.yml. The version is deliberately
  NOT pinned: it is read from defaults/main.yml so the assertion compares
  the running image against what the role ships.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 18:02:53 +03:00
renovate[bot]andSlavi Pantaleev 03f6e4305f Update docker.io/metio/matrix-alertmanager-receiver Docker tag to v2026.8.26 2026-08-27 18:00:34 +03:00
renovate[bot]andSlavi Pantaleev 18735b5b5c Update matrixconduit/matrix-conduit Docker tag to v0.10.13 2026-08-26 07:30:12 +03:00
renovate[bot]andSlavi Pantaleev a0dc741487 Update forgejo.ellis.link/continuwuation/continuwuity Docker tag to v26.8.1 2026-08-25 02:42:13 +03:00
renovate[bot]andSlavi Pantaleev 1ba962c353 Update nginx Docker tag to v1.31.4 2026-08-21 02:02:56 +03:00
Slavi PantaleevandClaude Opus 5 2a71b7aeee Revert "Stop advertising MatrixRTC transports in the client well-known"
This reverts commit 421b592690.

The org.matrix.msc4143.rtc_foci property is indeed gone from MSC4143 and
Element Call v0.24.0 no longer reads it, but Element Web does not ship that
version of Element Call yet. v1.12.26 embeds Element Call v0.22.0, which
discovers transports through the well-known property.

That embedded copy cannot consult the homeserver's RTC transports API
instead: it runs as a widget, a widget holds no access token and the API
requires authentication, so its own discovery code skips the API branch
outright. Newer Element Call versions ask their host client over the widget
API (MSC4515) and Element Web already implements that side of it, but the
widget has to speak it too.

Dropping the property therefore left Element Web and Element Desktop users
with MISSING_MATRIX_RTC_TRANSPORT when starting a call.

The restored variables carry a comment about why the property stays, and the
changelog entry is rewritten to announce the revert.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 13:13:48 +03:00
Slavi PantaleevandClaude Opus 5 619aba983e Disable the broken LiveKit JWT Service container healthcheck
lk-jwt-service v0.6.0 ships a healthcheck which builds its URL as
http://localhost:$LIVEKIT_JWT_BIND/healthz, interpolating the bind
address into the port slot. We set LIVEKIT_JWT_BIND to ":8080", so the
check requests http://localhost::8080/healthz, which does not parse and
can never succeed. The container therefore sits permanently unhealthy,
Traefik skips unhealthy containers, and the service stops being routed,
so Element Call fails to obtain an SFU token.

No value satisfies both sides: the service passes LIVEKIT_JWT_BIND to
ListenAndServe, which needs a full bind address, while the healthcheck
needs a bare port. The check only works when the variable is unset and
its own "8080" fallback applies, which would mean ignoring a configured
port. Correcting the check from here is not possible either, as the
image is built FROM scratch and has no shell for a --health-cmd
override to use.

Turn the healthcheck off, behind a variable so it can be turned back on
once upstream fixes it. This restores the pre-v0.6.0 behavior, where the
image carried no healthcheck at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 16:03:11 +03:00
Slavi PantaleevandClaude Opus 5 ddd99ba244 Point LiveKit JWT Service at our homeserver directly, instead of having it discover it
lk-jwt-service v0.6.0 stopped honoring the delay_cs_api_url request parameter
and now locates a user's Client-Server API by fetching the
/.well-known/matrix/client file of that user's base domain itself.

For our own homeserver, this makes the service leave the server over the
public network only to come back to it, which is wasteful at best and does
not work at all where the base domain is not reachable from the host.
Since we know where our homeserver is, we tell the service directly via the
new LIVEKIT_CS_API_URL_OVERRIDES environment variable. Federated homeservers
keep being resolved through discovery.

The service now also joins the container network that the homeserver's
Client-Server API is reachable on, like our other add-on services do.
It used to only be connected to it by coincidence, via the reverse-proxy
network, which left it unable to reach the homeserver when the playbook is
not managing Traefik.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 14:01:53 +03:00
renovate[bot]andSlavi Pantaleev 1127365126 Update ghcr.io/element-hq/lk-jwt-service Docker tag to v0.6.0 2026-08-19 13:56:49 +03:00
Slavi PantaleevandClaude Opus 5 3d5eece64e matrix-tuwunel: add matrix_tuwunel_config_msc3664_related_event_match
Tuwunel v1.9.0 adds the default `.im.nheko.msc3664.reply` push rule to every
account, but only evaluates its condition when this option is on. Without it,
replies do not affect notification counts or reach pushers.

Kept off, as upstream has it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 13:42:22 +03:00
Slavi PantaleevandClaude Opus 5 c075013553 matrix-tuwunel: drop the removed LDAP name_attribute option
Tuwunel v1.9.0 removes `[global.ldap] name_attribute` and no longer checks
a secondary attribute for the localpart, so a directory entry must carry it
in `uid_attribute` to allow login.

A leftover key produces no boot warning, so the playbook reports it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 13:29:33 +03:00
renovate[bot]andSlavi Pantaleev 1576c8c677 Update ghcr.io/matrix-construct/tuwunel Docker tag to v1.9.0 2026-08-19 13:28:01 +03:00
Slavi PantaleevandClaude Opus 5 421b592690 Stop advertising MatrixRTC transports in the client well-known
The org.matrix.msc4143.rtc_foci property has been dropped from MSC4143 and
Element Call v0.24.0 no longer reads it, so the homeserver's own RTC
transports API is left as the single source of truth. Synapse, continuwuity
and tuwunel all serve it at the unstable path which clients request.

Keeping both around also made Element Web list the same LiveKit transport
twice, as it merges the two sources without deduplicating them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 13:17:38 +03:00
Slavi PantaleevandClaude Opus 5 96d94d56d5 Derive matrix_synapse_experimental_features_msc4143_enabled from the configured transports
The RTC transports API was enabled based on matrix_rtc_enabled, while the
transports it serves were populated based on matrix_livekit_jwt_service_enabled.
Enabling the LiveKit JWT service on its own (say, when pointing it at an
externally hosted LiveKit server) therefore configured a transport but left
the API which announces it switched off.

Gating the feature on matrix_synapse_matrix_rtc_transports instead keeps the
API and its payload in sync, and makes the empty-transports case that the
variable's own documentation warns about unreachable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 13:16:48 +03:00
renovate[bot]andSlavi Pantaleev 0023616d69 Update ghcr.io/element-hq/element-call Docker tag to v0.24.0 2026-08-19 08:07:01 +03:00
renovate[bot]andSlavi Pantaleev e07aac7c1a Update ghcr.io/element-hq/matrix-authentication-service Docker tag to v1.23.0 2026-08-19 08:06:01 +03:00
renovate[bot]andSlavi Pantaleev 9291370fbb Update ghcr.io/element-hq/synapse Docker tag to v1.159.0 2026-08-19 08:05:47 +03:00
renovate[bot]andSlavi Pantaleev 4f91fbadcf Update dependency matrix-org/synapse-s3-storage-provider to v1.7.0 2026-08-19 07:21:45 +03:00
renovate[bot]andSlavi Pantaleev 5c4000182c Update ghcr.io/element-hq/element-web Docker tag to v1.12.26 2026-08-19 07:20:53 +03:00
renovate[bot]andSlavi Pantaleev 543123c96c Update jeremiah-k/mmrelay Docker tag to v1.4.0 2026-08-18 08:22:24 +03:00
renovate[bot]andSlavi Pantaleev 585ae50756 Update ghcr.io/etkecc/fluffychat-web Docker tag to v2.9.1 2026-08-17 22:09:56 +03:00
Slavi PantaleevandClaude Fable 5 d839e45548 Ensure the homeserver accepts matrix-bot-meowlnir's appservice token before provisioning
The homeserver only reads appservice registrations on startup, and the
playbook only restarts it at the very end of a run. On the run which
first enables Meowlnir, bot provisioning therefore talked to a
homeserver still running without Meowlnir's registration, hitting
M_UNKNOWN_TOKEN and hanging indefinitely.

Provisioning now verifies the token upfront and restarts the homeserver
itself when needed, so a single run completes even when Meowlnir was
just enabled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 09:32:14 +03:00
Slavi PantaleevandClaude Fable 5 c57e8fde84 Add a meowlnir-whoami diagnostic script to matrix-bot-meowlnir
Asks the homeserver who Meowlnir's appservice token belongs to.
A 401 (M_UNKNOWN_TOKEN) response means the homeserver is running
without Meowlnir's appservice registration, which is the usual cause
of Meowlnir's "Failed to connect to homeserver" log messages.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 09:03:23 +03:00
Slavi PantaleevandClaude Fable 5 74e50df931 Add request timeouts to matrix-bot-meowlnir helper scripts
Without a timeout, a request against an API which accepts connections
but never answers (e.g. Meowlnir stuck retrying against a homeserver
that rejects its appservice token) hangs the playbook forever instead
of failing with a usable error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 08:57:56 +03:00
renovate[bot]andSlavi Pantaleev 41dffae7a0 Update dock.mau.dev/mautrix/telegram Docker tag to v0.2608.0 2026-08-16 21:08:28 +03:00
Slavi PantaleevandClaude Fable 5 94bccec1ef Decouple mautrix-meta-instagram from mautrix-meta-messenger and fix Instagram self-building
Since mautrix-meta v26.07, Instagram is a separate bridge upstream (its own binary, container image and configuration schema). As of v0.2608.0, the bridge no longer has a `mode` configuration option at all, so the premise of auto-generating the Instagram role from the Messenger one (one binary, one schema, a mode switch) is gone.

- Drop the role generator (`bin/rebuild-mautrix-meta-instagram.sh` and the `just rebuild-mautrix-meta-instagram` recipe). The two roles are now maintained independently.

- Drop `matrix_bridge_mautrix_meta_instagram_meta_mode` and all mode-derived lookups from the Instagram role. Computed values are unchanged.

- Sync both config templates with the v0.2608.0 example configs: the Instagram template loses `mode` and gains the Instagram-only options; the Messenger template replaces `mode` with the new `tor` option (still derived from `matrix_bridge_mautrix_meta_messenger_meta_mode: facebook-tor`) and loses the Instagram-only `disable_xma_*` options.

- Fix self-building for the Instagram role: build via `Dockerfile.ig` (producing the actual Instagram binary at `/usr/bin/mautrix-instagram`) instead of the Messenger `Dockerfile`. A new `matrix_bridge_mautrix_meta_instagram_container_binary_path` variable points the systemd service at the right binary for self-built and prebuilt images.

- Rename the systemd service templates to role-specific file names.

Related to https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/5510

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 19:14:03 +03:00
renovate[bot]andSlavi Pantaleev 216995dc91 Update dock.mau.dev/mautrix/whatsapp Docker tag to v0.2608.0 2026-08-16 18:44:07 +03:00
renovate[bot]andSlavi Pantaleev 9c8b185e30 Update dock.mau.dev/mautrix/twitter Docker tag to v0.2608.0 2026-08-16 18:44:01 +03:00
renovate[bot]andSlavi Pantaleev 40f894623a Update dock.mau.dev/mautrix/slack Docker tag to v0.2608.0 2026-08-16 18:43:55 +03:00
renovate[bot]andSlavi Pantaleev 89a2f1e2cc Update dock.mau.dev/mautrix/signal Docker tag to v0.2608.0 2026-08-16 18:43:48 +03:00
renovate[bot]andSlavi Pantaleev 93fe35ab54 Update dock.mau.dev/mautrix/meta Docker tag to v0.2608.0 2026-08-16 18:43:40 +03:00
renovate[bot]andSlavi Pantaleev 5eab533cfe Update dock.mau.dev/mautrix/linkedin Docker tag to v0.2608.0 2026-08-16 18:40:13 +03:00
renovate[bot]andSlavi Pantaleev 1a5ee46174 Update dock.mau.dev/mautrix/gmessages Docker tag to v0.2608.0 2026-08-16 18:39:54 +03:00
renovate[bot]andSlavi Pantaleev 1aa277a267 Update dock.mau.dev/maunium/meowlnir Docker tag to v0.2608.0 2026-08-16 18:35:55 +03:00
renovate[bot]andSlavi Pantaleev 2654543d29 Update dock.mau.dev/mautrix/discord Docker tag to v0.7.7 2026-08-16 18:35:47 +03:00
Slavi PantaleevandClaude Fable 5 4d98ca54a6 Add matrix_rtc.transports support for Synapse (MSC4143)
Enabling the MSC4143 experimental feature without configuring any transports makes Synapse serve an empty response on the RTC transports API. Clients treat that response as authoritative and do not fall back to the org.matrix.msc4143.rtc_foci property in the client well-known, breaking Element Call with a MISSING_MATRIX_RTC_TRANSPORT error.

This makes the playbook wire the LiveKit JWT service URL into the new matrix_rtc.transports Synapse setting, matching what continuwuity, tuwunel and the client well-known already advertise.

Fixes https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/5522

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 08:44:09 +03:00
Slavi PantaleevandClaude Fable 5 df66f1f0b0 Restructure matrix_continuwuity_config_rtc_foci variables (_auto -> _default + _auto + _custom)
The role-constructed foci list now lives in the _default variable, freeing _auto for playbook-level injection, consistent with how other default/auto/custom variable triads work.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 17:26:41 +03:00
renovate[bot]andSlavi Pantaleev a17042fa1c Update dependency maunium/synapse-http-antispam to v0.5.1 2026-08-13 18:20:18 +03:00
Slavi PantaleevandClaude Opus 5 aef0fad8b5 Enable the appservice encryption MSCs on Synapse for Hookshot too
Hookshot's end-to-bridge encryption needs MSC2409 and MSC3202 enabled
on the homeserver, but the playbook only turned them on for Meowlnir.
Hookshot's encryption defaults to the playbook-wide
`matrix_bridges_encryption_enabled` toggle, so turning that on gave
Hookshot encryption against a Synapse which was not set up for it, and
Hookshot then struggled in encrypted rooms.

The playbook already wires up Hookshot's other encryption prerequisite
(Valkey) and fails the run when the Redis settings are missing, so
being only half-automatic here was the odd one out.

Synapse sends the extra data only to appservices which ask for it in
their registration file, so turning these on affects no other
component.

The documentation told Hookshot users to set the two Synapse variables
by hand, and argued they should be enabled deliberately. That
contradicted what we already do for Meowlnir, so it is gone; the note
now matches the Meowlnir one and points out that other homeserver
implementations still need arranging by hand.

Closes https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/5506

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 08:01:51 +03:00
Slavi PantaleevandClaude Opus 5 fdf3c13e66 Fix unterminated placeholder in a matrix-synapse deprecation message
The `matrix_synapse_experimental_features_msc3202_device_masquerading_enabled`
entry was missing its closing angle bracket, so anyone still setting
that variable was told to rename it to `<removed - this feature is
enabled by default now`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 07:37:50 +03:00
jasonlaguidiceandSlavi Pantaleev 1fe8e231b3 Remove old deprecation preventing rustpush bridge deployment 2026-08-13 07:31:48 +03:00