Add RandomizedElectionTimeout() method to RaftNode returning TimeSpan in
[ElectionTimeoutMinMs, ElectionTimeoutMaxMs) using TotalMilliseconds (not
.Milliseconds component) to prevent synchronized elections after partitions.
Make Random injectable for deterministic testing. Fix SendHeartbeatAsync stub
in NatsRaftTransport and test-local transport implementations to satisfy the
IRaftTransport interface added in Gap 8.7.
- Add RaftTimeoutNowWire: 16-byte wire type [8:term][8:leaderId] with
Encode/Decode roundtrip, matching Go's sendTimeoutNow wire layout
- Add TimeoutNow(group) subject "$NRG.TN.{group}" to RaftSubjects
- Add SendTimeoutNowAsync to IRaftTransport; implement in both
InMemoryRaftTransport (synchronous delivery) and NatsRaftTransport
(publishes to $NRG.TN.{group})
- Add TransferLeadershipAsync(targetId, ct) to RaftNode: leader sends
TimeoutNow RPC, blocks proposals via _transferInProgress flag, polls
until target becomes leader or 2x election timeout elapses
- Add ReceiveTimeoutNow(term) to RaftNode: target immediately starts
election bypassing pre-vote, updates term if sender's term is higher
- Block ProposeAsync with InvalidOperationException during transfer
- 15 tests in RaftLeadershipTransferTests covering wire roundtrip,
ReceiveTimeoutNow behaviour, proposal blocking, target leadership,
timeout on unreachable peer, and transfer flag lifecycle
Implements RaftSubjects static class with Go's $NRG.* subject constants
and NatsRaftTransport which routes RAFT RPCs over those subjects using
RaftAppendEntryWire / RaftVoteRequestWire encoding. 43 tests cover all
subject patterns, wire encoding fidelity, and transport construction.