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.
This commit is contained in:
Joseph Doherty
2026-02-26 08:03:21 -05:00
parent 023a5ddb7e
commit b335230498
12 changed files with 940 additions and 1 deletions

View File

@@ -0,0 +1,741 @@
# 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**
```bash
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`:
```xml
<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`:
```xml
<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`:
```xml
<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**
```bash
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**
```bash
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**
```bash
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**
```bash
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:
```csharp
// 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:
- `uint64``ulong`
- 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**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~SequenceSetTests"
```
Expected: all 16 tests pass.
**Step 7: Update DB**
```bash
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**
```bash
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.
```bash
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
```bash
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.
```bash
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
```bash
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`.
```bash
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
```bash
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.
```bash
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.
```bash
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.
```bash
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`.
```bash
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)
```bash
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`
```bash
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`
```bash
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`.
```bash
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`.
```bash
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`
```bash
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`
```bash
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`.
```bash
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`
```bash
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`
```bash
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.
```bash
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`
```bash
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.
```bash
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`
```bash
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`
```bash
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
```bash
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.
```bash
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
```bash
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"
```

View File

@@ -0,0 +1,36 @@
{
"planPath": "docs/plans/2026-02-26-phase-6-porting.md",
"tasks": [
{"id": 0, "subject": "Task 0: Create .NET Solution Structure", "status": "pending"},
{"id": 1, "subject": "Task 1: Port avl module - SequenceSet", "status": "pending", "blockedBy": [0]},
{"id": 2, "subject": "Task 2: Port ats module - AccessTimeService", "status": "pending", "blockedBy": [0]},
{"id": 3, "subject": "Task 3: Port elastic module - ElasticEncoding", "status": "pending", "blockedBy": [0]},
{"id": 4, "subject": "Task 4: Port sysmem module - SystemMemory", "status": "pending", "blockedBy": [0]},
{"id": 5, "subject": "Task 5: Port thw module - TimeHashWheel", "status": "pending", "blockedBy": [0]},
{"id": 6, "subject": "Task 6: Port certidp module - CertificateIdentityProvider", "status": "pending", "blockedBy": [0]},
{"id": 7, "subject": "Task 7: Port certstore module - CertificateStore", "status": "pending", "blockedBy": [0]},
{"id": 8, "subject": "Task 8: Port gsl module - GenericSubjectList", "status": "pending", "blockedBy": [0]},
{"id": 9, "subject": "Task 9: Port pse module - ProcessStatsProvider", "status": "pending", "blockedBy": [0]},
{"id": 10, "subject": "Task 10: Port stree module - SubjectTree", "status": "pending", "blockedBy": [0]},
{"id": 11, "subject": "Task 11: Port tpm module - TpmKeyProvider", "status": "pending", "blockedBy": [0]},
{"id": 12, "subject": "Task 12: Verify Wave 1 (all leaf modules complete)", "status": "pending", "blockedBy": [1,2,3,4,5,6,7,8,9,10,11]},
{"id": 13, "subject": "Task 13: Port server Batch A - Core Types", "status": "pending", "blockedBy": [12]},
{"id": 14, "subject": "Task 14: Port server Batch B - Options & Config", "status": "pending", "blockedBy": [13]},
{"id": 15, "subject": "Task 15: Port server Batch C - Parser & Protocol", "status": "pending", "blockedBy": [14]},
{"id": 16, "subject": "Task 16: Port server Batch D - Client & Connection", "status": "pending", "blockedBy": [15]},
{"id": 17, "subject": "Task 17: Port server Batch E - Auth & Security", "status": "pending", "blockedBy": [16]},
{"id": 18, "subject": "Task 18: Port server Batch F - Accounts & Events", "status": "pending", "blockedBy": [17]},
{"id": 19, "subject": "Task 19: Port server Batch G - Sublist & Subject Transform", "status": "pending", "blockedBy": [18]},
{"id": 20, "subject": "Task 20: Port server Batch H - Clustering", "status": "pending", "blockedBy": [19]},
{"id": 21, "subject": "Task 21: Port server Batch I - JetStream Core", "status": "pending", "blockedBy": [20]},
{"id": 22, "subject": "Task 22: Port server Batch J - JetStream Storage", "status": "pending", "blockedBy": [21]},
{"id": 23, "subject": "Task 23: Port server Batch K - JetStream Streams & Consumers", "status": "pending", "blockedBy": [22]},
{"id": 24, "subject": "Task 24: Port server Batch L - Monitoring", "status": "pending", "blockedBy": [23]},
{"id": 25, "subject": "Task 25: Port server Batch M - MQTT & WebSocket", "status": "pending", "blockedBy": [24]},
{"id": 26, "subject": "Task 26: Port server Batch N - OCSP & TLS", "status": "pending", "blockedBy": [25]},
{"id": 27, "subject": "Task 27: Port server Batch O - Platform-Specific & N/A", "status": "pending", "blockedBy": [26]},
{"id": 28, "subject": "Task 28: Port server Batch P - Server Core", "status": "pending", "blockedBy": [27]},
{"id": 29, "subject": "Task 29: Final Verification & Close Phase 6", "status": "pending", "blockedBy": [28]}
],
"lastUpdated": "2026-02-26T00:00:00Z"
}

View File

@@ -0,0 +1,10 @@
<Solution>
<Folder Name="/src/">
<Project Path="src/ZB.MOM.NatsNet.Server.Host/ZB.MOM.NatsNet.Server.Host.csproj" />
<Project Path="src/ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj" />
<Project Path="tests/ZB.MOM.NatsNet.Server.Tests/ZB.MOM.NatsNet.Server.Tests.csproj" />
</Folder>
</Solution>

View File

@@ -0,0 +1,2 @@
// Entry point placeholder - will be populated during server module porting
Console.WriteLine("ZB.MOM.NatsNet.Server");

View File

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

View File

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

View File

@@ -0,0 +1,10 @@
namespace ZB.MOM.NatsNet.Server.IntegrationTests;
public class UnitTest1
{
[Fact]
public void Test1()
{
}
}

View File

@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../../src/ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
<PackageReference Include="Shouldly" Version="*" />
<PackageReference Include="NSubstitute" Version="*" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
namespace ZB.MOM.NatsNet.Server.Tests;
public class UnitTest1
{
[Fact]
public void Test1()
{
}
}

View File

@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../../src/ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
<PackageReference Include="Shouldly" Version="*" />
<PackageReference Include="NSubstitute" Version="*" />
<PackageReference Include="BenchmarkDotNet" Version="*" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,6 @@
# NATS .NET Porting Status Report # NATS .NET Porting Status Report
Generated: 2026-02-26 12:45:05 UTC Generated: 2026-02-26 13:03:21 UTC
## Modules (12 total) ## Modules (12 total)

33
reports/report_023a5dd.md Normal file
View File

@@ -0,0 +1,33 @@
# NATS .NET Porting Status Report
Generated: 2026-02-26 13:03:21 UTC
## Modules (12 total)
| Status | Count |
|--------|-------|
| not_started | 12 |
## Features (3673 total)
| Status | Count |
|--------|-------|
| n_a | 41 |
| not_started | 3632 |
## Unit Tests (3257 total)
| Status | Count |
|--------|-------|
| not_started | 3257 |
## Library Mappings (36 total)
| Status | Count |
|--------|-------|
| mapped | 36 |
## Overall Progress
**41/6942 items complete (0.6%)**