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:
@@ -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.
|
||||
@@ -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"
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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 3’s 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"
|
||||
```
|
||||
138
docs/plans/2026-02-27-batch-4-logging-design.md
Normal file
138
docs/plans/2026-02-27-batch-4-logging-design.md
Normal 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.
|
||||
506
docs/plans/2026-02-27-batch-4-logging-plan.md
Normal file
506
docs/plans/2026-02-27-batch-4-logging-plan.md
Normal 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 feature’s 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?
|
||||
160
docs/plans/2026-02-27-batch-5-jetstream-errors-design.md
Normal file
160
docs/plans/2026-02-27-batch-5-jetstream-errors-design.md
Normal 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.
|
||||
530
docs/plans/2026-02-27-batch-5-jetstream-errors-plan.md
Normal file
530
docs/plans/2026-02-27-batch-5-jetstream-errors-plan.md
Normal 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"
|
||||
```
|
||||
138
docs/plans/2026-02-27-batch-8-store-interfaces-design.md
Normal file
138
docs/plans/2026-02-27-batch-8-store-interfaces-design.md
Normal 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.
|
||||
462
docs/plans/2026-02-27-batch-8-store-interfaces-plan.md
Normal file
462
docs/plans/2026-02-27-batch-8-store-interfaces-plan.md
Normal 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?
|
||||
Reference in New Issue
Block a user