All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
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
109 lines
4.8 KiB
Bash
Executable File
109 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ============================================================================
|
|
# dev-up.sh — bring up the DEV Synapse for RFC-001 P1 (presence)
|
|
# ============================================================================
|
|
#
|
|
# *** DEV-ONLY. LOCAL SANDBOX. This script must never be pointed at live
|
|
# infra. It writes only into infra/matrix/.data (gitignored) and drives
|
|
# a dedicated compose project (matrix-p1-dev). ***
|
|
#
|
|
# It renders the Synapse config + appservice registration from the committed
|
|
# templates (envsubst), generates a DEV signing key + self-signed TLS cert,
|
|
# and starts Synapse. All topology facts come from the environment with dev
|
|
# defaults (RFC-002 G2: nothing hardcoded).
|
|
# ----------------------------------------------------------------------------
|
|
set -euo pipefail
|
|
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
DATA="${HERE}/.data"
|
|
COMPOSE=(docker compose -f "${HERE}/docker-compose.dev.yml")
|
|
|
|
# ---- Topology inputs (dev defaults; override via env) ----------------------
|
|
export MATRIX_SERVER_NAME="${MATRIX_SERVER_NAME:-matrix.localhost}"
|
|
export MOSAIC_AS_ID="${MOSAIC_AS_ID:-mosaic-as}"
|
|
export MATRIX_HTTP_PORT="${MATRIX_HTTP_PORT:-18008}"
|
|
export MATRIX_TLS_PORT="${MATRIX_TLS_PORT:-18448}"
|
|
|
|
# ---- DEV secrets (throwaway; regenerated if absent) ------------------------
|
|
SECRETS_ENV="${DATA}/dev-secrets.env"
|
|
mkdir -p "${DATA}"
|
|
if [[ ! -f "${SECRETS_ENV}" ]]; then
|
|
{
|
|
echo "MOSAIC_AS_TOKEN=devas_$(openssl rand -hex 16)"
|
|
echo "MOSAIC_HS_TOKEN=devhs_$(openssl rand -hex 16)"
|
|
echo "SYNAPSE_REG_SHARED_SECRET=devreg_$(openssl rand -hex 16)"
|
|
echo "SYNAPSE_MACAROON_SECRET=devmac_$(openssl rand -hex 16)"
|
|
echo "SYNAPSE_FORM_SECRET=devform_$(openssl rand -hex 16)"
|
|
} > "${SECRETS_ENV}"
|
|
echo "[dev-up] generated throwaway DEV secrets -> ${SECRETS_ENV}"
|
|
fi
|
|
# shellcheck disable=SC1090
|
|
set -a; source "${SECRETS_ENV}"; set +a
|
|
|
|
# DEV: let the synapse container user (uid 991) write the sqlite db / media.
|
|
chmod 0777 "${DATA}" || true
|
|
|
|
# ---- Render config from templates ------------------------------------------
|
|
envsubst < "${HERE}/synapse/homeserver.dev.yaml.tpl" > "${DATA}/homeserver.yaml"
|
|
envsubst < "${HERE}/appservice/mosaic-as.dev.yaml.tpl" > "${DATA}/${MOSAIC_AS_ID}.yaml"
|
|
cp "${HERE}/synapse/log.config" "${DATA}/log.config"
|
|
echo "[dev-up] rendered homeserver.yaml + ${MOSAIC_AS_ID}.yaml (server_name=${MATRIX_SERVER_NAME})"
|
|
|
|
# ---- DEV signing key -------------------------------------------------------
|
|
# Generate as the synapse container user (uid 991) so the running container
|
|
# can read it; owned-by-991 mode-600 is fine (the container IS 991).
|
|
SIGNING_KEY="${DATA}/${MATRIX_SERVER_NAME}.signing.key"
|
|
if [[ ! -f "${SIGNING_KEY}" ]]; then
|
|
docker run --rm --user 991:991 -v "${DATA}:/data" --entrypoint generate_signing_key \
|
|
matrixdotorg/synapse:latest -o "/data/${MATRIX_SERVER_NAME}.signing.key"
|
|
echo "[dev-up] generated DEV signing key"
|
|
fi
|
|
|
|
# ---- DEV self-signed TLS cert (A1) -----------------------------------------
|
|
if [[ ! -f "${DATA}/dev-cert.pem" ]]; then
|
|
openssl req -x509 -newkey rsa:2048 -nodes \
|
|
-keyout "${DATA}/dev-key.pem" -out "${DATA}/dev-cert.pem" \
|
|
-days 90 -subj "/CN=${MATRIX_SERVER_NAME}" \
|
|
-addext "subjectAltName=DNS:${MATRIX_SERVER_NAME},DNS:localhost,IP:127.0.0.1" >/dev/null 2>&1
|
|
echo "[dev-up] generated DEV self-signed TLS cert for ${MATRIX_SERVER_NAME}"
|
|
fi
|
|
# Files hermes owns must be world-readable so the synapse (uid 991) container
|
|
# can read them (DEV-only; the signing key stays owned by 991 from above).
|
|
chmod 0644 "${DATA}/dev-cert.pem" "${DATA}/dev-key.pem" \
|
|
"${DATA}/homeserver.yaml" "${DATA}/${MOSAIC_AS_ID}.yaml" "${DATA}/log.config" || true
|
|
|
|
# ---- Element config (optional human view, A4) ------------------------------
|
|
cat > "${DATA}/element-config.json" <<JSON
|
|
{
|
|
"default_server_config": {
|
|
"m.homeserver": {
|
|
"base_url": "https://localhost:${MATRIX_TLS_PORT}",
|
|
"server_name": "${MATRIX_SERVER_NAME}"
|
|
}
|
|
},
|
|
"disable_guests": true,
|
|
"brand": "Mosaic P1 (DEV)"
|
|
}
|
|
JSON
|
|
|
|
# ---- Boot ------------------------------------------------------------------
|
|
"${COMPOSE[@]}" up -d synapse
|
|
|
|
echo -n "[dev-up] waiting for Synapse health"
|
|
for _ in $(seq 1 60); do
|
|
status="$("${COMPOSE[@]}" ps --format '{{.Health}}' synapse 2>/dev/null || true)"
|
|
if [[ "${status}" == "healthy" ]]; then echo " ... healthy"; break; fi
|
|
echo -n "."; sleep 2
|
|
done
|
|
|
|
if ! curl -fsS "http://127.0.0.1:${MATRIX_HTTP_PORT}/health" >/dev/null 2>&1; then
|
|
echo "[dev-up] ERROR: Synapse did not become healthy" >&2
|
|
"${COMPOSE[@]}" logs --tail 60 synapse >&2 || true
|
|
exit 1
|
|
fi
|
|
|
|
echo "[dev-up] Synapse UP:"
|
|
echo " plain HTTP : http://127.0.0.1:${MATRIX_HTTP_PORT}"
|
|
echo " TLS : https://127.0.0.1:${MATRIX_TLS_PORT} (self-signed, DEV)"
|
|
echo " server_name: ${MATRIX_SERVER_NAME} registration: OFF"
|