Severity: minor · packages/engine/src/engine/presence.ts:10-32, middleware/presenceRefresh.ts, fed only from middleware/rateLimit.ts:83; adapters/node/presence.ts
getPresence reads PresenceTracker.getOnline, and the in-process tracker's map is fed only by presenceRefresh, which fires on authenticated HTTP requests. A node-hosted agent that only receives deliveries over the node socket and makes no REST calls is never heartbeated, so it reports offline on the self-host engine.
The cloud adapter works around this by overriding getOnline to derive presence from agent_node_bindings + node liveness (documented in relaycast-cloud's CLAUDE.md) — but the engine's own Node adapter has no such derivation, so the two adapters give different presence answers for the same topology.
Failure scenario: a passive broker-hosted worker (listening, not calling REST) shows offline on self-host /v1/presence despite an active binding to a live node.
Fix: move the binding-liveness derivation into the engine (shared by all adapters) rather than leaving it cloud-only.
Found during a multi-agent reliability review of the relay tool/protocol.
Severity: minor ·
packages/engine/src/engine/presence.ts:10-32,middleware/presenceRefresh.ts, fed only frommiddleware/rateLimit.ts:83;adapters/node/presence.tsgetPresencereadsPresenceTracker.getOnline, and the in-process tracker's map is fed only bypresenceRefresh, which fires on authenticated HTTP requests. A node-hosted agent that only receives deliveries over the node socket and makes no REST calls is never heartbeated, so it reportsofflineon the self-host engine.The cloud adapter works around this by overriding
getOnlineto derive presence fromagent_node_bindings+ node liveness (documented in relaycast-cloud's CLAUDE.md) — but the engine's own Node adapter has no such derivation, so the two adapters give different presence answers for the same topology.Failure scenario: a passive broker-hosted worker (listening, not calling REST) shows
offlineon self-host/v1/presencedespite an active binding to a live node.Fix: move the binding-liveness derivation into the engine (shared by all adapters) rather than leaving it cloud-only.
Found during a multi-agent reliability review of the relay tool/protocol.