# Batch 24 Leaf Nodes Design **Date:** 2026-02-27 **Batch:** 24 (`Leaf Nodes`) **Scope:** Design only. No implementation in this document. ## Problem Batch 24 ports leaf-node connection handling from `golang/nats-server/server/leafnode.go` into the .NET server. - Features: `67` (all currently `deferred`) - Tests: `2` (both currently `deferred`) - Dependencies: batches `19` and `23` - Go source: `server/leafnode.go` - Batch status: `pending` Leaf-node behavior touches client protocol parsing, solicited/accepted leaf lifecycle, account interest propagation, and cross-cluster subscription semantics. ## Context Findings Collected with: - `dotnet run --project tools/NatsNet.PortTracker -- batch show 24 --db porting.db` - `dotnet run --project tools/NatsNet.PortTracker -- batch list --db porting.db` - `dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db` Additional repository findings: - .NET already has leaf data models in `dotnet/src/ZB.MOM.NatsNet.Server/LeafNode/LeafNodeTypes.cs` (`Leaf`, `LeafNodeCfg`, `LeafConnectInfo`) but the Batch 24 behavior surface is largely unimplemented. - `ClientConnection` currently has explicit leaf placeholders (`IsHubLeafNode`, `RemoteCluster`) and parser-level leaf argument helpers still marked as stubs/delegates. - `LeafNodeHandlerTests.Impltests.cs` and `RouteHandlerTests.Impltests.cs` still contain placeholder-style tests and do not currently include the two Batch 24 mapped methods. - Batch 24 mapped tests are: - `1966` (`LeafNodeHandlerTests.LeafNodeRoutedSubKeyDifferentBetweenLeafSubAndRoutedSub_ShouldSucceed`) - `2825` (`RouteHandlerTests.ClusterQueueGroupWeightTrackingLeak_ShouldSucceed`) ## Constraints and Success Criteria Constraints: - Follow project standards in `docs/standards/dotnet-standards.md`. - Keep behavior equivalent to Go intent, but idiomatic C# (.NET 10, nullable enabled). - No placeholder implementations, no fake-pass tests, no status promotion without evidence. - Feature work must be grouped into chunks of <= ~20 features. - Batch 24 execution must wait for dependency readiness (batches 19 and 23). Success criteria: - All 67 features are either implemented and verified, or explicitly deferred with a concrete blocker reason. - Both mapped tests are implemented as real behavioral tests and pass. - Leaf-related parser/account regression tests pass before `complete -> verified`. - Batch 24 can be completed through PortTracker without overrides for unverifiable work. ## Approaches ### Approach A: Single monolithic leaf file Implement all 67 methods in one large `NatsServer.LeafNodes.cs` and keep most `ClientConnection` work in `ClientConnection.cs`. Trade-offs: - Pros: fewer files to navigate. - Cons: very high review risk, difficult evidence tracking, poor checkpoint isolation. ### Approach B (Recommended): Domain-segmented partials by leaf lifecycle stage Split implementation by responsibility: 1. Leaf validation/config/bootstrap 2. Connect/handshake/lifecycle 3. Interest propagation/account/subscription maps 4. Message/sub/unsub processing and websocket solicit path Trade-offs: - Pros: aligns to `leafnode.go` sections, cleaner verification gates, easier status chunking and rollback. - Cons: more file coordination. ### Approach C: Test-first only on mapped tests, then fill remaining features Start with the two mapped tests and then backfill features. Trade-offs: - Pros: immediate test signal. - Cons: two tests under-cover 67 features, making false confidence likely unless strict feature-level verification is enforced. ## Recommended Design Use **Approach B** with four feature groups (18/18/14/17 IDs) mapped to Go line ranges and .NET class ownership. ### Architecture - `ClientConnection` partials handle leaf protocol parsing, leaf connect payload processing, sub/unsub deltas, permission violations, and websocket solicitation. - `NatsServer` partials handle remote solicitation, outbound reconnect/connect loops, listener accept loop, leaf info dissemination, and connection registration lifecycle. - `LeafNode` helper surface (`LeafNodeHandler` + `LeafNodeCfg` methods) centralizes validation and key generation utilities used by both server and client paths. - `Account` updates cover `UpdateLeafNodesEx` semantics and gateway/leaf interest propagation coupling. ### Proposed File Map Primary production files: - Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.LeafNodes.cs` - Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.LeafNodes.ConfigAndConnect.cs` - Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.LeafNodes.Subscriptions.cs` - Create: `dotnet/src/ZB.MOM.NatsNet.Server/LeafNode/LeafNodeHandler.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/LeafNode/LeafNodeTypes.cs` (for `LeafNodeCfg` method surface) - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs` - Modify (as needed): `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs` Mapped test files: - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs` - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs` Related regression tests: - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs` - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Accounts/ResolverDefaultsOpsTests.cs` - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs` ### Data and Control Flow - Outbound flow: configured remote leaf nodes -> validate -> pick URL -> connect/proxy/ws path -> leaf CONNECT/INFO handshake -> register connection -> initialize subscription map. - Inbound flow: accept loop -> create leaf client -> process INFO/CONNECT -> negotiate compression/perms -> account registration and interest sync. - Interest propagation: account sub changes -> leaf smap deltas -> leaf SUB/UNSUB protocol emission -> inbound leaf message/sub updates -> permission enforcement. ### Error Handling Strategy - Preserve Go failure modes for malformed protocol args, invalid remote config, and loop/duplicate detection paths. - Prefer explicit guard clauses with clear exceptions over silent default returns. - On infrastructure blockers, defer with reason rather than introducing placeholders. ### Verification Strategy - Enforce per-feature verification loop (Go read, C# implementation, build, related test run). - Enforce group-level stub scans and build gate before any `stub -> complete`. - Enforce full leaf-related test gate before any `complete -> verified`. - Enforce checkpoint protocol (full build + full tests + commit) between every task. ### Risks and Mitigations - Risk: race-prone account/smap updates regress existing account behavior. - Mitigation: isolate account update logic and require `ResolverDefaultsOpsTests` in every verification wave. - Risk: parser and runtime leaf arg handling diverge. - Mitigation: keep parser and client leaf arg updates in the same feature group and verify via `ProtocolParserTests`. - Risk: backlog tests remain placeholders and create false green. - Mitigation: mandatory anti-stub scans and method-level filters for mapped tests. ## Design Approval Basis This design is based on Batch 24 metadata from PortTracker, existing Batch 0 verification standards, and explicit requirements for feature+test anti-stub guardrails and grouped execution.