3.8 KiB
3.8 KiB
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 -dis a safe, fast recovery path. - Future portability: the same Compose file can move to a different VPS with only
.envchanges.
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 Let’s 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/Caddyfileand 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.pyand 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 mapinfra/matrix/scripts/validate-scaffold.py— automated integrity checks.gitea/workflows/validate-matrix-scaffold.yml— CI enforcementinfra/matrix/HERMES_INTEGRATION_VERIFICATION.md— adapter-to-scaffold mapping