Files
natsnet/docs/plans/2026-02-26-phase-6-porting.md
Joseph Doherty b335230498 chore: scaffold .NET solution structure for Phase 6
Creates the four-project .NET 10 solution (ZB.MOM.NatsNet.slnx):
- ZB.MOM.NatsNet.Server: main library with MEL, BCrypt.Net-Next, IronSnappy
- ZB.MOM.NatsNet.Server.Host: console host with Serilog + Microsoft.Extensions.Hosting
- ZB.MOM.NatsNet.Server.Tests: xUnit 2.9 / Shouldly / NSubstitute / BenchmarkDotNet
- ZB.MOM.NatsNet.Server.IntegrationTests: same test stack, separate project

Also adds Phase 6 porting plan and task-tracking JSON.
2026-02-26 08:03:21 -05:00

28 KiB
Raw Permalink Blame History

Phase 6: Initial Porting Implementation Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers-extended-cc:executing-plans to implement this plan task-by-task.

Goal: Port all 3632 Go features and 3257 tests across 12 modules from the Go NATS server to idiomatic .NET 10 C#, working bottom-up through the dependency graph.

Architecture: Port leaf modules (11 small modules, 279 features total) in parallel first, then tackle the server module (3394 features) in functional batches. The dependency ready command drives porting order. Every feature gets a stub before implementation; tests are ported alongside.

Tech Stack: .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, Microsoft.Extensions.Logging, Serilog, System.IO.Pipelines, BCrypt.Net-Next, IronSnappy, Tpm2Lib


Dependency Graph Summary

Leaf modules (all unblocked — port in parallel):
  ats      module 1   4 features,   3 tests  → AccessTimeService
  avl      module 2  36 features,  16 tests  → SequenceSet (AVL tree)
  certidp  module 3  14 features,   2 tests  → CertificateIdentityProvider
  certstore module 4 36 features,   0 tests  → CertificateStore
  elastic  module 5   5 features,   0 tests  → ElasticEncoding
  gsl      module 6  26 features,  21 tests  → GenericSubjectList
  pse      module 7  28 features,   3 tests  → ProcessStatsProvider
  stree    module 9 101 features,  59 tests  → SubjectTree
  sysmem   module 10  9 features,   0 tests  → SystemMemory
  thw      module 11 12 features,  14 tests  → TimeHashWheel
  tpm      module 12  8 features,   2 tests  → TpmKeyProvider

Server module (blocked on all leaf modules):
  server   module 8  3394 features, ~3137 tests → NatsServer (347K Go LOC)

TDD Porting Pattern (repeat for every feature)

  1. dotnet run --project tools/NatsNet.PortTracker -- feature update <id> --status stub --db porting.db
  2. Write failing test (translate Go test, Shouldly assertions, xUnit [Fact]/[Theory])
  3. Run test: confirm FAIL
  4. Implement feature: idiomatic C# from Go source (coordinates in feature show <id>)
  5. Run test: confirm PASS
  6. dotnet run --project tools/NatsNet.PortTracker -- feature update <id> --status complete --db porting.db

After all features in a module: dotnet run --project tools/NatsNet.PortTracker -- module update <id> --status complete --db porting.db


Go→.NET Translation Reference

Go pattern .NET equivalent
goroutine + channel Task + Channel<T> or async/await
sync.Mutex lock or SemaphoreSlim
sync.RWMutex ReaderWriterLockSlim
sync.WaitGroup Task.WhenAll or CountdownEvent
defer try/finally or using
interface{} / any object or generics
[]byte byte[], ReadOnlySpan<byte>, or ReadOnlyMemory<byte>
map[K]V Dictionary<K,V> or ConcurrentDictionary<K,V>
error return Exceptions or Result<T>
panic/recover Exceptions
select on channels Task.WhenAny or Channel<T> reader
context.Context CancellationToken
io.Reader/Writer Stream, PipeReader/PipeWriter
init() Static constructor or DI registration

Task 0: Create .NET Solution Structure

Files to create:

  • dotnet/ZB.MOM.NatsNet.sln
  • dotnet/src/ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj
  • dotnet/src/ZB.MOM.NatsNet.Server.Host/ZB.MOM.NatsNet.Server.Host.csproj
  • dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ZB.MOM.NatsNet.Server.Tests.csproj
  • dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj

Step 1: Scaffold projects

cd /Users/dohertj2/Desktop/natsnet/dotnet
dotnet new sln -n ZB.MOM.NatsNet
dotnet new classlib -n ZB.MOM.NatsNet.Server -o src/ZB.MOM.NatsNet.Server --framework net10.0
dotnet new console -n ZB.MOM.NatsNet.Server.Host -o src/ZB.MOM.NatsNet.Server.Host --framework net10.0
dotnet new xunit -n ZB.MOM.NatsNet.Server.Tests -o tests/ZB.MOM.NatsNet.Server.Tests --framework net10.0
dotnet new xunit -n ZB.MOM.NatsNet.Server.IntegrationTests -o tests/ZB.MOM.NatsNet.Server.IntegrationTests --framework net10.0
dotnet sln add src/ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj
dotnet sln add src/ZB.MOM.NatsNet.Server.Host/ZB.MOM.NatsNet.Server.Host.csproj
dotnet sln add tests/ZB.MOM.NatsNet.Server.Tests/ZB.MOM.NatsNet.Server.Tests.csproj
dotnet sln add tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj

Step 2: Configure server library .csproj

Replace contents of dotnet/src/ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <LangVersion>latest</LangVersion>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="*" />
    <PackageReference Include="Microsoft.Extensions.Options" Version="*" />
    <PackageReference Include="System.IO.Pipelines" Version="*" />
    <PackageReference Include="BCrypt.Net-Next" Version="*" />
    <PackageReference Include="IronSnappy" Version="*" />
  </ItemGroup>
</Project>

Note: Tpm2Lib is Windows-only; add it in Task 11 for the tpm module with a conditional reference.

Step 3: Configure Host .csproj

Replace contents of dotnet/src/ZB.MOM.NatsNet.Server.Host/ZB.MOM.NatsNet.Server.Host.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <LangVersion>latest</LangVersion>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="../ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="*" />
    <PackageReference Include="Serilog" Version="*" />
    <PackageReference Include="Serilog.Extensions.Hosting" Version="*" />
    <PackageReference Include="Serilog.Sinks.Console" Version="*" />
  </ItemGroup>
</Project>

Step 4: Configure Tests .csproj

Replace contents of dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ZB.MOM.NatsNet.Server.Tests.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <LangVersion>latest</LangVersion>
    <IsPackable>false</IsPackable>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="../../src/ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj" />
    <PackageReference Include="xunit" Version="3.*" />
    <PackageReference Include="xunit.runner.visualstudio" Version="3.*" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="*" />
    <PackageReference Include="Shouldly" Version="*" />
    <PackageReference Include="NSubstitute" Version="*" />
    <PackageReference Include="BenchmarkDotNet" Version="*" />
  </ItemGroup>
</Project>

Apply the same to dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj.

Step 5: Clean boilerplate, add placeholder Program.cs, verify build

rm -f dotnet/src/ZB.MOM.NatsNet.Server/Class1.cs
# Program.cs for Host (placeholder)
# Write: Console.WriteLine("ZB.MOM.NatsNet.Server"); to Program.cs
dotnet build /Users/dohertj2/Desktop/natsnet/dotnet/ZB.MOM.NatsNet.sln
dotnet test /Users/dohertj2/Desktop/natsnet/dotnet/ZB.MOM.NatsNet.sln

Expected: build succeeds, 0 tests (or default xUnit tests pass).

Step 6: Commit

git add dotnet/
git commit -m "chore: scaffold .NET solution structure for Phase 6"

Task 1: Port avl Module — SequenceSet

Go source: golang/nats-server/server/avl/seqset.go (678 LOC) Go tests: golang/nats-server/server/avl/seqset_test.go, norace_test.go Target: dotnet/src/ZB.MOM.NatsNet.Server/Internal/DataStructures/SequenceSet.cs Tests: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/DataStructures/SequenceSetTests.cs Namespace: ZB.MOM.NatsNet.Server.Internal.DataStructures Features: 36 (IDs 540) | Tests: 16 | Module ID: 2

Step 1: Mark all stubs

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 2 --db porting.db

Step 2: Lookup source coordinates for key features

dotnet run --project tools/NatsNet.PortTracker -- feature show 5 --db porting.db   # Insert (line 44)
dotnet run --project tools/NatsNet.PortTracker -- feature show 6 --db porting.db   # Exists
dotnet run --project tools/NatsNet.PortTracker -- feature show 8 --db porting.db   # Delete
dotnet run --project tools/NatsNet.PortTracker -- feature show 22 --db porting.db  # Encode
dotnet run --project tools/NatsNet.PortTracker -- feature show 23 --db porting.db  # Decode

Step 3: Create the class skeleton

Create dotnet/src/ZB.MOM.NatsNet.Server/Internal/DataStructures/SequenceSet.cs.

Key type mappings:

  • SequenceSet struct → public sealed class SequenceSet
  • node struct → private sealed class Node
  • Go uint64 → C# ulong
  • Go pointer receivers on node → C# methods on Node

All methods: throw new NotImplementedException() initially.

Step 4: Write failing tests

Create SequenceSetTests.cs translating from seqset_test.go. Example:

// Go: TestSeqSetBasics
[Fact]
public void SeqSetBasics_ShouldSucceed()
{
    var ss = new SequenceSet();
    ss.IsEmpty().ShouldBeTrue();
    ss.Insert(1);
    ss.Exists(1).ShouldBeTrue();
    ss.Exists(2).ShouldBeFalse();
    ss.Size().ShouldBe(1);
    ss.Delete(1);
    ss.IsEmpty().ShouldBeTrue();
}

Run: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~SequenceSetTests" Expected: FAIL with NotImplementedException.

Step 5: Implement SequenceSet

Port AVL tree logic from seqset.go. Critical Go→.NET:

  • uint64ulong
  • nil checks → null checks
  • Range(f func(uint64, uint64) bool)Range(Func<ulong, ulong, bool> f)
  • Encode/Decode using ReadOnlySpan<byte> and BinaryPrimitives

Step 6: Run tests

dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~SequenceSetTests"

Expected: all 16 tests pass.

Step 7: Update DB

for id in 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40; do
  dotnet run --project tools/NatsNet.PortTracker -- feature update $id --status complete --db porting.db
done
dotnet run --project tools/NatsNet.PortTracker -- test list --module 2 --db porting.db
# mark each test complete
dotnet run --project tools/NatsNet.PortTracker -- module update 2 --status complete --db porting.db

Step 8: Commit

git add dotnet/
git commit -m "feat: port avl module - SequenceSet AVL tree"

Task 2: Port ats Module — AccessTimeService

Go source: golang/nats-server/server/ats/ats.go (186 LOC) Go tests: golang/nats-server/server/ats/ats_test.go Target: dotnet/src/ZB.MOM.NatsNet.Server/Internal/AccessTimeService.cs Tests: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/AccessTimeServiceTests.cs Namespace: ZB.MOM.NatsNet.Server.Internal Features: IDs 14 | Tests: IDs 13 | Module ID: 1

Tracks access times; init() → static initialization. Follow TDD pattern.

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 1 --db porting.db
# implement Register, Unregister, AccessTime, Init
for id in 1 2 3 4; do dotnet run --project tools/NatsNet.PortTracker -- feature update $id --status complete --db porting.db; done
dotnet run --project tools/NatsNet.PortTracker -- module update 1 --status complete --db porting.db
git commit -m "feat: port ats module - AccessTimeService"

Task 3: Port elastic Module — ElasticEncoding

Go source: golang/nats-server/server/elastic/elastic.go (61 LOC) Target: dotnet/src/ZB.MOM.NatsNet.Server/Internal/ElasticEncoding.cs Namespace: ZB.MOM.NatsNet.Server.Internal Features: 5 | Tests: 0 | Module ID: 5

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 5 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- feature list --module 5 --db porting.db
# implement features; no tests to port
dotnet run --project tools/NatsNet.PortTracker -- module update 5 --status complete --db porting.db
git commit -m "feat: port elastic module - ElasticEncoding"

Task 4: Port sysmem Module — SystemMemory

Go source: golang/nats-server/server/sysmem/mem_*.go (platform-specific) Target: dotnet/src/ZB.MOM.NatsNet.Server/Internal/SystemMemory.cs Namespace: ZB.MOM.NatsNet.Server.Internal Features: 9 | Tests: 0 | Module ID: 10

Use System.Diagnostics.Process and GC.GetTotalMemory for cross-platform memory. Mark platform-specific Go variants (BSD, Solaris, WASM, z/OS) as N/A with reason.

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 10 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- feature list --module 10 --db porting.db
# implement; mark n/a for platform variants
dotnet run --project tools/NatsNet.PortTracker -- module update 10 --status complete --db porting.db
git commit -m "feat: port sysmem module - SystemMemory"

Task 5: Port thw Module — TimeHashWheel

Go source: golang/nats-server/server/thw/ (656 LOC) Target: dotnet/src/ZB.MOM.NatsNet.Server/Internal/TimeHashWheel.cs Namespace: ZB.MOM.NatsNet.Server.Internal Features: 12 | Tests: 14 | Module ID: 11

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 11 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- test list --module 11 --db porting.db
# TDD: write tests first, then implement hash wheel
dotnet run --project tools/NatsNet.PortTracker -- module update 11 --status complete --db porting.db
git commit -m "feat: port thw module - TimeHashWheel"

Task 6: Port certidp Module — CertificateIdentityProvider

Go source: golang/nats-server/server/certidp/ (600 LOC) Target: dotnet/src/ZB.MOM.NatsNet.Server/Auth/CertificateIdentityProvider.cs Namespace: ZB.MOM.NatsNet.Server.Auth Features: 14 | Tests: 2 | Module ID: 3

Use System.Security.Cryptography.X509Certificates.

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 3 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- module update 3 --status complete --db porting.db
git commit -m "feat: port certidp module - CertificateIdentityProvider"

Task 7: Port certstore Module — CertificateStore

Go source: golang/nats-server/server/certstore/ (1197 LOC) Target: dotnet/src/ZB.MOM.NatsNet.Server/Auth/CertificateStore.cs Namespace: ZB.MOM.NatsNet.Server.Auth Features: 36 | Tests: 0 | Module ID: 4

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 4 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- module update 4 --status complete --db porting.db
git commit -m "feat: port certstore module - CertificateStore"

Task 8: Port gsl Module — GenericSubjectList

Go source: golang/nats-server/server/gsl/ (936 LOC) Target: dotnet/src/ZB.MOM.NatsNet.Server/Subscriptions/GenericSubjectList.cs Namespace: ZB.MOM.NatsNet.Server.Subscriptions Features: 26 | Tests: 21 | Module ID: 6

Performance-sensitive. Use ReadOnlySpan<byte> for subject matching.

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 6 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- test list --module 6 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- module update 6 --status complete --db porting.db
git commit -m "feat: port gsl module - GenericSubjectList"

Task 9: Port pse Module — ProcessStatsProvider

Go source: golang/nats-server/server/pse/ (1150 LOC, platform-specific) Target: dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProcessStatsProvider.cs Namespace: ZB.MOM.NatsNet.Server.Internal Features: 28 | Tests: 3 | Module ID: 7

Use System.Diagnostics.Process. Mark Go-specific syscall wrappers N/A where replaced.

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 7 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- module update 7 --status complete --db porting.db
git commit -m "feat: port pse module - ProcessStatsProvider"

Task 10: Port stree Module — SubjectTree

Go source: golang/nats-server/server/stree/ (3628 LOC) Target: dotnet/src/ZB.MOM.NatsNet.Server/Subscriptions/SubjectTree.cs Namespace: ZB.MOM.NatsNet.Server.Subscriptions Features: 101 | Tests: 59 | Module ID: 9

Largest leaf module. Performance-critical NATS routing trie. Use ReadOnlySpan<byte> throughout.

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 9 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- test list --module 9 --db porting.db
# write 59 tests first, implement trie, iterate until all pass
dotnet run --project tools/NatsNet.PortTracker -- module update 9 --status complete --db porting.db
git commit -m "feat: port stree module - SubjectTree"

Task 11: Port tpm Module — TpmKeyProvider

Go source: golang/nats-server/server/tpm/ (387 LOC) Target: dotnet/src/ZB.MOM.NatsNet.Server/Auth/TpmKeyProvider.cs Namespace: ZB.MOM.NatsNet.Server.Auth Features: 8 | Tests: 2 | Module ID: 12

Add conditional Tpm2Lib reference (Windows-only). If unavailable on current platform, throw PlatformNotSupportedException.

dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub --all-in-module 12 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- module update 12 --status complete --db porting.db
git commit -m "feat: port tpm module - TpmKeyProvider"

Task 12: Verify Wave 1 (All Leaf Modules Complete)

dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db | head -5
dotnet build /Users/dohertj2/Desktop/natsnet/dotnet/ZB.MOM.NatsNet.sln
dotnet test /Users/dohertj2/Desktop/natsnet/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/

Expected: 11 modules complete, server module appears in dependency ready, build green.


Task 13: Port Server Module — Batch A: Core Types

Go sources: server/const.go, server/errors.go, server/errors_gen.go, server/proto.go, server/util.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Constants.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/NatsErrors.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolConstants.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Internal/Utilities.cs
dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
# identify IDs for const/errors/proto/util features; stub them
dotnet build /Users/dohertj2/Desktop/natsnet/dotnet/ZB.MOM.NatsNet.sln
git commit -m "feat: port server core types (const, errors, proto, util)"

Task 14: Port Server Module — Batch B: Options & Config

Go sources: server/opts.go, server/reload.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Configuration/NatsServerOptions.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Configuration/NatsServerReload.cs
git commit -m "feat: port server options and reload configuration"

Task 15: Port Server Module — Batch C: Parser & Protocol

Go sources: server/parser.go, server/ring.go, server/rate_counter.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Protocol/NatsParser.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Internal/RingBuffer.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Internal/RateCounter.cs

Parser is performance-critical. Use ReadOnlySpan<byte> and System.IO.Pipelines.

git commit -m "feat: port server parser, ring buffer, rate counter"

Task 16: Port Server Module — Batch D: Client & Connection

Go sources: server/client.go, server/client_proxyproto.go, server/sendq.go, server/ipqueue.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Connections/NatsClient.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Connections/ProxyProtocolHandler.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Connections/SendQueue.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Internal/IpQueue.cs

Use Channel<T> for send queue. All async I/O via PipeWriter/PipeReader.

git commit -m "feat: port server client, connection, send queue"

Task 17: Port Server Module — Batch E: Auth & Security

Go sources: server/auth.go, server/auth_callout.go, server/jwt.go, server/nkey.go, server/ciphersuites.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Auth/AuthHandler.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Auth/AuthCallout.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Auth/JwtValidator.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Auth/NkeyProvider.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Auth/CipherSuiteMapper.cs
git commit -m "feat: port server auth, JWT, nkeys, cipher suites"

Task 18: Port Server Module — Batch F: Accounts & Events

Go sources: server/accounts.go, server/events.go, server/dirstore.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Auth/AccountManager.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Events/NatsEventBus.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Auth/DirectoryAccountStore.cs
git commit -m "feat: port server accounts, events, directory store"

Task 19: Port Server Module — Batch G: Sublist & Subject Transform

Go sources: server/sublist.go, server/subject_transform.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Subscriptions/SubList.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Subscriptions/SubjectTransform.cs

Hot path. Use ReadOnlySpan<byte>, avoid allocations in Match.

git commit -m "feat: port server sublist and subject transform"

Task 20: Port Server Module — Batch H: Clustering

Go sources: server/route.go, server/gateway.go, server/leafnode.go, server/raft.go, server/sdm.go, server/scheduler.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Cluster/RouteHandler.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Cluster/GatewayHandler.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Cluster/LeafNodeHandler.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Cluster/RaftConsensus.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Cluster/StreamDomainManager.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Cluster/Scheduler.cs
git commit -m "feat: port server clustering (routes, gateway, leaf nodes, raft)"

Task 21: Port Server Module — Batch I: JetStream Core

Go sources: server/jetstream.go, server/jetstream_api.go, server/jetstream_errors.go, server/jetstream_errors_generated.go, server/jetstream_events.go, server/jetstream_versioning.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamEngine.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamApi.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamErrors.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamEvents.cs
git commit -m "feat: port JetStream core engine and API"

Task 22: Port Server Module — Batch J: JetStream Storage

Go sources: server/store.go, server/filestore.go, server/memstore.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/Storage/IMessageStore.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/Storage/FileMessageStore.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/Storage/MemoryMessageStore.cs

Define IMessageStore from store.go first, then implement.

git commit -m "feat: port JetStream storage (file store, memory store)"

Task 23: Port Server Module — Batch K: JetStream Streams & Consumers

Go sources: server/stream.go, server/consumer.go, server/jetstream_batching.go, server/jetstream_cluster.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StreamManager.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/ConsumerManager.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/BatchProcessor.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamCluster.cs
git commit -m "feat: port JetStream streams, consumers, batching, cluster"

Task 24: Port Server Module — Batch L: Monitoring

Go sources: server/monitor.go, server/monitor_sort_opts.go, server/msgtrace.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Monitoring/NatsMonitor.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Monitoring/MonitorSortOptions.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Monitoring/MessageTracer.cs

log.go features → mark N/A: replaced by Microsoft.Extensions.Logging + Serilog.

git commit -m "feat: port server monitoring, message tracing (log.go → N/A)"

Task 25: Port Server Module — Batch M: MQTT & WebSocket

Go sources: server/mqtt.go, server/websocket.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Protocol/MqttHandler.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Protocol/WebSocketHandler.cs
git commit -m "feat: port MQTT and WebSocket protocol handlers"

Task 26: Port Server Module — Batch N: OCSP & TLS

Go sources: server/ocsp.go, server/ocsp_peer.go, server/ocsp_responsecache.go Targets:

  • dotnet/src/ZB.MOM.NatsNet.Server/Auth/OcspValidator.cs
  • dotnet/src/ZB.MOM.NatsNet.Server/Auth/OcspResponseCache.cs
git commit -m "feat: port OCSP validation and response cache"

Task 27: Port Server Module — Batch O: Platform-Specific & N/A

Go sources: server/disk_avail_*.go, server/signal.go, server/signal_*.go, server/service.go, server/service_windows.go

  • Signal handling → mark N/A: replaced by IHostApplicationLifetime
  • Windows service → port using System.ServiceProcess
  • Disk availability → port using System.IO.DriveInfo; platform variants → N/A
git commit -m "feat: port platform-specific features, mark N/A where replaced"

Task 28: Port Server Module — Batch P: Server Core

Go source: server/server.go Target: dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.cs

Main Server struct and lifecycle. Final piece of the server module.

dotnet run --project tools/NatsNet.PortTracker -- module update 8 --status complete --db porting.db
git commit -m "feat: port server core lifecycle - server module complete"

Task 29: Final Verification & Close Phase 6

dotnet build /Users/dohertj2/Desktop/natsnet/dotnet/ZB.MOM.NatsNet.sln
dotnet test /Users/dohertj2/Desktop/natsnet/dotnet/ZB.MOM.NatsNet.sln
dotnet run --project tools/NatsNet.PortTracker -- dependency blocked --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- phase check 6 --db porting.db

# Close Gitea issues 39-44
for issue in 39 40 41 42 43 44; do
  curl -s -X PATCH "https://gitea.dohertylan.com/api/v1/repos/dohertj2/natsnet/issues/$issue" \
    -H "Content-Type: application/json" \
    -H "Authorization: token $GITEA_TOKEN" \
    -d '{"state":"closed"}'
done

# Close Phase 6 milestone
curl -s -X PATCH "https://gitea.dohertylan.com/api/v1/repos/dohertj2/natsnet/milestones/6" \
  -H "Content-Type: application/json" \
  -H "Authorization: token $GITEA_TOKEN" \
  -d '{"state":"closed"}'

git commit -m "chore: complete phase 6 - initial porting complete"