From a24e4f78eca26690cc7de1a07fc01ba1528cce85 Mon Sep 17 00:00:00 2001 From: Mikhail Agapov Date: Tue, 28 Jul 2026 16:43:56 +0300 Subject: [PATCH 1/2] Add pulse_clusters.proto Signed-off-by: Mikhail Agapov --- proto/decentraland/pulse/pulse_clusters.proto | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 proto/decentraland/pulse/pulse_clusters.proto diff --git a/proto/decentraland/pulse/pulse_clusters.proto b/proto/decentraland/pulse/pulse_clusters.proto new file mode 100644 index 00000000..3c32b5e0 --- /dev/null +++ b/proto/decentraland/pulse/pulse_clusters.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +package decentraland.pulse; + +// Published by Pulse to NATS on `peer.{address}.cluster_change` whenever a peer's post-debounce +// cluster assignment changes. Pulse is the sole author of cluster membership. +// +// A "cluster" is Pulse's own grouping of co-located peers, derived by union-find over occupied +// area-of-interest grid cells. It is deliberately a different concept from archipelago's "island": +// clusters have no size cap, are realm-partitioned, and carry no transport connection details. +// Comms Gatekeeper subscribes here, mints the LiveKit connection string (the ban check is +// authority-local to gatekeeper), and re-emits the legacy +// decentraland.kernel.comms.v3.IslandChangedMessage on `engine.peer.{address}.island_changed`, +// so the WebSocket Connector and clients stay untouched. +message PeerClusterChange { + // Cluster the peer now belongs to. Stable across passes for an unchanged crowd. + string cluster_id = 1; + + // The peer's realm. Clusters never span realms, so this qualifies cluster_id and keeps the + // event self-contained — consumers never have to join against the topology feed. + string realm = 2; +} From 2029cd35e0403901c657580e19515a006ccc6273 Mon Sep 17 00:00:00 2001 From: Mikhail Agapov Date: Thu, 30 Jul 2026 17:01:29 +0300 Subject: [PATCH 2/2] feat: generate TypeScript for pulse_clusters.proto PeerClusterChange had no generated TS because the generator only emits for public/*.proto entry points and none referenced decentraland/pulse/. Comms Gatekeeper needs this type to subscribe to peer.{addr}.cluster_change. --- public/comms.proto | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/comms.proto b/public/comms.proto index b81b7467..9d7e1cdf 100644 --- a/public/comms.proto +++ b/public/comms.proto @@ -2,4 +2,5 @@ syntax = "proto3"; import public "decentraland/kernel/comms/v3/archipelago.proto"; import public "decentraland/kernel/comms/rfc4/comms.proto"; -import public "decentraland/kernel/comms/rfc5/ws_comms.proto"; \ No newline at end of file +import public "decentraland/kernel/comms/rfc5/ws_comms.proto"; +import public "decentraland/pulse/pulse_clusters.proto"; \ No newline at end of file