Files
timmy-config/docs/matrix-fleet-comms/ADR-001-matrix-scaffold.md

3.8 KiB
Raw Blame History

ADR-001: Matrix/Conduit Deployment Scaffold

Field Value
Status Accepted
Date 2026-04-05
Decider Ezra (Architekt)
Stakeholders Allegro, Timmy, Alexander
Parent Issues #166, #183

1. Context

Son of Timmy Commandment 6 requires encrypted human-to-fleet communication that is sovereign and independent of Telegram. Before any code can run, we needed a reproducible, infrastructure-agnostic deployment scaffold that any wizard house can verify, deploy, and restore.

2. Decision: Conduit over Synapse

Chosen: Conduit as the Matrix homeserver.

Alternatives considered:

  • Synapse: Mature, but heavier (Python, more RAM, more complex config).
  • Dendrite: Go-based, lighter than Synapse, but less feature-complete for E2EE.

Rationale:

  • Conduit is written in Rust, has a small footprint, and runs comfortably on the Hermes VPS (~7 GB RAM).
  • Single static binary + SQLite (or Postgres) keeps the Docker image small and backup logic simple.
  • E2EE support is production-grade enough for a closed fleet.

3. Decision: Docker Compose over Bare Metal

Chosen: Docker Compose stack (docker-compose.yml) with explicit volume mounts.

Rationale:

  • Reproducibility: any host with Docker can stand the stack up in one command.
  • Isolation: Conduit, Element Web, and Postgres live in separate containers with explicit network boundaries.
  • Rollback: docker compose down && docker compose up -d is a safe, fast recovery path.
  • Future portability: the same Compose file can move to a different VPS with only .env changes.

4. Decision: Caddy as Reverse Proxy (with Nginx coexistence)

Chosen: Caddy handles TLS termination and .well-known/matrix delegation inside the Compose network.

Rationale:

  • Caddy automates Lets Encrypt TLS via on-demand TLS.
  • On hosts where Nginx already binds 80/443 (e.g., Hermes VPS), Nginx can reverse-proxy to Caddy or Conduit directly.
  • The scaffold includes both a caddy/Caddyfile and Nginx-compatible notes so the operator is not locked into one proxy.

5. Decision: One Matrix Account Per Wizard House

Chosen: Each wizard house (Ezra, Allegro, Bezalel, etc.) gets its own Matrix user ID (@ezra:domain, @allegro:domain).

Rationale:

  • Preserves sovereignty: each house has its own credentials, device keys, and E2EE trust chain.
  • Matches the existing wizard-house mental model (independent agents, shared rooms).
  • Simplifies debugging: message provenance is unambiguous.

6. Decision: matrix-nio for Hermes Gateway Integration

Chosen: matrix-nio with the e2e extra.

Rationale:

  • Already integrated into the Hermes gateway (gateway/platforms/matrix.py).
  • Asyncio-native, matching the Hermes gateway architecture.
  • Supports E2EE, media uploads, threads, and replies.

7. Consequences

Positive

  • The scaffold is self-enforcing: validate-scaffold.py and Gitea Actions CI guard integrity.
  • Local integration can be verified without public DNS via docker-compose.test.yml.
  • The path from "host decision" to "fleet online" is fully scripted.

Negative / Accepted Trade-offs

  • Conduit is younger than Synapse; edge-case federation bugs are possible. Mitigation: the fleet will run on a single homeserver initially.
  • SQLite is the default Conduit backend. For >100 users, Postgres is recommended. The Compose file includes an optional Postgres service.

8. References

  • infra/matrix/CANONICAL_INDEX.md — canonical artifact map
  • infra/matrix/scripts/validate-scaffold.py — automated integrity checks
  • .gitea/workflows/validate-matrix-scaffold.yml — CI enforcement
  • infra/matrix/HERMES_INTEGRATION_VERIFICATION.md — adapter-to-scaffold mapping