a25c9ed097
The load-bearing integration half of Critical 1. Adds TwoNodeClusterHarness.HardKillNodeAAsync (canonical in-process crash sim: shut down node A's remoting transport via IRemoteActorRefProvider.Transport.Shutdown() — associations drop, heartbeats/gossip stop, NO graceful Cluster.Leave, so node B's failure detector marks A Unreachable) + a WaitForNodeBSoleDriverLeaderAsync helper (waits for a STABLE takeover: B sole Up member + driver role-leader). HardKillFailoverTests crashes the oldest node and asserts the survivor takes over — the exact scenario the graceful StopNodeBAsync path (Cluster.Leave, no downing decision) cannot exercise. Live-verified in-process (~35s: acceptable-heartbeat-pause 10s + stable-after 15s + convergence). Negative control confirmed the test BITES: forcing explicit NoDowning (akka.cluster.downing-provider-class = "") makes it time out with the node stuck Up-but-Unreachable. FINDING surfaced by the negative control: removing Critical 1's typed ClusterOptions.SplitBrainResolver did NOT break failover, because Akka.Cluster.Hosting's WithClustering applies SplitBrainResolverOption.Default when the option is null — enabling the SBR downing provider that reads the akka.conf keep-oldest block (present on master BEFORE Critical 1). So the cluster was NOT running NoDowning before Critical 1; the typed option reinforces the akka.conf strategy rather than being the sole activator, and Critical 1's 'HOCON inert / NoDowning' premise is inaccurate. The test guards the failover OUTCOME regardless of activation path. Comments corrected to reflect this; flagged for review.