Files
stack/infra/matrix/README.md
mosaic-coder 2e7c124e4d
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
feat(comms): P1 presence — minimal Synapse + fleet presence room + mosaic.presence heartbeat + liveness
Implements RFC-001 P1 (the first shippable slice): deterministic Matrix
presence/liveness on a single-instance dev Synapse.

- infra/matrix/: DEV Synapse (RFC-002 Mode B, federation OFF, self-signed TLS,
  enable_registration:false, appservice registration wired). Rendered from
  parameterized templates — zero hardcoded topology. .data is gitignored.
- packages/comms/: minimal MACP presence SDK — set presence, run the
  mosaic.presence heartbeat (seq + interval per RFC-001 §4.5), and a
  deterministic liveness reader (online/away/offline from heartbeat age, NOT
  native-presence-timeout). Liveness core written RED-FIRST. 19 vitest tests.
- tools/matrix-presence-harness/: minimal provisioner (registers >=3 agent
  MXIDs, creates the fleet presence room, joins them — reuses the existing
  @mosaicstack/appservice intent lib) + an E2E validation harness proving
  A2/A3/A4 against a real Synapse.
- eslint.config.mjs: register packages/comms/vitest.config.ts with the
  type-aware project service (same as other packages' vitest configs).

DEV-compose validated only; production deploy is a separate coordinated step
(deploy-holds respected).

Part of the comms-evolution program (RFC-001 P1)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0158NZqN2n2ymKFeJAZ4GUCb
2026-07-24 20:18:18 -05:00

2.8 KiB

infra/matrix — DEV Synapse for RFC-001 P1 (presence)

DEV-ONLY. LOCAL SANDBOX. This stack is for local presence validation. It must never be pointed at, or run alongside, a live/production homeserver. It is single-instance, federation-OFF, self-signed TLS — the smallest slice RFC-002 §9 says P1 needs (Mode B single-domain, no federation, no IP-only, no secret-rotation story).

What this is

A single Synapse homeserver rendered from committed templates (no hardcoded topology — RFC-002 G2). Every topology fact is an environment variable with a dev default:

Var Default Meaning
MATRIX_SERVER_NAME matrix.localhost Synapse server_name (the :suffix of every MXID)
MOSAIC_AS_ID mosaic-as appservice id / registration filename
MATRIX_HTTP_PORT 18008 host port → Synapse 8008 (plain HTTP)
MATRIX_TLS_PORT 18448 host port → Synapse 8448 (self-signed TLS)

Secrets (as_token, hs_token, Synapse macaroon/form/registration secrets) are throwaway values generated at bring-up into .data/dev-secrets.env (gitignored). In production these are crown-jewel secrets held by the SecretBackend (RFC-001 §8 / RFC-002 §4) — never committed.

Files

  • docker-compose.dev.yml — Synapse (+ optional Element under --profile element).
  • synapse/homeserver.dev.yaml.tpl — rendered Synapse config (Mode B, enable_registration: false, appservice wired, native TLS).
  • synapse/log.config — Synapse logging.
  • appservice/mosaic-as.dev.yaml.tpl — minimal AS registration (declares the @agent-* user namespace).
  • dev-up.sh / dev-down.sh — bring up / tear down (--purge wipes .data).
  • .data/gitignored runtime state (rendered config, sqlite db, signing key, self-signed certs, dev secrets).

Usage

./dev-up.sh                       # render config, gen signing key + TLS cert, boot Synapse
# ... run the validation harness (tools/matrix-presence-harness/run.sh) ...
./dev-down.sh            # stop, keep .data
./dev-down.sh --purge   # stop and wipe .data for a pristine next boot

# optional human view (A4) — Element pointed at the dev server:
docker compose -f docker-compose.dev.yml --profile element up -d element
#   -> http://127.0.0.1:18080

Acceptance evidence (A1)

  • TLS (self-signed) reachable: curl -sk https://127.0.0.1:18448/_matrix/client/versions200.
  • Open registration OFF: POST /_matrix/client/v3/registerM_FORBIDDEN "Registration has been disabled".
  • AS-token registration bypasses the flag by design (that is how agents are provisioned).