Add batch plans for batches 1-5 and 8 (rounds 1-3)

Generated design docs and implementation plans via Codex for:
- Batch 1: Proto, Const, CipherSuites, NKey, JWT
- Batch 2: Parser, Sublist, MemStore remainders
- Batch 3: SendQ, Service, Client ProxyProto
- Batch 4: Logging
- Batch 5: JetStream Errors
- Batch 8: Store Interfaces

All plans include mandatory verification protocol and anti-stub guardrails.
Updated batches.md with file paths and planned status.
This commit is contained in:
Joseph Doherty
2026-02-27 14:11:29 -05:00
parent f98e33457f
commit b928be4f2f
15 changed files with 3784 additions and 8 deletions

View File

@@ -14,15 +14,15 @@
| Batch # | Batch Name | Design File | Plan File | Status |
|---------|------------|-------------|-----------|--------|
| 0 | Implementable Tests | | | not_planned |
| 1 | Proto, Const, CipherSuites, NKey, JWT | | | not_planned |
| 2 | Parser, Sublist, MemStore remainders | | | not_planned |
| 3 | SendQ, Service, Client ProxyProto | | | not_planned |
| 4 | Logging | | | not_planned |
| 5 | JetStream Errors | | | not_planned |
| 0 | Implementable Tests | [design](plans/2026-02-27-batch-0-implementable-tests-design.md) | [plan](plans/2026-02-27-batch-0-implementable-tests-plan.md) | planned |
| 1 | Proto, Const, CipherSuites, NKey, JWT | [design](plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-design.md) | [plan](plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-plan.md) | planned |
| 2 | Parser, Sublist, MemStore remainders | [design](plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-design.md) | [plan](plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-plan.md) | planned |
| 3 | SendQ, Service, Client ProxyProto | [design](plans/2026-02-27-batch-3-sendq-service-client-proxyproto-design.md) | [plan](plans/2026-02-27-batch-3-sendq-service-client-proxyproto-plan.md) | planned |
| 4 | Logging | [design](plans/2026-02-27-batch-4-logging-design.md) | [plan](plans/2026-02-27-batch-4-logging-plan.md) | planned |
| 5 | JetStream Errors | [design](plans/2026-02-27-batch-5-jetstream-errors-design.md) | [plan](plans/2026-02-27-batch-5-jetstream-errors-plan.md) | planned |
| 6 | Opts package-level functions | | | not_planned |
| 7 | Opts class methods + Reload | | | not_planned |
| 8 | Store Interfaces | | | not_planned |
| 8 | Store Interfaces | [design](plans/2026-02-27-batch-8-store-interfaces-design.md) | [plan](plans/2026-02-27-batch-8-store-interfaces-plan.md) | planned |
| 9 | Auth, DirStore, OCSP foundations | | | not_planned |
| 10 | OCSP Cache + JS Events | | | not_planned |
| 11 | FileStore Init | | | not_planned |

View File

@@ -0,0 +1,125 @@
# Batch 1 (Proto, Const, CipherSuites, NKey, JWT) Design
**Date:** 2026-02-27
**Scope:** Design only for implementing Batch 1 feature ports (10 features, 0 tracked tests).
## Context Snapshot
Batch metadata (from `porting.db`):
- Batch ID: `1`
- Name: `Proto, Const, CipherSuites, NKey, JWT`
- Features: `10`
- Tests: `0`
- Dependencies: none
- Go files: `server/ciphersuites.go`, `server/const.go`, `server/jwt.go`, `server/nkey.go`, `server/proto.go`
Feature IDs in this batch:
- `384` `init` -> `CipherSuites.Init`
- `583` `init` -> `ServerConstants.Init`
- `1975` `wipeSlice` -> `JwtProcessor.WipeSlice`
- `2441` `Server.nonceRequired` -> `NatsServer.NonceRequiredInternal`
- `2593` `protoScanField` -> `ProtoWire.ProtoScanField`
- `2594` `protoScanTag` -> `ProtoWire.ProtoScanTag`
- `2595` `protoScanFieldValue` -> `ProtoWire.ProtoScanFieldValue`
- `2596` `protoScanVarint` -> `ProtoWire.ProtoScanVarint`
- `2597` `protoScanBytes` -> `ProtoWire.ProtoScanBytes`
- `2598` `protoEncodeVarint` -> `ProtoWire.ProtoEncodeVarint`
## Current Code Findings
1. `CipherSuites` and `ServerConstants` use static constructors, but no explicit `Init()` method exists.
2. `JwtProcessor.WipeSlice` does not exist; `AuthHandler.WipeSlice` exists.
3. `NatsServer.NonceRequiredInternal` does not exist; `NonceRequired()` exists and is currently stubbed to `false`.
4. `ProtoWire` behavior is largely implemented, but method names are currently `Scan*` / `EncodeVarint`, not `ProtoScan*` / `ProtoEncodeVarint` mapped in Batch 1.
5. There are existing tests for `CipherSuites` and `JwtProcessor`, but no dedicated `ProtoWire` tests and no direct nonce-requirement tests.
## Goals
- Deliver full behavioral parity for the 10 Batch 1 features.
- Align implementation names/signatures with tracker mappings so Roslyn audit can classify features correctly.
- Add/extend tests where needed so features can be verified from evidence, not by assumption.
## Non-Goals
- No broader auth/JWT full claim-validation implementation beyond this batch's mapped functions.
- No batch execution/status updates in this design document.
- No unrelated refactors.
## Approaches
### Approach A: Tracker-name wrappers only (minimal)
Implement only mapped method names as wrappers around current code; avoid deeper behavior changes.
- Pros: Fastest; lowest risk of regressions.
- Cons: Could preserve existing behavioral drift (for example nonce logic), leaving hidden parity gaps.
### Approach B: Full rename + strict parity rewrite
Rename existing methods to exact Go-style mapped names and reshape internals to match Go structure exactly.
- Pros: Maximum parity and audit friendliness.
- Cons: Higher churn and avoidable breakage risk for existing callers/tests.
### Approach C (Recommended): Hybrid parity + compatibility
Add mapped methods required by Batch 1 while preserving current call surfaces via wrappers or forwards, then close behavior gaps and strengthen tests.
- Pros: Satisfies audit mapping and behavior with limited churn.
- Cons: Slightly more code than Approach A.
## Recommended Design
### 1. API + Audit Alignment Layer
- Add explicit `Init()` methods for `CipherSuites` and `ServerConstants` (idempotent warm-up semantics).
- Add `JwtProcessor.WipeSlice(Span<byte>)` and keep compatibility with existing usages.
- Add `NatsServer.NonceRequiredInternal()` (lock-held semantics) and call it from `NonceRequired()`.
- Add `ProtoWire.ProtoScan*` / `ProtoEncodeVarint` methods; keep existing `Scan*` / `EncodeVarint` as forwarding aliases if needed.
### 2. Behavior Parity Layer
- Ensure nonce requirement logic matches Go intent:
- `AlwaysEnableNonce`
- configured nkeys present
- trusted keys present
- proxy key pairs present
- Ensure proto varint and field scanners keep existing overflow/insufficient-data behavior at boundaries.
### 3. Verification Layer (Test-first)
- Extend existing tests:
- `Auth/CipherSuitesTests.cs`
- `Auth/JwtProcessorTests.cs`
- `ServerTests.cs` (or a dedicated nonce test file)
- Add new focused tests for `ProtoWire` in `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs`.
- Keep xUnit 3 + Shouldly + NSubstitute only.
### 4. PortTracker Status Discipline
- Move features through `stub -> complete -> verified` only after build + test evidence.
- Use max 15 IDs per batch status update.
- Store command output evidence in commit/task notes before updates.
## Risks and Mitigations
1. **Audit false negatives due naming mismatch**
Mitigation: implement mapped method names explicitly (`Init`, `WipeSlice`, `NonceRequiredInternal`, `Proto*`).
2. **Regressions from changing existing method names**
Mitigation: prefer additive wrappers and keep old names temporarily where already referenced.
3. **Undertested low-level protobuf boundaries**
Mitigation: dedicated boundary tests for 1..10-byte varint decode and overflow paths.
4. **Stub creep under schedule pressure**
Mitigation: mandatory stub scans and hard gates in the implementation plan.
## Success Criteria
- All 10 Batch 1 features are implemented with mapped method presence and intended behavior.
- Related tests pass and include explicit coverage for nonce logic and proto wire helpers.
- No placeholder implementations (`NotImplementedException`, TODO stubs, empty methods) in touched feature/test files.
- Batch 1 status can be advanced using evidence-based verification.

View File

@@ -0,0 +1,484 @@
# Batch 1 (Proto, Const, CipherSuites, NKey, JWT) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify all 10 Batch 1 feature mappings with audit-aligned method names and behavior-faithful .NET parity.
**Architecture:** Use a hybrid compatibility approach: add/align mapped methods required by PortTracker (`Init`, `WipeSlice`, `NonceRequiredInternal`, `Proto*`) while preserving existing callers via wrappers where needed. Execute in four feature groups with strict per-feature red/green loops, then close the batch via evidence-backed status updates.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-design.md`
---
## Batch 1 Working Set
Feature groups (max group size <= 20 features):
- **Group A (2 features):** `384`, `583`
- **Group B (2 features):** `1975`, `2441`
- **Group C (5 features):** `2593`, `2594`, `2595`, `2596`, `2597`
- **Group D (1 feature):** `2598`
Batch facts:
- Total features: `10`
- Total tracked tests: `0`
- Dependency batches: none
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** every feature in this batch must pass this loop before status advancement.
### What Counts as a Real Feature Verification
A feature is eligible for `verified` only when all are true:
1. Mapped .NET method exists on mapped class (`dotnet_class`.`dotnet_method`).
2. Behavior matches Go intent for the mapped function.
3. Related tests execute and pass (not merely discovered as zero tests).
4. No stub markers remain in touched feature/test files.
5. Build is green after the feature group.
### Per-Feature Verification Loop (REQUIRED for each feature ID)
1. Read exact Go source range from tracker mapping.
2. Write or adjust C# implementation in mapped class/method.
3. Write or update a focused test that exercises the behavior.
4. Run focused test(s):
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<ClassName>.<MethodOrScenario>" --verbosity normal
```
5. Verify summary shows at least 1 executed test and 0 failures.
6. Run build gate (`dotnet build dotnet/`) before promoting group statuses.
### Stub Detection Check (REQUIRED after each feature group)
Run against touched source and tests:
```bash
rg -n "NotImplementedException|throw new NotSupportedException\(" dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests
rg -n "TODO|PLACEHOLDER|Assert\.True\(true\)|Assert\.Pass\(|ShouldBe\(true\);$|^\s*\{\s*\}$" dotnet/tests/ZB.MOM.NatsNet.Server.Tests
```
Any hit in edited files blocks status updates until fixed or explicitly deferred.
### Build Gate (REQUIRED after each feature group)
```bash
dotnet build dotnet/
```
Required: build succeeds with 0 errors.
### Test Gate (REQUIRED before marking any feature `verified`)
- Run all related test classes for the group (existing + newly added).
- For this batch, related classes include at minimum:
- `ZB.MOM.NatsNet.Server.Tests.Auth.CipherSuitesTests`
- `ZB.MOM.NatsNet.Server.Tests.Auth.JwtProcessorTests`
- `ZB.MOM.NatsNet.Server.Tests.Auth.JwtProcessorOperatorTests`
- `ZB.MOM.NatsNet.Server.Tests.ServerTests` (or dedicated nonce test class)
- `ZB.MOM.NatsNet.Server.Tests.Internal.ProtoWireTests` (new)
Run pattern:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~<ClassName>" --verbosity normal
```
Required: all related class runs pass with `Failed: 0`.
### Status Update Protocol
- Use max 15 IDs per `feature batch-update` command.
- Never set `verified` without captured build + test evidence.
- Status flow per feature: `deferred/not_started -> stub -> complete -> verified`.
- Record evidence per update chunk (command + pass summary + files touched).
Commands (chunk size max 15):
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<ids>" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<ids>" --set-status verified --db porting.db --execute
```
If audit rejects a valid status, re-run with explicit reason:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status verified --db porting.db --override "manual verification evidence: <short reason>"
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each task group (A/B/C/D), before starting the next:
1. Full build:
```bash
dotnet build dotnet/
```
2. Full unit test suite:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Confirm total summary is stable and no new failures introduced.
4. Commit the group before moving on.
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
### Forbidden Patterns
The following are forbidden in touched feature or test code:
- `throw new NotImplementedException()`
- Empty method bodies used as placeholders
- `TODO`, `PLACEHOLDER`, or similar deferred markers without status deferral
- Fake-pass tests (`Assert.True(true)`, `Assert.Pass()`, meaningless single assert)
- Dummy return values used to bypass behavior (`return default`, `return null`) without Go-equivalent logic
### Hard Limits
- Max `15` IDs per status update command.
- Max `1` feature group promoted per verification cycle.
- Mandatory build + related test evidence before `verified`.
- Mandatory checkpoint commit after each group.
### If You Get Stuck
Do **not** stub.
1. Leave/return feature status as `deferred`.
2. Add explicit tracker override reason describing the concrete blocker.
3. Commit only proven work.
4. Continue with next unblocked feature in the current group.
Example:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status deferred --db porting.db --override "blocked: <specific runtime or API gap>"
```
---
### Task 1: Group A - Init Parity (Features 384, 583)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/CipherSuites.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerConstants.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/CipherSuitesTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ServerTests.cs` (or add focused constants test file)
**Step 1: Mark feature IDs as in-progress (`stub`)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "384,583" --set-status stub --db porting.db --execute
```
**Step 2: Write failing tests for explicit init hooks**
Add tests asserting `CipherSuites.Init()` and `ServerConstants.Init()` are callable and idempotent.
**Step 3: Run focused tests and confirm FAIL**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~CipherSuitesTests" --verbosity normal
```
**Step 4: Implement minimal production code to pass**
Add explicit mapped methods:
- `CipherSuites.Init()`
- `ServerConstants.Init()`
Both must be idempotent and preserve existing behavior.
**Step 5: Re-run focused tests and confirm PASS**
Run both related classes and confirm zero failures.
**Step 6: Run mandatory stub scan + build gate**
Use the protocol commands above.
**Step 7: Promote statuses with evidence**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "384,583" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "384,583" --set-status verified --db porting.db --execute
```
**Step 8: Checkpoint (full build + full unit tests + commit)**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/Auth/CipherSuites.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ServerConstants.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/CipherSuitesTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ServerTests.cs \
porting.db
git commit -m "feat(batch1): add init parity hooks for ciphers and constants"
```
---
### Task 2: Group B - JWT + NKey Nonce Helpers (Features 1975, 2441)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/JwtProcessor.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Listeners.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/AuthHandler.cs` (only if retaining compatibility wrapper)
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/JwtProcessorTests.cs`
- Modify/Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/NonceRequiredTests.cs` (or equivalent in `ServerTests.cs`)
**Step 1: Mark IDs as `stub`**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "1975,2441" --set-status stub --db porting.db --execute
```
**Step 2: Write failing tests**
- `JwtProcessor.WipeSlice` fills buffer with `'x'`.
- `NonceRequiredInternal` returns true for each Go condition and false otherwise.
**Step 3: Run focused tests and confirm FAIL**
Run `JwtProcessorTests` and nonce-focused tests.
**Step 4: Implement minimal code**
- Add `JwtProcessor.WipeSlice(Span<byte>)` and route existing call sites as needed.
- Implement `NatsServer.NonceRequiredInternal()` using:
- `GetOpts().AlwaysEnableNonce`
- `_nkeys?.Count > 0`
- `_trustedKeys != null`
- `_proxiesKeyPairs.Count > 0`
**Step 5: Re-run focused tests and confirm PASS**
**Step 6: Stub scan + build gate**
**Step 7: Promote statuses**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "1975,2441" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "1975,2441" --set-status verified --db porting.db --execute
```
**Step 8: Checkpoint + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/Auth/JwtProcessor.cs \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Listeners.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Auth/AuthHandler.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/JwtProcessorTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/NonceRequiredTests.cs \
porting.db
git commit -m "feat(batch1): implement jwt wipe and nonce-required internal logic"
```
---
### Task 3: Group C - Proto Scan Helpers (Features 2593-2597)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs`
**Step 1: Mark IDs as `stub`**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2593,2594,2595,2596,2597" --set-status stub --db porting.db --execute
```
**Step 2: Write failing tests for mapped scan methods**
Cover:
- valid/invalid tag decode
- unsupported wire type error
- insufficient data behavior
- overflow behavior in varint decode
- length-delimited size behavior
**Step 3: Run focused tests and confirm FAIL**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtoWireTests" --verbosity normal
```
**Step 4: Implement minimal mapped methods**
Add mapped methods:
- `ProtoScanField`
- `ProtoScanTag`
- `ProtoScanFieldValue`
- `ProtoScanVarint`
- `ProtoScanBytes`
Use existing logic or direct forwards without changing behavior.
**Step 5: Re-run ProtoWire tests and confirm PASS**
**Step 6: Stub scan + build gate**
**Step 7: Promote statuses**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2593,2594,2595,2596,2597" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2593,2594,2595,2596,2597" --set-status verified --db porting.db --execute
```
**Step 8: Checkpoint + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs \
porting.db
git commit -m "feat(batch1): add mapped proto scan helpers with boundary tests"
```
---
### Task 4: Group D - Proto Varint Encode (Feature 2598)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs`
**Step 1: Mark ID as `stub`**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update 2598 --status stub --db porting.db
```
**Step 2: Write failing tests for `ProtoEncodeVarint` boundaries**
Cover `1<<7`, `1<<14`, ..., `1<<63` edges and encode/decode round-trip with `ProtoScanVarint`.
**Step 3: Run focused tests and confirm FAIL**
**Step 4: Implement minimal code**
Add `ProtoEncodeVarint` mapped method (forward or primary implementation) with 10-byte max semantics matching Go.
**Step 5: Re-run focused tests and confirm PASS**
**Step 6: Stub scan + build gate**
**Step 7: Promote status**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update 2598 --status complete --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- \
feature update 2598 --status verified --db porting.db
```
**Step 8: Checkpoint + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs \
porting.db
git commit -m "feat(batch1): implement proto varint encoder parity"
```
---
### Task 5: Batch 1 Final Verification and Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md` (optional at end of batch)
**Step 1: Full regression gates**
```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
Required: `Failed: 0`.
**Step 2: Final stub audit on touched files**
```bash
rg -n "NotImplementedException|TODO|PLACEHOLDER|Assert\.True\(true\)|Assert\.Pass\(" \
dotnet/src/ZB.MOM.NatsNet.Server/Auth/CipherSuites.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ServerConstants.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Auth/JwtProcessor.cs \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Listeners.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/CipherSuitesTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/JwtProcessorTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/NonceRequiredTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs
```
Required: no matches.
**Step 3: Audit feature mapping resolution**
```bash
dotnet run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db
```
If dry-run is clean, apply:
```bash
dotnet run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db --execute
```
**Step 4: Close batch**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch complete 1 --db porting.db
```
**Step 5: Report + final commit**
```bash
./reports/generate-report.sh
git add dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests \
porting.db reports/current.md
git commit -m "feat(batch1): complete proto/const/ciphers/nkey/jwt feature set"
```

View File

@@ -0,0 +1,127 @@
# Batch 2 (Parser, Sublist, MemStore remainders) Design
**Date:** 2026-02-27
**Scope:** Design only for implementing and verifying Batch 2 feature ports (8 features, 0 tracked tests).
## Context Snapshot
Batch metadata (from `porting.db`):
- Batch ID: `2`
- Name: `Parser, Sublist, MemStore remainders`
- Features: `8`
- Tests: `0`
- Dependencies: `Batch 1`
- Go files: `server/memstore.go`, `server/parser.go`, `server/sublist.go`
Feature IDs in this batch:
- `2068` `newMemStore` -> `JetStreamMemStore.NewMemStore`
- `2086` `memStore.allLastSeqsLocked` -> `JetStreamMemStore.AllLastSeqsLocked`
- `2588` `client.parse` -> `ClientConnection.Parse`
- `2590` `client.overMaxControlLineLimit` -> `ClientConnection.OverMaxControlLineLimit`
- `2591` `client.clonePubArg` -> `ClientConnection.ClonePubArg`
- `3446` `level.pruneNode` -> `Level.PruneNode`
- `3447` `node.isEmpty` -> `Node.IsEmpty`
- `3448` `level.numNodes` -> `Level.NumNodes`
## Current Code Findings
1. Parser behavior exists in `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs`:
- `Parse` at line 36
- `OverMaxControlLineLimit` at line 781
- `ClonePubArg` at line 1096
2. `JetStreamMemStore` has constructor parity for `newMemStore` and `AllLastSeqs` behavior in `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MemStore.cs` (constructor line 81, `AllLastSeqs` line 1131).
3. Sublist helper behavior exists in both data-structure implementations:
- `SubscriptionIndex.cs` nested node/level helpers (`IsEmpty`, `NumNodes`, `PruneNode`)
- `GenericSublist.cs` trie helper equivalents (`IsEmpty`, `NumNodes`, `PruneNode`)
4. Existing test coverage already targets these areas:
- `Protocol/ProtocolParserTests.cs`
- `JetStream/JetStreamMemoryStoreTests.cs`
- `JetStream/StorageEngineTests.cs`
- `Internal/DataStructures/SubscriptionIndexTests.cs`
- `Internal/DataStructures/GenericSublistTests.cs`
5. Relevant files still contain unrelated TODO/stub markers; Batch 2 execution must prevent introducing any new stubs while tolerating pre-existing untouched markers.
## Assumptions
- Batch 1 dependency must be completed before Batch 2 status updates.
- Existing mapped behavior may be mostly implemented; Batch 2 likely requires a mix of parity fixes plus evidence-backed verification/status promotion.
- Because Batch 2 tracks 0 tests, verification must rely on related existing unit tests outside the batch.
## Approaches
### Approach A: Status-first verification only
Run related tests and update statuses if green; avoid code edits unless tests fail.
- Pros: Lowest churn, fast throughput.
- Cons: Risks hiding tracker/mapping drift or subtle behavior gaps not directly asserted.
### Approach B: Full parser/sublist/memstore rewrite for strict Go shape
Refactor methods and class placement to mirror Go structure exactly.
- Pros: Maximum structural parity.
- Cons: High regression risk and unnecessary code churn for a remainder batch.
### Approach C (Recommended): Hybrid parity hardening + evidence-driven status progression
Start with feature-by-feature verification loops; only add minimal targeted code/tests when a feature lacks direct proof or behavior diverges.
- Pros: Balances correctness, audit alignment, and delivery speed.
- Cons: Requires disciplined evidence collection and strict guardrails to avoid shallow verification.
## Recommended Design
### 1. Feature-Group Execution Model
Split Batch 2 into three groups:
- Parser group: `2588`, `2590`, `2591`
- Sublist group: `3446`, `3447`, `3448`
- MemStore group: `2068`, `2086`
Each group is implemented/verified independently with build and test gates before any status promotion.
### 2. Verification-First Feature Loop
For each feature:
1. Read mapped Go source range (`feature show <id>` + source file lines).
2. Confirm or implement C# parity in mapped target area.
3. Run focused related tests.
4. Run group-level build + test gates.
5. Only then promote statuses (`stub -> complete -> verified`) with evidence.
### 3. Mapping Drift Handling
If tracker expects a method shape that differs from existing .NET placement (for example parser methods under `ProtocolParser` instead of `ClientConnection`), use minimal compatibility wrappers or forwarding methods only when required by behavior/audit proof. Avoid broad refactors.
### 4. Evidence and Guardrails
- Mandatory stub scans on touched files after each group.
- Build gate after each group.
- Related test class gates before `verified`.
- Full checkpoint (build + full unit tests + commit) between tasks.
## Risks and Mitigations
1. **False confidence from pre-existing tests**
Mitigation: require per-feature evidence and add focused tests when a feature lacks direct assertions.
2. **Stub creep in large files**
Mitigation: baseline-plus-delta stub scan and hard failure on new markers.
3. **Over-refactoring for naming alignment**
Mitigation: additive wrappers only; preserve stable call paths.
4. **Status updates without proof**
Mitigation: enforce max-15 ID updates and attach command output evidence before promotion.
## Success Criteria
- All 8 Batch 2 features are implemented or confirmed behaviorally complete against Go intent.
- All related test gates pass for parser, sublist, and memstore areas.
- No new stub patterns are introduced in touched source or tests.
- Batch 2 feature statuses can be advanced to `verified` with explicit evidence and dependency compliance.

View File

@@ -0,0 +1,454 @@
# Batch 2 (Parser, Sublist, MemStore remainders) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify all 8 Batch 2 features with Go-parity behavior and evidence-backed status promotion to `verified`.
**Architecture:** Execute Batch 2 in three feature groups (parser, sublist, memstore). For each feature, run a strict verify-first loop: read Go source, implement/adjust minimal C# parity, run focused tests, then pass group build/test gates before any status updates. Use additive compatibility methods only if mapping alignment requires them.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-design.md`
---
## Batch 2 Working Set
Feature groups (max group size <= 20 features):
- **Group A (3 features):** `2588`, `2590`, `2591`
- **Group B (3 features):** `3446`, `3447`, `3448`
- **Group C (2 features):** `2068`, `2086`
Batch facts:
- Total features: `8`
- Total tracked tests in batch: `0`
- Required dependency: `Batch 1`
- Related Go files: `server/parser.go`, `server/sublist.go`, `server/memstore.go`
> If `dotnet` is not on PATH, use `/usr/local/share/dotnet/dotnet` for all commands in this plan.
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** Every feature in this batch must pass this protocol before status advancement.
### What Counts as Real Feature Verification
A feature is eligible for `verified` only when all are true:
1. Mapped behavior is confirmed against the referenced Go implementation.
2. .NET implementation exists and executes without placeholder logic.
3. Related tests execute (non-zero discovered) and pass.
4. Group build gate is green after the feature changes.
5. Stub scans on touched files are clean for new/edited code.
### Per-Feature Verification Loop (REQUIRED for every feature ID)
1. Read Go source for the feature (`feature show <id>` then open referenced lines in Go file).
2. Implement or adjust C# in mapped target files.
3. Run a focused build and tests for that feature area.
4. Confirm test discovery is non-zero and failures are zero.
5. Add feature ID to the group verification evidence list only after green results.
Template loop command set:
```bash
# Inspect mapping
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db
# Build check after feature change
/usr/local/share/dotnet/dotnet build dotnet/
# Run focused related tests
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<RelatedTestClass>" --verbosity normal
```
### Stub Detection Check (REQUIRED after each feature group)
Run on changed source + test files before status updates.
```bash
# Placeholder markers
rg -n "NotImplementedException|TODO|PLACEHOLDER" \
dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests
# Empty method bodies (single-line and compact multiline forms)
rg -nUP "(public|private|internal|protected)\\s+[^\\{;]+\\)\\s*\\{\\s*\\}" \
dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests
# Guard against newly introduced stubs in this change set
git diff -- dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests | \
rg -n "^\+.*(NotImplementedException|TODO|PLACEHOLDER|Assert\\.True\\(true\\)|ShouldBe\\(true\\);)"
```
Any new hit blocks status promotion.
### Build Gate (REQUIRED after each feature group)
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
Required: 0 errors.
### Test Gate (REQUIRED before marking any feature `verified`)
All related test classes for the current group must pass.
Group A (Parser):
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol.ProtocolParserTests" --verbosity normal
```
Group B (Sublist):
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Internal.DataStructures.SubscriptionIndexTests" --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Internal.DataStructures.GenericSublistTests" --verbosity normal
```
Group C (MemStore):
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.JetStream.JetStreamMemoryStoreTests" --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.JetStream.StorageEngineTests" --verbosity normal
```
### Status Update Protocol
- Max 15 IDs per `feature batch-update` call.
- No `verified` update without recorded evidence (Go mapping reviewed + build gate + related test gate + stub scan).
- Required status flow: `deferred/not_started -> stub -> complete -> verified`.
- Evidence required per update: command run, pass/fail summary, and files touched.
Commands (max 15 IDs per call):
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<ids>" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<ids>" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<ids>" --set-status verified --db porting.db --execute
```
If audit rejects an evidence-backed promotion:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status verified --db porting.db --override "manual verification evidence: <reason>"
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After completing each task group (A, B, C), before starting the next:
1. Full build:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
2. Full unit test run:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Confirm no new failures were introduced.
4. Commit group changes (including `porting.db`) before moving forward.
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
These rules apply to both feature code and any tests touched while implementing Batch 2.
### Forbidden Patterns
The following are forbidden in edited code:
- `throw new NotImplementedException()`
- Empty method bodies used as placeholders
- `TODO`, `PLACEHOLDER`, or equivalent unresolved markers
- Fake-pass test assertions (`Assert.True(true)`, `Assert.Pass()`, trivial sentinel asserts)
- Returning defaults/null purely to satisfy compile without Go-equivalent behavior
### Hard Limits
- Max `15` feature IDs per status update command.
- Max `1` feature group promoted per verification cycle.
- Mandatory build + related test gates before any `verified` update.
- Mandatory checkpoint commit between feature groups.
- No partial “verified” promotion for a group with unresolved failures.
### If You Get Stuck (REQUIRED behavior)
Do not stub and do not force fake pass behavior.
1. Leave the blocked feature as `deferred`.
2. Record concrete blocker reason using `--override`.
3. Continue with next unblocked feature in the same group.
4. Revisit blocked feature after prerequisite gap is resolved.
Example:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status deferred --db porting.db --override "blocked: <specific missing dependency/runtime precondition>"
```
---
### Task 1: Group A - Parser Remainders (`2588`, `2590`, `2591`)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs`
- Modify (only if mapping wrapper needed): `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs`
**Step 1: Mark parser feature IDs as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2588,2590,2591" --set-status stub --db porting.db --execute
```
**Step 2: Write/adjust failing parser tests first**
- Ensure explicit coverage for:
- `Parse` state-machine transitions and split-buffer behavior
- max-control-line enforcement by client kind
- `ClonePubArg` reparse paths for client/router/leaf branches
**Step 3: Run focused parser tests and confirm red/green progression**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal
```
**Step 4: Implement minimal production parity fixes**
- Align parser behavior with Go intent for the three mapped methods.
- Add compatibility forwarding only if needed for tracker mapping or call-site parity.
**Step 5: Re-run parser tests until all pass**
Use the same command from Step 3.
**Step 6: Run mandatory stub scan + build gate**
Use protocol commands above.
**Step 7: Promote parser features (`complete` then `verified`) with evidence**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2588,2590,2591" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2588,2590,2591" --set-status verified --db porting.db --execute
```
**Step 8: Run checkpoint protocol and commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs \
porting.db
git commit -m "feat(batch2): verify parser remainder features"
```
---
### Task 2: Group B - Sublist Node/Level Remainders (`3446`, `3447`, `3448`)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Internal/DataStructures/SubscriptionIndex.cs`
- Modify (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/Internal/DataStructures/GenericSublist.cs`
- Modify/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/DataStructures/SubscriptionIndexTests.cs`
- Modify/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/DataStructures/GenericSublistTests.cs`
**Step 1: Mark sublist feature IDs as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3446,3447,3448" --set-status stub --db porting.db --execute
```
**Step 2: Add/adjust failing tests first for pruning and node-count behavior**
- Ensure tests explicitly cover:
- pruning of wildcard and literal nodes
- empty-node evaluation for leaf/intermediate nodes
- node counting before/after remove cleanup
**Step 3: Run focused sublist test classes**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~SubscriptionIndexTests" --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~GenericSublistTests" --verbosity normal
```
**Step 4: Implement minimal parity fixes in data structures**
- Update only helpers directly related to `PruneNode`, `IsEmpty`, `NumNodes` behavior.
- Keep public API stable unless mapping compatibility requires additive methods.
**Step 5: Re-run focused tests until all pass**
Use commands from Step 3.
**Step 6: Run mandatory stub scan + build gate**
Use protocol commands above.
**Step 7: Promote sublist features (`complete` then `verified`) with evidence**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3446,3447,3448" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3446,3447,3448" --set-status verified --db porting.db --execute
```
**Step 8: Run checkpoint protocol and commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/Internal/DataStructures/SubscriptionIndex.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Internal/DataStructures/GenericSublist.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/DataStructures/SubscriptionIndexTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/DataStructures/GenericSublistTests.cs \
porting.db
git commit -m "feat(batch2): verify sublist helper remainder features"
```
---
### Task 3: Group C - MemStore Remainders (`2068`, `2086`)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MemStore.cs`
- Modify/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs`
- Modify/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StorageEngineTests.cs`
**Step 1: Mark memstore feature IDs as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2068,2086" --set-status stub --db porting.db --execute
```
**Step 2: Write/adjust failing tests first**
- Ensure coverage for:
- `newMemStore` initialization semantics (`Storage=Memory`, `FirstSeq`, TTL/scheduling setup)
- `allLastSeqsLocked`/`AllLastSeqs` sorted subject-last sequence behavior
**Step 3: Run focused memstore test classes**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~JetStreamMemoryStoreTests" --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~StorageEngineTests" --verbosity normal
```
**Step 4: Implement minimal parity fixes**
- Add/adjust constructor/factory compatibility for `newMemStore` semantics if needed.
- Add/adjust locked helper behavior so `AllLastSeqs` parity is exact and stable.
**Step 5: Re-run focused tests until all pass**
Use commands from Step 3.
**Step 6: Run mandatory stub scan + build gate**
Use protocol commands above.
**Step 7: Promote memstore features (`complete` then `verified`) with evidence**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2068,2086" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2068,2086" --set-status verified --db porting.db --execute
```
**Step 8: Run checkpoint protocol and commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MemStore.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StorageEngineTests.cs \
porting.db
git commit -m "feat(batch2): verify memstore remainder features"
```
---
### Task 4: Batch 2 Closure and Reporting
**Files:**
- Modify: `porting.db`
- Modify: `reports/current.md` (via report generation script)
**Step 1: Confirm all Batch 2 features are `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 2 --db porting.db
```
**Step 2: Complete the batch**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 2 --db porting.db
```
**Step 3: Validate global summary and dependency readiness**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
```
**Step 4: Generate report artifact**
```bash
./reports/generate-report.sh
```
**Step 5: Final commit**
```bash
git add porting.db reports/
git commit -m "chore(batch2): complete parser-sublist-memstore remainder batch"
```

View File

@@ -0,0 +1,106 @@
# Batch 3 (SendQ, Service, Client ProxyProto) Design
**Date:** 2026-02-27
**Scope:** Design only for Batch 3 implementation planning (18 features, 1 test).
## Context Snapshot
Batch metadata (from `porting.db`):
- Batch ID: `3`
- Name: `SendQ, Service, Client ProxyProto`
- Features: `18`
- Tests: `1`
- Dependency: `Batch 1`
- Go files: `server/client_proxyproto.go`, `server/sendq.go`, `server/service.go`, `server/service_windows.go`
Batch 3 feature sets:
- **Proxy protocol (8):** `574-581`
- **Send queue (3):** `2971-2973`
- **Service (7):** `3148-3154`
- **Tracked test (1):** `2832` (`TestRoutePoolRouteStoredSameIndexBothSides`)
## Current Code Findings
1. Proxy protocol behavior is mostly present in .NET:
- `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProxyProtocol.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProxyProtocolTests.cs`
2. `ClientConnection.RemoteAddress()` exists, but Batch 3 maps `proxyConn.RemoteAddr` and parser methods to `ClientConnection`-named methods.
3. Send queue is not implemented as a concrete type yet:
- `Account.SendQueue` is currently `object?` with TODO note.
4. Service wrappers are partly represented by `Internal/SignalHandler.cs` (`Run`, `IsWindowsService`), but Batch 3 maps to `ServiceManager` and Windows-specific service functions.
5. The tracked test `#2832` maps to `RouteHandlerTests`, but current route backlog tests are mostly placeholder-style and do not yet include this scenario.
## Constraints and Success Criteria
- Follow .NET 10 + xUnit 3 + Shouldly + NSubstitute standards.
- No fake/stub implementations to satisfy status updates.
- Every feature/test status change must be evidence-backed (build + related tests + source parity).
- Batch 3 completion should leave all 19 items in `verified`, `complete`, or `n_a` only when justified.
## Approach Options
### Approach A: Strict file-by-file Go shape port
Create direct C# equivalents for all four Go files with minimal reuse of existing .NET code.
- Pros: Strong visual parity with Go source.
- Cons: Duplicates already-ported proxy logic; higher regression risk; unnecessary churn.
### Approach B: Tracker-only remap/status promotion
Avoid code movement; rely on current behavior and update statuses aggressively.
- Pros: Fastest short-term status movement.
- Cons: High audit risk, likely mapping mismatches, and weak behavioral evidence.
### Approach C (Recommended): Compatibility-layer parity with evidence-first verification
Reuse existing .NET behavior where already correct (proxy parser and signal handling), add compatibility wrappers/classes to satisfy mapped Batch 3 entry points (`ClientConnection`, `SendQueue`, `ServiceManager`), and add focused tests for each group before status promotion.
- Pros: Lowest risk path to real parity and audit compliance.
- Cons: Requires disciplined verification and selective wrapper design.
## Recommended Design
### 1. Proxy protocol group (`574-581`)
- Keep `Protocol/ProxyProtocol.cs` as the behavioral core.
- Add a `ClientConnection` partial shim exposing mapped method names (`RemoteAddr`, `DetectProxyProtoVersion`, `ReadProxyProtoV1Header`, `ReadProxyProtoHeader`, `ReadProxyProtoV2Header`, `ParseProxyProtoV2Header`, `ParseIPv4Addr`, `ParseIPv6Addr`) that delegate to the parser core.
- Extend `ProxyProtocolTests` only where mapping-specific behavior lacks direct assertion.
### 2. Send queue group (`2971-2973`)
- Introduce concrete `SendQueue` implementation (`newSendQ`, `InternalLoop`, `Send`) using existing `IpQueue<T>` and internal client plumbing (`CreateInternalSystemClient`).
- Replace `Account.SendQueue` placeholder type from `object?` to concrete queue type.
- Add focused unit tests for queue push/pop, no-op on null queue, and internal loop dispatch semantics.
### 3. Service group (`3148-3154`)
- Create `ServiceManager` abstraction as mapped Batch 3 surface.
- Non-Windows path: `Run` delegates to start action; `IsWindowsService` returns false.
- Windows-specific entries (`SetServiceName`, `Init`, `Execute`, Windows `Run`, Windows `IsWindowsService`) use one of two evidence-backed outcomes:
- implemented wrapper behavior where runtime-checkable, or
- explicit `n_a` classification when host-level Windows service integration is intentionally owned by `Microsoft.Extensions.Hosting.WindowsServices` and not by server library.
- Add/extend tests to verify non-Windows and wrapper semantics.
### 4. Tracked test group (`2832`)
- Implement real `RoutePoolRouteStoredSameIndexBothSides_ShouldSucceed` only if route-pool prerequisites are available in current server runtime.
- If infrastructure is still missing, keep test `deferred` with explicit reason and no fake assertions.
## Risk Register and Mitigations
1. **Mapping mismatch despite correct behavior**
- Mitigation: compatibility shim methods with mapped names on mapped classes.
2. **Stub creep while filling gaps quickly**
- Mitigation: mandatory stub scans on touched files after each feature group.
3. **Windows-service ambiguity**
- Mitigation: explicit decision tree (`verified` wrapper vs `n_a` with evidence) captured per feature ID.
4. **Route test false positives**
- Mitigation: require non-trivial assertions and actual route index comparison; otherwise defer with reason.
## Design Outcome
Proceed with **Approach C** in three feature groups plus one test group, each with strict evidence gates, explicit anti-stub checks, and controlled status updates.

View File

@@ -0,0 +1,509 @@
# Batch 3 (SendQ, Service, Client ProxyProto) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 3s 18 features and 1 tracked test with Go-parity behavior, zero stub leakage, and evidence-backed PortTracker status updates.
**Architecture:** Execute Batch 3 in three feature groups (ProxyProto, SendQueue, Service) plus one tracked-test group. Reuse existing .NET proxy/service behavior where valid, add compatibility surfaces for mapped Batch 3 methods, and run strict per-feature verification loops before any status promotion.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-3-sendq-service-client-proxyproto-design.md`
---
## Batch 3 Working Set
Feature groups (max group size <= 20 features):
- **Group A - ProxyProto (8):** `574`, `575`, `576`, `577`, `578`, `579`, `580`, `581`
- **Group B - SendQueue (3):** `2971`, `2972`, `2973`
- **Group C - Service (7):** `3148`, `3149`, `3150`, `3151`, `3152`, `3153`, `3154`
- **Tracked test (1):** `2832`
Batch facts:
- Total features: `18`
- Total tracked tests: `1`
- Dependency: `Batch 1`
- Go files: `server/client_proxyproto.go`, `server/sendq.go`, `server/service.go`, `server/service_windows.go`
> `dotnet` is not on PATH in this environment. Use `/usr/local/share/dotnet/dotnet` in all commands.
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** Every feature and test in this plan must follow this protocol. Skipping steps is a plan violation.
### What Counts as Real Verification
A feature or test can be marked `verified` only if all are true:
1. Go source was reviewed for the mapped ID (`feature show` or `test show` + source lines).
2. C# implementation/test contains real behavior (no placeholders/fake pass assertions).
3. Related tests execute with non-zero discovery and pass.
4. Group build gate is green.
5. Stub detection checks are clean for touched files.
### Per-Feature Verification Loop (REQUIRED for every feature ID)
1. Read mapped Go source and intent:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db
```
2. Write/adjust C# implementation in mapped target area.
3. Build immediately after feature-level change:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
4. Run related tests for that feature area.
5. Confirm `Passed > 0` and `Failed = 0` before adding ID to verified candidates.
### Per-Test Verification Loop (REQUIRED for test `2832`)
1. Read Go test source and dependent feature behavior:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- test show 2832 --db porting.db
```
2. Write the C# test first (real Arrange/Act/Assert, no placeholder asserts).
3. Run the specific test filter and confirm it is discovered and passing.
4. Run containing class filter and confirm cumulative pass summary.
### Stub Detection Check (REQUIRED after each feature group and test group)
Run on touched files before any status updates:
```bash
# Forbidden markers in changed source/test files
git diff -- dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests | \
grep -nE "^\+.*(NotImplementedException|TODO|PLACEHOLDER|Assert\.True\(true\)|Assert\.Pass\(|ShouldBe\(true\);)"
# Empty method bodies introduced in touched files
for f in $(git diff --name-only -- dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests | grep -E "\.cs$"); do
grep -nE "(public|private|internal|protected).*\)\s*\{\s*\}" "$f";
done
```
Any match blocks status promotion until fixed or reclassified (`deferred`/`n_a`) with reason.
### Build Gate (REQUIRED after each feature group)
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
Required: `0` errors.
### Test Gate (REQUIRED before marking features `verified`)
All related tests for the active group must pass:
- Group A (ProxyProto):
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol.ProxyProtocolTests" --verbosity normal
```
- Group B (SendQueue):
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~SendQueueTests" --verbosity normal
```
- Group C (Service):
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~SignalHandlerTests|FullyQualifiedName~ServiceManagerTests" --verbosity normal
```
- Group D (tracked test):
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~RoutePoolRouteStoredSameIndexBothSides_ShouldSucceed" --verbosity normal
```
### Status Update Protocol
- **Maximum 15 IDs per `batch-update` call** (hard cap).
- Do not mark `verified` without evidence bundle (Go source reference, build output, related test output, stub-scan output).
- Apply status in order: `deferred/not_started -> stub -> complete -> verified`.
- Use `n_a` only with explicit technical justification.
Examples:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "574,575,576,577,578,579,580,581" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "574,575,576,577,578,579,580,581" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "574,575,576,577,578,579,580,581" --set-status verified --db porting.db --execute
```
For blocked items:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status deferred --db porting.db --override "blocked: <specific reason>"
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status n_a --db porting.db --override "n/a: <specific reason>"
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each task group and before starting the next:
1. Full build:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
2. Full unit tests:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Confirm no regressions introduced.
4. Commit task-scoped changes (including `porting.db`) before proceeding.
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
### Forbidden Patterns
These are forbidden in feature or test changes for Batch 3:
- `throw new NotImplementedException()`
- `TODO` / `PLACEHOLDER` markers in newly added code
- Empty method body placeholders (`{ }`) for mapped features
- Fake pass assertions (`Assert.True(true)`, `Assert.Pass()`, meaningless sentinel assertions)
- Default/null return used only to satisfy compiler with no Go-equivalent behavior
- Test methods with no production call + no meaningful assertion
### Hard Limits
- Max `15` IDs per status update command.
- Max `1` feature group promoted per verification cycle.
- Mandatory `build` + related `test` gate before `verified`.
- Mandatory stub scan before every status promotion.
- Mandatory checkpoint commit between groups.
### If You Get Stuck (REQUIRED behavior)
Do not stub and do not fake-pass.
1. Keep item as `deferred` (or `n_a` only if genuinely non-applicable).
2. Add explicit reason with `--override` in PortTracker.
3. Commit only proven work.
4. Continue with next unblocked ID.
---
### Task 1: Group A - Proxy Protocol Features (`574-581`)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.ProxyProto.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProxyProtocol.cs`
- Modify/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProxyProtocolTests.cs`
**Step 1: Mark Group A features as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "574,575,576,577,578,579,580,581" --set-status stub --db porting.db --execute
```
**Step 2: Write/adjust failing tests first**
Add coverage for any missing mapped behavior:
- `RemoteAddr` mapped semantics
- version detect wrappers
- v1/v2 parser wrapper entry points
- IPv4/IPv6 parse wrappers
**Step 3: Run focused ProxyProto tests (expect fail first, then pass)**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ProxyProtocolTests" --verbosity normal
```
**Step 4: Implement minimal production parity**
- Add `ClientConnection` mapped method shims to existing parser core.
- Keep parsing logic centralized in `Protocol/ProxyProtocol.cs`.
**Step 5: Re-run focused tests until green**
Use Step 3 command.
**Step 6: Run stub detection + build gate**
Run protocol checks.
**Step 7: Promote statuses (`complete`, then `verified`)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "574,575,576,577,578,579,580,581" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "574,575,576,577,578,579,580,581" --set-status verified --db porting.db --execute
```
**Step 8: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.ProxyProto.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProxyProtocol.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProxyProtocolTests.cs \
porting.db
git commit -m "feat(batch3): verify client proxy protocol feature group"
```
---
### Task 2: Group B - SendQueue Features (`2971-2973`)
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/SendQueue.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Accounts.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Create/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/SendQueueTests.cs`
**Step 1: Mark Group B features as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2971,2972,2973" --set-status stub --db porting.db --execute
```
**Step 2: Write failing tests first**
Cover at minimum:
- `NewSendQ` creates queue and starts loop entry path
- `Send` no-ops when queue is null/disposed
- queued messages are copied and passed to internal client path
**Step 3: Run focused SendQueue tests (expect fail first, then pass)**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~SendQueueTests" --verbosity normal
```
**Step 4: Implement minimal SendQueue parity**
- Port `newSendQ`, `internalLoop`, `send` intent using `IpQueue<T>` + existing internal client APIs.
- Replace `Account.SendQueue` placeholder with concrete type usage.
**Step 5: Re-run focused tests until green**
Use Step 3 command.
**Step 6: Run stub detection + build gate**
Run protocol checks.
**Step 7: Promote statuses (`complete`, then `verified`)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2971,2972,2973" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2971,2972,2973" --set-status verified --db porting.db --execute
```
**Step 8: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/SendQueue.cs \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Accounts.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/SendQueueTests.cs \
porting.db
git commit -m "feat(batch3): implement send queue feature group"
```
---
### Task 3: Group C - Service Features (`3148-3154`)
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/Internal/ServiceManager.cs`
- Create (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/Internal/ServiceManager.Windows.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Internal/SignalHandler.cs`
- Create/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ServiceManagerTests.cs`
- Modify/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/SignalHandlerTests.cs`
**Step 1: Mark Group C features as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3148,3149,3150,3151,3152,3153,3154" --set-status stub --db porting.db --execute
```
**Step 2: Write failing tests first**
Cover:
- non-Windows `Run` behavior
- non-Windows `IsWindowsService` behavior
- service-name configuration behavior (if implemented)
- Windows-only hooks either behaviorally verified or explicitly marked `n_a`
**Step 3: Run focused service tests (expect fail first, then pass)**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~SignalHandlerTests|FullyQualifiedName~ServiceManagerTests" --verbosity normal
```
**Step 4: Implement service parity layer**
- Add `ServiceManager` mapped surface.
- For Windows-only features (`3150-3154`), choose one per-ID outcome based on evidence:
- implemented wrapper (`complete/verified`), or
- `n_a` with explicit reason tied to host-level WindowsService ownership.
**Step 5: Re-run focused tests until green**
Use Step 3 command.
**Step 6: Run stub detection + build gate**
Run protocol checks.
**Step 7: Promote statuses with evidence**
- Use `complete` -> `verified` for implemented service features.
- Use `n_a` for validated non-applicable Windows-host-only entries.
- Keep max 7 IDs in this task update (below 15 cap).
**Step 8: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/Internal/ServiceManager.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Internal/ServiceManager.Windows.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Internal/SignalHandler.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ServiceManagerTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/SignalHandlerTests.cs \
porting.db
git commit -m "feat(batch3): implement service feature group"
```
---
### Task 4: Group D - Tracked Test `2832`
**Files:**
- Modify/Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Modify (only if required by real behavior): `dotnet/src/ZB.MOM.NatsNet.Server/Routes/*`
**Step 1: Mark test `2832` as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update 2832 --status stub --db porting.db
```
**Step 2: Write real failing test first**
Implement `RoutePoolRouteStoredSameIndexBothSides_ShouldSucceed` with actual route index/endpoint assertions mirroring Go intent.
**Step 3: Run focused test and class gates**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~RoutePoolRouteStoredSameIndexBothSides_ShouldSucceed" --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~RouteHandlerTests" --verbosity normal
```
**Step 4: If infrastructure is missing, defer explicitly (do not stub)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update 2832 --status deferred --db porting.db \
--override "blocked: requires route-pool runtime topology not yet implemented in current server core"
```
**Step 5: If test is green, promote to `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update 2832 --status verified --db porting.db
```
**Step 6: Checkpoint protocol + commit**
```bash
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Routes \
porting.db
git commit -m "test(batch3): handle route pool same-index test"
```
---
### Task 5: Batch 3 Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md` (via report script)
**Step 1: Verify batch state**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 3 --db porting.db
```
Required: all 18 features and test `2832` are `verified`/`complete`/`n_a`; unresolved blockers remain explicitly `deferred` with reason.
**Step 2: Full regression gate**
```bash
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
Required: `Failed: 0` for full unit test suite.
**Step 3: Complete batch if eligible**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 3 --db porting.db
```
**Step 4: Validate summary + readiness**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
```
**Step 5: Generate report and final commit**
```bash
./reports/generate-report.sh
git add porting.db reports/current.md
git commit -m "chore(batch3): close sendq-service-proxyproto batch"
```

View File

@@ -0,0 +1,138 @@
# Batch 4 (Logging) Design
**Date:** 2026-02-27
**Scope:** Design for Batch 4 implementation planning only (11 features, 31 tests).
## Context Snapshot
Batch metadata (from `porting.db`):
- Batch ID: `4`
- Name: `Logging`
- Features: `11` (all currently `deferred`)
- Tests: `31` (all currently `deferred`)
- Dependency: `Batch 1`
- Go source: `server/log.go`
PortTracker command snapshot:
- `batch show 4` confirms feature IDs: `2050,2052,2053,2054,2057,2058,2059,2061,2062,2063,2067`
- `batch show 4` confirms test IDs: `622,623,643,678,1906,1911,1916,1917,1922,1940,1947,1954,1971,1973,1977,1991,2000,2188,2270,2469,2506,2820,2826,2827,2828,2834,2847,2848,3104,3110,3130`
- `report summary` shows the repository is mixed-state (`verified`, `deferred`, `n_a`) with Batch 4 still pending.
## Current Code Findings
1. `dotnet/src/ZB.MOM.NatsNet.Server/Internal/NatsLogger.cs` already implements most `log.go` behavior in `ServerLogging` (set logger flags, execute log call, error convenience methods, rate-limited warn/debug).
2. `NatsServer` still lacks the mapped Batch 4 `NatsServer` method surface (`ConfigureLogger`, `SetLogger`, `SetLoggerV2`, `ReOpenLogFile`, `Errors`, `Errorc`, `Errorsc`, `RateLimit*`, `ExecuteLogCall`).
3. `NatsServer` currently uses `ILogger` fields directly (`_logger`, `_debugEnabled`, `_traceEnabled`, `_traceSysAcc`), so the Batch 4 implementation must preserve compatibility with existing callers.
4. Batch 4 mapped tests point to `ImplBacklog` classes in:
- `GatewayHandlerTests.Impltests.cs`
- `LeafNodeHandlerTests.Impltests.cs`
- `MqttHandlerTests.Impltests.cs`
- `ConcurrencyTests1.Impltests.cs`
- `ConcurrencyTests2.Impltests.cs`
- `RouteHandlerTests.Impltests.cs`
- `WebSocketHandlerTests.Impltests.cs`
5. Existing backlog tests in those files are mostly shallow placeholders and need real behavior assertions for Batch 4 IDs instead of synthetic constant checks.
## Constraints and Success Criteria
Constraints:
- Follow .NET standards and toolchain already used by this repo.
- Plan must enforce mandatory verification protocol and anti-stub controls for both features and tests.
- Feature/test status changes must be evidence-based with max 15 IDs per batch update.
- No implementation in this design step; planning only.
Success criteria:
- All 11 Batch 4 features implemented on `NatsServer` with `log.go` parity.
- Batch 4 test methods are real tests (or explicitly deferred with concrete blockers).
- No feature marked `verified` without passing related test gates.
- No placeholder/stub code promoted as complete.
## Approach Options
### Approach A: Keep `NatsServer` logging as-is and update statuses only
- Pros: fastest paperwork.
- Cons: fails parity goals and verification gates; high audit risk.
### Approach B: Replace `NatsServer` logging internals entirely with `ServerLogging`
- Pros: direct reuse of existing `Internal/NatsLogger.cs`.
- Cons: larger refactor risk for existing `ILogger` call sites and `INatsServer.Logger` consumers.
### Approach C (Recommended): Add `NatsServer` logging partial with adapter bridge
- Keep existing `ILogger`-based behavior compatible.
- Implement mapped Batch 4 methods in a dedicated `NatsServer.Logging.cs` partial.
- Bridge `INatsLogger <-> ILogger` using `MicrosoftLoggerAdapter`.
- Port Batch 4 tests in mapped backlog classes with real Arrange/Act/Assert semantics.
Why this is recommended: it achieves Go parity for mapped methods with minimal disruption to already-ported code paths.
## Recommended Design
### 1. Production Surface
- Add `NatsServer` partial for Batch 4 APIs:
- `ConfigureLogger`
- `SetLogger`
- `SetLoggerV2`
- `ReOpenLogFile`
- `Errors`
- `Errorc`
- `Errorsc`
- `RateLimitFormatWarnf`
- `RateLimitWarnf`
- `RateLimitDebugf`
- `ExecuteLogCall`
- Preserve current `ILogger Logger` property and existing call sites.
- Use lock + atomic patterns consistent with current server style.
### 2. Logger Configuration Strategy
- `ConfigureLogger` reads `ServerOptions` and selects logger backend behavior by precedence:
1. `NoLog` => no-op/null logging
2. `LogFile` => file-backed logger path (or explicit deferred reason if host constraint blocks parity)
3. `RemoteSyslog`/`Syslog` => explicit behavior branch with documented platform policy
4. default => standard logger path
- `SetLoggerV2` and `SetLogger` update debug/trace/system-trace flags and replace prior logger safely.
- `ReOpenLogFile` only reopens when file logging is active; otherwise logs ignore notice.
### 3. Test Strategy for 31 Batch 4 Tests
- Port only mapped IDs in their mapped classes with real behavior:
- Gateway/Route reconnection and duplicate-name scenarios validate expected log warnings/errors.
- Leaf/MQTT scenarios validate logger interactions tied to option/auth/reconnect paths.
- Concurrency/WebSocket scenarios validate log emission and suppression under failure/loop paths.
- If runtime topology requirements are unavailable in current harness, keep test `deferred` with explicit reason and evidence.
### 4. Grouping Strategy
Feature groups (both <=20):
- **F1 Core Logger Wiring (5):** `2050,2052,2053,2054,2067`
- **F2 Error + Rate-Limit Helpers (6):** `2057,2058,2059,2061,2062,2063`
Test groups:
- **T1 Gateway + Route (11):** `622,623,643,678,2820,2826,2827,2828,2834,2847,2848`
- **T2 Leaf + MQTT (15):** `1906,1911,1916,1917,1922,1940,1947,1954,1971,1973,1977,1991,2000,2188,2270`
- **T3 Concurrency + WebSocket (5):** `2469,2506,3104,3110,3130`
### 5. Risk Register
1. Existing `ILogger` call paths regress if adapter bridge is intrusive.
- Mitigation: keep `ILogger` as source of truth and isolate new mapped methods in partial file.
2. Backlog test quality regresses into synthetic assertions.
- Mitigation: mandatory anti-stub scans and per-test verification loop.
3. Infra-heavy tests cannot run in local harness.
- Mitigation: explicit defer protocol with blocker evidence; no fake passes.
4. Status drift between code and `porting.db`.
- Mitigation: capped chunked updates with evidence before each update command.
## Design Outcome
Proceed with **Approach C** and execute in two feature groups plus three test groups under strict verification gates. The implementation plan will enforce mandatory verification protocol and anti-stub guardrails for both production features and mapped tests.

View File

@@ -0,0 +1,506 @@
# Batch 4 (Logging) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 4 logging parity (`11` features, `31` tests) from `server/log.go` with evidence-backed status updates and zero stub leakage.
**Architecture:** Add a dedicated `NatsServer` logging partial that ports the mapped `log.go` methods while preserving existing `ILogger`-based call sites. Implement in two feature groups (<=20 each), then port mapped tests in three class-based groups with strict per-feature and per-test verification loops. Use deferred-with-reason only when runtime blockers are proven.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-4-logging-design.md`
---
## Batch 4 Working Set
Batch facts:
- Batch ID: `4`
- Features: `11`
- Tests: `31`
- Dependency: `Batch 1`
- Go file: `server/log.go`
Feature groups (max group size <= 20):
- **F1 Core Logger Wiring (5):** `2050,2052,2053,2054,2067`
- **F2 Error + Rate-Limit Helpers (6):** `2057,2058,2059,2061,2062,2063`
Test groups:
- **T1 Gateway + Route (11):** `622,623,643,678,2820,2826,2827,2828,2834,2847,2848`
- **T2 Leaf + MQTT (15):** `1906,1911,1916,1917,1922,1940,1947,1954,1971,1973,1977,1991,2000,2188,2270`
- **T3 Concurrency + WebSocket (5):** `2469,2506,3104,3110,3130`
Environment note:
- `dotnet` is not on PATH in this environment; use `/usr/local/share/dotnet/dotnet` in commands.
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** Every feature and every test in this plan must follow this protocol.
### Per-Feature Verification Loop (REQUIRED for each feature ID)
1. Read Go source mapping and intent:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db
```
2. Read the mapped `server/log.go` code region for the feature.
3. Write C# implementation for only that features behavior.
4. Build immediately:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
5. Run related tests for the affected area (focused class/method filter).
6. Add the feature ID to a verified-candidates list only after build + related tests are green.
### Per-Test Verification Loop (REQUIRED for each test ID)
1. Read test mapping:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- test show <id> --db porting.db
```
2. Read Go test method lines and identify expected logging behavior.
3. Write/replace C# test with real Arrange/Act/Assert.
4. Run only that test and confirm discovery + pass:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<ExactTestMethod>" --verbosity normal
```
5. Add test ID to verified-candidates list only after focused test passes.
### Stub Detection Check (REQUIRED after each feature group and each test class group)
Run these checks on touched files before any status promotion:
```bash
# 1) Forbidden stub markers
grep -n -E "(NotImplementedException|TODO|PLACEHOLDER)" \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Internal/NatsLogger.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/*.cs
# 2) Empty method bodies in changed C# files
for f in $(git diff --name-only -- '*.cs'); do
grep -n -E "^\s*(public|private|internal|protected).*\)\s*\{\s*\}\s*$" "$f";
done
```
Any match blocks status updates until fixed or explicitly deferred with reason.
### Build Gate (REQUIRED after each feature group)
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
Required result: build succeeds with zero errors.
### Test Gate (REQUIRED before marking any Batch 4 feature as `verified`)
Run all related suites for the currently active groups and require `Failed: 0`:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~NatsLoggerTests|FullyQualifiedName~ServerLoggerTests" --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~GatewayHandlerTests|FullyQualifiedName~RouteHandlerTests" --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~LeafNodeHandlerTests|FullyQualifiedName~MqttHandlerTests" --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ConcurrencyTests1|FullyQualifiedName~ConcurrencyTests2|FullyQualifiedName~WebSocketHandlerTests" --verbosity normal
```
Rule: do not mark any feature `verified` until all related mapped tests for that feature group are passing. If blocked, keep feature at `complete` and defer blocked tests with explicit reason.
### Status Update Protocol (REQUIRED)
- Max `15` IDs per `feature batch-update` or `test batch-update` command.
- Evidence required for each update chunk:
- Go source reviewed
- build gate output
- related focused test output
- stub detection output
- Required state progression:
- Features: `deferred/not_started -> stub -> complete -> verified`
- Tests: `deferred/not_started -> stub -> verified` (or remain `deferred` with reason)
Command templates:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "<max15ids>" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "<max15ids>" --set-status verified --db porting.db --execute
```
If audit disagrees, attach override evidence:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status <status> --db porting.db --override "verification evidence: <reason>"
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each task, before starting the next:
1. Run full build:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
2. Run full unit tests:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Record pass/fail totals.
4. Commit the completed task slice (including `porting.db`) before proceeding.
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
### Forbidden Patterns
Do not introduce these in feature or test code:
- `throw new NotImplementedException(...)`
- `TODO` / `PLACEHOLDER` markers in newly touched Batch 4 code
- Empty method bodies (`{ }`) for mapped feature methods
- Trivial always-pass assertions (`Assert.True(true)`, `Assert.Pass()`)
- Non-behavioral string/self checks used in place of production behavior
- Tests that never invoke production code
### Hard Limits
- Max `20` features per feature group.
- Max `15` IDs per status update command.
- Max `1` feature group status promotion per verification cycle.
- Mandatory build gate + related test gate before any `verified` promotion.
- Mandatory checkpoint commit between tasks.
### If You Get Stuck (REQUIRED BEHAVIOR)
Do not stub. Do not fake-pass.
1. Keep the blocked item `deferred`.
2. Add explicit reason with `--override`:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status deferred --db porting.db \
--override "blocked: <specific runtime/dependency reason>"
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update <id> --status deferred --db porting.db \
--override "blocked: <specific runtime/dependency reason>"
```
3. Commit only proven work and continue with next unblocked ID.
---
### Task 1: Preflight and Batch Claim
**Files:**
- Modify: `porting.db`
**Step 1: Confirm dependency and batch readiness**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 1 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 4 --db porting.db
```
**Step 2: Start batch 4**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch start 4 --db porting.db
```
**Step 3: Mark F1 as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2050,2052,2053,2054,2067" --set-status stub --db porting.db --execute
```
**Step 4: Checkpoint protocol + commit**
---
### Task 2: Implement Feature Group F1 (Core Logger Wiring)
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Logging.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Internal/NatsLogger.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/NatsLoggerTests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/ServerLifecycleStubFeaturesTests.cs` (or dedicated new server logging test file if cleaner)
- Modify: `porting.db`
**Step 1: Write/expand failing tests for F1 mapped behaviors**
- `ConfigureLogger` option precedence behavior
- `SetLogger` delegates to `SetLoggerV2`
- `SetLoggerV2` flag + replacement semantics
- `ReOpenLogFile` behavior by log mode
- `ExecuteLogCall` no-op with nil logger
**Step 2: Run focused tests and confirm they fail first**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~NatsLoggerTests|FullyQualifiedName~ServerLoggerTests" --verbosity normal
```
**Step 3: Implement F1 in `NatsServer.Logging.cs` with Go parity**
**Step 4: Run per-feature verification loop for `2050,2052,2053,2054,2067`**
**Step 5: Run stub detection check + build gate + focused test gate**
**Step 6: Promote F1 statuses to `complete` then `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2050,2052,2053,2054,2067" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2050,2052,2053,2054,2067" --set-status verified --db porting.db --execute
```
**Step 7: Checkpoint protocol + commit**
---
### Task 3: Implement Feature Group F2 (Errors + Rate-Limit Helpers)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Logging.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/NatsLoggerTests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/ServerLifecycleStubFeaturesTests.cs` (or dedicated server logging test file)
- Modify: `porting.db`
**Step 1: Mark F2 as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2057,2058,2059,2061,2062,2063" --set-status stub --db porting.db --execute
```
**Step 2: Write/expand failing tests for F2**
- `Errors`, `Errorc`, `Errorsc` formatting parity
- `RateLimitFormatWarnf` dedupe-by-format
- `RateLimitWarnf` dedupe-by-rendered-statement
- `RateLimitDebugf` respects debug flag and dedupe
**Step 3: Run focused tests and confirm fail**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~NatsLoggerTests|FullyQualifiedName~ServerLoggerTests" --verbosity normal
```
**Step 4: Implement F2 feature methods**
**Step 5: Run per-feature verification loop for `2057,2058,2059,2061,2062,2063`**
**Step 6: Run stub detection + build gate + focused test gate**
**Step 7: Promote F2 statuses to `complete` then `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2057,2058,2059,2061,2062,2063" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2057,2058,2059,2061,2062,2063" --set-status verified --db porting.db --execute
```
**Step 8: Checkpoint protocol + commit**
---
### Task 4: Port Test Group T1 (Gateway + Route, 11 tests)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/GatewayHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark T1 tests as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "622,623,643,678,2820,2826,2827,2828,2834,2847,2848" \
--set-status stub --db porting.db --execute
```
**Step 2: For each test ID, run Per-Test Verification Loop**
**Step 3: Run class-level gates**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~GatewayHandlerTests|FullyQualifiedName~RouteHandlerTests" --verbosity normal
```
**Step 4: Run stub detection for touched backlog files**
**Step 5: Promote T1 test IDs to `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "622,623,643,678,2820,2826,2827,2828,2834,2847,2848" \
--set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
---
### Task 5: Port Test Group T2 (Leaf + MQTT, 15 tests)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MqttHandlerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark T2 tests as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1906,1911,1916,1917,1922,1940,1947,1954,1971,1973,1977,1991,2000,2188,2270" \
--set-status stub --db porting.db --execute
```
**Step 2: Run Per-Test Verification Loop for each T2 ID**
**Step 3: Run class-level gates**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~LeafNodeHandlerTests|FullyQualifiedName~MqttHandlerTests" --verbosity normal
```
**Step 4: Run stub detection for touched backlog files**
**Step 5: Promote T2 test IDs in max-15 chunks**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1906,1911,1916,1917,1922,1940,1947,1954,1971,1973,1977,1991,2000,2188,2270" \
--set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
---
### Task 6: Port Test Group T3 (Concurrency + WebSocket, 5 tests)
**Files:**
- 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: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark T3 tests as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2469,2506,3104,3110,3130" --set-status stub --db porting.db --execute
```
**Step 2: Run Per-Test Verification Loop for each T3 ID**
**Step 3: Run class-level gates**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ConcurrencyTests1|FullyQualifiedName~ConcurrencyTests2|FullyQualifiedName~WebSocketHandlerTests" \
--verbosity normal
```
**Step 4: Run stub detection for touched backlog files**
**Step 5: Promote T3 test IDs to `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2469,2506,3104,3110,3130" --set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
---
### Task 7: Batch 4 Closure and Final Verification
**Files:**
- Modify: `porting.db`
- Optional: `reports/current.md` (if report regenerated)
**Step 1: Run final full verification gates**
```bash
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ --verbosity normal
```
**Step 2: Validate batch state**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 4 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 4 --db porting.db
```
**Step 3: Generate status report**
```bash
./reports/generate-report.sh
```
**Step 4: Final checkpoint commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests porting.db reports/current.md
git commit -m "feat(batch4): implement logging features and mapped tests with verification evidence"
```
---
Plan complete and saved to `docs/plans/2026-02-27-batch-4-logging-plan.md`. Two execution options:
1. Subagent-Driven (this session) - dispatch a fresh subagent per task, review between tasks, fast iteration.
2. Parallel Session (separate) - open a new session with `executeplan`, batch execution with checkpoints.
Which approach?

View File

@@ -0,0 +1,160 @@
# Batch 5 (JetStream Errors) Design
**Date:** 2026-02-27
**Scope:** Design for Batch 5 implementation planning only (206 features, 11 tests).
## Context Snapshot
Batch metadata (`implementation_batches.id = 5`):
- Batch ID: `5`
- Name: `JetStream Errors`
- Features: `206`
- Tests: `11`
- Dependencies: none
- Go files: `server/jetstream_errors.go`, `server/jetstream_errors_generated.go`
- Current status: all `206` features are `deferred`; all `11` tests are `deferred`
Current code baseline:
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamErrors.cs` already contains `203` static `JsApiError` constants.
- Go has `203` generated `NewJS*Error` constructors.
- C# currently exposes only `3` `NewJS*Error` methods:
- `NewJSRestoreSubscribeFailedError`
- `NewJSStreamRestoreError`
- `NewJSPeerRemapError`
- Batch 5 includes helper parity work from `jetstream_errors.go`:
- `Unless` (already present)
- `parseOpts` (mapped as `ParseOpts`)
- `ApiError.toReplacerArgs` (mapped as `ToReplacerArgs`)
## Problem Statement
Batch 5 is predominantly mechanical but high-risk for audit drift:
1. Method-surface gap is large (200 missing constructors).
2. Constructor signatures are mixed (no args, 1 arg, 2 args with placeholder replacement).
3. Existing test landscape includes deferred infra-heavy tests and impl-backlog stub patterns that must not be reused for verification.
4. PortTracker audit requires mapped method presence and evidence-backed status transitions.
## Constraints and Success Criteria
Constraints:
- Must follow .NET standards (xUnit 3 + Shouldly + NSubstitute; no FluentAssertions/Moq).
- Must keep feature groups at max ~20 features each.
- Must enforce strict anti-stub verification before status updates.
- Must require passing related tests before setting features to `verified`.
Success criteria:
- All 206 Batch 5 feature mappings implemented with Go-behavior parity.
- Constructor methods mirror Go semantics for `opts` override and placeholder substitution.
- Verification evidence exists per feature group (build, focused tests, stub scan).
- 11 mapped tests are either fully ported and passing, or explicitly kept deferred with concrete blocker reasons (no fake tests).
## Approaches
### Approach A: Manual method-by-method implementation
Write all 200 missing `NewJS*Error` methods manually in `JetStreamErrors.cs`.
- Pros: no generator tooling.
- Cons: high typo risk, high audit drift risk, high review cost.
### Approach B: Full code generation from Go source for entire error file
Generate both constants and constructors from Go into one fully generated C# file.
- Pros: strongest parity with Go source.
- Cons: higher one-time tooling complexity, risk of replacing hand-authored helpers/tests unexpectedly.
### Approach C (Recommended): Hybrid generation of constructor surface + hand-owned helper core
Keep existing hand-owned constants/helpers in `JetStreamErrors.cs`, and generate/maintain a partial file containing all `NewJS*Error` constructors. Add focused tests validating constructor parity, override behavior, and placeholder replacement.
- Pros: low-risk incremental adoption, deterministic method coverage, easier review per feature group.
- Cons: requires a small generator script and disciplined grouped verification.
## Recommended Design
### 1. Class Structure
- Keep `JsApiError` and base constants in existing file.
- Split `JsApiErrors` into partial class files:
- Hand-authored core (`Unless`, `ParseOpts`, `ToReplacerArgs`, `Clone`, `NewWithTags`, lookup methods)
- Generated constructor surface (`NewJS*Error` methods)
### 2. Constructor Semantics
For each generated constructor:
- Parse `opts` and immediately return override when override is a `JsApiError`.
- For non-templated descriptions, return canonical static error instance (or cloned equivalent where required by design/tests).
- For templated descriptions, return a cloned instance with formatted `Description` using replacement args derived by `ToReplacerArgs` parity.
- Type mapping:
- Go `error` -> C# `Exception`
- Go `interface{}` -> C# `object`
- Go `uint64` -> C# `ulong`
### 3. Verification Architecture
- Add/extend JetStream error unit tests for:
- helper semantics (`Unless`, `ParseOpts`, replacement formatting)
- constructor existence/signature consistency for all Batch 5 `NewJS*Error` methods
- representative replacement-heavy constructors and known dependent constructors used by mapped tests
- Keep infra-dependent tests deferred if server harness is unavailable; never replace with trivial passing tests.
### 4. Feature Grouping Strategy
Implement and verify in 11 groups (<=20 features each) ordered by source line and tracker IDs:
- Group 01: `1751,1752,1755,1756-1772` (20)
- Group 02: `1773-1792` (20)
- Group 03: `1793-1812` (20)
- Group 04: `1813-1832` (20)
- Group 05: `1833-1852` (20)
- Group 06: `1853-1872` (20)
- Group 07: `1873-1892` (20)
- Group 08: `1893-1912` (20)
- Group 09: `1913-1932` (20)
- Group 10: `1933-1952` (20)
- Group 11: `1953-1958` (6)
### 5. Test Handling Strategy for 11 Batch Tests
Mapped tests:
- `742`, `1304`, `1476`, `1606`, `1694`, `1696`, `1708`, `1757`, `1767`, `1777`, `2272`
Design rule:
- Attempt real ports where executable infrastructure exists.
- If blocked by missing runtime server/cluster harness, keep `deferred` with specific reason and evidence; do not add fake assertions, empty non-skipped tests, or non-behavioral placeholders.
## Data Flow (Runtime)
1. Caller invokes `JsApiErrors.NewJS...Error(...)`.
2. Constructor evaluates `ParseOpts(opts)` for override.
3. If override contains `JsApiError`, return override clone.
4. Else clone canonical error constant.
5. For templated descriptions, apply replacements using `ToReplacerArgs` + replace pipeline.
6. Return `JsApiError` with stable `Code`, `ErrCode`, and resolved `Description`.
## Risks and Mitigations
1. **Large mechanical surface introduces silent mistakes**
Mitigation: generated constructor file + grouped verification + reflection/parameterized tests.
2. **Audit mismatch due method naming/signature drift**
Mitigation: source-of-truth method inventory from batch feature IDs and Go signatures.
3. **False confidence from placeholder tests**
Mitigation: mandatory anti-stub scans and strict verification gates before status updates.
4. **Infra-heavy mapped tests block completion**
Mitigation: explicit deferred protocol with reasoned notes; avoid fake completion.
## Approval-to-Plan Transition
This design selects **Approach C (Hybrid generation + strict grouped verification)** and is ready for execution planning with mandatory verification protocol and anti-stub guardrails.

View File

@@ -0,0 +1,530 @@
# Batch 5 (JetStream Errors) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 5 JetStream error helper parity (`206` features) and resolve the `11` mapped tests with evidence-backed status updates.
**Architecture:** Keep canonical `JsApiError` constants in hand-authored code, add missing helper parity (`ParseOpts`, `ToReplacerArgs`), and generate constructor surface for all missing `NewJS*Error` methods in grouped increments (<=20 features). Use strict verification gates after each group: stub scan, build, focused tests, and status updates in <=15-ID chunks with captured evidence.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-5-jetstream-errors-design.md`
---
## Batch 5 Working Set
Batch facts:
- Batch ID: `5`
- Features: `206` (all currently `deferred`)
- Tests: `11` (all currently `deferred`)
- Dependencies: none
- Go sources: `server/jetstream_errors.go`, `server/jetstream_errors_generated.go`
Feature groups (<=20 features each):
- **Group 01 (20):** `1751,1752,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772`
- **Group 02 (20):** `1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792`
- **Group 03 (20):** `1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812`
- **Group 04 (20):** `1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832`
- **Group 05 (20):** `1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852`
- **Group 06 (20):** `1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872`
- **Group 07 (20):** `1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892`
- **Group 08 (20):** `1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912`
- **Group 09 (20):** `1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932`
- **Group 10 (20):** `1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952`
- **Group 11 (6):** `1953,1954,1955,1956,1957,1958`
Mapped tests in this batch:
- `742`, `1304`, `1476`, `1606`, `1694`, `1696`, `1708`, `1757`, `1767`, `1777`, `2272`
Batch-5-linked features referenced by those tests:
- `1765`, `1806`, `1821`, `1876`, `1883`, `1903`, `1916`, `1930`, `1938`, `1953`
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** this protocol applies to every feature group and every test task.
### Per-Feature Verification Loop (REQUIRED for every feature ID)
1. Read the mapped Go source (`feature show <id>` + source file/line).
2. Implement or update mapped C# method in the mapped class.
3. Run focused constructor/helper tests for that feature group.
4. Run build gate.
5. Run related test gate.
6. Only then add the feature ID to `complete`/`verified` candidate lists.
Focused run pattern:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~JetStreamErrorsGeneratedConstructorsTests.ConstructorSurface_Group<NN>" \
--verbosity normal
```
### Stub Detection Check (REQUIRED after every feature group and test class)
Run on touched files only:
```bash
rg -n "NotImplementedException|throw new NotSupportedException\(|TODO|PLACEHOLDER" \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamErrors*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/*.cs
rg -n "Assert\.True\(true\)|Assert\.Pass\(|\.ShouldBe\(true\);$|^\s*\{\s*\}$" \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/*.cs
```
Any hit in edited code blocks status promotion until resolved or explicitly deferred.
### Build Gate (REQUIRED after each feature group)
```bash
dotnet build dotnet/
```
Required: zero errors.
### Test Gate (REQUIRED before marking any feature `verified`)
Run all related classes and require `Failed: 0`:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~JetStreamErrorsTests|FullyQualifiedName~JetStreamErrorsGeneratedConstructorsTests" \
--verbosity normal
```
For the 10 features linked to tracked tests (`1765,1806,1821,1876,1883,1903,1916,1930,1938,1953`), related mapped test IDs must also pass before those features can move to `verified`. If those tests are infra-blocked, keep those features at `complete` and document blocker.
### Status Update Protocol (REQUIRED)
- Maximum `15` IDs per `feature batch-update` or `test batch-update` command.
- Evidence is required for every status update chunk:
- focused test pass output
- build gate output
- related test gate output
- stub scan output
- State progression:
- Features: `deferred -> stub -> complete -> verified`
- Tests: `deferred -> stub -> verified` (or stay `deferred` with explicit reason)
Command templates:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "<max15ids>" --set-status verified --db porting.db --execute
```
If audit disagrees, use explicit reason:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status verified --db porting.db \
--override "manual verification evidence: <short reason>"
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each feature group task and each test-class task:
1. Full build:
```bash
dotnet build dotnet/
```
2. Full unit tests:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Full integration tests:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ --verbosity normal
```
4. Commit the task slice before moving on.
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
### Forbidden Patterns
Production code forbidden:
- `throw new NotImplementedException()`
- `return default;` / `return null;` placeholders not present in Go logic
- Empty public method bodies used as placeholders
- `TODO`, `PLACEHOLDER`, or equivalent unresolved markers
Test code forbidden (for tests marked `verified`):
- `Assert.True(true)`
- `Assert.Pass()`
- String/self-assertions unrelated to behavior
- Empty method body without `[Fact(Skip = ...)]`
- Any test that does not exercise production code path
### Hard Limits
- Max `20` features per task group.
- Max `15` IDs per status update command.
- Max `1` feature group promoted per verification cycle.
- No feature gets `verified` without passing test gate evidence.
- No test gets `verified` if skipped.
### If You Get Stuck (Explicit Protocol)
Do not stub. Do not fake-pass tests.
1. Keep item `deferred`.
2. Add concrete blocker reason (server runtime, cluster harness, missing infra dependency, etc.).
3. Capture evidence command output proving blocker.
4. Continue with next unblocked item.
Commands:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status deferred --db porting.db \
--override "blocked: <specific reason>"
dotnet run --project tools/NatsNet.PortTracker -- \
test update <id> --status deferred --db porting.db \
--override "blocked: <specific reason>"
```
---
### Task 1: Build Constructor/Test Harness Foundation (Group 01 baseline)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamErrors.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamErrors.GeneratedConstructors.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamErrorsTests.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamErrorsGeneratedConstructorsTests.cs`
- Create: `tools/generate-jetstream-errors.sh` (or equivalent deterministic generator script)
- Modify: `porting.db`
**Step 1: Mark Group 01 as `stub` (<=15 IDs per command)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "1751,1752,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767" \
--set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "1768,1769,1770,1771,1772" \
--set-status stub --db porting.db --execute
```
**Step 2: Write failing tests for Group 01 constructor surface + helper parity**
- Add failing coverage for:
- `Unless`/`ParseOpts` override behavior
- `ToReplacerArgs` parity conversions (`string`, `Exception`, generic object)
- Group 01 constructor method existence and output parity
**Step 3: Run focused tests to confirm FAIL**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~JetStreamErrorsGeneratedConstructorsTests.ConstructorSurface_Group01" --verbosity normal
```
**Step 4: Implement Group 01 methods + helper parity**
- Implement mapped helper methods (`ParseOpts`, `ToReplacerArgs`) and Group 01 constructors.
**Step 5: Re-run focused tests and confirm PASS**
**Step 6: Run stub scan + build gate + test gate**
Use protocol commands above.
**Step 7: Promote Group 01 statuses to `complete` then `verified`**
Use the same two ID chunks as Step 1, first `complete`, then `verified`.
**Step 8: Checkpoint + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamErrors.cs \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamErrors.GeneratedConstructors.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamErrorsTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamErrorsGeneratedConstructorsTests.cs \
tools/generate-jetstream-errors.sh porting.db
git commit -m "feat(batch5): implement jetstream error helpers and group01 constructors"
```
---
### Task 2: Implement Feature Group 02 (20 features)
**IDs:** `1773-1792`
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamErrors.GeneratedConstructors.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamErrorsGeneratedConstructorsTests.cs`
- Modify: `porting.db`
**Execution Steps (repeat pattern for this and all later feature groups):**
1. Set `stub` in <=15 chunks:
- `1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1786,1787`
- `1788,1789,1790,1791,1792`
2. Add/enable failing Group 02 tests.
3. Run Group 02 focused tests and confirm fail.
4. Implement constructors for Group 02.
5. Run Group 02 focused tests and confirm pass.
6. Run stub scan + build gate + test gate.
7. Set `complete` in same 2 chunks.
8. Set `verified` in same 2 chunks.
9. Run checkpoint protocol and commit.
---
### Task 3: Implement Feature Group 03 (20 features)
**IDs:** `1793-1812`
**Status chunks:**
- Chunk A: `1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807`
- Chunk B: `1808,1809,1810,1811,1812`
Follow Task 2 steps verbatim (stub -> failing tests -> implementation -> pass -> gates -> complete -> verified -> checkpoint commit).
---
### Task 4: Implement Feature Group 04 (20 features)
**IDs:** `1813-1832`
**Status chunks:**
- Chunk A: `1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827`
- Chunk B: `1828,1829,1830,1831,1832`
Follow Task 2 steps verbatim.
---
### Task 5: Implement Feature Group 05 (20 features)
**IDs:** `1833-1852`
**Status chunks:**
- Chunk A: `1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847`
- Chunk B: `1848,1849,1850,1851,1852`
Follow Task 2 steps verbatim.
---
### Task 6: Implement Feature Group 06 (20 features)
**IDs:** `1853-1872`
**Status chunks:**
- Chunk A: `1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867`
- Chunk B: `1868,1869,1870,1871,1872`
Follow Task 2 steps verbatim.
---
### Task 7: Implement Feature Group 07 (20 features)
**IDs:** `1873-1892`
**Status chunks:**
- Chunk A: `1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887`
- Chunk B: `1888,1889,1890,1891,1892`
Follow Task 2 steps verbatim.
---
### Task 8: Implement Feature Group 08 (20 features)
**IDs:** `1893-1912`
**Status chunks:**
- Chunk A: `1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907`
- Chunk B: `1908,1909,1910,1911,1912`
Follow Task 2 steps verbatim.
---
### Task 9: Implement Feature Group 09 (20 features)
**IDs:** `1913-1932`
**Status chunks:**
- Chunk A: `1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927`
- Chunk B: `1928,1929,1930,1931,1932`
Follow Task 2 steps verbatim.
---
### Task 10: Implement Feature Group 10 (20 features)
**IDs:** `1933-1952`
**Status chunks:**
- Chunk A: `1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947`
- Chunk B: `1948,1949,1950,1951,1952`
Follow Task 2 steps verbatim.
---
### Task 11: Implement Feature Group 11 (6 features)
**IDs:** `1953,1954,1955,1956,1957,1958`
**Steps:**
1. Set all 6 to `stub` in one command.
2. Add/enable failing Group 11 tests.
3. Run focused Group 11 tests and confirm fail.
4. Implement constructors for Group 11.
5. Re-run focused tests and confirm pass.
6. Run stub scan + build gate + test gate.
7. Set all 6 to `complete`.
8. Set all 6 to `verified` only if linked mapped tests also pass (`1953` is linked); otherwise keep linked feature at `complete` with blocker note.
9. Run checkpoint protocol and commit.
---
### Task 12: Port/Resolve Batch 5 Mapped Tests (11 tests)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamBatchingTests.cs` (`T:742`)
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/NatsConsumerTests.cs` (`T:1304`)
- Create/Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamEngineTests.cs` (`T:1476,1606,1694,1696,1708,1757,1767,1777`)
- Create/Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/MqttHandlerTests.cs` (`T:2272`)
- Modify: `porting.db`
**Per-test loop (REQUIRED):**
1. Read exact Go test body (`test show <id>` + source lines).
2. Attempt faithful C# port.
3. Run single-test filter and collect output.
4. If pass: mark test `verified`.
5. If blocked by infra: keep `deferred` with specific reason; do not fake-pass.
Single-test run template:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<ClassName>.<MethodName>" --verbosity normal
```
Status updates (max 15 IDs):
- Verified chunk example:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "742,1304,1476,1606,1694,1696,1708,1757,1767,1777,2272" \
--set-status verified --db porting.db --execute
```
- Deferred (if blocked) per-test with reason:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update <id> --status deferred --db porting.db \
--override "blocked: requires running JetStream/MQTT server harness parity"
```
Checkpoint after each test class and one commit at task end.
---
### Task 13: Batch 5 Final Verification and Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md`
**Step 1: Full gates**
```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ --verbosity normal
```
**Step 2: Batch-level audit checks**
```bash
dotnet run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- audit --type tests --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- batch show 5 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```
**Step 3: Global stub scan for touched areas**
```bash
rg -n "NotImplementedException|TODO|PLACEHOLDER|Assert\.True\(true\)|Assert\.Pass\(" \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server
```
**Step 4: Complete batch only if all items satisfy allowed terminal states**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch complete 5 --db porting.db
```
If blocked by deferred tests/features, do not force completion; leave explicit blocker notes.
**Step 5: Generate report + commit**
```bash
./reports/generate-report.sh
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server \
tools/generate-jetstream-errors.sh \
porting.db reports/
git commit -m "feat(batch5): port jetstream error constructors and verify mapped tests"
```

View File

@@ -0,0 +1,138 @@
# Batch 8 (Store Interfaces) Design
**Date:** 2026-02-27
**Scope:** Batch 8 planning only (27 features, 1 tracked test) for `server/store.go` parity.
## Context Snapshot
Batch metadata (from PortTracker):
- Batch ID: `8`
- Name: `Store Interfaces`
- Features: `27`
- Tests: `1`
- Dependencies: none
- Go source: `server/store.go`
- Current status: all `27` features and test `1751` are `deferred`
Targeted feature clusters:
- Stream-state codec/parsing and delete-block state helpers (`IsEncodedStreamState`, `DecodeStreamState`, `DeleteRange.State`, `DeleteSlice.State`)
- Consumer state encoding (`encodeConsumerState`)
- Enum JSON/string parity for `RetentionPolicy`, `DiscardPolicy`, `StorageType`, `AckPolicy`, `ReplayPolicy`, `DeliverPolicy`
- Store/runtime helpers (`isOutOfSpaceErr`, `isClusterResetErr`, `StoreMsg.copy`, `bytesToString`, `stringToBytes`, `copyString`, `isPermissionError`)
Tracked test in this batch:
- `unit_test #1751` (`TestJetStreamDirectGetUpToTime` -> `.NET: JetStreamEngineTests.JetStreamDirectGetUpToTime_ShouldSucceed`)
- Depends on feature `3191` (`bytesToString`) plus already-verified features (`325`, `804`, `2474`, `2483`, `3051`)
## Problem Statement
`StoreTypes.cs` already defines many store types and interfaces, but Batch 8 parity methods are still unverified/deferred. The risk is twofold:
1. Behavior gaps: binary decode/encode parity, enum JSON text parity, and byte/string helpers can silently diverge from Go semantics.
2. Audit/status drift: mapped feature names require explicit, test-backed evidence before transitioning from `deferred` to `verified`.
## Constraints and Success Criteria
Constraints:
- .NET 10 + C# latest with nullable enabled
- xUnit 3 + Shouldly + NSubstitute only
- No stubs/fake tests for status promotion
- Batch/task grouping must stay <= ~20 features per task
Success criteria:
- All 27 feature mappings implemented or mapped with explicit wrappers/adapters and verified by related tests.
- One tracked test (`1751`) is either truly passing or explicitly deferred with concrete blocker evidence.
- PortTracker statuses updated in evidence-backed chunks with strict verification gates.
## Approaches
### Approach A: Minimal wrappers to satisfy mapped method names
Add thin wrappers only (for mapped member names), keep most logic unchanged.
- Pros: fast mapping closure.
- Cons: high risk of semantic mismatch; weak confidence in parity.
### Approach B: Full parity refactor inside `StoreTypes.cs`
Rework all Batch 8 behavior directly in existing types and enums, including JSON handling and helpers.
- Pros: strongest parity in one place.
- Cons: high change surface in a core file; harder review/debug cycle.
### Approach C (Recommended): Focused parity layer with targeted tests
Keep existing `StoreTypes.cs` types stable, add explicit parity methods/wrappers where needed, and add a dedicated test class that validates each mapped behavior from `store.go`.
- Pros: controlled change scope, strong evidence, easier audit and rollback.
- Cons: requires careful method-shape decisions for enum/string/JSON mappings.
## Recommended Design
### 1. Production Code Layout
Primary touchpoint:
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs`
If needed to keep `StoreTypes.cs` readable, allow one focused helper file:
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs` (or similarly named)
Design intent:
- Implement stream-state decode and encoding helpers with Go-equivalent error handling (`ErrBadStreamStateEncoding`, `ErrCorruptStreamState`).
- Add explicit state methods/parity wrappers for delete blocks and `StoreMsg.copy` semantics.
- Implement enum string/JSON parity through explicit methods and/or converters that preserve Go wire values (`"limits"`, `"new"`, `"memory"`, etc.).
- Implement utility predicates/helpers exactly for Batch 8 semantics.
### 2. Test Design
Primary new test file:
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs`
Test coverage split:
- Codec tests: encoded-stream header detection, decode success/failure paths, corrupt payload handling.
- Delete-block tests: `State()` and `Range()` behavior parity.
- Consumer-state encoding tests: deterministic structural assertions (header, key fields, pending/redelivery shape).
- Enum tests: string and JSON round-trip coverage, invalid input failures.
- Helper tests: out-of-space/cluster-reset predicates, byte/string conversion and copy isolation, permission error predicate.
Tracked test handling:
- Add/port `JetStreamDirectGetUpToTime_ShouldSucceed` in `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs` only if it can be made real and executable.
- If environment/runtime dependencies block realism, keep `#1751` deferred with explicit evidence and reason; do not add a fake-pass test.
### 3. Execution Slicing
Use two feature groups (both <=20 IDs):
- Group A (12 features): `3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194`
- Group B (15 features): `3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186`
Then handle tracked test `1751` as a separate task.
### 4. Risks and Mitigations
1. Enum method-shape mismatch with C# enums vs Go methods
Mitigation: use explicit parity methods/extensions and validate via tracker audit + tests.
2. Binary decode edge cases (varint parsing/corrupt payloads)
Mitigation: table-driven tests using known-good and intentionally malformed byte payloads.
3. Existing ImplBacklog test quality is low
Mitigation: strict anti-stub policy; only behavior-based assertions count toward verification.
4. Direct-get test may require broader server runtime not yet ported
Mitigation: defer with concrete blocker evidence instead of fake implementation.
## Design Decision
Choose **Approach C**: implement Batch 8 via a focused parity layer plus dedicated targeted tests, executed in two feature groups and one test task with strict status-evidence gates.

View File

@@ -0,0 +1,462 @@
# Batch 8 (Store Interfaces) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 8 store-interface parity from `server/store.go` (27 features + 1 tracked test) with evidence-backed status updates and zero stub work.
**Architecture:** Implement Batch 8 in two feature groups (12 + 15 IDs) centered on `StoreTypes.cs` parity helpers plus focused unit tests in `StoreTypesTests.cs`. Run strict per-feature verification loops and gate status promotions behind build/test/stub checks. Treat tracked test `#1751` separately: pass with a real behavior test or keep deferred with explicit blocker evidence.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-8-store-interfaces-design.md`
---
I'm using `writeplan` to create the implementation plan.
## Batch 8 Working Set
Batch facts:
- Batch ID: `8`
- Features: `27` (currently `deferred`)
- Tests: `1` (currently `deferred`)
- Dependencies: none
- Go file: `server/store.go`
Feature groups (max ~20 features per group):
- **Group A (12):** `3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194`
- **Group B (15):** `3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186`
Tracked test:
- **Test ID 1751:** `JetStreamEngineTests.JetStreamDirectGetUpToTime_ShouldSucceed`
Primary files:
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs` (create only if needed for clarity)
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs` (new)
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs` (tracked test `1751`)
- `porting.db`
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** every feature/test status update in this batch must follow this protocol.
### Per-Feature Verification Loop (REQUIRED for every feature ID)
1. Read exact Go source mapping from tracker:
```bash
dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db
```
2. Open mapped Go code (`server/store.go`) and confirm behavior at mapped line range.
3. Implement/update mapped C# method(s) in the mapped class/file.
4. Build immediately:
```bash
dotnet build dotnet/
```
5. Run related tests for that feature slice:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~StoreTypesTests" --verbosity normal
```
6. Only if build+related tests are green, include the feature ID in status-promotion candidates.
### Stub Detection Check (REQUIRED after every feature group and test task)
Run these checks on all touched files before any status promotion:
```bash
grep -RInE "NotImplementedException|TODO|PLACEHOLDER" \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/Store*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs
grep -RInE "^\s*\{\s*\}$|Assert\.True\(true\)|Assert\.Pass\(" \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs
```
Any match blocks status updates until resolved or explicitly deferred.
### Build Gate (REQUIRED after each feature group)
```bash
dotnet build dotnet/
```
Required: `0` build errors.
### Test Gate (REQUIRED before marking features `verified`)
All related tests must pass before features in that group can move to `verified`:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~StoreTypesTests|FullyQualifiedName~JetStreamMemoryStoreTests|FullyQualifiedName~StorageEngineTests" \
--verbosity normal
```
For test-linked feature `3191`, `unit_test #1751` must also be resolved (pass or explicit deferred reason) before final batch closure.
### Status Update Protocol (REQUIRED)
Rules:
- Maximum `15` IDs per `feature batch-update` / `test batch-update` command.
- Evidence is mandatory for each update chunk:
- latest build gate output
- related test gate output
- stub detection output
- Valid promotion path:
- Features: `deferred -> stub -> complete -> verified`
- Test `1751`: `deferred -> stub -> verified` (or remain `deferred` with reason)
Command templates:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
test update 1751 --status verified --db porting.db
```
If audit disagrees, include explicit justification:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status verified --db porting.db \
--override "manual verification evidence: <short reason>"
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each task (Group A, Group B, Test 1751), before continuing:
1. Full build:
```bash
dotnet build dotnet/
```
2. Full unit tests:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Commit task slice:
```bash
git add <touched-files> porting.db
git commit -m "feat(batch8): <task-slice-summary>"
```
---
## ANTI-STUB GUARDRAILS
### Forbidden Patterns
Production code forbidden:
- `throw new NotImplementedException()`
- Empty public/internal method bodies used as placeholders
- `return default;` or `return null;` where Go logic requires real behavior
- unresolved `TODO`/`PLACEHOLDER` markers in touched Batch 8 code
Test code forbidden for `verified` status:
- `Assert.True(true)` / `Assert.Pass()`
- method-name/self-string assertions that do not exercise production code
- empty test bodies
- single trivial assert that does not validate mapped behavior
### Hard Limits
- Max `20` feature IDs per task group (Batch 8 uses groups of `12` and `15`)
- Max `15` IDs per status update command
- No `verified` feature status without passing related test gate
- No `verified` test status for skipped/non-behavioral tests
- One group per verification cycle (no cross-group bulk promotion)
### If You Get Stuck (Explicit Rule)
Do not stub and do not fake-pass.
1. Keep the blocked item as `deferred`.
2. Record concrete blocker in override reason.
3. Capture command output showing the blocker.
4. Continue with next unblocked item.
Example:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status deferred --db porting.db \
--override "blocked: <specific missing runtime/api/infrastructure dependency>"
dotnet run --project tools/NatsNet.PortTracker -- \
test update 1751 --status deferred --db porting.db \
--override "blocked: <specific missing runtime/api/infrastructure dependency>"
```
---
### Task 1: Baseline + Group A Implementation (12 features)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs`
- Create (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs`
- Modify: `porting.db`
Group A IDs:
- `3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194`
**Step 1: Mark Group A as `stub` (single chunk <=15)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194" \
--set-status stub --db porting.db --execute
```
**Step 2: Write failing Group A tests in `StoreTypesTests`**
Cover:
- encoded-stream header detection
- decode success/failure/corrupt paths
- delete-block state parity
- consumer-state encode shape checks
- out-of-space/cluster-reset predicates
- `StoreMsg.copy` behavior
- byte/string conversion + copy isolation + permission error predicate
**Step 3: Run Group A focused tests and confirm FAIL**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~StoreTypesTests" --verbosity normal
```
**Step 4: Implement Group A production code minimally to pass tests**
**Step 5: Re-run Group A focused tests and confirm PASS**
Same command as Step 3; require `Failed: 0`.
**Step 6: Run stub detection + build gate + test gate**
Use protocol commands above.
**Step 7: Promote Group A statuses to `complete` then `verified`**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194" \
--set-status verified --db porting.db --execute
```
**Step 8: Execute checkpoint protocol and commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs \
porting.db
git commit -m "feat(batch8): implement store codec/helpers parity group A"
```
---
### Task 2: Group B Enum String/JSON Parity (15 features)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs`
- Modify/Create: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs`
- Modify: `porting.db`
Group B IDs:
- `3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186`
**Step 1: Mark Group B as `stub` (15 IDs = one chunk)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186" \
--set-status stub --db porting.db --execute
```
**Step 2: Write failing enum parity tests**
Cover all mapped cases:
- `String()` parity text values
- marshal/unmarshal JSON token values
- invalid-value error behavior
- `DeliverPolicy` special `"undefined"` mapping behavior
**Step 3: Run focused tests and confirm FAIL**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~StoreTypesTests" --verbosity normal
```
**Step 4: Implement Group B enum string/JSON parity**
**Step 5: Re-run focused tests and confirm PASS**
Same command as Step 3; require `Failed: 0`.
**Step 6: Run stub detection + build gate + test gate**
Use protocol commands above.
**Step 7: Promote Group B statuses to `complete` then `verified`**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186" \
--set-status verified --db porting.db --execute
```
**Step 8: Execute checkpoint protocol and commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs \
porting.db
git commit -m "feat(batch8): implement store enum parity group B"
```
---
### Task 3: Tracked Test 1751 (`JetStreamDirectGetUpToTime_ShouldSucceed`)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark test 1751 as `stub`**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update 1751 --status stub --db porting.db
```
**Step 2: Port failing test logic from Go `TestJetStreamDirectGetUpToTime`**
- Preserve the behavior checks (distant past/future, before first, before fifth).
- Ensure it exercises real server/message paths, not constant/string-only assertions.
**Step 3: Run the single mapped test and confirm real execution**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~JetStreamEngineTests.JetStreamDirectGetUpToTime_ShouldSucceed" \
--verbosity normal
```
Required: at least one executed test and `Failed: 0`.
**Step 4: If blocked by missing runtime infrastructure, defer with reason (do not stub)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update 1751 --status deferred --db porting.db \
--override "blocked: requires <specific runtime/infra gap>"
```
**Step 5: If passing, promote test to `verified`**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update 1751 --status verified --db porting.db
```
**Step 6: Run checkpoint protocol and commit**
```bash
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs \
porting.db
git commit -m "test(batch8): resolve jetstream direct get up-to-time mapping"
```
---
### Task 4: Batch 8 Final Closure
**Files:**
- Modify: `porting.db`
- Optional regenerate: `reports/current.md`
**Step 1: Re-run final evidence gates**
```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
**Step 2: Confirm all Batch 8 IDs are closed correctly**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch show 8 --db porting.db
```
Required end-state:
- Features: `verified` (or explicit `deferred` only with blocker reason)
- Test `1751`: `verified` or explicit `deferred` with blocker reason
**Step 3: Complete batch if eligibility checks pass**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch complete 8 --db porting.db
```
**Step 4: Regenerate report and commit closure artifacts**
```bash
./reports/generate-report.sh
git add porting.db reports/current.md
git commit -m "chore(batch8): close store interfaces batch with verification evidence"
```
---
Plan complete and saved to `docs/plans/2026-02-27-batch-8-store-interfaces-plan.md`. Two execution options:
**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration
**2. Parallel Session (separate)** - Open new session with `executeplan`, batch execution with checkpoints
Which approach?

View File

@@ -1,6 +1,6 @@
# NATS .NET Porting Status Report
Generated: 2026-02-27 18:23:18 UTC
Generated: 2026-02-27 19:11:30 UTC
## Modules (12 total)

37
reports/report_f98e334.md Normal file
View File

@@ -0,0 +1,37 @@
# NATS .NET Porting Status Report
Generated: 2026-02-27 19:11:30 UTC
## Modules (12 total)
| Status | Count |
|--------|-------|
| verified | 12 |
## Features (3673 total)
| Status | Count |
|--------|-------|
| deferred | 2377 |
| n_a | 24 |
| stub | 1 |
| verified | 1271 |
## Unit Tests (3257 total)
| Status | Count |
|--------|-------|
| deferred | 2640 |
| n_a | 187 |
| verified | 430 |
## Library Mappings (36 total)
| Status | Count |
|--------|-------|
| mapped | 36 |
## Overall Progress
**1924/6942 items complete (27.7%)**