The shell would never emit .reachable events once a node is found to be alive again.
I'd propose remodeling the .applied() to return "change" style directives like the high level membership. As it's hard to guarantee now that we only once emit a .reachable or .unreachable.
So something like:
switch swim.onGossipPayload(member) {
case .applied(change, ...) if change.reachabilityChanged:
let reachability: Cluster.MemberReachability
if change.status.isUnreachable || change.status.isDead {
reachability = .unreachable
} else {
reachability = .reachable
}
self.clusterRef.tell(.command(.failureDetectorReachabilityChanged(member.node, reachability)))