# @mosaicstack/comms MACP presence SDK — the **P1 (presence)** slice of RFC-001 (§4.5 liveness, §4.2 event envelope). Minimal by design: set Matrix presence, run the `mosaic.presence` heartbeat, and compute **deterministic** fleet liveness. Out of P1 scope (later phases): enrollment/auto-detect, room taxonomy, per-agent token minting, signed-authorship, federation. ## API - `classifyLiveness(ageMs, policy)` / `computeFleetLiveness(observations, now, policy)` — pure, deterministic online/away/offline from heartbeat age. The authoritative liveness source (RFC-001 §4.5): native Matrix presence is _not_ relied upon. - `HeartbeatEmitter` / `startHeartbeatLoop(...)` — build and drive the `mosaic.presence` heartbeat (monotonic `seq`, `interval_ms`). - `MinimalMatrixClient` — tiny C-S client: `setPresence`, `sendHeartbeat`, `readHeartbeats`, `joinRoom`. Supports Application-Service masquerade (`actAsUserId`) for the P1 provisioner, or a per-agent `accessToken`. - `PresenceAgent` — high-level: join the fleet room, go present, heartbeat. `pauseHeartbeat()` models a crash (no graceful signal). - `FleetLivenessReader` — reads the fleet room and computes the liveness board (`read()` / `formatBoard()`), the surface a human or watchdog reads. ## Liveness policy (RFC-001 §4.5) ``` online : age <= heartbeatIntervalMs * missTolerance away : age < darkThresholdMs offline: otherwise (or never-seen / non-finite age -> fail safe to offline) ``` Defaults: interval 30s, miss-tolerance 2, dark-threshold 10min (`DEFAULT_LIVENESS_POLICY`). All runtime-tunable per RFC-002 §5.3. ## Tests `pnpm --filter @mosaicstack/comms test` — the liveness core is written RED-FIRST; an end-to-end proof against a real Synapse lives in `tools/matrix-presence-harness`.