Files
natsnet/docs/plans/2026-02-27-batch-18-server-core-implementation-plan.md
Joseph Doherty dc3e162608 Add batch plans for batches 13-15, 18-22 (rounds 8-11)
Generated design docs and implementation plans via Codex for:
- Batch 13: FileStore Read/Query
- Batch 14: FileStore Write/Lifecycle
- Batch 15: MsgBlock + ConsumerFileStore
- Batch 18: Server Core
- Batch 19: Accounts Core
- Batch 20: Accounts Resolvers
- Batch 21: Events + MsgTrace
- Batch 22: Monitoring

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

457 lines
17 KiB
Markdown

# Batch 18 (Server Core) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 18 server-core behavior from `server/server.go` across 10 features and 8 tests without placeholder logic or fake-pass tests.
**Architecture:** Execute in two feature groups (6 + 4 IDs) mapped to `NatsServer` partial files, then run two test waves: real behavioral tests first, benchmark/race viability triage second. Promote tracker statuses only with build/test/stub-scan evidence.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
---
I'm using `writeplan` to create the implementation plan.
**Design doc:** `docs/plans/2026-02-27-batch-18-server-core-design.md`
## Batch Inputs
- Batch: `18` (`Server Core`)
- Depends on: `4`, `16`
- Features: `10`
- Tests: `8`
- Go source focus: `golang/nats-server/server/server.go`
Feature groups (max ~20 each):
- **Group A (6):** `2982,2987,3066,3068,3078,3119`
- **Group B (4):** `3048,3088,3112,3118`
Test groups:
- **T1 (behavioral ports):** `2111,2819,2897`
- **T2 (benchmark/race triage):** `2167,2382,2467,2468,2481`
> If `dotnet` is not on `PATH`, use `/usr/local/share/dotnet/dotnet` in all commands below.
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** Every feature/test status change in Batch 18 must satisfy this protocol.
### Per-Feature Verification Loop (REQUIRED for every feature ID)
1. Read tracker mapping and Go location:
```bash
dotnet run --project tools/NatsNet.PortTracker -- feature show <FEATURE_ID> --db porting.db
```
2. Read the exact Go implementation in `golang/nats-server/server/server.go` at mapped lines.
3. Write behavior-faithful C# code in the mapped `NatsServer` partial file.
4. Build immediately:
```bash
dotnet build dotnet/
```
5. Run related tests (targeted filter):
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<RelatedClassOrMethod>" --verbosity normal
```
6. Confirm tests were discovered (`Passed` > 0 when expected) and `Failed: 0`.
7. Only then add that feature ID to the verified-candidate list.
### Stub Detection Check (REQUIRED after every feature/test group)
Run all scans before any `complete` or `verified` promotion:
```bash
# Feature-code stubs
grep -R -n -E "NotImplementedException|TODO|PLACEHOLDER" \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs
# Empty method-body detector in feature files touched by Batch 18
grep -R -n -E "^[[:space:]]*(public|internal|private|protected)[^{;]*\)[[:space:]]*\{[[:space:]]*\}$" \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs
# Test stubs + fake-pass patterns
grep -R -n -E "NotImplementedException|Assert\.True\(true\)|Assert\.Pass|// TODO|// PLACEHOLDER|ShouldContain\(\"Should\"\)|ShouldStartWith\(\"server/\"\)" \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog
```
Any new hit in touched files blocks promotion until fixed or explicitly deferred.
### Build Gate (REQUIRED after each feature group)
```bash
dotnet build dotnet/
```
Required: `0` errors.
### Test Gate (REQUIRED before marking features `verified`)
All related tests for the feature group must pass before `complete -> verified`:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ServerTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ServerLifecycleStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog.MonitoringHandlerTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog.RouteHandlerTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog.NatsServerTests" --verbosity normal
```
Required: `Failed: 0` and non-trivial execution for changed scenarios.
### Status Update Protocol (REQUIRED)
1. Maximum **15 IDs per `feature batch-update` or `test batch-update` call**.
2. Evidence required per update chunk:
- Go source reviewed for each ID.
- Build gate passed.
- Related tests passed.
- Stub scan clean.
3. No blind promotion:
- Features: `deferred -> stub -> complete -> verified`.
- Tests: `deferred -> stub -> verified` (or `deferred/n_a` with explicit reason).
4. If Roslyn audit disagrees, require explicit override reason.
### Checkpoint Protocol Between Tasks (REQUIRED)
After each task (and before the next):
1. Full build:
```bash
dotnet build dotnet/
```
2. Full unit-test pass:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Verify no new regressions.
4. Commit checkpoint:
```bash
git add <touched-files> porting.db
git commit -m "<checkpoint message>"
```
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
### Forbidden Patterns
Do not introduce or keep any of these in Batch 18 scope:
- `throw new NotImplementedException(...)`
- `// TODO` or `// PLACEHOLDER` in executable Batch 18 paths
- Empty method bodies (`{ }`) for mapped Batch 18 features
- Tests that only assert constants/labels (for example `"...ShouldSucceed".ShouldContain("Should")`)
- Tests that never execute target server behavior (no real Arrange/Act against `NatsServer`)
- Fake wrappers that ignore inputs and always return success values
### Hard Limits
- Max ~20 feature IDs per implementation task group (Batch 18 uses `6` and `4`)
- Max 15 IDs per status-update command
- No status promotion without clean stub scan + build gate + test gate
- No cross-group status updates until current group is fully verified/deferred
- Mandatory commit at each checkpoint
### If You Get Stuck
1. Stop on the blocked item; do not add a stub workaround.
2. Do **not** write fake-pass tests or no-op implementations.
3. Mark the exact ID as `deferred` (or `n_a` for benchmark-only items) with specific reason:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update <ID> --status deferred --db porting.db \
--override "blocked: <specific infra/dependency reason>"
```
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update <ID> --status deferred --db porting.db \
--override "blocked: <specific infra/dependency reason>"
```
4. Continue with the next unblocked ID.
---
### Task 1: Preflight and Batch Activation
**Files:**
- Modify: `porting.db`
**Step 1: Confirm dependency readiness and batch contents**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch show 18 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
```
**Step 2: Start batch**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch start 18 --db porting.db
```
**Step 3: Move Group A features to `stub` (<=15 IDs)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2982,2987,3066,3068,3078,3119" \
--set-status stub --db porting.db --execute
```
**Step 4: Commit checkpoint**
```bash
git add porting.db
git commit -m "chore(batch18): start batch and stage group-a features"
```
### Task 2: Group A Features (6) - Compression/TLS/Monitoring/Goroutine Labels
**Feature IDs:** `2982,2987,3066,3068,3078,3119`
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Init.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Listeners.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ServerTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs`
**Step 1: Add/extend failing tests for Group A behavior**
Target behaviors:
- S2 writer-option mapping behavior (`s2WriterOptions`).
- TLS rejection log loop cadence and warning behavior.
- Monitoring TLS config clone + `ClientAuth` override.
- `HTTPHandler` returns non-null while monitor is active and null after shutdown.
- TLS handshake timeout closure path.
- Goroutine label helper invoked by task start path (or explicit helper test if direct validation is feasible).
**Step 2: Run focused tests and confirm failures first**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ServerTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog.MonitoringHandlerTests" --verbosity normal
```
**Step 3: Implement Group A methods with per-feature loop**
For each of the 6 feature IDs: read Go -> implement -> build -> run related tests.
**Step 4: Run mandatory stub detection + build gate + test gate**
Use protocol commands above.
**Step 5: Promote Group A feature statuses (`complete`, then `verified`)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2982,2987,3066,3068,3078,3119" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2982,2987,3066,3068,3078,3119" \
--set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Init.cs \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Listeners.cs \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ServerTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs \
porting.db
git commit -m "feat(batch18): implement group-a server core helpers"
```
### Task 3: Group B Features (4) - Accounts/Readiness/Introspection
**Feature IDs:** `3048,3088,3112,3118`
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Accounts.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/ServerLifecycleStubFeaturesTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`
**Step 1: Write/extend failing tests for Group B behavior**
Target behaviors:
- Account fetch path parity (`fetchAccount` wrapper/behavior alignment).
- Internal `numRemotes` path parity under lock.
- `readyForConnections` path parity for listener checks and timeout errors.
- `String()` / `ToString()` parity on server identity.
**Step 2: Run focused tests and confirm failures first**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ServerLifecycleStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog.RouteHandlerTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog.NatsServerTests" --verbosity normal
```
**Step 3: Implement Group B methods with per-feature loop**
For each of the 4 feature IDs: read Go -> implement -> build -> run related tests.
**Step 4: Run mandatory stub detection + build gate + test gate**
Use protocol commands above.
**Step 5: Promote Group B feature statuses (`complete`, then `verified`)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3048,3088,3112,3118" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3048,3088,3112,3118" \
--set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Accounts.cs \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/ServerLifecycleStubFeaturesTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs \
porting.db
git commit -m "feat(batch18): implement group-b server core helpers"
```
### Task 4: Test Group T1 (Behavioral Tests) - Verify 3 Tests
**Test IDs:** `2111,2819,2897`
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: For each test ID, read mapping + Go source and port behavior intent**
```bash
dotnet run --project tools/NatsNet.PortTracker -- test show <TEST_ID> --db porting.db
```
**Step 2: Run each test method individually (must execute and pass)**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<MappedClass>.<MappedMethod>" --verbosity normal
```
**Step 3: Run class-level validation for touched classes**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog.MonitoringHandlerTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog.RouteHandlerTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog.NatsServerTests" --verbosity normal
```
**Step 4: Update T1 tests in one chunk (<=15 IDs)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2111,2819,2897" --set-status verified --db porting.db --execute
```
**Step 5: Checkpoint protocol + commit**
```bash
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs \
porting.db
git commit -m "test(batch18): port behavioral batch-18 tests"
```
### Task 5: Test Group T2 (Benchmark/Race Triage) - Resolve 5 Tests Without Stubs
**Test IDs:** `2167,2382,2467,2468,2481`
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MqttExternalTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests2.Impltests.cs`
- Modify: `porting.db`
**Step 1: Evaluate each Go test for xUnit viability**
- `2167` is a Go benchmark (`BenchmarkXMQTT`): classify as `n_a` unless a benchmark harness is explicitly introduced.
- Norace wrapper tests (`2382,2467,2468,2481`): verify whether meaningful deterministic unit assertions can be ported.
**Step 2: For viable tests, implement and verify with single-test execution**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ImplBacklog.ConcurrencyTests" --verbosity normal
```
**Step 3: For non-viable tests, set `deferred` or `n_a` with concrete reasons**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update 2167 --status n_a --db porting.db \
--override "BenchmarkXMQTT is benchmark-only and not an xUnit unit-test target"
```
(Repeat for remaining blocked IDs with specific blocker text.)
**Step 4: Run stub scan and checkpoint protocol, then commit**
```bash
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MqttExternalTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests2.Impltests.cs \
porting.db
git commit -m "test(batch18): triage benchmark and norace mapped tests"
```
### Task 6: Final Batch 18 Verification and Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md`
**Step 1: Final full verification**
```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
**Step 2: Batch-wide stub audit**
```bash
grep -R -n -E "NotImplementedException|TODO|PLACEHOLDER|Assert\.True\(true\)|Assert\.Pass|ShouldContain\(\"Should\"\)" \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog
```
**Step 3: Validate batch status and close**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch show 18 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- batch complete 18 --db porting.db
```
**Step 4: Refresh reports and final commit**
```bash
./reports/generate-report.sh
git add porting.db reports/
git commit -m "chore(batch18): complete server-core batch with verified evidence"
```