# Batch 23 Routes Implementation Plan > **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task. **Goal:** Port and verify Batch 23 (`Routes`) by implementing 52 deferred route features from `server/route.go` and replacing/verifying the 5 mapped route tests with real behavioral coverage. **Architecture:** Implement route behavior in focused partials for `ClientConnection` and `NatsServer`, plus a small `RouteHandler` helper surface for batch-mapped helper methods. Execute in three feature groups (18/14/20 IDs), each with strict per-feature verification loops and group gates, then run the mapped test wave and only promote features `complete -> verified` after all related route regression tests are green. **Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`) **Design doc:** `docs/plans/2026-02-27-batch-23-routes-design.md` --- ## Batch 23 Scope - Batch ID: `23` - Name: `Routes` - Dependencies: `16`, `18` - Go source: `golang/nats-server/server/route.go` - Features: `52` - Tests: `5` Reference commands: ```bash dotnet run --project tools/NatsNet.PortTracker -- batch show 23 --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 ``` Primary production files: - Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Routes.cs` - Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.InfoAndPerms.cs` - Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Subscriptions.cs` - Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Connections.cs` - Create: `dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteHandler.cs` - Modify (as needed): `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs` - Modify (as needed): `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/IProtocolHandler.cs` - Modify (as needed): `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs` - Modify (as needed): `dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteTypes.cs` Mapped test file: - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs` Related regression test files: - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs` - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ServerTests.cs` - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/ServerLifecycleStubFeaturesTests.cs` --- ## MANDATORY VERIFICATION PROTOCOL > **NON-NEGOTIABLE:** Every Batch 23 feature/test update must follow this protocol. ### Per-Feature Verification Loop (REQUIRED for every feature ID) 1. Read the tracked feature metadata and Go source before coding: ```bash dotnet run --project tools/NatsNet.PortTracker -- feature show --db porting.db # then open golang/nats-server/server/route.go at go_line_number..(go_line_number + go_line_count) ``` 2. Implement the mapped C# behavior in the planned file(s) without placeholders. 3. Build immediately after each feature (or tightly coupled pair): ```bash dotnet build dotnet/ ``` 4. Run the smallest related tests immediately: ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests|FullyQualifiedName~ServerTests|FullyQualifiedName~ServerLifecycleStubFeaturesTests|FullyQualifiedName~RouteHandlerTests" ``` 5. Record evidence (feature ID, build result, test result) before moving on. 6. If red, fix first. Do not stack unresolved failures. ### Stub Detection Check (REQUIRED after every feature group and test wave) Run these checks before any status promotion: ```bash # 1) Forbidden stub markers grep -R -n -E "(NotImplementedException|TODO|PLACEHOLDER)" \ dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Routes.cs \ dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.InfoAndPerms.cs \ dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Subscriptions.cs \ dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Connections.cs \ dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteHandler.cs \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs # 2) Empty method bodies in mapped feature files grep -R -n -E "^[[:space:]]*(public|internal|private|protected)[^{;=]*\)[[:space:]]*\{[[:space:]]*\}$" \ dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Routes.cs \ dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.InfoAndPerms.cs \ dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Subscriptions.cs \ dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Connections.cs \ dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteHandler.cs # 3) Fake ImplBacklog placeholders grep -n -E "(var goFile = \"server/|ShouldContain\(\"Should\"\)|ShouldNotBeNullOrWhiteSpace\(\))" \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs ``` Any hit must be removed or explicitly deferred. No exceptions. ### Build Gate (REQUIRED after each feature group) ```bash dotnet build dotnet/ ``` `Build succeeded` is required before moving any group features to `complete`. ### Test Gate (REQUIRED before any `complete -> verified` promotion) All related route tests must pass: ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol.ProtocolParserTests" dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ServerTests" dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Server.ServerLifecycleStubFeaturesTests" dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.RouteHandlerTests" ``` All 5 Batch 23 mapped tests must pass before any Batch 23 feature is marked `verified`. ### Status Update Protocol (REQUIRED) - Max `15` IDs per `feature batch-update` or `test batch-update` command. - Required progression: - `deferred -> stub` when active work begins. - `stub -> complete` only after clean stub checks + build gate. - `complete -> verified` only after global route test gate passes. - Evidence required for each update chunk: - successful build output, - successful related test output, - clean stub scan output, - explicit ID list and reason. Status command templates: ```bash # features (<=15 IDs) dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "" --set-status --db porting.db --execute # tests (<=15 IDs) dotnet run --project tools/NatsNet.PortTracker -- \ test batch-update --ids "" --set-status --db porting.db --execute ``` ### Checkpoint Protocol (REQUIRED between tasks) After each task (every feature group and the test wave): ```bash dotnet build dotnet/ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ git add dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog porting.db git commit -m "" ``` Do not start the next task until this checkpoint is complete. ### If You Get Stuck (REQUIRED) 1. Stop on the blocked ID. 2. Remove partial placeholder code (do not leave stubs). 3. Mark blocked item deferred with explicit reason: ```bash dotnet run --project tools/NatsNet.PortTracker -- feature update --status deferred --override "blocked: " --db porting.db # or dotnet run --project tools/NatsNet.PortTracker -- test update --status deferred --override "blocked: " --db porting.db ``` 4. Continue to the next unblocked ID. 5. Never write fake-pass code or tests to bypass blockers. --- ## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE) ### Forbidden Patterns These patterns are forbidden in Batch 23 feature and test work: - `throw new NotImplementedException()` in mapped methods - Empty method bodies for mapped route features - `// TODO` or `// PLACEHOLDER` in mapped route code paths - Trivial default-return placeholders for non-trivial route logic (`return null`, `return false`, `return 0`, `return string.Empty`) - ImplBacklog placeholder tests that only assert string literals (for example `"...".ShouldContain("Should")`) - Test bodies that do not exercise route production code ### Hard Limits - Maximum `20` features per feature group - Maximum `15` IDs per status update command - One feature group active at a time - Zero unresolved stub-scan hits in touched Batch 23 files - Mandatory checkpoint (full build + full test + commit) between tasks --- ## Feature Groups (<=20 IDs each) ### Group 1 (18 IDs): Route protocol and info/perms foundation IDs: `2895,2896,2897,2898,2899,2900,2901,2902,2903,2904,2905,2906,2908,2909,2910,2911,2912,2913` Focus: - Account SUB/UNSUB handling and reply-sub cleanup - Routed args parsing and inbound routed message setup - Route CONNECT and route INFO processing - Route compression negotiation and remote permission update - Implicit route filtering/forwarding and import/export permission checks Target files: - `ClientConnection.Routes.cs` - `NatsServer.Routes.InfoAndPerms.cs` - `Routes/RouteHandler.cs` ### Group 2 (14 IDs): Remote route subs and sub-proto fanout IDs: `2914,2915,2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927` Focus: - Routed-sub key/account extraction - Remote sub/unsub parsing and state mutation - Route SUB/UNSUB protocol buffer generation - Sending full subscription interest to a route - Route object creation and delayed-info decision helper Target files: - `ClientConnection.Routes.cs` - `NatsServer.Routes.Subscriptions.cs` - `Routes/RouteHandler.cs` ### Group 3 (20 IDs): Route lifecycle, solicitation, dedupe, iteration IDs: `2928,2929,2930,2931,2932,2933,2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2947,2948,2950` Focus: - Initial route INFO JSON and `addRoute` - Solicited/duplicate route detection and upgrade path - Route import filters - Route accept loop, start routing, connect/reconnect/validate - Route connect processing, remove-all-except behavior - Duplicate server-name check and route iterators by pool index Target files: - `ClientConnection.Routes.cs` - `NatsServer.Routes.Connections.cs` - `NatsServer.Lifecycle.cs` (for harmonization of remove/iterate paths) - `Routes/RouteHandler.cs` --- ## Mapped Test Wave (5 IDs) IDs: `2798,2822,2823,2844,2850` Target file: - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs` Required behavior focus: - Cluster advertise startup error behavior - TLS route certificate implicit allow pass/fail behavior - Origin cluster route msg arg parsing behavior - Route compression behavior --- ## Task 1: Preflight and Batch Start **Files:** - Read: `docs/standards/dotnet-standards.md` - Read: `docs/plans/2026-02-27-batch-23-routes-design.md` - Read: `golang/nats-server/server/route.go` **Step 1: Confirm batch context** ```bash dotnet run --project tools/NatsNet.PortTracker -- batch show 23 --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 ``` **Step 2: Start batch** ```bash dotnet run --project tools/NatsNet.PortTracker -- batch start 23 --db porting.db ``` **Step 3: Baseline gate** ```bash dotnet build dotnet/ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ ``` **Step 4: Checkpoint commit** ```bash git add porting.db git commit -m "chore(batch23): start routes batch" ``` --- ## Task 2: Implement Feature Group 1 (18 IDs) **Files:** - Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Routes.cs` - Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.InfoAndPerms.cs` - Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteHandler.cs` **Step 1: Move Group 1 to `stub` in chunks <=15** ```bash dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2895,2896,2897,2898,2899,2900,2901,2902,2903,2904,2905,2906,2908,2909,2910" --set-status stub --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2911,2912,2913" --set-status stub --db porting.db --execute ``` **Step 2: Execute Per-Feature Verification Loop for all 18 IDs** **Step 3: Run Stub Detection Check + Build Gate + Group-related tests** ```bash # mandatory stub checks (see protocol) # then: dotnet build dotnet/ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests|FullyQualifiedName~RouteHandlerTests" ``` **Step 4: Move Group 1 IDs to `complete` in chunks <=15** ```bash dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2895,2896,2897,2898,2899,2900,2901,2902,2903,2904,2905,2906,2908,2909,2910" --set-status complete --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2911,2912,2913" --set-status complete --db porting.db --execute ``` **Step 5: Run Checkpoint Protocol and commit** ```bash git commit -m "feat(batch23): implement route protocol and info/perms foundation" ``` --- ## Task 3: Implement Feature Group 2 (14 IDs) **Files:** - Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Routes.cs` - Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Subscriptions.cs` - Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteHandler.cs` **Step 1: Move Group 2 to `stub`** ```bash dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2914,2915,2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927" --set-status stub --db porting.db --execute ``` **Step 2: Execute Per-Feature Verification Loop for all 14 IDs** **Step 3: Run Stub Detection Check + Build Gate + Group-related tests** ```bash dotnet build dotnet/ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests|FullyQualifiedName~ServerTests|FullyQualifiedName~RouteHandlerTests" ``` **Step 4: Move Group 2 IDs to `complete`** ```bash dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2914,2915,2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927" --set-status complete --db porting.db --execute ``` **Step 5: Run Checkpoint Protocol and commit** ```bash git commit -m "feat(batch23): implement route subscription propagation and creation helpers" ``` --- ## Task 4: Implement Feature Group 3 (20 IDs) **Files:** - Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Routes.cs` - Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Connections.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs` - Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteHandler.cs` **Step 1: Move Group 3 to `stub` in chunks <=15** ```bash dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2928,2929,2930,2931,2932,2933,2935,2936,2937,2938,2939,2940,2941,2942,2943" --set-status stub --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2944,2945,2947,2948,2950" --set-status stub --db porting.db --execute ``` **Step 2: Execute Per-Feature Verification Loop for all 20 IDs** **Step 3: Run Stub Detection Check + Build Gate + Group-related tests** ```bash dotnet build dotnet/ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ServerTests|FullyQualifiedName~ServerLifecycleStubFeaturesTests|FullyQualifiedName~RouteHandlerTests" ``` **Step 4: Move Group 3 IDs to `complete` in chunks <=15** ```bash dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2928,2929,2930,2931,2932,2933,2935,2936,2937,2938,2939,2940,2941,2942,2943" --set-status complete --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2944,2945,2947,2948,2950" --set-status complete --db porting.db --execute ``` **Step 5: Run Checkpoint Protocol and commit** ```bash git commit -m "feat(batch23): implement route lifecycle, solicitation, dedupe, and iteration" ``` --- ## Task 5: Implement and Verify Mapped Tests (5 IDs) **Files:** - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs` **Step 1: Move mapped tests to `stub`** ```bash dotnet run --project tools/NatsNet.PortTracker -- test batch-update --ids "2798,2822,2823,2844,2850" --set-status stub --db porting.db --execute ``` **Step 2: For each test ID (2798, 2822, 2823, 2844, 2850), run per-test loop** ```bash dotnet run --project tools/NatsNet.PortTracker -- test show --db porting.db # port behavior from routes_test.go line range # run single test: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~" ``` **Step 3: Run Stub Detection Check on test file + class-level gate** ```bash grep -n -E "(NotImplementedException|Assert\.True\(true\)|TODO|PLACEHOLDER|ShouldContain\(\"Should\"\))" \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.RouteHandlerTests" ``` **Step 4: Move mapped tests to `complete`, then `verified` only after full Test Gate** ```bash dotnet run --project tools/NatsNet.PortTracker -- test batch-update --ids "2798,2822,2823,2844,2850" --set-status complete --db porting.db --execute ``` **Step 5: Run full Route Test Gate from protocol section and promote statuses** ```bash # tests verified dotnet run --project tools/NatsNet.PortTracker -- test batch-update --ids "2798,2822,2823,2844,2850" --set-status verified --db porting.db --execute # features verified in chunks <=15 dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2895,2896,2897,2898,2899,2900,2901,2902,2903,2904,2905,2906,2908,2909,2910" --set-status verified --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2911,2912,2913,2914,2915,2916,2917,2918,2919,2920,2921,2922,2923,2924,2925" --set-status verified --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2926,2927,2928,2929,2930,2931,2932,2933,2935,2936,2937,2938,2939,2940,2941" --set-status verified --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2942,2943,2944,2945,2947,2948,2950" --set-status verified --db porting.db --execute ``` **Step 6: Run Checkpoint Protocol and commit** ```bash git commit -m "test(batch23): port and verify mapped route tests" ``` --- ## Task 6: Batch Closure and Reporting **Files:** - Modify: `porting.db` - Generate: `reports/current.md` **Step 1: Final build + full unit test sweep** ```bash dotnet build dotnet/ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ ``` **Step 2: Final Batch 23 stub audit** ```bash grep -R -n -E "(NotImplementedException|TODO|PLACEHOLDER)" \ dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Routes.cs \ dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.InfoAndPerms.cs \ dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Subscriptions.cs \ dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Routes.Connections.cs \ dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteHandler.cs \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs ``` **Step 3: Verify batch status and complete batch** ```bash dotnet run --project tools/NatsNet.PortTracker -- batch show 23 --db porting.db dotnet run --project tools/NatsNet.PortTracker -- batch complete 23 --db porting.db ``` **Step 4: Generate report and final commit** ```bash ./reports/generate-report.sh git add dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog porting.db reports/ git commit -m "feat(batch23): complete routes implementation and verification" ```