feat(comms): P1 presence — minimal Synapse + fleet presence room + mosaic.presence heartbeat + liveness #888
Reference in New Issue
Block a user
Delete Branch "feat/comms-p1-presence"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What P1 delivers
The first shippable slice of the Matrix/MACP comms system (RFC-001 §10 P1):
deterministic Matrix presence/liveness on a single-instance dev Synapse.
infra/matrix/— DEV Synapse, rendered from parameterized templates(RFC-002 Mode B single-domain, federation OFF, self-signed TLS,
enable_registration: false, appservice registration wired). Zero hardcodedtopology — every fact is an env var with a dev default. Runtime state
(
.data/, incl. throwaway secrets/keys) is gitignored.dev-up.sh/dev-down.sh.packages/comms/— minimal MACP presence SDK:MinimalMatrixClient(set native presence, send
mosaic.presence, read heartbeats),HeartbeatEmitter/startHeartbeatLoop(monotonicseq+interval_msperRFC-001 §4.5),
PresenceAgent, andFleetLivenessReader. The liveness core(
classifyLiveness/computeFleetLiveness) is heartbeat-age deterministic— online/away/offline, not dependent on native Matrix presence timeouts.
Written RED-FIRST; 19 vitest tests.
tools/matrix-presence-harness/provision.ts) —registers ≥3 agent MXIDs, creates the fleet presence room, joins the
agents. Reuses the existing tested
@mosaicstack/appserviceintent lib ratherthan reinventing. Explicitly NOT the P2 appservice (no auto-enroll / taxonomy /
token minting / introductions).
tools/matrix-presence-harness/) — spawns eachagent as its own OS process and proves A2/A3/A4 end-to-end against a real
Synapse,
SIGKILL-ing one agent for a true hard-kill.A1–A5 evidence (local dev-compose)
A1 — dev Synapse up over TLS, registration OFF
AS-token registration bypasses the flag by design (that is how agents are provisioned):
POST /v3/register {type: m.login.application_service}->@agent-smoke:matrix.localhost.A2 — ≥3 agents live in the fleet presence room
A3 — hard-killed agent flips to offline within
dark_threshold, DETERMINISTICALLYdark_threshold = 6000ms, heartbeat interval 1000ms.SIGKILL charlie, then polling theheartbeat-derived liveness (NOT native presence):
charlie's
seqfreezes at 2 (stopped beating at the kill) while survivors climb to seq 8 —the flip is driven purely by heartbeat age crossing the threshold, not by any native-presence
timeout or graceful signal.
A4 — human sees fleet liveness at a glance
CLI liveness board via
FleetLivenessReader.formatBoard(). Element (the alternative human view)is wired in
docker-compose.dev.ymlunder--profile elementpointed at the dev server.A5 — zero impact to existing tmux + mos-comms
Purely additive: three new dirs (
infra/matrix/,packages/comms/,tools/matrix-presence-harness/) + a one-linepnpm-workspace.yamladdition + oneeslint.config.mjsline (register the new vitest config, same as sibling packages) +regenerated lockfile. No tmux files touched;
mos-commsappears only indocs/which isuntouched;
packages/appservicetracked files unchanged.Gates
pnpm typecheck— 45/45 passpnpm lint— 25/25 passpnpm format:check— cleanpnpm --filter @mosaicstack/comms test— 19/19 pass (liveness core RED-FIRST)Scope / holds
DEV-compose validated only; production deploy is a separate coordinated step
(deploy-holds respected). No live infra was touched — only a local, isolated
compose project (
matrix-p1-dev, dedicated network + high host ports).[VERIFY] notes observed in practice
listener with a self-signed cert, sqlite store,
enable_registration:false,and the appservice registration (
url: null,@agent-*namespace) all loadedcleanly on
matrixdotorg/synapse:latest.we do NOT rely on native presence for liveness. The authoritative signal is the
mosaic.presenceheartbeat age, which gives a crisp, deterministic offline flipexactly at
dark_threshold— independent of Synapse's coarser native-presencedecay. Native presence EDUs are still emitted for Element's dot.
Part of the comms-evolution program (RFC-001 P1)
Part of #887 (comms-evolution epic) — RFC-001 P1 (presence).
RECORD OF REVIEW — PR #888 @2e7c124e — VERDICT: APPROVE
Reviewer: independent review (fresh clone, HTTPS + fleet token; local checkout stale-repo not used).
Head reviewed:
2e7c124e4dfa7314f6c06e751a655b4070279c5e(confirmed exact match, no drift). Base:main @ 529c1778303c8b82b5d593ceba0690c798729e0c.Diff:
git diff origin/main...2e7c124e— 33 files changed, 2140 insertions(+), 0 deletions(-).1. Presence-liveness correctness — PASS (LOAD-BEARING)
packages/comms/src/liveness.ts:classifyLiveness(ageMs, policy)is a pure function of heartbeat age vs policy — no native Matrix presence involved:Matches RFC-001 §4.5 exactly (online/away/offline definitions, heartbeat-not-native-presence rationale).
Edge cases verified in
src/__tests__/liveness.test.ts:age===onlineWindow→ online (inclusive);age===darkThreshold→ offline (inclusive). No gap/overlap.Number.POSITIVE_INFINITY→ offline (fails safe).NaN→ offline (fails safe, doesn't silently report online).seqmonotonicity:readHeartbeats()inmatrix-client.tsreduces the room timeline by keeping, per slug, only the highestseqobserved (verified inmatrix-client.test.ts: an out-of-order/duplicate timeline correctly resolves to the highest-seq beat and itsorigin_server_ts).Non-tautological / RED-FIRST spot-check performed: I mutated
classifyLivenessto a constantreturn 'online'stub and re-ranpnpm --filter @mosaicstack/comms testagainst the mutated tree (impl reverted immediately after, verified clean diff). Result: 7/19 tests failed with precise, semantically-correct assertion diffs (expected 'online' to be 'offline', fleet board mismatches, A3 flip assertion failure) — proving the suite genuinely exercises the liveness math rather than mirroring the implementation. Re-ran with the real implementation: 19/19 pass, matching the PR's claim.2. A3 proof integrity — PASS
tools/matrix-presence-harness/validate.tsspawns each agent via:This runs
nodedirectly with tsx as an--importloader hook — the spawned PID is the agent process (notsxCLI wrapper/grandchild in between, unlikenpx tsx agent-proc.tswhich would interpose a wrapper).hardKill()sendsSIGKILLstraight tochild.pid, which the code comments correctly explain ("pid is the in-process agent — a true kill"). This holds up: the builder's claimed fix is real, not cosmetic.The offline-flip assertion is heartbeat-age-based, not a native-presence timeout:
agent-proc.tsnever callssetPresence('offline')on kill (SIGKILL skips the SIGTERM handler entirely, so no graceful native-presence signal is even possible) — the only wayFleetLivenessReadercan observe "offline" is via heartbeat-age math. A complementary unit-level A3 proof exists inpresence-flow.test.tsusing fake timers + an in-memory fake room (no network), independently reproducing the online→away→offline flip and confirming survivors stay online — this is a legitimate second, deterministic axis of evidence for the same claim.3. infra/matrix dev config correctness + safety — PASS
homeserver.dev.yaml.tplsetsserver_name: "${MATRIX_SERVER_NAME}"and the same value is the listener's identity (no delegation config) — matches Mode B ("server_name == host, no delegation").enable_registration: false+enable_registration_without_verification: falsepresent; appservice registration wired viaapp_service_config_filespointing at the rendered${MOSAIC_AS_ID}.yaml, which declares the exclusive@agent-.*:${MATRIX_SERVER_NAME}user namespace.dev-up.sh(openssl req -x509 ... -days 90), not committed..tplfiles is an${ENV_VAR}with a dev default resolved indev-up.sh(MATRIX_SERVER_NAME:-matrix.localhost, etc.).infra/matrix/.gitignoreexcludes.data/(rendered config, sqlite db, signing key, self-signed certs, throwaway secrets — "Never committed").dev-up.shgenerates all secrets (MOSAIC_AS_TOKEN,MOSAIC_HS_TOKEN,SYNAPSE_REG_SHARED_SECRET,SYNAPSE_MACAROON_SECRET,SYNAPSE_FORM_SECRET) at bring-up viaopenssl rand -hex 16into.data/dev-secrets.env, which is gitignored. I grepped the full diff for hardcoded-looking secret/token/key literals (excluding${...}template vars and thedev*_prefixed placeholder names) — zero hits.docker-compose.dev.ymland both.tpl/script headers are marked "DEV-ONLY / LOCAL SANDBOX", isolated project name (matrix-p1-dev) + dedicated network + high host ports (18008/18448/18080), no systemd unit, no Portainer/swarm artifact anywhere in the diff (grepped, zero hits).4. Additive-only / A5 — PASS
git diff --name-onlyconfirms: notmux*paths, nomos-commspaths, and nopackages/appservice/*tracked files touched (all greps returned zero hits). The only pre-existing files touched areeslint.config.mjs(+1 line registeringpackages/comms/vitest.config.ts),pnpm-workspace.yaml(+1 line registeringtools/matrix-presence-harness), andpnpm-lock.yaml(regenerated, additions only — newpackages/commsandtools/matrix-presence-harnessimporters). Diff is 0 deletions across the whole PR.5. Scope = P1, not P2 — PASS
tools/matrix-presence-harness/provision.tsis genuinely minimal: registers N agent MXIDs, creates one fleet room, joins agents, done — no auto-enroll, no taxonomy, no token-minting logic of its own (reuses the existing tested@mosaicstack/appserviceAppserviceIntent).packages/comms/src/types.tsdocstring explicitly scopes out enrollment/taxonomy/token-minting/signed-authorship as P2+, and theMacpEnvelope'ssignaturefield is intentionally absent. No scope-creep found.6. Gates at exact head — PASS
Ran in a fresh clone with a scratch pnpm store (
npm_config_store_dirpointed off-root):pnpm typecheck→ 45/45 successfulpnpm lint→ 25/25 successfulpnpm format:check→ clean ("All matched files use Prettier code style!")pnpm --filter @mosaicstack/comms test→ 19/19 passAll four numbers match the PR body's claims exactly. No
--no-verify/hook bypass evidence found: single squashed commit, commit message contains no bypass language,.husky/pre-commit(npx lint-staged) is untouched by this diff.7. State/CI/linkage — PASS
open,mergeable: true, basemain.GET /repos/mosaicstack/stack/commits/2e7c124e.../status— startedpending/running, reached terminalsuccessat the exact reviewed head (ci/woodpecker/pr/ci, "Pipeline was successful").8. Commit author — PASS
git show -s --format='%an <%ae>' 2e7c124e→mosaic-coder <coder@fleet.mosaicstack.dev>— distinct from the reviewing identity.Verdict: APPROVE
All 8 criteria PASS. The liveness core is genuinely heartbeat-age-deterministic (verified both by reading and by a mutation/revert spot-check), the A3 hard-kill is a true SIGKILL to the real agent PID (no tsx-wrapper grandchild), no secrets or production topology are committed, the diff is purely additive with no P2 scope-creep, all four gates pass at the exact reviewed head with matching numbers to the PR body, and CI is terminal-green at
2e7c124e.GO — Gate-16 id-11 stamp, pinned to exact head
2e7c124e4d.Basis: verbatim RoR (comment 18675) — independent reviewer APPROVE at this exact head (MS-LEAD relay, strict non-executor); CI success. Named executor: Mos (id-11), squash with pinned head. Part of #887.
Merge lands code only — NO runtime change; live-deploy is a separately-held ruling (not actionable until the Synapse/appservice phase stands up a target).