Files
natsnet/docs/plans/2026-02-27-batch-23-routes-implementation-plan.md
Joseph Doherty c05d93618e Add batch plans for batches 23-30 (rounds 12-15)
Generated design docs and implementation plans via Codex for:
- Batch 23: Routes
- Batch 24: Leaf Nodes
- Batch 25: Gateways
- Batch 26: WebSocket
- Batch 27: JetStream Core
- Batch 28: JetStream API
- Batch 29: JetStream Batching
- Batch 30: Raft Part 1

All plans include mandatory verification protocol and anti-stub guardrails.
Updated batches.md with file paths and planned status.
2026-02-27 16:33:10 -05:00

20 KiB

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:

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:
dotnet run --project tools/NatsNet.PortTracker -- feature show <feature_id> --db porting.db
# then open golang/nats-server/server/route.go at go_line_number..(go_line_number + go_line_count)
  1. Implement the mapped C# behavior in the planned file(s) without placeholders.
  2. Build immediately after each feature (or tightly coupled pair):
dotnet build dotnet/
  1. Run the smallest related tests immediately:
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests|FullyQualifiedName~ServerTests|FullyQualifiedName~ServerLifecycleStubFeaturesTests|FullyQualifiedName~RouteHandlerTests"
  1. Record evidence (feature ID, build result, test result) before moving on.
  2. 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:

# 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)

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:

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:

# features (<=15 IDs)
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<comma-separated up to 15 IDs>" --set-status <stub|complete|verified> --db porting.db --execute

# tests (<=15 IDs)
dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "<comma-separated up to 15 IDs>" --set-status <stub|complete|verified> --db porting.db --execute

Checkpoint Protocol (REQUIRED between tasks)

After each task (every feature group and the test wave):

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 "<batch23 checkpoint message>"

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:
dotnet run --project tools/NatsNet.PortTracker -- feature update <id> --status deferred --override "blocked: <specific reason>" --db porting.db
# or
dotnet run --project tools/NatsNet.PortTracker -- test update <id> --status deferred --override "blocked: <specific reason>" --db porting.db
  1. Continue to the next unblocked ID.
  2. 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

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

dotnet run --project tools/NatsNet.PortTracker -- batch start 23 --db porting.db

Step 3: Baseline gate

dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/

Step 4: Checkpoint commit

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

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

# 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

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

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

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

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

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

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

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

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

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

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

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

dotnet run --project tools/NatsNet.PortTracker -- test show <test_id> --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~<dotnet_method_name>"

Step 3: Run Stub Detection Check on test file + class-level gate

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

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

# 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

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

dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/

Step 2: Final Batch 23 stub audit

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

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

./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"